Skip to content

Commit 50109e8

Browse files
fgrosaalibuild
andauthored
[ITS3] Update default parameters and adapt code to work with fourth layer (#11227)
* Change default parameters * Avoid to get GRPECS from CCDB * Fix simulation and digitisation with 4th later * Adapt clusterer to work with 4th layer * Adapt ITS3 tracker to work with 4th layer * Update README * Fix typo * Please consider the following formatting changes * Move modifications to ITS code in dedicated PR * Remove leftover * Fix conflicts * Fix conflicts --------- Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 0a5342b commit 50109e8

20 files changed

Lines changed: 261 additions & 171 deletions

File tree

Detectors/Upgrades/ITS3/README.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Events can be simulated using the `o2-sim` workflow. To include ITS3 in the simu
1313

1414
The following command can be used to generate heavy-ion collisions:
1515
```bash
16-
o2-sim -j 1 \
16+
o2-sim -j 8 \
1717
-n 10 -g pythia8hi --field ccdb \
1818
--configKeyValues "Diamond.width[2]=6.;DescriptorInnerBarrelITS3.mVersion=ThreeLayers" \
1919
--run 311935
@@ -22,14 +22,16 @@ In the previous command:
2222
- `-j` is used to set the number of threads;
2323
- `-n` is used to set the number of events to simulate;
2424
- `-g` is used to set the event generator, in this case `pythia8hi`. To simulate pp collisions one can use `pythia8pp`.
25-
- `--configKeyValues` is needed to set internal parameters of the workflow. Among these parameters, the geometry of the ITS3 inner barrel can be set.
25+
- `--configKeyValues` is needed to set internal parameters of the workflow. Among these parameters, the geometry of the ITS3 inner barrel can be set:
26+
- `DescriptorInnerBarrel.mVersion` is the geometry version of the ITS3 inner barrel (`ThreeLayersNoDeadZones`, `ThreeLayers`, or `FourLayers`)
27+
- `DescriptorInnerBarrel.mRadii` is a 4-element vector with the radii of the ITS3 layers
28+
- `DescriptorInnerBarrel.mLength` is the length of the ITS3 in the Z direction
29+
- `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
30+
- `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.
31+
- `DescriptorInnerBarrel.mGapXDirection4thLayer` is the gap in the horizontal direction for the fourth layer, analogous to the `mGapY`.
32+
- `SuperAlpideParams.mDetectorThickness` is the thickness of the chip
2633
- `--run` is needed to set the run number.
2734

28-
Currently, three different geometries of the ITS3 inner barrel are available:
29-
- `ThreeLayersNoDeadZones`
30-
- `ThreeLayers`
31-
- `FourLayers`
32-
3335
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:
3436

3537
- **pp** collisions:
@@ -42,7 +44,6 @@ The run number is needed to retrieve objects from the CCDB. There are specific r
4244
- 311934—311966 (`ThreeLayers`)
4345
- 311967—311999 (`FourLayers`)
4446

45-
4647
### Using external generators based on AliRoot
4748
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):
4849

@@ -77,17 +78,28 @@ o2-sim-digitizer-workflow -b --run --interactionRate 50000 \
7778
```
7879
As above, it is important to set the correct interaction rate and run number.
7980
81+
In addition, some parameters related to the segmentation of the chips can be set with the `--configKeyValues` argument:
82+
- `SuperAlpideParams.mPitchCol` is the pitch of the column (Z direction)
83+
- `SuperAlpideParams.mPitchRow` is the pitch of the row (r$\phi$ direction)
84+
- `SuperAlpideParams.mDetectorThickness` is the thickness of the chip
85+
86+
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.
87+
8088
# Reconstruction
8189
8290
In this step, clustering, vertexing and tracking are performed. This is obtained with the `o2-its3-reco-workflow`:
8391
8492
```bash
8593
o2-its3-reco-workflow --tracking-mode async -b --run \
8694
-—configKeyValues "
87-
HBFUtils.runNumber=311935;ITSCATrackerParam.trackletsPerClusterLimit=20;ITSCATrackerParam.cellsPerC
88-
lusterLimit=20;ITSVertexerParam.lowMultXYcut2=0."
95+
HBFUtils.runNumber=311935;ITSCATrackerParam.trackletsPerClusterLimit=20;ITSCATrackerParam.cellsPerClusterLimit=20;ITSVertexerParam.lowMultXYcut2=0."
8996
```
9097
91-
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 provided `-—configKeyValues` via are specific to the cased here considered (Pb-Pb) and are inherited from ITS2.
98+
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.
99+
100+
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"`.
92101
93-
> **_NOTE:_** reconstruction for the `FourLayers` geometry is not implemented yet.
102+
> **_NOTE:_** in order to make the reconstruction for the `FourLayers` geometry work, the following line has to be added to the CMake options in the [o2.sh](https://github.com/alisw/alidist/blob/master/o2.sh) recipe in alidist:
103+
```bash
104+
${ENABLE_ITS3_4L:+-DENABLE_ITS3_4L=ON}
105+
```

Detectors/Upgrades/ITS3/base/include/ITS3Base/DescriptorInnerBarrelITS3Param.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ enum class ITS3Version {
3939
struct DescriptorInnerBarrelITS3Param : public o2::conf::ConfigurableParamHelper<DescriptorInnerBarrelITS3Param> {
4040
ITS3Version mVersion = ITS3Version::None;
4141
int mBuildLevel{0};
42-
double mGapY[4] = {0.1f, 0.1f, 0.1f, 0.1f};
43-
double mGapPhi[4] = {0.f, 0.f, 0.f, 0.f};
42+
double mGapY[4] = {0.f, 0.f, 0.f, 0.f};
43+
double mGapPhi[4] = {0.1f, 0.1f, 0.1f, 0.1f};
4444
double mRadii[4] = {1.8f, 2.4f, 3.0f, 6.0f};
45-
double mLength{27.f};
46-
double mGapXDirection4thLayer{0.05f};
45+
double mLength{26.f};
46+
double mGapXDirection4thLayer{0.f};
4747
std::string const& getITS3LayerConfigString() const;
4848
O2ParamDef(DescriptorInnerBarrelITS3Param, "DescriptorInnerBarrelITS3");
4949
};

Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,20 @@ class SegmentationSuperAlpide
4040
}
4141
SegmentationSuperAlpide(int layer = 0) : SegmentationSuperAlpide(layer, SuperAlpideParams::Instance().mPitchCol, SuperAlpideParams::Instance().mPitchRow, SuperAlpideParams::Instance().mDetectorThickness, DescriptorInnerBarrelITS3Param::Instance().mLength, DescriptorInnerBarrelITS3Param::Instance().mRadii) {}
4242

43-
double mRadii[4] = {1.8f, 2.4f, 3.0f, 6.0f}; ///< radii for different layers
44-
const double mLength; ///< chip length
45-
const int mLayer; ///< chip layer
46-
const float mPitchCol; ///< pixel column size
47-
const float mPitchRow; ///< pixel row size
48-
const float mDetectorLayerThickness; ///< detector thickness
49-
const int mNCols{static_cast<int>(std::ceil(mLength / mPitchCol))}; ///< number of columns
50-
const int mNRows{static_cast<int>(std::ceil(double(mRadii[mLayer] + mDetectorLayerThickness - mSensorLayerThickness / 2.) * double(constants::math::PI) / double(mPitchRow)))}; ///< number of rows
51-
const int mNPixels{mNRows * mNCols}; ///< total number of pixels
52-
static constexpr float mPassiveEdgeReadOut = 0.; ///< width of the readout edge (Passive bottom)
53-
static constexpr float mPassiveEdgeTop = 0.; ///< Passive area on top
54-
static constexpr float mPassiveEdgeSide = 0.; ///< width of Passive area on left/right of the sensor
55-
const float mActiveMatrixSizeCols{mPitchCol * mNCols}; ///< Active size along columns
56-
const float mActiveMatrixSizeRows{mPitchRow * mNRows}; ///< Active size along rows
43+
double mRadii[4] = {1.8f, 2.4f, 3.0f, 6.0f}; ///< radii for different layers
44+
const double mLength; ///< chip length
45+
const int mLayer; ///< chip layer
46+
const float mPitchCol; ///< pixel column size
47+
const float mPitchRow; ///< pixel row size
48+
const float mDetectorLayerThickness; ///< detector thickness
49+
const int mNCols{static_cast<int>(std::ceil(mLength / mPitchCol))}; ///< number of columns
50+
const int mNRows{static_cast<int>(std::ceil(double(mRadii[mLayer] + mDetectorLayerThickness - mSensorLayerThickness / 2.) * double(constants::math::PI) / double(mPitchRow) * (mLayer == 3 ? 0.5 : 1.)))}; ///< number of rows
51+
const int mNPixels{mNRows * mNCols}; ///< total number of pixels
52+
static constexpr float mPassiveEdgeReadOut = 0.; ///< width of the readout edge (Passive bottom)
53+
static constexpr float mPassiveEdgeTop = 0.; ///< Passive area on top
54+
static constexpr float mPassiveEdgeSide = 0.; ///< width of Passive area on left/right of the sensor
55+
const float mActiveMatrixSizeCols{mPitchCol * mNCols}; ///< Active size along columns
56+
const float mActiveMatrixSizeRows{mPitchRow * mNRows}; ///< Active size along rows
5757

5858
// effective thickness of sensitive layer, accounting for charge collection non-uniformity, https://alice.its.cern.ch/jira/browse/AOC-46
5959
static constexpr float mSensorLayerThicknessEff = 28.e-4; ///< effective thickness of sensitive part

Detectors/Upgrades/ITS3/base/include/ITS3Base/SuperAlpideParams.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ namespace its3
2424

2525
/// Segmentation parameters for Super ALPIDE chips
2626
struct SuperAlpideParams : public o2::conf::ConfigurableParamHelper<SuperAlpideParams> {
27-
float mPitchCol = 20.e-4; ///< Pixel column size (cm)
28-
float mPitchRow = 20.e-4; ///< Pixel row size (cm)
27+
float mPitchCol = 29.24e-4; ///< Pixel column size (cm) //FIXME: proxy value to get same resolution as ITS2 given incorrect sensor response
28+
float mPitchRow = 26.88e-4; ///< Pixel row size (cm) //FIXME: proxy value to get same resolution as ITS2 given incorrect sensor response
2929
float mDetectorThickness = 50.e-4; ///< Detector thickness (cm)
3030

3131
// boilerplate

Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
#include "DetectorsCommonDataFormats/DetectorNameConf.h"
3939
#endif
4040

41-
void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.root", std::string hitfile = "o2sim_HitsIT3.root",
42-
std::string inputGeom = "", std::string dictfile = "", bool batch = true)
41+
void CheckClustersITS3(std::string clusfile = "o2clus_it3.root", std::string hitfile = "o2sim_HitsIT3.root",
42+
std::string inputGeom = "o2sim_geometry.root", std::string dictfile = "", bool batch = true)
4343
{
4444
gROOT->SetBatch(batch);
4545

@@ -58,15 +58,6 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r
5858
std::vector<HitVec*> hitVecPool;
5959
std::vector<MC2HITS_map> mc2hitVec;
6060

61-
// we assume that we have 2 chips per layer
62-
const int nChipsPerLayer = 2;
63-
std::vector<SegmentationSuperAlpide> segs{};
64-
for (int iLayer{0}; iLayer < nITS3layers; ++iLayer) {
65-
for (int iChip{0}; iChip < nChipsPerLayer; ++iChip) {
66-
segs.push_back(SegmentationSuperAlpide(iLayer));
67-
}
68-
}
69-
7061
const int QEDSourceID = 99; // Clusters from this MC source correspond to QED electrons
7162

7263
TFile fout("CheckClusters.root", "recreate");
@@ -78,6 +69,13 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r
7869
gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot,
7970
o2::math_utils::TransformType::L2G)); // request cached transforms
8071

72+
std::vector<SegmentationSuperAlpide> segs{};
73+
for (int iLayer{0}; iLayer < gman->getNumberOfLayers() - 4; ++iLayer) {
74+
for (int iChip{0}; iChip < gman->getNumberOfChipsPerLayer(iLayer); ++iChip) {
75+
segs.push_back(SegmentationSuperAlpide(iLayer));
76+
}
77+
}
78+
8179
// Hits
8280
TFile fileH(hitfile.data());
8381
TTree* hitTree = (TTree*)fileH.Get("o2sim");
@@ -183,13 +181,13 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r
183181
auto chipID = cluster.getSensorID();
184182
if (pattID == o2::its3::CompCluster::InvalidPatternID || dict.isGroup(pattID)) {
185183
o2::itsmft::ClusterPattern patt(pattIt);
186-
locC = dict.getClusterCoordinates(cluster, patt, false);
184+
locC = dict.getClusterCoordinates(cluster, patt, false, segs.size());
187185
LOGP(info, "I am invalid and I am on chip {}", chipID);
188186
} else {
189-
locC = dict.getClusterCoordinates(cluster);
187+
locC = dict.getClusterCoordinates(cluster, segs.size());
190188
errX = dict.getErrX(pattID);
191189
errZ = dict.getErrZ(pattID);
192-
if (chipID / nChipsPerLayer >= nITS3layers) {
190+
if (chipID >= segs.size()) {
193191
errX *= Segmentation::PitchRow;
194192
errZ *= Segmentation::PitchCol;
195193
} else {
@@ -231,7 +229,7 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r
231229
auto y0 = locHsta.Y(), dlty = locH.Y() - y0;
232230
auto z0 = locHsta.Z(), dltz = locH.Z() - z0;
233231

234-
if (chipID / nChipsPerLayer >= nITS3layers) {
232+
if (chipID >= segs.size()) {
235233
auto r = (0.5 * (Segmentation::SensorLayerThickness - Segmentation::SensorLayerThicknessEff) - y0) / dlty;
236234
locH.SetXYZ(x0 + r * dltx, y0 + r * dlty, z0 + r * dltz);
237235
} else {

Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
#endif
4040

41-
void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root", std::string hitfile = "o2sim_HitsIT3.root", std::string inputGeom = "", std::string paramfile = "o2sim_par.root", bool batch = true)
41+
void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfile = "o2sim_HitsIT3.root", std::string inputGeom = "o2sim_geometry.root", std::string paramfile = "o2sim_par.root", bool batch = true)
4242
{
4343
gROOT->SetBatch(batch);
4444

@@ -62,8 +62,8 @@ void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root
6262
const int nChipsPerLayer = 2;
6363

6464
std::vector<SegmentationSuperAlpide> segs{};
65-
for (int iLayer{0}; iLayer < nITS3layers; ++iLayer) {
66-
for (int iChip{0}; iChip < nChipsPerLayer; ++iChip) {
65+
for (int iLayer{0}; iLayer < gman->getNumberOfLayers() - 4; ++iLayer) {
66+
for (int iChip{0}; iChip < gman->getNumberOfChipsPerLayer(iLayer); ++iChip) {
6767
segs.push_back(SegmentationSuperAlpide(iLayer));
6868
}
6969
}
@@ -172,7 +172,7 @@ void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root
172172

173173
int chipID = (*digArr)[iDigit].getChipIndex();
174174

175-
if (chipID / nChipsPerLayer < nITS3layers) {
175+
if (chipID < segs.size()) {
176176
float xFlat{0.f};
177177
segs[chipID].detectorToLocal(ix, iz, xFlat, z);
178178
segs[chipID].flatToCurved(xFlat, 0., x, y);
@@ -214,7 +214,7 @@ void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root
214214
int row, col;
215215
float xlc = 0., zlc = 0.;
216216

217-
if (chipID / nChipsPerLayer < nITS3layers) {
217+
if (chipID < segs.size()) {
218218
segs[chipID].localToDetector(locH.X(), locH.Z(), row, col);
219219
segs[chipID].detectorToLocal(row, col, xlc, zlc);
220220
} else {

Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ void CheckTracksITS3(std::string tracfile = "o2trac_its3.root",
7373
std::string clusfile = "o2clus_it3.root",
7474
std::string kinefile = "o2sim_Kine.root",
7575
std::string magfile = "o2sim_grp.root",
76+
std::string inputGeom = "o2sim_geometry.root",
7677
bool batch = true)
7778
{
7879

@@ -94,7 +95,7 @@ void CheckTracksITS3(std::string tracfile = "o2trac_its3.root",
9495
double orig[3] = {0., 0., 0.};
9596
float bz = field->getBz(orig);
9697
// Geometry
97-
o2::base::GeometryManager::loadGeometry();
98+
o2::base::GeometryManager::loadGeometry(inputGeom);
9899
auto gman = o2::its::GeometryTGeo::Instance();
99100

100101
// MC tracks

0 commit comments

Comments
 (0)