Skip to content

Commit

Permalink
IT3: Support lightweight GeometryTGeo (#12769)
Browse files Browse the repository at this point in the history
* IT3: Support lightweight GeometryTGeo

Signed-off-by: Felix Schlepper <felix.schlepper@cern.ch>

* IT3: fix spelling

Signed-off-by: Felix Schlepper <felix.schlepper@cern.ch>

* IT3: Update README

Signed-off-by: Felix Schlepper <felix.schlepper@cern.ch>

---------

Signed-off-by: Felix Schlepper <felix.schlepper@cern.ch>
  • Loading branch information
f3sch authored Mar 5, 2024
1 parent 89d55ee commit 14189ae
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 153 deletions.
8 changes: 6 additions & 2 deletions Detectors/GRP/workflows/src/create-aligned-geometry.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ class AlignerTask : public Task
LOGP(info, "Stored aligned geometry to local file {}", fnm);

// create GeometryTGeo for detectors which support it
{
if (mDetsMask[DetID::ITS]
#ifdef ENABLE_UPGRADES
|| mDetsMask[DetID::IT3]
#endif
) {
auto itsTGeo = o2::its::GeometryTGeo::Instance();
itsTGeo->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G, o2::math_utils::TransformType::T2GRot));
TFile outF("its_GeometryTGeo.root", "recreate");
Expand All @@ -110,7 +114,7 @@ class AlignerTask : public Task
outF.Close();
itsTGeo->destroy();
}
{
if (mDetsMask[DetID::MFT]) {
auto mftTGeo = o2::mft::GeometryTGeo::Instance();
mftTGeo->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G, o2::math_utils::TransformType::T2G));
TFile outF("mft_GeometryTGeo.root", "recreate");
Expand Down
6 changes: 3 additions & 3 deletions Detectors/ITSMFT/ITS/base/include/ITSBase/GeometryTGeo.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ class GeometryTGeo : public o2::itsmft::GeometryTGeo
// it is cheaper to use T2GRot
using DetMatrixCache::getMatrixT2G;

