diff --git a/Detectors/Upgrades/ITS3/README.md b/Detectors/Upgrades/ITS3/README.md index 8b81ec17e0a09..c4a7b8de3e22c 100644 --- a/Detectors/Upgrades/ITS3/README.md +++ b/Detectors/Upgrades/ITS3/README.md @@ -13,7 +13,7 @@ Events can be simulated using the `o2-sim` workflow. To include ITS3 in the simu The following command can be used to generate heavy-ion collisions: ```bash -o2-sim -j 1 \ +o2-sim -j 8 \ -n 10 -g pythia8hi --field ccdb \ --configKeyValues "Diamond.width[2]=6.;DescriptorInnerBarrelITS3.mVersion=ThreeLayers" \ --run 311935 @@ -22,14 +22,16 @@ 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. +- `--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. -Currently, three different geometries of the ITS3 inner barrel are available: -- `ThreeLayersNoDeadZones` -- `ThreeLayers` -- `FourLayers` - 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: @@ -42,7 +44,6 @@ The run number is needed to retrieve objects from the CCDB. There are specific r - 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): @@ -77,6 +78,13 @@ o2-sim-digitizer-workflow -b --run --interactionRate 50000 \ ``` 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. + # Reconstruction In this step, clustering, vertexing and tracking are performed. This is obtained with the `o2-its3-reco-workflow`: @@ -84,10 +92,14 @@ In this step, clustering, vertexing and tracking are performed. This is obtained ```bash o2-its3-reco-workflow --tracking-mode async -b --run \ -—configKeyValues " -HBFUtils.runNumber=311935;ITSCATrackerParam.trackletsPerClusterLimit=20;ITSCATrackerParam.cellsPerC -lusterLimit=20;ITSVertexerParam.lowMultXYcut2=0." +HBFUtils.runNumber=311935;ITSCATrackerParam.trackletsPerClusterLimit=20;ITSCATrackerParam.cellsPerClusterLimit=20;ITSVertexerParam.lowMultXYcut2=0." ``` -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. +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. + +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"`. -> **_NOTE:_** reconstruction for the `FourLayers` geometry is not implemented yet. +> **_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: +```bash +${ENABLE_ITS3_4L:+-DENABLE_ITS3_4L=ON} +``` diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/DescriptorInnerBarrelITS3Param.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/DescriptorInnerBarrelITS3Param.h index 68766b644cf5f..df9d438e4e435 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/DescriptorInnerBarrelITS3Param.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/DescriptorInnerBarrelITS3Param.h @@ -39,11 +39,11 @@ enum class ITS3Version { struct DescriptorInnerBarrelITS3Param : public o2::conf::ConfigurableParamHelper { ITS3Version mVersion = ITS3Version::None; int mBuildLevel{0}; - double mGapY[4] = {0.1f, 0.1f, 0.1f, 0.1f}; - double mGapPhi[4] = {0.f, 0.f, 0.f, 0.f}; + double mGapY[4] = {0.f, 0.f, 0.f, 0.f}; + double mGapPhi[4] = {0.1f, 0.1f, 0.1f, 0.1f}; double mRadii[4] = {1.8f, 2.4f, 3.0f, 6.0f}; - double mLength{27.f}; - double mGapXDirection4thLayer{0.05f}; + double mLength{26.f}; + double mGapXDirection4thLayer{0.f}; std::string const& getITS3LayerConfigString() const; O2ParamDef(DescriptorInnerBarrelITS3Param, "DescriptorInnerBarrelITS3"); }; diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h index 321afe1d646a8..810fa19e882fa 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h @@ -40,20 +40,20 @@ class SegmentationSuperAlpide } SegmentationSuperAlpide(int layer = 0) : SegmentationSuperAlpide(layer, SuperAlpideParams::Instance().mPitchCol, SuperAlpideParams::Instance().mPitchRow, SuperAlpideParams::Instance().mDetectorThickness, DescriptorInnerBarrelITS3Param::Instance().mLength, DescriptorInnerBarrelITS3Param::Instance().mRadii) {} - double mRadii[4] = {1.8f, 2.4f, 3.0f, 6.0f}; ///< radii for different layers - const double mLength; ///< chip length - const int mLayer; ///< chip layer - const float mPitchCol; ///< pixel column size - const float mPitchRow; ///< pixel row size - const float mDetectorLayerThickness; ///< detector thickness - const int mNCols{static_cast(std::ceil(mLength / mPitchCol))}; ///< number of columns - const int mNRows{static_cast(std::ceil(double(mRadii[mLayer] + mDetectorLayerThickness - mSensorLayerThickness / 2.) * double(constants::math::PI) / double(mPitchRow)))}; ///< number of rows - const int mNPixels{mNRows * mNCols}; ///< total number of pixels - static constexpr float mPassiveEdgeReadOut = 0.; ///< width of the readout edge (Passive bottom) - static constexpr float mPassiveEdgeTop = 0.; ///< Passive area on top - static constexpr float mPassiveEdgeSide = 0.; ///< width of Passive area on left/right of the sensor - const float mActiveMatrixSizeCols{mPitchCol * mNCols}; ///< Active size along columns - const float mActiveMatrixSizeRows{mPitchRow * mNRows}; ///< Active size along rows + double mRadii[4] = {1.8f, 2.4f, 3.0f, 6.0f}; ///< radii for different layers + const double mLength; ///< chip length + const int mLayer; ///< chip layer + const float mPitchCol; ///< pixel column size + const float mPitchRow; ///< pixel row size + const float mDetectorLayerThickness; ///< detector thickness + const int mNCols{static_cast(std::ceil(mLength / mPitchCol))}; ///< number of columns + const int mNRows{static_cast(std::ceil(double(mRadii[mLayer] + mDetectorLayerThickness - mSensorLayerThickness / 2.) * double(constants::math::PI) / double(mPitchRow) * (mLayer == 3 ? 0.5 : 1.)))}; ///< number of rows + const int mNPixels{mNRows * mNCols}; ///< total number of pixels + static constexpr float mPassiveEdgeReadOut = 0.; ///< width of the readout edge (Passive bottom) + static constexpr float mPassiveEdgeTop = 0.; ///< Passive area on top + static constexpr float mPassiveEdgeSide = 0.; ///< width of Passive area on left/right of the sensor + const float mActiveMatrixSizeCols{mPitchCol * mNCols}; ///< Active size along columns + const float mActiveMatrixSizeRows{mPitchRow * mNRows}; ///< Active size along rows // effective thickness of sensitive layer, accounting for charge collection non-uniformity, https://alice.its.cern.ch/jira/browse/AOC-46 static constexpr float mSensorLayerThicknessEff = 28.e-4; ///< effective thickness of sensitive part diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SuperAlpideParams.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SuperAlpideParams.h index 0dd4d52d5060d..d3971efcd2431 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SuperAlpideParams.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SuperAlpideParams.h @@ -24,8 +24,8 @@ namespace its3 /// Segmentation parameters for Super ALPIDE chips struct SuperAlpideParams : public o2::conf::ConfigurableParamHelper { - float mPitchCol = 20.e-4; ///< Pixel column size (cm) - float mPitchRow = 20.e-4; ///< Pixel row size (cm) + float mPitchCol = 29.24e-4; ///< Pixel column size (cm) //FIXME: proxy value to get same resolution as ITS2 given incorrect sensor response + float mPitchRow = 26.88e-4; ///< Pixel row size (cm) //FIXME: proxy value to get same resolution as ITS2 given incorrect sensor response float mDetectorThickness = 50.e-4; ///< Detector thickness (cm) // boilerplate diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index 50ea7e73376bd..e14a526e31e01 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -38,8 +38,8 @@ #include "DetectorsCommonDataFormats/DetectorNameConf.h" #endif -void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.root", std::string hitfile = "o2sim_HitsIT3.root", - std::string inputGeom = "", std::string dictfile = "", bool batch = true) +void CheckClustersITS3(std::string clusfile = "o2clus_it3.root", std::string hitfile = "o2sim_HitsIT3.root", + std::string inputGeom = "o2sim_geometry.root", std::string dictfile = "", bool batch = true) { gROOT->SetBatch(batch); @@ -58,15 +58,6 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r std::vector hitVecPool; std::vector mc2hitVec; - // we assume that we have 2 chips per layer - const int nChipsPerLayer = 2; - std::vector segs{}; - for (int iLayer{0}; iLayer < nITS3layers; ++iLayer) { - for (int iChip{0}; iChip < nChipsPerLayer; ++iChip) { - segs.push_back(SegmentationSuperAlpide(iLayer)); - } - } - const int QEDSourceID = 99; // Clusters from this MC source correspond to QED electrons TFile fout("CheckClusters.root", "recreate"); @@ -78,6 +69,13 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::L2G)); // request cached transforms + std::vector segs{}; + for (int iLayer{0}; iLayer < gman->getNumberOfLayers() - 4; ++iLayer) { + for (int iChip{0}; iChip < gman->getNumberOfChipsPerLayer(iLayer); ++iChip) { + segs.push_back(SegmentationSuperAlpide(iLayer)); + } + } + // Hits TFile fileH(hitfile.data()); TTree* hitTree = (TTree*)fileH.Get("o2sim"); @@ -183,13 +181,13 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r auto chipID = cluster.getSensorID(); if (pattID == o2::its3::CompCluster::InvalidPatternID || dict.isGroup(pattID)) { o2::itsmft::ClusterPattern patt(pattIt); - locC = dict.getClusterCoordinates(cluster, patt, false); + locC = dict.getClusterCoordinates(cluster, patt, false, segs.size()); LOGP(info, "I am invalid and I am on chip {}", chipID); } else { - locC = dict.getClusterCoordinates(cluster); + locC = dict.getClusterCoordinates(cluster, segs.size()); errX = dict.getErrX(pattID); errZ = dict.getErrZ(pattID); - if (chipID / nChipsPerLayer >= nITS3layers) { + if (chipID >= segs.size()) { errX *= Segmentation::PitchRow; errZ *= Segmentation::PitchCol; } else { @@ -231,7 +229,7 @@ void CheckClustersITS3(int nITS3layers = 3, std::string clusfile = "o2clus_it3.r auto y0 = locHsta.Y(), dlty = locH.Y() - y0; auto z0 = locHsta.Z(), dltz = locH.Z() - z0; - if (chipID / nChipsPerLayer >= nITS3layers) { + if (chipID >= segs.size()) { auto r = (0.5 * (Segmentation::SensorLayerThickness - Segmentation::SensorLayerThicknessEff) - y0) / dlty; locH.SetXYZ(x0 + r * dltx, y0 + r * dlty, z0 + r * dltz); } else { diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C index 72f2c06fae234..acc11af572b49 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C @@ -38,7 +38,7 @@ #endif -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) +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) { gROOT->SetBatch(batch); @@ -62,8 +62,8 @@ void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root const int nChipsPerLayer = 2; std::vector segs{}; - for (int iLayer{0}; iLayer < nITS3layers; ++iLayer) { - for (int iChip{0}; iChip < nChipsPerLayer; ++iChip) { + for (int iLayer{0}; iLayer < gman->getNumberOfLayers() - 4; ++iLayer) { + for (int iChip{0}; iChip < gman->getNumberOfChipsPerLayer(iLayer); ++iChip) { segs.push_back(SegmentationSuperAlpide(iLayer)); } } @@ -172,7 +172,7 @@ void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root int chipID = (*digArr)[iDigit].getChipIndex(); - if (chipID / nChipsPerLayer < nITS3layers) { + if (chipID < segs.size()) { float xFlat{0.f}; segs[chipID].detectorToLocal(ix, iz, xFlat, z); segs[chipID].flatToCurved(xFlat, 0., x, y); @@ -214,7 +214,7 @@ void CheckDigitsITS3(int nITS3layers = 3, std::string digifile = "it3digits.root int row, col; float xlc = 0., zlc = 0.; - if (chipID / nChipsPerLayer < nITS3layers) { + if (chipID < segs.size()) { segs[chipID].localToDetector(locH.X(), locH.Z(), row, col); segs[chipID].detectorToLocal(row, col, xlc, zlc); } else { diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C index cfddc7716013a..8b0383246e7fc 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C @@ -73,6 +73,7 @@ void CheckTracksITS3(std::string tracfile = "o2trac_its3.root", std::string clusfile = "o2clus_it3.root", std::string kinefile = "o2sim_Kine.root", std::string magfile = "o2sim_grp.root", + std::string inputGeom = "o2sim_geometry.root", bool batch = true) { @@ -94,7 +95,7 @@ void CheckTracksITS3(std::string tracfile = "o2trac_its3.root", double orig[3] = {0., 0., 0.}; float bz = field->getBz(orig); // Geometry - o2::base::GeometryManager::loadGeometry(); + o2::base::GeometryManager::loadGeometry(inputGeom); auto gman = o2::its::GeometryTGeo::Instance(); // MC tracks diff --git a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C index e9517c94cbb16..1c53390946c01 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C @@ -86,13 +86,6 @@ void CreateDictionariesITS3(bool saveDeltas = false, LOGP(info, "Loaded external cluster dictionary with {} entries from {}", clusDictOld.getSize(), clusDictFile); } - static SegmentationSuperAlpide segmentations[6]{SegmentationSuperAlpide(0), - SegmentationSuperAlpide(0), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(2), - SegmentationSuperAlpide(2)}; // TODO: fix NLayers - TFile* fout = nullptr; TNtuple* nt = nullptr; if (saveDeltas) { @@ -110,6 +103,13 @@ void CreateDictionariesITS3(bool saveDeltas = false, gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::L2G)); // request cached transforms + std::vector segs{}; + for (int iLayer{0}; iLayer < gman->getNumberOfLayers() - 4; ++iLayer) { + for (int iChip{0}; iChip < gman->getNumberOfChipsPerLayer(iLayer); ++iChip) { + segs.push_back(SegmentationSuperAlpide(iLayer)); + } + } + // Hits TFile* fileH = nullptr; TTree* hitTree = nullptr; @@ -273,12 +273,12 @@ void CreateDictionariesITS3(bool saveDeltas = false, locH.SetXYZ(0.5 * (locH.X() + locHsta.X()), 0.5 * (locH.Y() + locHsta.Y()), 0.5 * (locH.Z() + locHsta.Z())); const auto locC = o2::its3::TopologyDictionary::getClusterCoordinates(cluster, pattern, false); float locXflat, locYflat; - if (cluster.getSensorID() < 6) - segmentations[cluster.getSensorID()].curvedToFlat(locC.X(), locC.Y(), locXflat, locYflat); + if (cluster.getSensorID() < segs.size()) + segs[cluster.getSensorID()].curvedToFlat(locC.X(), locC.Y(), locXflat, locYflat); dX = locH.X() - locC.X(); dZ = locH.Z() - locC.Z(); - dX /= (cluster.getSensorID() < 6) ? segmentations[cluster.getSensorID()].mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow; - dZ /= (cluster.getSensorID() < 6) ? segmentations[cluster.getSensorID()].mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol; + dX /= (cluster.getSensorID() < segs.size()) ? segs[cluster.getSensorID()].mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow; + dZ /= (cluster.getSensorID() < segs.size()) ? segs[cluster.getSensorID()].mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol; if (saveDeltas) { nt->Fill(topology.getHash(), dX, dZ); } diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h index df0d6b6d8a334..6eda6e98f0b52 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h @@ -123,6 +123,7 @@ class Clusterer struct ClustererThread { int id = -1; + int nLayersITS3 = 3; // number of ITS3 layers Clusterer* parent = nullptr; // parent clusterer // buffers for entries in preClusterIndices in 2 columns, to avoid boundary checks, we reserve // extra elements in the beginning and the end @@ -236,6 +237,8 @@ class Clusterer mChipsOld.resize(n); } + void setNumLayersITS3(int n) { mNlayersITS3 = n; } + ///< load the dictionary of cluster topologies void loadDictionary(const std::string& fileName) { mPattIdConverter.loadDictionary(fileName); } void setDictionary(const its3::TopologyDictionary* dict) { mPattIdConverter.setDictionary(dict); } @@ -246,6 +249,9 @@ class Clusterer private: void flushClusters(CompClusCont* compClus, MCTruth* labels); + // geometry options + int mNlayersITS3 = 3; ///< number of ITS3 layers + // clusterization options bool mContinuousReadout = true; ///< flag continuous readout diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h index 497df6cd9d696..ac0a507f0ca51 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h @@ -18,7 +18,6 @@ #include "DataFormatsITSMFT/TopologyDictionary.h" #include "DataFormatsITSMFT/ClusterPattern.h" #include "DataFormatsITS3/CompCluster.h" -#include "ITS3Base/SegmentationSuperAlpide.h" namespace o2 { @@ -128,14 +127,14 @@ class TopologyDictionary // array version of getClusterCoordinates template - std::array getClusterCoordinatesA(const its3::CompClusterExt& cl) const; + std::array getClusterCoordinatesA(const its3::CompClusterExt& cl, int nChipsITS3 = 6) const; /// Returns the local position of a compact cluster template - static std::array getClusterCoordinatesA(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true); + static std::array getClusterCoordinatesA(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true, int nChipsITS3 = 6); /// Returns the local position of a compact cluster - math_utils::Point3D getClusterCoordinates(const its3::CompClusterExt& cl) const; + math_utils::Point3D getClusterCoordinates(const its3::CompClusterExt& cl, int nChipsITS3 = 6) const; /// Returns the local position of a compact cluster - static math_utils::Point3D getClusterCoordinates(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true); + static math_utils::Point3D getClusterCoordinates(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true, int nChipsITS3 = 6); static TopologyDictionary* loadFrom(const std::string& fileName = "", const std::string& objName = "ccdb_object"); diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx index d6a859fff32a7..a14d44e5451d9 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx @@ -13,8 +13,6 @@ #include "ITS3Reconstruction/BuildTopologyDictionary.h" #include "ITS3Reconstruction/LookUp.h" -#include "ITS3Base/SegmentationSuperAlpide.h" -#include "ITSMFTBase/SegmentationAlpide.h" ClassImp(o2::its3::BuildTopologyDictionary); namespace o2 diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx index f459c4f1490d4..c959ba249d769 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx @@ -32,7 +32,7 @@ void Clusterer::process(int nThreads, PixelReader& reader, CompClusCont* compClu PatternCont* patterns, ROFRecCont* vecROFRec, MCTruth* labelsCl) { #ifdef _PERFORM_TIMING_ - mTimer.Start(kFALSE); + mTimer.Start(false); #endif if (nThreads < 1) { nThreads = 1; @@ -80,6 +80,7 @@ void Clusterer::process(int nThreads, PixelReader& reader, CompClusCont* compClu mThreads.resize(nThreads); for (int i = oldSz; i < nThreads; i++) { mThreads[i] = std::make_unique(this, i); + mThreads[i]->nLayersITS3 = mNlayersITS3; } } #ifdef WITH_OPENMP @@ -334,8 +335,12 @@ void Clusterer::ClustererThread::initChip(const ChipPixelData* curChipData, uint { // init chip with the 1st unmasked pixel (entry "from" in the mChipData) size = itsmft::SegmentationAlpide::NRows + 2; - if (curChipData->getChipID() < 6) { // TODO Fix for mutable layouts - SegmentationSuperAlpide seg(curChipData->getChipID() / 2); + int chipId = curChipData->getChipID(); + if (chipId < 6) { + SegmentationSuperAlpide seg(chipId / 2); + size = seg.mNRows + 2; + } else if (chipId < 10 && nLayersITS3 == 4) { + SegmentationSuperAlpide seg(3); size = seg.mNRows + 2; } if (column1) { @@ -386,7 +391,7 @@ void Clusterer::ClustererThread::updateChip(const ChipPixelData* curChipData, ui currCol = pix.getCol(); } - Bool_t orphan = true; + bool orphan = true; if (noLeftCol) { // check only the row above if (curr[row - 1] >= 0) { diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx index 4bf769e91439e..2fd770d06e57f 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx @@ -38,30 +38,32 @@ int loadROFrameDataITS3(its::TimeFrame* tf, std::vector segITS3; for (int iLayer{0}; iLayer < geom->getNumberOfLayers() - 4; ++iLayer) { - segITS3.push_back(SegmentationSuperAlpide(iLayer)); + for (int iChip{0}; iChip < geom->getNumberOfChipsPerLayer(iLayer); ++iChip) { + segITS3.push_back(SegmentationSuperAlpide(iLayer)); + } } + int nChipsITS3 = segITS3.size(); tf->mNrof = 0; for (auto& rof : rofs) { for (int clusterId{rof.getFirstEntry()}; clusterId < rof.getFirstEntry() + rof.getNEntries(); ++clusterId) { auto& c = clusters[clusterId]; - auto sensorID = c.getSensorID(); int layer = layer = geom->getLayer(sensorID); auto pattID = c.getPatternID(); o2::math_utils::Point3D locXYZ; float sigmaY2 = o2::its::ioutils::DefClusError2Row, sigmaZ2 = o2::its::ioutils::DefClusError2Col, sigmaYZ = 0; // Dummy COG errors (about half pixel size) - float pitchRow = ((layer < geom->getNumberOfLayers() - 4) ? segITS3[layer].mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow); - float pitchCol = ((layer < geom->getNumberOfLayers() - 4) ? segITS3[layer].mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol); + float pitchRow = ((sensorID < nChipsITS3) ? segITS3[sensorID].mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow); + float pitchCol = ((sensorID < nChipsITS3) ? segITS3[sensorID].mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol); if (pattID != its3::CompCluster::InvalidPatternID) { sigmaY2 = dict->getErr2X(pattID) * pitchRow * pitchRow; sigmaZ2 = dict->getErr2Z(pattID) * pitchCol * pitchCol; if (!dict->isGroup(pattID)) { - locXYZ = dict->getClusterCoordinates(c); + locXYZ = dict->getClusterCoordinates(c, nChipsITS3); } else { o2::itsmft::ClusterPattern patt(pattIt); - locXYZ = dict->getClusterCoordinates(c, patt); + locXYZ = dict->getClusterCoordinates(c, patt, nChipsITS3); sigmaY2 = patt.getRowSpan() * patt.getRowSpan() * pitchRow * pitchRow / 12.; sigmaZ2 = patt.getColumnSpan() * patt.getColumnSpan() * pitchCol * pitchCol / 12.; } @@ -69,7 +71,7 @@ int loadROFrameDataITS3(its::TimeFrame* tf, o2::itsmft::ClusterPattern patt(pattIt); sigmaY2 = patt.getRowSpan() * patt.getRowSpan() * pitchRow * pitchRow / 12.; sigmaZ2 = patt.getColumnSpan() * patt.getColumnSpan() * pitchCol * pitchCol / 12.; - locXYZ = dict->getClusterCoordinates(c, patt, false); + locXYZ = dict->getClusterCoordinates(c, patt, false, nChipsITS3); } // Transformation to the local --> global diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx index 6aeddce7820e0..34456a58103c9 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx @@ -142,17 +142,21 @@ void TopologyDictionary::getTopologyDistribution(const its3::TopologyDictionary& } } -math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3::CompClusterExt& cl) const +math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3::CompClusterExt& cl, int nChipsITS3) const { LOGP(debug, "Getting cluster coordinates from TopologyDictionaryITS3"); - static SegmentationSuperAlpide segmentations[6]{SegmentationSuperAlpide(0), - SegmentationSuperAlpide(0), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(2), - SegmentationSuperAlpide(2)}; // TODO: fix NLayers + static SegmentationSuperAlpide segmentations[10]{SegmentationSuperAlpide(0), + SegmentationSuperAlpide(0), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3)}; math_utils::Point3D locCl; - if (cl.getSensorID() >= 6) { // TODO: fix NLayers + if (cl.getSensorID() >= nChipsITS3) { o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * itsmft::SegmentationAlpide::PitchRow); locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * itsmft::SegmentationAlpide::PitchCol); @@ -167,15 +171,19 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3: return locCl; } -math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) +math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup, int nChipsITS3) { LOGP(debug, "Getting cluster coordinates from TopologyDictionaryITS3"); - static SegmentationSuperAlpide segmentations[6]{SegmentationSuperAlpide(0), - SegmentationSuperAlpide(0), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(2), - SegmentationSuperAlpide(2)}; // TODO: fix NLayers + static SegmentationSuperAlpide segmentations[10]{SegmentationSuperAlpide(0), + SegmentationSuperAlpide(0), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3)}; auto refRow = cl.getRow(); auto refCol = cl.getCol(); @@ -186,7 +194,7 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3: refCol -= round(zCOG); } math_utils::Point3D locCl; - if (cl.getSensorID() >= 6) { // TODO: fix NLayers + if (cl.getSensorID() >= nChipsITS3) { o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); } else { segmentations[cl.getSensorID()].detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); @@ -198,17 +206,21 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const its3: } template -std::array TopologyDictionary::getClusterCoordinatesA(const its3::CompClusterExt& cl) const +std::array TopologyDictionary::getClusterCoordinatesA(const its3::CompClusterExt& cl, int nChipsITS3) const { LOGP(debug, "Getting cluster coordinates from TopologyDictionaryITS3"); - static SegmentationSuperAlpide segmentations[6]{SegmentationSuperAlpide(0), - SegmentationSuperAlpide(0), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(2), - SegmentationSuperAlpide(2)}; // TODO: fix NLayers + static SegmentationSuperAlpide segmentations[10]{SegmentationSuperAlpide(0), + SegmentationSuperAlpide(0), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3)}; std::array locCl; - if (cl.getSensorID() >= 6) { // TODO: fix NLayers + if (cl.getSensorID() >= nChipsITS3) { o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * itsmft::SegmentationAlpide::PitchRow); locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * itsmft::SegmentationAlpide::PitchCol); @@ -224,15 +236,19 @@ std::array TopologyDictionary::getClusterCoordinatesA(const its3::CompClus } template -std::array TopologyDictionary::getClusterCoordinatesA(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) +std::array TopologyDictionary::getClusterCoordinatesA(const its3::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup, int nChipsITS3) { LOGP(debug, "Getting cluster coordinates from TopologyDictionaryITS3"); - static SegmentationSuperAlpide segmentations[6]{SegmentationSuperAlpide(0), - SegmentationSuperAlpide(0), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(1), - SegmentationSuperAlpide(2), - SegmentationSuperAlpide(2)}; // TODO: fix NLayers + static SegmentationSuperAlpide segmentations[10]{SegmentationSuperAlpide(0), + SegmentationSuperAlpide(0), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(1), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(2), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3), + SegmentationSuperAlpide(3)}; auto refRow = cl.getRow(); auto refCol = cl.getCol(); @@ -243,7 +259,7 @@ std::array TopologyDictionary::getClusterCoordinatesA(const its3::CompClus refCol -= round(zCOG); } std::array locCl; - if (cl.getSensorID() >= 6) { // TODO: fix NLayers + if (cl.getSensorID() >= nChipsITS3) { o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); } else { segmentations[cl.getSensorID()].detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h index 9b5e57338d71d..ad2bb1c15f1fb 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h @@ -44,10 +44,10 @@ class ITS3Layer : public TObject /// Default destructor ~ITS3Layer() override; - void createLayer(TGeoVolume* motherVolume); - void createLayerWithDeadZones(TGeoVolume* motherVolume); - void createCarbonFoamStructure(TGeoVolume* motherVolume); + void createLayer(TGeoVolume* motherVolume, double radiusBetweenLayer); + void createLayerWithDeadZones(TGeoVolume* motherVolume, double radiusBetweenLayer); void create4thLayer(TGeoVolume* motherVolume); + void createCarbonFoamStructure(TGeoVolume* motherVolume, double deltaR, bool fourthLayer = false); void setChipThick(double thick) { mChipThickness = thick; } void setLayerRadius(double radius) { mRadius = radius; } diff --git a/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx b/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx index 636ee3f4c0a44..82f611f3c3b54 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx @@ -209,6 +209,9 @@ ITS3Layer* DescriptorInnerBarrelITS3::createLayer(int idLayer, TGeoVolume* dest) return nullptr; } + int maxLayer = (mVersion != "FourLayers") ? 3 : 4; + double deltaR = (idLayer < maxLayer - 1) ? mLayerRadii[idLayer + 1] - mLayerRadii[idLayer] : 0.6; + mLayer[idLayer] = new ITS3Layer(idLayer); mLayer[idLayer]->setLayerRadius(mLayerRadii[idLayer]); mLayer[idLayer]->setLayerZLen(mLayerZLen[idLayer]); @@ -220,19 +223,19 @@ ITS3Layer* DescriptorInnerBarrelITS3::createLayer(int idLayer, TGeoVolume* dest) mLayer[idLayer]->setThickGluedFoam(mThickGluedFoam[idLayer]); mLayer[idLayer]->setBuildLevel(mBuildLevel[idLayer]); if (mVersion == "ThreeLayersNoDeadZones") { - mLayer[idLayer]->createLayer(dest); + mLayer[idLayer]->createLayer(dest, deltaR); } else if (mVersion == "ThreeLayers") { mLayer[idLayer]->setFringeChipWidth(mFringeChipWidth[idLayer]); mLayer[idLayer]->setMiddleChipWidth(mMiddleChipWidth[idLayer]); mLayer[idLayer]->setNumSubSensorsHalfLayer(mNumSubSensorsHalfLayer[idLayer]); - mLayer[idLayer]->createLayerWithDeadZones(dest); + mLayer[idLayer]->createLayerWithDeadZones(dest, deltaR); } else if (mVersion == "FourLayers") { mLayer[idLayer]->setFringeChipWidth(mFringeChipWidth[idLayer]); mLayer[idLayer]->setMiddleChipWidth(mMiddleChipWidth[idLayer]); mLayer[idLayer]->setNumSubSensorsHalfLayer(mNumSubSensorsHalfLayer[idLayer]); - if (idLayer != 3) { - mLayer[idLayer]->createLayerWithDeadZones(dest); - } else if (idLayer == 3) { + if (idLayer < maxLayer - 1) { + mLayer[idLayer]->createLayerWithDeadZones(dest, deltaR); + } else { mLayer[idLayer]->setGapXDirection(mGapXDirection4thLayer); mLayer[idLayer]->create4thLayer(dest); } diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index e3f2d309a67ab..d164d9604f73c 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -40,7 +40,7 @@ ITS3Layer::ITS3Layer(int lay) ITS3Layer::~ITS3Layer() = default; -void ITS3Layer::createLayer(TGeoVolume* motherVolume) +void ITS3Layer::createLayer(TGeoVolume* motherVolume, double radiusBetweenLayer) { TGeoMedium* medSi = gGeoManager->GetMedium("IT3_SI$"); TGeoMedium* medAir = gGeoManager->GetMedium("IT3_AIR$"); @@ -48,7 +48,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) double rmin = mRadius; double rmax = rmin + mChipThickness; double rminSensor = rmax - mSensorThickness; - double radiusBetweenLayer = 0.6 - mChipThickness; // FIXME: hard-coded distance between layers + radiusBetweenLayer = radiusBetweenLayer - mChipThickness; double phiGap = TMath::ASin(mGapPhi / 2.f / mRadius) * TMath::RadToDeg(); // degrees double piDeg = TMath::Pi() * TMath::RadToDeg(); // degrees @@ -71,7 +71,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) if (iEl == 4) { halfLayer[iEl] = new TGeoTubeSeg(rmin, rmax + radiusBetweenLayer, mZLen / 2, phiGap, piDeg - phiGap); volHalfLayer[iEl] = new TGeoVolume(names[iEl].data(), halfLayer[iEl], med); - createCarbonFoamStructure(volHalfLayer[iEl]); + createCarbonFoamStructure(volHalfLayer[iEl], radiusBetweenLayer); volHalfLayer[iEl]->SetVisibility(true); volHalfLayer[iEl]->SetLineColor(kGray + 2); } else if (iEl < 2) { @@ -102,7 +102,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) TGeoTranslation* translationTop = new TGeoTranslation(0., mGapY / 2, 0.); TGeoTranslation* translationBottom = new TGeoTranslation(0., -mGapY / 2, 0.); - TGeoRotation* rotationBottom = new TGeoRotation("", 180., 0., 0.); + TGeoRotation* rotationBottom = new TGeoRotation("", piDeg, 0., 0.); TGeoCombiTrans* rotoTranslationBottom = new TGeoCombiTrans(*translationBottom, *rotationBottom); @@ -115,7 +115,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) motherVolume->AddNode(volLayer, 1, nullptr); } -void ITS3Layer::createLayerWithDeadZones(TGeoVolume* motherVolume) +void ITS3Layer::createLayerWithDeadZones(TGeoVolume* motherVolume, double radiusBetweenLayer) { TGeoMedium* medSi = gGeoManager->GetMedium("IT3_SI$"); TGeoMedium* medAir = gGeoManager->GetMedium("IT3_AIR$"); @@ -126,7 +126,7 @@ void ITS3Layer::createLayerWithDeadZones(TGeoVolume* motherVolume) double rmed = (rmax + rmin) / 2; // width of sensors of layers is calculated from r and chips' widths double widthSensor = (TMath::Pi() * rmed - (mNumSubSensorsHalfLayer - 1) * mMiddleChipWidth - 2 * mFringeChipWidth) / mNumSubSensorsHalfLayer; - double radiusBetweenLayer = 0.6 - mChipThickness; // FIXME: hard coded distance between layers + radiusBetweenLayer = radiusBetweenLayer - mChipThickness; double phiGap = TMath::ASin(mGapPhi / 2.f / mRadius) * TMath::RadToDeg(); // degrees double piDeg = TMath::Pi() * TMath::RadToDeg(); // degrees @@ -181,7 +181,7 @@ void ITS3Layer::createLayerWithDeadZones(TGeoVolume* motherVolume) volHalfLayer[iEl] = new TGeoVolume(names[iEl].data(), halfLayer[iEl][0], med); volHalfLayer[iEl]->SetUniqueID(mChipTypeID); if (iEl == 4) { - createCarbonFoamStructure(volHalfLayer[iEl]); + createCarbonFoamStructure(volHalfLayer[iEl], radiusBetweenLayer); volHalfLayer[iEl]->SetVisibility(true); volHalfLayer[iEl]->SetLineColor(kGray + 2); } else if (iEl == 1) { @@ -197,7 +197,7 @@ void ITS3Layer::createLayerWithDeadZones(TGeoVolume* motherVolume) TGeoTranslation* translationTop = new TGeoTranslation(0., mGapY / 2, 0.); TGeoTranslation* translationBottom = new TGeoTranslation(0., -mGapY / 2, 0.); - TGeoRotation* rotationBottom = new TGeoRotation("", 180., 0., 0.); + TGeoRotation* rotationBottom = new TGeoRotation("", piDeg, 0., 0.); TGeoCombiTrans* rotoTranslationBottom = new TGeoCombiTrans(*translationBottom, *rotationBottom); @@ -239,24 +239,24 @@ void ITS3Layer::create4thLayer(TGeoVolume* motherVolume) std::array, nElements - 1> quarterLayer{}; TGeoVolume* volQuarterLayer[nElements - 1]; - for (int iEl{0}; iEl < nElements - 1; ++iEl) { + for (int iEl{0}; iEl < nElements - 2; ++iEl) { // we need only 2 half barrels as usual, so we stop at the stave TGeoMedium* med = (iEl <= 2) ? medSi : medAir; for (int iObj{0}; iObj < nObjPerElement[iEl]; ++iObj) { if (iEl == 0) { // subsensors (mNumSubSensorsHalfLayer sectors with dead zones) if (iObj == 0) { - quarterLayer[iEl].push_back(new TGeoTubeSeg(Form("subsens%dlayer%d", iObj, mLayerNumber), rminSensor, rmax, mZLen / 2, TMath::RadToDeg() * mFringeChipWidth / rmed + phiGap, TMath::RadToDeg() * (mFringeChipWidth + widthSensor) / rmed)); + quarterLayer[iEl].push_back(new TGeoTubeSeg(Form("subsens%dlayer%d", iObj, mLayerNumber), rminSensor, rmax, mZLen / 2, piDeg / 4. + TMath::RadToDeg() * mFringeChipWidth / rmed + phiGap, piDeg / 4. + TMath::RadToDeg() * (mFringeChipWidth + widthSensor) / rmed)); } else if (iObj == mNumSubSensorsHalfLayer - 1) { - quarterLayer[iEl].push_back(new TGeoTubeSeg(Form("subsens%dlayer%d", iObj, mLayerNumber), rminSensor, rmax, mZLen / 2, TMath::RadToDeg() * (mFringeChipWidth + iObj * widthSensor + iObj * mMiddleChipWidth) / rmed, TMath::RadToDeg() * 0.5 * TMath::Pi() - TMath::RadToDeg() * mFringeChipWidth / rmed - phiGap)); + quarterLayer[iEl].push_back(new TGeoTubeSeg(Form("subsens%dlayer%d", iObj, mLayerNumber), rminSensor, rmax, mZLen / 2, piDeg / 4. + TMath::RadToDeg() * (mFringeChipWidth + iObj * widthSensor + iObj * mMiddleChipWidth) / rmed, 3. / 4. * piDeg - TMath::RadToDeg() * mFringeChipWidth / rmed - phiGap)); } else { - quarterLayer[iEl].push_back(new TGeoTubeSeg(Form("subsens%dlayer%d", iObj, mLayerNumber), rminSensor, rmax, mZLen / 2, TMath::RadToDeg() * (mFringeChipWidth + iObj * widthSensor + iObj * mMiddleChipWidth) / rmed, TMath::RadToDeg() * (mFringeChipWidth + (iObj + 1) * widthSensor + iObj * mMiddleChipWidth) / rmed)); + quarterLayer[iEl].push_back(new TGeoTubeSeg(Form("subsens%dlayer%d", iObj, mLayerNumber), rminSensor, rmax, mZLen / 2, piDeg / 4. + TMath::RadToDeg() * (mFringeChipWidth + iObj * widthSensor + iObj * mMiddleChipWidth) / rmed, piDeg / 4. + TMath::RadToDeg() * (mFringeChipWidth + (iObj + 1) * widthSensor + iObj * mMiddleChipWidth) / rmed)); } } else if (iEl == 1) { - quarterLayer[iEl].push_back(new TGeoTubeSeg(rminSensor, rmax, mZLen / 2, phiGap, TMath::RadToDeg() * 0.5 * TMath::Pi() - phiGap)); + quarterLayer[iEl].push_back(new TGeoTubeSeg(rminSensor, rmax, mZLen / 2, phiGap, piDeg / 4. + piDeg * 3 / 4. - phiGap)); } else if (iEl == 2) { - quarterLayer[iEl].push_back(new TGeoTubeSeg(rmin, rmax, mZLen / 2, phiGap, TMath::RadToDeg() * 0.5 * TMath::Pi() - phiGap)); + quarterLayer[iEl].push_back(new TGeoTubeSeg(rmin, rmax, mZLen / 2, piDeg / 4. + phiGap, piDeg * 3 / 4. - phiGap)); } else { // all the others are simply quarter cylinders filling all the space - quarterLayer[iEl].push_back(new TGeoTubeSeg(rmin, rmax, mZLen / 2, phiGap, TMath::RadToDeg() * 0.5 * TMath::Pi() - phiGap)); + quarterLayer[iEl].push_back(new TGeoTubeSeg(rmin, rmax, mZLen / 2, piDeg / 4. + phiGap, piDeg * 3 / 4. - phiGap)); } } @@ -274,7 +274,11 @@ void ITS3Layer::create4thLayer(TGeoVolume* motherVolume) } else { volQuarterLayer[iEl] = new TGeoVolume(names[iEl].data(), quarterLayer[iEl][0], med); volQuarterLayer[iEl]->SetUniqueID(mChipTypeID); - if (iEl == 1) { + if (iEl == 4) { + // createCarbonFoamStructure(volQuarterLayer[iEl], 0., true); + volQuarterLayer[iEl]->SetVisibility(true); + volQuarterLayer[iEl]->SetLineColor(kGray + 2); + } else if (iEl == 1) { volQuarterLayer[iEl]->SetVisibility(true); volQuarterLayer[iEl]->SetLineColor(kBlue + 2); } @@ -285,41 +289,44 @@ void ITS3Layer::create4thLayer(TGeoVolume* motherVolume) } } - TGeoTranslation* translationTopRight = new TGeoTranslation(mGapXDirection / 2, mGapY / 2, 0.); + TGeoTranslation* translationTopRight = new TGeoTranslation(mGapXDirection / 2, 0., 0.); + TGeoRotation* rotationTopRight = new TGeoRotation("", -piDeg / 4, 0., 0.); + TGeoCombiTrans* rotoTranslationTopRight = new TGeoCombiTrans(*translationTopRight, *rotationTopRight); - TGeoTranslation* translationTopLeft = new TGeoTranslation(-mGapXDirection / 2, mGapY / 2, 0.); - TGeoRotation* rotationTopLeft = new TGeoRotation("", 90., 0., 0.); + TGeoTranslation* translationTopLeft = new TGeoTranslation(-mGapXDirection / 2, 0., 0.); + TGeoRotation* rotationTopLeft = new TGeoRotation("", piDeg / 4, 0., 0.); TGeoCombiTrans* rotoTranslationTopLeft = new TGeoCombiTrans(*translationTopLeft, *rotationTopLeft); - TGeoTranslation* translationBottomLeft = new TGeoTranslation(-mGapXDirection / 2, -mGapY / 2, 0.); - TGeoRotation* rotationBottomLeft = new TGeoRotation("", 180., 0., 0.); - TGeoCombiTrans* rotoTranslationBottomLeft = new TGeoCombiTrans(*translationBottomLeft, *rotationBottomLeft); + TGeoVolumeAssembly* halfLayer = new TGeoVolumeAssembly(names[nElements - 2].data()); + halfLayer->AddNode(volQuarterLayer[nElements - 3], 0, rotoTranslationTopRight); + halfLayer->AddNode(volQuarterLayer[nElements - 3], 1, rotoTranslationTopLeft); - TGeoTranslation* translationBottomRight = new TGeoTranslation(mGapXDirection / 2, -mGapY / 2, 0.); - TGeoRotation* rotationBottomRight = new TGeoRotation("", 270., 0., 0.); - TGeoCombiTrans* rotoTranslationBottomRight = new TGeoCombiTrans(*translationBottomRight, *rotationBottomRight); + TGeoTranslation* translationTop = new TGeoTranslation(0., mGapY / 2, 0.); + TGeoTranslation* translationBottom = new TGeoTranslation(0., -mGapY / 2, 0.); + TGeoRotation* rotationBottom = new TGeoRotation("", piDeg, 0., 0.); + TGeoCombiTrans* rotoTranslationBottom = new TGeoCombiTrans(*translationBottom, *rotationBottom); TGeoVolumeAssembly* volLayer = new TGeoVolumeAssembly(names[nElements - 1].data()); - volLayer->AddNode(volQuarterLayer[nElements - 2], 0, translationTopRight); - volLayer->AddNode(volQuarterLayer[nElements - 2], 1, rotoTranslationTopLeft); - volLayer->AddNode(volQuarterLayer[nElements - 2], 2, rotoTranslationBottomLeft); - volLayer->AddNode(volQuarterLayer[nElements - 2], 3, rotoTranslationBottomRight); + volLayer->AddNode(halfLayer, 0, translationTop); + volLayer->AddNode(halfLayer, 1, rotoTranslationBottom); // Finally put everything in the mother volume LOGP(debug, "Inserting {} inside {}", volLayer->GetName(), motherVolume->GetName()); motherVolume->AddNode(volLayer, 1, nullptr); } -void ITS3Layer::createCarbonFoamStructure(TGeoVolume* motherVolume) +void ITS3Layer::createCarbonFoamStructure(TGeoVolume* motherVolume, double deltaR, bool fourthLayer) { TGeoMedium* medCarbonFoam = (mBuildLevel < 1) ? gGeoManager->GetMedium("IT3_ERGDUOCEL$") : gGeoManager->GetMedium("IT3_AIR$"); // if build level >= 1 we do not put carbon foam but air TGeoMedium* medGlue = (mBuildLevel < 2) ? gGeoManager->GetMedium("IT3_IMPREG_FLEECE$") : gGeoManager->GetMedium("IT3_AIR$"); // if build level >= 2 we do not put glue but air double rmax = mRadius + mChipThickness; - double radiusBetweenLayer = 0.6 - mChipThickness; // FIXME: hard coded distance between layers + double radiusBetweenLayer = deltaR - mChipThickness; double rmedFoam = rmax + radiusBetweenLayer / 2; double phiGap = TMath::ASin(mGapPhi / 2.f / mRadius) * TMath::RadToDeg(); // degrees double piDeg = TMath::Pi() * TMath::RadToDeg(); // degrees + double phiMin = (fourthLayer) ? piDeg / 4 : 0.; // degrees + double phiMax = (fourthLayer) ? piDeg * 3 / 4 : piDeg; // degrees TGeoTranslation* transSemicircle[2]; transSemicircle[0] = new TGeoTranslation("transSemicircleFoam0", 0, 0, (mZLen - mLengthSemiCircleFoam) / 2); @@ -328,15 +335,15 @@ void ITS3Layer::createCarbonFoamStructure(TGeoVolume* motherVolume) transSemicircle[1]->RegisterYourself(); TGeoTubeSeg* subGluedFoamBottom[4]; - subGluedFoamBottom[0] = new TGeoTubeSeg(Form("subgluedfoambottom0layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, mLengthSemiCircleFoam / 2, phiGap, piDeg - phiGap); - subGluedFoamBottom[1] = new TGeoTubeSeg(Form("subgluedfoambottom1layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, mLengthSemiCircleFoam / 2, phiGap, piDeg - phiGap); - subGluedFoamBottom[2] = new TGeoTubeSeg(Form("subgluedfoambottom2layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, phiGap, TMath::RadToDeg() * mHeightStripFoam / rmedFoam); - subGluedFoamBottom[3] = new TGeoTubeSeg(Form("subgluedfoambottom3layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, TMath::RadToDeg() * (TMath::Pi() - (mHeightStripFoam / rmedFoam)), piDeg - phiGap); + subGluedFoamBottom[0] = new TGeoTubeSeg(Form("subgluedfoambottom0layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, mLengthSemiCircleFoam / 2, phiMin + phiGap, phiMax - phiGap); + subGluedFoamBottom[1] = new TGeoTubeSeg(Form("subgluedfoambottom1layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, mLengthSemiCircleFoam / 2, phiMin + phiGap, phiMax - phiGap); + subGluedFoamBottom[2] = new TGeoTubeSeg(Form("subgluedfoambottom2layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, phiMin + phiGap, phiMin + TMath::RadToDeg() * mHeightStripFoam / rmedFoam + phiGap); + subGluedFoamBottom[3] = new TGeoTubeSeg(Form("subgluedfoambottom3layer%d", mLayerNumber), rmax, rmax + mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, phiMax - TMath::RadToDeg() * (mHeightStripFoam / rmedFoam) - phiGap, phiMax - phiGap); TGeoTubeSeg* subGluedFoamTop[4]; - subGluedFoamTop[0] = new TGeoTubeSeg(Form("subgluedfoamtop0layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, mLengthSemiCircleFoam / 2, phiGap, piDeg - phiGap); - subGluedFoamTop[1] = new TGeoTubeSeg(Form("subgluedfoamtop1layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, mLengthSemiCircleFoam / 2, phiGap, piDeg - phiGap); - subGluedFoamTop[2] = new TGeoTubeSeg(Form("subgluedfoamtop2layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, (mZLen - mLengthSemiCircleFoam) / 2, phiGap, TMath::RadToDeg() * mHeightStripFoam / rmedFoam); - subGluedFoamTop[3] = new TGeoTubeSeg(Form("subgluedfoamtop3layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, (mZLen - mLengthSemiCircleFoam) / 2, TMath::RadToDeg() * (TMath::Pi() - (mHeightStripFoam / rmedFoam)), piDeg - phiGap); + subGluedFoamTop[0] = new TGeoTubeSeg(Form("subgluedfoamtop0layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, mLengthSemiCircleFoam / 2, phiMin + phiGap, phiMax - phiGap); + subGluedFoamTop[1] = new TGeoTubeSeg(Form("subgluedfoamtop1layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, mLengthSemiCircleFoam / 2, phiMin + phiGap, phiMax - phiGap); + subGluedFoamTop[2] = new TGeoTubeSeg(Form("subgluedfoamtop2layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, (mZLen - mLengthSemiCircleFoam) / 2, phiMin + phiGap, phiMin + TMath::RadToDeg() * mHeightStripFoam / rmedFoam + phiGap); + subGluedFoamTop[3] = new TGeoTubeSeg(Form("subgluedfoamtop3layer%d", mLayerNumber), rmax + radiusBetweenLayer - mThickGluedFoam, rmax + radiusBetweenLayer, (mZLen - mLengthSemiCircleFoam) / 2, phiMax - TMath::RadToDeg() * (mHeightStripFoam / rmedFoam) - phiGap, phiMax - phiGap); std::string subGluedFoamsNames = ""; for (int iObj{0}; iObj < 2; ++iObj) { @@ -356,10 +363,10 @@ void ITS3Layer::createCarbonFoamStructure(TGeoVolume* motherVolume) motherVolume->AddNode(volGlue, 1, nullptr); TGeoTubeSeg* subFoam[4]; - subFoam[0] = new TGeoTubeSeg(Form("subfoam0layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, mLengthSemiCircleFoam / 2, 0., piDeg); - subFoam[1] = new TGeoTubeSeg(Form("subfoam1layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, mLengthSemiCircleFoam / 2, 0., piDeg); - subFoam[2] = new TGeoTubeSeg(Form("subfoam2layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, 0., TMath::RadToDeg() * mHeightStripFoam / rmedFoam); - subFoam[3] = new TGeoTubeSeg(Form("subfoam3layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, TMath::RadToDeg() * (TMath::Pi() - (mHeightStripFoam / rmedFoam)), piDeg); + subFoam[0] = new TGeoTubeSeg(Form("subfoam0layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, mLengthSemiCircleFoam / 2, phiMin + phiGap, phiMax - phiGap); + subFoam[1] = new TGeoTubeSeg(Form("subfoam1layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, mLengthSemiCircleFoam / 2, phiMin + phiGap, phiMax - phiGap); + subFoam[2] = new TGeoTubeSeg(Form("subfoam2layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, phiMin + phiGap, phiMin + TMath::RadToDeg() * mHeightStripFoam / rmedFoam + phiGap); + subFoam[3] = new TGeoTubeSeg(Form("subfoam3layer%d", mLayerNumber), rmax + mThickGluedFoam, rmax + radiusBetweenLayer - mThickGluedFoam, (mZLen - mLengthSemiCircleFoam) / 2, phiMax - TMath::RadToDeg() * (mHeightStripFoam / rmedFoam) - phiGap, phiMax - phiGap); std::string subFoamNames = ""; for (int iObj{0}; iObj < 2; ++iObj) { diff --git a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h index f31c37d237f53..8146e621f4df1 100644 --- a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h +++ b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h @@ -56,6 +56,7 @@ class TrackerDPL : public framework::Task bool mRunVertexer = true; bool mCosmicsProcessing = false; int mUseTriggers = 0; + int mNLayers = 7; std::string mMode = "sync"; std::shared_ptr mGGCCDBRequest; const o2::its3::TopologyDictionary* mDict = nullptr; diff --git a/Detectors/Upgrades/ITS3/workflow/src/ClustererSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/ClustererSpec.cxx index 8b47eddae3c85..e6c9b5bc4b910 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/ClustererSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/ClustererSpec.cxx @@ -30,6 +30,7 @@ #include "ITSMFTBase/DPLAlpideParam.h" #include "CommonConstants/LHCConstants.h" #include "DetectorsCommonDataFormats/DetectorNameConf.h" +#include "ITS3Base/DescriptorInnerBarrelITS3Param.h" using namespace o2::framework; @@ -40,17 +41,38 @@ namespace its3 void ClustererDPL::init(InitContext& ic) { + auto& paramGeom = DescriptorInnerBarrelITS3Param::Instance(); mClusterer = std::make_unique(); - mClusterer->setNChips(o2::itsmft::ChipMappingITS::getNChips(o2::itsmft::ChipMappingITS::MB) + o2::itsmft::ChipMappingITS::getNChips(o2::itsmft::ChipMappingITS::OB) + 6); // FIXME + int nChipsOB = o2::itsmft::ChipMappingITS::getNChips(o2::itsmft::ChipMappingITS::MB) + o2::itsmft::ChipMappingITS::getNChips(o2::itsmft::ChipMappingITS::OB); + int nChipsIB = 6; + int nLayersITS3 = 3; + if (paramGeom.getITS3LayerConfigString() == "FourLayers") { + nChipsIB += 4; + nLayersITS3 = 4; + } + mClusterer->setNChips(nChipsOB + nChipsIB); + mClusterer->setNumLayersITS3(nLayersITS3); mUseClusterDictionary = !ic.options().get("ignore-cluster-dictionary"); o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); mState = 1; + + auto filenameGRP = ic.options().get("grp-file"); + const auto grp = o2::parameters::GRPObject::loadFrom(filenameGRP.c_str()); + + if (grp) { + mClusterer->setContinuousReadOut(grp->isDetContinuousReadOut("IT3")); + } else { + LOG(error) << "Cannot retrieve GRP from the " << filenameGRP.c_str() << " file !"; + mState = 0; + return; + } + mClusterer->print(); } void ClustererDPL::run(ProcessingContext& pc) { - updateTimeDependentParams(pc); + // updateTimeDependentParams(pc); auto digits = pc.inputs().get>("digits"); auto rofs = pc.inputs().get>("ROframes"); @@ -115,7 +137,6 @@ void ClustererDPL::updateTimeDependentParams(ProcessingContext& pc) pc.inputs().get("cldict"); // just to trigger the finaliseCCDB pc.inputs().get*>("alppar"); pc.inputs().get*>("cluspar"); - mClusterer->setContinuousReadOut(o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS)); // settings for the fired pixel overflow masking const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); const auto& clParams = o2::itsmft::ClustererParam::Instance(); @@ -176,7 +197,7 @@ DataProcessorSpec getClustererSpec(bool useMC) inputs.emplace_back("cluspar", "ITS", "CLUSPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/ClustererParam")); inputs.emplace_back("alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam")); auto ggRequest = std::make_shared(false, // orbitResetTime - true, // GRPECS=true + false, // GRPECS false, // GRPLHCIF false, // GRPMagField false, // askMatLUT @@ -201,6 +222,7 @@ DataProcessorSpec getClustererSpec(bool useMC) outputs, AlgorithmSpec{adaptFromTask(ggRequest, useMC)}, Options{ + {"grp-file", VariantType::String, "o2sim_grp.root", {"Name of the grp file"}}, {"ignore-cluster-dictionary", VariantType::Bool, false, {"do not use cluster dictionary, always store explicit patterns"}}}}; } diff --git a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx index 899645dfcd902..f66454ebad52e 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx @@ -30,6 +30,7 @@ #include "DataFormatsTRD/TriggerRecord.h" #include #include "ITSReconstruction/FastMultEstConfig.h" +#include "ITS3Base/DescriptorInnerBarrelITS3Param.h" // #include "ITS3Reconstruction/FastMultEst.h" namespace o2 @@ -57,6 +58,11 @@ void TrackerDPL::init(InitContext& ic) mTimer.Stop(); mTimer.Reset(); o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); + auto& paramGeom = DescriptorInnerBarrelITS3Param::Instance(); + if (paramGeom.getITS3LayerConfigString() == "FourLayers") { + mNLayers = 8; + } + mChainITS.reset(mRecChain->AddChain()); mVertexer = std::make_unique(mChainITS->GetITSVertexerTraits()); mTracker = std::make_unique(mChainITS->GetITSTrackerTraits()); @@ -120,7 +126,21 @@ void TrackerDPL::init(InitContext& ic) for (auto& params : trackParams) { params.CorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT; + params.NLayers = mNLayers; + if (params.NLayers > 7) { // shift by one position OB radii and lengths + params.LayerZ.resize(params.NLayers); + params.LayerRadii.resize(params.NLayers); + for (int iLayer{params.NLayers - 1}; iLayer >= params.NLayers - 4; iLayer--) { + params.LayerZ[iLayer] = params.LayerZ[iLayer - 1]; + params.LayerRadii[iLayer] = params.LayerRadii[iLayer - 1]; + } + } + for (int iLayer{0}; iLayer < params.NLayers - 4; ++iLayer) { // initialise ITS3 radii and lengths + params.LayerZ[iLayer] = paramGeom.mLength; + params.LayerRadii[iLayer] = paramGeom.mRadii[iLayer]; + } } + mTracker->setParameters(trackParams); } @@ -180,8 +200,8 @@ void TrackerDPL::run(ProcessingContext& pc) auto& vertROFvec = pc.outputs().make>(Output{"IT3", "VERTICESROF", 0, Lifetime::Timeframe}); auto& vertices = pc.outputs().make>(Output{"IT3", "VERTICES", 0, Lifetime::Timeframe}); - bool continuous = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS); TimeFrame* timeFrame = mChainITS->GetITSTimeframe(); + timeFrame->resizeVectors(mNLayers); mTracker->adoptTimeFrame(*timeFrame); mTracker->setBz(o2::base::Propagator::Instance()->getNominalBz()); @@ -359,7 +379,7 @@ DataProcessorSpec getTrackerSpec(bool useMC, int trgType, const std::string& trM inputs.emplace_back("cldict", "IT3", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("IT3/Calib/ClusterDictionary")); inputs.emplace_back("alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam")); auto ggRequest = std::make_shared(false, // orbitResetTime - true, // GRPECS=true + false, // GRPECS false, // GRPLHCIF true, // GRPMagField true, // askMatLUT