From a4bbdeda91e4436a0b47f6c2448ae52e002f94b1 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 27 Nov 2024 15:22:35 +0100 Subject: [PATCH 01/34] ITS3: Add metalstack to geometry Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/SpecsV2.h | 17 +++++++++++++---- .../ITS3/macros/test/TestSensorGeometry.C | 2 +- .../include/ITS3Simulation/ITS3Layer.h | 1 + .../Upgrades/ITS3/simulation/src/ITS3Layer.cxx | 11 ++++++++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index d3efde58d0e0d..03264ae80a3d8 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -106,16 +106,25 @@ constexpr std::array nHoles{11, 11, 11}; // how constexpr std::array radiusHoles{1.0 * mm, 1.0 * mm, 2.0 * mm}; // what is the radius of the holes for each layer? constexpr EColor color{kGray}; } // namespace carbonfoam +namespace metalstack +{ +constexpr float thickness{5 * mu}; // physical thickness of the copper metal stack +constexpr float length{segment::length}; +constexpr float width{segment::width}; +constexpr EColor color{kBlack}; +} // namespace metalstack constexpr unsigned int nLayers{3}; constexpr unsigned int nTotLayers{7}; constexpr unsigned int nSensorsIB{2 * nLayers}; constexpr float equatorialGap{1 * mm}; constexpr std::array nSegments{3, 4, 5}; -constexpr float thickness{50 * mu}; //< Physical Thickness of chip -constexpr float effThickness{66 * mu}; //< Physical thickness + metal substrate +constexpr float epitaxialThickness{10 * mu}; +constexpr float psubThickness{40 * mu}; +constexpr float thickness{epitaxialThickness + psubThickness}; // physical thickness of chip +constexpr float effThickness{epitaxialThickness + psubThickness / 2.0}; // correction to the epitaxial layer constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. -constexpr std::array radiiInner{radii[0] - thickness / 2.f, radii[1] - thickness / 2.f, radii[2] - thickness / 2.f}; // inner radius -constexpr std::array radiiOuter{radii[0] + thickness / 2.f, radii[1] + thickness / 2.f, radii[2] + thickness / 2.f}; // inner radius +constexpr std::array radiiInner{radii[0] - thickness / 2.0, radii[1] - thickness / 2.0, radii[2] - thickness / 2.0}; // inner radius +constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // inner radius namespace detID { constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU diff --git a/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C b/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C index 1a0ec73e34f31..b3221fd2dfbc2 100644 --- a/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C +++ b/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C @@ -45,7 +45,7 @@ void TestSensorGeometry(bool checkFull = false) if (checkFull) { gGeoManager->CheckGeometryFull(); } - gGeoManager->CheckOverlaps(0.0001); + gGeoManager->CheckOverlaps(0.00001); TIter nextOverlap{gGeoManager->GetListOfOverlaps()}; while ((obj = (TObject*)nextOverlap())) { LOGP(info, "Overlap in {}", obj->GetName()); diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h index 7543650e04a71..8e0b74cc90617 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h @@ -82,6 +82,7 @@ class ITS3Layer TGeoMedium* mSilicon{nullptr}; TGeoMedium* mAir{nullptr}; TGeoMedium* mCarbon{nullptr}; + TGeoMedium* mCopper{nullptr}; void getMaterials(bool create = false); TGeoMedium* getMaterial(const char* matName, bool create = false); diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index 26e47e03057c2..8b5fdfc1a1a63 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -47,6 +47,7 @@ void ITS3Layer::getMaterials(bool create) mSilicon = getMaterial("IT3_SI$", create); mAir = getMaterial("IT3_AIR$", create); mCarbon = getMaterial("IT3_CARBON$", create); + mCopper = getMaterial("IT3_COPPER$", create); } TGeoMedium* ITS3Layer::getMaterial(const char* matName, bool create) @@ -276,11 +277,19 @@ void ITS3Layer::createChip() mChip = new TGeoVolumeAssembly(its3TGeo::getITS3ChipPattern(mNLayer)); mChip->VisibleDaughters(); + auto phiOffset = constants::segment::width / mR * o2m::Rad2Deg; for (unsigned int i{0}; i < constants::nSegments[mNLayer]; ++i) { - double phiOffset = constants::segment::width / mR * o2m::Rad2Deg; auto rot = new TGeoRotation("", 0, 0, phiOffset * i); mChip->AddNode(mSegment, i, rot); } + + // Add metal stack positioned radially outward + auto zMoveMetal = new TGeoTranslation(0, 0, constants::metalstack::length / 2. - constants::segment::lec::length); + auto metal = new TGeoTubeSeg(mRmax, mRmax + constants::metalstack::thickness, constants::metalstack::length / 2., 0, 3.0 * phiOffset); + auto metalVol = new TGeoVolume(Form("metal%d", mNLayer), metal, mCopper); + metalVol->SetLineColor(constants::metalstack::color); + metalVol->RegisterYourself(); + mChip->AddNode(metalVol, 0, zMoveMetal); } void ITS3Layer::createCarbonForm() From be3c6c04f5446525bd0b18459c792c8f7bf782a8 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 23 Jan 2025 15:17:09 +0100 Subject: [PATCH 02/34] ITS3: correction to epitaxial layer Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h | 1 + Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h index dbdf90574ce5d..d49714829a2d8 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h @@ -69,6 +69,7 @@ class SegmentationSuperAlpide static constexpr float mPitchRow{constants::pixelarray::width / static_cast(mNRows)}; static constexpr float mSensorLayerThickness{constants::thickness}; static constexpr float mSensorLayerThicknessEff{constants::effThickness}; + static constexpr float mSensorLayerThicknessCorr{constants::corrThickness}; static constexpr std::array mRadii{constants::radii}; /// Transformation from the curved surface to a flat surface diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index 03264ae80a3d8..394a3674e84ec 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -118,10 +118,11 @@ constexpr unsigned int nTotLayers{7}; constexpr unsigned int nSensorsIB{2 * nLayers}; constexpr float equatorialGap{1 * mm}; constexpr std::array nSegments{3, 4, 5}; -constexpr float epitaxialThickness{10 * mu}; -constexpr float psubThickness{40 * mu}; +constexpr float epitaxialThickness{10 * mu}; // eptixial layer (charge collection) +constexpr float psubThickness{40 * mu}; // silicon substrate constexpr float thickness{epitaxialThickness + psubThickness}; // physical thickness of chip -constexpr float effThickness{epitaxialThickness + psubThickness / 2.0}; // correction to the epitaxial layer +constexpr float effThickness{epitaxialThickness / 2.0 + psubThickness}; // effective physical thickness +constexpr float corrThickness{effThickness - thickness / 2.0}; // correction to get into the epitxial layer constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. constexpr std::array radiiInner{radii[0] - thickness / 2.0, radii[1] - thickness / 2.0, radii[2] - thickness / 2.0}; // inner radius constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // inner radius From e0c063344e207d82d87e811d95cc6c4d6c39464d Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 18 Dec 2024 10:19:33 +0100 Subject: [PATCH 03/34] ITS3: small readme changes Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/README.md | 105 ++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/Detectors/Upgrades/ITS3/README.md b/Detectors/Upgrades/ITS3/README.md index 6d3b0d8d821fb..afcea6a5c3e17 100644 --- a/Detectors/Upgrades/ITS3/README.md +++ b/Detectors/Upgrades/ITS3/README.md @@ -35,7 +35,7 @@ export ALICEO2_CCDB_LOCALCACHE=${PWD}/ccdb Simulate diamond -``` bash +```bash # append to o2-sim --configKeyValues="Diamond.width[2]=6.;"" ``` @@ -86,13 +86,27 @@ TODO ```bash # Create Full Geometry -o2-sim -g pythia8pp -j10 --detectorList ALICE2.1 --run 303901 -n0 +o2-sim --detectorList ALICE2.1 --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 cp its_GeometryTGeo.root ${ALICEO2_CCDB_LOCALCACHE}/ITS/Config/Geometry/snapshot.root ``` +or copying the ideal geometry to the aligned one and: + +```cpp +{ + o2::base::GeometryManager::loadGeometry(""); + 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"); + outF.WriteObjectAny(itsTGeo, "o2::its::GeometryTGeo", "ccdb_object"); + outF.Close(); + itsTGeo->destroy(); +} +``` + ### Regenerating the TopologyDictionary 1. Clusterization w/o tracking @@ -158,7 +172,7 @@ The file `hijing.C` can be found [here](https://alice.its.cern.ch/jira/browse/AO 2. (optional) Run the macro `CreateITS3StaticDeadMap.C` and/or visualize with `CheckTileNumbering.C` 3. Move the ccdb object into `${ALICEO2_CCDB_LOCALCACHE}/IT3/Calib/DeadMap`, this is not optional since there is no default object uploaded 4. Run digitizer with `ITS3Params.useDeadChannelMap=true;`, e.g.: -``` bash +```bash o2-sim-digitizer-workflow --configKeyValues="ITS3Params.useDeadChannelMap=true;" ``` @@ -168,6 +182,89 @@ o2-sim-digitizer-workflow --configKeyValues="ITS3Params.useDeadChannelMap=true;" 1. Create misalignment parameters with `CreateMisalignmentITS3.C` 2. Visualize with `ShowCoefficients.C` 3. Run digitizer -``` bash +```bash o2-sim-digitizer-workflow -b --configKeyValues="ITS3Params.applyMisalignmentHits=true;ITS3Params.misalignmentHitsParams=misparams.root" ``` + + +### Misc +#### Setup to run SIM+DIGIT+TRACKING +```bash + +#!/bin/bash + +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +export ALICEO2_CCDB_LOCALCACHE=$PWD/ccdb + +BASE_DIR="batch_" +TOTAL_DIRS=4 +SIM_CMD="o2-sim -g pythia8pp --detectorList ALICE2.1 -m IT3 --run 303901 -n2000 --field ccdb -j8" +DIGIT_CMD="o2-sim-digitizer-workflow -b --interactionRate 675000 --run --configKeyValues=\"HBFUtils.runNumber=303901;HBFUtils.nHBFPerTF=32;ITSAlpideParam.roFrameLengthInBC=198\"" +RECO_CMD="o2-its3-reco-workflow -b --run --configKeyValues=\"ITSVertexerParam.phiCut=0.5;ITSVertexerParam.clusterContributorsCut=3;ITSVertexerParam.tanLambdaCut=0.2;ITSCATrackerParam.useTrackFollower=0;ITSCATrackerParam.findShortTracks=1;HBFUtils.runNumber=303901;HBFUtils.nHBFPerTF=32;ITSAlpideParam.roFrameLengthInBC=198\" --tracking-mode async" + +for ((i = 1; i <= TOTAL_DIRS; i++)); do + DIR="${BASE_DIR}${i}" + + if [ ! -d "$DIR" ]; then + mkdir "$DIR" + fi + + if [ -f "${DIR}/sim_done" ]; then + echo "Skipping SIM ${DIR} because _done exists." + continue + fi + + cd "$DIR" + + echo "Executing SIM command in ${DIR}..." + eval $SIM_CMD >sim.log + + touch sim_done + + cd .. +done + +for ((i = 1; i <= TOTAL_DIRS; i++)); do + DIR="${BASE_DIR}${i}" + + if [ ! -d "$DIR" ]; then + mkdir "$DIR" + fi + + if [ -f "${DIR}/digit_done" ]; then + echo "Skipping DIGIT ${DIR} because _done exists." + continue + fi + + cd "$DIR" + + echo "Executing DIGIT command in ${DIR}..." + eval $DIGIT_CMD >digit.log + + touch digit_done + + cd .. +done + +for ((i = 1; i <= TOTAL_DIRS; i++)); do + DIR="${BASE_DIR}${i}" + + if [ ! -d "$DIR" ]; then + mkdir "$DIR" + fi + + if [ -f "${DIR}/reco_done" ]; then + echo "Skipping RECO ${DIR} because _done exists." + continue + fi + + cd "$DIR" + + echo "Executing RECO command in ${DIR}..." + eval $RECO_CMD >reco.log + + touch reco_done + + cd .. +done +``` From 6af64f3296ff35e7d8ddbd50f570412dceab957b Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 22 Jan 2025 17:57:50 +0100 Subject: [PATCH 04/34] ITS3: Fix metal stack geo Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index 8b5fdfc1a1a63..cca97241de4f8 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -285,7 +285,7 @@ void ITS3Layer::createChip() // Add metal stack positioned radially outward auto zMoveMetal = new TGeoTranslation(0, 0, constants::metalstack::length / 2. - constants::segment::lec::length); - auto metal = new TGeoTubeSeg(mRmax, mRmax + constants::metalstack::thickness, constants::metalstack::length / 2., 0, 3.0 * phiOffset); + auto metal = new TGeoTubeSeg(mRmax, mRmax + constants::metalstack::thickness, constants::metalstack::length / 2., 0, constants::nSegments[mNLayer] * phiOffset); auto metalVol = new TGeoVolume(Form("metal%d", mNLayer), metal, mCopper); metalVol->SetLineColor(constants::metalstack::color); metalVol->RegisterYourself(); From 9a055bcbadb62013f79d98b5b0bfb1881fbe680b Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 22 Jan 2025 21:41:02 +0100 Subject: [PATCH 05/34] ITS3: change severity to debug Signed-off-by: Felix Schlepper --- .../ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx | 4 ++-- Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx b/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx index 6d1bc621b5287..540e1d41f1c62 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/DescriptorInnerBarrelITS3.cxx @@ -18,14 +18,14 @@ ClassImp(DescriptorInnerBarrelITS3); void DescriptorInnerBarrelITS3::createLayer(int iLayer, TGeoVolume* dest) { - LOGP(info, "ITS3-IB: Creating Layer {}", iLayer); + LOGP(debug, "ITS3-IB: Creating Layer {}", iLayer); mIBLayers[iLayer] = std::make_unique(iLayer); mIBLayers[iLayer]->createLayer(dest); } void DescriptorInnerBarrelITS3::createServices(TGeoVolume* dest) { - LOGP(info, "ITS3-IB: Creating Services"); + LOGP(debug, "ITS3-IB: Creating Services"); mServices = std::make_unique(); mServices->createCYSSAssembly(dest); } diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index cca97241de4f8..7459ec0c370f0 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -76,7 +76,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) createLayerImpl(); mBuilt = true; - LOGP(info, "ITS3-Layer: Created Layer {} with mR={} (minR={}, maxR={})", mNLayer, mR, mRmin, mRmax); + LOGP(debug, "ITS3-Layer: Created Layer {} with mR={} (minR={}, maxR={})", mNLayer, mR, mRmin, mRmax); if (motherVolume == nullptr) { return; } From b9ae93839923117b717e7880b965a47e66f94d4f Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 23 Jan 2025 09:35:06 +0100 Subject: [PATCH 06/34] ITS3: modify layer geo Signed-off-by: Felix Schlepper --- .../include/ITS3Simulation/ITS3Layer.h | 18 +++++++++--------- .../Upgrades/ITS3/simulation/src/ITS3Layer.cxx | 15 +++------------ 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h index 8e0b74cc90617..1cc575f729146 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h @@ -20,13 +20,12 @@ #include #include -#include "Framework/Logger.h" -#include +#include "ITS3Base/SpecsV2.h" namespace o2::its3 { -/// This class defines the Geometry for the ITS3 using TGeo. +/// This class defines the geometry for the ITS3 IB layers. class ITS3Layer { // The hierarchy will be the following: @@ -56,11 +55,10 @@ class ITS3Layer return mNames[static_cast((b == BuildLevel::kAll) ? BuildLevel::kLayer : b)]; } - explicit ITS3Layer(int layer = 0) : mNLayer(layer) - { - LOGP(debug, "Called on {} layer {}", layer, mNLayer); - init(); - } + explicit ITS3Layer(int layer = 0) : mNLayer(layer), + mR(o2::its3::constants::radii[mNLayer]), + mRmin(o2::its3::constants::radiiInner[mNLayer]), + mRmax(o2::its3::constants::radiiOuter[mNLayer]) {} explicit ITS3Layer(TGeoVolume* motherVolume, int layer = 0) : ITS3Layer(layer) { @@ -101,7 +99,9 @@ class ITS3Layer double mRmin{}; // Minimum Radius double mRmax{0}; // Maximum Radius - // Individual Pieces + // Individual pieces + // since TGeo manages the resources itself one should not use these pointers + // after initializition anymore! TGeoVolume* mPixelArray{nullptr}; TGeoVolumeAssembly* mTile{nullptr}; TGeoVolumeAssembly* mRSU{nullptr}; diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index 7459ec0c370f0..b288a08df1b47 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -18,11 +18,11 @@ #include "TGeoVolume.h" #include "TGeoCompositeShape.h" +#include "Framework/Logger.h" #include "CommonConstants/MathConstants.h" #include "ITSBase/GeometryTGeo.h" #include "ITS3Base/SpecsV2.h" #include "ITS3Simulation/ITS3Layer.h" -#include "fairlogger/Logger.h" namespace o2m = o2::constants::math; namespace its3c = o2::its3::constants; @@ -31,13 +31,6 @@ namespace o2::its3 { using its3TGeo = o2::its::GeometryTGeo; -void ITS3Layer::init() -{ - mR = its3c::radii[mNLayer]; - mRmin = its3c::radiiInner[mNLayer]; - mRmax = its3c::radiiOuter[mNLayer]; -} - void ITS3Layer::getMaterials(bool create) { if (gGeoManager == nullptr) { @@ -59,11 +52,11 @@ TGeoMedium* ITS3Layer::getMaterial(const char* matName, bool create) } else { // create dummy auto matDummy = gGeoManager->GetMaterial("MAT_DUMMY$"); if (matDummy == nullptr) { - LOGP(info, "Created Dummy material"); + LOGP(warn, "Created Dummy material"); matDummy = new TGeoMaterial("MAT_DUMMY$", 26.98, 13, 2.7); } mat = new TGeoMedium(matName, 1, matDummy); - LOGP(info, "Created medium {}", matName); + LOGP(warn, "Created medium {}", matName); } } return mat; @@ -76,12 +69,10 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) createLayerImpl(); mBuilt = true; - LOGP(debug, "ITS3-Layer: Created Layer {} with mR={} (minR={}, maxR={})", mNLayer, mR, mRmin, mRmax); if (motherVolume == nullptr) { return; } // Add it to motherVolume - LOGP(debug, " `-> Attaching to motherVolume '{}'", motherVolume->GetName()); auto* trans = new TGeoTranslation(0, 0, -constants::segment::lengthSensitive / 2.); motherVolume->AddNode(mLayer, 0, trans); } From c27c43ca1e4f8c455e4947d8e7b4f7d55afe70dd Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 23 Jan 2025 15:51:21 +0100 Subject: [PATCH 07/34] ITS3: make segmentation class header only Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/base/CMakeLists.txt | 12 ++++----- .../ITS3Base/SegmentationSuperAlpide.h | 18 +++++-------- .../Upgrades/ITS3/base/src/ITS3BaseLinkDef.h | 1 - .../ITS3/base/src/SegmentationSuperAlpide.cxx | 20 --------------- .../ITS3Reconstruction/TopologyDictionary.h | 12 +++++---- .../reconstruction/src/TopologyDictionary.cxx | 12 ++++----- .../include/ITS3Simulation/Digitizer.h | 2 ++ .../ITS3/simulation/src/Digitizer.cxx | 25 +++++++++---------- 8 files changed, 38 insertions(+), 64 deletions(-) delete mode 100644 Detectors/Upgrades/ITS3/base/src/SegmentationSuperAlpide.cxx diff --git a/Detectors/Upgrades/ITS3/base/CMakeLists.txt b/Detectors/Upgrades/ITS3/base/CMakeLists.txt index 8695e2323bbab..306226e5088cf 100644 --- a/Detectors/Upgrades/ITS3/base/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/base/CMakeLists.txt @@ -9,11 +9,9 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2_add_library(ITS3Base - SOURCES src/SegmentationSuperAlpide.cxx - src/ITS3Params.cxx - PUBLIC_LINK_LIBRARIES O2::CommonConstants O2::MathUtils O2::DetectorsBase) +o2_add_library( + ITS3Base + SOURCES src/ITS3Params.cxx + PUBLIC_LINK_LIBRARIES O2::CommonConstants O2::MathUtils O2::DetectorsBase) -o2_target_root_dictionary(ITS3Base - HEADERS include/ITS3Base/SegmentationSuperAlpide.h - include/ITS3Base/ITS3Params.h) +o2_target_root_dictionary(ITS3Base HEADERS include/ITS3Base/ITS3Params.h) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h index d49714829a2d8..524d6b59352a2 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h @@ -53,10 +53,10 @@ class SegmentationSuperAlpide // | | | // x----------------------x public: - virtual ~SegmentationSuperAlpide() = default; + ~SegmentationSuperAlpide() = default; SegmentationSuperAlpide(const SegmentationSuperAlpide&) = default; SegmentationSuperAlpide(SegmentationSuperAlpide&&) = delete; - SegmentationSuperAlpide& operator=(const SegmentationSuperAlpide&) = delete; + SegmentationSuperAlpide& operator=(const SegmentationSuperAlpide&) = default; SegmentationSuperAlpide& operator=(SegmentationSuperAlpide&&) = delete; constexpr SegmentationSuperAlpide(int layer) : mLayer{layer} {} @@ -85,9 +85,8 @@ class SegmentationSuperAlpide { // MUST align the flat surface with the curved surface with the original pixel array is on float dist = std::hypot(xCurved, yCurved); - float phiReadout = constants::tile::readout::width / constants::radii[mLayer]; float phi = std::atan2(yCurved, xCurved); - xFlat = mRadii[mLayer] * (phi - phiReadout) - constants::pixelarray::width / 2.; + xFlat = (mRadii[mLayer] * phi) - constants::pixelarray::width / 2.; yFlat = dist - mRadii[mLayer]; } @@ -105,9 +104,8 @@ class SegmentationSuperAlpide { // MUST align the flat surface with the curved surface with the original pixel array is on float dist = yFlat + mRadii[mLayer]; - float phiReadout = constants::tile::readout::width / mRadii[mLayer]; - xCurved = dist * std::cos(phiReadout + (xFlat + constants::pixelarray::width / 2.) / mRadii[mLayer]); - yCurved = dist * std::sin(phiReadout + (xFlat + constants::pixelarray::width / 2.) / mRadii[mLayer]); + xCurved = dist * std::cos((xFlat + constants::pixelarray::width / 2.) / mRadii[mLayer]); + yCurved = dist * std::sin((xFlat + constants::pixelarray::width / 2.) / mRadii[mLayer]); } /// Transformation from Geant detector centered local coordinates (cm) to @@ -196,13 +194,9 @@ class SegmentationSuperAlpide } } - const int mLayer{0}; ///< chip layer - - ClassDef(SegmentationSuperAlpide, 1); + int mLayer{0}; ///< chip layer }; -/// Segmentation array -extern const std::array SuperSegmentations; } // namespace o2::its3 #endif diff --git a/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h b/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h index dc0557824e0f8..144711b052a1b 100644 --- a/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h +++ b/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h @@ -15,7 +15,6 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::its3::SegmentationSuperAlpide + ; #pragma link C++ class o2::its3::ITS3Params + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its3::ITS3Params> + ; diff --git a/Detectors/Upgrades/ITS3/base/src/SegmentationSuperAlpide.cxx b/Detectors/Upgrades/ITS3/base/src/SegmentationSuperAlpide.cxx deleted file mode 100644 index 26ca09f351bec..0000000000000 --- a/Detectors/Upgrades/ITS3/base/src/SegmentationSuperAlpide.cxx +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "ITS3Base/SegmentationSuperAlpide.h" - -ClassImp(o2::its3::SegmentationSuperAlpide); - -namespace o2::its3 -{ - -const std::array SuperSegmentations{0, 1, 2}; -} diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h index a11131ed9f61f..c810ddc49fd76 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h @@ -17,6 +17,7 @@ #include "DataFormatsITSMFT/TopologyDictionary.h" #include "DataFormatsITSMFT/ClusterPattern.h" +#include "ITS3Base/SegmentationSuperAlpide.h" namespace o2::its3 { @@ -125,7 +126,7 @@ class TopologyDictionary /// Returns the local position of a compact cluster template - static math_utils::Point3D getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true); + math_utils::Point3D getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true) const; static TopologyDictionary* loadFrom(const std::string& fileName = "", const std::string& objName = "ccdb_object"); @@ -134,10 +135,11 @@ class TopologyDictionary private: static constexpr int STopoSize{8 * 255 + 1}; - std::unordered_map mCommonMap{}; ///< Map of pair - std::unordered_map mGroupMap{}; ///< Map of pair - int mSmallTopologiesLUT[STopoSize]{}; ///< Look-Up Table for the topologies with 1-byte linearised matrix - std::vector mVectorOfIDs{}; ///< Vector of topologies and groups + std::unordered_map mCommonMap{}; ///< Map of pair + std::unordered_map mGroupMap{}; ///< Map of pair + int mSmallTopologiesLUT[STopoSize]{}; ///< Look-Up Table for the topologies with 1-byte linearised matrix + std::vector mVectorOfIDs{}; ///< Vector of topologies and groups + std::array mSuperSegmentations{0, 1, 2}; ///< Segmentations for IB layers ClassDefNV(TopologyDictionary, 3); }; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx index 66a4b0a6878cd..903d852f84a1f 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx @@ -143,18 +143,18 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * itsmft::SegmentationAlpide::PitchCol); } else { auto layer = its3::constants::detID::getDetID2Layer(cl.getSensorID()); - its3::SuperSegmentations[layer].detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); + mSuperSegmentations[layer].detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * its3::SegmentationSuperAlpide::mPitchRow); locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * its3::SegmentationSuperAlpide::mPitchCol); float xCurved{0.f}, yCurved{0.f}; - its3::SuperSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); + mSuperSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); locCl.SetXYZ(xCurved, yCurved, locCl.Z()); } return locCl; } template -math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) +math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) const { auto refRow = cl.getRow(); auto refCol = cl.getCol(); @@ -169,9 +169,9 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); } else { auto layer = its3::constants::detID::getDetID2Layer(cl.getSensorID()); - its3::SuperSegmentations[layer].detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); + mSuperSegmentations[layer].detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); float xCurved{0.f}, yCurved{0.f}; - its3::SuperSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); + mSuperSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); locCl.SetXYZ(xCurved, yCurved, locCl.Z()); } return locCl; @@ -194,6 +194,6 @@ TopologyDictionary* TopologyDictionary::loadFrom(const std::string& fname, const // Explicitly instaniate templates template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl) const; -template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup); +template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) const; } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index 7ece842b6f61f..67b0cc7456a46 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -108,6 +108,8 @@ class Digitizer : public TObject uint32_t mEventROFrameMin = 0xffffffff; ///< lowest RO frame for processed events (w/o automatic noise ROFs) uint32_t mEventROFrameMax = 0; ///< highest RO frame forfor processed events (w/o automatic noise ROFs) + const std::array mSuperSegmentations{0, 1, 2}; + o2::itsmft::AlpideSimResponse* mAlpSimResp = nullptr; // simulated response const o2::its::GeometryTGeo* mGeometry = nullptr; ///< ITS3 geometry diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index f1519c1d04063..b85574402de5b 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -26,7 +26,6 @@ using o2::itsmft::Hit; using Segmentation = o2::itsmft::SegmentationAlpide; -using SuperSegmentation = o2::its3::SegmentationSuperAlpide; using o2::itsmft::AlpideRespSimMat; using o2::itsmft::PreDigit; @@ -143,7 +142,7 @@ void Digitizer::fillOutputContainer(uint32_t frameLast) for (size_t iChip{0}; iChip < mChips.size(); ++iChip) { auto& chip = mChips[iChip]; if (constants::detID::isDetITS3(iChip)) { // Check if this is a chip of ITS3 - chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SuperSegmentation::mNRows, SuperSegmentation::mNCols); + chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SegmentationSuperAlpide::mNRows, SegmentationSuperAlpide::mNCols); } else { chip.addNoise(mROFrameMin, mROFrameMin, &mParams); } @@ -238,8 +237,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID if (innerBarrel) { // transform the point on the curved surface to a flat one float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f}; - SuperSegmentations[layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS); - SuperSegmentations[layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE); + mSuperSegmentations[layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS); + mSuperSegmentations[layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE); // update the local coordinates with the flattened ones xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z()); xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z()); @@ -255,14 +254,14 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0; if (innerBarrel) { // get entrance pixel row and col - while (!SuperSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ? + while (!mSuperSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ? if (++nSkip >= nSteps) { return; // did not enter to sensitive matrix } xyzLocS += step; } // get exit pixel row and col - while (!SuperSegmentations[layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ? + while (!mSuperSegmentations[layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ? if (++nSkip >= nSteps) { return; // did not enter to sensitive matrix } @@ -298,8 +297,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID rowS = 0; } - int maxNrows{innerBarrel ? SuperSegmentation::mNRows : Segmentation::NRows}; - int maxNcols{innerBarrel ? SuperSegmentation::mNCols : Segmentation::NCols}; + int maxNrows{innerBarrel ? SegmentationSuperAlpide::mNRows : Segmentation::NRows}; + int maxNcols{innerBarrel ? SegmentationSuperAlpide::mNCols : Segmentation::NCols}; if (rowE >= maxNrows) { rowE = maxNrows - 1; } @@ -327,19 +326,19 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID // take into account that the AlpideSimResponse depth defintion has different min/max boundaries // although the max should coincide with the surface of the epitaxial layer, which in the chip // local coordinates has Y = +SensorLayerThickness/2 - float thickness = innerBarrel ? SuperSegmentation::mSensorLayerThickness : Segmentation::SensorLayerThickness; + float thickness = innerBarrel ? SegmentationSuperAlpide::mSensorLayerThickness : Segmentation::SensorLayerThickness; xyzLocS.SetY(xyzLocS.Y() + mAlpSimResp->getDepthMax() - thickness / 2.); // collect charge in evey pixel which might be affected by the hit for (int iStep = nSteps; iStep--;) { // Get the pixel ID if (innerBarrel) { - SuperSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); + mSuperSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); } else { Segmentation::localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); } if (row != rowPrev || col != colPrev) { // update pixel and coordinates of its center if (innerBarrel) { - if (!SuperSegmentations[layer].detectorToLocal(row, col, cRowPix, cColPix)) { + if (!mSuperSegmentations[layer].detectorToLocal(row, col, cRowPix, cColPix)) { continue; } } else if (!Segmentation::detectorToLocal(row, col, cRowPix, cColPix)) { @@ -350,8 +349,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID } bool flipCol = false, flipRow = false; // note that response needs coordinates along column row (locX) (locZ) then depth (locY) - double rowMax{0.5f * (innerBarrel ? SuperSegmentation::mPitchRow : Segmentation::PitchRow)}; - double colMax{0.5f * (innerBarrel ? SuperSegmentation::mPitchCol : Segmentation::PitchCol)}; + double rowMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchRow : Segmentation::PitchRow)}; + double colMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchCol : Segmentation::PitchCol)}; auto rspmat = mAlpSimResp->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); xyzLocS += step; From d3a120e3adddd5cb92b2e959fee3cbb9a941e398 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 23 Jan 2025 10:58:41 +0100 Subject: [PATCH 08/34] ITS3: move pixelarray to start at zero phi Signed-off-by: Felix Schlepper --- .../ITS3/macros/test/CheckDigitsDensity.C | 6 +-- .../ITS3/macros/test/CheckDigitsITS3.C | 15 +++--- .../macros/test/CheckSuperAlpideSegment.C | 54 +++++++++---------- .../test/CheckSuperAlpideSegmentTrans.C | 16 +++--- .../ITS3/macros/test/CheckTileNumbering.C | 4 +- .../macros/test/CompareClustersAndDigits.C | 14 ++--- .../ITS3/macros/test/CreateDictionariesITS3.C | 5 +- .../ITS3/macros/test/TestSensorGeometry.C | 19 ++++--- .../ITS3Reconstruction/TopologyDictionary.h | 11 ++-- .../reconstruction/src/TopologyDictionary.cxx | 6 ++- .../include/ITS3Simulation/ITS3Layer.h | 4 +- .../ITS3/simulation/src/ITS3Layer.cxx | 21 ++++---- 12 files changed, 88 insertions(+), 87 deletions(-) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C index 0c8d9c3bdfbec..bb07c1a49b7f0 100755 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C @@ -64,7 +64,7 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig { gROOT->SetBatch(batch); LOGP(debug, "Checking Digit ITS3 Density"); - // Vars + std::array mSuperSegmentations{0, 1, 2}; // Geometry o2::base::GeometryManager::loadGeometry(geomFileName); @@ -103,8 +103,8 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig // goto curved coordinates float x{0.f}, y{0.f}, z{0.f}; float xFlat{0.f}, yFlat{0.f}; - its3::SuperSegmentations[layer].detectorToLocal(row, col, xFlat, z); - its3::SuperSegmentations[layer].flatToCurved(xFlat, 0., x, y); + mSuperSegmentations[layer].detectorToLocal(row, col, xFlat, z); + mSuperSegmentations[layer].flatToCurved(xFlat, 0., x, y); const o2::math_utils::Point3D locD(x, y, z); const auto gloD = gman->getMatrixL2G(id)(locD); // convert to global const auto R = std::hypot(gloD.X(), gloD.Y()); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C index 16aa3adc8101c..0ce9b4ed798f1 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C @@ -51,6 +51,7 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil using o2::itsmft::Hit; using o2::itsmft::SegmentationAlpide; + std::array mSuperSegmentations{0, 1, 2}; TFile* f = TFile::Open("CheckDigits.root", "recreate"); TNtuple* nt = new TNtuple("ntd", "digit ntuple", "id:x:y:z:rowD:colD:rowH:colH:xlH:zlH:xlcH:zlcH:dx:dz"); @@ -165,8 +166,8 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil if (isIB) { // ITS3 IB float xFlat{0.f}, yFlat{0.f}; - its3::SuperSegmentations[layer].detectorToLocal(ix, iz, xFlat, z); - its3::SuperSegmentations[layer].flatToCurved(xFlat, 0., x, y); + mSuperSegmentations[layer].detectorToLocal(ix, iz, xFlat, z); + mSuperSegmentations[layer].flatToCurved(xFlat, 0., x, y); } else { // ITS2 OB SegmentationAlpide::detectorToLocal(ix, iz, x, z); @@ -202,12 +203,12 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil if (isIB) { float xFlat{0.}, yFlat{0.}; - its3::SuperSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); + mSuperSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); xyzLocM.SetCoordinates(xFlat, yFlat, xyzLocM.Z()); - its3::SuperSegmentations[layer].curvedToFlat(locD.X(), locD.Y(), xFlat, yFlat); + mSuperSegmentations[layer].curvedToFlat(locD.X(), locD.Y(), xFlat, yFlat); locD.SetCoordinates(xFlat, yFlat, locD.Z()); - if (auto v1 = !its3::SuperSegmentations[layer].localToDetector(xyzLocM.X(), xyzLocM.Z(), row, col), - v2 = !its3::SuperSegmentations[layer].detectorToLocal(row, col, xlc, zlc); + if (auto v1 = !mSuperSegmentations[layer].localToDetector(xyzLocM.X(), xyzLocM.Z(), row, col), + v2 = !mSuperSegmentations[layer].detectorToLocal(row, col, xlc, zlc); v1 || v2) { continue; } @@ -223,7 +224,7 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil (isIB) ? ++nDigitFilledIB : ++nDigitFilledOB; } // end loop on digits array - } // end loop on ROFRecords array + } // end loop on ROFRecords array auto canvXY = new TCanvas("canvXY", "", 1600, 1600); canvXY->Divide(2, 2); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C b/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C index 76ac02959415d..a0ccee366841d 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C @@ -24,14 +24,6 @@ #include "TGLViewer.h" #include "TMath.h" -#include "TEveGeoNode.h" -#include "TEveManager.h" -#include "TEveViewer.h" -#include "TEvePointSet.h" -#include "TEveTrackPropagator.h" -#include "TEveTrack.h" -#include "TEveVSDStructs.h" - #include "TFile.h" #include "TGraph.h" #include "TH1D.h" @@ -64,21 +56,22 @@ void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, static constexpr unsigned int mNCols{SegmentationSuperAlpide::mNCols}; static constexpr unsigned int mNRows{SegmentationSuperAlpide::mNRows}; static constexpr unsigned int nPixels{mNCols * mNRows}; + std::array mSuperSegmentations{0, 1, 2}; if (isTestDetectorToLocal || isTestFlatToCurved) { namespace cp = constants::pixelarray; - TH2I* h_raw_col = new TH2I("h_raw_col", "raws and cols sown;raw;col", mNRows, 0, mNRows, mNCols, 0, mNCols); - TH2D* h_xLocal_zLocal = new TH2D("h_xLocal_zLocal", "x and z from raws and cols;xLocal;zLocal", mNRows, -cp::length / 2, cp::length / 2, mNCols, -cp::width / 2, cp::width / 2); - TH2I* h_raw_col_translate = new TH2I("h_raw_col_translate", "raws and cols from x and z;raw;col", mNRows, 0, mNRows, mNCols, 0, mNCols); - TGraph* g_raw_xLocal = new TGraph(); - g_raw_xLocal->SetMarkerStyle(20); - g_raw_xLocal->SetMarkerSize(0.2); + TH2I* h_row_col = new TH2I("h_row_col", "rows and cols sown;row;col", mNRows, 0, mNRows, mNCols, 0, mNCols); + TH2D* h_xLocal_zLocal = new TH2D("h_xLocal_zLocal", "x and z from rows and cols;xLocal;zLocal", mNRows, -cp::length / 2, cp::length / 2, mNCols, -cp::width / 2, cp::width / 2); + TH2I* h_row_col_translate = new TH2I("h_row_col_translate", "rows and cols from x and z;row;col", mNRows, 0, mNRows, mNCols, 0, mNCols); + TGraph* g_row_xLocal = new TGraph(); + g_row_xLocal->SetMarkerStyle(20); + g_row_xLocal->SetMarkerSize(0.2); TGraph* g_col_zLocal = new TGraph(); g_col_zLocal->SetMarkerStyle(20); g_col_zLocal->SetMarkerSize(0.2); - TGraph* g_raw_xLocal_translate = new TGraph(); - g_raw_xLocal_translate->SetMarkerStyle(20); - g_raw_xLocal_translate->SetMarkerSize(0.2); + TGraph* g_row_xLocal_translate = new TGraph(); + g_row_xLocal_translate->SetMarkerStyle(20); + g_row_xLocal_translate->SetMarkerSize(0.2); TGraph* g_col_zLocal_translate = new TGraph(); g_col_zLocal_translate->SetMarkerStyle(20); @@ -92,16 +85,16 @@ void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, int col_trans = -1; seg.detectorToLocal(i, j, xLocal, zLocal); seg.localToDetector(xLocal, zLocal, row_trans, col_trans); - g_raw_xLocal->SetPoint(nPoint, i, xLocal); + g_row_xLocal->SetPoint(nPoint, i, xLocal); g_col_zLocal->SetPoint(nPoint, j, zLocal); - g_raw_xLocal_translate->SetPoint(nPoint, xLocal, row_trans); + g_row_xLocal_translate->SetPoint(nPoint, xLocal, row_trans); g_col_zLocal_translate->SetPoint(nPoint++, zLocal, col_trans); bool pattern = ((i >= 50 && i <= 100) || (i >= 250 && i <= 350)) && ((j >= 30 && j <= 70) || (j >= 100 && j <= 120)); if (pattern) { - h_raw_col->Fill(i, j); + h_row_col->Fill(i, j); h_xLocal_zLocal->Fill(xLocal, zLocal); - h_raw_col_translate->Fill(row_trans, col_trans); + h_row_col_translate->Fill(row_trans, col_trans); } } } @@ -110,29 +103,30 @@ void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, // gStyle->SetPalette(kCMYK); c1->Divide(3, 1); c1->cd(1); - h_raw_col->Draw("colz"); + h_row_col->Draw("colz"); c1->cd(2); h_xLocal_zLocal->Draw("colz"); c1->cd(3); - h_raw_col_translate->Draw("colz"); + h_row_col_translate->Draw("colz"); TCanvas* c2 = new TCanvas("c2", "c2", 1600, 400); c2->Divide(4, 1); c2->cd(1); - g_raw_xLocal->SetTitle("xLocal vs raw;raw;xLocal"); - g_raw_xLocal->Draw("same ap"); + g_row_xLocal->SetTitle("xLocal vs row;row;xLocal"); + g_row_xLocal->Draw("same ap"); c2->cd(2); g_col_zLocal->SetTitle("zLocal vs col;col;zLocal"); g_col_zLocal->Draw("same ap"); c2->cd(3); - g_raw_xLocal_translate->SetTitle("raw_translate vs xLocal;xLocal;raw_translate"); - g_raw_xLocal_translate->Draw("same ap"); + g_row_xLocal_translate->SetTitle("row_translate vs xLocal;xLocal;row_translate"); + g_row_xLocal_translate->Draw("same ap"); c2->cd(4); g_col_zLocal_translate->SetTitle("col_translate vs zLocal;zLocal;col_translate"); g_col_zLocal_translate->Draw("same ap"); } if (isTestLocalToGlobal) { + o2::base::GeometryManager::loadGeometry(); namespace cp = constants::pixelarray; TH2D* h_xCurved_yCurved = new TH2D("h_xCurved_yCurved", "from flat to curved;x;y", 200, -1, 4, 200, -2, 3); TH2D* h_xFlat_yFlat = new TH2D("h_xFlat_yFlat", "from curved to flat ;x;y", 200, -1, 4, 200, -2, 3); @@ -170,11 +164,11 @@ void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, float xLocal_translate = 0; float yLocal_translate = 0; - SuperSegmentations[iLayer].detectorToLocal(row, col, xLocal, zLocal); - SuperSegmentations[iLayer].flatToCurved(xLocal, 0., xCurved, yCurved); + mSuperSegmentations[iLayer].detectorToLocal(row, col, xLocal, zLocal); + mSuperSegmentations[iLayer].flatToCurved(xLocal, 0., xCurved, yCurved); double posLocal[3] = {xCurved, yCurved, zLocal}; double posGlobal[3] = {0, 0, 0}; - SuperSegmentations[iLayer].curvedToFlat(xCurved, yCurved, xLocal_translate, yLocal_translate); + mSuperSegmentations[iLayer].curvedToFlat(xCurved, yCurved, xLocal_translate, yLocal_translate); matrix->LocalToMaster(posLocal, posGlobal); h_xCurved_yCurved->Fill(xLocal, 0); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C b/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C index 64937f2ad2855..0fd1d0225c78d 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C @@ -41,6 +41,7 @@ constexpr auto nRows{SegmentationSuperAlpide::mNRows}; constexpr auto nCols{SegmentationSuperAlpide::mNCols}; constexpr auto fLength{SegmentationSuperAlpide::mLength}; constexpr auto fWidth{SegmentationSuperAlpide::mWidth}; +std::array mSuperSegmentations{0, 1, 2}; TH2* DrawReverseBins(TH2* h) { @@ -140,10 +141,10 @@ void CheckSuperAlpideSegmentTrans() g_arc_inner->AddPoint(x_inner, y_inner); g_arc_outer->AddPoint(x_outer, y_outer); // Test Segmentation - SuperSegmentations[iLayer].curvedToFlat(x_inner, y_inner, x_inner_flat, y_inner_flat); - SuperSegmentations[iLayer].flatToCurved(x_inner_flat, y_inner_flat, x_inner_curved, y_inner_curved); - SuperSegmentations[iLayer].curvedToFlat(x_outer, y_outer, x_outer_flat, y_outer_flat); - SuperSegmentations[iLayer].flatToCurved(x_outer_flat, y_outer_flat, x_outer_curved, y_outer_curved); + mSuperSegmentations[iLayer].curvedToFlat(x_inner, y_inner, x_inner_flat, y_inner_flat); + mSuperSegmentations[iLayer].flatToCurved(x_inner_flat, y_inner_flat, x_inner_curved, y_inner_curved); + mSuperSegmentations[iLayer].curvedToFlat(x_outer, y_outer, x_outer_flat, y_outer_flat); + mSuperSegmentations[iLayer].flatToCurved(x_outer_flat, y_outer_flat, x_outer_curved, y_outer_curved); g_arc_inner_flat->AddPoint(x_inner_flat, y_inner_flat); g_arc_outer_flat->AddPoint(x_outer_flat, y_outer_flat); h_f2c_res->Fill(x_inner - x_inner_curved, y_inner - y_inner_curved); @@ -201,10 +202,9 @@ void CheckSuperAlpideSegmentTrans() for (int iCol{0}; iCol < nCols; ++iCol) { float xRow{0}, zCol{0}; int iiRow{0}, iiCol{0}; - auto v1 = - SuperSegmentations[iLayer].detectorToLocal(iRow, iCol, xRow, zCol); - auto v2 = SuperSegmentations[iLayer].localToDetector(xRow, zCol, iiRow, - iiCol); + auto v1 = mSuperSegmentations[iLayer].detectorToLocal(iRow, iCol, xRow, zCol); + auto v2 = mSuperSegmentations[iLayer].localToDetector(xRow, zCol, iiRow, + iiCol); // Info("L2D", // "iRow=%d, iCol=%d --d2l(%s)--> xRow=%f, zCol=%f --l2d(%s)--> " // "iiRow=%d, iiCol=%d", diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C b/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C index 3a01960b1859d..4550e2c1a17e0 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C @@ -102,6 +102,8 @@ void CheckTileNumbering(const std::string& inputGeom = "", const std::string& de Int_t colors[NRGBs] = {kWhite, kRed, kGray}; TColor::SetPalette(NRGBs, colors, 1.0); + std::array mSuperSegmentations{0, 1, 2}; + const float phiOffsetL0 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[0]); const float phiOffsetL1 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[1]); const float phiOffsetL2 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[2]); @@ -142,7 +144,7 @@ void CheckTileNumbering(const std::string& inputGeom = "", const std::string& de for (unsigned int iDet{0}; iDet <= o2::its3::constants::detID::l2IDEnd; ++iDet) { int sensorID = o2::its3::constants::detID::getSensorID(iDet); int layerID = o2::its3::constants::detID::getDetID2Layer(iDet); - o2::its3::SuperSegmentations[layerID].flatToCurved(xFlat, 0., x, y); + mSuperSegmentations[layerID].flatToCurved(xFlat, 0., x, y); o2::math_utils::Point3D locC{x, y, z}; auto gloC = gman->getMatrixL2G(iDet)(locC); float phi = o2::math_utils::to02Pi(std::atan2(gloC.Y(), gloC.X())); diff --git a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C index f151de72c8ac1..f454745c0f076 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C +++ b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C @@ -97,6 +97,8 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", std::vector hitVecPool; std::vector mc2hitVec; + std::array mSuperSegmentations{0, 1, 2}; + // Geometry o2::base::GeometryManager::loadGeometry(inputGeom); auto gman = o2::its::GeometryTGeo::Instance(); @@ -282,9 +284,9 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", o2::math_utils::Point3D locHMiddle; if (isIB) { float xFlat{0.}, yFlat{0.}; - o2::its3::SuperSegmentations[layer].curvedToFlat(locHEnd.X(), locHEnd.Y(), xFlat, yFlat); + mSuperSegmentations[layer].curvedToFlat(locHEnd.X(), locHEnd.Y(), xFlat, yFlat); locHEnd.SetXYZ(xFlat, yFlat, locHEnd.Z()); - o2::its3::SuperSegmentations[layer].curvedToFlat(locHStart.X(), locHStart.Y(), xFlat, yFlat); + mSuperSegmentations[layer].curvedToFlat(locHStart.X(), locHStart.Y(), xFlat, yFlat); locHStart.SetXYZ(xFlat, yFlat, locHStart.Z()); } locHMiddle.SetXYZ(0.5f * (locHEnd.X() + locHStart.X()), 0.5f * (locHEnd.Y() + locHStart.Y()), 0.5f * (locHEnd.Z() + locHStart.Z())); @@ -292,10 +294,10 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", int rowHS, colHS, rowHM, colHM, rowHE, colHE, colC, rowC; bool v1, v2, v3, v4; if (isIB) { - v1 = o2::its3::SuperSegmentations[layer].localToDetector(locHStart.X(), locHStart.Z(), rowHS, colHS); - v2 = o2::its3::SuperSegmentations[layer].localToDetector(locHMiddle.X(), locHMiddle.Z(), rowHM, colHM); - v3 = o2::its3::SuperSegmentations[layer].localToDetector(locHEnd.X(), locHEnd.Z(), rowHE, colHE); - v4 = o2::its3::SuperSegmentations[layer].localToDetector(locC.X(), locC.Z(), rowC, colC); + v1 = mSuperSegmentations[layer].localToDetector(locHStart.X(), locHStart.Z(), rowHS, colHS); + v2 = mSuperSegmentations[layer].localToDetector(locHMiddle.X(), locHMiddle.Z(), rowHM, colHM); + v3 = mSuperSegmentations[layer].localToDetector(locHEnd.X(), locHEnd.Z(), rowHE, colHE); + v4 = mSuperSegmentations[layer].localToDetector(locC.X(), locC.Z(), rowC, colC); } else { v1 = o2::itsmft::SegmentationAlpide::localToDetector(locHStart.X(), locHStart.Z(), rowHS, colHS); v2 = o2::itsmft::SegmentationAlpide::localToDetector(locHMiddle.X(), locHMiddle.Z(), rowHM, colHM); diff --git a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C index d8783ba7c8fb9..ac6e1138f24e8 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C @@ -82,6 +82,7 @@ void CreateDictionariesITS3(bool saveDeltas = false, std::vector hitVecPool; std::vector mc2hitVec; o2::its3::TopologyDictionary clusDictOld; + std::array mSuperSegmentations{0, 1, 2}; if (!clusDictFile.empty()) { clusDictOld.readFromFile(clusDictFile); LOGP(info, "Loaded external cluster dictionary with {} entries from {}", clusDictOld.getSize(), clusDictFile); @@ -274,9 +275,9 @@ void CreateDictionariesITS3(bool saveDeltas = false, int layer = gman->getLayer(chipID); if (isIB) { float xFlat{0.}, yFlat{0.}; - o2::its3::SuperSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); + mSuperSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); xyzLocM.SetCoordinates(xFlat, yFlat, xyzLocM.Z()); - o2::its3::SuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlat, yFlat); + mSuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlat, yFlat); locC.SetCoordinates(xFlat, yFlat, locC.Z()); } dX = xyzLocM.X() - locC.X(); diff --git a/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C b/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C index b3221fd2dfbc2..4b54bbced2929 100644 --- a/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C +++ b/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C @@ -21,7 +21,7 @@ #include "TList.h" #endif -void TestSensorGeometry(bool checkFull = false) +void TestSensorGeometry(bool draw = false, bool checkFull = false) { gGeoManager = new TGeoManager("simple", "Simple geometry"); TGeoMaterial* matVacuum = new TGeoMaterial("Vacuum", 0, 0, 0); @@ -30,8 +30,7 @@ void TestSensorGeometry(bool checkFull = false) auto top = gGeoManager->MakeBox("TOP", Vacuum, 270., 270., 120.); gGeoManager->SetTopVolume(top); - o2::its3::ITS3Layer layer0{0, top, nullptr, - o2::its3::ITS3Layer::BuildLevel::kLayer, true}; + o2::its3::ITS3Layer layer0{2, top, nullptr, o2::its3::ITS3Layer::BuildLevel::kLayer, true}; // Print available medias TIter next{gGeoManager->GetListOfMedia()}; @@ -42,13 +41,17 @@ void TestSensorGeometry(bool checkFull = false) gGeoManager->CloseGeometry(); gGeoManager->SetVisLevel(99); + if (draw) { + gGeoManager->Draw("ogl"); + } + if (checkFull) { gGeoManager->CheckGeometryFull(); - } - gGeoManager->CheckOverlaps(0.00001); - TIter nextOverlap{gGeoManager->GetListOfOverlaps()}; - while ((obj = (TObject*)nextOverlap())) { - LOGP(info, "Overlap in {}", obj->GetName()); + gGeoManager->CheckOverlaps(0.00001); + TIter nextOverlap{gGeoManager->GetListOfOverlaps()}; + while ((obj = (TObject*)nextOverlap())) { + LOGP(info, "Overlap in {}", obj->GetName()); + } } std::unique_ptr f{TFile::Open("geo.root", "RECREATE")}; diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h index c810ddc49fd76..bc5fd73d48c84 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h @@ -126,7 +126,7 @@ class TopologyDictionary /// Returns the local position of a compact cluster template - math_utils::Point3D getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true) const; + static math_utils::Point3D getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup = true); static TopologyDictionary* loadFrom(const std::string& fileName = "", const std::string& objName = "ccdb_object"); @@ -135,11 +135,10 @@ class TopologyDictionary private: static constexpr int STopoSize{8 * 255 + 1}; - std::unordered_map mCommonMap{}; ///< Map of pair - std::unordered_map mGroupMap{}; ///< Map of pair - int mSmallTopologiesLUT[STopoSize]{}; ///< Look-Up Table for the topologies with 1-byte linearised matrix - std::vector mVectorOfIDs{}; ///< Vector of topologies and groups - std::array mSuperSegmentations{0, 1, 2}; ///< Segmentations for IB layers + std::unordered_map mCommonMap{}; ///< Map of pair + std::unordered_map mGroupMap{}; ///< Map of pair + int mSmallTopologiesLUT[STopoSize]{}; ///< Look-Up Table for the topologies with 1-byte linearised matrix + std::vector mVectorOfIDs{}; ///< Vector of topologies and groups ClassDefNV(TopologyDictionary, 3); }; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx index 903d852f84a1f..fa521c3b21b31 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx @@ -136,6 +136,7 @@ TH1F* TopologyDictionary::getTopologyDistribution(const std::string_view hname) template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl) const { + static std::array mSuperSegmentations{0, 1, 2}; math_utils::Point3D locCl; if (!its3::constants::detID::isDetITS3(cl.getSensorID())) { o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); @@ -154,8 +155,9 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C } template -math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) const +math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) { + static std::array mSuperSegmentations{0, 1, 2}; auto refRow = cl.getRow(); auto refCol = cl.getCol(); float xCOG = 0, zCOG = 0; @@ -194,6 +196,6 @@ TopologyDictionary* TopologyDictionary::loadFrom(const std::string& fname, const // Explicitly instaniate templates template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl) const; -template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) const; +template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup); } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h index 1cc575f729146..3ca506845aadd 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h @@ -44,8 +44,8 @@ class ITS3Layer kTile, kRSU, kSegment, - kCarbonForm, kChip, + kCarbonForm, kLayer, kAll, }; @@ -110,7 +110,7 @@ class ITS3Layer TGeoVolumeAssembly* mCarbonForm{nullptr}; TGeoVolumeAssembly* mLayer{nullptr}; - ClassDef(ITS3Layer, 2); + ClassDef(ITS3Layer, 3); }; } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index b288a08df1b47..153fe8ab620fd 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -85,13 +85,9 @@ void ITS3Layer::createPixelArray() // A pixel array is pure silicon and the sensitive part of our detector. // It will be segmented into a 442x156 matrix by the // SuperSegmentationAlpide. - // Pixel Array is just a longer version of the biasing but starts in phi at - // biasPhi2. using namespace its3c::pixelarray; - double pixelArrayPhi1 = constants::tile::readout::width / mR * o2m::Rad2Deg; - double pixelArrayPhi2 = width / mR * o2m::Rad2Deg + pixelArrayPhi1; - auto pixelArray = new TGeoTubeSeg(mRmin, mRmax, length / 2., - pixelArrayPhi1, pixelArrayPhi2); + double pixelArrayPhi = width / mR * o2m::Rad2Deg; + auto pixelArray = new TGeoTubeSeg(mRmin, mRmax, length / 2., 0, pixelArrayPhi); mPixelArray = new TGeoVolume(its3TGeo::getITS3PixelArrayPattern(mNLayer), pixelArray, mSilicon); mPixelArray->SetLineColor(color); mPixelArray->RegisterYourself(); @@ -123,8 +119,9 @@ void ITS3Layer::createTile() mTile->AddNode(readoutVol, 0, zMoveReadout); // Pixel Array is just a longer version of the biasing but starts in phi at - // biasPhi2. - mTile->AddNode(mPixelArray, 0); + // readoutPhi2. + auto phiRotPixelArray = new TGeoRotation(Form("its3PhiPixelArrayOffset_%d", mNLayer), readoutPhi2, 0, 0); + mTile->AddNode(mPixelArray, 0, phiRotPixelArray); // Biasing double biasPhi1 = constants::pixelarray::width / mR * o2m::Rad2Deg + readoutPhi2; @@ -191,7 +188,7 @@ void ITS3Layer::createRSU() // Rotation for top half and vertical mirroring double phi = width / mR * o2m::Rad2Deg; - auto rot = new TGeoRotation("", 0, 0, -phi); + auto rot = new TGeoRotation(Form("its3RotHalfBarrel_%d", mNLayer), 0, 0, -phi); rot->ReflectY(true); // Upper Left @@ -270,7 +267,7 @@ void ITS3Layer::createChip() auto phiOffset = constants::segment::width / mR * o2m::Rad2Deg; for (unsigned int i{0}; i < constants::nSegments[mNLayer]; ++i) { - auto rot = new TGeoRotation("", 0, 0, phiOffset * i); + auto rot = new TGeoRotation(Form("its3PhiSegmentOffset_%d_%d", mNLayer, i), 0, 0, phiOffset * i); mChip->AddNode(mSegment, i, rot); } @@ -372,8 +369,8 @@ void ITS3Layer::createLayerImpl() // The offset is the right angle triangle of the middle radius with the // transverse axis. double phiOffset = std::asin(constants::equatorialGap / 2. / mR) * o2m::Rad2Deg; - auto rotTop = new TGeoRotation("", 0, 0, +phiOffset); - auto rotBot = new TGeoRotation("", 0, 0, phiOffset + 180); + auto rotTop = new TGeoRotation(Form("its3CarbonPhiOffsetTop_%d", mNLayer), 0, 0, +phiOffset); + auto rotBot = new TGeoRotation(Form("its3CarbonPhiOffsetBot_%d", mNLayer), 0, 0, phiOffset + 180); mLayer->AddNode(mCarbonForm, 0, rotTop); mLayer->AddNode(mCarbonForm, 1, rotBot); From 212a0001b5df65fb14a83bfb90d67dbe314675a5 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 23 Jan 2025 14:38:41 +0100 Subject: [PATCH 09/34] ITS3: macro fixes Signed-off-by: Felix Schlepper --- .../ITS3/macros/test/CheckClusterSize.C | 19 ++++++++++++++----- .../ITS3/macros/test/CheckClustersITS3.C | 9 +++++---- .../macros/test/CompareClustersAndDigits.C | 16 ++++++++-------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C b/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C index addaaf47269d2..5fffed4fcc580 100755 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C @@ -43,6 +43,7 @@ #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCEventHeader.h" #include "SimulationDataFormat/MCTrack.h" +#include "ITS3Base/SpecsV2.h" #endif #define ENABLE_UPGRADES #include "SimulationDataFormat/MCTruthContainer.h" @@ -65,7 +66,11 @@ void checkFile(const std::unique_ptr& file); inline auto hist_map(unsigned short id) { - return std::clamp(id, static_cast(0), static_cast(6)) / 2; + int lay = o2::its3::constants::detID::getDetID2Layer(id); + if (lay == -1) { + return nLayers - 1; + } + return lay; } void CheckClusterSize(std::string clusFileName = "o2clus_its.root", @@ -133,7 +138,7 @@ void CheckClusterSize(std::string clusFileName = "o2clus_its.root", std::vector hOtherSecondaryEta; std::vector hOtherSecondaryPt; std::vector hOtherSecondaryPhi; - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < nLayers; ++i) { hPrimary.emplace_back(Form("primary/L%d", i), Form("L%d Primary Cluster Size", i), maxClusterSize, 0, maxClusterSize); hPrimaryEta.emplace_back(Form("primary/EtaL%d", i), Form("L%d Primary Cluster Size vs Eta", i), maxClusterSize, 0, maxClusterSize, 100, -3.0, 3.0); hPrimaryPt.emplace_back(Form("primary/Pt%d", i), Form("L%d Primary Cluster Size vs Pt", i), maxClusterSize, 0, maxClusterSize, 100, 0.0, 10.0); @@ -238,14 +243,15 @@ void CheckClusterSize(std::string clusFileName = "o2clus_its.root", int nROFRec = (int)rofRecVec.size(); auto pattIt = patternsPtr->cbegin(); + int cInvalid{0}, cGood{0}; for (int irof = 0; irof < nROFRec; irof++) { const auto& rofRec = rofRecVec[irof]; - // rofRec.print(); + /*rofRec.print();*/ for (int icl = 0; icl < rofRec.getNEntries(); icl++) { int clEntry = rofRec.getFirstEntry() + icl; const auto& cluster = clusArr[clEntry]; - // cluster.print(); + /*cluster.print();*/ auto pattId = cluster.getPatternID(); auto id = cluster.getSensorID(); @@ -260,13 +266,15 @@ void CheckClusterSize(std::string clusFileName = "o2clus_its.root", const auto& label = (clusLabArr->getLabels(clEntry))[0]; if (!label.isValid() || label.getSourceID() != 0 || !label.isCorrect()) { + ++cInvalid; continue; } + ++cGood; const int trackID = label.getTrackID(); int evID = label.getEventID(); const auto& pInfo = info[evID][trackID]; - if (id > 6) { + if (!o2::its3::constants::detID::isDetITS3(id)) { hOuterBarrel.Fill(clusterSize); } @@ -332,6 +340,7 @@ void CheckClusterSize(std::string clusFileName = "o2clus_its.root", } } } + std::cout << "Good labels: " << cGood << "; invalid: " << cInvalid << '\n'; std::cout << "Done measuring cluster sizes:" << std::endl; for (int i = 0; i < nLayers; ++i) { std::cout << "* Layer " << i << ":\n"; diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index af03ed7a9877b..13db31b46aa4e 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -57,7 +57,8 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", using ROFRec = o2::itsmft::ROFRecord; using MC2ROF = o2::itsmft::MC2ROFRecord; using HitVec = std::vector; - using MC2HITS_map = std::unordered_map; // maps (track_ID<<16 + chip_ID) to entry in the hit vector + using MC2HITS_map = std::unordered_map; // maps (track_ID<<32 + chip_ID) to entry in the hit vector + std::array mSuperSegmentations{0, 1, 2}; std::vector hitVecPool; std::vector mc2hitVec; @@ -234,10 +235,10 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", } else { // compare in local flat coordinates float xFlatEnd{0.}, yFlatEnd{0.}; - o2::its3::SuperSegmentations[layer].curvedToFlat(locH.X(), locH.Y(), xFlatEnd, yFlatEnd); + mSuperSegmentations[layer].curvedToFlat(locH.X(), locH.Y(), xFlatEnd, yFlatEnd); locH.SetXYZ(xFlatEnd, yFlatEnd, locH.Z()); float xFlatSta{0.}, yFlatSta{0.}; - o2::its3::SuperSegmentations[layer].curvedToFlat(locHsta.X(), locHsta.Y(), xFlatSta, yFlatSta); + mSuperSegmentations[layer].curvedToFlat(locHsta.X(), locHsta.Y(), xFlatSta, yFlatSta); locHsta.SetXYZ(xFlatSta, yFlatSta, locHsta.Z()); // recalculate x/y in flat // x0 = xFlatSta, dltx = xFlatEnd - x0; @@ -248,7 +249,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", // not really precise, but okish locH.SetXYZ(0.5f * (locH.X() + locHsta.X()), 0.5f * (locH.Y() + locHsta.Y()), 0.5f * (locH.Z() + locHsta.Z())); - o2::its3::SuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlatSta, yFlatSta); + mSuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlatSta, yFlatSta); locC.SetXYZ(xFlatSta, yFlatSta, locC.Z()); } diff --git a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C index f454745c0f076..486ef2bb8d84d 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C +++ b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C @@ -126,9 +126,9 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", TFile fileC(clusfile.data()); auto* clusTree = dynamic_cast(fileC.Get("o2sim")); std::vector* clusArr = nullptr; - clusTree->SetBranchAddress("IT3ClusterComp", &clusArr); + clusTree->SetBranchAddress("ITSClusterComp", &clusArr); std::vector* patternsPtr = nullptr; - auto pattBranch = clusTree->GetBranch("IT3ClusterPatt"); + auto pattBranch = clusTree->GetBranch("ITSClusterPatt"); if (pattBranch != nullptr) { pattBranch->SetAddress(&patternsPtr); } @@ -146,14 +146,14 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", // ROFrecords std::vector rofRecVec, *rofRecVecP = &rofRecVec; - clusTree->SetBranchAddress("IT3ClustersROF", &rofRecVecP); + clusTree->SetBranchAddress("ITSClustersROF", &rofRecVecP); // Cluster MC labels o2::dataformats::MCTruthContainer* clusLabArr = nullptr; std::vector mc2rofVec, *mc2rofVecP = &mc2rofVec; - if ((hitTree != nullptr) && (clusTree->GetBranch("IT3ClusterMCTruth") != nullptr)) { - clusTree->SetBranchAddress("IT3ClusterMCTruth", &clusLabArr); - clusTree->SetBranchAddress("IT3ClustersMC2ROF", &mc2rofVecP); + if ((hitTree != nullptr) && (clusTree->GetBranch("ITSClusterMCTruth") != nullptr)) { + clusTree->SetBranchAddress("ITSClusterMCTruth", &clusLabArr); + clusTree->SetBranchAddress("ITSClustersMC2ROF", &mc2rofVecP); } clusTree->GetEntry(0); @@ -340,8 +340,8 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", } auto& dat = data[iChip]; gFile->cd(); - /* auto path = gman->getMatrixPath(iChip); */ - TString path; // TODO wrong use above + auto path = gman->getMatrixPath(iChip); + /*TString path; // TODO wrong use above*/ const std::string cpath{path.Data() + 39, path.Data() + path.Length()}; const std::filesystem::path p{cpath}; if (oFile->mkdir(p.parent_path().c_str(), "", true) == nullptr) { From f2930352f222202cfc2da1f69eeaedf4de721e51 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 24 Jan 2025 10:41:00 +0100 Subject: [PATCH 10/34] ITS3: double precision for geometry + z-shift Signed-off-by: Felix Schlepper --- .../ITS3Base/SegmentationSuperAlpide.h | 2 +- .../ITS3/base/include/ITS3Base/SpecsV2.h | 91 ++++++++++--------- .../include/ITS3Simulation/ITS3Layer.h | 2 +- .../ITS3/simulation/src/ITS3Layer.cxx | 7 +- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h index 524d6b59352a2..10e586b50ecb4 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h @@ -70,7 +70,7 @@ class SegmentationSuperAlpide static constexpr float mSensorLayerThickness{constants::thickness}; static constexpr float mSensorLayerThicknessEff{constants::effThickness}; static constexpr float mSensorLayerThicknessCorr{constants::corrThickness}; - static constexpr std::array mRadii{constants::radii}; + static constexpr std::array mRadii{constants::radiiF}; /// Transformation from the curved surface to a flat surface /// \param xCurved Detector local curved coordinate x in cm with respect to diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index 394a3674e84ec..c8880788edebe 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -23,109 +23,110 @@ namespace o2::its3::constants { -constexpr float cm{1e+2}; // This is the default unit of TGeo so we use this as scale -constexpr float mu{1e-6 * cm}; -constexpr float mm{1e-3 * cm}; +constexpr double cm{1e+2}; // This is the default unit of TGeo so we use this as scale +constexpr double mu{1e-6 * cm}; +constexpr double mm{1e-3 * cm}; namespace pixelarray { -constexpr float width{9.197 * mm}; -constexpr float length{3.571 * mm}; +constexpr double width{9.197 * mm}; +constexpr double length{3.571 * mm}; constexpr int nCols{156}; constexpr int nRows{442}; constexpr int nPixels{nRows * nCols}; constexpr EColor color{kGreen}; -constexpr float area{width * length}; +constexpr double area{width * length}; } // namespace pixelarray namespace tile { namespace biasing { -constexpr float width{0.06 * mm}; -constexpr float length{3.571 * mm}; +constexpr double width{0.06 * mm}; +constexpr double length{3.571 * mm}; constexpr EColor color{kYellow}; static_assert(length == pixelarray::length); } // namespace biasing namespace powerswitches { -constexpr float width{9.257 * mm}; -constexpr float length{0.02 * mm}; -constexpr float z{pixelarray::width}; +constexpr double width{9.257 * mm}; +constexpr double length{0.02 * mm}; +constexpr double z{pixelarray::width}; constexpr EColor color{kBlue}; } // namespace powerswitches namespace readout { -constexpr float width{0.525 * mm}; -constexpr float length{3.591 * mm}; +constexpr double width{0.525 * mm}; +constexpr double length{3.591 * mm}; constexpr EColor color{kMagenta}; static_assert(length == (biasing::length + powerswitches::length)); } // namespace readout -constexpr float length{readout::length}; -constexpr float width{powerswitches::width + readout::width}; +constexpr double length{readout::length}; +constexpr double width{powerswitches::width + readout::width}; } // namespace tile namespace rsu { namespace databackbone { -constexpr float width{9.782 * mm}; -constexpr float length{0.06 * mm}; +constexpr double width{9.782 * mm}; +constexpr double length{0.06 * mm}; constexpr EColor color{kRed}; } // namespace databackbone -constexpr float width{19.564 * mm}; -constexpr float length{21.666 * mm}; +constexpr double width{19.564 * mm}; +constexpr double length{21.666 * mm}; constexpr unsigned int nTiles{12}; } // namespace rsu namespace segment { -constexpr float width{rsu::width}; +constexpr double width{rsu::width}; namespace lec { -constexpr float width{segment::width}; -constexpr float length{4.5 * mm}; +constexpr double width{segment::width}; +constexpr double length{4.5 * mm}; constexpr EColor color{kCyan}; } // namespace lec namespace rec { -constexpr float width{segment::width}; -constexpr float length{1.5 * mm}; +constexpr double width{segment::width}; +constexpr double length{1.5 * mm}; constexpr EColor color{kCyan}; } // namespace rec constexpr unsigned int nRSUs{12}; constexpr unsigned int nTilesPerSegment{nRSUs * rsu::nTiles}; -constexpr float length{nRSUs * rsu::length + lec::length + rec::length}; -constexpr float lengthSensitive{nRSUs * rsu::length}; +constexpr double length{nRSUs * rsu::length + lec::length + rec::length}; +constexpr double lengthSensitive{nRSUs * rsu::length}; } // namespace segment namespace carbonfoam { // TODO: Waiting for the further information from WP5(Corrado) -constexpr float longeronsWidth{2.0 * mm}; // what is the height of the longerons? -constexpr float longeronsLength{263 * mm}; // from blueprint -constexpr float HringLength{6.0 * mm}; // from blueprint -constexpr float edgeBetwChipAndFoam{1.0 * mm}; // from blueprint but not used cause forms are already overlapping -constexpr float gapBetwHringsLongerons{0.05 * mm}; // from blueprint -constexpr std::array nHoles{11, 11, 11}; // how many holes for each layer? -constexpr std::array radiusHoles{1.0 * mm, 1.0 * mm, 2.0 * mm}; // what is the radius of the holes for each layer? +constexpr double longeronsWidth{2.0 * mm}; // what is the height of the longerons? +constexpr double longeronsLength{263 * mm}; // from blueprint +constexpr double HringLength{6.0 * mm}; // from blueprint +constexpr double edgeBetwChipAndFoam{1.0 * mm}; // from blueprint but not used cause forms are already overlapping +constexpr double gapBetwHringsLongerons{0.05 * mm}; // from blueprint +constexpr std::array nHoles{11, 11, 11}; // how many holes for each layer? +constexpr std::array radiusHoles{1.0 * mm, 1.0 * mm, 2.0 * mm}; // what is the radius of the holes for each layer? constexpr EColor color{kGray}; } // namespace carbonfoam namespace metalstack { -constexpr float thickness{5 * mu}; // physical thickness of the copper metal stack -constexpr float length{segment::length}; -constexpr float width{segment::width}; +constexpr double thickness{5 * mu}; // physical thickness of the copper metal stack +constexpr double length{segment::length}; +constexpr double width{segment::width}; constexpr EColor color{kBlack}; } // namespace metalstack constexpr unsigned int nLayers{3}; constexpr unsigned int nTotLayers{7}; constexpr unsigned int nSensorsIB{2 * nLayers}; -constexpr float equatorialGap{1 * mm}; +constexpr double equatorialGap{1 * mm}; constexpr std::array nSegments{3, 4, 5}; -constexpr float epitaxialThickness{10 * mu}; // eptixial layer (charge collection) -constexpr float psubThickness{40 * mu}; // silicon substrate -constexpr float thickness{epitaxialThickness + psubThickness}; // physical thickness of chip -constexpr float effThickness{epitaxialThickness / 2.0 + psubThickness}; // effective physical thickness -constexpr float corrThickness{effThickness - thickness / 2.0}; // correction to get into the epitxial layer -constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. -constexpr std::array radiiInner{radii[0] - thickness / 2.0, radii[1] - thickness / 2.0, radii[2] - thickness / 2.0}; // inner radius -constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // inner radius +constexpr double epitaxialThickness{10 * mu}; // eptixial layer (charge collection) +constexpr double psubThickness{40 * mu}; // silicon substrate +constexpr double thickness{epitaxialThickness + psubThickness}; // physical thickness of chip +constexpr double effThickness{epitaxialThickness / 2.0 + psubThickness}; // effective physical thickness +constexpr double corrThickness{effThickness - thickness / 2.0}; // correction to get into the epitxial layer +constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. +constexpr std::array radiiF{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. +constexpr std::array radiiInner{radii[0] - thickness / 2.0, radii[1] - thickness / 2.0, radii[2] - thickness / 2.0}; // inner radius +constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // inner radius namespace detID { constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h index 3ca506845aadd..fd9195f9ee228 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h @@ -96,7 +96,7 @@ class ITS3Layer uint8_t mNLayer{0}; // Layer number double mR{0}; // Middle Radius - double mRmin{}; // Minimum Radius + double mRmin{0}; // Minimum Radius double mRmax{0}; // Maximum Radius // Individual pieces diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index 153fe8ab620fd..f3667c5393b4b 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -73,7 +73,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) return; } // Add it to motherVolume - auto* trans = new TGeoTranslation(0, 0, -constants::segment::lengthSensitive / 2.); + auto* trans = new TGeoTranslation(0, 0, -constants::segment::lengthSensitive / 2. - constants::rsu::databackbone::length / 2. + constants::tile::powerswitches::length / 2.); motherVolume->AddNode(mLayer, 0, trans); } @@ -293,7 +293,7 @@ void ITS3Layer::createCarbonForm() mCarbonForm->VisibleDaughters(); double dRadius = -1; if (mNLayer < 2) { - dRadius = constants::radii[mNLayer + 1] - constants::radii[mNLayer] - constants::thickness; + dRadius = constants::radii[mNLayer + 1] - constants::radii[mNLayer] - constants::thickness - constants::metalstack::thickness; } else { dRadius = 0.7; // TODO: lack of carbon foam radius for layer 2, use 0.7mm as a temporary value } @@ -409,8 +409,7 @@ void ITS3Layer::buildPartial(TGeoVolume* motherVolume, TGeoMatrix* mat, BuildLev case BuildLevel::kLayer: [[fallthrough]]; default: - createLayerImpl(); - motherVolume->AddNode(mLayer, 0, mat); + createLayer(motherVolume); } LOGP(info, "Partially built ITS3-{}-{}", mNLayer, getName(level)); } From a7d0cf7404ea01dc391b834108839ba5c4259c36 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 24 Jan 2025 11:45:35 +0100 Subject: [PATCH 11/34] ITS3: Digitizer constness Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index b85574402de5b..531387ee256d6 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -297,8 +297,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID rowS = 0; } - int maxNrows{innerBarrel ? SegmentationSuperAlpide::mNRows : Segmentation::NRows}; - int maxNcols{innerBarrel ? SegmentationSuperAlpide::mNCols : Segmentation::NCols}; + const int maxNrows{innerBarrel ? SegmentationSuperAlpide::mNRows : Segmentation::NRows}; + const int maxNcols{innerBarrel ? SegmentationSuperAlpide::mNCols : Segmentation::NCols}; if (rowE >= maxNrows) { rowE = maxNrows - 1; } From 2ce3be32eef7e172e7bf76b36e7ec480fd2be51f Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 24 Jan 2025 14:34:46 +0100 Subject: [PATCH 12/34] ITS3: macro include cluster eta, row, col Signed-off-by: Felix Schlepper --- .../ITS3/macros/test/CheckClustersITS3.C | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index 13db31b46aa4e..a7a65b5045f1e 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -42,7 +42,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", const std::string& hitfile = "o2sim_HitsIT3.root", const std::string& inputGeom = "", - std::string dictfile = "./ccdb/IT3/Calib/ClusterDictionary/snapshot.root", + std::string dictfile = "../ccdb/IT3/Calib/ClusterDictionary/snapshot.root", bool batch = false) { gROOT->SetBatch(batch); @@ -66,7 +66,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", ULong_t cPattValid{0}, cPattInvalid{0}, cLabelInvalid{0}, cNoMC{0}; TFile fout("CheckClusters.root", "recreate"); - 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"); + 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:eta:row:col"); // Geometry o2::base::GeometryManager::loadGeometry(inputGeom); @@ -252,8 +252,10 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", mSuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlatSta, yFlatSta); locC.SetXYZ(xFlatSta, yFlatSta, locC.Z()); } + float theta = std::acos(gloC.Z() / gloC.Rho()); + float eta = -std::log(std::tan(theta / 2)); - std::array data = {(float)lab.getEventID(), (float)trID, + std::array data = {(float)lab.getEventID(), (float)trID, locH.X(), locH.Z(), gloH.X(), gloH.Z(), dltx / dlty, dltz / dlty, @@ -261,7 +263,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", locC.X(), locC.Y(), locC.Z(), locC.X() - locH.X(), locC.Y() - locH.Y(), locC.Z() - locH.Z(), errX, errZ, (float)pattID, - (float)rofRec.getROFrame(), (float)npix, (float)chipID}; + (float)rofRec.getROFrame(), (float)npix, (float)chipID, eta, (float)cluster.getRow(), (float)cluster.getCol()}; nt.Fill(data.data()); } } @@ -293,6 +295,18 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", nt.Draw("dx:dz>>h_dx_vs_dz_OB_z(1000, -0.01, 0.01, 1000, -0.01, 0.01)", "id >= 3456 && abs(cgz) < 2", "colz"); canvdXdZ->SaveAs("it3clusters_dx_vs_dz.pdf"); + auto canvCHXZ = new TCanvas("canvCHXZ", "", 1600, 1600); + canvCHXZ->Divide(2, 2); + canvCHXZ->cd(1); + nt.Draw("(cgx-hgx)*10000:eta>>h_chx_IB(101,-1.4,1.4,101,-50,50)", "id<3456", "prof"); + canvCHXZ->cd(2); + nt.Draw("(cgx-hgx)*10000:eta>>h_chx_OB(101,-1.4,1.4,101,-50,50)", "id>=3456", "prof"); + canvCHXZ->cd(3); + nt.Draw("(cgz-hgz)*10000:eta>>h_chz_IB(101,-1.4,1.4,101,-50,50)", "id<3456", "prof"); + canvCHXZ->cd(4); + nt.Draw("(cgz-hgz)*10000:eta>>h_chz_OB(101,-1.4,1.4,101,-50,50)", "id>=3456", "prof"); + canvCgXCgY->SaveAs("it3clusters_xz_eta.pdf"); + auto c1 = new TCanvas("p1", "pullX"); c1->cd(); c1->SetLogy(); From 79732e3d30dc1b6802402984a12877b6efc16145 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Sat, 25 Jan 2025 23:46:16 +0100 Subject: [PATCH 13/34] ITS3: extend wrapvolZ to include outer edges Signed-off-by: Felix Schlepper --- .../include/ITS3Simulation/DescriptorInnerBarrelITS3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h index 80536a14d99c2..d1b54f81face4 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h @@ -45,9 +45,9 @@ class DescriptorInnerBarrelITS3 : public o2::its::DescriptorInnerBarrel int mNumLayers{constants::nLayers}; // wrapper volume properties - double mWrapperMinRadiusITS3{1.8}; - double mWrapperMaxRadiusITS3{4.}; - double mWrapperZSpanITS3{20.}; + static constexpr double mWrapperMinRadiusITS3{1.8}; + static constexpr double mWrapperMaxRadiusITS3{4.}; + static constexpr double mWrapperZSpanITS3{constants::segment::length + 5.}; private: std::array, constants::nLayers> mIBLayers; From 5a672def2d21aaf4c97482cbe87a63263c3af4cf Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 27 Jan 2025 08:37:14 +0100 Subject: [PATCH 14/34] ITS3: remove unused var Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx index 50e651f7f5675..0fecf914ac6eb 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx @@ -80,7 +80,6 @@ int loadROFrameDataITS3(its::TimeFrame* tf, auto isITS3 = its3::constants::detID::isDetITS3(sensorID); auto layer = geom->getLayer(sensorID); - auto pattID = c.getPatternID(); float sigmaY2{0}, sigmaZ2{0}, sigmaYZ{0}; uint8_t clusterSize{0}; auto locXYZ = extractClusterData(c, pattIt, dict, sigmaY2, sigmaZ2, clusterSize); From f8194f26ef8b5f334cbeb8cde4823a89ed570cba Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 27 Jan 2025 10:53:00 +0100 Subject: [PATCH 15/34] ITS3: cluster macro Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index a7a65b5045f1e..58570bd47bc55 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -66,7 +66,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", ULong_t cPattValid{0}, cPattInvalid{0}, cLabelInvalid{0}, cNoMC{0}; TFile fout("CheckClusters.root", "recreate"); - 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:eta:row:col"); + 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:eta:row:col:lay"); // Geometry o2::base::GeometryManager::loadGeometry(inputGeom); @@ -255,7 +255,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", float theta = std::acos(gloC.Z() / gloC.Rho()); float eta = -std::log(std::tan(theta / 2)); - std::array data = {(float)lab.getEventID(), (float)trID, + std::array data = {(float)lab.getEventID(), (float)trID, locH.X(), locH.Z(), gloH.X(), gloH.Z(), dltx / dlty, dltz / dlty, @@ -263,7 +263,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", locC.X(), locC.Y(), locC.Z(), locC.X() - locH.X(), locC.Y() - locH.Y(), locC.Z() - locH.Z(), errX, errZ, (float)pattID, - (float)rofRec.getROFrame(), (float)npix, (float)chipID, eta, (float)cluster.getRow(), (float)cluster.getCol()}; + (float)rofRec.getROFrame(), (float)npix, (float)chipID, eta, (float)cluster.getRow(), (float)cluster.getCol(), (float)layer}; nt.Fill(data.data()); } } From a6320806620af2d55f4d5ec65dfb0d105ad915c9 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 3 Feb 2025 11:57:05 +0100 Subject: [PATCH 16/34] ITS3: Add DigiParams Signed-off-by: Felix Schlepper --- .../Upgrades/ITS3/simulation/CMakeLists.txt | 4 +- .../include/ITS3Simulation/DigiParams.h | 45 +++++++++++++++++++ .../ITS3/simulation/src/DigiParams.cxx | 40 +++++++++++++++++ .../simulation/src/ITS3SimulationLinkDef.h | 1 + 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DigiParams.h create mode 100644 Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx diff --git a/Detectors/Upgrades/ITS3/simulation/CMakeLists.txt b/Detectors/Upgrades/ITS3/simulation/CMakeLists.txt index 17a8fd2748b87..2fad72a96426d 100644 --- a/Detectors/Upgrades/ITS3/simulation/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/simulation/CMakeLists.txt @@ -14,6 +14,7 @@ o2_add_library(ITS3Simulation src/ITS3Services.cxx src/DescriptorInnerBarrelITS3.cxx src/Digitizer.cxx + src/DigiParams.cxx PUBLIC_LINK_LIBRARIES O2::SimulationDataFormat O2::ITSBase O2::ITSMFTSimulation ROOT::Physics) @@ -23,6 +24,7 @@ o2_target_root_dictionary(ITS3Simulation include/ITS3Simulation/ITS3Services.h include/ITS3Simulation/DescriptorInnerBarrelITS3.h include/ITS3Simulation/Digitizer.h + include/ITS3Simulation/DigiParams.h ) -o2_data_file(COPY data DESTINATION Detectors/ITS3/simulation) \ No newline at end of file +o2_data_file(COPY data DESTINATION Detectors/ITS3/simulation) diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DigiParams.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DigiParams.h new file mode 100644 index 0000000000000..eca0a71949ba7 --- /dev/null +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DigiParams.h @@ -0,0 +1,45 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ITS3_DIGIPARAMS_H +#define ITS3_DIGIPARAMS_H + +#include "ITSMFTSimulation/DigiParams.h" + +namespace o2::its3 +{ + +class DigiParams final : public o2::itsmft::DigiParams +{ + public: + const o2::itsmft::AlpideSimResponse* getAlpSimResponse() const = delete; + void setAlpSimResponse(const o2::itsmft::AlpideSimResponse* par) = delete; + + const o2::itsmft::AlpideSimResponse* getOBSimResponse() const { return mOBSimResponse; } + void setOBSimResponse(const o2::itsmft::AlpideSimResponse* response) { mOBSimResponse = response; } + + const o2::itsmft::AlpideSimResponse* getIBSimResponse() const { return mIBSimResponse; } + void setIBSimResponse(const o2::itsmft::AlpideSimResponse* response) { mIBSimResponse = response; } + + bool hasResponseFunctions() const { return mIBSimResponse != nullptr && mOBSimResponse != nullptr; } + + void print() const final; + + private: + const o2::itsmft::AlpideSimResponse* mOBSimResponse = nullptr; //!< pointer to external response + const o2::itsmft::AlpideSimResponse* mIBSimResponse = nullptr; //!< pointer to external response + + ClassDef(DigiParams, 1); +}; + +} // namespace o2::its3 + +#endif diff --git a/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx b/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx new file mode 100644 index 0000000000000..e07e581c3c28c --- /dev/null +++ b/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx @@ -0,0 +1,40 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file DigiParams.cxx +/// \brief Implementation of the ITS3 digitization steering params + +#include "Framework/Logger.h" +#include "ITS3Simulation/DigiParams.h" + +ClassImp(o2::its3::DigiParams); + +namespace o2::its3 +{ + +void DigiParams::print() const +{ + // print settings + LOGF(info, "ITS3 DigiParams settings:\n"); + LOGF(info, "Continuous readout : %s\n", isContinuous() ? "ON" : "OFF"); + LOGF(info, "Readout Frame Length(ns) : %f\n", getROFrameLength()); + LOGF(info, "Strobe delay (ns) : %f\n", getStrobeDelay()); + LOGF(info, "Strobe length (ns) : %f\n", getStrobeLength()); + LOGF(info, "Threshold (N electrons) : %d\n", getChargeThreshold()); + LOGF(info, "Min N electrons to account : %d\n", getMinChargeToAccount()); + LOGF(info, "Number of charge sharing steps : %d\n", getNSimSteps()); + LOGF(info, "ELoss to N electrons factor : %e\n", getEnergyToNElectrons()); + LOGF(info, "Noise level per pixel : %e\n", getNoisePerPixel()); + LOGF(info, "Charge time-response:\n"); + getSignalShape().print(); +} + +} // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3SimulationLinkDef.h b/Detectors/Upgrades/ITS3/simulation/src/ITS3SimulationLinkDef.h index b9af595018a34..fca3f5d63c2c4 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3SimulationLinkDef.h +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3SimulationLinkDef.h @@ -18,6 +18,7 @@ #pragma link C++ class o2::its3::ITS3Layer + ; #pragma link C++ class o2::its3::ITS3Services + ; #pragma link C++ class o2::its3::DescriptorInnerBarrelITS3 + ; +#pragma link C++ class o2::its3::DigiParams + ; #pragma link C++ class o2::its3::Digitizer + ; #endif From 7ad18a76350975bbb406dc641fc45998b4db3912 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 31 Jan 2025 17:52:06 +0100 Subject: [PATCH 17/34] ITS3: Digitizer option to pick response function Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/ITS3Params.h | 5 +- .../include/ITS3Simulation/Digitizer.h | 24 +++++---- .../ITS3/simulation/src/Digitizer.cxx | 50 +++++++++++++++---- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h index c685bf0f085d6..af00e88ef0d92 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h @@ -25,7 +25,10 @@ struct ITS3Params : public o2::conf::ConfigurableParamHelper { bool misalignmentHitsUseProp{false}; // Use propagtor for mis-alignment std::string globalGeoMisAlignerMacro{"${O2_ROOT}/share/macro/MisAlignGeoITS3.C"}; // Path to macro for global geometry mis-alignment // Chip studies - bool useDeadChannelMap{false}; // Query for a dead channel map to study disabling individual tiles + bool useDeadChannelMap{false}; // Query for a dead channel map to study disabling individual tiles + std::string chipResponseFunction{"APTS"}; // Chip response function one of "Alpide", "APTS" or "Mosaix" (not yet available) + std::string responseFunctionIB{"response0"}; // Chip response function name for IB + std::string responseFunctionOB{"response1"}; // Chip response function name for 0B O2ParamDef(ITS3Params, "ITS3Params"); }; diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index 67b0cc7456a46..01ca21961edb8 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -18,15 +18,15 @@ #include #include -#include "Rtypes.h" // for Digitizer::Class -#include "TObject.h" // for TObject +#include "Rtypes.h" +#include "TObject.h" #include "ITSMFTSimulation/ChipDigitsContainer.h" #include "ITSMFTSimulation/AlpideSimResponse.h" -#include "ITSMFTSimulation/DigiParams.h" #include "ITSMFTSimulation/Hit.h" #include "ITSBase/GeometryTGeo.h" #include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Simulation/DigiParams.h" #include "DataFormatsITSMFT/Digit.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "CommonDataFormat/InteractionRecord.h" @@ -35,6 +35,7 @@ namespace o2::its3 { + class Digitizer : public TObject { using ExtraDig = std::vector; ///< container for extra contributions to PreDigits @@ -44,8 +45,8 @@ class Digitizer : public TObject void setMCLabels(o2::dataformats::MCTruthContainer* mclb) { mMCLabels = mclb; } void setROFRecords(std::vector* rec) { mROFRecords = rec; } - o2::itsmft::DigiParams& getParams() { return (o2::itsmft::DigiParams&)mParams; } - const o2::itsmft::DigiParams& getParams() const { return mParams; } + o2::its3::DigiParams& getParams() { return mParams; } + const o2::its3::DigiParams& getParams() const { return mParams; } void init(); @@ -62,9 +63,6 @@ class Digitizer : public TObject bool isContinuous() const { return mParams.isContinuous(); } void fillOutputContainer(uint32_t maxFrame = 0xffffffff); - void setDigiParams(const o2::itsmft::DigiParams& par) { mParams = par; } - const o2::itsmft::DigiParams& getDigitParams() const { return mParams; } - // provide the common itsmft::GeometryTGeo to access matrices and segmentation void setGeometry(const o2::its::GeometryTGeo* gm) { mGeometry = gm; } @@ -97,7 +95,7 @@ class Digitizer : public TObject static constexpr float sec2ns = 1e9; - o2::itsmft::DigiParams mParams; ///< digitization parameters + o2::its3::DigiParams mParams; ///< digitization parameters o2::InteractionTimeRecord mEventTime; ///< global event time and interaction record o2::InteractionRecord mIRFirstSampledTF; ///< IR of the 1st sampled IR, noise-only ROFs will be inserted till this IR only double mCollisionTimeWrtROF{}; @@ -110,7 +108,10 @@ class Digitizer : public TObject const std::array mSuperSegmentations{0, 1, 2}; - o2::itsmft::AlpideSimResponse* mAlpSimResp = nullptr; // simulated response + o2::itsmft::AlpideSimResponse* mSimRespIB = nullptr; // simulated response for IB + o2::itsmft::AlpideSimResponse* mSimRespOB = nullptr; // simulated response for OB + float mSimRespIBShift{0.}; // adjusting the Y-shift in the IB response function to match sensor local coord. + float mSimRespOBShift{0.}; // adjusting the Y-shift in the OB response function to match sensor local coord. const o2::its::GeometryTGeo* mGeometry = nullptr; ///< ITS3 geometry @@ -123,8 +124,9 @@ class Digitizer : public TObject const o2::itsmft::NoiseMap* mDeadChanMap = nullptr; - ClassDef(Digitizer, 4); + ClassDef(Digitizer, 5); }; + } // namespace o2::its3 #endif /* ALICEO2_ITS3_DIGITIZER_H */ diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 531387ee256d6..24cadc4117c05 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -14,6 +14,7 @@ #include "ITSMFTBase/SegmentationAlpide.h" #include "ITS3Simulation/Digitizer.h" +#include "ITS3Base/ITS3Params.h" #include "MathUtils/Cartesian.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "DetectorsRaw/HBFUtils.h" @@ -43,12 +44,39 @@ void Digitizer::init() } } - if (mParams.getAlpSimResponse() == nullptr) { - std::string responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; - LOGP(info, "Loading AlpideSimRespnse from file: {}", responseFile); - auto file = TFile::Open(responseFile.data()); - mAlpSimResp = (o2::itsmft::AlpideSimResponse*)file->Get("response0"); // We use by default the alpide response for Vbb=0V - mParams.setAlpSimResponse(mAlpSimResp); + if (!mParams.hasResponseFunctions()) { + auto loadSetResponseFunc = [&](const char* fileIB, const char* fileOB, const char* name) { + const auto& nameIB = ITS3Params::Instance().responseFunctionIB; + const auto& nameOB = ITS3Params::Instance().responseFunctionOB; + LOGP(info, "Loading response function for {}: IB={}:{} / OB={}:{}", name, nameIB, fileIB, nameOB, fileOB); + auto fIB = TFile::Open(fileIB); + if (fIB->IsZombie() || !fIB->IsOpen()) { + LOGP(fatal, "Cannot open file {}", fileIB); + } + auto fOB = TFile::Open(fileIB); + if (fOB->IsZombie() || !fOB->IsOpen()) { + LOGP(fatal, "Cannot open file {}", fileOB); + } + mParams.setIBSimResponse(mSimRespIB = fIB->Get(nameIB.c_str())); + mParams.setOBSimResponse(mSimRespOB = fOB->Get(nameOB.c_str())); + fIB->Close(); + fOB->Close(); + }; + + if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") { + constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; + loadSetResponseFunc(responseFile, responseFile, "Alpide"); + mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationSuperAlpide::mSensorLayerThickness / 2.f; + mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; + } else if (func == "APTS") { + constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; + constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; + loadSetResponseFunc(responseFileIB, responseFileOB, "APTS"); + mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; + mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; + } else { + LOGP(fatal, "ResponseFunction '{}' not implemented!", func); + } } mParams.print(); mIRFirstSampledTF = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); @@ -326,8 +354,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID // take into account that the AlpideSimResponse depth defintion has different min/max boundaries // although the max should coincide with the surface of the epitaxial layer, which in the chip // local coordinates has Y = +SensorLayerThickness/2 - float thickness = innerBarrel ? SegmentationSuperAlpide::mSensorLayerThickness : Segmentation::SensorLayerThickness; - xyzLocS.SetY(xyzLocS.Y() + mAlpSimResp->getDepthMax() - thickness / 2.); + xyzLocS.SetY(xyzLocS.Y() + ((innerBarrel) ? mSimRespIBShift : mSimRespOBShift)); + // collect charge in evey pixel which might be affected by the hit for (int iStep = nSteps; iStep--;) { // Get the pixel ID @@ -349,9 +377,9 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID } bool flipCol = false, flipRow = false; // note that response needs coordinates along column row (locX) (locZ) then depth (locY) - double rowMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchRow : Segmentation::PitchRow)}; - double colMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchCol : Segmentation::PitchCol)}; - auto rspmat = mAlpSimResp->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); + float rowMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchRow : Segmentation::PitchRow)}; + float colMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchCol : Segmentation::PitchCol)}; + auto rspmat = ((innerBarrel) ? mSimRespIB : mSimRespOB)->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); xyzLocS += step; if (rspmat == nullptr) { From acd47bc571716ec02f6e0b6c211c261969ab47b1 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 31 Jan 2025 17:52:28 +0100 Subject: [PATCH 18/34] ITS3: build APTS response function Signed-off-by: Felix Schlepper --- Detectors/Upgrades/ITS3/CMakeLists.txt | 3 ++- Detectors/Upgrades/ITS3/data/CMakeLists.txt | 25 +++++++++++++++++++ .../ITS3/simulation/src/Digitizer.cxx | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 Detectors/Upgrades/ITS3/data/CMakeLists.txt diff --git a/Detectors/Upgrades/ITS3/CMakeLists.txt b/Detectors/Upgrades/ITS3/CMakeLists.txt index 6965061571da6..7cbb5cffe4243 100644 --- a/Detectors/Upgrades/ITS3/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/CMakeLists.txt @@ -11,9 +11,10 @@ #add_compile_options(-O0 -g -fPIC) -add_subdirectory(macros) +add_subdirectory(data) add_subdirectory(simulation) add_subdirectory(alignment) add_subdirectory(base) add_subdirectory(workflow) add_subdirectory(reconstruction) +add_subdirectory(macros) diff --git a/Detectors/Upgrades/ITS3/data/CMakeLists.txt b/Detectors/Upgrades/ITS3/data/CMakeLists.txt new file mode 100644 index 0000000000000..ba8b60c8aa7eb --- /dev/null +++ b/Detectors/Upgrades/ITS3/data/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +add_custom_target( + GenerateAPTSResponse ALL + COMMAND + ${CMAKE_BINARY_DIR}/stage/bin/o2-alpide-response-generator -c APTS -i + ${ITSRESPONSE_DIR}/response/ITS3ChipResponseData/AptsResponseData/ -o + ${CMAKE_CURRENT_BINARY_DIR}/ + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/APTSResponseData.root + DEPENDS GenerateAlpideResponse + COMMENT "Generating APTSResponseData.root") +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/APTSResponseData.root" + DESTINATION + "${CMAKE_INSTALL_PREFIX}/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/" +) diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 24cadc4117c05..b1e69d30bf159 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -69,7 +69,7 @@ void Digitizer::init() mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationSuperAlpide::mSensorLayerThickness / 2.f; mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; } else if (func == "APTS") { - constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; + constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/"; constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc(responseFileIB, responseFileOB, "APTS"); mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; From c70b15b2f0d576906e8e5610cfe26439e3bdfad3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 31 Jan 2025 18:21:54 +0100 Subject: [PATCH 19/34] ITS3: renamed SuperAlpide to Mosaix This is essentially a rebase on the changes by @ChunzhengLab. Signed-off-by: Felix Schlepper --- .../ITS3/alignment/src/MisalignmentHits.cxx | 1 - ...tionSuperAlpide.h => SegmentationMosaix.h} | 22 +++++++------- .../Upgrades/ITS3/macros/test/CMakeLists.txt | 4 +-- .../ITS3/macros/test/CheckClustersITS3.C | 21 +++++-------- .../ITS3/macros/test/CheckDigitsDensity.C | 12 ++++---- .../ITS3/macros/test/CheckDigitsITS3.C | 16 +++++----- .../Upgrades/ITS3/macros/test/CheckHits.C | 2 -- ...erAlpideSegment.C => CheckMosaixSegment.C} | 25 +++++++--------- ...gmentTrans.C => CheckMosaixSegmentTrans.C} | 30 +++++++++---------- .../ITS3/macros/test/CheckTileNumbering.C | 6 ++-- .../macros/test/CompareClustersAndDigits.C | 19 ++++++------ .../ITS3/macros/test/CreateDictionariesITS3.C | 13 ++++---- .../include/ITS3Reconstruction/IOUtils.h | 7 ++--- .../ITS3Reconstruction/TopologyDictionary.h | 11 ++++--- .../src/BuildTopologyDictionary.cxx | 1 - .../ITS3/reconstruction/src/Clusterer.cxx | 10 +++---- .../ITS3/reconstruction/src/IOUtils.cxx | 2 -- .../reconstruction/src/TopologyDictionary.cxx | 18 +++++------ .../include/ITS3Simulation/Digitizer.h | 4 +-- .../ITS3/simulation/src/Digitizer.cxx | 24 +++++++-------- 20 files changed, 115 insertions(+), 133 deletions(-) rename Detectors/Upgrades/ITS3/base/include/ITS3Base/{SegmentationSuperAlpide.h => SegmentationMosaix.h} (92%) rename Detectors/Upgrades/ITS3/macros/test/{CheckSuperAlpideSegment.C => CheckMosaixSegment.C} (91%) rename Detectors/Upgrades/ITS3/macros/test/{CheckSuperAlpideSegmentTrans.C => CheckMosaixSegmentTrans.C} (88%) diff --git a/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx index fbc0b5d623dca..66ab4c8090b54 100644 --- a/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx +++ b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx @@ -10,7 +10,6 @@ // or submit itself to any jurisdiction. #include "ITS3Align/MisalignmentHits.h" -#include "ITS3Base/SegmentationSuperAlpide.h" #include "ITS3Base/ITS3Params.h" #include "SimConfig/DigiParams.h" #include "DetectorsBase/Propagator.h" diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h similarity index 92% rename from Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h rename to Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index 10e586b50ecb4..ae21565f69a6b 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -9,12 +9,12 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file SegmentationSuperAlpide.h -/// \brief Definition of the SegmentationSuperAlpide class +/// \file SegmentationMosaix.h +/// \brief Definition of the SegmentationMosaix class /// \author felix.schlepper@cern.ch -#ifndef ALICEO2_ITS3_SEGMENTATIONSUPERALPIDE_H_ -#define ALICEO2_ITS3_SEGMENTATIONSUPERALPIDE_H_ +#ifndef ALICEO2_ITS3_SEGMENTATIONMOSAIX_H_ +#define ALICEO2_ITS3_SEGMENTATIONMOSAIX_H_ #include "MathUtils/Cartesian.h" #include "ITS3Base/SpecsV2.h" @@ -26,7 +26,7 @@ namespace o2::its3 { /// Segmentation and response for pixels in ITS3 upgrade -class SegmentationSuperAlpide +class SegmentationMosaix { // This class defines the segmenation of the pixelArray in the tile. We define // two coordinate systems, one width x,z detector local coordianates (cm) and @@ -53,12 +53,12 @@ class SegmentationSuperAlpide // | | | // x----------------------x public: - ~SegmentationSuperAlpide() = default; - SegmentationSuperAlpide(const SegmentationSuperAlpide&) = default; - SegmentationSuperAlpide(SegmentationSuperAlpide&&) = delete; - SegmentationSuperAlpide& operator=(const SegmentationSuperAlpide&) = default; - SegmentationSuperAlpide& operator=(SegmentationSuperAlpide&&) = delete; - constexpr SegmentationSuperAlpide(int layer) : mLayer{layer} {} + ~SegmentationMosaix() = default; + SegmentationMosaix(const SegmentationMosaix&) = default; + SegmentationMosaix(SegmentationMosaix&&) = delete; + SegmentationMosaix& operator=(const SegmentationMosaix&) = default; + SegmentationMosaix& operator=(SegmentationMosaix&&) = delete; + constexpr SegmentationMosaix(int layer) : mLayer{layer} {} static constexpr int mNCols{constants::pixelarray::nCols}; static constexpr int mNRows{constants::pixelarray::nRows}; diff --git a/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt b/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt index bdd0329c55ecd..39e435f0ba2e6 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt @@ -19,8 +19,8 @@ its3_add_macro(CheckHits.C) its3_add_macro(CheckDigitsDensity.C) its3_add_macro(CheckClusterSize.C) its3_add_macro(CompareClusterSize.C) -its3_add_macro(CheckSuperAlpideSegment.C) -its3_add_macro(CheckSuperAlpideSegmentTrans.C) +its3_add_macro(CheckMosaixSegment.C) +its3_add_macro(CheckMosaixSegmentTrans.C) its3_add_macro(CompareClustersAndDigits.C) its3_add_macro(CheckROFs.C) its3_add_macro(CheckTileNumbering.C) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index 58570bd47bc55..c2fc25ef0086f 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -25,7 +25,7 @@ #define ENABLE_UPGRADES #include "DetectorsCommonDataFormats/DetID.h" #include "ITSMFTBase/SegmentationAlpide.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITS3Base/SpecsV2.h" #include "ITSBase/GeometryTGeo.h" #include "DataFormatsITSMFT/CompCluster.h" @@ -50,7 +50,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", using namespace o2::base; using namespace o2::its; - using SuperSegmentation = o2::its3::SegmentationSuperAlpide; + using MosaixSegmentation = o2::its3::SegmentationMosaix; using Segmentation = o2::itsmft::SegmentationAlpide; using o2::itsmft::CompClusterExt; using o2::itsmft::Hit; @@ -58,7 +58,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", using MC2ROF = o2::itsmft::MC2ROFRecord; using HitVec = std::vector; using MC2HITS_map = std::unordered_map; // maps (track_ID<<32 + chip_ID) to entry in the hit vector - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; std::vector hitVecPool; std::vector mc2hitVec; @@ -185,8 +185,8 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", locC = dict.getClusterCoordinates(cluster); errX = dict.getErrX(pattID); errZ = dict.getErrZ(pattID); - errX *= (isIB) ? SuperSegmentation::mPitchRow : Segmentation::PitchRow; - errZ *= (isIB) ? SuperSegmentation::mPitchCol : Segmentation::PitchCol; + errX *= (isIB) ? MosaixSegmentation::mPitchRow : Segmentation::PitchRow; + errZ *= (isIB) ? MosaixSegmentation::mPitchCol : Segmentation::PitchCol; npix = dict.getNpixels(pattID); ++cPattValid; } @@ -235,21 +235,16 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", } else { // compare in local flat coordinates float xFlatEnd{0.}, yFlatEnd{0.}; - mSuperSegmentations[layer].curvedToFlat(locH.X(), locH.Y(), xFlatEnd, yFlatEnd); + mMosaixSegmentations[layer].curvedToFlat(locH.X(), locH.Y(), xFlatEnd, yFlatEnd); locH.SetXYZ(xFlatEnd, yFlatEnd, locH.Z()); float xFlatSta{0.}, yFlatSta{0.}; - mSuperSegmentations[layer].curvedToFlat(locHsta.X(), locHsta.Y(), xFlatSta, yFlatSta); + mMosaixSegmentations[layer].curvedToFlat(locHsta.X(), locHsta.Y(), xFlatSta, yFlatSta); locHsta.SetXYZ(xFlatSta, yFlatSta, locHsta.Z()); - // recalculate x/y in flat - // x0 = xFlatSta, dltx = xFlatEnd - x0; - // y0 = yFlatSta, dlty = yFlatEnd - y0; - // r = (0.5 * (SuperSegmentation::mSensorLayerThickness - SuperSegmentation::mSensorLayerThicknessEff) - y0) / dlty; - // locH.SetXYZ(x0 + r * dltx, y0 + r * dlty, z0 + r * dltz); // not really precise, but okish locH.SetXYZ(0.5f * (locH.X() + locHsta.X()), 0.5f * (locH.Y() + locHsta.Y()), 0.5f * (locH.Z() + locHsta.Z())); - mSuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlatSta, yFlatSta); + mMosaixSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlatSta, yFlatSta); locC.SetXYZ(xFlatSta, yFlatSta, locC.Z()); } float theta = std::acos(gloC.Z() / gloC.Rho()); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C index bb07c1a49b7f0..19a0357e65399 100755 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C @@ -37,7 +37,7 @@ #include "ITS3Base/SpecsV2.h" #include "CommonConstants/MathConstants.h" #include "DataFormatsITSMFT/Digit.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "DetectorsBase/GeometryManager.h" #include "ITSBase/GeometryTGeo.h" #include "fairlogger/Logger.h" @@ -56,7 +56,7 @@ constexpr double qedRate = qedXSection / hadXSection * interaction_rate; // Hz constexpr double qedFactor = qedRate * integration_time; // a.u. using o2::itsmft::Digit; namespace its3 = o2::its3; -using SSAlpide = its3::SegmentationSuperAlpide; +using Mosaix = its3::SegmentationMosaix; void checkFile(const std::unique_ptr& file); @@ -64,7 +64,7 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig { gROOT->SetBatch(batch); LOGP(debug, "Checking Digit ITS3 Density"); - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; // Geometry o2::base::GeometryManager::loadGeometry(geomFileName); @@ -103,8 +103,8 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig // goto curved coordinates float x{0.f}, y{0.f}, z{0.f}; float xFlat{0.f}, yFlat{0.f}; - mSuperSegmentations[layer].detectorToLocal(row, col, xFlat, z); - mSuperSegmentations[layer].flatToCurved(xFlat, 0., x, y); + mMosaixSegmentations[layer].detectorToLocal(row, col, xFlat, z); + mMosaixSegmentations[layer].flatToCurved(xFlat, 0., x, y); const o2::math_utils::Point3D locD(x, y, z); const auto gloD = gman->getMatrixL2G(id)(locD); // convert to global const auto R = std::hypot(gloD.X(), gloD.Y()); @@ -115,7 +115,7 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig std::unique_ptr oFile(TFile::Open("checkDigitsDensity.root", "RECREATE")); checkFile(oFile); for (const auto& h : hists) { - h->Scale(1. / (SSAlpide::mPitchCol * SSAlpide::mPitchRow * nEvents)); + h->Scale(1. / (Mosaix::mPitchCol * Mosaix::mPitchRow * nEvents)); h->ProjectionX()->Write(); h->Write(); } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C index 0ce9b4ed798f1..e6e5079aabf25 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C @@ -27,7 +27,7 @@ #define ENABLE_UPGRADES #include "ITSBase/GeometryTGeo.h" #include "DataFormatsITSMFT/Digit.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITSMFTBase/SegmentationAlpide.h" #include "ITSMFTSimulation/Hit.h" #include "MathUtils/Utils.h" @@ -51,7 +51,7 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil using o2::itsmft::Hit; using o2::itsmft::SegmentationAlpide; - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; TFile* f = TFile::Open("CheckDigits.root", "recreate"); TNtuple* nt = new TNtuple("ntd", "digit ntuple", "id:x:y:z:rowD:colD:rowH:colH:xlH:zlH:xlcH:zlcH:dx:dz"); @@ -166,8 +166,8 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil if (isIB) { // ITS3 IB float xFlat{0.f}, yFlat{0.f}; - mSuperSegmentations[layer].detectorToLocal(ix, iz, xFlat, z); - mSuperSegmentations[layer].flatToCurved(xFlat, 0., x, y); + mMosaixSegmentations[layer].detectorToLocal(ix, iz, xFlat, z); + mMosaixSegmentations[layer].flatToCurved(xFlat, 0., x, y); } else { // ITS2 OB SegmentationAlpide::detectorToLocal(ix, iz, x, z); @@ -203,12 +203,12 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil if (isIB) { float xFlat{0.}, yFlat{0.}; - mSuperSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); + mMosaixSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); xyzLocM.SetCoordinates(xFlat, yFlat, xyzLocM.Z()); - mSuperSegmentations[layer].curvedToFlat(locD.X(), locD.Y(), xFlat, yFlat); + mMosaixSegmentations[layer].curvedToFlat(locD.X(), locD.Y(), xFlat, yFlat); locD.SetCoordinates(xFlat, yFlat, locD.Z()); - if (auto v1 = !mSuperSegmentations[layer].localToDetector(xyzLocM.X(), xyzLocM.Z(), row, col), - v2 = !mSuperSegmentations[layer].detectorToLocal(row, col, xlc, zlc); + if (auto v1 = !mMosaixSegmentations[layer].localToDetector(xyzLocM.X(), xyzLocM.Z(), row, col), + v2 = !mMosaixSegmentations[layer].detectorToLocal(row, col, xlc, zlc); v1 || v2) { continue; } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckHits.C b/Detectors/Upgrades/ITS3/macros/test/CheckHits.C index 7833b7c205f4a..00ac0a992ba39 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckHits.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckHits.C @@ -31,7 +31,6 @@ #define ENABLE_UPGRADES #include "CommonConstants/MathConstants.h" -#include "ITS3Base/SegmentationSuperAlpide.h" #include "ITS3Base/SpecsV2.h" #include "ITSMFTSimulation/Hit.h" #include "SimulationDataFormat/MCTrack.h" @@ -39,7 +38,6 @@ namespace it3c = o2::its3::constants; namespace it3d = it3c::detID; -using SSAlpide = o2::its3::SegmentationSuperAlpide; using o2::itsmft::Hit; constexpr double interaction_rate = 50e3; // Hz diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C similarity index 91% rename from Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C rename to Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C index a0ccee366841d..c584bc0ad4547 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegment.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C @@ -9,9 +9,6 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file CheckTracksITS3.C -/// \brief Simple macro to check ITS3 tracks - #if !defined(__CLING__) || defined(__ROOTCLING__) #include "Rtypes.h" @@ -41,22 +38,22 @@ #include "MathUtils/Cartesian.h" #include "ITS3Base/SpecsV2.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITSBase/GeometryTGeo.h" #endif using gITS = o2::its::GeometryTGeo; -void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, - bool isTestFlatToCurved = false, - bool isTestLocalToGlobal = false) +void CheckMosaixSegment(bool isTestDetectorToLocal = false, + bool isTestFlatToCurved = false, + bool isTestLocalToGlobal = false) { using namespace o2::its3; - static constexpr unsigned int mNCols{SegmentationSuperAlpide::mNCols}; - static constexpr unsigned int mNRows{SegmentationSuperAlpide::mNRows}; + static constexpr unsigned int mNCols{SegmentationMosaix::mNCols}; + static constexpr unsigned int mNRows{SegmentationMosaix::mNRows}; static constexpr unsigned int nPixels{mNCols * mNRows}; - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; if (isTestDetectorToLocal || isTestFlatToCurved) { namespace cp = constants::pixelarray; @@ -75,7 +72,7 @@ void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, TGraph* g_col_zLocal_translate = new TGraph(); g_col_zLocal_translate->SetMarkerStyle(20); - SegmentationSuperAlpide seg(0); + SegmentationMosaix seg(0); int nPoint = 0; for (UInt_t i = 0; i < mNRows; ++i) { for (UInt_t j = 0; j < mNCols; ++j) { @@ -164,11 +161,11 @@ void CheckSuperAlpideSegment(bool isTestDetectorToLocal = false, float xLocal_translate = 0; float yLocal_translate = 0; - mSuperSegmentations[iLayer].detectorToLocal(row, col, xLocal, zLocal); - mSuperSegmentations[iLayer].flatToCurved(xLocal, 0., xCurved, yCurved); + mMosaixSegmentations[iLayer].detectorToLocal(row, col, xLocal, zLocal); + mMosaixSegmentations[iLayer].flatToCurved(xLocal, 0., xCurved, yCurved); double posLocal[3] = {xCurved, yCurved, zLocal}; double posGlobal[3] = {0, 0, 0}; - mSuperSegmentations[iLayer].curvedToFlat(xCurved, yCurved, xLocal_translate, yLocal_translate); + mMosaixSegmentations[iLayer].curvedToFlat(xCurved, yCurved, xLocal_translate, yLocal_translate); matrix->LocalToMaster(posLocal, posGlobal); h_xCurved_yCurved->Fill(xLocal, 0); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C similarity index 88% rename from Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C rename to Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C index 0fd1d0225c78d..c325fedd82237 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckSuperAlpideSegmentTrans.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file CheckSuperAlpideSegmentTrans.C +/// \file CheckMosaixSegmentTrans.C /// \brief Simple macro to check ITS3 Alpide Trans #if !defined(__CLING__) || defined(__ROOTCLING__) @@ -26,7 +26,7 @@ #include "TStyle.h" #include "TTree.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITS3Base/SpecsV2.h" #endif @@ -37,11 +37,11 @@ constexpr float PI = 3.14159274101257324e+00f; constexpr float Rad2Deg = 180.f / PI; constexpr float Deg2Rad = 1. / Rad2Deg; -constexpr auto nRows{SegmentationSuperAlpide::mNRows}; -constexpr auto nCols{SegmentationSuperAlpide::mNCols}; -constexpr auto fLength{SegmentationSuperAlpide::mLength}; -constexpr auto fWidth{SegmentationSuperAlpide::mWidth}; -std::array mSuperSegmentations{0, 1, 2}; +constexpr auto nRows{SegmentationMosaix::mNRows}; +constexpr auto nCols{SegmentationMosaix::mNCols}; +constexpr auto fLength{SegmentationMosaix::mLength}; +constexpr auto fWidth{SegmentationMosaix::mWidth}; +const std::array mMosaixSegmentations{0, 1, 2}; TH2* DrawReverseBins(TH2* h) { @@ -84,7 +84,7 @@ void DrawXAxisCol(TH1* h) newaxis->Draw(); } -void CheckSuperAlpideSegmentTrans() +void CheckMosaixSegmentTrans() { gStyle->SetOptStat(1111111); @@ -141,10 +141,10 @@ void CheckSuperAlpideSegmentTrans() g_arc_inner->AddPoint(x_inner, y_inner); g_arc_outer->AddPoint(x_outer, y_outer); // Test Segmentation - mSuperSegmentations[iLayer].curvedToFlat(x_inner, y_inner, x_inner_flat, y_inner_flat); - mSuperSegmentations[iLayer].flatToCurved(x_inner_flat, y_inner_flat, x_inner_curved, y_inner_curved); - mSuperSegmentations[iLayer].curvedToFlat(x_outer, y_outer, x_outer_flat, y_outer_flat); - mSuperSegmentations[iLayer].flatToCurved(x_outer_flat, y_outer_flat, x_outer_curved, y_outer_curved); + mMosaixSegmentations[iLayer].curvedToFlat(x_inner, y_inner, x_inner_flat, y_inner_flat); + mMosaixSegmentations[iLayer].flatToCurved(x_inner_flat, y_inner_flat, x_inner_curved, y_inner_curved); + mMosaixSegmentations[iLayer].curvedToFlat(x_outer, y_outer, x_outer_flat, y_outer_flat); + mMosaixSegmentations[iLayer].flatToCurved(x_outer_flat, y_outer_flat, x_outer_curved, y_outer_curved); g_arc_inner_flat->AddPoint(x_inner_flat, y_inner_flat); g_arc_outer_flat->AddPoint(x_outer_flat, y_outer_flat); h_f2c_res->Fill(x_inner - x_inner_curved, y_inner - y_inner_curved); @@ -202,9 +202,9 @@ void CheckSuperAlpideSegmentTrans() for (int iCol{0}; iCol < nCols; ++iCol) { float xRow{0}, zCol{0}; int iiRow{0}, iiCol{0}; - auto v1 = mSuperSegmentations[iLayer].detectorToLocal(iRow, iCol, xRow, zCol); - auto v2 = mSuperSegmentations[iLayer].localToDetector(xRow, zCol, iiRow, - iiCol); + auto v1 = mMosaixSegmentations[iLayer].detectorToLocal(iRow, iCol, xRow, zCol); + auto v2 = mMosaixSegmentations[iLayer].localToDetector(xRow, zCol, iiRow, + iiCol); // Info("L2D", // "iRow=%d, iCol=%d --d2l(%s)--> xRow=%f, zCol=%f --l2d(%s)--> " // "iiRow=%d, iiCol=%d", diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C b/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C index 4550e2c1a17e0..220b1d39ad42b 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C @@ -25,7 +25,7 @@ #include "ITSBase/GeometryTGeo.h" #include "ITS3Base/SpecsV2.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "MathUtils/Cartesian.h" #include "MathUtils/Utils.h" #include "DataFormatsITSMFT/NoiseMap.h" @@ -102,7 +102,7 @@ void CheckTileNumbering(const std::string& inputGeom = "", const std::string& de Int_t colors[NRGBs] = {kWhite, kRed, kGray}; TColor::SetPalette(NRGBs, colors, 1.0); - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; const float phiOffsetL0 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[0]); const float phiOffsetL1 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[1]); @@ -144,7 +144,7 @@ void CheckTileNumbering(const std::string& inputGeom = "", const std::string& de for (unsigned int iDet{0}; iDet <= o2::its3::constants::detID::l2IDEnd; ++iDet) { int sensorID = o2::its3::constants::detID::getSensorID(iDet); int layerID = o2::its3::constants::detID::getDetID2Layer(iDet); - mSuperSegmentations[layerID].flatToCurved(xFlat, 0., x, y); + mMosaixSegmentations[layerID].flatToCurved(xFlat, 0., x, y); o2::math_utils::Point3D locC{x, y, z}; auto gloC = gman->getMatrixL2G(iDet)(locC); float phi = o2::math_utils::to02Pi(std::atan2(gloC.Y(), gloC.X())); diff --git a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C index 486ef2bb8d84d..862b7434ea4c9 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C +++ b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C @@ -31,7 +31,7 @@ #include "DataFormatsITSMFT/ROFRecord.h" #include "DetectorsCommonDataFormats/DetID.h" #include "DetectorsCommonDataFormats/DetectorNameConf.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITS3Base/SpecsV2.h" #include "ITS3Reconstruction/TopologyDictionary.h" #include "ITSBase/GeometryTGeo.h" @@ -86,7 +86,6 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", using namespace o2::base; using o2::itsmft::Hit; - using SuperSegmentation = o2::its3::SegmentationSuperAlpide; using Segmentation = o2::itsmft::SegmentationAlpide; using o2::itsmft::CompClusterExt; using ROFRec = o2::itsmft::ROFRecord; @@ -97,7 +96,7 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", std::vector hitVecPool; std::vector mc2hitVec; - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; // Geometry o2::base::GeometryManager::loadGeometry(inputGeom); @@ -190,7 +189,7 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", std::vector data(nChips); for (int iChip{0}; iChip < nChips; ++iChip) { auto& dat = data[iChip]; - int col{o2::its3::SegmentationSuperAlpide::mNCols}, row{o2::its3::SegmentationSuperAlpide::mNRows}; + int col{o2::its3::SegmentationMosaix::mNCols}, row{o2::its3::SegmentationMosaix::mNRows}; if (!o2::its3::constants::detID::isDetITS3(iChip)) { col = o2::itsmft::SegmentationAlpide::NCols; row = o2::itsmft::SegmentationAlpide::NRows; @@ -284,9 +283,9 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", o2::math_utils::Point3D locHMiddle; if (isIB) { float xFlat{0.}, yFlat{0.}; - mSuperSegmentations[layer].curvedToFlat(locHEnd.X(), locHEnd.Y(), xFlat, yFlat); + mMosaixSegmentations[layer].curvedToFlat(locHEnd.X(), locHEnd.Y(), xFlat, yFlat); locHEnd.SetXYZ(xFlat, yFlat, locHEnd.Z()); - mSuperSegmentations[layer].curvedToFlat(locHStart.X(), locHStart.Y(), xFlat, yFlat); + mMosaixSegmentations[layer].curvedToFlat(locHStart.X(), locHStart.Y(), xFlat, yFlat); locHStart.SetXYZ(xFlat, yFlat, locHStart.Z()); } locHMiddle.SetXYZ(0.5f * (locHEnd.X() + locHStart.X()), 0.5f * (locHEnd.Y() + locHStart.Y()), 0.5f * (locHEnd.Z() + locHStart.Z())); @@ -294,10 +293,10 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", int rowHS, colHS, rowHM, colHM, rowHE, colHE, colC, rowC; bool v1, v2, v3, v4; if (isIB) { - v1 = mSuperSegmentations[layer].localToDetector(locHStart.X(), locHStart.Z(), rowHS, colHS); - v2 = mSuperSegmentations[layer].localToDetector(locHMiddle.X(), locHMiddle.Z(), rowHM, colHM); - v3 = mSuperSegmentations[layer].localToDetector(locHEnd.X(), locHEnd.Z(), rowHE, colHE); - v4 = mSuperSegmentations[layer].localToDetector(locC.X(), locC.Z(), rowC, colC); + v1 = mMosaixSegmentations[layer].localToDetector(locHStart.X(), locHStart.Z(), rowHS, colHS); + v2 = mMosaixSegmentations[layer].localToDetector(locHMiddle.X(), locHMiddle.Z(), rowHM, colHM); + v3 = mMosaixSegmentations[layer].localToDetector(locHEnd.X(), locHEnd.Z(), rowHE, colHE); + v4 = mMosaixSegmentations[layer].localToDetector(locC.X(), locC.Z(), rowC, colC); } else { v1 = o2::itsmft::SegmentationAlpide::localToDetector(locHStart.X(), locHStart.Z(), rowHS, colHS); v2 = o2::itsmft::SegmentationAlpide::localToDetector(locHMiddle.X(), locHMiddle.Z(), rowHM, colHM); diff --git a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C index ac6e1138f24e8..a56104f0106b6 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C @@ -34,7 +34,7 @@ #include "DetectorsCommonDataFormats/DetID.h" #include "ITSBase/GeometryTGeo.h" #include "ITSMFTBase/SegmentationAlpide.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsITSMFT/ClusterTopology.h" #include "ITS3Reconstruction/TopologyDictionary.h" @@ -67,7 +67,6 @@ void CreateDictionariesITS3(bool saveDeltas = false, using namespace o2::base; using namespace o2::its; - using o2::its3::SegmentationSuperAlpide; using Segmentation = o2::itsmft::SegmentationAlpide; using o2::its3::BuildTopologyDictionary; using o2::itsmft::ClusterTopology; @@ -82,7 +81,7 @@ void CreateDictionariesITS3(bool saveDeltas = false, std::vector hitVecPool; std::vector mc2hitVec; o2::its3::TopologyDictionary clusDictOld; - std::array mSuperSegmentations{0, 1, 2}; + std::array mMosaixSegmentations{0, 1, 2}; if (!clusDictFile.empty()) { clusDictOld.readFromFile(clusDictFile); LOGP(info, "Loaded external cluster dictionary with {} entries from {}", clusDictOld.getSize(), clusDictFile); @@ -275,15 +274,15 @@ void CreateDictionariesITS3(bool saveDeltas = false, int layer = gman->getLayer(chipID); if (isIB) { float xFlat{0.}, yFlat{0.}; - mSuperSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); + mMosaixSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); xyzLocM.SetCoordinates(xFlat, yFlat, xyzLocM.Z()); - mSuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlat, yFlat); + mMosaixSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlat, yFlat); locC.SetCoordinates(xFlat, yFlat, locC.Z()); } dX = xyzLocM.X() - locC.X(); dZ = xyzLocM.Z() - locC.Z(); - dX /= (isIB) ? o2::its3::SegmentationSuperAlpide::mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow; - dZ /= (isIB) ? o2::its3::SegmentationSuperAlpide::mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol; + dX /= (isIB) ? o2::its3::SegmentationMosaix::mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow; + dZ /= (isIB) ? o2::its3::SegmentationMosaix::mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol; if (saveDeltas) { nt->Fill(topology.getHash(), dX, dZ); } diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h index 2407344aa0193..8daa74b44ac07 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h @@ -16,14 +16,13 @@ #include "ITS3Reconstruction/TopologyDictionary.h" #include "ITStracking/TimeFrame.h" #include "ITStracking/IOUtils.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITS3Base/SpecsV2.h" namespace o2::its3::ioutils { -using SSAlpide = o2::its3::SegmentationSuperAlpide; -constexpr float DefClusErrorRow = o2::its3::SegmentationSuperAlpide::mPitchRow * 0.5; -constexpr float DefClusErrorCol = o2::its3::SegmentationSuperAlpide::mPitchCol * 0.5; +constexpr float DefClusErrorRow = o2::its3::SegmentationMosaix::mPitchRow * 0.5; +constexpr float DefClusErrorCol = o2::its3::SegmentationMosaix::mPitchCol * 0.5; constexpr float DefClusError2Row = DefClusErrorRow * DefClusErrorRow; constexpr float DefClusError2Col = DefClusErrorCol * DefClusErrorCol; diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h index bc5fd73d48c84..1a9b4048fd06f 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h @@ -17,7 +17,6 @@ #include "DataFormatsITSMFT/TopologyDictionary.h" #include "DataFormatsITSMFT/ClusterPattern.h" -#include "ITS3Base/SegmentationSuperAlpide.h" namespace o2::its3 { @@ -33,11 +32,11 @@ class TopologyDictionary /// constexpr for the definition of the groups of rare topologies. /// The attritbution of the group ID is stringly dependent on the following parameters: it must be a power of 2. - static constexpr int RowClassSpan = 4; ///< Row span of the classes of rare topologies - static constexpr int ColClassSpan = 4; ///< Column span of the classes of rare topologies - static constexpr int MaxNumberOfRowClasses = 1 + (itsmft::ClusterPattern::MaxRowSpan - 1) / RowClassSpan; ///< Maximum number of row classes for the groups of rare topologies - static constexpr int MaxNumberOfColClasses = 1 + (itsmft::ClusterPattern::MaxColSpan - 1) / ColClassSpan; ///< Maximum number of col classes for the groups of rare topologies - static constexpr int NumberOfRareGroups = MaxNumberOfRowClasses * MaxNumberOfColClasses; ///< Number of entries corresponding to groups of rare topologies (those whos matrix exceed the max number of bytes are empty). + static constexpr int RowClassSpan = 4; ///< Row span of the classes of rare topologies + static constexpr int ColClassSpan = 4; ///< Column span of the classes of rare topologies + static constexpr int MaxNumberOfRowClasses = 1 + ((itsmft::ClusterPattern::MaxRowSpan - 1) / RowClassSpan); ///< Maximum number of row classes for the groups of rare topologies + static constexpr int MaxNumberOfColClasses = 1 + ((itsmft::ClusterPattern::MaxColSpan - 1) / ColClassSpan); ///< Maximum number of col classes for the groups of rare topologies + static constexpr int NumberOfRareGroups = MaxNumberOfRowClasses * MaxNumberOfColClasses; ///< Number of entries corresponding to groups of rare topologies (those whos matrix exceed the max number of bytes are empty). /// Prints the dictionary friend std::ostream& operator<<(std::ostream& os, const its3::TopologyDictionary& dictionary); /// Prints the dictionary in a binary file diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx index 87ad450eecd9e..8667066f91fac 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx @@ -14,7 +14,6 @@ #include "ITS3Reconstruction/BuildTopologyDictionary.h" #include "ITS3Reconstruction/LookUp.h" #include "DataFormatsITSMFT/CompCluster.h" -#include "ITS3Base/SegmentationSuperAlpide.h" #include "TFile.h" diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx index 90f5245bcef58..4e91230d5b084 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx @@ -12,15 +12,15 @@ /// \file Clusterer.cxx /// \brief Implementation of the ITS cluster finder -#include "ITS3Reconstruction/Clusterer.h" +#include -#include #include "Framework/Logger.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Reconstruction/Clusterer.h" +#include "ITS3Base/SegmentationMosaix.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "CommonDataFormat/InteractionRecord.h" -#include +#include "TTree.h" #ifdef WITH_OPENMP #include @@ -334,7 +334,7 @@ void Clusterer::ClustererThread::initChip(const ChipPixelData* curChipData, uint size = itsmft::SegmentationAlpide::NRows + 2; int chipId = curChipData->getChipID(); if (its3::constants::detID::isDetITS3(chipId)) { - size = its3::SegmentationSuperAlpide::mNRows + 2; + size = its3::SegmentationMosaix::mNRows + 2; } delete[] column1; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx index 0fecf914ac6eb..58dd56ac41f95 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx @@ -16,8 +16,6 @@ #include "DataFormatsITSMFT/ROFRecord.h" #include "ITS3Reconstruction/TopologyDictionary.h" #include "ITSBase/GeometryTGeo.h" -#include "ITSMFTBase/SegmentationAlpide.h" -#include "ITS3Base/SegmentationSuperAlpide.h" #include "ITS3Base/SpecsV2.h" #include "ITStracking/TrackingConfigParam.h" #include "Framework/Logger.h" diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx index fa521c3b21b31..3104717db19ba 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx @@ -12,7 +12,7 @@ /// \file TopologyDictionary.cxx #include "ITS3Reconstruction/TopologyDictionary.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITSMFTBase/SegmentationAlpide.h" #include "CommonUtils/StringUtils.h" #include @@ -136,7 +136,7 @@ TH1F* TopologyDictionary::getTopologyDistribution(const std::string_view hname) template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl) const { - static std::array mSuperSegmentations{0, 1, 2}; + static std::array mIBSegmentations{0, 1, 2}; math_utils::Point3D locCl; if (!its3::constants::detID::isDetITS3(cl.getSensorID())) { o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); @@ -144,11 +144,11 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * itsmft::SegmentationAlpide::PitchCol); } else { auto layer = its3::constants::detID::getDetID2Layer(cl.getSensorID()); - mSuperSegmentations[layer].detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); - locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * its3::SegmentationSuperAlpide::mPitchRow); - locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * its3::SegmentationSuperAlpide::mPitchCol); + mIBSegmentations[layer].detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); + locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * its3::SegmentationMosaix::mPitchRow); + locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * its3::SegmentationMosaix::mPitchCol); float xCurved{0.f}, yCurved{0.f}; - mSuperSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); + mIBSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); locCl.SetXYZ(xCurved, yCurved, locCl.Z()); } return locCl; @@ -157,7 +157,7 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C template math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::CompClusterExt& cl, const itsmft::ClusterPattern& patt, bool isGroup) { - static std::array mSuperSegmentations{0, 1, 2}; + static std::array mIBSegmentations{0, 1, 2}; auto refRow = cl.getRow(); auto refCol = cl.getCol(); float xCOG = 0, zCOG = 0; @@ -171,9 +171,9 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C o2::itsmft::SegmentationAlpide::detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); } else { auto layer = its3::constants::detID::getDetID2Layer(cl.getSensorID()); - mSuperSegmentations[layer].detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); + mIBSegmentations[layer].detectorToLocalUnchecked(refRow + xCOG, refCol + zCOG, locCl); float xCurved{0.f}, yCurved{0.f}; - mSuperSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); + mIBSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); locCl.SetXYZ(xCurved, yCurved, locCl.Z()); } return locCl; diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index 01ca21961edb8..cbf52527d3085 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -25,7 +25,7 @@ #include "ITSMFTSimulation/AlpideSimResponse.h" #include "ITSMFTSimulation/Hit.h" #include "ITSBase/GeometryTGeo.h" -#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" #include "ITS3Simulation/DigiParams.h" #include "DataFormatsITSMFT/Digit.h" #include "DataFormatsITSMFT/ROFRecord.h" @@ -106,7 +106,7 @@ class Digitizer : public TObject uint32_t mEventROFrameMin = 0xffffffff; ///< lowest RO frame for processed events (w/o automatic noise ROFs) uint32_t mEventROFrameMax = 0; ///< highest RO frame forfor processed events (w/o automatic noise ROFs) - const std::array mSuperSegmentations{0, 1, 2}; + const std::array mIBSegmentations{0, 1, 2}; o2::itsmft::AlpideSimResponse* mSimRespIB = nullptr; // simulated response for IB o2::itsmft::AlpideSimResponse* mSimRespOB = nullptr; // simulated response for OB diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index b1e69d30bf159..4a589896a7a4b 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -66,7 +66,7 @@ void Digitizer::init() if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") { constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc(responseFile, responseFile, "Alpide"); - mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationSuperAlpide::mSensorLayerThickness / 2.f; + mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::mSensorLayerThickness / 2.f; mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; } else if (func == "APTS") { constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/"; @@ -170,7 +170,7 @@ void Digitizer::fillOutputContainer(uint32_t frameLast) for (size_t iChip{0}; iChip < mChips.size(); ++iChip) { auto& chip = mChips[iChip]; if (constants::detID::isDetITS3(iChip)) { // Check if this is a chip of ITS3 - chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SegmentationSuperAlpide::mNRows, SegmentationSuperAlpide::mNCols); + chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SegmentationMosaix::mNRows, SegmentationMosaix::mNCols); } else { chip.addNoise(mROFrameMin, mROFrameMin, &mParams); } @@ -265,8 +265,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID if (innerBarrel) { // transform the point on the curved surface to a flat one float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f}; - mSuperSegmentations[layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS); - mSuperSegmentations[layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE); + mIBSegmentations[layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS); + mIBSegmentations[layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE); // update the local coordinates with the flattened ones xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z()); xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z()); @@ -282,14 +282,14 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0; if (innerBarrel) { // get entrance pixel row and col - while (!mSuperSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ? + while (!mIBSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ? if (++nSkip >= nSteps) { return; // did not enter to sensitive matrix } xyzLocS += step; } // get exit pixel row and col - while (!mSuperSegmentations[layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ? + while (!mIBSegmentations[layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ? if (++nSkip >= nSteps) { return; // did not enter to sensitive matrix } @@ -325,8 +325,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID rowS = 0; } - const int maxNrows{innerBarrel ? SegmentationSuperAlpide::mNRows : Segmentation::NRows}; - const int maxNcols{innerBarrel ? SegmentationSuperAlpide::mNCols : Segmentation::NCols}; + const int maxNrows{innerBarrel ? SegmentationMosaix::mNRows : Segmentation::NRows}; + const int maxNcols{innerBarrel ? SegmentationMosaix::mNCols : Segmentation::NCols}; if (rowE >= maxNrows) { rowE = maxNrows - 1; } @@ -360,13 +360,13 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID for (int iStep = nSteps; iStep--;) { // Get the pixel ID if (innerBarrel) { - mSuperSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); + mIBSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); } else { Segmentation::localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); } if (row != rowPrev || col != colPrev) { // update pixel and coordinates of its center if (innerBarrel) { - if (!mSuperSegmentations[layer].detectorToLocal(row, col, cRowPix, cColPix)) { + if (!mIBSegmentations[layer].detectorToLocal(row, col, cRowPix, cColPix)) { continue; } } else if (!Segmentation::detectorToLocal(row, col, cRowPix, cColPix)) { @@ -377,8 +377,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID } bool flipCol = false, flipRow = false; // note that response needs coordinates along column row (locX) (locZ) then depth (locY) - float rowMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchRow : Segmentation::PitchRow)}; - float colMax{0.5f * (innerBarrel ? SegmentationSuperAlpide::mPitchCol : Segmentation::PitchCol)}; + float rowMax{0.5f * (innerBarrel ? SegmentationMosaix::mPitchRow : Segmentation::PitchRow)}; + float colMax{0.5f * (innerBarrel ? SegmentationMosaix::mPitchCol : Segmentation::PitchCol)}; auto rspmat = ((innerBarrel) ? mSimRespIB : mSimRespOB)->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); xyzLocS += step; From d2e060b3c2df49bc1ddafa1eaa32d655c8da60f3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Sat, 1 Feb 2025 19:38:46 +0100 Subject: [PATCH 20/34] ITS3: digitizer pre-set response names Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/ITS3Params.h | 6 ++---- .../ITS3/simulation/src/Digitizer.cxx | 20 +++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h index af00e88ef0d92..0bd548cef953d 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h @@ -25,10 +25,8 @@ struct ITS3Params : public o2::conf::ConfigurableParamHelper { bool misalignmentHitsUseProp{false}; // Use propagtor for mis-alignment std::string globalGeoMisAlignerMacro{"${O2_ROOT}/share/macro/MisAlignGeoITS3.C"}; // Path to macro for global geometry mis-alignment // Chip studies - bool useDeadChannelMap{false}; // Query for a dead channel map to study disabling individual tiles - std::string chipResponseFunction{"APTS"}; // Chip response function one of "Alpide", "APTS" or "Mosaix" (not yet available) - std::string responseFunctionIB{"response0"}; // Chip response function name for IB - std::string responseFunctionOB{"response1"}; // Chip response function name for 0B + bool useDeadChannelMap{false}; // Query for a dead channel map to study disabling individual tiles + std::string chipResponseFunction{"APTS"}; // Chip response function one of "Alpide", "APTS" or "Mosaix" (not yet available) O2ParamDef(ITS3Params, "ITS3Params"); }; diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 4a589896a7a4b..656b748215672 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -45,33 +45,31 @@ void Digitizer::init() } if (!mParams.hasResponseFunctions()) { - auto loadSetResponseFunc = [&](const char* fileIB, const char* fileOB, const char* name) { - const auto& nameIB = ITS3Params::Instance().responseFunctionIB; - const auto& nameOB = ITS3Params::Instance().responseFunctionOB; - LOGP(info, "Loading response function for {}: IB={}:{} / OB={}:{}", name, nameIB, fileIB, nameOB, fileOB); - auto fIB = TFile::Open(fileIB); + auto loadSetResponseFunc = [&](const char* name, const char* fileIB, const char* nameIB, const char* fileOB, const char* nameOB) { + LOGP(info, "Loading response function for {}: IB={}:{} ; OB={}:{}", name, nameIB, fileIB, nameOB, fileOB); + auto fIB = TFile::Open(fileIB, "READ"); if (fIB->IsZombie() || !fIB->IsOpen()) { LOGP(fatal, "Cannot open file {}", fileIB); } - auto fOB = TFile::Open(fileIB); + auto fOB = TFile::Open(fileIB, "READ"); if (fOB->IsZombie() || !fOB->IsOpen()) { LOGP(fatal, "Cannot open file {}", fileOB); } - mParams.setIBSimResponse(mSimRespIB = fIB->Get(nameIB.c_str())); - mParams.setOBSimResponse(mSimRespOB = fOB->Get(nameOB.c_str())); + mParams.setIBSimResponse(mSimRespIB = fIB->Get(nameIB)); + mParams.setOBSimResponse(mSimRespOB = fOB->Get(nameOB)); fIB->Close(); fOB->Close(); }; if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") { constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; - loadSetResponseFunc(responseFile, responseFile, "Alpide"); + loadSetResponseFunc("Alpide", responseFile, "response0", responseFile, "response1"); mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::mSensorLayerThickness / 2.f; mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; } else if (func == "APTS") { - constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/"; + constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; - loadSetResponseFunc(responseFileIB, responseFileOB, "APTS"); + loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1"); mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; } else { From e97cf5dc49e56dd2c8384ed627f1fc0c077282d3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Sat, 1 Feb 2025 20:31:05 +0100 Subject: [PATCH 21/34] ITS3: remove unneeded variables + make segmentation fully float Signed-off-by: Felix Schlepper --- .../include/ITS3Base/SegmentationMosaix.h | 33 +++++++++---------- .../ITS3/base/include/ITS3Base/SpecsV2.h | 7 ++-- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index ae21565f69a6b..2a8f09238d24f 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -16,11 +16,10 @@ #ifndef ALICEO2_ITS3_SEGMENTATIONMOSAIX_H_ #define ALICEO2_ITS3_SEGMENTATIONMOSAIX_H_ +#include + #include "MathUtils/Cartesian.h" #include "ITS3Base/SpecsV2.h" -#include "Rtypes.h" - -#include namespace o2::its3 { @@ -68,9 +67,6 @@ class SegmentationMosaix static constexpr float mPitchCol{constants::pixelarray::length / static_cast(mNCols)}; static constexpr float mPitchRow{constants::pixelarray::width / static_cast(mNRows)}; static constexpr float mSensorLayerThickness{constants::thickness}; - static constexpr float mSensorLayerThicknessEff{constants::effThickness}; - static constexpr float mSensorLayerThicknessCorr{constants::corrThickness}; - static constexpr std::array mRadii{constants::radiiF}; /// Transformation from the curved surface to a flat surface /// \param xCurved Detector local curved coordinate x in cm with respect to @@ -86,8 +82,8 @@ class SegmentationMosaix // MUST align the flat surface with the curved surface with the original pixel array is on float dist = std::hypot(xCurved, yCurved); float phi = std::atan2(yCurved, xCurved); - xFlat = (mRadii[mLayer] * phi) - constants::pixelarray::width / 2.; - yFlat = dist - mRadii[mLayer]; + xFlat = (getRadius() * phi) - mWidth / 2.f; + yFlat = dist - getRadius(); } /// Transformation from the flat surface to a curved surface @@ -103,9 +99,9 @@ class SegmentationMosaix void flatToCurved(float xFlat, float yFlat, float& xCurved, float& yCurved) const noexcept { // MUST align the flat surface with the curved surface with the original pixel array is on - float dist = yFlat + mRadii[mLayer]; - xCurved = dist * std::cos((xFlat + constants::pixelarray::width / 2.) / mRadii[mLayer]); - yCurved = dist * std::sin((xFlat + constants::pixelarray::width / 2.) / mRadii[mLayer]); + float dist = yFlat + getRadius(); + xCurved = dist * std::cos((xFlat + mWidth / 2.f) / getRadius()); + yCurved = dist * std::sin((xFlat + mWidth / 2.f) / getRadius()); } /// Transformation from Geant detector centered local coordinates (cm) to @@ -132,9 +128,8 @@ class SegmentationMosaix // Same as localToDetector w.o. checks. void localToDetectorUnchecked(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept { - namespace cp = constants::pixelarray; - iRow = std::floor((cp::width / 2. - xRow) / mPitchRow); - iCol = std::floor((zCol + cp::length / 2.) / mPitchCol); + iRow = std::floor((mWidth / 2. - xRow) / mPitchRow); + iCol = std::floor((zCol + mLength / 2.) / mPitchCol); } /// Transformation from Detector cell coordinates to Geant detector centered @@ -160,9 +155,8 @@ class SegmentationMosaix // We position ourself in the middle of the pixel. void detectorToLocalUnchecked(int const iRow, int const iCol, float& xRow, float& zCol) const noexcept { - namespace cp = constants::pixelarray; - xRow = -(iRow + 0.5) * mPitchRow + cp::width / 2.; - zCol = (iCol + 0.5) * mPitchCol - cp::length / 2.; + xRow = -(static_cast(iRow) + 0.5f) * mPitchRow + mWidth / 2.f; + zCol = (static_cast(iCol) + 0.5f) * mPitchCol - mLength / 2.f; } bool detectorToLocal(int const row, int const col, math_utils::Point3D& loc) const noexcept @@ -194,6 +188,11 @@ class SegmentationMosaix } } + float getRadius() const noexcept + { + return static_cast(constants::radii[mLayer]); + } + int mLayer{0}; ///< chip layer }; diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index c8880788edebe..5e45bcfd714af 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -121,12 +121,9 @@ constexpr std::array nSegments{3, 4, 5}; constexpr double epitaxialThickness{10 * mu}; // eptixial layer (charge collection) constexpr double psubThickness{40 * mu}; // silicon substrate constexpr double thickness{epitaxialThickness + psubThickness}; // physical thickness of chip -constexpr double effThickness{epitaxialThickness / 2.0 + psubThickness}; // effective physical thickness -constexpr double corrThickness{effThickness - thickness / 2.0}; // correction to get into the epitxial layer -constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. -constexpr std::array radiiF{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. +constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius constexpr std::array radiiInner{radii[0] - thickness / 2.0, radii[1] - thickness / 2.0, radii[2] - thickness / 2.0}; // inner radius -constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // inner radius +constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // outer radius namespace detID { constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU From 799f309a84e2b83f8f2e5fb8e40a35ffa85240e2 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Sat, 1 Feb 2025 22:34:15 +0100 Subject: [PATCH 22/34] ITS3: scale pixel-resp + fix OB resp func Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/SpecsV2.h | 21 ++++++++++++++++ .../include/ITS3Simulation/Digitizer.h | 2 ++ .../ITS3/simulation/src/Digitizer.cxx | 24 ++++++++++++++----- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index 5e45bcfd714af..90859becdd30b 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -35,6 +35,27 @@ constexpr int nRows{442}; constexpr int nPixels{nRows * nCols}; constexpr EColor color{kGreen}; constexpr double area{width * length}; +namespace pixels +{ +namespace apts +{ +constexpr double pitchX{15.0 * mu}; +constexpr double pitchZ{15.0 * mu}; +} // namespace apts +namespace moss +{ +namespace top +{ +constexpr double pitchX{22.5 * mu}; +constexpr double pitchZ{22.5 * mu}; +} // namespace top +namespace bot +{ +constexpr double pitchX{18.0 * mu}; +constexpr double pitchZ{18.0 * mu}; +} // namespace bot +} // namespace moss +} // namespace pixels } // namespace pixelarray namespace tile { diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index cbf52527d3085..508261f03ce38 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -111,6 +111,8 @@ class Digitizer : public TObject o2::itsmft::AlpideSimResponse* mSimRespIB = nullptr; // simulated response for IB o2::itsmft::AlpideSimResponse* mSimRespOB = nullptr; // simulated response for OB float mSimRespIBShift{0.}; // adjusting the Y-shift in the IB response function to match sensor local coord. + float mSimRespIBScaleX{1.}; // scale x-local coordinate to response function x-coordinate + float mSimRespIBScaleZ{1.}; // scale z-local coordinate to response function z-coordinate float mSimRespOBShift{0.}; // adjusting the Y-shift in the OB response function to match sensor local coord. const o2::its::GeometryTGeo* mGeometry = nullptr; ///< ITS3 geometry diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 656b748215672..82e88691b6f8d 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -48,11 +48,11 @@ void Digitizer::init() auto loadSetResponseFunc = [&](const char* name, const char* fileIB, const char* nameIB, const char* fileOB, const char* nameOB) { LOGP(info, "Loading response function for {}: IB={}:{} ; OB={}:{}", name, nameIB, fileIB, nameOB, fileOB); auto fIB = TFile::Open(fileIB, "READ"); - if (fIB->IsZombie() || !fIB->IsOpen()) { + if (!fIB || fIB->IsZombie() || !fIB->IsOpen()) { LOGP(fatal, "Cannot open file {}", fileIB); } - auto fOB = TFile::Open(fileIB, "READ"); - if (fOB->IsZombie() || !fOB->IsOpen()) { + auto fOB = TFile::Open(fileOB, "READ"); + if (!fOB || fOB->IsZombie() || !fOB->IsOpen()) { LOGP(fatal, "Cannot open file {}", fileOB); } mParams.setIBSimResponse(mSimRespIB = fIB->Get(nameIB)); @@ -72,11 +72,15 @@ void Digitizer::init() loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1"); mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; + mSimRespIBScaleX = 0.5 * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::mPitchRow; + mSimRespIBScaleZ = 0.5 * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::mPitchCol; } else { LOGP(fatal, "ResponseFunction '{}' not implemented!", func); } } mParams.print(); + LOGP(info, "IBShift = {} ; OBShift = {}", mSimRespIBShift, mSimRespOBShift); + LOGP(info, "IB-Scale: X={} ; Z={}", mSimRespIBScaleX, mSimRespIBScaleZ); mIRFirstSampledTF = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); } @@ -375,9 +379,17 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID } bool flipCol = false, flipRow = false; // note that response needs coordinates along column row (locX) (locZ) then depth (locY) - float rowMax{0.5f * (innerBarrel ? SegmentationMosaix::mPitchRow : Segmentation::PitchRow)}; - float colMax{0.5f * (innerBarrel ? SegmentationMosaix::mPitchCol : Segmentation::PitchCol)}; - auto rspmat = ((innerBarrel) ? mSimRespIB : mSimRespOB)->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); + float rowMax{}, colMax{}; + const AlpideRespSimMat* rspmat{nullptr}; + if (innerBarrel) { + rowMax = 0.5 * SegmentationMosaix::mPitchRow; + colMax = 0.5 * SegmentationMosaix::mPitchCol; + rspmat = mSimRespIB->getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); + } else { + rowMax = 0.5 * Segmentation::PitchRow; + colMax = 0.5 * Segmentation::PitchCol; + rspmat = mSimRespOB->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); + } xyzLocS += step; if (rspmat == nullptr) { From 1e9006e72a4cdff696f130ab2380b09afdc5324c Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 3 Feb 2025 11:32:36 +0100 Subject: [PATCH 23/34] ITS3: digitizer offset for Alpide resp. Signed-off-by: Felix Schlepper --- .../ITS3/simulation/src/Digitizer.cxx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 82e88691b6f8d..bf5f11500dac6 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -26,7 +26,7 @@ #include using o2::itsmft::Hit; -using Segmentation = o2::itsmft::SegmentationAlpide; +using SegmentationAlpide = o2::itsmft::SegmentationAlpide; using o2::itsmft::AlpideRespSimMat; using o2::itsmft::PreDigit; @@ -64,14 +64,14 @@ void Digitizer::init() if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") { constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc("Alpide", responseFile, "response0", responseFile, "response1"); - mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::mSensorLayerThickness / 2.f; - mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; + mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::mSensorLayerThickness / 2.f + 10.e-4f; // TODO why this offset? + mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; } else if (func == "APTS") { constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1"); mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; - mSimRespOBShift = mSimRespOB->getDepthMax() - Segmentation::SensorLayerThickness / 2.f; + mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; mSimRespIBScaleX = 0.5 * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::mPitchRow; mSimRespIBScaleZ = 0.5 * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::mPitchCol; } else { @@ -299,14 +299,14 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID } } else { // get entrance pixel row and col - while (!Segmentation::localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ? + while (!SegmentationAlpide::localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ? if (++nSkip >= nSteps) { return; // did not enter to sensitive matrix } xyzLocS += step; } // get exit pixel row and col - while (!Segmentation::localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ? + while (!SegmentationAlpide::localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ? if (++nSkip >= nSteps) { return; // did not enter to sensitive matrix } @@ -327,8 +327,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID rowS = 0; } - const int maxNrows{innerBarrel ? SegmentationMosaix::mNRows : Segmentation::NRows}; - const int maxNcols{innerBarrel ? SegmentationMosaix::mNCols : Segmentation::NCols}; + const int maxNrows{innerBarrel ? SegmentationMosaix::mNRows : SegmentationAlpide::NRows}; + const int maxNcols{innerBarrel ? SegmentationMosaix::mNCols : SegmentationAlpide::NCols}; if (rowE >= maxNrows) { rowE = maxNrows - 1; } @@ -364,14 +364,14 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID if (innerBarrel) { mIBSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); } else { - Segmentation::localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); + SegmentationAlpide::localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col); } if (row != rowPrev || col != colPrev) { // update pixel and coordinates of its center if (innerBarrel) { if (!mIBSegmentations[layer].detectorToLocal(row, col, cRowPix, cColPix)) { continue; } - } else if (!Segmentation::detectorToLocal(row, col, cRowPix, cColPix)) { + } else if (!SegmentationAlpide::detectorToLocal(row, col, cRowPix, cColPix)) { continue; // should not happen } rowPrev = row; @@ -386,8 +386,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID colMax = 0.5 * SegmentationMosaix::mPitchCol; rspmat = mSimRespIB->getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); } else { - rowMax = 0.5 * Segmentation::PitchRow; - colMax = 0.5 * Segmentation::PitchCol; + rowMax = 0.5 * SegmentationAlpide::PitchRow; + colMax = 0.5 * SegmentationAlpide::PitchCol; rspmat = mSimRespOB->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); } From 73853a890989b819c37ba3c05cfffc4847d70536 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 3 Feb 2025 11:47:01 +0100 Subject: [PATCH 24/34] ITS3: Segmenatation remove member prefix from vars Signed-off-by: Felix Schlepper --- .../include/ITS3Base/SegmentationMosaix.h | 32 +++++++++---------- .../ITS3/macros/test/CheckClustersITS3.C | 4 +-- .../ITS3/macros/test/CheckDigitsDensity.C | 2 +- .../ITS3/macros/test/CheckMosaixSegment.C | 4 +-- .../macros/test/CheckMosaixSegmentTrans.C | 8 ++--- .../macros/test/CompareClustersAndDigits.C | 2 +- .../ITS3/macros/test/CreateDictionariesITS3.C | 4 +-- .../include/ITS3Reconstruction/IOUtils.h | 4 +-- .../ITS3/reconstruction/src/Clusterer.cxx | 2 +- .../reconstruction/src/TopologyDictionary.cxx | 4 +-- .../ITS3/simulation/src/Digitizer.cxx | 25 +++++++-------- 11 files changed, 44 insertions(+), 47 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index 2a8f09238d24f..03ce1d3f7ab71 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -59,14 +59,14 @@ class SegmentationMosaix SegmentationMosaix& operator=(SegmentationMosaix&&) = delete; constexpr SegmentationMosaix(int layer) : mLayer{layer} {} - static constexpr int mNCols{constants::pixelarray::nCols}; - static constexpr int mNRows{constants::pixelarray::nRows}; - static constexpr int nPixels{mNCols * mNRows}; - static constexpr float mLength{constants::pixelarray::length}; - static constexpr float mWidth{constants::pixelarray::width}; - static constexpr float mPitchCol{constants::pixelarray::length / static_cast(mNCols)}; - static constexpr float mPitchRow{constants::pixelarray::width / static_cast(mNRows)}; - static constexpr float mSensorLayerThickness{constants::thickness}; + static constexpr int NCols{constants::pixelarray::nCols}; + static constexpr int NRows{constants::pixelarray::nRows}; + static constexpr int NPixels{NCols * NRows}; + static constexpr float Length{constants::pixelarray::length}; + static constexpr float Width{constants::pixelarray::width}; + static constexpr float PitchCol{constants::pixelarray::length / static_cast(NCols)}; + static constexpr float PitchRow{constants::pixelarray::width / static_cast(NRows)}; + static constexpr float SensorLayerThickness{constants::thickness}; /// Transformation from the curved surface to a flat surface /// \param xCurved Detector local curved coordinate x in cm with respect to @@ -82,7 +82,7 @@ class SegmentationMosaix // MUST align the flat surface with the curved surface with the original pixel array is on float dist = std::hypot(xCurved, yCurved); float phi = std::atan2(yCurved, xCurved); - xFlat = (getRadius() * phi) - mWidth / 2.f; + xFlat = (getRadius() * phi) - Width / 2.f; yFlat = dist - getRadius(); } @@ -100,8 +100,8 @@ class SegmentationMosaix { // MUST align the flat surface with the curved surface with the original pixel array is on float dist = yFlat + getRadius(); - xCurved = dist * std::cos((xFlat + mWidth / 2.f) / getRadius()); - yCurved = dist * std::sin((xFlat + mWidth / 2.f) / getRadius()); + xCurved = dist * std::cos((xFlat + Width / 2.f) / getRadius()); + yCurved = dist * std::sin((xFlat + Width / 2.f) / getRadius()); } /// Transformation from Geant detector centered local coordinates (cm) to @@ -128,8 +128,8 @@ class SegmentationMosaix // Same as localToDetector w.o. checks. void localToDetectorUnchecked(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept { - iRow = std::floor((mWidth / 2. - xRow) / mPitchRow); - iCol = std::floor((zCol + mLength / 2.) / mPitchCol); + iRow = std::floor((Width / 2. - xRow) / PitchRow); + iCol = std::floor((zCol + Length / 2.) / PitchCol); } /// Transformation from Detector cell coordinates to Geant detector centered @@ -155,8 +155,8 @@ class SegmentationMosaix // We position ourself in the middle of the pixel. void detectorToLocalUnchecked(int const iRow, int const iCol, float& xRow, float& zCol) const noexcept { - xRow = -(static_cast(iRow) + 0.5f) * mPitchRow + mWidth / 2.f; - zCol = (static_cast(iCol) + 0.5f) * mPitchCol - mLength / 2.f; + xRow = -(static_cast(iRow) + 0.5f) * PitchRow + Width / 2.f; + zCol = (static_cast(iCol) + 0.5f) * PitchCol - Length / 2.f; } bool detectorToLocal(int const row, int const col, math_utils::Point3D& loc) const noexcept @@ -184,7 +184,7 @@ class SegmentationMosaix namespace cp = constants::pixelarray; return !static_cast(row <= -cp::width / 2. || cp::width / 2. <= row || col <= -cp::length / 2. || cp::length / 2. <= col); } else { // compares in rows/cols - return !static_cast(row < 0 || row >= static_cast(mNRows) || col < 0 || col >= static_cast(mNCols)); + return !static_cast(row < 0 || row >= static_cast(NRows) || col < 0 || col >= static_cast(NCols)); } } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index c2fc25ef0086f..a0f7dffc6ed1b 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -185,8 +185,8 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", locC = dict.getClusterCoordinates(cluster); errX = dict.getErrX(pattID); errZ = dict.getErrZ(pattID); - errX *= (isIB) ? MosaixSegmentation::mPitchRow : Segmentation::PitchRow; - errZ *= (isIB) ? MosaixSegmentation::mPitchCol : Segmentation::PitchCol; + errX *= (isIB) ? MosaixSegmentation::PitchRow : Segmentation::PitchRow; + errZ *= (isIB) ? MosaixSegmentation::PitchCol : Segmentation::PitchCol; npix = dict.getNpixels(pattID); ++cPattValid; } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C index 19a0357e65399..23d48f9ad57b5 100755 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C @@ -115,7 +115,7 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig std::unique_ptr oFile(TFile::Open("checkDigitsDensity.root", "RECREATE")); checkFile(oFile); for (const auto& h : hists) { - h->Scale(1. / (Mosaix::mPitchCol * Mosaix::mPitchRow * nEvents)); + h->Scale(1. / (Mosaix::PitchCol * Mosaix::PitchRow * nEvents)); h->ProjectionX()->Write(); h->Write(); } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C index c584bc0ad4547..29ee833bd4881 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C @@ -50,8 +50,8 @@ void CheckMosaixSegment(bool isTestDetectorToLocal = false, bool isTestLocalToGlobal = false) { using namespace o2::its3; - static constexpr unsigned int mNCols{SegmentationMosaix::mNCols}; - static constexpr unsigned int mNRows{SegmentationMosaix::mNRows}; + static constexpr unsigned int mNCols{SegmentationMosaix::NCols}; + static constexpr unsigned int mNRows{SegmentationMosaix::NRows}; static constexpr unsigned int nPixels{mNCols * mNRows}; std::array mMosaixSegmentations{0, 1, 2}; diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C index c325fedd82237..5ee3c60758302 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C @@ -37,10 +37,10 @@ constexpr float PI = 3.14159274101257324e+00f; constexpr float Rad2Deg = 180.f / PI; constexpr float Deg2Rad = 1. / Rad2Deg; -constexpr auto nRows{SegmentationMosaix::mNRows}; -constexpr auto nCols{SegmentationMosaix::mNCols}; -constexpr auto fLength{SegmentationMosaix::mLength}; -constexpr auto fWidth{SegmentationMosaix::mWidth}; +constexpr auto nRows{SegmentationMosaix::NRows}; +constexpr auto nCols{SegmentationMosaix::NCols}; +constexpr auto fLength{SegmentationMosaix::Length}; +constexpr auto fWidth{SegmentationMosaix::Width}; const std::array mMosaixSegmentations{0, 1, 2}; TH2* DrawReverseBins(TH2* h) diff --git a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C index 862b7434ea4c9..7770ede749f0c 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C +++ b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C @@ -189,7 +189,7 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", std::vector data(nChips); for (int iChip{0}; iChip < nChips; ++iChip) { auto& dat = data[iChip]; - int col{o2::its3::SegmentationMosaix::mNCols}, row{o2::its3::SegmentationMosaix::mNRows}; + int col{o2::its3::SegmentationMosaix::NCols}, row{o2::its3::SegmentationMosaix::NRows}; if (!o2::its3::constants::detID::isDetITS3(iChip)) { col = o2::itsmft::SegmentationAlpide::NCols; row = o2::itsmft::SegmentationAlpide::NRows; diff --git a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C index a56104f0106b6..0116659940de1 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C @@ -281,8 +281,8 @@ void CreateDictionariesITS3(bool saveDeltas = false, } dX = xyzLocM.X() - locC.X(); dZ = xyzLocM.Z() - locC.Z(); - dX /= (isIB) ? o2::its3::SegmentationMosaix::mPitchRow : o2::itsmft::SegmentationAlpide::PitchRow; - dZ /= (isIB) ? o2::its3::SegmentationMosaix::mPitchCol : o2::itsmft::SegmentationAlpide::PitchCol; + dX /= (isIB) ? o2::its3::SegmentationMosaix::PitchRow : o2::itsmft::SegmentationAlpide::PitchRow; + dZ /= (isIB) ? o2::its3::SegmentationMosaix::PitchCol : o2::itsmft::SegmentationAlpide::PitchCol; if (saveDeltas) { nt->Fill(topology.getHash(), dX, dZ); } diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h index 8daa74b44ac07..4f865d11c90a9 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h @@ -21,8 +21,8 @@ namespace o2::its3::ioutils { -constexpr float DefClusErrorRow = o2::its3::SegmentationMosaix::mPitchRow * 0.5; -constexpr float DefClusErrorCol = o2::its3::SegmentationMosaix::mPitchCol * 0.5; +constexpr float DefClusErrorRow = o2::its3::SegmentationMosaix::PitchRow * 0.5; +constexpr float DefClusErrorCol = o2::its3::SegmentationMosaix::PitchCol * 0.5; constexpr float DefClusError2Row = DefClusErrorRow * DefClusErrorRow; constexpr float DefClusError2Col = DefClusErrorCol * DefClusErrorCol; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx index 4e91230d5b084..d59a4859b9990 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx @@ -334,7 +334,7 @@ void Clusterer::ClustererThread::initChip(const ChipPixelData* curChipData, uint size = itsmft::SegmentationAlpide::NRows + 2; int chipId = curChipData->getChipID(); if (its3::constants::detID::isDetITS3(chipId)) { - size = its3::SegmentationMosaix::mNRows + 2; + size = its3::SegmentationMosaix::NRows + 2; } delete[] column1; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx index 3104717db19ba..e64f63071c837 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx @@ -145,8 +145,8 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C } else { auto layer = its3::constants::detID::getDetID2Layer(cl.getSensorID()); mIBSegmentations[layer].detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); - locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * its3::SegmentationMosaix::mPitchRow); - locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * its3::SegmentationMosaix::mPitchCol); + locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * its3::SegmentationMosaix::PitchRow); + locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * its3::SegmentationMosaix::PitchCol); float xCurved{0.f}, yCurved{0.f}; mIBSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); locCl.SetXYZ(xCurved, yCurved, locCl.Z()); diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index bf5f11500dac6..74c7f31dad44a 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -22,6 +22,7 @@ #include "Framework/Logger.h" #include +#include #include #include @@ -64,7 +65,7 @@ void Digitizer::init() if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") { constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc("Alpide", responseFile, "response0", responseFile, "response1"); - mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::mSensorLayerThickness / 2.f + 10.e-4f; // TODO why this offset? + mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::SensorLayerThickness / 2.f + 10.e-4f; // TODO why this offset? mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; } else if (func == "APTS") { constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; @@ -72,8 +73,8 @@ void Digitizer::init() loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1"); mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; - mSimRespIBScaleX = 0.5 * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::mPitchRow; - mSimRespIBScaleZ = 0.5 * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::mPitchCol; + mSimRespIBScaleX = 0.5 * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::PitchRow; + mSimRespIBScaleZ = 0.5 * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::PitchCol; } else { LOGP(fatal, "ResponseFunction '{}' not implemented!", func); } @@ -172,7 +173,7 @@ void Digitizer::fillOutputContainer(uint32_t frameLast) for (size_t iChip{0}; iChip < mChips.size(); ++iChip) { auto& chip = mChips[iChip]; if (constants::detID::isDetITS3(iChip)) { // Check if this is a chip of ITS3 - chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SegmentationMosaix::mNRows, SegmentationMosaix::mNCols); + chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SegmentationMosaix::NRows, SegmentationMosaix::NCols); } else { chip.addNoise(mROFrameMin, mROFrameMin, &mParams); } @@ -323,20 +324,16 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID } rowS -= AlpideRespSimMat::NPix / 2; rowE += AlpideRespSimMat::NPix / 2; - if (rowS < 0) { - rowS = 0; - } + rowS = std::max(rowS, 0); - const int maxNrows{innerBarrel ? SegmentationMosaix::mNRows : SegmentationAlpide::NRows}; - const int maxNcols{innerBarrel ? SegmentationMosaix::mNCols : SegmentationAlpide::NCols}; + const int maxNrows{innerBarrel ? SegmentationMosaix::NRows : SegmentationAlpide::NRows}; + const int maxNcols{innerBarrel ? SegmentationMosaix::NCols : SegmentationAlpide::NCols}; if (rowE >= maxNrows) { rowE = maxNrows - 1; } colS -= AlpideRespSimMat::NPix / 2; colE += AlpideRespSimMat::NPix / 2; - if (colS < 0) { - colS = 0; - } + colS = std::max(colS, 0); if (colE >= maxNcols) { colE = maxNcols - 1; } @@ -382,8 +379,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID float rowMax{}, colMax{}; const AlpideRespSimMat* rspmat{nullptr}; if (innerBarrel) { - rowMax = 0.5 * SegmentationMosaix::mPitchRow; - colMax = 0.5 * SegmentationMosaix::mPitchCol; + rowMax = 0.5 * SegmentationMosaix::PitchRow; + colMax = 0.5 * SegmentationMosaix::PitchCol; rspmat = mSimRespIB->getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); } else { rowMax = 0.5 * SegmentationAlpide::PitchRow; From 0cd2559f34ce963e6f0d08dc74dd03711353c83d Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 4 Feb 2025 15:09:49 +0100 Subject: [PATCH 25/34] ITS3: shift back to nominal pos + proper metal stack position Signed-off-by: Felix Schlepper --- .../include/ITS3Base/SegmentationMosaix.h | 18 ++++++--- .../ITS3/base/include/ITS3Base/SpecsV2.h | 40 +++++++++++-------- .../ITS3/macros/test/CheckDigitsDensity.C | 4 +- .../ITS3/macros/test/CheckDigitsITS3.C | 4 +- .../ITS3/macros/test/CheckMosaixSegment.C | 3 +- .../macros/test/CheckMosaixSegmentTrans.C | 16 ++++---- .../ITS3/simulation/src/ITS3Layer.cxx | 6 +-- 7 files changed, 49 insertions(+), 42 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index 03ce1d3f7ab71..37bb6156685cd 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -66,7 +66,7 @@ class SegmentationMosaix static constexpr float Width{constants::pixelarray::width}; static constexpr float PitchCol{constants::pixelarray::length / static_cast(NCols)}; static constexpr float PitchRow{constants::pixelarray::width / static_cast(NRows)}; - static constexpr float SensorLayerThickness{constants::thickness}; + static constexpr float SensorLayerThickness{constants::totalThickness}; /// Transformation from the curved surface to a flat surface /// \param xCurved Detector local curved coordinate x in cm with respect to @@ -79,11 +79,14 @@ class SegmentationMosaix /// the center of the sensitive volume. void curvedToFlat(const float xCurved, const float yCurved, float& xFlat, float& yFlat) const noexcept { - // MUST align the flat surface with the curved surface with the original pixel array is on + // MUST align the flat surface with the curved surface with the original pixel array is on and account for metal + // stack float dist = std::hypot(xCurved, yCurved); float phi = std::atan2(yCurved, xCurved); xFlat = (getRadius() * phi) - Width / 2.f; - yFlat = dist - getRadius(); + // the y position is in the silicon volume however we need the chip volume (silicon+metalstack) + // this is accounted by a y shift + yFlat = dist - getRadius() + static_cast(constants::nominalYShift); } /// Transformation from the flat surface to a curved surface @@ -98,8 +101,11 @@ class SegmentationMosaix /// the center of the sensitive volume. void flatToCurved(float xFlat, float yFlat, float& xCurved, float& yCurved) const noexcept { - // MUST align the flat surface with the curved surface with the original pixel array is on - float dist = yFlat + getRadius(); + // MUST align the flat surface with the curved surface with the original pixel array is on and account for metal + // stack + // the y position is in the chip volume however we need the silicon volume + // this is accounted by a -y shift + float dist = yFlat + getRadius() - static_cast(constants::nominalYShift); xCurved = dist * std::cos((xFlat + Width / 2.f) / getRadius()); yCurved = dist * std::sin((xFlat + Width / 2.f) / getRadius()); } @@ -190,7 +196,7 @@ class SegmentationMosaix float getRadius() const noexcept { - return static_cast(constants::radii[mLayer]); + return static_cast(constants::radiiMiddle[mLayer]); } int mLayer{0}; ///< chip layer diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index 90859becdd30b..2b460d5c029d0 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -134,30 +134,36 @@ constexpr double length{segment::length}; constexpr double width{segment::width}; constexpr EColor color{kBlack}; } // namespace metalstack +namespace silicon +{ +constexpr double thickness{45 * mu}; // thickness of silicion +constexpr double radiusInner{(thickness + metalstack::thickness) / 2.}; // inner silicion radius correction +constexpr double radiusOuter{(thickness - metalstack::thickness) / 2.}; // outer silicion radius correction +} // namespace silicon constexpr unsigned int nLayers{3}; constexpr unsigned int nTotLayers{7}; constexpr unsigned int nSensorsIB{2 * nLayers}; constexpr double equatorialGap{1 * mm}; constexpr std::array nSegments{3, 4, 5}; -constexpr double epitaxialThickness{10 * mu}; // eptixial layer (charge collection) -constexpr double psubThickness{40 * mu}; // silicon substrate -constexpr double thickness{epitaxialThickness + psubThickness}; // physical thickness of chip -constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius -constexpr std::array radiiInner{radii[0] - thickness / 2.0, radii[1] - thickness / 2.0, radii[2] - thickness / 2.0}; // inner radius -constexpr std::array radiiOuter{radii[0] + thickness / 2.0, radii[1] + thickness / 2.0, radii[2] + thickness / 2.0}; // outer radius +constexpr double totalThickness{silicon::thickness + metalstack::thickness}; // total chip thickness +constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // nominal radius +constexpr std::array radiiInner{radii[0] - silicon::radiusInner, radii[1] - silicon::radiusInner, radii[2] - silicon::radiusInner}; // inner silicon radius +constexpr std::array radiiOuter{radii[0] + silicon::radiusOuter, radii[1] + silicon::radiusOuter, radii[2] + silicon::radiusOuter}; // outer silicon radius +constexpr std::array radiiMiddle{(radiiInner[0] + radiiOuter[0]) / 2., (radiiInner[1] + radiiOuter[1]) / 2., (radiiInner[2] + radiiOuter[2]) / 2.}; // middle silicon radius +constexpr double nominalYShift{-metalstack::thickness / 2.}; // shift to position in silicion volume to the chip volume (silicon+metalstack) namespace detID { -constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU -constexpr unsigned int l0IDStart{0}; //< Start DetID layer 0 -constexpr unsigned int l0IDEnd{2 * 3 * 12 * 12 - 1}; //< End First DetID layer 0; inclusive range -constexpr unsigned int l0IDTot{2 * 3 * 12 * 12}; //< Total DetID in Layer 0 -constexpr unsigned int l1IDStart{l0IDEnd + 1}; //< Start DetID layer 1 -constexpr unsigned int l1IDEnd{l1IDStart + 2 * 4 * 12 * 12 - 1}; //< End First DetID layer 1; inclusive range -constexpr unsigned int l1IDTot{2 * 4 * 12 * 12}; //< Total DetID in Layer 1 -constexpr unsigned int l2IDStart{l1IDEnd + 1}; //< Start DetID layer 2 -constexpr unsigned int l2IDEnd{l2IDStart + 2 * 5 * 12 * 12 - 1}; //< End First DetID layer 2; inclusive range -constexpr unsigned int l2IDTot{2 * 5 * 12 * 12}; //< Total DetID in Layer 2 -constexpr unsigned int nChips{l2IDEnd + 1}; //< number of Chips (PixelArrays) in IB +constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU +constexpr unsigned int l0IDStart{0}; //< Start DetID layer 0 +constexpr unsigned int l0IDEnd{(2 * 3 * 12 * 12) - 1}; //< End First DetID layer 0; inclusive range +constexpr unsigned int l0IDTot{2 * 3 * 12 * 12}; //< Total DetID in Layer 0 +constexpr unsigned int l1IDStart{l0IDEnd + 1}; //< Start DetID layer 1 +constexpr unsigned int l1IDEnd{l1IDStart + (2 * 4 * 12 * 12) - 1}; //< End First DetID layer 1; inclusive range +constexpr unsigned int l1IDTot{2 * 4 * 12 * 12}; //< Total DetID in Layer 1 +constexpr unsigned int l2IDStart{l1IDEnd + 1}; //< Start DetID layer 2 +constexpr unsigned int l2IDEnd{l2IDStart + (2 * 5 * 12 * 12) - 1}; //< End First DetID layer 2; inclusive range +constexpr unsigned int l2IDTot{2 * 5 * 12 * 12}; //< Total DetID in Layer 2 +constexpr unsigned int nChips{l2IDEnd + 1}; //< number of Chips (PixelArrays) in IB template inline T getDetID2Layer(T detID) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C index 23d48f9ad57b5..67b75e33bc430 100755 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsDensity.C @@ -80,8 +80,8 @@ void CheckDigitsDensity(int nEvents = 10000, std::string digitFileName = "it3dig digitTree->SetBranchAddress("IT3Digit", &digitArrayPtr); std::array hists; for (int i{3}; i--;) { - double rmin = its3::constants::radii[i] - its3::constants::thickness; - double rmax = its3::constants::radii[i] + its3::constants::thickness; + double rmin = its3::constants::radiiInner[i]; + double rmax = its3::constants::radiiOuter[i]; hists[i] = new TH2F(Form("h_digits_dens_L%d", i), Form("Digit Density L%d in %d Events; Z_{Glo} [cm]; R_{Glo} [cm]", i, nEvents), 100, -15, 15, 100, rmin, rmax); } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C index e6e5079aabf25..1dc4a4e2d6b47 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C @@ -185,7 +185,7 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil const auto* mc2hit = &mc2hitVec[lab.getEventID()]; const auto& hitEntry = mc2hit->find(key); if (hitEntry == mc2hit->end()) { - LOGP(error, "Failed to find MC hit entry for Tr {} chipID {}", trID, chipID); + LOGP(debug, "Failed to find MC hit entry for Tr {} chipID {}", trID, chipID); continue; } @@ -197,7 +197,7 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil auto xyzLocE = gman->getMatrixL2G(chipID) ^ (hit.GetPos()); // inverse conversion from global to local auto xyzLocS = gman->getMatrixL2G(chipID) ^ (hit.GetPosStart()); o2::math_utils::Vector3D xyzLocM; - xyzLocM.SetCoordinates(0.5 * (xyzLocE.X() + xyzLocS.X()), 0.5 * (xyzLocE.Y() + xyzLocS.Y()), 0.5 * (xyzLocE.Z() + xyzLocS.Z())); + xyzLocM.SetCoordinates(0.5f * (xyzLocE.X() + xyzLocS.X()), 0.5f * (xyzLocE.Y() + xyzLocS.Y()), 0.5f * (xyzLocE.Z() + xyzLocS.Z())); float xlc = 0., zlc = 0.; int row = 0, col = 0; diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C index 29ee833bd4881..12e1ab3a7280d 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegment.C @@ -186,8 +186,7 @@ void CheckMosaixSegment(bool isTestDetectorToLocal = false, TArc* arc[3]; h_xCurved_yCurved->Draw("colz"); for (int i = 0; i < 3; i++) { - arc[i] = new TArc(-0, 0, constants::radii[i] + constants::thickness / 2., -5, 40); - arc[i]->SetLineColor(kRed); + arc[i] = new TArc(-0, 0, constants::radiiOuter[i], -5, 40); arc[i]->SetFillStyle(0); } diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C index 5ee3c60758302..1a723bd6017bb 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckMosaixSegmentTrans.C @@ -89,8 +89,8 @@ void CheckMosaixSegmentTrans() gStyle->SetOptStat(1111111); for (int iLayer{0}; iLayer < 3; ++iLayer) { - float r_inner = constants::radii[iLayer] - constants::thickness / 2.; - float r_outer = constants::radii[iLayer] + constants::thickness / 2.; + float r_inner = constants::radiiInner[iLayer]; + float r_outer = constants::radiiOuter[iLayer]; float phiReadout_inner = constants::tile::readout::width / r_inner * Rad2Deg; float phiReadout_outer = @@ -203,13 +203,11 @@ void CheckMosaixSegmentTrans() float xRow{0}, zCol{0}; int iiRow{0}, iiCol{0}; auto v1 = mMosaixSegmentations[iLayer].detectorToLocal(iRow, iCol, xRow, zCol); - auto v2 = mMosaixSegmentations[iLayer].localToDetector(xRow, zCol, iiRow, - iiCol); - // Info("L2D", - // "iRow=%d, iCol=%d --d2l(%s)--> xRow=%f, zCol=%f --l2d(%s)--> " - // "iiRow=%d, iiCol=%d", - // iRow, iCol, v1 ? "good" : "bad", xRow, zCol, v2 ? "good" : - // "bad", iiRow, iiCol); + auto v2 = mMosaixSegmentations[iLayer].localToDetector(xRow, zCol, iiRow, iiCol); + Info("L2D", + "iRow=%d, iCol=%d --d2l(%s)--> xRow=%f, zCol=%f --l2d(%s)--> " + "iiRow=%d, iiCol=%d", + iRow, iCol, v1 ? "good" : "bad", xRow, zCol, v2 ? "good" : "bad", iiRow, iiCol); if (!v1 || !v2) { Error("LOOP", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Layer %d", iLayer); return; diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index f3667c5393b4b..8dc94e339c793 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -73,7 +73,7 @@ void ITS3Layer::createLayer(TGeoVolume* motherVolume) return; } // Add it to motherVolume - auto* trans = new TGeoTranslation(0, 0, -constants::segment::lengthSensitive / 2. - constants::rsu::databackbone::length / 2. + constants::tile::powerswitches::length / 2.); + auto* trans = new TGeoTranslation(0, 0, -constants::segment::lengthSensitive / 2.); motherVolume->AddNode(mLayer, 0, trans); } @@ -83,8 +83,6 @@ void ITS3Layer::createPixelArray() return; } // A pixel array is pure silicon and the sensitive part of our detector. - // It will be segmented into a 442x156 matrix by the - // SuperSegmentationAlpide. using namespace its3c::pixelarray; double pixelArrayPhi = width / mR * o2m::Rad2Deg; auto pixelArray = new TGeoTubeSeg(mRmin, mRmax, length / 2., 0, pixelArrayPhi); @@ -293,7 +291,7 @@ void ITS3Layer::createCarbonForm() mCarbonForm->VisibleDaughters(); double dRadius = -1; if (mNLayer < 2) { - dRadius = constants::radii[mNLayer + 1] - constants::radii[mNLayer] - constants::thickness - constants::metalstack::thickness; + dRadius = constants::radii[mNLayer + 1] - constants::radii[mNLayer] - constants::totalThickness; } else { dRadius = 0.7; // TODO: lack of carbon foam radius for layer 2, use 0.7mm as a temporary value } From 214575e8c035a7e0a897a93c9d0977d1f895ab47 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 7 Feb 2025 14:17:14 +0100 Subject: [PATCH 26/34] ITS3: remove newline from digiparams Signed-off-by: Felix Schlepper --- .../ITS3/simulation/src/DigiParams.cxx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx b/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx index e07e581c3c28c..a9f17a544b3c4 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/DigiParams.cxx @@ -23,16 +23,16 @@ namespace o2::its3 void DigiParams::print() const { // print settings - LOGF(info, "ITS3 DigiParams settings:\n"); - LOGF(info, "Continuous readout : %s\n", isContinuous() ? "ON" : "OFF"); - LOGF(info, "Readout Frame Length(ns) : %f\n", getROFrameLength()); - LOGF(info, "Strobe delay (ns) : %f\n", getStrobeDelay()); - LOGF(info, "Strobe length (ns) : %f\n", getStrobeLength()); - LOGF(info, "Threshold (N electrons) : %d\n", getChargeThreshold()); - LOGF(info, "Min N electrons to account : %d\n", getMinChargeToAccount()); - LOGF(info, "Number of charge sharing steps : %d\n", getNSimSteps()); - LOGF(info, "ELoss to N electrons factor : %e\n", getEnergyToNElectrons()); - LOGF(info, "Noise level per pixel : %e\n", getNoisePerPixel()); + LOGF(info, "ITS3 DigiParams settings:"); + LOGF(info, "Continuous readout : %s", isContinuous() ? "ON" : "OFF"); + LOGF(info, "Readout Frame Length(ns) : %f", getROFrameLength()); + LOGF(info, "Strobe delay (ns) : %f", getStrobeDelay()); + LOGF(info, "Strobe length (ns) : %f", getStrobeLength()); + LOGF(info, "Threshold (N electrons) : %d", getChargeThreshold()); + LOGF(info, "Min N electrons to account : %d", getMinChargeToAccount()); + LOGF(info, "Number of charge sharing steps : %d", getNSimSteps()); + LOGF(info, "ELoss to N electrons factor : %e", getEnergyToNElectrons()); + LOGF(info, "Noise level per pixel : %e", getNoisePerPixel()); LOGF(info, "Charge time-response:\n"); getSignalShape().print(); } From 292abdc6255d0f20efdd8c331fe2fd270a5472c7 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 10 Feb 2025 11:31:58 +0100 Subject: [PATCH 27/34] ITS3: make segmentation mostly constexpr Signed-off-by: Felix Schlepper --- .../include/ITS3Base/SegmentationMosaix.h | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index 37bb6156685cd..948db53fa6499 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -52,18 +52,20 @@ class SegmentationMosaix // | | | // x----------------------x public: - ~SegmentationMosaix() = default; - SegmentationMosaix(const SegmentationMosaix&) = default; - SegmentationMosaix(SegmentationMosaix&&) = delete; - SegmentationMosaix& operator=(const SegmentationMosaix&) = default; - SegmentationMosaix& operator=(SegmentationMosaix&&) = delete; - constexpr SegmentationMosaix(int layer) : mLayer{layer} {} + constexpr SegmentationMosaix(int layer) : mRadius(static_cast(constants::radiiMiddle[layer])) {} + constexpr ~SegmentationMosaix() = default; + constexpr SegmentationMosaix(const SegmentationMosaix&) = default; + constexpr SegmentationMosaix(SegmentationMosaix&&) = delete; + constexpr SegmentationMosaix& operator=(const SegmentationMosaix&) = default; + constexpr SegmentationMosaix& operator=(SegmentationMosaix&&) = delete; static constexpr int NCols{constants::pixelarray::nCols}; static constexpr int NRows{constants::pixelarray::nRows}; static constexpr int NPixels{NCols * NRows}; static constexpr float Length{constants::pixelarray::length}; + static constexpr float LengthH{Length / 2.f}; static constexpr float Width{constants::pixelarray::width}; + static constexpr float WidthH{Width / 2.f}; static constexpr float PitchCol{constants::pixelarray::length / static_cast(NCols)}; static constexpr float PitchRow{constants::pixelarray::width / static_cast(NRows)}; static constexpr float SensorLayerThickness{constants::totalThickness}; @@ -77,16 +79,16 @@ class SegmentationMosaix /// the center of the sensitive volume. /// \param yFlat Detector local flat coordinate y in cm with respect to /// the center of the sensitive volume. - void curvedToFlat(const float xCurved, const float yCurved, float& xFlat, float& yFlat) const noexcept + constexpr void curvedToFlat(const float xCurved, const float yCurved, float& xFlat, float& yFlat) const noexcept { // MUST align the flat surface with the curved surface with the original pixel array is on and account for metal // stack float dist = std::hypot(xCurved, yCurved); float phi = std::atan2(yCurved, xCurved); - xFlat = (getRadius() * phi) - Width / 2.f; + xFlat = (mRadius * phi) - WidthH; // the y position is in the silicon volume however we need the chip volume (silicon+metalstack) // this is accounted by a y shift - yFlat = dist - getRadius() + static_cast(constants::nominalYShift); + yFlat = dist + (static_cast(constants::nominalYShift) - mRadius); } /// Transformation from the flat surface to a curved surface @@ -99,15 +101,15 @@ class SegmentationMosaix /// the center of the sensitive volume. /// \param yCurved Detector local curved coordinate y in cm with respect to /// the center of the sensitive volume. - void flatToCurved(float xFlat, float yFlat, float& xCurved, float& yCurved) const noexcept + constexpr void flatToCurved(float xFlat, float yFlat, float& xCurved, float& yCurved) const noexcept { // MUST align the flat surface with the curved surface with the original pixel array is on and account for metal // stack // the y position is in the chip volume however we need the silicon volume // this is accounted by a -y shift - float dist = yFlat + getRadius() - static_cast(constants::nominalYShift); - xCurved = dist * std::cos((xFlat + Width / 2.f) / getRadius()); - yCurved = dist * std::sin((xFlat + Width / 2.f) / getRadius()); + float dist = yFlat + (mRadius - static_cast(constants::nominalYShift)); + xCurved = dist * std::cos((xFlat + WidthH) / mRadius); + yCurved = dist * std::sin((xFlat + WidthH) / mRadius); } /// Transformation from Geant detector centered local coordinates (cm) to @@ -121,7 +123,7 @@ class SegmentationMosaix /// the center of the sensitive volume. /// \param int iRow Detector x cell coordinate. /// \param int iCol Detector z cell coordinate. - bool localToDetector(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept + constexpr bool localToDetector(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept { localToDetectorUnchecked(xRow, zCol, iRow, iCol); if (!isValid(iRow, iCol)) { @@ -132,10 +134,10 @@ class SegmentationMosaix } // Same as localToDetector w.o. checks. - void localToDetectorUnchecked(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept + constexpr void localToDetectorUnchecked(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept { - iRow = std::floor((Width / 2. - xRow) / PitchRow); - iCol = std::floor((zCol + Length / 2.) / PitchCol); + iRow = static_cast(std::floor((WidthH - xRow) / PitchRow)); + iCol = static_cast(std::floor((zCol + LengthH) / PitchCol)); } /// Transformation from Detector cell coordinates to Geant detector centered @@ -148,7 +150,7 @@ class SegmentationMosaix /// center of the sensitive volume. /// If iRow and or iCol is outside of the segmentation range a value of -0.5*Dx() /// or -0.5*Dz() is returned. - bool detectorToLocal(int const iRow, int const iCol, float& xRow, float& zCol) const noexcept + constexpr bool detectorToLocal(int const iRow, int const iCol, float& xRow, float& zCol) const noexcept { if (!isValid(iRow, iCol)) { return false; @@ -159,10 +161,10 @@ class SegmentationMosaix // Same as detectorToLocal w.o. checks. // We position ourself in the middle of the pixel. - void detectorToLocalUnchecked(int const iRow, int const iCol, float& xRow, float& zCol) const noexcept + constexpr void detectorToLocalUnchecked(int const iRow, int const iCol, float& xRow, float& zCol) const noexcept { - xRow = -(static_cast(iRow) + 0.5f) * PitchRow + Width / 2.f; - zCol = (static_cast(iCol) + 0.5f) * PitchCol - Length / 2.f; + xRow = -(static_cast(iRow) + 0.5f) * PitchRow + WidthH; + zCol = (static_cast(iCol) + 0.5f) * PitchCol - LengthH; } bool detectorToLocal(int const row, int const col, math_utils::Point3D& loc) const noexcept @@ -184,22 +186,16 @@ class SegmentationMosaix private: template - [[nodiscard]] bool isValid(T const row, T const col) const noexcept + [[nodiscard]] constexpr bool isValid(T const row, T const col) const noexcept { if constexpr (std::is_floating_point_v) { // compares in local coord. - namespace cp = constants::pixelarray; - return !static_cast(row <= -cp::width / 2. || cp::width / 2. <= row || col <= -cp::length / 2. || cp::length / 2. <= col); + return (-WidthH < row && row < WidthH && -LengthH < col && col < LengthH); } else { // compares in rows/cols return !static_cast(row < 0 || row >= static_cast(NRows) || col < 0 || col >= static_cast(NCols)); } } - float getRadius() const noexcept - { - return static_cast(constants::radiiMiddle[mLayer]); - } - - int mLayer{0}; ///< chip layer + float mRadius; }; } // namespace o2::its3 From cbaa5d4ab97fa7f39726e66fe39e415e11ec94b0 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 10 Feb 2025 11:32:37 +0100 Subject: [PATCH 28/34] ITS3: minor changes in Digitizer for float Signed-off-by: Felix Schlepper --- .../include/ITS3Simulation/Digitizer.h | 10 ++++----- .../ITS3/simulation/src/Digitizer.cxx | 22 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index 508261f03ce38..efdf4f8096f82 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -106,14 +106,14 @@ class Digitizer : public TObject uint32_t mEventROFrameMin = 0xffffffff; ///< lowest RO frame for processed events (w/o automatic noise ROFs) uint32_t mEventROFrameMax = 0; ///< highest RO frame forfor processed events (w/o automatic noise ROFs) - const std::array mIBSegmentations{0, 1, 2}; + static constexpr std::array mIBSegmentations{0, 1, 2}; o2::itsmft::AlpideSimResponse* mSimRespIB = nullptr; // simulated response for IB o2::itsmft::AlpideSimResponse* mSimRespOB = nullptr; // simulated response for OB - float mSimRespIBShift{0.}; // adjusting the Y-shift in the IB response function to match sensor local coord. - float mSimRespIBScaleX{1.}; // scale x-local coordinate to response function x-coordinate - float mSimRespIBScaleZ{1.}; // scale z-local coordinate to response function z-coordinate - float mSimRespOBShift{0.}; // adjusting the Y-shift in the OB response function to match sensor local coord. + float mSimRespIBShift{0.f}; // adjusting the Y-shift in the IB response function to match sensor local coord. + float mSimRespIBScaleX{1.f}; // scale x-local coordinate to response function x-coordinate + float mSimRespIBScaleZ{1.f}; // scale z-local coordinate to response function z-coordinate + float mSimRespOBShift{0.f}; // adjusting the Y-shift in the OB response function to match sensor local coord. const o2::its::GeometryTGeo* mGeometry = nullptr; ///< ITS3 geometry diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 74c7f31dad44a..53fee11421f0a 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -65,13 +65,13 @@ void Digitizer::init() if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") { constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc("Alpide", responseFile, "response0", responseFile, "response1"); - mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::SensorLayerThickness / 2.f + 10.e-4f; // TODO why this offset? + mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::SensorLayerThickness / 2.f + 10.e-4f; mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; } else if (func == "APTS") { constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1"); - mSimRespIBShift = mSimRespIB->getDepthMax() - 10.e-4f; + mSimRespIBShift = mSimRespIB->getDepthMax() - 6.5e-4f; mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; mSimRespIBScaleX = 0.5 * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::PitchRow; mSimRespIBScaleZ = 0.5 * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::PitchCol; @@ -328,15 +328,13 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID const int maxNrows{innerBarrel ? SegmentationMosaix::NRows : SegmentationAlpide::NRows}; const int maxNcols{innerBarrel ? SegmentationMosaix::NCols : SegmentationAlpide::NCols}; - if (rowE >= maxNrows) { - rowE = maxNrows - 1; - } + + rowE = std::min(rowE, maxNrows - 1); colS -= AlpideRespSimMat::NPix / 2; colE += AlpideRespSimMat::NPix / 2; colS = std::max(colS, 0); - if (colE >= maxNcols) { - colE = maxNcols - 1; - } + colE = std::min(colE, maxNcols - 1); + int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1; // size of plaquet where some response is expected float respMatrix[rowSpan][colSpan]; // response accumulated here std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f); @@ -379,12 +377,12 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID float rowMax{}, colMax{}; const AlpideRespSimMat* rspmat{nullptr}; if (innerBarrel) { - rowMax = 0.5 * SegmentationMosaix::PitchRow; - colMax = 0.5 * SegmentationMosaix::PitchCol; + rowMax = 0.5f * SegmentationMosaix::PitchRow; + colMax = 0.5f * SegmentationMosaix::PitchCol; rspmat = mSimRespIB->getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); } else { - rowMax = 0.5 * SegmentationAlpide::PitchRow; - colMax = 0.5 * SegmentationAlpide::PitchCol; + rowMax = 0.5f * SegmentationAlpide::PitchRow; + colMax = 0.5f * SegmentationAlpide::PitchCol; rspmat = mSimRespOB->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax); } From 2e0a53dfb157729a7650a0a0aa3f2b3c1d6d3a18 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 11 Feb 2025 10:57:57 +0100 Subject: [PATCH 29/34] ITS3: move pixel specs down Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/SpecsV2.h | 72 +++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index 2b460d5c029d0..35c3db41ac77a 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -21,6 +21,11 @@ #include +// This files defines the design specifications of the chip. +// Each TGeoShape has the following properties +// length: dimension in z-axis +// width: dimension in xy-axes +// color: for visulisation namespace o2::its3::constants { constexpr double cm{1e+2}; // This is the default unit of TGeo so we use this as scale @@ -35,27 +40,6 @@ constexpr int nRows{442}; constexpr int nPixels{nRows * nCols}; constexpr EColor color{kGreen}; constexpr double area{width * length}; -namespace pixels -{ -namespace apts -{ -constexpr double pitchX{15.0 * mu}; -constexpr double pitchZ{15.0 * mu}; -} // namespace apts -namespace moss -{ -namespace top -{ -constexpr double pitchX{22.5 * mu}; -constexpr double pitchZ{22.5 * mu}; -} // namespace top -namespace bot -{ -constexpr double pitchX{18.0 * mu}; -constexpr double pitchZ{18.0 * mu}; -} // namespace bot -} // namespace moss -} // namespace pixels } // namespace pixelarray namespace tile { @@ -112,7 +96,7 @@ constexpr EColor color{kCyan}; } // namespace rec constexpr unsigned int nRSUs{12}; constexpr unsigned int nTilesPerSegment{nRSUs * rsu::nTiles}; -constexpr double length{nRSUs * rsu::length + lec::length + rec::length}; +constexpr double length{(nRSUs * rsu::length) + lec::length + rec::length}; constexpr double lengthSensitive{nRSUs * rsu::length}; } // namespace segment namespace carbonfoam @@ -136,9 +120,9 @@ constexpr EColor color{kBlack}; } // namespace metalstack namespace silicon { -constexpr double thickness{45 * mu}; // thickness of silicion -constexpr double radiusInner{(thickness + metalstack::thickness) / 2.}; // inner silicion radius correction -constexpr double radiusOuter{(thickness - metalstack::thickness) / 2.}; // outer silicion radius correction +constexpr double thickness{45 * mu}; // thickness of silicon +constexpr double thicknessIn{(thickness + metalstack::thickness) / 2.}; // inner silicon thickness +constexpr double thicknessOut{(thickness - metalstack::thickness) / 2.}; // outer silicon thickness } // namespace silicon constexpr unsigned int nLayers{3}; constexpr unsigned int nTotLayers{7}; @@ -147,10 +131,42 @@ constexpr double equatorialGap{1 * mm}; constexpr std::array nSegments{3, 4, 5}; constexpr double totalThickness{silicon::thickness + metalstack::thickness}; // total chip thickness constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // nominal radius -constexpr std::array radiiInner{radii[0] - silicon::radiusInner, radii[1] - silicon::radiusInner, radii[2] - silicon::radiusInner}; // inner silicon radius -constexpr std::array radiiOuter{radii[0] + silicon::radiusOuter, radii[1] + silicon::radiusOuter, radii[2] + silicon::radiusOuter}; // outer silicon radius +constexpr std::array radiiInner{radii[0] - silicon::thicknessIn, radii[1] - silicon::thicknessIn, radii[2] - silicon::thicknessIn}; // inner silicon radius +constexpr std::array radiiOuter{radii[0] + silicon::thicknessOut, radii[1] + silicon::thicknessOut, radii[2] + silicon::thicknessOut}; // outer silicon radius constexpr std::array radiiMiddle{(radiiInner[0] + radiiOuter[0]) / 2., (radiiInner[1] + radiiOuter[1]) / 2., (radiiInner[2] + radiiOuter[2]) / 2.}; // middle silicon radius -constexpr double nominalYShift{-metalstack::thickness / 2.}; // shift to position in silicion volume to the chip volume (silicon+metalstack) +/*constexpr double nominalYShift{-metalstack::thickness / 2.}; // shift to position in silicion volume to the chip volume (silicon+metalstack)*/ +constexpr double nominalYShift{0}; // shift to position in silicion volume to the chip volume (silicon+metalstack) + +// extra information of pixels and their response functions +namespace pixelarray::pixels +{ +namespace mosaix +{ +constexpr double pitchX{width / static_cast(nRows)}; +constexpr double pitchZ{length / static_cast(nCols)}; +} // namespace mosaix +namespace apts +{ +constexpr double pitchX{15.0 * mu}; +constexpr double pitchZ{15.0 * mu}; +constexpr double responseUpperLimit{10 * mu}; +constexpr double responseYShift{responseUpperLimit - silicon::thicknessOut}; +} // namespace apts +namespace moss +{ +namespace top +{ +constexpr double pitchX{22.5 * mu}; +constexpr double pitchZ{22.5 * mu}; +} // namespace top +namespace bot +{ +constexpr double pitchX{18.0 * mu}; +constexpr double pitchZ{18.0 * mu}; +} // namespace bot +} // namespace moss +} // namespace pixelarray::pixels + namespace detID { constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU From f6161d3cfc29a1dfa3795de897ffc9a08b5911d1 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 11 Feb 2025 10:59:12 +0100 Subject: [PATCH 30/34] ITS3: account in segmentation trans for nominal shift Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/SegmentationMosaix.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index 948db53fa6499..fb1d161a8eedc 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -66,9 +66,10 @@ class SegmentationMosaix static constexpr float LengthH{Length / 2.f}; static constexpr float Width{constants::pixelarray::width}; static constexpr float WidthH{Width / 2.f}; - static constexpr float PitchCol{constants::pixelarray::length / static_cast(NCols)}; - static constexpr float PitchRow{constants::pixelarray::width / static_cast(NRows)}; + static constexpr float PitchCol{constants::pixelarray::pixels::mosaix::pitchZ}; + static constexpr float PitchRow{constants::pixelarray::pixels::mosaix::pitchX}; static constexpr float SensorLayerThickness{constants::totalThickness}; + static constexpr float NominalYShift{constants::nominalYShift}; /// Transformation from the curved surface to a flat surface /// \param xCurved Detector local curved coordinate x in cm with respect to @@ -88,7 +89,7 @@ class SegmentationMosaix xFlat = (mRadius * phi) - WidthH; // the y position is in the silicon volume however we need the chip volume (silicon+metalstack) // this is accounted by a y shift - yFlat = dist + (static_cast(constants::nominalYShift) - mRadius); + yFlat = dist - mRadius + NominalYShift; } /// Transformation from the flat surface to a curved surface @@ -107,7 +108,7 @@ class SegmentationMosaix // stack // the y position is in the chip volume however we need the silicon volume // this is accounted by a -y shift - float dist = yFlat + (mRadius - static_cast(constants::nominalYShift)); + float dist = yFlat - NominalYShift + mRadius; xCurved = dist * std::cos((xFlat + WidthH) / mRadius); yCurved = dist * std::sin((xFlat + WidthH) / mRadius); } @@ -173,7 +174,7 @@ class SegmentationMosaix if (!detectorToLocal(row, col, xRow, zCol)) { return false; } - loc.SetCoordinates(xRow, 0., zCol); + loc.SetCoordinates(xRow, NominalYShift, zCol); return true; } @@ -181,7 +182,7 @@ class SegmentationMosaix { float xRow{0.}, zCol{0.}; detectorToLocalUnchecked(row, col, xRow, zCol); - loc.SetCoordinates(xRow, 0., zCol); + loc.SetCoordinates(xRow, NominalYShift, zCol); } private: From 882545b703a4a674e870e3897c83d8d931df73d7 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 11 Feb 2025 10:59:35 +0100 Subject: [PATCH 31/34] ITS3: Digitizer flip row for IB for APTS Signed-off-by: Felix Schlepper --- .../ITS3/simulation/include/ITS3Simulation/Digitizer.h | 1 + Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index efdf4f8096f82..8d0f06a27343b 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -110,6 +110,7 @@ class Digitizer : public TObject o2::itsmft::AlpideSimResponse* mSimRespIB = nullptr; // simulated response for IB o2::itsmft::AlpideSimResponse* mSimRespOB = nullptr; // simulated response for OB + bool mSimRespIBOrientation{false}; // wether the orientation in the IB response function is flipped float mSimRespIBShift{0.f}; // adjusting the Y-shift in the IB response function to match sensor local coord. float mSimRespIBScaleX{1.f}; // scale x-local coordinate to response function x-coordinate float mSimRespIBScaleZ{1.f}; // scale z-local coordinate to response function z-coordinate diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 53fee11421f0a..3c75bf3e8f680 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -71,10 +71,11 @@ void Digitizer::init() constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1"); - mSimRespIBShift = mSimRespIB->getDepthMax() - 6.5e-4f; + mSimRespIBShift = mSimRespIB->getDepthMax() + (float)constants::pixelarray::pixels::apts::responseYShift; mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f; - mSimRespIBScaleX = 0.5 * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::PitchRow; - mSimRespIBScaleZ = 0.5 * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::PitchCol; + mSimRespIBScaleX = 0.5f * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::PitchRow; + mSimRespIBScaleZ = 0.5f * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::PitchCol; + mSimRespIBOrientation = true; } else { LOGP(fatal, "ResponseFunction '{}' not implemented!", func); } @@ -401,7 +402,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID if (colDest < 0 || colDest >= colSpan) { continue; } - respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, flipRow, flipCol); + respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, ((innerBarrel && mSimRespIBOrientation) ? !flipRow : flipRow), flipCol); } } } From 7ac713e707c06354060ab568c5f31311821ca2d6 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 14 Feb 2025 10:03:52 +0100 Subject: [PATCH 32/34] ITS3: Add explanation to SegmentationMosaix Signed-off-by: Felix Schlepper --- .../include/ITS3Base/SegmentationMosaix.h | 20 +++++++++++++++++-- .../ITS3/base/include/ITS3Base/SpecsV2.h | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h index fb1d161a8eedc..f8d4a784120a0 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h @@ -32,6 +32,16 @@ class SegmentationMosaix // the more natural row,col layout: Also all the transformation between these // two. The class provides the transformation from the tile to TGeo // coordinates. + // In fact there exist three coordinate systems and one is transient. + // 1. The curved coordinate system. The chip's local coordinate system is + // defined with its center at the the mid-point of the tube. + // 2. The flat coordinate system. This is the tube segment projected onto a flat + // surface. In the projection we implicitly assume that the inner and outer + // stretch does not depend on the radius. + // Additionally, there is a difference between the flat geometrical center + // and the phyiscal center defined by the metal layer. + // 3. The detector coordinate system. Defined by the row and column segmentation + // defined at the upper edge in the flat coord. // row,col=0 // | @@ -71,7 +81,13 @@ class SegmentationMosaix static constexpr float SensorLayerThickness{constants::totalThickness}; static constexpr float NominalYShift{constants::nominalYShift}; - /// Transformation from the curved surface to a flat surface + /// Transformation from the curved surface to a flat surface. + /// Additionally a shift in the flat coordinates must be applied because + /// the center of the TGeoShap when projected will be higher than the + /// physical thickness of the chip (we add an additional hull to account for + /// the copper metal interconnection which is in reality part of the chip but in our + /// simulation the silicon and metal layer are separated). Thus we shift the projected center + /// down by this difference to align the coordinate systems. /// \param xCurved Detector local curved coordinate x in cm with respect to /// the center of the sensitive volume. /// \param yCurved Detector local curved coordinate y in cm with respect to @@ -93,7 +109,7 @@ class SegmentationMosaix } /// Transformation from the flat surface to a curved surface - /// It works only if the detector is not rototraslated + /// It works only if the detector is not rototraslated. /// \param xFlat Detector local flat coordinate x in cm with respect to /// the center of the sensitive volume. /// \param yFlat Detector local flat coordinate y in cm with respect to diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index 35c3db41ac77a..b604b8094363f 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -134,8 +134,8 @@ constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * constexpr std::array radiiInner{radii[0] - silicon::thicknessIn, radii[1] - silicon::thicknessIn, radii[2] - silicon::thicknessIn}; // inner silicon radius constexpr std::array radiiOuter{radii[0] + silicon::thicknessOut, radii[1] + silicon::thicknessOut, radii[2] + silicon::thicknessOut}; // outer silicon radius constexpr std::array radiiMiddle{(radiiInner[0] + radiiOuter[0]) / 2., (radiiInner[1] + radiiOuter[1]) / 2., (radiiInner[2] + radiiOuter[2]) / 2.}; // middle silicon radius -/*constexpr double nominalYShift{-metalstack::thickness / 2.}; // shift to position in silicion volume to the chip volume (silicon+metalstack)*/ -constexpr double nominalYShift{0}; // shift to position in silicion volume to the chip volume (silicon+metalstack) +constexpr double nominalYShift{-metalstack::thickness / 2.}; // shift to position in silicion volume to the chip volume (silicon+metalstack) +/*constexpr double nominalYShift{0}; // shift to position in silicion volume to the chip volume (silicon+metalstack)*/ // extra information of pixels and their response functions namespace pixelarray::pixels From 9b9bf02798f3d72a0b47ce7ab9c0cf9d600e5614 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 27 Feb 2025 12:46:51 +0100 Subject: [PATCH 33/34] ITS3: split topo dict into IB and OB Signed-off-by: Felix Schlepper --- .../ITS3/base/include/ITS3Base/SpecsV2.h | 1 - .../ITS3/macros/test/CheckClusterSize.C | 5 +- .../ITS3/macros/test/CheckClustersITS3.C | 30 ++- .../macros/test/CompareClustersAndDigits.C | 4 +- .../ITS3/macros/test/CreateDictionariesITS3.C | 107 +++++--- .../BuildTopologyDictionary.h | 48 ++-- .../include/ITS3Reconstruction/Clusterer.h | 10 +- .../include/ITS3Reconstruction/IOUtils.h | 16 +- .../include/ITS3Reconstruction/LookUp.h | 20 +- .../ITS3Reconstruction/TopologyDictionary.h | 114 +++++--- .../src/BuildTopologyDictionary.cxx | 253 +++++++++++------- .../ITS3/reconstruction/src/Clusterer.cxx | 11 +- .../src/ITS3ReconstructionLinkDef.h | 1 + .../ITS3/reconstruction/src/LookUp.cxx | 21 +- .../reconstruction/src/TopologyDictionary.cxx | 164 ++++++++---- 15 files changed, 498 insertions(+), 307 deletions(-) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index b604b8094363f..fedaad9182cce 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -135,7 +135,6 @@ constexpr std::array radiiInner{radii[0] - silicon::thicknessIn constexpr std::array radiiOuter{radii[0] + silicon::thicknessOut, radii[1] + silicon::thicknessOut, radii[2] + silicon::thicknessOut}; // outer silicon radius constexpr std::array radiiMiddle{(radiiInner[0] + radiiOuter[0]) / 2., (radiiInner[1] + radiiOuter[1]) / 2., (radiiInner[2] + radiiOuter[2]) / 2.}; // middle silicon radius constexpr double nominalYShift{-metalstack::thickness / 2.}; // shift to position in silicion volume to the chip volume (silicon+metalstack) -/*constexpr double nominalYShift{0}; // shift to position in silicion volume to the chip volume (silicon+metalstack)*/ // extra information of pixels and their response functions namespace pixelarray::pixels diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C b/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C index 5fffed4fcc580..564b20350b883 100755 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C @@ -255,13 +255,14 @@ void CheckClusterSize(std::string clusFileName = "o2clus_its.root", auto pattId = cluster.getPatternID(); auto id = cluster.getSensorID(); + auto ib = o2::its3::constants::detID::isDetITS3(id); int clusterSize{-1}; - if (pattId == o2::itsmft::CompCluster::InvalidPatternID || dict.isGroup(pattId)) { + if (pattId == o2::itsmft::CompCluster::InvalidPatternID || dict.isGroup(pattId, ib)) { o2::itsmft::ClusterPattern patt(pattIt); clusterSize = patt.getNPixels(); continue; } else { - clusterSize = dict.getNpixels(pattId); + clusterSize = dict.getNpixels(pattId, ib); } const auto& label = (clusLabArr->getLabels(clEntry))[0]; diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index a0f7dffc6ed1b..006271a1ea7bd 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -42,7 +42,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", const std::string& hitfile = "o2sim_HitsIT3.root", const std::string& inputGeom = "", - std::string dictfile = "../ccdb/IT3/Calib/ClusterDictionary/snapshot.root", + std::string dictfile = "./ccdb/IT3/Calib/ClusterDictionary/snapshot.root", bool batch = false) { gROOT->SetBatch(batch); @@ -63,7 +63,8 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", std::vector hitVecPool; std::vector mc2hitVec; - ULong_t cPattValid{0}, cPattInvalid{0}, cLabelInvalid{0}, cNoMC{0}; + ULong_t cPattValidIB{0}, cPattInvalidIB{0}, cLabelInvalidIB{0}, cNoMCIB{0}; + ULong_t cPattValidOB{0}, cPattInvalidOB{0}, cLabelInvalidOB{0}, cNoMCOB{0}; TFile fout("CheckClusters.root", "recreate"); 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:eta:row:col:lay"); @@ -103,6 +104,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", } else { LOG(info) << "Running without dictionary !"; } + dict.print(); // ROFrecords std::vector rofRecVec, *rofRecVecP = &rofRecVec; @@ -175,20 +177,18 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", auto isIB = o2::its3::constants::detID::isDetITS3(chipID); auto layer = o2::its3::constants::detID::getDetID2Layer(chipID); auto clusterSize{-1}; - if (pattID == o2::itsmft::CompCluster::InvalidPatternID || dict.isGroup(pattID)) { + if (pattID == o2::itsmft::CompCluster::InvalidPatternID || dict.isGroup(pattID, isIB)) { o2::itsmft::ClusterPattern patt(pattIt); locC = dict.getClusterCoordinates(cluster, patt, false); LOGP(debug, "I am invalid and I am on chip {}", chipID); - ++cPattInvalid; + (isIB) ? ++cPattInvalidIB : ++cPattInvalidOB; continue; } else { locC = dict.getClusterCoordinates(cluster); - errX = dict.getErrX(pattID); - errZ = dict.getErrZ(pattID); - errX *= (isIB) ? MosaixSegmentation::PitchRow : Segmentation::PitchRow; - errZ *= (isIB) ? MosaixSegmentation::PitchCol : Segmentation::PitchCol; - npix = dict.getNpixels(pattID); - ++cPattValid; + errX = dict.getErrX(pattID, isIB); + errZ = dict.getErrZ(pattID, isIB); + npix = dict.getNpixels(pattID, isIB); + (isIB) ? ++cPattValidIB : ++cPattValidOB; } // Transformation to the local --> global @@ -196,7 +196,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", const auto& lab = (clusLabArr->getLabels(clEntry))[0]; if (!lab.isValid()) { - ++cLabelInvalid; + (isIB) ? ++cLabelInvalidIB : ++cLabelInvalidOB; continue; } @@ -208,7 +208,7 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", auto hitEntry = mc2hit.find(key); if (hitEntry == mc2hit.end()) { LOG(debug) << "Failed to find MC hit entry for Tr" << trID << " chipID" << chipID; - ++cNoMC; + (isIB) ? ++cNoMCIB : ++cNoMCOB; continue; } const auto& hit = (*hitArray)[hitEntry->second]; @@ -263,8 +263,10 @@ void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", } } - LOGP(info, "There were {} valid PatternIDs and {} ({:.1f}%) invalid ones", cPattValid, cPattInvalid, ((float)cPattInvalid / (float)(cPattInvalid + cPattValid)) * 100); - LOGP(info, "There were {} invalid Labels and {} with No MC Hit information ", cLabelInvalid, cNoMC); + LOGP(info, "IB {} valid PatternIDs and {} ({:.1f}%) invalid ones", cPattValidIB, cPattInvalidIB, ((float)cPattInvalidIB / (float)(cPattInvalidIB + cPattValidIB)) * 100); + LOGP(info, "IB {} invalid Labels and {} with No MC Hit information ", cLabelInvalidIB, cNoMCIB); + LOGP(info, "OB {} valid PatternIDs and {} ({:.1f}%) invalid ones", cPattValidOB, cPattInvalidOB, ((float)cPattInvalidOB / (float)(cPattInvalidOB + cPattValidOB)) * 100); + LOGP(info, "OB {} invalid Labels and {} with No MC Hit information ", cLabelInvalidOB, cNoMCOB); auto canvCgXCgY = new TCanvas("canvCgXCgY", "", 1600, 1600); canvCgXCgY->Divide(2, 2); diff --git a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C index 7770ede749f0c..c124481cc6f76 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C +++ b/Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigits.C @@ -260,7 +260,7 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", const auto pattID = cluster.getPatternID(); const auto isIB = o2::its3::constants::detID::isDetITS3(chipID); const auto layer = gman->getLayer(chipID); - if (pattID == o2::itsmft::CompCluster::InvalidPatternID || dict.isGroup(pattID)) { + if (pattID == o2::itsmft::CompCluster::InvalidPatternID || dict.isGroup(pattID, isIB)) { continue; } const auto& lab = (clusLabArr->getLabels(clEntry))[0]; @@ -316,7 +316,7 @@ void CompareClustersAndDigits(std::string clusfile = "o2clus_it3.root", data[chipID].cog->AddPoint(colC, rowC); constexpr float delta = 1e-2; - const auto& patt = dict.getPattern(cluster.getPatternID()); + const auto& patt = dict.getPattern(cluster.getPatternID(), isIB); auto box = new TBox( cluster.getCol() - delta - 0.5, cluster.getRow() - delta - 0.5, diff --git a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C index 0116659940de1..cc241afb3357a 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CreateDictionariesITS3.C @@ -60,7 +60,7 @@ void CreateDictionariesITS3(bool saveDeltas = false, std::string collContextfile = "collisioncontext.root", std::string inputGeom = "", float checkOutliers = 2., // reject outliers (MC dX or dZ exceeds row/col span by a factor above the threshold) - float minPtMC = 0.01) // account only MC hits with pT above threshold + float minPtMC = 0.1) // account only MC hits with pT above threshold { const int QEDSourceID = 99; // Clusters from this MC source correspond to QED electrons @@ -84,10 +84,11 @@ void CreateDictionariesITS3(bool saveDeltas = false, std::array mMosaixSegmentations{0, 1, 2}; if (!clusDictFile.empty()) { clusDictOld.readFromFile(clusDictFile); - LOGP(info, "Loaded external cluster dictionary with {} entries from {}", clusDictOld.getSize(), clusDictFile); + LOGP(info, "Loaded external cluster dictionary with {} IB/{} OBentries from {}", clusDictOld.getSize(true), clusDictOld.getSize(false), clusDictFile); } - ULong_t cOk{0}, cOutliers{0}, cFailedMC{0}; + ULong_t cOkIB{0}, cOutliersIB{0}, cFailedMCIB{0}; + ULong_t cOkOB{0}, cOutliersOB{0}, cFailedMCOB{0}; TFile* fout = nullptr; TNtuple* nt = nullptr; @@ -233,17 +234,18 @@ void CreateDictionariesITS3(bool saveDeltas = false, const auto& cluster = (*clusArr)[clEntry]; o2::itsmft::ClusterPattern pattern; + bool ib = o2::its3::constants::detID::isDetITS3(cluster.getChipID()); if (cluster.getPatternID() != CompCluster::InvalidPatternID) { - if (clusDictOld.getSize() == 0) { + if (clusDictOld.getSize(ib) == 0) { LOG(error) << "Encountered patternID = " << cluster.getPatternID() << " != " << CompCluster::InvalidPatternID; LOG(error) << "Clusters have already been generated with a dictionary which was not provided"; return; } - if (clusDictOld.isGroup(cluster.getPatternID())) { + if (clusDictOld.isGroup(cluster.getPatternID(), ib)) { pattern.acquirePattern(pattIdx); } else { - pattern = clusDictOld.getPattern(cluster.getPatternID()); + pattern = clusDictOld.getPattern(cluster.getPatternID(), ib); } } else { pattern.acquirePattern(pattIdx); @@ -270,9 +272,8 @@ void CreateDictionariesITS3(bool saveDeltas = false, o2::math_utils::Vector3D xyzLocM; xyzLocM.SetCoordinates(0.5f * (xyzLocE.X() + xyzLocS.X()), 0.5f * (xyzLocE.Y() + xyzLocS.Y()), 0.5f * (xyzLocE.Z() + xyzLocS.Z())); auto locC = o2::its3::TopologyDictionary::getClusterCoordinates(cluster, pattern, false); - bool isIB = o2::its3::constants::detID::isDetITS3(chipID); int layer = gman->getLayer(chipID); - if (isIB) { + if (ib) { float xFlat{0.}, yFlat{0.}; mMosaixSegmentations[layer].curvedToFlat(xyzLocM.X(), xyzLocM.Y(), xFlat, yFlat); xyzLocM.SetCoordinates(xFlat, yFlat, xyzLocM.Z()); @@ -281,33 +282,33 @@ void CreateDictionariesITS3(bool saveDeltas = false, } dX = xyzLocM.X() - locC.X(); dZ = xyzLocM.Z() - locC.Z(); - dX /= (isIB) ? o2::its3::SegmentationMosaix::PitchRow : o2::itsmft::SegmentationAlpide::PitchRow; - dZ /= (isIB) ? o2::its3::SegmentationMosaix::PitchCol : o2::itsmft::SegmentationAlpide::PitchCol; + dX /= (ib) ? o2::its3::SegmentationMosaix::PitchRow : o2::itsmft::SegmentationAlpide::PitchRow; + dZ /= (ib) ? o2::its3::SegmentationMosaix::PitchCol : o2::itsmft::SegmentationAlpide::PitchCol; if (saveDeltas) { nt->Fill(topology.getHash(), dX, dZ); } if (checkOutliers > 0.) { if (bool bX = std::abs(dX) > topology.getRowSpan() * checkOutliers, bZ = std::abs(dZ) > topology.getColumnSpan() * checkOutliers; bX || bZ) { // ignore outlier - ++cOutliers; + (ib) ? ++cOutliersIB : ++cOutliersOB; LOGP(debug, "Ignored Value dX={} > {} * {} -> {}", dX, topology.getRowSpan(), checkOutliers, bX); LOGP(debug, "Ignored Value dZ={} > {} * {} -> {}", dZ, topology.getColumnSpan(), checkOutliers, bZ); dX = dZ = BuildTopologyDictionary::IgnoreVal; } else { - ++cOk; + (ib) ? ++cOkIB : ++cOkOB; } } } } else { /* LOGP(info, " Failed to find MC hit entry for Tr: {} chipID: {}", trID, chipID); */ /* lab.print(); */ - ++cFailedMC; + (ib) ? ++cFailedMCIB : ++cFailedMCOB; } - signalDictionary.accountTopology(topology, dX, dZ); + signalDictionary.accountTopology(topology, ib, dX, dZ); } else { - noiseDictionary.accountTopology(topology, dX, dZ); + noiseDictionary.accountTopology(topology, ib, dX, dZ); } } - completeDictionary.accountTopology(topology, dX, dZ); + completeDictionary.accountTopology(topology, ib, dX, dZ); } // clean MC cache for events which are not needed anymore @@ -323,12 +324,14 @@ void CreateDictionariesITS3(bool saveDeltas = false, } } - LOGP(info, "Clusters: {} okay (failed MCHit2Clus {}); outliers {}", cOk, cFailedMC, cOutliers); + LOGP(info, "IB Clusters: {} okay (failed MCHit2Clus {}); outliers {}", cOkIB, cFailedMCIB, cOutliersIB); + LOGP(info, "OB Clusters: {} okay (failed MCHit2Clus {}); outliers {}", cOkOB, cFailedMCOB, cOutliersOB); auto dID = o2::detectors::DetID::IT3; LOGP(info, "Complete Dictionary:"); - completeDictionary.setThreshold(probThreshold); + completeDictionary.setThreshold(probThreshold, true); + completeDictionary.setThreshold(probThreshold, false); completeDictionary.groupRareTopologies(); completeDictionary.printDictionaryBinary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "")); completeDictionary.printDictionary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "", "txt")); @@ -336,24 +339,34 @@ void CreateDictionariesITS3(bool saveDeltas = false, TFile histogramOutput("histograms.root", "recreate"); TCanvas* cComplete = new TCanvas("cComplete", "Distribution of all the topologies"); - cComplete->cd(); - cComplete->SetLogy(); - TH1F* hComplete = completeDictionary.getDictionary().getTopologyDistribution("hComplete"); - hComplete->SetDirectory(nullptr); - hComplete->Draw("hist"); - hComplete->Write(); + cComplete->Divide(2, 1); + cComplete->cd(1); + TH1F* hCompleteIB = completeDictionary.getDictionary().getTopologyDistribution("hCompleteInnerBarrel", true); + hCompleteIB->SetDirectory(nullptr); + hCompleteIB->Draw("hist"); + gPad->SetLogy(); + cComplete->cd(2); + TH1F* hCompleteOB = completeDictionary.getDictionary().getTopologyDistribution("hCompleteOuterBarrel", false); + hCompleteOB->SetDirectory(nullptr); + hCompleteOB->Draw("hist"); + gPad->SetLogy(); + histogramOutput.cd(); + hCompleteIB->Write(); + hCompleteOB->Write(); cComplete->Write(); if (clusLabArr) { LOGP(info, "Noise Dictionary:"); - noiseDictionary.setThreshold(0.0001); + noiseDictionary.setThreshold(0.0001, true); + noiseDictionary.setThreshold(0.0001, false); noiseDictionary.groupRareTopologies(); noiseDictionary.printDictionaryBinary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "noiseClusTopo")); noiseDictionary.printDictionary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "noiseClusTopo", "txt")); noiseDictionary.saveDictionaryRoot(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "noiseClusTopo", "root")); LOGP(info, "Signal Dictionary:"); - signalDictionary.setThreshold(0.0001); + signalDictionary.setThreshold(0.0001, true); + signalDictionary.setThreshold(0.0001, false); signalDictionary.groupRareTopologies(); signalDictionary.printDictionaryBinary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "signal")); signalDictionary.printDictionary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "signal", "txt")); @@ -361,26 +374,42 @@ void CreateDictionariesITS3(bool saveDeltas = false, LOGP(info, "Plotting Channels"); auto cNoise = new TCanvas("cNoise", "Distribution of noise topologies"); - cNoise->cd(); - cNoise->SetLogy(); - auto hNoise = noiseDictionary.getDictionary().getTopologyDistribution("hNoise"); - hNoise->SetDirectory(nullptr); - hNoise->Draw("hist"); + cNoise->Divide(2, 1); + cNoise->cd(1); + auto hNoiseIB = noiseDictionary.getDictionary().getTopologyDistribution("hNoiseInnerBarrel", true); + hNoiseIB->SetDirectory(nullptr); + hNoiseIB->Draw("hist"); + gPad->SetLogy(); + cNoise->cd(2); + auto hNoiseOB = noiseDictionary.getDictionary().getTopologyDistribution("hNoiseOuterBarrel", false); + hNoiseOB->SetDirectory(nullptr); + hNoiseOB->Draw("hist"); + gPad->SetLogy(); histogramOutput.cd(); - hNoise->Write(); + hNoiseIB->Write(); + hNoiseOB->Write(); cNoise->Write(); + auto cSignal = new TCanvas("cSignal", "cSignal"); - cSignal->cd(); + cSignal->Divide(2, 1); + cSignal->cd(1); + auto hSignalIB = signalDictionary.getDictionary().getTopologyDistribution("hSignalInnerBarrel", true); + hSignalIB->SetDirectory(nullptr); + hSignalIB->Draw("hist"); + gPad->SetLogy(); + cSignal->cd(2); cSignal->SetLogy(); - auto hSignal = signalDictionary.getDictionary().getTopologyDistribution("hSignal"); - hSignal->SetDirectory(nullptr); - hSignal->Draw("hist"); + auto hSignalOB = signalDictionary.getDictionary().getTopologyDistribution("hSignalOuterBarrel", false); + hSignalOB->SetDirectory(nullptr); + hSignalOB->Draw("hist"); + gPad->SetLogy(); histogramOutput.cd(); - hSignal->Write(); + hSignalIB->Write(); + hSignalOB->Write(); cSignal->Write(); - sw.Stop(); - sw.Print(); } + sw.Stop(); + sw.Print(); if (saveDeltas) { fout->cd(); nt->Write(); diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/BuildTopologyDictionary.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/BuildTopologyDictionary.h index 7df603bb29fb2..662c58aeb2cd8 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/BuildTopologyDictionary.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/BuildTopologyDictionary.h @@ -24,31 +24,47 @@ namespace o2::its3 class BuildTopologyDictionary { + using TopoInfo = std::unordered_map; + using TopoStat = std::map; + using TopoFreq = std::vector>; + public: static constexpr float IgnoreVal = 999.; - void accountTopology(const itsmft::ClusterTopology& cluster, float dX = IgnoreVal, float dZ = IgnoreVal); - void setNCommon(unsigned int nCommon); // set number of common topologies - void setThreshold(double thr); - void setThresholdCumulative(double cumulative); // Considering the integral + void accountTopology(const itsmft::ClusterTopology& cluster, bool IB, float dX = IgnoreVal, float dZ = IgnoreVal); + void setNCommon(unsigned int nCommon, bool IB); // set number of common topologies + void setThreshold(double thr, bool IB); + void setThresholdCumulative(double cumulative, bool IB); // Considering the integral void groupRareTopologies(); - friend std::ostream& operator<<(std::ostream& os, const BuildTopologyDictionary& BD); void printDictionary(const std::string& fname); void printDictionaryBinary(const std::string& fname); void saveDictionaryRoot(const std::string& fname); - unsigned int getTotClusters() const { return mTotClusters; } - unsigned int getNotInGroups() const { return mNCommonTopologies; } - TopologyDictionary getDictionary() const { return mDictionary; } + [[nodiscard]] unsigned int getTotClusters(bool IB) const { return (IB) ? mTotClustersIB : mTotClustersOB; } + [[nodiscard]] unsigned int getNotInGroups(bool IB) const { return (IB) ? mNCommonTopologiesIB : mNCommonTopologiesOB; } + [[nodiscard]] const TopologyDictionary& getDictionary() const { return mDictionary; } + + friend std::ostream& operator<<(std::ostream& os, const BuildTopologyDictionary& BD); private: - TopologyDictionary mDictionary; ///< Dictionary of topologies - std::map mTopologyMap; //! Temporary map of type - std::vector> mTopologyFrequency; //! , needed to define threshold - unsigned int mTotClusters{0}; - unsigned int mNCommonTopologies{0}; - double mFrequencyThreshold{0.}; - - std::unordered_map mMapInfo; + void accountTopologyImpl(const itsmft::ClusterTopology& cluster, TopoInfo& tinfo, TopoStat& tstat, unsigned int& ntot, float sigmaX, float sigmaZ, float dX, float dZ); + void setNCommonImpl(unsigned int ncom, TopoFreq& tfreq, TopoStat& tstat, unsigned int& ncommon, unsigned int ntot); + void setThresholdImpl(double thr, TopoFreq& tfreq, TopoInfo& tinfo, TopoStat& tstat, unsigned int& ncommon, double& freqthres, unsigned int ntot); + void setThresholdCumulativeImpl(double cumulative, TopoFreq& tfreq, unsigned int& ncommon, double& freqthres, unsigned int ntot); + void groupRareTopologiesImpl(TopoFreq& tfreq, TopoInfo& tinfo, TopoStat& tstat, unsigned int& ncommon, double& freqthres, TopologyDictionaryData& data, unsigned int ntot); + + TopologyDictionary mDictionary; ///< Dictionary of topologies + unsigned int mTotClustersIB{0}; + unsigned int mTotClustersOB{0}; + unsigned int mNCommonTopologiesIB{0}; + unsigned int mNCommonTopologiesOB{0}; + double mFrequencyThresholdIB{0.}; + double mFrequencyThresholdOB{0.}; + TopoInfo mMapInfoIB; + TopoInfo mMapInfoOB; + TopoStat mTopologyMapIB; //! IB Temporary map of type + TopoStat mTopologyMapOB; //! OB Temporary map of type + TopoFreq mTopologyFrequencyIB; //! IB , needed to define threshold + TopoFreq mTopologyFrequencyOB; //! OB , needed to define threshold ClassDefNV(BuildTopologyDictionary, 3); }; diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h index 20acf07d4f547..a81db09217e9b 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/Clusterer.h @@ -207,7 +207,7 @@ class Clusterer template static void streamCluster(const std::vector& pixbuf, const std::array* lblBuff, const BBox& bbox, const its3::LookUp& pattIdConverter, - VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isHuge = false); + VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isIB, bool isHuge = false); bool isContinuousReadOut() const { return mContinuousReadout; } void setContinuousReadOut(bool v) { mContinuousReadout = v; } @@ -230,7 +230,7 @@ class Clusterer ///< load the dictionary of cluster topologies void setDictionary(const its3::TopologyDictionary* dict) { - LOGP(info, "Setting TopologyDictionary with size={}", dict->getSize()); + LOGP(info, "Setting TopologyDictionary with IB size={} & OB size={}", dict->getSize(true), dict->getSize(false)); mPattIdConverter.setDictionary(dict); // dict->print(); } @@ -274,7 +274,7 @@ class Clusterer template void Clusterer::streamCluster(const std::vector& pixbuf, const std::array* lblBuff, const Clusterer::BBox& bbox, const its3::LookUp& pattIdConverter, - VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isHuge) + VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isIB, bool isHuge) { if (labelsClusPtr && lblBuff) { // MC labels were requested auto cnt = compClusPtr->size(); @@ -291,10 +291,10 @@ void Clusterer::streamCluster(const std::vector& pixbuf, const std::a int nbits = ir * colSpanW + ic; patt[nbits >> 3] |= (0x1 << (7 - (nbits % 8))); } - uint16_t pattID = (isHuge || pattIdConverter.size() == 0) ? CompCluster::InvalidPatternID : pattIdConverter.findGroupID(rowSpanW, colSpanW, patt.data()); + uint16_t pattID = (isHuge || pattIdConverter.size(isIB) == 0) ? CompCluster::InvalidPatternID : pattIdConverter.findGroupID(rowSpanW, colSpanW, isIB, patt.data()); uint16_t row = bbox.rowMin, col = bbox.colMin; LOGP(debug, "PattID: findGroupID({},{},{})={}", row, col, patt[0], pattID); - if (pattID == CompCluster::InvalidPatternID || pattIdConverter.isGroup(pattID)) { + if (pattID == CompCluster::InvalidPatternID || pattIdConverter.isGroup(pattID, isIB)) { if (pattID != CompCluster::InvalidPatternID) { // For groupped topologies, the reference pixel is the COG pixel float xCOG = 0., zCOG = 0.; diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h index 4f865d11c90a9..b9e7fd0f6ec39 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h @@ -30,13 +30,14 @@ template o2::math_utils::Point3D extractClusterData(const itsmft::CompClusterExt& c, iterator& iter, const its3::TopologyDictionary* dict, T& sig2y, T& sig2z) { auto pattID = c.getPatternID(); + auto ib = constants::detID::isDetITS3(c.getSensorID()); // Dummy COG errors (about half pixel size) - sig2y = (constants::detID::isDetITS3(c.getSensorID())) ? DefClusError2Row : o2::its::ioutils::DefClusError2Row; - sig2z = (constants::detID::isDetITS3(c.getSensorID())) ? DefClusError2Col : o2::its::ioutils::DefClusError2Col; + sig2y = (ib) ? DefClusError2Row : o2::its::ioutils::DefClusError2Row; + sig2z = (ib) ? DefClusError2Col : o2::its::ioutils::DefClusError2Col; if (pattID != itsmft::CompCluster::InvalidPatternID) { - sig2y = dict->getErr2X(pattID) * sig2y; // Error is given in detector coordinates - sig2z = dict->getErr2Z(pattID) * sig2z; - if (!dict->isGroup(pattID)) { + sig2y = dict->getErr2X(pattID, ib); + sig2z = dict->getErr2Z(pattID, ib); + if (!dict->isGroup(pattID, ib)) { return dict->getClusterCoordinates(c); } else { o2::itsmft::ClusterPattern patt(iter); @@ -52,13 +53,14 @@ template o2::math_utils::Point3D extractClusterData(const itsmft::CompClusterExt& c, iterator& iter, const its3::TopologyDictionary* dict, T& sig2y, T& sig2z, uint8_t& cls) { auto pattID = c.getPatternID(); + auto ib = constants::detID::isDetITS3(c.getSensorID()); auto iterC = iter; unsigned int clusterSize{999}; - if (pattID == itsmft::CompCluster::InvalidPatternID || dict->isGroup(pattID)) { + if (pattID == itsmft::CompCluster::InvalidPatternID || dict->isGroup(pattID, ib)) { o2::itsmft::ClusterPattern patt(iterC); clusterSize = patt.getNPixels(); } else { - clusterSize = dict->getNpixels(pattID); + clusterSize = dict->getNpixels(pattID, ib); } cls = static_cast(std::clamp(clusterSize, static_cast(std::numeric_limits::min()), static_cast(std::numeric_limits::max()))); return extractClusterData(c, iter, dict, sig2y, sig2z); diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/LookUp.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/LookUp.h index 0fbecb41393ff..809a129a0debf 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/LookUp.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/LookUp.h @@ -21,7 +21,6 @@ #ifndef ALICEO2_ITS3_LOOKUP_H #define ALICEO2_ITS3_LOOKUP_H -#include "DataFormatsITSMFT/ClusterTopology.h" #include "ITS3Reconstruction/TopologyDictionary.h" namespace o2::its3 @@ -32,20 +31,21 @@ class LookUp LookUp() = default; LookUp(std::string fileName); static int groupFinder(int nRow, int nCol); - int findGroupID(int nRow, int nCol, const unsigned char patt[itsmft::ClusterPattern::MaxPatternBytes]) const; - int getTopologiesOverThreshold() const { return mTopologiesOverThreshold; } + int findGroupID(int nRow, int nCol, bool IB, const unsigned char patt[itsmft::ClusterPattern::MaxPatternBytes]) const; + int getTopologiesOverThreshold(bool IB) const { return (IB) ? mTopologiesOverThresholdIB : mTopologiesOverThresholdOB; } void loadDictionary(std::string fileName); void setDictionary(const TopologyDictionary* dict); - bool isGroup(int id) const { return mDictionary.isGroup(id); } - int size() const { return mDictionary.getSize(); } - auto getPattern(int id) const { return mDictionary.getPattern(id); } - auto getDictionaty() const { return mDictionary; } + auto getDictionary() const { return mDictionary; } + bool isGroup(int id, bool IB) const { return mDictionary.isGroup(id, IB); } + int size(bool IB) const { return mDictionary.getSize(IB); } + auto getPattern(int id, bool IB) const { return mDictionary.getPattern(id, IB); } private: - TopologyDictionary mDictionary{}; - int mTopologiesOverThreshold{0}; + TopologyDictionary mDictionary; + int mTopologiesOverThresholdIB{0}; + int mTopologiesOverThresholdOB{0}; - ClassDefNV(LookUp, 2); + ClassDefNV(LookUp, 3); }; } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h index 1a9b4048fd06f..d5f5721170aa7 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TopologyDictionary.h @@ -24,6 +24,18 @@ namespace o2::its3 class BuildTopologyDictionary; class LookUp; +struct TopologyDictionaryData { + static constexpr int STopoSize{(8 * 255) + 1}; + std::array mSmallTopologiesLUT{}; ///< Look-Up Table for the topologies with 1-byte linearised matrix + std::vector mVectorOfIDs; ///< Vector of topologies and groups + std::unordered_map mCommonMap; ///< Map of pair + std::unordered_map mGroupMap; ///< Map of pair + + void print() const noexcept; + + ClassDefNV(TopologyDictionaryData, 1); +}; + class TopologyDictionary { public: @@ -37,86 +49,103 @@ class TopologyDictionary static constexpr int MaxNumberOfRowClasses = 1 + ((itsmft::ClusterPattern::MaxRowSpan - 1) / RowClassSpan); ///< Maximum number of row classes for the groups of rare topologies static constexpr int MaxNumberOfColClasses = 1 + ((itsmft::ClusterPattern::MaxColSpan - 1) / ColClassSpan); ///< Maximum number of col classes for the groups of rare topologies static constexpr int NumberOfRareGroups = MaxNumberOfRowClasses * MaxNumberOfColClasses; ///< Number of entries corresponding to groups of rare topologies (those whos matrix exceed the max number of bytes are empty). + /// Resets internal structures + void reset() noexcept; + void resetMaps(bool IB = true) noexcept; /// Prints the dictionary friend std::ostream& operator<<(std::ostream& os, const its3::TopologyDictionary& dictionary); /// Prints the dictionary in a binary file void writeBinaryFile(const std::string& outputFile); /// Reads the dictionary from a binary file - int readBinaryFile(const std::string& fileName); - - int readFromFile(const std::string& fileName); + void readBinaryFile(const std::string& fileName); + void readFromFile(const std::string& fileName); + void print() const noexcept; /// Returns the x position of the COG for the n_th element - inline float getXCOG(int n) const + [[nodiscard]] float getXCOG(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mXCOG; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mXCOG; } /// Returns the error on the x position of the COG for the n_th element - inline float getErrX(int n) const + [[nodiscard]] float getErrX(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mErrX; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mErrX; } /// Returns the z position of the COG for the n_th element - inline float getZCOG(int n) const + [[nodiscard]] float getZCOG(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mZCOG; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mZCOG; } /// Returns the error on the z position of the COG for the n_th element - inline float getErrZ(int n) const + [[nodiscard]] float getErrZ(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mErrZ; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mErrZ; } /// Returns the error^2 on the x position of the COG for the n_th element - inline float getErr2X(int n) const + [[nodiscard]] float getErr2X(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mErr2X; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mErr2X; } /// Returns the error^2 on the z position of the COG for the n_th element - inline float getErr2Z(int n) const + [[nodiscard]] float getErr2Z(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mErr2Z; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mErr2Z; } /// Returns the hash of the n_th element - inline unsigned long getHash(int n) const + [[nodiscard]] unsigned long getHash(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mHash; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mHash; } /// Returns the number of fired pixels of the n_th element - inline int getNpixels(int n) const + [[nodiscard]] int getNpixels(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mNpixels; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mNpixels; } /// Returns the frequency of the n_th element; - inline double getFrequency(int n) const + [[nodiscard]] double getFrequency(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mFrequency; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mFrequency; } /// Returns true if the element corresponds to a group of rare topologies - inline bool isGroup(int n) const + [[nodiscard]] bool isGroup(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mIsGroup; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mIsGroup; } /// Returns the pattern of the topology - inline const itsmft::ClusterPattern& getPattern(int n) const + [[nodiscard]] const itsmft::ClusterPattern& getPattern(int n, bool IB = true) const { - assert(n >= 0 || n < (int)mVectorOfIDs.size()); - return mVectorOfIDs[n].mPattern; + const auto& data = (IB) ? mDataIB : mDataOB; + assert(n >= 0 || n < (int)data.mVectorOfIDs.size()); + return data.mVectorOfIDs[n].mPattern; } /// Fills a hostogram with the distribution of the IDs - TH1F* getTopologyDistribution(const std::string_view hname = "h_topo_dist") const; + [[nodiscard]] TH1F* getTopologyDistribution(const std::string_view hname, bool IB = true) const; /// Returns the number of elements in the dicionary; - int getSize() const { return (int)mVectorOfIDs.size(); } + [[nodiscard]] int getSize(bool IB) const + { + return static_cast((IB) ? mDataIB.mVectorOfIDs.size() : mDataOB.mVectorOfIDs.size()); + } /// Returns the local position of a compact cluster /// Returns the local position of a compact cluster @@ -133,13 +162,10 @@ class TopologyDictionary friend its3::LookUp; private: - static constexpr int STopoSize{8 * 255 + 1}; - std::unordered_map mCommonMap{}; ///< Map of pair - std::unordered_map mGroupMap{}; ///< Map of pair - int mSmallTopologiesLUT[STopoSize]{}; ///< Look-Up Table for the topologies with 1-byte linearised matrix - std::vector mVectorOfIDs{}; ///< Vector of topologies and groups + TopologyDictionaryData mDataIB; + TopologyDictionaryData mDataOB; - ClassDefNV(TopologyDictionary, 3); + ClassDefNV(TopologyDictionary, 4); }; } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx index 8667066f91fac..f7eec52f9434a 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx @@ -15,20 +15,34 @@ #include "ITS3Reconstruction/LookUp.h" #include "DataFormatsITSMFT/CompCluster.h" +#include "ITSMFTBase/SegmentationAlpide.h" +#include "ITS3Base/SegmentationMosaix.h" + #include "TFile.h" ClassImp(o2::its3::BuildTopologyDictionary); namespace o2::its3 { -void BuildTopologyDictionary::accountTopology(const itsmft::ClusterTopology& cluster, float dX, float dZ) +void BuildTopologyDictionary::accountTopology(const itsmft::ClusterTopology& cluster, bool IB, float dX, float dZ) { - mTotClusters++; + accountTopologyImpl(cluster, + ((IB) ? mMapInfoIB : mMapInfoOB), + ((IB) ? mTopologyMapIB : mTopologyMapOB), + ((IB) ? mTotClustersIB : mTotClustersOB), + ((IB) ? SegmentationMosaix::PitchRow : itsmft::SegmentationAlpide::PitchRow), + ((IB) ? SegmentationMosaix::PitchCol : itsmft::SegmentationAlpide::PitchCol), + dX, dZ); +} + +void BuildTopologyDictionary::accountTopologyImpl(const itsmft::ClusterTopology& cluster, TopoInfo& tinfo, TopoStat& tstat, unsigned int& tot, float sigmaX, float sigmaZ, float dX, float dZ) +{ + ++tot; bool useDf = dX < IgnoreVal / 2; // we may need to account the frequency but to not update the centroid // std::pair::iterator,bool> ret; // auto ret = mTopologyMap.insert(std::make_pair(cluster.getHash(), std::make_pair(cluster, 1))); - auto& topoStat = mTopologyMap[cluster.getHash()]; + auto& topoStat = tstat[cluster.getHash()]; topoStat.countsTotal++; if (topoStat.countsTotal == 1) { // a new topology is inserted topoStat.topology = cluster; @@ -44,14 +58,14 @@ void BuildTopologyDictionary::accountTopology(const itsmft::ClusterTopology& clu topInf.mZmean = dZ; topoStat.countsWithBias = 1; } else { // assign expected sigmas from the pixel X, Z sizes - topInf.mXsigma2 = 1.f / 12.f / (float)std::min(10, topInf.mSizeX); - topInf.mZsigma2 = 1.f / 12.f / (float)std::min(10, topInf.mSizeZ); + topInf.mXsigma2 = sigmaX * sigmaX / 12.f / (float)std::min(10, topInf.mSizeX); + topInf.mZsigma2 = sigmaZ * sigmaZ / (float)std::min(10, topInf.mSizeZ); } - mMapInfo.emplace(cluster.getHash(), topInf); + tinfo.emplace(cluster.getHash(), topInf); } else { if (useDf) { auto num = topoStat.countsWithBias++; - auto ind = mMapInfo.find(cluster.getHash()); + auto ind = tinfo.find(cluster.getHash()); float tmpxMean = ind->second.mXmean; float newxMean = ind->second.mXmean = ((tmpxMean)*num + dX) / (num + 1); float tmpxSigma2 = ind->second.mXsigma2; @@ -64,101 +78,135 @@ void BuildTopologyDictionary::accountTopology(const itsmft::ClusterTopology& clu } } -void BuildTopologyDictionary::setThreshold(double thr) +void BuildTopologyDictionary::setNCommon(unsigned int nCommon, bool IB) +{ + mDictionary.resetMaps(IB); + + auto& freqTopo = ((IB) ? mTopologyFrequencyIB : mTopologyFrequencyOB); + auto& freqThres = ((IB) ? mFrequencyThresholdIB : mFrequencyThresholdOB); + auto& comTopo = ((IB) ? mNCommonTopologiesIB : mNCommonTopologiesOB); + auto ntot = ((IB) ? mTotClustersIB : mTotClustersOB); + + setNCommonImpl(nCommon, + freqTopo, + ((IB) ? mTopologyMapIB : mTopologyMapOB), + comTopo, + ntot); + // Recaculate also the threshold + freqThres = ((double)freqTopo[comTopo - 1].first) / ntot; +} + +void BuildTopologyDictionary::setNCommonImpl(unsigned int ncom, TopoFreq& tfreq, TopoStat& tstat, unsigned int& ncommon, unsigned int ntot) { - mTopologyFrequency.clear(); - for (auto&& p : mTopologyMap) { // p is pair - mTopologyFrequency.emplace_back(p.second.countsTotal, p.first); + if (ncom >= itsmft::CompCluster::InvalidPatternID) { + LOGP(warning, "Redefining nCommon from {} to {} to be below InvalidPatternID", ncom, itsmft::CompCluster::InvalidPatternID - 1); + ncom = itsmft::CompCluster::InvalidPatternID - 1; + } + tfreq.clear(); + for (auto&& p : tstat) { // p os pair + tfreq.emplace_back(p.second.countsTotal, p.first); } - std::sort(mTopologyFrequency.begin(), mTopologyFrequency.end(), + std::sort(tfreq.begin(), tfreq.end(), [](const std::pair& couple1, const std::pair& couple2) { return (couple1.first > couple2.first); }); - mNCommonTopologies = 0; - mDictionary.mCommonMap.clear(); - mDictionary.mGroupMap.clear(); - mFrequencyThreshold = thr; - for (auto& q : mTopologyFrequency) { - if (((double)q.first) / mTotClusters > thr) { - mNCommonTopologies++; + ncommon = ncom; +} + +void BuildTopologyDictionary::setThreshold(double thr, bool IB) +{ + mDictionary.resetMaps(IB); + setThresholdImpl(thr, + ((IB) ? mTopologyFrequencyIB : mTopologyFrequencyOB), + ((IB) ? mMapInfoIB : mMapInfoOB), + ((IB) ? mTopologyMapIB : mTopologyMapOB), + ((IB) ? mNCommonTopologiesIB : mNCommonTopologiesOB), + ((IB) ? mFrequencyThresholdIB : mFrequencyThresholdOB), + ((IB) ? mTotClustersIB : mTotClustersOB)); +} + +void BuildTopologyDictionary::setThresholdImpl(double thr, TopoFreq& tfreq, TopoInfo& tinfo, TopoStat& tstat, unsigned int& ncommon, double& freqthres, unsigned int ntot) +{ + setNCommonImpl(0, tfreq, tstat, ncommon, ntot); + freqthres = thr; + for (auto& q : tfreq) { + if (((double)q.first) / ntot > thr) { + ++ncommon; } else { break; } } - if (mNCommonTopologies >= itsmft::CompCluster::InvalidPatternID) { - mFrequencyThreshold = ((double)mTopologyFrequency[itsmft::CompCluster::InvalidPatternID - 1].first) / mTotClusters; - LOGP(warning, "Redefining prob. threshould from {} to {} to be below InvalidPatternID (was {})", thr, mFrequencyThreshold, mNCommonTopologies); - mNCommonTopologies = itsmft::CompCluster::InvalidPatternID - 1; + if (ncommon >= itsmft::CompCluster::InvalidPatternID) { + freqthres = ((double)tfreq[itsmft::CompCluster::InvalidPatternID - 1].first) / ntot; + LOGP(warning, "Redefining prob. threshold from {} to {} to be below InvalidPatternID (was {})", thr, freqthres, ntot); + ncommon = itsmft::CompCluster::InvalidPatternID - 1; } } -void BuildTopologyDictionary::setNCommon(unsigned int nCommon) +void BuildTopologyDictionary::setThresholdCumulative(double cumulative, bool IB) { - if (nCommon >= itsmft::CompCluster::InvalidPatternID) { - LOGP(warning, "Redefining nCommon from {} to {} to be below InvalidPatternID", nCommon, itsmft::CompCluster::InvalidPatternID - 1); - nCommon = itsmft::CompCluster::InvalidPatternID - 1; - } - mTopologyFrequency.clear(); - for (auto&& p : mTopologyMap) { // p os pair - mTopologyFrequency.emplace_back(p.second.countsTotal, p.first); + if (cumulative <= 0. || cumulative >= 1.) { + cumulative = 0.99; } - std::sort(mTopologyFrequency.begin(), mTopologyFrequency.end(), - [](const std::pair& couple1, - const std::pair& couple2) { return (couple1.first > couple2.first); }); - mNCommonTopologies = nCommon; - mDictionary.mCommonMap.clear(); - mDictionary.mGroupMap.clear(); - mFrequencyThreshold = ((double)mTopologyFrequency[mNCommonTopologies - 1].first) / mTotClusters; + + auto& freqTopo = ((IB) ? mTopologyFrequencyIB : mTopologyFrequencyOB); + auto& freqThres = ((IB) ? mFrequencyThresholdIB : mFrequencyThresholdOB); + auto& statTopo = ((IB) ? mTopologyMapIB : mTopologyMapOB); + auto& comTopo = ((IB) ? mNCommonTopologiesIB : mNCommonTopologiesOB); + auto ntot = ((IB) ? mTotClustersIB : mTotClustersOB); + + mDictionary.resetMaps(IB); + setNCommonImpl(0, freqTopo, statTopo, comTopo, ntot); + setThresholdCumulativeImpl(cumulative, freqTopo, comTopo, freqThres, ntot); } -void BuildTopologyDictionary::setThresholdCumulative(double cumulative) +void BuildTopologyDictionary::setThresholdCumulativeImpl(double cumulative, TopoFreq& tfreq, unsigned int& ncommon, double& freqthres, unsigned int ntot) { - mTopologyFrequency.clear(); - if (cumulative <= 0. || cumulative >= 1.) { - cumulative = 0.99; - } double totFreq = 0.; - for (auto&& p : mTopologyMap) { // p os pair - mTopologyFrequency.emplace_back(p.second.countsTotal, p.first); - } - std::sort(mTopologyFrequency.begin(), mTopologyFrequency.end(), - [](const std::pair& couple1, - const std::pair& couple2) { return (couple1.first > couple2.first); }); - mNCommonTopologies = 0; - mDictionary.mCommonMap.clear(); - mDictionary.mGroupMap.clear(); - for (auto& q : mTopologyFrequency) { - totFreq += ((double)(q.first)) / mTotClusters; + for (auto& q : tfreq) { + totFreq += ((double)(q.first)) / ntot; if (totFreq < cumulative) { - mNCommonTopologies++; - if (mNCommonTopologies >= itsmft::CompCluster::InvalidPatternID) { - totFreq -= ((double)(q.first)) / mTotClusters; - mNCommonTopologies--; + ++ncommon; + if (ncommon >= itsmft::CompCluster::InvalidPatternID) { + totFreq -= ((double)(q.first)) / ntot; + --ncommon; LOGP(warning, "Redefining cumulative threshould from {} to {} to be below InvalidPatternID)", cumulative, totFreq); } } else { break; } } - mFrequencyThreshold = ((double)(mTopologyFrequency[--mNCommonTopologies].first)) / mTotClusters; - while (std::fabs(((double)mTopologyFrequency[mNCommonTopologies].first) / mTotClusters - mFrequencyThreshold) < 1.e-15) { - mNCommonTopologies--; + freqthres = ((double)(tfreq[--ncommon].first)) / ntot; + while (std::fabs(((double)tfreq[ncommon--].first) / ntot - freqthres) < 1.e-15) { } - mFrequencyThreshold = ((double)mTopologyFrequency[mNCommonTopologies++].first) / mTotClusters; + freqthres = ((double)tfreq[ncommon++].first) / ntot; } void BuildTopologyDictionary::groupRareTopologies() { LOG(info) << "Dictionary finalisation"; - LOG(info) << "Number of clusters: " << mTotClusters; + LOG(info) << "Number of IB clusters: " << mTotClustersIB; + LOG(info) << "Number of OB clusters: " << mTotClustersOB; + + groupRareTopologiesImpl(mTopologyFrequencyIB, mMapInfoIB, mTopologyMapIB, mNCommonTopologiesIB, mFrequencyThresholdIB, mDictionary.mDataIB, mNCommonTopologiesIB); + groupRareTopologiesImpl(mTopologyFrequencyOB, mMapInfoOB, mTopologyMapOB, mNCommonTopologiesOB, mFrequencyThresholdOB, mDictionary.mDataOB, mNCommonTopologiesOB); + + LOG(info) << "Dictionay finalised"; + LOG(info) << "IB:"; + mDictionary.mDataIB.print(); + LOG(info) << "OB:"; + mDictionary.mDataOB.print(); +} +void BuildTopologyDictionary::groupRareTopologiesImpl(TopoFreq& tfreq, TopoInfo& tinfo, TopoStat& tstat, unsigned int& ncommon, double& freqthres, TopologyDictionaryData& data, unsigned int ntot) +{ double totFreq = 0.; - for (unsigned int j = 0; j < mNCommonTopologies; j++) { + for (unsigned int j = 0; j < ncommon; j++) { itsmft::GroupStruct gr; - gr.mHash = mTopologyFrequency[j].second; - gr.mFrequency = ((double)(mTopologyFrequency[j].first)) / mTotClusters; + gr.mHash = tfreq[j].second; + gr.mFrequency = ((double)(tfreq[j].first)) / ntot; totFreq += gr.mFrequency; // rough estimation for the error considering a8 uniform distribution - const auto& topo = mMapInfo.find(gr.mHash)->second; + const auto& topo = tinfo.find(gr.mHash)->second; gr.mErrX = std::sqrt(topo.mXsigma2); gr.mErrZ = std::sqrt(topo.mZsigma2); gr.mErr2X = topo.mXsigma2; @@ -168,11 +216,11 @@ void BuildTopologyDictionary::groupRareTopologies() gr.mNpixels = topo.mNpixels; gr.mPattern = topo.mPattern; gr.mIsGroup = false; - mDictionary.mVectorOfIDs.push_back(gr); + data.mVectorOfIDs.push_back(gr); if (j == int(itsmft::CompCluster::InvalidPatternID - 1)) { LOGP(warning, "Limiting N unique topologies to {}, threshold freq. to {}, cumulative freq. to {} to be below InvalidPatternID", j, gr.mFrequency, totFreq); - mNCommonTopologies = j; - mFrequencyThreshold = gr.mFrequency; + ncommon = j; + freqthres = gr.mFrequency; break; } } @@ -192,8 +240,8 @@ void BuildTopologyDictionary::groupRareTopologies() // Create a structure for a group of rare topologies itsmft::GroupStruct gr; gr.mHash = (((unsigned long)(grNum)) << 32) & 0xffffffff00000000; - gr.mErrX = its3::TopologyDictionary::RowClassSpan / std::sqrt(12 * std::min(10, rowBinEdge)); - gr.mErrZ = its3::TopologyDictionary::ColClassSpan / std::sqrt(12 * std::min(10, colBinEdge)); + gr.mErrX = its3::TopologyDictionary::RowClassSpan / std::sqrt(12.f * (float)std::min(10, rowBinEdge)); + gr.mErrZ = its3::TopologyDictionary::ColClassSpan / std::sqrt(12.f * (float)std::min(10, colBinEdge)); gr.mErr2X = gr.mErrX * gr.mErrX; gr.mErr2Z = gr.mErrZ * gr.mErrZ; gr.mXCOG = 0; @@ -227,58 +275,65 @@ void BuildTopologyDictionary::groupRareTopologies() int rs{}, cs{}, index{}; // Updating the counts for the groups of rare topologies - for (auto j{mNCommonTopologies}; j < mTopologyFrequency.size(); j++) { - unsigned long hash1 = mTopologyFrequency[j].second; - rs = mTopologyMap.find(hash1)->second.topology.getRowSpan(); - cs = mTopologyMap.find(hash1)->second.topology.getColumnSpan(); + for (auto j{ncommon}; j < tfreq.size(); j++) { + unsigned long hash1 = tfreq[j].second; + rs = tstat.find(hash1)->second.topology.getRowSpan(); + cs = tstat.find(hash1)->second.topology.getColumnSpan(); index = its3::LookUp::groupFinder(rs, cs); - tmp_GroupMap[index].second += mTopologyFrequency[j].first; + tmp_GroupMap[index].second += tfreq[j].first; } for (auto&& p : tmp_GroupMap) { itsmft::GroupStruct& group = p.second.first; - group.mFrequency = ((double)p.second.second) / mTotClusters; - mDictionary.mVectorOfIDs.push_back(group); + group.mFrequency = ((double)p.second.second) / ntot; + data.mVectorOfIDs.push_back(group); } // Sorting the dictionary preserving all unique topologies - std::sort(mDictionary.mVectorOfIDs.begin(), mDictionary.mVectorOfIDs.end(), [](const itsmft::GroupStruct& a, const itsmft::GroupStruct& b) { + std::sort(data.mVectorOfIDs.begin(), data.mVectorOfIDs.end(), [](const itsmft::GroupStruct& a, const itsmft::GroupStruct& b) { return (!a.mIsGroup) && b.mIsGroup ? true : (a.mIsGroup && (!b.mIsGroup) ? false : (a.mFrequency > b.mFrequency)); }); - if (mDictionary.mVectorOfIDs.size() >= itsmft::CompCluster::InvalidPatternID - 1) { + if (data.mVectorOfIDs.size() >= itsmft::CompCluster::InvalidPatternID - 1) { LOGP(warning, "Max allowed {} patterns is reached, stopping", itsmft::CompCluster::InvalidPatternID - 1); - mDictionary.mVectorOfIDs.resize(itsmft::CompCluster::InvalidPatternID - 1); + data.mVectorOfIDs.resize(itsmft::CompCluster::InvalidPatternID - 1); } // Sorting the dictionary to final form - std::sort(mDictionary.mVectorOfIDs.begin(), mDictionary.mVectorOfIDs.end(), [](const itsmft::GroupStruct& a, const itsmft::GroupStruct& b) { return a.mFrequency > b.mFrequency; }); + std::sort(data.mVectorOfIDs.begin(), data.mVectorOfIDs.end(), [](const itsmft::GroupStruct& a, const itsmft::GroupStruct& b) { return a.mFrequency > b.mFrequency; }); // Creating the map for common topologies - for (int iKey = 0; iKey < mDictionary.getSize(); iKey++) { - itsmft::GroupStruct& gr = mDictionary.mVectorOfIDs[iKey]; + for (int iKey = 0; iKey < data.mVectorOfIDs.size(); iKey++) { + itsmft::GroupStruct& gr = data.mVectorOfIDs[iKey]; if (!gr.mIsGroup) { - mDictionary.mCommonMap.emplace(gr.mHash, iKey); + data.mCommonMap.emplace(gr.mHash, iKey); if (gr.mPattern.getUsedBytes() == 1) { - mDictionary.mSmallTopologiesLUT[(gr.mPattern.getColumnSpan() - 1) * 255 + (int)gr.mPattern.getByte(2)] = iKey; + data.mSmallTopologiesLUT[(gr.mPattern.getColumnSpan() - 1) * 255 + (int)gr.mPattern.getByte(2)] = iKey; } } else { - mDictionary.mGroupMap.emplace((int)(gr.mHash >> 32) & 0x00000000ffffffff, iKey); + data.mGroupMap.emplace((int)(gr.mHash >> 32) & 0x00000000ffffffff, iKey); } } - LOG(info) << "Dictionay finalised"; - LOG(info) << "Number of keys: " << mDictionary.getSize(); - LOG(info) << "Number of common topologies: " << mDictionary.mCommonMap.size(); - LOG(info) << "Number of groups of rare topologies: " << mDictionary.mGroupMap.size(); } std::ostream& operator<<(std::ostream& os, const BuildTopologyDictionary& DB) { - for (unsigned int i = 0; i < DB.mNCommonTopologies; i++) { - const unsigned long& hash = DB.mTopologyFrequency[i].second; + os << "--- InnerBarrel\n"; + for (unsigned int i = 0; i < DB.mNCommonTopologiesIB; i++) { + const unsigned long& hash = DB.mTopologyFrequencyIB[i].second; + os << "Hash: " << hash << '\n'; + os << "counts: " << DB.mTopologyMapIB.find(hash)->second.countsTotal; + os << " (with bias provided: " << DB.mTopologyMapIB.find(hash)->second.countsWithBias << ")" << '\n'; + os << "sigmaX: " << std::sqrt(DB.mMapInfoIB.find(hash)->second.mXsigma2) << '\n'; + os << "sigmaZ: " << std::sqrt(DB.mMapInfoIB.find(hash)->second.mZsigma2) << '\n'; + os << DB.mTopologyMapIB.find(hash)->second.topology; + } + os << "--- OuterBarrel\n"; + for (unsigned int i = 0; i < DB.mNCommonTopologiesOB; i++) { + const unsigned long& hash = DB.mTopologyFrequencyOB[i].second; os << "Hash: " << hash << '\n'; - os << "counts: " << DB.mTopologyMap.find(hash)->second.countsTotal; - os << " (with bias provided: " << DB.mTopologyMap.find(hash)->second.countsWithBias << ")" << '\n'; - os << "sigmaX: " << std::sqrt(DB.mMapInfo.find(hash)->second.mXsigma2) << '\n'; - os << "sigmaZ: " << std::sqrt(DB.mMapInfo.find(hash)->second.mZsigma2) << '\n'; - os << DB.mTopologyMap.find(hash)->second.topology; + os << "counts: " << DB.mTopologyMapOB.find(hash)->second.countsTotal; + os << " (with bias provided: " << DB.mTopologyMapOB.find(hash)->second.countsWithBias << ")" << '\n'; + os << "sigmaX: " << std::sqrt(DB.mMapInfoOB.find(hash)->second.mXsigma2) << '\n'; + os << "sigmaZ: " << std::sqrt(DB.mMapInfoOB.find(hash)->second.mZsigma2) << '\n'; + os << DB.mTopologyMapOB.find(hash)->second.topology; } return os; } diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx index d59a4859b9990..bce17b3759340 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx @@ -14,7 +14,6 @@ #include -#include "Framework/Logger.h" #include "ITS3Reconstruction/Clusterer.h" #include "ITS3Base/SegmentationMosaix.h" #include "SimulationDataFormat/MCTruthContainer.h" @@ -252,7 +251,7 @@ void Clusterer::ClustererThread::finishChip(ChipPixelData* curChipData, CompClus preClusterIndices[i2] = -1; } if (bbox.isAcceptableSize()) { - parent->streamCluster(pixArrBuff, &labelsBuff, bbox, parent->mPattIdConverter, compClusPtr, patternsPtr, labelsClusPtr, nlab); + parent->streamCluster(pixArrBuff, &labelsBuff, bbox, parent->mPattIdConverter, compClusPtr, patternsPtr, labelsClusPtr, nlab, constants::detID::isDetITS3(curChipData->getChipID())); } else { auto warnLeft = MaxHugeClusWarn - parent->mNHugeClus; if (warnLeft > 0) { @@ -278,7 +277,7 @@ void Clusterer::ClustererThread::finishChip(ChipPixelData* curChipData, CompClus } } if (!pixbuf.empty()) { // Stream a piece of cluster only if the reduced bounding box is not empty - parent->streamCluster(pixbuf, &labelsBuff, bboxT, parent->mPattIdConverter, compClusPtr, patternsPtr, labelsClusPtr, nlab, true); + parent->streamCluster(pixbuf, &labelsBuff, bboxT, parent->mPattIdConverter, compClusPtr, patternsPtr, labelsClusPtr, nlab, constants::detID::isDetITS3(curChipData->getChipID()), true); pixbuf.clear(); } bboxT.rowMin = bboxT.rowMax + 1; @@ -305,10 +304,12 @@ void Clusterer::ClustererThread::finishChipSingleHitFast(uint32_t hit, ChipPixel } } + auto ib = constants::detID::isDetITS3(curChipData->getChipID()); + // add to compact clusters, which must be always filled unsigned char patt[ClusterPattern::MaxPatternBytes]{0x1 << (7 - (0 % 8))}; // unrolled 1 hit version of full loop in finishChip - uint16_t pattID = (parent->mPattIdConverter.size() == 0) ? CompCluster::InvalidPatternID : parent->mPattIdConverter.findGroupID(1, 1, patt); - if ((pattID == CompCluster::InvalidPatternID || parent->mPattIdConverter.isGroup(pattID)) && patternsPtr) { + uint16_t pattID = (parent->mPattIdConverter.size(ib) == 0) ? CompCluster::InvalidPatternID : parent->mPattIdConverter.findGroupID(1, 1, ib, patt); + if ((pattID == CompCluster::InvalidPatternID || parent->mPattIdConverter.isGroup(pattID, ib)) && patternsPtr) { patternsPtr->emplace_back(1); // rowspan patternsPtr->emplace_back(1); // colspan patternsPtr->insert(patternsPtr->end(), std::begin(patt), std::begin(patt) + 1); diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/ITS3ReconstructionLinkDef.h b/Detectors/Upgrades/ITS3/reconstruction/src/ITS3ReconstructionLinkDef.h index f19a7fcaba9ca..2ebd89970d9a1 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/ITS3ReconstructionLinkDef.h +++ b/Detectors/Upgrades/ITS3/reconstruction/src/ITS3ReconstructionLinkDef.h @@ -16,6 +16,7 @@ #pragma link off all functions; #pragma link C++ class o2::its3::Clusterer + ; +#pragma link C++ class o2::its3::TopologyDictionaryData + ; #pragma link C++ class o2::its3::TopologyDictionary + ; #pragma link C++ class o2::its3::BuildTopologyDictionary + ; #pragma link C++ class o2::its3::LookUp + ; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/LookUp.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/LookUp.cxx index caabfa6f2decb..e137e091dc631 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/LookUp.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/LookUp.cxx @@ -31,7 +31,8 @@ LookUp::LookUp(std::string fileName) void LookUp::loadDictionary(std::string fileName) { mDictionary.readFromFile(fileName); - mTopologiesOverThreshold = mDictionary.mCommonMap.size(); + mTopologiesOverThresholdIB = mDictionary.mDataIB.mCommonMap.size(); + mTopologiesOverThresholdOB = mDictionary.mDataOB.mCommonMap.size(); } void LookUp::setDictionary(const its3::TopologyDictionary* dict) @@ -39,7 +40,8 @@ void LookUp::setDictionary(const its3::TopologyDictionary* dict) if (dict != nullptr) { mDictionary = *dict; } - mTopologiesOverThreshold = mDictionary.mCommonMap.size(); + mTopologiesOverThresholdIB = mDictionary.mDataIB.mCommonMap.size(); + mTopologiesOverThresholdOB = mDictionary.mDataOB.mCommonMap.size(); } int LookUp::groupFinder(int nRow, int nCol) @@ -61,25 +63,26 @@ int LookUp::groupFinder(int nRow, int nCol) return grNum; } -int LookUp::findGroupID(int nRow, int nCol, const unsigned char patt[itsmft::ClusterPattern::MaxPatternBytes]) const +int LookUp::findGroupID(int nRow, int nCol, bool IB, const unsigned char patt[itsmft::ClusterPattern::MaxPatternBytes]) const { + const auto& data = (IB) ? mDictionary.mDataIB : mDictionary.mDataOB; int nBits = nRow * nCol; if (nBits < 9) { // Small unique topology - int ID = mDictionary.mSmallTopologiesLUT[(nCol - 1) * 255 + (int)patt[0]]; + int ID = data.mSmallTopologiesLUT[(nCol - 1) * 255 + (int)patt[0]]; if (ID >= 0) { return ID; } } else { // Big unique topology unsigned long hash = itsmft::ClusterTopology::getCompleteHash(nRow, nCol, patt); - auto ret = mDictionary.mCommonMap.find(hash); - if (ret != mDictionary.mCommonMap.end()) { + auto ret = data.mCommonMap.find(hash); + if (ret != data.mCommonMap.end()) { return ret->second; } } - if (!mDictionary.mGroupMap.empty()) { // rare valid topology group + if (!data.mGroupMap.empty()) { // rare valid topology group int index = groupFinder(nRow, nCol); - auto res = mDictionary.mGroupMap.find(index); - return res == mDictionary.mGroupMap.end() ? itsmft::CompCluster::InvalidPatternID : res->second; + auto res = data.mGroupMap.find(index); + return res == data.mGroupMap.end() ? itsmft::CompCluster::InvalidPatternID : res->second; } return itsmft::CompCluster::InvalidPatternID; } diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx index e64f63071c837..61ab051ffb565 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TopologyDictionary.cxx @@ -23,9 +23,16 @@ ClassImp(o2::its3::TopologyDictionary); namespace o2::its3 { +void TopologyDictionaryData::print() const noexcept +{ + LOG(info) << "Number of keys: " << mVectorOfIDs.size(); + LOG(info) << "Number of common topologies: " << mCommonMap.size(); + LOG(info) << "Number of groups of rare topologies: " << mGroupMap.size(); +} + TopologyDictionary::TopologyDictionary() { - memset(mSmallTopologiesLUT, -1, STopoSize * sizeof(int)); + reset(); } TopologyDictionary::TopologyDictionary(const std::string& fileName) @@ -33,10 +40,43 @@ TopologyDictionary::TopologyDictionary(const std::string& fileName) readFromFile(fileName); } +void TopologyDictionary::print() const noexcept +{ + LOG(info) << "ITS3 TopologyDictionary"; + LOG(info) << "InnerBarrel"; + mDataIB.print(); + LOG(info) << "OuterBarrel"; + mDataOB.print(); +} + +void TopologyDictionary::reset() noexcept +{ + mDataIB.mSmallTopologiesLUT.fill(-1); + mDataOB.mSmallTopologiesLUT.fill(-1); + mDataIB.mVectorOfIDs.clear(); + mDataOB.mVectorOfIDs.clear(); +} + +void TopologyDictionary::resetMaps(bool IB) noexcept +{ + auto& data = (IB) ? mDataIB : mDataOB; + data.mCommonMap.clear(); + data.mGroupMap.clear(); +} + std::ostream& operator<<(std::ostream& os, const its3::TopologyDictionary& dict) { int ID = 0; - for (auto& p : dict.mVectorOfIDs) { + os << "--- InnerBarrel:\n"; + for (auto& p : dict.mDataIB.mVectorOfIDs) { + os << "ID: " << ID++ << " Hash: " << p.mHash << " ErrX: " << p.mErrX << " ErrZ : " << p.mErrZ << " xCOG: " << p.mXCOG << " zCOG: " << p.mZCOG << " Npixles: " << p.mNpixels << " Frequency: " << p.mFrequency << " isGroup : " << std::boolalpha << p.mIsGroup << '\n' + << p.mPattern << '\n' + << "*********************************************************" << '\n' + << '\n'; + } + ID = 0; + os << "--- OuterBarrel:\n"; + for (auto& p : dict.mDataOB.mVectorOfIDs) { os << "ID: " << ID++ << " Hash: " << p.mHash << " ErrX: " << p.mErrX << " ErrZ : " << p.mErrZ << " xCOG: " << p.mXCOG << " zCOG: " << p.mZCOG << " Npixles: " << p.mNpixels << " Frequency: " << p.mFrequency << " isGroup : " << std::boolalpha << p.mIsGroup << '\n' << p.mPattern << '\n' << "*********************************************************" << '\n' @@ -48,24 +88,36 @@ std::ostream& operator<<(std::ostream& os, const its3::TopologyDictionary& dict) void TopologyDictionary::writeBinaryFile(const std::string& outputfile) { std::ofstream file_output(outputfile, std::ios::out | std::ios::binary); - for (auto& p : mVectorOfIDs) { - file_output.write(reinterpret_cast(&p.mHash), sizeof(unsigned long)); - file_output.write(reinterpret_cast(&p.mErrX), sizeof(float)); - file_output.write(reinterpret_cast(&p.mErrZ), sizeof(float)); - file_output.write(reinterpret_cast(&p.mErr2X), sizeof(float)); - file_output.write(reinterpret_cast(&p.mErr2Z), sizeof(float)); - file_output.write(reinterpret_cast(&p.mXCOG), sizeof(float)); - file_output.write(reinterpret_cast(&p.mZCOG), sizeof(float)); - file_output.write(reinterpret_cast(&p.mNpixels), sizeof(int)); - file_output.write(reinterpret_cast(&p.mFrequency), sizeof(double)); - file_output.write(reinterpret_cast(&p.mIsGroup), sizeof(bool)); - file_output.write(const_cast(reinterpret_cast(&p.mPattern.getPattern())), - sizeof(unsigned char) * (itsmft::ClusterPattern::kExtendedPatternBytes)); + if (!file_output) { + throw std::runtime_error(fmt::format("Cannot open output file %s!", outputfile)); } + + auto writeData = [](auto& file_output, auto& data) { + auto size = data.mVectorOfIDs.size(); + file_output.write(reinterpret_cast(&size), sizeof(size)); + for (auto& p : data.mVectorOfIDs) { + file_output.write(reinterpret_cast(&p.mHash), sizeof(unsigned long)); + file_output.write(reinterpret_cast(&p.mErrX), sizeof(float)); + file_output.write(reinterpret_cast(&p.mErrZ), sizeof(float)); + file_output.write(reinterpret_cast(&p.mErr2X), sizeof(float)); + file_output.write(reinterpret_cast(&p.mErr2Z), sizeof(float)); + file_output.write(reinterpret_cast(&p.mXCOG), sizeof(float)); + file_output.write(reinterpret_cast(&p.mZCOG), sizeof(float)); + file_output.write(reinterpret_cast(&p.mNpixels), sizeof(int)); + file_output.write(reinterpret_cast(&p.mFrequency), sizeof(double)); + file_output.write(reinterpret_cast(&p.mIsGroup), sizeof(bool)); + file_output.write(const_cast(reinterpret_cast(&p.mPattern.getPattern())), + sizeof(unsigned char) * (itsmft::ClusterPattern::kExtendedPatternBytes)); + } + }; + + writeData(file_output, mDataIB); + writeData(file_output, mDataOB); + file_output.close(); } -int TopologyDictionary::readFromFile(const std::string& fname) +void TopologyDictionary::readFromFile(const std::string& fname) { LOGP(info, "Reading TopologyDictionary from File '{}'", fname); if (o2::utils::Str::endsWith(fname, ".root")) { @@ -76,59 +128,63 @@ int TopologyDictionary::readFromFile(const std::string& fname) } else { throw std::runtime_error(fmt::format("Unrecognized format {}", fname)); } - return 0; } -int TopologyDictionary::readBinaryFile(const std::string& fname) +void TopologyDictionary::readBinaryFile(const std::string& fname) { - mVectorOfIDs.clear(); - mCommonMap.clear(); - for (auto& p : mSmallTopologiesLUT) { - p = -1; - } + reset(); + std::ifstream in(fname.data(), std::ios::in | std::ios::binary); - itsmft::GroupStruct gr; - int groupID = 0; if (!in.is_open()) { LOG(error) << "The file " << fname << " coud not be opened"; throw std::runtime_error("The file coud not be opened"); } else { - while (in.read(reinterpret_cast(&gr.mHash), sizeof(unsigned long))) { - in.read(reinterpret_cast(&gr.mErrX), sizeof(float)); - in.read(reinterpret_cast(&gr.mErrZ), sizeof(float)); - in.read(reinterpret_cast(&gr.mErr2X), sizeof(float)); - in.read(reinterpret_cast(&gr.mErr2Z), sizeof(float)); - in.read(reinterpret_cast(&gr.mXCOG), sizeof(float)); - in.read(reinterpret_cast(&gr.mZCOG), sizeof(float)); - in.read(reinterpret_cast(&gr.mNpixels), sizeof(int)); - in.read(reinterpret_cast(&gr.mFrequency), sizeof(double)); - in.read(reinterpret_cast(&gr.mIsGroup), sizeof(bool)); - in.read(const_cast(reinterpret_cast(&gr.mPattern.getPattern())), sizeof(unsigned char) * (itsmft::ClusterPattern::kExtendedPatternBytes)); - mVectorOfIDs.push_back(gr); - if (!gr.mIsGroup) { - mCommonMap.insert(std::make_pair(gr.mHash, groupID)); - if (gr.mPattern.getUsedBytes() == 1) { - mSmallTopologiesLUT[(gr.mPattern.getColumnSpan() - 1) * 255 + (int)gr.mPattern.getByte(2)] = groupID; + + auto readData = [](auto& in, auto& data) { + int groupID = 0; + std::size_t size{}, cur{}; + itsmft::GroupStruct gr; + in.read(reinterpret_cast(&size), sizeof(std::size_t)); + while (cur++ != size) { + in.read(reinterpret_cast(&gr.mHash), sizeof(unsigned long)); + in.read(reinterpret_cast(&gr.mErrX), sizeof(float)); + in.read(reinterpret_cast(&gr.mErrZ), sizeof(float)); + in.read(reinterpret_cast(&gr.mErr2X), sizeof(float)); + in.read(reinterpret_cast(&gr.mErr2Z), sizeof(float)); + in.read(reinterpret_cast(&gr.mXCOG), sizeof(float)); + in.read(reinterpret_cast(&gr.mZCOG), sizeof(float)); + in.read(reinterpret_cast(&gr.mNpixels), sizeof(int)); + in.read(reinterpret_cast(&gr.mFrequency), sizeof(double)); + in.read(reinterpret_cast(&gr.mIsGroup), sizeof(bool)); + in.read(const_cast(reinterpret_cast(&gr.mPattern.getPattern())), sizeof(unsigned char) * (itsmft::ClusterPattern::kExtendedPatternBytes)); + data.mVectorOfIDs.push_back(gr); + if (!gr.mIsGroup) { + data.mCommonMap.insert(std::make_pair(gr.mHash, groupID)); + if (gr.mPattern.getUsedBytes() == 1) { + data.mSmallTopologiesLUT[(gr.mPattern.getColumnSpan() - 1) * 255 + (int)gr.mPattern.getByte(2)] = groupID; + } + } else { + data.mGroupMap.insert(std::make_pair((int)(gr.mHash >> 32) & 0x00000000ffffffff, groupID)); } - } else { - mGroupMap.insert(std::make_pair((int)(gr.mHash >> 32) & 0x00000000ffffffff, groupID)); + groupID++; } - groupID++; - } + }; + + readData(in, mDataIB); + readData(in, mDataOB); } in.close(); - return 0; } -TH1F* TopologyDictionary::getTopologyDistribution(const std::string_view hname) const +TH1F* TopologyDictionary::getTopologyDistribution(const std::string_view hname, bool IB) const { - int dictSize = getSize(); - auto* histo = new TH1F(hname.data(), ";Topology ID;Frequency", dictSize, -0.5, dictSize - 0.5); + int dictSize = getSize(IB); + auto* histo = new TH1F(hname.data(), Form("%s;Topology ID;Frequency", (IB) ? "InnerBarrel" : "OuterBarrel"), dictSize, -0.5, dictSize - 0.5); histo->SetFillColor(kRed); histo->SetFillStyle(3005); histo->SetDrawOption("histo"); for (int i = 0; i < dictSize; i++) { - histo->Fill(i, getFrequency(i)); + histo->Fill(i, getFrequency(i, IB)); } return histo; } @@ -140,13 +196,13 @@ math_utils::Point3D TopologyDictionary::getClusterCoordinates(const itsmft::C math_utils::Point3D locCl; if (!its3::constants::detID::isDetITS3(cl.getSensorID())) { 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); + locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID(), false) * itsmft::SegmentationAlpide::PitchRow); + locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID(), false) * itsmft::SegmentationAlpide::PitchCol); } else { auto layer = its3::constants::detID::getDetID2Layer(cl.getSensorID()); mIBSegmentations[layer].detectorToLocalUnchecked(cl.getRow(), cl.getCol(), locCl); - locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID()) * its3::SegmentationMosaix::PitchRow); - locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID()) * its3::SegmentationMosaix::PitchCol); + locCl.SetX(locCl.X() + this->getXCOG(cl.getPatternID(), true) * its3::SegmentationMosaix::PitchRow); + locCl.SetZ(locCl.Z() + this->getZCOG(cl.getPatternID(), true) * its3::SegmentationMosaix::PitchCol); float xCurved{0.f}, yCurved{0.f}; mIBSegmentations[layer].flatToCurved(locCl.X(), locCl.Y(), xCurved, yCurved); locCl.SetXYZ(xCurved, yCurved, locCl.Z()); From ea84cf6a5e1a05f0c4ab029a50d5cd5af265c975 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 2 Apr 2025 14:28:44 +0200 Subject: [PATCH 34/34] ITS3: add opt. sanitizer --- Detectors/Upgrades/ITS3/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ITS3/CMakeLists.txt b/Detectors/Upgrades/ITS3/CMakeLists.txt index 7cbb5cffe4243..73ad4b9d53e37 100644 --- a/Detectors/Upgrades/ITS3/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/CMakeLists.txt @@ -9,7 +9,8 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -#add_compile_options(-O0 -g -fPIC) +#add_compile_options(-O0 -g -fPIC -fsanitize=address) +#add_link_options(-fsanitize=address) add_subdirectory(data) add_subdirectory(simulation)