static GeometryTGeo* Instance(bool isITS3 = false)
static GeometryTGeo* Instance()
{
// get (create if needed) a unique instance of the object
#ifdef GPUCA_STANDALONE
return nullptr; // TODO: DR: Obviously wrong, but to make it compile for now
#else
if (!sInstance) {
sInstance = std::make_unique<GeometryTGeo>(true, 0, isITS3);
sInstance = std::make_unique<GeometryTGeo>(true, 0);
}
return sInstance.get();
#endif
Expand All @@ -72,7 +72,7 @@ class GeometryTGeo : public o2::itsmft::GeometryTGeo
// we must define public default constructor.
// NEVER use it, it will throw exception if the class instance was already created
// Use GeometryTGeo::Instance() instead
GeometryTGeo(bool build = kFALSE, int loadTrans = 0, bool isITS3 = false);
GeometryTGeo(bool build = kFALSE, int loadTrans = 0);

/// Default destructor, don't use
~GeometryTGeo() override;
Expand Down
41 changes: 23 additions & 18 deletions Detectors/ITSMFT/ITS/base/src/GeometryTGeo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ using SuperSegmentation = o2::its3::SegmentationSuperAlpide;
#include <cctype> // for isdigit
#include <cstdio> // for snprintf, NULL, printf
#include <cstring> // for strstr, strlen
#include <algorithm>

using namespace TMath;
using namespace o2::its;
Expand Down Expand Up @@ -76,12 +77,7 @@ const std::string GeometryTGeo::sChipNameITS3 = "ITS3Tile"; ///< Chi
const std::string GeometryTGeo::sSensorNameITS3 = "ITS3PixelArray"; ///< Sensor name for ITS3

//__________________________________________________________________________
GeometryTGeo::GeometryTGeo(bool build, int loadTrans, bool isITS3) :
#ifdef ENABLE_UPGRADES
o2::itsmft::GeometryTGeo((!isITS3) ? DetID::ITS : DetID::IT3)
#else
o2::itsmft::GeometryTGeo(DetID::ITS)
#endif
GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : o2::itsmft::GeometryTGeo(DetID::ITS)
{
// default c-tor, if build is true, the structures will be filled and the transform matrices
// will be cached
Expand Down Expand Up @@ -419,7 +415,7 @@ TGeoHMatrix* GeometryTGeo::extractMatrixSensor(int index) const
// account for the difference between physical sensitive layer (where charge collection is simulated) and effective sensor thicknesses
double delta = Segmentation::SensorLayerThickness - Segmentation::SensorLayerThicknessEff;
#ifdef ENABLE_UPGRADES
if (its3::constants::detID::isDetITS3(index)) {
if (mIsLayerITS3[getLayer(index)]) {
delta = its3::SegmentationSuperAlpide::mSensorLayerThickness - its3::SegmentationSuperAlpide::mSensorLayerThicknessEff;
}
#endif
Expand Down Expand Up @@ -447,8 +443,8 @@ const o2::math_utils::Transform3D GeometryTGeo::getT2LMatrixITS3(int isn, float
static TGeoHMatrix t2l;
t2l.Clear();
t2l.RotateZ(alpha * RadToDeg()); // rotate in direction of normal to the tangent to the cylinder
const TGeoHMatrix* matL2G = extractMatrixSensor(isn);
const TGeoHMatrix& matL2Gi = matL2G->Inverse();
const TGeoHMatrix& matL2G = getMatrixL2G(isn);
const auto& matL2Gi = matL2G.Inverse();
t2l.MultiplyLeft(&matL2Gi);
return Mat3D(t2l);
}
Expand Down Expand Up @@ -514,9 +510,16 @@ void GeometryTGeo::Build(int loadTrans)
LOGP(debug, " Layer {}: {:*^30}", i, "END");
}
LOGP(debug, "In total there {} chips registered", numberOfChips);

#ifdef ENABLE_UPGRADES
if (std::any_of(mIsLayerITS3.cbegin(), mIsLayerITS3.cend(), [](auto b) { return b; })) {
LOGP(info, "Found active IT3 layers -> Renaming Detector ITS to IT3");
mDetID = DetID::IT3;
}
#endif

setSize(numberOfChips);
fillTrackingFramesCache();
//
fillMatrixCache(loadTrans);
}

Expand Down Expand Up @@ -853,19 +856,21 @@ int GeometryTGeo::extractLayerChipType(int lay) const
//__________________________________________________________________________
void GeometryTGeo::Print(Option_t*) const
{
printf("NLayers:%d NChips:%d\n", mNumberOfLayers, getNumberOfChips());
if (!isBuilt()) {
LOGF(info, "Geometry not built yet!");
return;
}

LOGF(info, "Summary of GeometryTGeo: %s", getName());
LOGF(info, "NLayers:%d NChips:%d\n", mNumberOfLayers, getNumberOfChips());
for (int i = 0; i < mNumberOfLayers; i++) {
printf(
"Lr%2d\tNStav:%2d\tNChips:%2d "
"(%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChip#:%5d:%-5d\tWrapVol:%d\n",
i, mNumberOfStaves[i], mNumberOfChipsPerModule[i], mNumberOfChipRowsPerModule[i],
mNumberOfChipRowsPerModule[i] ? mNumberOfChipsPerModule[i] / mNumberOfChipRowsPerModule[i] : 0,
mNumberOfModules[i], mNumberOfHalfStaves[i], mNumberOfStaves[i], getFirstChipIndex(i), getLastChipIndex(i),
mLayerToWrapper[i]);
LOGF(info,
"Lr%2d\tNStav:%2d\tNChips:%2d "
"(%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChip#:%5d:%-5d\tWrapVol:%d",
i, mNumberOfStaves[i], mNumberOfChipsPerModule[i], mNumberOfChipRowsPerModule[i],
mNumberOfChipRowsPerModule[i] ? mNumberOfChipsPerModule[i] / mNumberOfChipRowsPerModule[i] : 0,
mNumberOfModules[i], mNumberOfHalfStaves[i], mNumberOfStaves[i], getFirstChipIndex(i), getLastChipIndex(i),
mLayerToWrapper[i]);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Detectors/Upgrades/ITS3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ add_subdirectory(macros)
add_subdirectory(simulation)
add_subdirectory(base)
add_subdirectory(workflow)
add_subdirectory(reconstruction)
add_subdirectory(reconstruction)
182 changes: 71 additions & 111 deletions Detectors/Upgrades/ITS3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,167 +3,127 @@
/doxy -->

# ITS3
Upgraded version of the ITS that includes upgraded truly-cylindrical inner barrel.

# Run the full simulation
Provided O2 has been compiled with upgrades enabled, it is possible to simulate ITS3 geometry within the `o2-sim` executable.
Upgraded version of the ITS that includes upgraded truly-cylindrical inner barrel.
Provided O2 has been compiled with upgrades enabled (`ENABLE_UPGRADES=1 aliBuild build O2`), it is possible to simulate ITS3 geometry within the `o2-sim` executable.

## Simulation
Events can be simulated using the `o2-sim` workflow. To include ITS3 in the simulation, `IT3` module must be enabled via the `-m IT3` parameter. To include the beam pipe, the module `PIPE` must be enabled.

The following command can be used to generate heavy-ion collisions:
```bash
o2-sim -j 8 \
-n 10 -g pythia8hi --field ccdb \
--configKeyValues "Diamond.width[2]=6.;DescriptorInnerBarrelITS3.mVersion=ThreeLayers" \
--run 311935
```
In the previous command:
- `-j` is used to set the number of threads;
- `-n` is used to set the number of events to simulate;
- `-g` is used to set the event generator, in this case `pythia8hi`. To simulate pp collisions one can use `pythia8pp`.
- `--configKeyValues` is needed to set internal parameters of the workflow. Among these parameters, the geometry of the ITS3 inner barrel can be set:
- `DescriptorInnerBarrel.mVersion` is the geometry version of the ITS3 inner barrel (`ThreeLayersNoDeadZones`, `ThreeLayers`, or `FourLayers`)
- `DescriptorInnerBarrel.mRadii` is a 4-element vector with the radii of the ITS3 layers
- `DescriptorInnerBarrel.mLength` is the length of the ITS3 in the Z direction
- `DescriptorInnerBarrel.mGapY` is a 4-element vector with the values of gap between the two hemicylinders, described by a translation of the hemicylinders in the vertical direction
- `DescriptorInnerBarrel.mGapPhi` is a 4-element vector with the values of gap of azimuthal angle between the two hemicylinders, described by the maximum distance between the two hemicylinders. Differently from `mGapY`, in this case there no shift in the vertical direction, but a smaller coverage in the azimuthal angle of the half layers.
- `DescriptorInnerBarrel.mGapXDirection4thLayer` is the gap in the horizontal direction for the fourth layer, analogous to the `mGapY`.
- `SuperAlpideParams.mDetectorThickness` is the thickness of the chip
- `--run` is needed to set the run number.

The run number is needed to retrieve objects from the CCDB. There are specific ranges of run-numbers, according to the collision system and to the selected geometry if the ITS3 inner barrel:

- **pp** collisions:
- 303901—303933 (`ThreeLayersNoDeadZones`)
- 303934—303966 (`ThreeLayers`)
- 303967—303999 (`FourLayers`)

- 303901—303999

- **Pb-Pb** collisions:
- 311901—311933 (`ThreeLayersNoDeadZones`)
- 311934—311966 (`ThreeLayers`)
- 311967—311999 (`FourLayers`)

### Using external generators based on AliRoot
It is also possible to simulate heavy-ion collision using external generators based on AliRoot. In this case, it is necessary to load both O2 and AliROOT (the order is important):
- 311901—311999

```bash
alienv enter O2/latest AliRoot/latest
```
_Note: For now the same topology dictionary will be used for both collision-systems_
_Last Update of file here (jira)[https://its.cern.ch/jira/browse/O2-4698]_

After that, the option `-g external` must be used and the file with the definition of the generator and the function to be used must be provided as parameters of the workflow:
## Simulation

```bash
o2-sim -j 1 \
-n 10 -g external \
--configKeyValues "Diamond.width[2]=6.;DescriptorInnerBarrelITS3.mVersion=ThreeLayers;GeneratorExternal.fileName=hijing.C;GeneratorExternal.funcName=hijing(5020, 0, 20)"
```
The file `hijing.C` can be found [here](https://alice.its.cern.ch/jira/browse/AOGM-246).
0. Optional

## Digitisation
The process consists of two steps. First, it is necessary to create the file `collision_context.root`:
This just caches the ccdb object to reduce calls in case we are testing.

```bash
o2-sim-digitizer-workflow --only-context -b \
--interactionRate 50000 --run \
--configKeyValues "HBFUtils.runNumber=311935
export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1
export ALICEO2_CCDB_LOCALCACHE=$PWD/ccdb
```
It is important to set the correct collision rate via `--interactionRate` and to set the correct run number with `--configKeyValues`.

To complete the digitisation, run the command:
1. Simulate

Simulate PIPE and ITS3

```bash
o2-sim-digitizer-workflow -b --run --interactionRate 50000 \
--incontext collisioncontext.root \
--configKeyValues “HBFUtils.runNumber=311935”
o2-sim -g pythia8pp -j10 -m PIPE IT3 --run 303901 -n1000 #--configKeyValues "Diamond.width[2]=6.;"
```
As above, it is important to set the correct interaction rate and run number.
In addition, some parameters related to the segmentation of the chips can be set with the `--configKeyValues` argument:
- `SuperAlpideParams.mPitchCol` is the pitch of the column (Z direction)
- `SuperAlpideParams.mPitchRow` is the pitch of the row (r$\phi$ direction)
- `SuperAlpideParams.mDetectorThickness` is the thickness of the chip

If some parameters of the geometry changed in the simulation, they should be set similarly for the digitisation. In particular, the `mVersion`, `mRadii`, and `mLength` must be set if different from the default ones.
In the previous command:

# Reconstruction
- `-j` is used to set the number of threads;
- `-n` is used to set the number of events to simulate;
- `-g` is used to set the event generator, in this case `pythia8hi`. To simulate pp collisions one can use `pythia8pp`.
- `--run` is needed to set the run number.

In this step, clustering, vertexing and tracking are performed. This is obtained with the `o2-its3-reco-workflow`:
2. Digitization

```bash
o2-its3-reco-workflow --tracking-mode async -b --run \
-—configKeyValues "
HBFUtils.runNumber=311935;ITSCATrackerParam.trackletsPerClusterLimit=20;ITSCATrackerParam.cellsPerClusterLimit=20;ITSVertexerParam.lowMultXYcut2=0."
o2-sim-digitizer-workflow -b --interactionRate 50000 --run --configKeyValues="HBFUtils.runNumber=303901;"
root -x -l ${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C++
```

As above, it is important to provide the correct run number using `-—configKeyValues`, to retrieve the correct files from the CCDB. The other internal parameters for the vertexer and the tracker are provided `-—configKeyValues` via are specific to the cased here considered (Pb-Pb) and are inherited from ITS2.
3. Clusterization with tracking

If the `FourLayers` geometry was used in the simulation, it should be set also for the reconstruction to set properly the tracker to work with the additional layer. If something else of the geometry was set differently (`mRadii`, `mLength`, `mGapY`, `mGapPhi`, `mGapXDirection4thLayer`, or `mDetectorThickness`), it is necessary to remap the file with the geometry to replace the one on the CCDB, which would be different. This can be done by copying the `o2sim_geometry-aligned.root` file created during the simulation to a directory called `GLO/Config/GeometryAligned`, with the name `snapshot.root` in a local path of choice. Then, the following argument has to be added to the reco workflow: `--condition-remap "file://local_path=GLO/Config/GeometryAligned"`.
```bash
o2-its3-reco-workflow -b --run --tracking-mode async --configKeyValues "HBFUtils.runNumber=303901;"
root -x -l '${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C++("o2trac_its3.root", "o2clus_it3.root", "o2sim_Kine.root", "o2sim_grp.root", "o2sim_geometry-aligned.root", false)'
```

## Creating CCDB Objects

# NEW
## Simulation
``` bash
export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1
export ALICEO2_CCDB_LOCALCACHE=../ccdb
mkdir -p ../ccdb/GLO/Config/GeometryAligned
mkdir -p ../ccdb/IT3/Calib/ClusterDictionary
```
### pp
Simulate PIPE and ITS3
### Create Full geometry + Aligned + GeometryTGeo

``` bash
o2-sim -g pythia8pp -j10 -m PIPE IT3 --field ccdb --vertexMode kCCDB --noemptyevents --run 302000 -n10000
```bash
# Create Full Geometry
o2-sim -m PIPE IT3 TPC TRD TOF PHS CPV EMC HMP MFT MCH MID ZDC FT0 FV0 FDD CTP FOC TST --run 303901 -n0
cp o2sim_geometry.root ${ALICEO2_CCDB_LOCALCACHE}/GLO/Config/Geometry/snapshot.root
o2-create-aligned-geometry-workflow -b --configKeyValues "HBFUtils.startTime=1547978230000" --condition-remap="file://${ALICEO2_CCDB_LOCALCACHE}=GLO/Config/Geometry"
cp o2sim_geometry-aligned.root ${ALICEO2_CCDB_LOCALCACHE}/GLO/Config/GeometryAligned/snapshot.root
```

## Digitization
``` bash
o2-sim-digitizer-workflow -b --interactionRate 50000 --run --configKeyValues="HBFUtils.runNumber=302000;"
root -x -l ~/git/alice/O2/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C++
```
### Regenerating the TopologyDictionary

## Clusterization w/o tracking
1. Clusterization w/o tracking

First we need to use the clusterizer but ignoring the default TopologyDictionary, we built our own.

``` bash
```bash
o2-its3-reco-workflow -b --tracking-mode off \
--configKeyValues "HBFUtils.runNumber=302000;" \
--condition-remap="file://${ALICEO2_CCDB_LOCALCACHE}=IT3/Calib/ClusterDictionary" \
--ignore-cluster-dictionary --run |\
tee cluster0.log
--configKeyValues "HBFUtils.runNumber=303901;" \
--ignore-cluster-dictionary --run
```

### Creating the Topology Dictionary
``` bash
root -x -l ~/git/alice/O2/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C++
2. Creating the Topology Dictionary

```bash
root -x -l ${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C++
cp IT3dictionary.root ${ALICEO2_CCDB_LOCALCACHE}/IT3/Calib/ClusterDictionary/snapshot.root
```

### Rerun Clusterization with new TopologyDictionary
``` bash
3. Rerun Clusterization with new TopologyDictionary

```bash
o2-its3-reco-workflow -b --tracking-mode off \
--configKeyValues "HBFUtils.runNumber=302000;" \
--configKeyValues "HBFUtils.runNumber=303901;" \
--condition-remap="file://${ALICEO2_CCDB_LOCALCACHE}=IT3/Calib/ClusterDictionary" \
--run |\
tee cluster1.log
--run
```

### Check Clusters
``` bash
root -x -l '~/git/alice/O2/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C++("o2clus_it3.root", "o2sim_HitsIT3.root", "o2sim_geometry-aligned.root", "IT3dictionary.root")'
root -x -l '~/git/alice/O2/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C++("o2clus_it3.root", "it3digits.root","IT3dictionary.root", "o2sim_HitsIT3.root", "o2sim_geometry-aligned.root")'
root -x -l '~/git/alice/O2/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C++("o2clus_it3.root", "o2sim_Kine.root", "IT3dictionary.root", false)'
4. Check Clusters

```bash
root -x -l '${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C++("o2clus_it3.root", "o2sim_HitsIT3.root", "o2sim_geometry-aligned.root", "IT3dictionary.root")'
root -x -l '${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C++("o2clus_it3.root", "it3digits.root","IT3dictionary.root", "o2sim_HitsIT3.root", "o2sim_geometry-aligned.root")'
root -x -l '${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C++("o2clus_it3.root", "o2sim_Kine.root", "IT3dictionary.root", false)'
```

### Using external generators based on AliRoot

It is also possible to simulate heavy-ion collision using external generators based on AliRoot. In this case, it is necessary to load both O2 and AliROOT (the order is important):

```bash
alienv enter O2/latest AliRoot/latest
```

## Clusterization with tracking
This repeats the clusterization steps and enables travcking.
After that, the option `-g external` must be used and the file with the definition of the generator and the function to be used must be provided as parameters of the workflow:

``` bash
o2-its3-reco-workflow -b --tracking-mode sync --condition-remap="file://${ALICEO2_CCDB_LOCALCACHE}=IT3/Calib/ClusterDictionary,GLO/Config/GeometryAligned"
root -x -l '~/git/alice/O2/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C++("o2trac_its3.root", "o2clus_it3.root", "o2sim_Kine.root", "o2sim_grp.root", "o2sim_geometry-aligned.root", false)'
```bash
o2-sim -j 1 \
-n 10 -g external \
--configKeyValues "Diamond.width[2]=6.;GeneratorExternal.fileName=hijing.C;GeneratorExternal.funcName=hijing(5020, 0, 20)"
```

The file `hijing.C` can be found [here](https://alice.its.cern.ch/jira/browse/AOGM-246).
2 changes: 1 addition & 1 deletion Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void CheckClustersITS3(std::string clusfile = "o2clus_it3.root", std::string hit
TNtuple nt("ntc", "cluster ntuple", "ev:lab:hlx:hlz:hgx:hgz:tx:tz:cgx:cgy:cgz:clx:cly:clz:dx:dy:dz:ex:ez:patid:rof:npx:id");

// Geometry
/* o2::base::GeometryManager::loadGeometry(inputGeom, false, false, true); */
o2::base::GeometryManager::loadGeometry(inputGeom);
auto gman = o2::its::GeometryTGeo::Instance();
gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot,
o2::math_utils::TransformType::L2G)); // request cached transforms
Expand Down
Loading

0 comments on commit 14189ae

Please sign in to comment.