From 31d17955664e6c854d1f329dd00d563a5d19a3e5 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Mon, 6 Oct 2025 18:42:08 +0200 Subject: [PATCH 01/37] First commit to refine layer segmentation --- .../Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h | 2 ++ .../ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h | 1 + Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index a1e4b9321130f..ed9a5f8df86b5 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -46,8 +46,10 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static const char* getTRKPetalDiskPattern() { return sPetalDiskName.c_str(); } static const char* getTRKPetalLayerPattern() { return sPetalLayerName.c_str(); } static const char* getTRKStavePattern() { return sStaveName.c_str(); } + static const char* getTRKModulePattern() { return sModuleName.c_str(); } static const char* getTRKChipPattern() { return sChipName.c_str(); } static const char* getTRKSensorPattern() { return sSensorName.c_str(); } + static const char* getTRKWrapVolPattern() { return sWrapperVolumeName.c_str(); } int getNumberOfChips() const { return mSize; } diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index ba894f6d7a92b..a3fdba2fb4599 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -41,6 +41,7 @@ class TRKLayer TGeoVolume* createSensor(std::string type, double width = -1); TGeoVolume* createChip(std::string type, double width = -1); + TGeoVolume* createModule(std::string type, double width = -1); TGeoVolume* createStave(std::string type, double width = -1); void createLayer(TGeoVolume* motherVolume); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index a95418afbba25..23ce91cec0904 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -94,6 +94,10 @@ TGeoVolume* TRKLayer::createChip(std::string type, double width) return chipVol; } +TGeoVolume* TRKLayer::createModule(std::string type, double width) +{ +} + TGeoVolume* TRKLayer::createStave(std::string type, double width) { TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); From fa6ab076929ca0490cc0808c0100815f4005f87e Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Mon, 6 Oct 2025 19:33:48 +0200 Subject: [PATCH 02/37] Added sModuleName --- .../Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h | 4 +++- Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index ed9a5f8df86b5..6f689d4520c88 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -147,9 +147,11 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static std::string sPetalDiskName; static std::string sPetalLayerName; static std::string sStaveName; + static std::string sModuleName; static std::string sChipName; static std::string sSensorName; - static std::string sWrapperVolumeName; ///< Wrapper volume name + + static std::string sWrapperVolumeName; ///< Wrapper volume name, not implemented at the moment Int_t mNumberOfLayersMLOT; ///< number of layers Int_t mNumberOfActivePartsVD; ///< number of layers diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 20088179f4dcc..41de7457c1cbc 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -29,7 +29,9 @@ std::string GeometryTGeo::sPetalDiskName = "DISK"; std::string GeometryTGeo::sPetalLayerName = "LAYER"; std::string GeometryTGeo::sStaveName = "TRKStave"; std::string GeometryTGeo::sChipName = "TRKChip"; +std::string GeometryTGeo::sModuleName = "TRKModule"; std::string GeometryTGeo::sSensorName = "TRKSensor"; + std::string GeometryTGeo::sWrapperVolumeName = "TRKUWrapVol"; ///< Wrapper volume name, not implemented at the moment o2::trk::GeometryTGeo::~GeometryTGeo() From a7618188560a855bd9eb8812c0ccacd1011e2943 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 7 Oct 2025 16:34:44 +0200 Subject: [PATCH 03/37] Added createModule function and adopted in createStave --- .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 2 +- .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 63 +++++++++++++------ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 41de7457c1cbc..cd9aba66ea466 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -28,8 +28,8 @@ std::string GeometryTGeo::sPetalName = "PETALCASE"; std::string GeometryTGeo::sPetalDiskName = "DISK"; std::string GeometryTGeo::sPetalLayerName = "LAYER"; std::string GeometryTGeo::sStaveName = "TRKStave"; -std::string GeometryTGeo::sChipName = "TRKChip"; std::string GeometryTGeo::sModuleName = "TRKModule"; +std::string GeometryTGeo::sChipName = "TRKChip"; std::string GeometryTGeo::sSensorName = "TRKSensor"; std::string GeometryTGeo::sWrapperVolumeName = "TRKUWrapVol"; ///< Wrapper volume name, not implemented at the moment diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 23ce91cec0904..1c1d6513a97ed 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -44,7 +44,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLe TGeoVolume* TRKLayer::createSensor(std::string type, double width) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); - std::string sensName = Form("%s%d", GeometryTGeo::getTRKSensorPattern(), this->mLayerNumber); + std::string sensName = GeometryTGeo::getTRKSensorPattern() + std::to_string(mLayerNumber); TGeoShape* sensor; @@ -68,7 +68,7 @@ TGeoVolume* TRKLayer::createSensor(std::string type, double width) TGeoVolume* TRKLayer::createChip(std::string type, double width) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); - std::string chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber); + std::string chipName = GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber); TGeoShape* chip; TGeoVolume* sensVol; @@ -96,48 +96,73 @@ TGeoVolume* TRKLayer::createChip(std::string type, double width) TGeoVolume* TRKLayer::createModule(std::string type, double width) { + TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); + std::string moduleName = GeometryTGeo::getTRKModulePattern() + std::to_string(mLayerNumber); + + TGeoShape* module; + TGeoVolume* chipVol; + + if (type == "cylinder") { + module = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + chipVol = createChip("cylinder"); + } else if (type == "flat") { + if (width < 0) { + LOGP(fatal, "Attempting to create module with invalid width"); + } + module = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + chipVol = createChip("flat", width); + } else { + LOGP(fatal, "Chip of type '{}' is not implemented", type); + } + + TGeoVolume* moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); + LOGP(info, "Inserting {} in {} ", chipVol->GetName(), moduleVol->GetName()); + moduleVol->AddNode(chipVol, 1, nullptr); + moduleVol->SetLineColor(kYellow); + + return moduleVol; } TGeoVolume* TRKLayer::createStave(std::string type, double width) { TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); - std::string staveName = o2::trk::GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber); + std::string staveName = GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber); TGeoShape* stave; TGeoVolume* staveVol; - TGeoVolume* chipVol; + TGeoVolume* moduleVol; if (type == "cylinder") { stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); - chipVol = createChip("cylinder"); + moduleVol = createModule("cylinder"); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName()); - staveVol->AddNode(chipVol, 1, nullptr); + LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVol, 1, nullptr); } else if (type == "flat") { if (width < 0) { LOGP(fatal, "Attempting to create stave with invalid width"); } stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); - chipVol = createChip("flat", width); + moduleVol = createModule("flat", width); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName()); - staveVol->AddNode(chipVol, 1, nullptr); + LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVol, 1, nullptr); } else if (type == "staggered") { double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design) stave = new TGeoBBox(width / 2, mLogicalVolumeThickness / 2, mZ / 2); - TGeoVolume* chipVolLeft = createChip("flat", mModuleWidth); - TGeoVolume* chipVolRight = createChip("flat", mModuleWidth); + TGeoVolume* moduleVolLeft = createModule("flat", mModuleWidth); + TGeoVolume* moduleVolRight = createModule("flat", mModuleWidth); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); TGeoCombiTrans* transLeft = new TGeoCombiTrans(); transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, 0); // 1mm overlap between the modules - LOGP(info, "Inserting {} in {} ", chipVolLeft->GetName(), staveVol->GetName()); - staveVol->AddNode(chipVolLeft, 0, transLeft); + LOGP(info, "Inserting {} in {} ", moduleVolLeft->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVolLeft, 0, transLeft); TGeoCombiTrans* transRight = new TGeoCombiTrans(); transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0.2, 0); - LOGP(info, "Inserting {} in {} ", chipVolRight->GetName(), staveVol->GetName()); - staveVol->AddNode(chipVolRight, 1, transRight); + LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVolRight, 1, transRight); } else { LOGP(fatal, "Chip of type '{}' is not implemented", type); } @@ -152,9 +177,9 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); - std::string staveName = o2::trk::GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber), - chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber), - sensName = Form("%s%d", GeometryTGeo::getTRKSensorPattern(), mLayerNumber); + std::string staveName = GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber), + chipName = GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber), + sensName = GeometryTGeo::getTRKSensorPattern() + std::to_string(mLayerNumber); double layerThickness = mChipThickness; if (mLayout != eLayout::kCylinder) { From 9c1a9e0fff3f3a16971e659bec13c8633d017cb5 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 7 Oct 2025 19:17:16 +0200 Subject: [PATCH 04/37] Refined segmentation with multiple modules, chips and differentiation among sensor and deadzone --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 2 + .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 1 + .../include/TRKSimulation/TRKLayer.h | 1 + .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 118 ++++++++++++++---- 4 files changed, 95 insertions(+), 27 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index 6f689d4520c88..def05fcc63b8c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -49,6 +49,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static const char* getTRKModulePattern() { return sModuleName.c_str(); } static const char* getTRKChipPattern() { return sChipName.c_str(); } static const char* getTRKSensorPattern() { return sSensorName.c_str(); } + static const char* getTRKDeadzonePattern() { return sDeadzoneName.c_str(); } static const char* getTRKWrapVolPattern() { return sWrapperVolumeName.c_str(); } @@ -150,6 +151,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static std::string sModuleName; static std::string sChipName; static std::string sSensorName; + static std::string sDeadzoneName; static std::string sWrapperVolumeName; ///< Wrapper volume name, not implemented at the moment diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index cd9aba66ea466..171a30263ba17 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -31,6 +31,7 @@ std::string GeometryTGeo::sStaveName = "TRKStave"; std::string GeometryTGeo::sModuleName = "TRKModule"; std::string GeometryTGeo::sChipName = "TRKChip"; std::string GeometryTGeo::sSensorName = "TRKSensor"; +std::string GeometryTGeo::sDeadzoneName = "TRKDeadzone"; std::string GeometryTGeo::sWrapperVolumeName = "TRKUWrapVol"; ///< Wrapper volume name, not implemented at the moment diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index a3fdba2fb4599..ae165c486d7f2 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -40,6 +40,7 @@ class TRKLayer auto getName() const { return mLayerName; } TGeoVolume* createSensor(std::string type, double width = -1); + TGeoVolume* createDeadzone(std::string type, double width = -1); TGeoVolume* createChip(std::string type, double width = -1); TGeoVolume* createModule(std::string type, double width = -1); TGeoVolume* createStave(std::string type, double width = -1); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 1c1d6513a97ed..54ad08e7bb1df 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -49,12 +49,12 @@ TGeoVolume* TRKLayer::createSensor(std::string type, double width) TGeoShape* sensor; if (type == "cylinder") { - sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); // TO BE CHECKED !!! } else if (type == "flat") { if (width < 0) { LOGP(fatal, "Attempting to create sensor with invalid width"); } - sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! } else { LOGP(fatal, "Sensor of type '{}' is not implemented", type); } @@ -65,30 +65,63 @@ TGeoVolume* TRKLayer::createSensor(std::string type, double width) return sensVol; }; +TGeoVolume* TRKLayer::createDeadzone(std::string type, double width) +{ + TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); + std::string deadName = GeometryTGeo::getTRKDeadzonePattern() + std::to_string(mLayerNumber); + + TGeoShape* deadzone; + + if (type == "cylinder") { + deadzone = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); // TO BE CHECKED !!! + } else if (type == "flat") { + if (width < 0) { + LOGP(fatal, "Attempting to create deadzone with invalid width"); + } + deadzone = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! + } else { + LOGP(fatal, "Deadzone of type '{}' is not implemented", type); + } + + TGeoVolume* deadVol = new TGeoVolume(deadName.c_str(), deadzone, medSi); + deadVol->SetLineColor(kGray); + + return deadVol; +}; + TGeoVolume* TRKLayer::createChip(std::string type, double width) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); std::string chipName = GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber); TGeoShape* chip; + TGeoVolume* sensVol; + TGeoVolume* deadVol; if (type == "cylinder") { chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); sensVol = createSensor("cylinder"); + deadVol = createDeadzone("cylinder"); } else if (type == "flat") { if (width < 0) { LOGP(fatal, "Attempting to create chip with invalid width"); } - chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! sensVol = createSensor("flat", width); + deadVol = createDeadzone("flat", width); } else { LOGP(fatal, "Sensor of type '{}' is not implemented", type); } TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); chipVol->AddNode(sensVol, 1, nullptr); + + LOGP(info, "Inserting {} in {} ", deadVol->GetName(), chipVol->GetName()); + chipVol->AddNode(deadVol, 1, nullptr); + chipVol->SetLineColor(kYellow); return chipVol; @@ -100,24 +133,39 @@ TGeoVolume* TRKLayer::createModule(std::string type, double width) std::string moduleName = GeometryTGeo::getTRKModulePattern() + std::to_string(mLayerNumber); TGeoShape* module; - TGeoVolume* chipVol; + TGeoVolume* moduleVol; if (type == "cylinder") { module = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); - chipVol = createChip("cylinder"); + moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); + + TGeoVolume* chipVol = createChip("cylinder"); + LOGP(info, "Inserting {} in {} ", chipVol->GetName(), moduleVol->GetName()); + moduleVol->AddNode(chipVol, 1, nullptr); } else if (type == "flat") { if (width < 0) { LOGP(fatal, "Attempting to create module with invalid width"); } - module = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); - chipVol = createChip("flat", width); + + module = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! + moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); + + int nChips = 4; + + for (int iChip = 0; iChip < nChips; iChip++) { + TGeoVolume* chipVol = createChip("flat", mModuleWidth); + + // Put the chips in the correct position + TGeoCombiTrans* trans = new TGeoCombiTrans(); + trans->SetTranslation(0, 0, iChip * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + + LOGP(info, "Inserting {} in {} ", chipVol->GetName(), moduleVol->GetName()); + moduleVol->AddNode(chipVol, iChip, trans); + } } else { LOGP(fatal, "Chip of type '{}' is not implemented", type); } - TGeoVolume* moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); - LOGP(info, "Inserting {} in {} ", chipVol->GetName(), moduleVol->GetName()); - moduleVol->AddNode(chipVol, 1, nullptr); moduleVol->SetLineColor(kYellow); return moduleVol; @@ -130,39 +178,56 @@ TGeoVolume* TRKLayer::createStave(std::string type, double width) TGeoShape* stave; TGeoVolume* staveVol; - TGeoVolume* moduleVol; if (type == "cylinder") { stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); - moduleVol = createModule("cylinder"); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); + + TGeoVolume* moduleVol = createModule("cylinder"); LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVol, 1, nullptr); } else if (type == "flat") { if (width < 0) { LOGP(fatal, "Attempting to create stave with invalid width"); } + stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); - moduleVol = createModule("flat", width); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); - staveVol->AddNode(moduleVol, 1, nullptr); + + int nModules = 10; + + for (int iModule = 0; iModule < nModules; iModule++) { + TGeoVolume* moduleVol = createModule("flat", mModuleWidth); + + // Put the modules in the correct position + TGeoCombiTrans* trans = new TGeoCombiTrans(); + trans->SetTranslation(0, 0, iModule * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + + LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVol, iModule, trans); + } } else if (type == "staggered") { double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design) stave = new TGeoBBox(width / 2, mLogicalVolumeThickness / 2, mZ / 2); - TGeoVolume* moduleVolLeft = createModule("flat", mModuleWidth); - TGeoVolume* moduleVolRight = createModule("flat", mModuleWidth); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - TGeoCombiTrans* transLeft = new TGeoCombiTrans(); - transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, 0); // 1mm overlap between the modules - LOGP(info, "Inserting {} in {} ", moduleVolLeft->GetName(), staveVol->GetName()); - staveVol->AddNode(moduleVolLeft, 0, transLeft); + int nModules = 10; + + for (int iModule = 0; iModule < nModules; iModule++) { + TGeoVolume* moduleVolLeft = createModule("flat", mModuleWidth); + TGeoVolume* moduleVolRight = createModule("flat", mModuleWidth); + + // Put the modules in the correct position + TGeoCombiTrans* transLeft = new TGeoCombiTrans(); + transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, iModule * (mModuleWidth + 0.1)); // TO BE CHECKED !!! 1mm overlap between the modules + LOGP(info, "Inserting {} in {} ", moduleVolLeft->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVolLeft, iModule * 2, transLeft); - TGeoCombiTrans* transRight = new TGeoCombiTrans(); - transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0.2, 0); - LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); - staveVol->AddNode(moduleVolRight, 1, transRight); + TGeoCombiTrans* transRight = new TGeoCombiTrans(); + transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0, iModule * (mModuleWidth + 0.1)); // TO BE CHECKED !!! 1mm overlap between the modules + LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); + staveVol->AddNode(moduleVolRight, iModule * 2 + 1, transRight); + } } else { LOGP(fatal, "Chip of type '{}' is not implemented", type); } @@ -191,7 +256,7 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) layerVol->SetLineColor(kYellow); if (mLayout == eLayout::kCylinder) { - auto staveVol = createStave("cylinder"); + TGeoVolume* staveVol = createStave("cylinder"); LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName()); layerVol->AddNode(staveVol, 1, nullptr); } else if (mLayout == eLayout::kTurboStaves) { @@ -200,7 +265,6 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) if (mInnerRadius > 25) { width *= 2; // Outer layers have two modules per stave } - int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width); nStaves += nStaves % 2; // Require an even number of staves From ed677e583dc7d3426e4d03614420e27509413c7d Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 7 Oct 2025 19:46:14 +0200 Subject: [PATCH 05/37] 2 chip columns per module --- .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 54ad08e7bb1df..60700bc72572d 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -153,14 +153,19 @@ TGeoVolume* TRKLayer::createModule(std::string type, double width) int nChips = 4; for (int iChip = 0; iChip < nChips; iChip++) { - TGeoVolume* chipVol = createChip("flat", mModuleWidth); + TGeoVolume* chipVolLeft = createChip("flat", mModuleWidth / 2); + TGeoVolume* chipVolRight = createChip("flat", mModuleWidth / 2); // TO BE CHECKED !!! // Put the chips in the correct position - TGeoCombiTrans* trans = new TGeoCombiTrans(); - trans->SetTranslation(0, 0, iChip * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + TGeoCombiTrans* transLeft = new TGeoCombiTrans(); + transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, iChip * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + LOGP(info, "Inserting {} in {} ", chipVolLeft->GetName(), moduleVol->GetName()); + moduleVol->AddNode(chipVolLeft, iChip * 2, transLeft); - LOGP(info, "Inserting {} in {} ", chipVol->GetName(), moduleVol->GetName()); - moduleVol->AddNode(chipVol, iChip, trans); + TGeoCombiTrans* transRight = new TGeoCombiTrans(); + transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0, iChip * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + LOGP(info, "Inserting {} in {} ", chipVolRight->GetName(), moduleVol->GetName()); + moduleVol->AddNode(chipVolRight, iChip * 2 + 1, transRight); } } else { LOGP(fatal, "Chip of type '{}' is not implemented", type); From a39d96672b89e9517386b2ed47413619acdf58aa Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 9 Oct 2025 00:30:18 +0200 Subject: [PATCH 06/37] Fixed dimensions with bottom up approach --- .../ALICE3/TRK/base/include/TRKBase/Specs.h | 2 +- .../include/TRKSimulation/TRKLayer.h | 17 +-- .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 119 ++++++++++-------- 3 files changed, 78 insertions(+), 60 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h index 373e9d972656b..d0398806f6115 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h @@ -22,7 +22,7 @@ // Each TGeoShape has the following properties // length: dimension in z-axis // width: dimension in xy-axes -// color: for visulisation +// color: for visualisation namespace o2::trk::constants { // Default unit of TGeo = cm diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index ae165c486d7f2..c3fb29d74c2b0 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -39,11 +39,11 @@ class TRKLayer auto getNumber() const { return mLayerNumber; } auto getName() const { return mLayerName; } - TGeoVolume* createSensor(std::string type, double width = -1); - TGeoVolume* createDeadzone(std::string type, double width = -1); - TGeoVolume* createChip(std::string type, double width = -1); - TGeoVolume* createModule(std::string type, double width = -1); - TGeoVolume* createStave(std::string type, double width = -1); + TGeoVolume* createSensor(std::string type); + TGeoVolume* createDeadzone(std::string type); + TGeoVolume* createChip(std::string type); + TGeoVolume* createModule(std::string type); + TGeoVolume* createStave(std::string type); void createLayer(TGeoVolume* motherVolume); private: @@ -51,14 +51,17 @@ class TRKLayer static constexpr float mLogicalVolumeThickness = 1; int mLayerNumber; + eLayout mLayout; std::string mLayerName; float mInnerRadius; float mOuterRadius; float mZ; float mX2X0; - float mChipThickness; float mModuleWidth; // u.m. = cm - eLayout mLayout; + float mChipWidth; + float mChipLength; + float mChipThickness; + float mDeadzoneWidth; ClassDef(TRKLayer, 1); }; diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 60700bc72572d..e4a61c0c1eb59 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -11,6 +11,7 @@ #include "TRKSimulation/TRKLayer.h" #include "TRKBase/GeometryTGeo.h" +#include "TRKBase/Specs.h" #include "Framework/Logger.h" @@ -25,7 +26,7 @@ namespace o2 namespace trk { TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, float zLength, float layerX2X0) - : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mModuleWidth(4.54), mLayout(kCylinder) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mModuleWidth(4.54), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) { float Si_X0 = 9.5f; mChipThickness = mX2X0 * Si_X0; @@ -33,7 +34,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOu } TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick) - : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mModuleWidth(4.54), mLayout(kCylinder) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mModuleWidth(4.54), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) { float Si_X0 = 9.5f; mOuterRadius = rInn + thick; @@ -41,7 +42,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLe LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, mZ, mX2X0); } -TGeoVolume* TRKLayer::createSensor(std::string type, double width) +TGeoVolume* TRKLayer::createSensor(std::string type) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); std::string sensName = GeometryTGeo::getTRKSensorPattern() + std::to_string(mLayerNumber); @@ -51,10 +52,7 @@ TGeoVolume* TRKLayer::createSensor(std::string type, double width) if (type == "cylinder") { sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); // TO BE CHECKED !!! } else if (type == "flat") { - if (width < 0) { - LOGP(fatal, "Attempting to create sensor with invalid width"); - } - sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! + sensor = new TGeoBBox((mChipWidth - mDeadzoneWidth) / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! } else { LOGP(fatal, "Sensor of type '{}' is not implemented", type); } @@ -65,7 +63,7 @@ TGeoVolume* TRKLayer::createSensor(std::string type, double width) return sensVol; }; -TGeoVolume* TRKLayer::createDeadzone(std::string type, double width) +TGeoVolume* TRKLayer::createDeadzone(std::string type) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); std::string deadName = GeometryTGeo::getTRKDeadzonePattern() + std::to_string(mLayerNumber); @@ -75,10 +73,7 @@ TGeoVolume* TRKLayer::createDeadzone(std::string type, double width) if (type == "cylinder") { deadzone = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); // TO BE CHECKED !!! } else if (type == "flat") { - if (width < 0) { - LOGP(fatal, "Attempting to create deadzone with invalid width"); - } - deadzone = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! + deadzone = new TGeoBBox(mDeadzoneWidth / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! } else { LOGP(fatal, "Deadzone of type '{}' is not implemented", type); } @@ -89,45 +84,52 @@ TGeoVolume* TRKLayer::createDeadzone(std::string type, double width) return deadVol; }; -TGeoVolume* TRKLayer::createChip(std::string type, double width) +TGeoVolume* TRKLayer::createChip(std::string type) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); std::string chipName = GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber); TGeoShape* chip; + TGeoVolume* chipVol; TGeoVolume* sensVol; TGeoVolume* deadVol; if (type == "cylinder") { chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + sensVol = createSensor("cylinder"); - deadVol = createDeadzone("cylinder"); + LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); + chipVol->AddNode(sensVol, 1, nullptr); + + // deadVol = createDeadzone("cylinder"); } else if (type == "flat") { - if (width < 0) { - LOGP(fatal, "Attempting to create chip with invalid width"); - } - chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! - sensVol = createSensor("flat", width); - deadVol = createDeadzone("flat", width); - } else { - LOGP(fatal, "Sensor of type '{}' is not implemented", type); - } + chip = new TGeoBBox(mChipWidth / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! + chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); - TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + sensVol = createSensor("flat"); + deadVol = createDeadzone("flat"); - LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); - chipVol->AddNode(sensVol, 1, nullptr); + TGeoCombiTrans* transSens = new TGeoCombiTrans(); + transSens->SetTranslation(-mDeadzoneWidth / 2, 0, 0); // TO BE CHECKED !!! + LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); + chipVol->AddNode(sensVol, 1, transSens); - LOGP(info, "Inserting {} in {} ", deadVol->GetName(), chipVol->GetName()); - chipVol->AddNode(deadVol, 1, nullptr); + TGeoCombiTrans* transDead = new TGeoCombiTrans(); + transDead->SetTranslation((mChipWidth - mDeadzoneWidth) / 2, 0, 0); // TO BE CHECKED !!! + LOGP(info, "Inserting {} in {} ", deadVol->GetName(), chipVol->GetName()); + chipVol->AddNode(deadVol, 1, transDead); + } else { + LOGP(fatal, "Sensor of type '{}' is not implemented", type); + } chipVol->SetLineColor(kYellow); return chipVol; } -TGeoVolume* TRKLayer::createModule(std::string type, double width) +TGeoVolume* TRKLayer::createModule(std::string type) { TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); std::string moduleName = GeometryTGeo::getTRKModulePattern() + std::to_string(mLayerNumber); @@ -143,27 +145,32 @@ TGeoVolume* TRKLayer::createModule(std::string type, double width) LOGP(info, "Inserting {} in {} ", chipVol->GetName(), moduleVol->GetName()); moduleVol->AddNode(chipVol, 1, nullptr); } else if (type == "flat") { - if (width < 0) { - LOGP(fatal, "Attempting to create module with invalid width"); - } + double moduleWidth = constants::moduleMLOT::width; + double moduleLength = constants::moduleMLOT::length; - module = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); // TO BE CHECKED !!! + module = new TGeoBBox(moduleWidth / 2, mChipThickness / 2, moduleLength / 2); // TO BE CHECKED !!! moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); int nChips = 4; for (int iChip = 0; iChip < nChips; iChip++) { - TGeoVolume* chipVolLeft = createChip("flat", mModuleWidth / 2); - TGeoVolume* chipVolRight = createChip("flat", mModuleWidth / 2); // TO BE CHECKED !!! + TGeoVolume* chipVolLeft = createChip("flat"); + TGeoVolume* chipVolRight = createChip("flat"); // Put the chips in the correct position + double xLeft = -moduleWidth / 2 + constants::moduleMLOT::gaps::outerEdgeLongSide + constants::moduleMLOT::chip::width / 2; + double zLeft = -moduleLength / 2 + constants::moduleMLOT::gaps::outerEdgeShortSide + iChip * (constants::moduleMLOT::chip::length + constants::moduleMLOT::gaps::interChips) + constants::moduleMLOT::chip::length / 2; + TGeoCombiTrans* transLeft = new TGeoCombiTrans(); - transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, iChip * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + transLeft->SetTranslation(xLeft, 0, zLeft); // TO BE CHECKED !!! LOGP(info, "Inserting {} in {} ", chipVolLeft->GetName(), moduleVol->GetName()); moduleVol->AddNode(chipVolLeft, iChip * 2, transLeft); + double xRight = +moduleWidth / 2 - constants::moduleMLOT::gaps::outerEdgeLongSide - constants::moduleMLOT::chip::width / 2; + double zRight = -moduleLength / 2 + constants::moduleMLOT::gaps::outerEdgeShortSide + iChip * (constants::moduleMLOT::chip::length + constants::moduleMLOT::gaps::interChips) + constants::moduleMLOT::chip::length / 2; + TGeoCombiTrans* transRight = new TGeoCombiTrans(); - transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0, iChip * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + transRight->SetTranslation(xRight, 0, zRight); // TO BE CHECKED !!! LOGP(info, "Inserting {} in {} ", chipVolRight->GetName(), moduleVol->GetName()); moduleVol->AddNode(chipVolRight, iChip * 2 + 1, transRight); } @@ -176,7 +183,7 @@ TGeoVolume* TRKLayer::createModule(std::string type, double width) return moduleVol; } -TGeoVolume* TRKLayer::createStave(std::string type, double width) +TGeoVolume* TRKLayer::createStave(std::string type) { TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); std::string staveName = GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber); @@ -192,44 +199,52 @@ TGeoVolume* TRKLayer::createStave(std::string type, double width) LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVol, 1, nullptr); } else if (type == "flat") { - if (width < 0) { - LOGP(fatal, "Attempting to create stave with invalid width"); - } + double moduleLength = constants::ML::length; + double staveWidth = constants::ML::width; - stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + stave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, mZ / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); int nModules = 10; for (int iModule = 0; iModule < nModules; iModule++) { - TGeoVolume* moduleVol = createModule("flat", mModuleWidth); + TGeoVolume* moduleVol = createModule("flat"); // Put the modules in the correct position + double zPos = -0.5 * (nModules - 1) * moduleLength + iModule * moduleLength; + TGeoCombiTrans* trans = new TGeoCombiTrans(); - trans->SetTranslation(0, 0, iModule * (mModuleWidth + 0.1)); // TO BE CHECKED !!! + trans->SetTranslation(0, 0, zPos); // TO BE CHECKED !!! LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVol, iModule, trans); } } else if (type == "staggered") { - double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design) - stave = new TGeoBBox(width / 2, mLogicalVolumeThickness / 2, mZ / 2); + double moduleWidth = constants::ML::width; + double moduleLength = constants::ML::length; + double staveWidth = constants::OT::width; // Each stave has two modules (based on the LOI design) + + stave = new TGeoBBox(staveWidth / 2, mLogicalVolumeThickness / 2, mZ / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - int nModules = 10; + int nModules = 20; for (int iModule = 0; iModule < nModules; iModule++) { - TGeoVolume* moduleVolLeft = createModule("flat", mModuleWidth); - TGeoVolume* moduleVolRight = createModule("flat", mModuleWidth); + TGeoVolume* moduleVolLeft = createModule("flat"); + TGeoVolume* moduleVolRight = createModule("flat"); // Put the modules in the correct position + double xLeft = -moduleWidth / 2 + 0.05; + double xRight = moduleWidth / 2 - 0.05; + double zPos = -0.5 * (nModules - 1) * moduleLength + iModule * moduleLength; + TGeoCombiTrans* transLeft = new TGeoCombiTrans(); - transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, iModule * (mModuleWidth + 0.1)); // TO BE CHECKED !!! 1mm overlap between the modules + transLeft->SetTranslation(xLeft, 0, zPos); // TO BE CHECKED !!! 1mm overlap between the modules LOGP(info, "Inserting {} in {} ", moduleVolLeft->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVolLeft, iModule * 2, transLeft); TGeoCombiTrans* transRight = new TGeoCombiTrans(); - transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0, iModule * (mModuleWidth + 0.1)); // TO BE CHECKED !!! 1mm overlap between the modules + transRight->SetTranslation(xRight, 0, zPos); // TO BE CHECKED !!! 1mm overlap between the modules LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVolRight, iModule * 2 + 1, transRight); } @@ -283,7 +298,7 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10); for (int iStave = 0; iStave < nStaves; iStave++) { - TGeoVolume* staveVol = createStave("flat", width); + TGeoVolume* staveVol = createStave("flat"); // Put the staves in the correct position and orientation TGeoCombiTrans* trans = new TGeoCombiTrans(); From 7f666baf5583d10c56939bda10c702e816bdf476 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 9 Oct 2025 00:49:17 +0200 Subject: [PATCH 07/37] Removed unnecessary cast --- .../ALICE3/TRK/simulation/src/Detector.cxx | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index f5027310fa66d..b30dc1dbcdbc9 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -20,6 +20,8 @@ #include "TRKSimulation/Detector.h" #include "TRKBase/TRKBaseParam.h" +#include + using o2::itsmft::Hit; namespace o2 @@ -102,17 +104,17 @@ void Detector::configDefault() mLayers.clear(); LOGP(warning, "Loading Scoping Document configuration for ALICE3 TRK"); - // mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 0.5f, 50.f, 100.e-4); - // mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 1.2f, 50.f, 100.e-4); - // mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 2.5f, 50.f, 100.e-4); - mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 3.78f, 124.f, 100.e-3); - mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 7.f, 124.f, 100.e-3); - mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 12.f, 124.f, 100.e-3); - mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(3)}, 20.f, 124.f, 100.e-3); - mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(4)}, 30.f, 124.f, 100.e-3); - mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(5)}, 45.f, 258.f, 100.e-3); - mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(6)}, 60.f, 258.f, 100.e-3); - mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(7)}, 80.f, 258.f, 100.e-3); + // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 0.5f, 50.f, 100.e-4); + // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 1.2f, 50.f, 100.e-4); + // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 2.5f, 50.f, 100.e-4); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 3.78f, 124.f, 100.e-3); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 7.f, 124.f, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 124.f, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 20.f, 124.f, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 124.f, 100.e-3); + mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 258.f, 100.e-3); + mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 258.f, 100.e-3); + mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 258.f, 100.e-3); } void Detector::buildTRKNewVacuumVessel() @@ -125,18 +127,18 @@ void Detector::buildTRKNewVacuumVessel() mLayers.clear(); LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); - // mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 0.5f, 50.f, 100.e-4); - // mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 1.2f, 50.f, 100.e-4); - // mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 2.5f, 50.f, 100.e-4); - mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 7.f, 124.f, 100.e-3); - LOGP(info, "TRKLayer created. Name: {}", std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}); - mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 9.f, 124.f, 100.e-3); - mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 12.f, 124.f, 100.e-3); - mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(3)}, 20.f, 124.f, 100.e-3); - mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(4)}, 30.f, 124.f, 100.e-3); - mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(5)}, 45.f, 258.f, 100.e-3); - mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(6)}, 60.f, 258.f, 100.e-3); - mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(7)}, 80.f, 258.f, 100.e-3); + // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 50.f, 100.e-4); + // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 50.f, 100.e-4); + // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 50.f, 100.e-4); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 124.f, 100.e-3); + LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 9.f, 124.f, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 124.f, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 20.f, 124.f, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 124.f, 100.e-3); + mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 258.f, 100.e-3); + mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 258.f, 100.e-3); + mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 258.f, 100.e-3); auto& trkPars = TRKBaseParam::Instance(); From ae2a4607e0ffa760b49f8c10187baac12a8a597a Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 9 Oct 2025 00:49:50 +0200 Subject: [PATCH 08/37] Removed unnecessary cast --- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index b30dc1dbcdbc9..626d22cc2879a 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -181,7 +181,7 @@ void Detector::configFromFile(std::string fileName) while (getline(ss, substr, '\t')) { tmpBuff.push_back(std::stof(substr)); } - mLayers.emplace_back(layerCount, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(layerCount)}, tmpBuff[0], tmpBuff[1], tmpBuff[2]); + mLayers.emplace_back(layerCount, GeometryTGeo::getTRKLayerPattern() + std::to_string(layerCount), tmpBuff[0], tmpBuff[1], tmpBuff[2]); ++layerCount; } } From a3da6c4bb086f621133140d915b47239605c8af7 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 9 Oct 2025 03:53:22 +0200 Subject: [PATCH 09/37] Set new inner radii for MLs --- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 626d22cc2879a..093a08be5c8a6 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -132,9 +132,9 @@ void Detector::buildTRKNewVacuumVessel() // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 50.f, 100.e-4); mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 124.f, 100.e-3); LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); - mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 9.f, 124.f, 100.e-3); - mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 124.f, 100.e-3); - mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 20.f, 124.f, 100.e-3); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 124.f, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 124.f, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 124.f, 100.e-3); mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 124.f, 100.e-3); mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 258.f, 100.e-3); mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 258.f, 100.e-3); From 280f928365744003c4f3913ce830955737d2b54a Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 9 Oct 2025 04:01:05 +0200 Subject: [PATCH 10/37] Set new lengths for MLs --- .../Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 093a08be5c8a6..50d53abdd67c1 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -130,12 +130,12 @@ void Detector::buildTRKNewVacuumVessel() // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 50.f, 100.e-4); // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 50.f, 100.e-4); // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 50.f, 100.e-4); - mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 124.f, 100.e-3); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 129.f, 100.e-3); LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); - mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 124.f, 100.e-3); - mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 124.f, 100.e-3); - mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 124.f, 100.e-3); - mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 124.f, 100.e-3); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 129.f, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 129.f, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 129.f, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 129.f, 100.e-3); mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 258.f, 100.e-3); mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 258.f, 100.e-3); mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 258.f, 100.e-3); From 5efdfee987c54585426d76a991bde09b952788fe Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 9 Oct 2025 04:07:37 +0200 Subject: [PATCH 11/37] Removed mModuleWidth and fixed createLayer --- .../include/TRKSimulation/TRKLayer.h | 1 - .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 22 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index c3fb29d74c2b0..dfba97ae395ca 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -57,7 +57,6 @@ class TRKLayer float mOuterRadius; float mZ; float mX2X0; - float mModuleWidth; // u.m. = cm float mChipWidth; float mChipLength; float mChipThickness; diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index e4a61c0c1eb59..5ac592018e69b 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -26,7 +26,7 @@ namespace o2 namespace trk { TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, float zLength, float layerX2X0) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mModuleWidth(4.54), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) { float Si_X0 = 9.5f; mChipThickness = mX2X0 * Si_X0; @@ -34,7 +34,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOu } TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mModuleWidth(4.54), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) { float Si_X0 = 9.5f; mOuterRadius = rInn + thick; @@ -281,19 +281,19 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) layerVol->AddNode(staveVol, 1, nullptr); } else if (mLayout == eLayout::kTurboStaves) { // Compute the number of staves - double width = mModuleWidth; // Each stave has two modules (based on the LOI design) + double staveWidth = constants::ML::width; // Each stave has two modules (based on the LOI design) if (mInnerRadius > 25) { - width *= 2; // Outer layers have two modules per stave + staveWidth = constants::OT::width; // Outer layers have two modules per stave } - int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width); + int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / staveWidth); nStaves += nStaves % 2; // Require an even number of staves // Compute the size of the overlap region double theta = 2 * TMath::Pi() / nStaves; - double theta1 = std::atan(width / 2 / mInnerRadius); + double theta1 = std::atan(staveWidth / 2 / mInnerRadius); double st = std::sin(theta); double ct = std::cos(theta); - double theta2 = std::atan((mInnerRadius * st - width / 2 * ct) / (mInnerRadius * ct + width / 2 * st)); + double theta2 = std::atan((mInnerRadius * st - staveWidth / 2 * ct) / (mInnerRadius * ct + staveWidth / 2 * st)); double overlap = (theta1 - theta2) * mInnerRadius; LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10); @@ -312,16 +312,16 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) } } else if (mLayout == kStaggered) { // Compute the number of staves - double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design) - int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width); + double staveWidth = constants::OT::width; // Each stave has two modules (based on the LOI design) + int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / staveWidth); nStaves += nStaves % 2; // Require an even number of staves // Compute the size of the overlap region double theta = 2 * TMath::Pi() / nStaves; - double theta1 = std::atan(width / 2 / mInnerRadius); + double theta1 = std::atan(staveWidth / 2 / mInnerRadius); double st = std::sin(theta); double ct = std::cos(theta); - double theta2 = std::atan((mInnerRadius * st - width / 2 * ct) / (mInnerRadius * ct + width / 2 * st)); + double theta2 = std::atan((mInnerRadius * st - staveWidth / 2 * ct) / (mInnerRadius * ct + staveWidth / 2 * st)); double overlap = (theta1 - theta2) * mInnerRadius; LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10); From bbf7739986ac6162a7bb162cc7caaebfca617b9c Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 10 Oct 2025 02:29:29 +0200 Subject: [PATCH 12/37] Preparing to remove mZ member from TRKLayer + getter in GeometryTGeo --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 13 +++---- .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 38 ++++++++++++------ .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 39 ++++++++++++------- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index def05fcc63b8c..0bac9b499c59d 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -78,12 +78,13 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache void Print(Option_t* opt = "") const; void PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const; + int getSubDetID(int index) const; + int getPetalCase(int index) const; int getLayer(int index) const; int getStave(int index) const; int getHalfStave(int index) const; - int getSubDetID(int index) const; - int getPetalCase(int index) const; int getDisk(int index) const; + int getModule(int index) const; /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave /// TODO: retrieve also from chip when chips will be available /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT @@ -130,13 +131,11 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache TString getMatrixPath(int index) const; - static const char* composeSymNameTRK(int d) - { - return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::TRK).getName(), d); - } + static const char* composeSymNameTRK(int d); static const char* composeSymNameLayer(int d, int layer); static const char* composeSymNameStave(int d, int layer); - static const char* composeSymNameChip(int d, int lr); + static const char* composeSymNameModule(int d, int layer); + static const char* composeSymNameChip(int d, int layer); static const char* composeSymNameSensor(int d, int layer); protected: diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 171a30263ba17..8f87282cff375 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -133,9 +133,7 @@ int GeometryTGeo::getPetalCase(int index) const int subDetID = getSubDetID(index); if (subDetID == 1) { return -1; - } - - else if (index <= mLastChipIndexVD[mNumberOfPetalsVD - 1]) { + } else if (index <= mLastChipIndexVD[mNumberOfPetalsVD - 1]) { while (index > mLastChipIndexVD[petalcase]) { petalcase++; } @@ -159,7 +157,7 @@ int GeometryTGeo::getLayer(int index) const while (index > mLastChipIndex[lay]) { lay++; } - return lay - mNumberOfPetalsVD; /// numeration of MLOT layesrs starting from 0 + return lay - mNumberOfPetalsVD; /// numeration of MLOT layers starting from 0 } return -1; /// -1 if not found } @@ -214,6 +212,12 @@ int GeometryTGeo::getDisk(int index) const return -1; /// not found or ML/OT } +//__________________________________________________________________________ +int GeometryTGeo::getModule(int index) const +{ + int subDetID = getSubDetID(index); +} + //__________________________________________________________________________ int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const { @@ -370,24 +374,34 @@ void GeometryTGeo::fillMatrixCache(int mask) //__________________________________________________________________________ -const char* GeometryTGeo::composeSymNameLayer(int d, int lr) +const char* GeometryTGeo::composeSymNameTRK(int d) +{ + return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::TRK).getName(), d); +} + +const char* GeometryTGeo::composeSymNameLayer(int d, int layer) +{ + return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), layer); +} + +const char* GeometryTGeo::composeSymNameStave(int d, int layer) { - return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), lr); + return Form("%s/%s%d", composeSymNameLayer(d, layer), getTRKStavePattern(), layer); } -const char* GeometryTGeo::composeSymNameStave(int d, int lr) +const char* GeometryTGeo::composeSymNameModule(int d, int layer) { - return Form("%s/%s%d", composeSymNameLayer(d, lr), getTRKStavePattern(), lr); + return Form("%s/%s%d", composeSymNameStave(d, layer), getTRKModulePattern(), layer); } -const char* GeometryTGeo::composeSymNameChip(int d, int lr) +const char* GeometryTGeo::composeSymNameChip(int d, int layer) { - return Form("%s/%s%d", composeSymNameStave(d, lr), getTRKChipPattern(), lr); + return Form("%s/%s%d", composeSymNameStave(d, layer), getTRKChipPattern(), layer); } -const char* GeometryTGeo::composeSymNameSensor(int d, int lr) +const char* GeometryTGeo::composeSymNameSensor(int d, int layer) { - return Form("%s/%s%d", composeSymNameChip(d, lr), getTRKSensorPattern(), lr); + return Form("%s/%s%d", composeSymNameChip(d, layer), getTRKSensorPattern(), layer); } //__________________________________________________________________________ diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 5ac592018e69b..cc277d4dae1a8 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -201,8 +201,9 @@ TGeoVolume* TRKLayer::createStave(std::string type) } else if (type == "flat") { double moduleLength = constants::ML::length; double staveWidth = constants::ML::width; + double staveLength = constants::ML::length; - stave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, mZ / 2); + stave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); int nModules = 10; @@ -220,11 +221,12 @@ TGeoVolume* TRKLayer::createStave(std::string type) staveVol->AddNode(moduleVol, iModule, trans); } } else if (type == "staggered") { - double moduleWidth = constants::ML::width; - double moduleLength = constants::ML::length; + double moduleWidth = constants::moduleMLOT::width; + double moduleLength = constants::moduleMLOT::length; double staveWidth = constants::OT::width; // Each stave has two modules (based on the LOI design) + double staveLength = constants::OT::length; - stave = new TGeoBBox(staveWidth / 2, mLogicalVolumeThickness / 2, mZ / 2); + stave = new TGeoBBox(staveWidth / 2, mLogicalVolumeThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); int nModules = 20; @@ -259,32 +261,36 @@ TGeoVolume* TRKLayer::createStave(std::string type) void TRKLayer::createLayer(TGeoVolume* motherVolume) { - TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); - std::string staveName = GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber), - chipName = GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber), - sensName = GeometryTGeo::getTRKSensorPattern() + std::to_string(mLayerNumber); - double layerThickness = mChipThickness; if (mLayout != eLayout::kCylinder) { layerThickness = mLogicalVolumeThickness; } - TGeoTube* layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, mZ / 2); - TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); - layerVol->SetLineColor(kYellow); + TGeoTube* layer; + TGeoVolume* layerVol; if (mLayout == eLayout::kCylinder) { + layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, mZ / 2); + layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); + TGeoVolume* staveVol = createStave("cylinder"); LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName()); layerVol->AddNode(staveVol, 1, nullptr); } else if (mLayout == eLayout::kTurboStaves) { - // Compute the number of staves + double layerLength = constants::ML::length; double staveWidth = constants::ML::width; // Each stave has two modules (based on the LOI design) + if (mInnerRadius > 25) { + layerLength = constants::OT::length; staveWidth = constants::OT::width; // Outer layers have two modules per stave } + + layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, layerLength / 2); + layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); + + // Compute the number of staves int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / staveWidth); nStaves += nStaves % 2; // Require an even number of staves @@ -311,6 +317,11 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) layerVol->AddNode(staveVol, iStave, trans); } } else if (mLayout == kStaggered) { + double layerLength = constants::OT::length; + + layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, layerLength / 2); + layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); + // Compute the number of staves double staveWidth = constants::OT::width; // Each stave has two modules (based on the LOI design) int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / staveWidth); @@ -341,6 +352,8 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) } else { LOGP(fatal, "Layout not implemented"); } + layerVol->SetLineColor(kYellow); + LOGP(info, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName()); motherVolume->AddNode(layerVol, 1, nullptr); } From 218590d9c1d1665c9acbbba4f82cd6b45ef8f8da Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 10 Oct 2025 04:09:05 +0200 Subject: [PATCH 13/37] Removed mZ --- .../include/TRKSimulation/TRKLayer.h | 9 ++-- .../ALICE3/TRK/simulation/src/Detector.cxx | 44 +++++++++---------- .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 44 ++++++++----------- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index dfba97ae395ca..6bb7d0e2064a6 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -25,15 +25,15 @@ class TRKLayer { public: TRKLayer() = default; - TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, float zLength, float layerX2X0); - TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick); + TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, int numberOfModules, float layerX2X0); + TRKLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thick); ~TRKLayer() = default; void setLayout(eLayout layout) { mLayout = layout; }; auto getInnerRadius() const { return mInnerRadius; } auto getOuterRadius() const { return mOuterRadius; } - auto getZ() const { return mZ; } + auto getZ() const { return constants::moduleMLOT::length * mNumberOfModules; } auto getx2X0() const { return mX2X0; } auto getChipThickness() const { return mChipThickness; } auto getNumber() const { return mLayerNumber; } @@ -55,12 +55,13 @@ class TRKLayer std::string mLayerName; float mInnerRadius; float mOuterRadius; - float mZ; + int mNumberOfModules; float mX2X0; float mChipWidth; float mChipLength; float mChipThickness; float mDeadzoneWidth; + int mHalfNumberOfChips; ClassDef(TRKLayer, 1); }; diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 50d53abdd67c1..c0568fc86e264 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -104,17 +104,17 @@ void Detector::configDefault() mLayers.clear(); LOGP(warning, "Loading Scoping Document configuration for ALICE3 TRK"); - // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 0.5f, 50.f, 100.e-4); - // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 1.2f, 50.f, 100.e-4); - // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 2.5f, 50.f, 100.e-4); - mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 3.78f, 124.f, 100.e-3); - mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 7.f, 124.f, 100.e-3); - mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 124.f, 100.e-3); - mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 20.f, 124.f, 100.e-3); - mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 124.f, 100.e-3); - mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 258.f, 100.e-3); - mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 258.f, 100.e-3); - mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 258.f, 100.e-3); + // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 4, 100.e-4); + // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 4, 100.e-4); + // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 4, 100.e-4); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 3.78f, 10, 100.e-3); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 7.f, 10, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 10, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 20.f, 10, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 10, 100.e-3); + mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 20, 100.e-3); + mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 20, 100.e-3); + mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); } void Detector::buildTRKNewVacuumVessel() @@ -127,18 +127,18 @@ void Detector::buildTRKNewVacuumVessel() mLayers.clear(); LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); - // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 50.f, 100.e-4); - // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 50.f, 100.e-4); - // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 50.f, 100.e-4); - mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 129.f, 100.e-3); + // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 4, 100.e-4); + // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 4, 100.e-4); + // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 4, 100.e-4); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 10, 100.e-3); LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); - mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 129.f, 100.e-3); - mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 129.f, 100.e-3); - mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 129.f, 100.e-3); - mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 129.f, 100.e-3); - mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 258.f, 100.e-3); - mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 258.f, 100.e-3); - mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 258.f, 100.e-3); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 10, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 10, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 10, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 10, 100.e-3); + mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 20, 100.e-3); + mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 20, 100.e-3); + mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); auto& trkPars = TRKBaseParam::Instance(); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index cc277d4dae1a8..412c2155f4f62 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -25,21 +25,21 @@ namespace o2 { namespace trk { -TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, float zLength, float layerX2X0) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) +TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, int numberOfModules, float layerX2X0) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mNumberOfModules(numberOfModules), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mHalfNumberOfChips(4) { float Si_X0 = 9.5f; mChipThickness = mX2X0 * Si_X0; - LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, mZ, mX2X0); + LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, getZ(), mX2X0); } -TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1) +TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thick) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mNumberOfModules(numberOfModules), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mHalfNumberOfChips(4) { float Si_X0 = 9.5f; mOuterRadius = rInn + thick; mX2X0 = mChipThickness / Si_X0; - LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, mZ, mX2X0); + LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, getZ(), mX2X0); } TGeoVolume* TRKLayer::createSensor(std::string type) @@ -50,7 +50,7 @@ TGeoVolume* TRKLayer::createSensor(std::string type) TGeoShape* sensor; if (type == "cylinder") { - sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); // TO BE CHECKED !!! + sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); // TO BE CHECKED !!! } else if (type == "flat") { sensor = new TGeoBBox((mChipWidth - mDeadzoneWidth) / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! } else { @@ -71,7 +71,7 @@ TGeoVolume* TRKLayer::createDeadzone(std::string type) TGeoShape* deadzone; if (type == "cylinder") { - deadzone = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); // TO BE CHECKED !!! + deadzone = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); // TO BE CHECKED !!! } else if (type == "flat") { deadzone = new TGeoBBox(mDeadzoneWidth / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! } else { @@ -96,7 +96,7 @@ TGeoVolume* TRKLayer::createChip(std::string type) TGeoVolume* deadVol; if (type == "cylinder") { - chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); sensVol = createSensor("cylinder"); @@ -138,7 +138,7 @@ TGeoVolume* TRKLayer::createModule(std::string type) TGeoVolume* moduleVol; if (type == "cylinder") { - module = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + module = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); TGeoVolume* chipVol = createChip("cylinder"); @@ -151,9 +151,7 @@ TGeoVolume* TRKLayer::createModule(std::string type) module = new TGeoBBox(moduleWidth / 2, mChipThickness / 2, moduleLength / 2); // TO BE CHECKED !!! moduleVol = new TGeoVolume(moduleName.c_str(), module, medAir); - int nChips = 4; - - for (int iChip = 0; iChip < nChips; iChip++) { + for (int iChip = 0; iChip < mHalfNumberOfChips; iChip++) { TGeoVolume* chipVolLeft = createChip("flat"); TGeoVolume* chipVolRight = createChip("flat"); @@ -192,7 +190,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) TGeoVolume* staveVol; if (type == "cylinder") { - stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); TGeoVolume* moduleVol = createModule("cylinder"); @@ -206,13 +204,11 @@ TGeoVolume* TRKLayer::createStave(std::string type) stave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - int nModules = 10; - - for (int iModule = 0; iModule < nModules; iModule++) { + for (int iModule = 0; iModule < mNumberOfModules; iModule++) { TGeoVolume* moduleVol = createModule("flat"); // Put the modules in the correct position - double zPos = -0.5 * (nModules - 1) * moduleLength + iModule * moduleLength; + double zPos = -0.5 * (mNumberOfModules - 1) * moduleLength + iModule * moduleLength; TGeoCombiTrans* trans = new TGeoCombiTrans(); trans->SetTranslation(0, 0, zPos); // TO BE CHECKED !!! @@ -229,16 +225,14 @@ TGeoVolume* TRKLayer::createStave(std::string type) stave = new TGeoBBox(staveWidth / 2, mLogicalVolumeThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - int nModules = 20; - - for (int iModule = 0; iModule < nModules; iModule++) { + for (int iModule = 0; iModule < mNumberOfModules; iModule++) { TGeoVolume* moduleVolLeft = createModule("flat"); TGeoVolume* moduleVolRight = createModule("flat"); // Put the modules in the correct position double xLeft = -moduleWidth / 2 + 0.05; double xRight = moduleWidth / 2 - 0.05; - double zPos = -0.5 * (nModules - 1) * moduleLength + iModule * moduleLength; + double zPos = -0.5 * (mNumberOfModules - 1) * moduleLength + iModule * moduleLength; TGeoCombiTrans* transLeft = new TGeoCombiTrans(); transLeft->SetTranslation(xLeft, 0, zPos); // TO BE CHECKED !!! 1mm overlap between the modules @@ -272,14 +266,14 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) TGeoVolume* layerVol; if (mLayout == eLayout::kCylinder) { - layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, mZ / 2); + layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, mChipLength / 2); layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); TGeoVolume* staveVol = createStave("cylinder"); LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName()); layerVol->AddNode(staveVol, 1, nullptr); } else if (mLayout == eLayout::kTurboStaves) { - double layerLength = constants::ML::length; + double layerLength = constants::moduleMLOT::length * mNumberOfModules; double staveWidth = constants::ML::width; // Each stave has two modules (based on the LOI design) if (mInnerRadius > 25) { @@ -317,7 +311,7 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) layerVol->AddNode(staveVol, iStave, trans); } } else if (mLayout == kStaggered) { - double layerLength = constants::OT::length; + double layerLength = constants::moduleMLOT::length * mNumberOfModules; layer = new TGeoTube(mInnerRadius - 0.333 * layerThickness, mInnerRadius + 0.667 * layerThickness, layerLength / 2); layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); From 57698aa60d6b329bdaea08af7986f2a23f7635e4 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 10 Oct 2025 14:05:15 +0200 Subject: [PATCH 14/37] Modified buildTRKNewVacuumVessel --- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 3 --- 1 file changed, 3 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index c0568fc86e264..6b3b63d6d2d72 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -127,9 +127,6 @@ void Detector::buildTRKNewVacuumVessel() mLayers.clear(); LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); - // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 4, 100.e-4); - // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 4, 100.e-4); - // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 4, 100.e-4); mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 10, 100.e-3); LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 10, 100.e-3); From 78e96a6beda3b7e138b50b23f27a259383e92282 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 10 Oct 2025 14:46:38 +0200 Subject: [PATCH 15/37] Dummy implementation --- Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 8f87282cff375..d03296dd6d9c1 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -216,6 +216,8 @@ int GeometryTGeo::getDisk(int index) const int GeometryTGeo::getModule(int index) const { int subDetID = getSubDetID(index); + + return -1; /// not implemented yet } //__________________________________________________________________________ From 98a18c5988eb9bcfff261936482a29f8f0ac45de Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 10 Oct 2025 15:26:54 +0200 Subject: [PATCH 16/37] Fix include --- .../ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index 6bb7d0e2064a6..dc3199928ddaa 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -16,6 +16,7 @@ #include #include "TRKBase/TRKBaseParam.h" +#include "TRKBase/Specs.h" namespace o2 { From 59ff15d20d0cd4d1ce26d9bf66cf28d7d5ef5fbe Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 10 Oct 2025 15:52:36 +0200 Subject: [PATCH 17/37] Fix half staves for staggered --- Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 412c2155f4f62..25454bdc5ac8e 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -240,7 +240,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) staveVol->AddNode(moduleVolLeft, iModule * 2, transLeft); TGeoCombiTrans* transRight = new TGeoCombiTrans(); - transRight->SetTranslation(xRight, 0, zPos); // TO BE CHECKED !!! 1mm overlap between the modules + transRight->SetTranslation(xRight, 0.2, zPos); // TO BE CHECKED !!! 1mm overlap between the modules LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVolRight, iModule * 2 + 1, transRight); } From 614f9a9fcb5e71040e4e6ffac1f0fa45e7031a89 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Mon, 13 Oct 2025 17:32:26 +0200 Subject: [PATCH 18/37] Fix --- Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 25454bdc5ac8e..52355a17e6795 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -197,7 +197,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVol, 1, nullptr); } else if (type == "flat") { - double moduleLength = constants::ML::length; + double moduleLength = constants::moduleMLOT::length; double staveWidth = constants::ML::width; double staveLength = constants::ML::length; @@ -208,7 +208,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) TGeoVolume* moduleVol = createModule("flat"); // Put the modules in the correct position - double zPos = -0.5 * (mNumberOfModules - 1) * moduleLength + iModule * moduleLength; + double zPos = -0.5 * mNumberOfModules * moduleLength + (iModule + 0.5) * moduleLength; TGeoCombiTrans* trans = new TGeoCombiTrans(); trans->SetTranslation(0, 0, zPos); // TO BE CHECKED !!! @@ -232,7 +232,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) // Put the modules in the correct position double xLeft = -moduleWidth / 2 + 0.05; double xRight = moduleWidth / 2 - 0.05; - double zPos = -0.5 * (mNumberOfModules - 1) * moduleLength + iModule * moduleLength; + double zPos = -0.5 * mNumberOfModules * moduleLength + (iModule + 0.5) * moduleLength; TGeoCombiTrans* transLeft = new TGeoCombiTrans(); transLeft->SetTranslation(xLeft, 0, zPos); // TO BE CHECKED !!! 1mm overlap between the modules @@ -277,7 +277,6 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume) double staveWidth = constants::ML::width; // Each stave has two modules (based on the LOI design) if (mInnerRadius > 25) { - layerLength = constants::OT::length; staveWidth = constants::OT::width; // Outer layers have two modules per stave } From 336dceffa94e0da297aea4591fddfb932a9d58e3 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 15 Oct 2025 12:54:17 +0200 Subject: [PATCH 19/37] Update indexing scheme --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 37 ++++++-- .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 95 ++++++++++++++++--- 2 files changed, 111 insertions(+), 21 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index 0bac9b499c59d..85f3b538df162 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -46,6 +46,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static const char* getTRKPetalDiskPattern() { return sPetalDiskName.c_str(); } static const char* getTRKPetalLayerPattern() { return sPetalLayerName.c_str(); } static const char* getTRKStavePattern() { return sStaveName.c_str(); } + static const char* getTRKHalfStavePattern() { return sHalfStaveName.c_str(); } static const char* getTRKModulePattern() { return sModuleName.c_str(); } static const char* getTRKChipPattern() { return sChipName.c_str(); } static const char* getTRKSensorPattern() { return sSensorName.c_str(); } @@ -64,6 +65,8 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache int extractNumberOfChipsPerPetalVD() const; int extractNumberOfStavesMLOT(int lay) const; int extractNumberOfHalfStavesMLOT(int lay) const; + int extractNumberOfModulesMLOT(int lay) const; + int extractNumberOfChipsMLOT(int lay) const; /// Extract number following the prefix in the name string int extractVolumeCopy(const char* name, const char* prefix) const; @@ -85,6 +88,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache int getHalfStave(int index) const; int getDisk(int index) const; int getModule(int index) const; + int getChip(int index) const; /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave /// TODO: retrieve also from chip when chips will be available /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT @@ -93,7 +97,9 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int lay The layer number. Starting from 0 both for VD and MLOT /// \param int stave The stave number for MLOT. Starting from 0 /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 - int getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const; + /// \param int module The module number for MLOT, from 0 to 10 (or 20) + /// \param int chip The chip number for MLOT, from 0 to 8 + int getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int module, int chip) const; /// This routine computes the chip index number from the subDetID, volume, layer, stave /// TODO: retrieve also from chip when chips will be available /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT @@ -101,7 +107,9 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int lay The layer number for the MLOT. In the current configuration for VD this is not needed. // TODO: when the geometry naming scheme will be changed, change this method /// \param int stave The stave number in each layer for MLOT. Starting from 0. /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 - int getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave) const; + /// \param int module The module number for MLOT, from 0 to 10 (or 20) + /// \param int chip The chip number for MLOT, from 0 to 8 + int getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int module, int chip) const; /// This routine computes subDetID, petal, disk, layer, stave given the chip index number /// TODO: copute also from chip when chips will be available /// \param int index The chip index number, starting from 0 @@ -111,7 +119,9 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int lay The layer number. Starting from 0 both for VD and MLOT /// \param int stave The stave number for MLOT. Starting from 0 /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 - bool getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave) const; + /// \param int module The module number for MLOT, from 0 to 10 (or 20) + /// \param int chip The chip number for MLOT, from 0 to 8 + bool getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& module, int& chip) const; int getLastChipIndex(int lay) const { return mLastChipIndex[lay]; } int getFirstChipIndex(int lay, int petalcase, int subDetID) const @@ -147,6 +157,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static std::string sPetalDiskName; static std::string sPetalLayerName; static std::string sStaveName; + static std::string sHalfStaveName; static std::string sModuleName; static std::string sChipName; static std::string sSensorName; @@ -159,16 +170,22 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache Int_t mNumberOfLayersVD; ///< number of layers Int_t mNumberOfPetalsVD; ///< number of Petals = chip in each VD layer Int_t mNumberOfDisksVD; ///< number of Disks = 6 - std::vector mLastChipIndex; ///< max ID of the detctor in the petal(VD) or layer(MLOT) - std::vector mLastChipIndexVD; ///< max ID of the detctor in the layer for the VD - std::vector mLastChipIndexMLOT; ///< max ID of the detctor in the layer for the MLOT + std::vector mNumberOfStaves; ///< Number Of Staves per layer in ML/OT + std::vector mNumberOfHalfStaves; ///< Number Of Half staves in each stave of the layer in ML/OT + std::vector mNumberOfModules; ///< Number Of Modules per stave (half stave) in ML/OT + std::vector mNumberOfChips; ///< number of chips per module in ML/OT std::vector mNumberOfChipsPerLayerVD; ///< number of chips per layer VD ( = number of petals) - std::vector mNumberOfChipsPerLayerMLOT; ///< number of chips per layer MLOT ( = 1 for the moment) + std::vector mNumberOfChipsPerLayerMLOT; ///< number of chips per layer MLOT std::vector mNumbersOfChipPerDiskVD; ///< numbersOfChipPerDiskVD std::vector mNumberOfChipsPerPetalVD; ///< numbersOfChipPerPetalVD - std::vector mNumberOfStaves; ///< Number Of Staves per layer in ML/OT - std::vector mNumberOfHalfStaves; ///< Number Of Staves in each stave of the layer in ML/OT - std::array mLayerToWrapper; ///< Layer to wrapper correspondence + // std::vector mNumberOfChipsPerStave; ///< number of chips per stave in ML/OT + // std::vector mNumberOfChipsPerHalfStave; ///< number of chips per half stave in ML/OT + // std::vector mNumberOfChipsPerModule; ///< number of chips per module in ML/OT + std::vector mLastChipIndex; ///< max ID of the detctor in the petal(VD) or layer(MLOT) + std::vector mLastChipIndexVD; ///< max ID of the detctor in the layer for the VD + std::vector mLastChipIndexMLOT; ///< max ID of the detctor in the layer for the MLOT + + std::array mLayerToWrapper; ///< Layer to wrapper correspondence, not implemented yet bool mOwner = true; //! is it owned by the singleton? diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index d03296dd6d9c1..5fe3e70f8ad45 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -28,6 +28,7 @@ std::string GeometryTGeo::sPetalName = "PETALCASE"; std::string GeometryTGeo::sPetalDiskName = "DISK"; std::string GeometryTGeo::sPetalLayerName = "LAYER"; std::string GeometryTGeo::sStaveName = "TRKStave"; +std::string GeometryTGeo::sHalfStaveName = "TRKHalfStave"; std::string GeometryTGeo::sModuleName = "TRKModule"; std::string GeometryTGeo::sChipName = "TRKChip"; std::string GeometryTGeo::sSensorName = "TRKSensor"; @@ -78,18 +79,24 @@ void GeometryTGeo::Build(int loadTrans) mNumberOfStaves.resize(mNumberOfLayersMLOT); mNumberOfHalfStaves.resize(mNumberOfLayersMLOT); - mLastChipIndex.resize(mNumberOfPetalsVD + mNumberOfLayersMLOT); - mLastChipIndexVD.resize(mNumberOfPetalsVD); - mLastChipIndexMLOT.resize(mNumberOfLayersMLOT); /// ML and OT are part of TRK as the same detector, without disks + mNumberOfModules.resize(mNumberOfLayersMLOT); + mNumberOfChips.resize(mNumberOfLayersMLOT); + mNumberOfChipsPerLayerVD.resize(mNumberOfLayersVD); mNumberOfChipsPerLayerMLOT.resize(mNumberOfLayersMLOT); mNumbersOfChipPerDiskVD.resize(mNumberOfDisksVD); mNumberOfChipsPerPetalVD.resize(mNumberOfPetalsVD); + mLastChipIndex.resize(mNumberOfPetalsVD + mNumberOfLayersMLOT); + mLastChipIndexVD.resize(mNumberOfPetalsVD); + mLastChipIndexMLOT.resize(mNumberOfLayersMLOT); /// ML and OT are part of TRK as the same detector, without disks + for (int i = 0; i < mNumberOfLayersMLOT; i++) { std::cout << "Layer MLOT: " << i << std::endl; mNumberOfStaves[i] = extractNumberOfStavesMLOT(i); mNumberOfHalfStaves[i] = extractNumberOfHalfStavesMLOT(i); + mNumberOfModules[i] = extractNumberOfModulesMLOT(i); + mNumberOfChips[i] = extractNumberOfChipsMLOT(i); } int numberOfChipsTotal = 0; @@ -104,13 +111,13 @@ void GeometryTGeo::Build(int loadTrans) /// filling the information for the MLOT for (int i = 0; i < mNumberOfLayersMLOT; i++) { - mNumberOfChipsPerLayerMLOT[i] = extractNumberOfStavesMLOT(i) * extractNumberOfHalfStavesMLOT(i); // for the moment, considering 1 half stave = 1 chip. TODO: add the final segmentation in chips + mNumberOfChipsPerLayerMLOT[i] = mNumberOfStaves[i] * mNumberOfHalfStaves[i] * mNumberOfModules[i] * mNumberOfChips[i]; numberOfChipsTotal += mNumberOfChipsPerLayerMLOT[i]; mLastChipIndex[i + mNumberOfPetalsVD] = numberOfChipsTotal - 1; mLastChipIndexMLOT[i] = numberOfChipsTotal - 1; } - setSize(numberOfChipsTotal); /// temporary, number of chips = number of staves and active parts + setSize(numberOfChipsTotal); fillMatrixCache(loadTrans); } @@ -221,7 +228,15 @@ int GeometryTGeo::getModule(int index) const } //__________________________________________________________________________ -int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const +int GeometryTGeo::getChip(int index) const +{ + int subDetID = getSubDetID(index); + + return -1; /// not implemented yet +} + +//__________________________________________________________________________ +int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int module, int chip) const { if (subDetID == 0) { // VD if (lay == -1) { // disk @@ -240,7 +255,7 @@ int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, i } //__________________________________________________________________________ -int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave) const +int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int module, int chip) const { if (subDetID == 0) { // VD return volume; /// In the current configuration for VD, each volume is the sensor element = chip. // TODO: when the geometry naming scheme will be changed, change this method @@ -256,7 +271,7 @@ int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int } //__________________________________________________________________________ -bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave) const +bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& module, int& chip) const { subDetID = getSubDetID(index); petalcase = getPetalCase(index); @@ -264,6 +279,8 @@ bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk lay = getLayer(index); stave = getStave(index); halfstave = getHalfStave(index); + module = getModule(index); + chip = getChip(index); return kTRUE; } @@ -272,8 +289,8 @@ bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk TString GeometryTGeo::getMatrixPath(int index) const { - int subDetID, petalcase, disk, layer, stave, halfstave; //// TODO: add chips in a second step - getChipID(index, subDetID, petalcase, disk, layer, stave, halfstave); + int subDetID, petalcase, disk, layer, stave, halfstave, module, chip; //// TODO: add chips in a second step + getChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, module, chip); // PrintChipID(index, subDetID, petalcase, disk, layer, stave, halfstave); @@ -662,13 +679,69 @@ int GeometryTGeo::extractNumberOfHalfStavesMLOT(int lay) const for (int j = 0; j < nNodes; j++) { auto nd = dynamic_cast(nodes->At(j)); /// layer node const char* name = nd->GetName(); - if (strstr(name, getTRKChipPattern()) != nullptr) { + if (strstr(name, getTRKHalfStavePattern()) != nullptr) { numberOfHalfStaves++; } } + + if (numberOfHalfStaves == 0) { + numberOfHalfStaves = 1; /// in case of turbo geometry, there is no half stave volume, but only stave volume + } return numberOfHalfStaves; } +//__________________________________________________________________________ +int GeometryTGeo::extractNumberOfModulesMLOT(int lay) const +{ + int numberOfModules = 0; + + std::string staveName = Form("%s%d", getTRKStavePattern(), lay); + TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str()); + + if (staveV == nullptr) { + LOG(fatal) << getName() << " volume " << getTRKStavePattern() << " is not in the geometry"; + } + + // Loop on all staveV nodes, count Module volumes by checking names + TObjArray* nodes = staveV->GetNodes(); + int nNodes = nodes->GetEntriesFast(); + + for (int j = 0; j < nNodes; j++) { + auto nd = dynamic_cast(nodes->At(j)); /// stave node + const char* name = nd->GetName(); + if (strstr(name, getTRKModulePattern()) != nullptr) { + numberOfModules++; + } + } + return numberOfModules; +} + +//__________________________________________________________________________ +int GeometryTGeo::extractNumberOfChipsMLOT(int lay) const +{ + int numberOfChips = 0; + + std::string moduleName = Form("%s%d", getTRKModulePattern(), lay); + TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str()); + + if (moduleV == nullptr) { + LOG(fatal) << getName() << " volume " << getTRKModulePattern() << " is not in the geometry"; + } + + // Loop on all moduleV nodes, count Chip volumes by checking names + TObjArray* nodes = moduleV->GetNodes(); + int nNodes = nodes->GetEntriesFast(); + + for (int j = 0; j < nNodes; j++) { + auto nd = dynamic_cast(nodes->At(j)); /// module node + const char* name = nd->GetName(); + if (strstr(name, getTRKChipPattern()) != nullptr) { + numberOfChips++; + } + } + return numberOfChips; +} + //__________________________________________________________________________ void GeometryTGeo::PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const { From 67553cbf6cd9f1bfe317d9c3bfeb868f00b302f3 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 15 Oct 2025 12:58:29 +0200 Subject: [PATCH 20/37] change variables named module to mod --- .../ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h | 6 +++--- .../Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index 85f3b538df162..b210c54386027 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -99,7 +99,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 /// \param int module The module number for MLOT, from 0 to 10 (or 20) /// \param int chip The chip number for MLOT, from 0 to 8 - int getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int module, int chip) const; + int getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const; /// This routine computes the chip index number from the subDetID, volume, layer, stave /// TODO: retrieve also from chip when chips will be available /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT @@ -109,7 +109,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 /// \param int module The module number for MLOT, from 0 to 10 (or 20) /// \param int chip The chip number for MLOT, from 0 to 8 - int getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int module, int chip) const; + int getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const; /// This routine computes subDetID, petal, disk, layer, stave given the chip index number /// TODO: copute also from chip when chips will be available /// \param int index The chip index number, starting from 0 @@ -121,7 +121,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 /// \param int module The module number for MLOT, from 0 to 10 (or 20) /// \param int chip The chip number for MLOT, from 0 to 8 - bool getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& module, int& chip) const; + bool getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& mod, int& chip) const; int getLastChipIndex(int lay) const { return mLastChipIndex[lay]; } int getFirstChipIndex(int lay, int petalcase, int subDetID) const diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 5fe3e70f8ad45..f5b58634992cd 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -236,7 +236,7 @@ int GeometryTGeo::getChip(int index) const } //__________________________________________________________________________ -int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int module, int chip) const +int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const { if (subDetID == 0) { // VD if (lay == -1) { // disk @@ -255,7 +255,7 @@ int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, i } //__________________________________________________________________________ -int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int module, int chip) const +int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const { if (subDetID == 0) { // VD return volume; /// In the current configuration for VD, each volume is the sensor element = chip. // TODO: when the geometry naming scheme will be changed, change this method @@ -271,7 +271,7 @@ int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int } //__________________________________________________________________________ -bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& module, int& chip) const +bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& mod, int& chip) const { subDetID = getSubDetID(index); petalcase = getPetalCase(index); @@ -279,7 +279,7 @@ bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk lay = getLayer(index); stave = getStave(index); halfstave = getHalfStave(index); - module = getModule(index); + mod = getModule(index); chip = getChip(index); return kTRUE; @@ -289,8 +289,8 @@ bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk TString GeometryTGeo::getMatrixPath(int index) const { - int subDetID, petalcase, disk, layer, stave, halfstave, module, chip; //// TODO: add chips in a second step - getChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, module, chip); + int subDetID, petalcase, disk, layer, stave, halfstave, mod, chip; //// TODO: add chips in a second step + getChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, mod, chip); // PrintChipID(index, subDetID, petalcase, disk, layer, stave, halfstave); From fc6071bf2bc28a4411f767f3194194deeab46cee Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 15 Oct 2025 14:57:37 +0200 Subject: [PATCH 21/37] createHalfStave --- .../include/TRKSimulation/TRKLayer.h | 1 + .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 67 +++++++++++++++++-- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index dc3199928ddaa..b99686d423382 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -45,6 +45,7 @@ class TRKLayer TGeoVolume* createChip(std::string type); TGeoVolume* createModule(std::string type); TGeoVolume* createStave(std::string type); + TGeoVolume* createHalfStave(std::string type); void createLayer(TGeoVolume* motherVolume); private: diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 52355a17e6795..29e6077575a21 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -181,6 +181,45 @@ TGeoVolume* TRKLayer::createModule(std::string type) return moduleVol; } +TGeoVolume* TRKLayer::createHalfStave(std::string type) +{ + TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); + std::string halfStaveName = GeometryTGeo::getTRKHalfStavePattern() + std::to_string(mLayerNumber); + + TGeoShape* halfStave; + TGeoVolume* halfStaveVol; + + if (type == "cylinder") { + halfStave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); + halfStaveVol = new TGeoVolume(halfStaveName.c_str(), halfStave, medAir); + + TGeoVolume* moduleVol = createModule("cylinder"); + LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), halfStaveVol->GetName()); + halfStaveVol->AddNode(moduleVol, 1, nullptr); + } else if (type == "flat") { + double moduleLength = constants::moduleMLOT::length; + double staveWidth = constants::ML::width; + double staveLength = constants::ML::length; + + halfStave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, staveLength / 2); + halfStaveVol = new TGeoVolume(halfStaveName.c_str(), halfStave, medAir); + + for (int iModule = 0; iModule < mNumberOfModules; iModule++) { + TGeoVolume* moduleVol = createModule("flat"); + + // Put the modules in the correct position + double zPos = -0.5 * mNumberOfModules * moduleLength + (iModule + 0.5) * moduleLength; + + TGeoCombiTrans* trans = new TGeoCombiTrans(); + trans->SetTranslation(0, 0, zPos); // TO BE CHECKED !!! + + LOGP(info, "Inserting {} in {} ", moduleVol->GetName(), halfStaveVol->GetName()); + halfStaveVol->AddNode(moduleVol, iModule, trans); + } + } + return halfStaveVol; +} + TGeoVolume* TRKLayer::createStave(std::string type) { TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); @@ -199,7 +238,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) } else if (type == "flat") { double moduleLength = constants::moduleMLOT::length; double staveWidth = constants::ML::width; - double staveLength = constants::ML::length; + double staveLength = constants::moduleMLOT::length * mNumberOfModules; stave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); @@ -217,15 +256,17 @@ TGeoVolume* TRKLayer::createStave(std::string type) staveVol->AddNode(moduleVol, iModule, trans); } } else if (type == "staggered") { - double moduleWidth = constants::moduleMLOT::width; - double moduleLength = constants::moduleMLOT::length; + /*double moduleWidth = constants::moduleMLOT::width; + double moduleLength = constants::moduleMLOT::length;*/ + + double halfstaveWidth = constants::ML::width; double staveWidth = constants::OT::width; // Each stave has two modules (based on the LOI design) - double staveLength = constants::OT::length; + double staveLength = constants::moduleMLOT::length * mNumberOfModules; stave = new TGeoBBox(staveWidth / 2, mLogicalVolumeThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - for (int iModule = 0; iModule < mNumberOfModules; iModule++) { + /*for (int iModule = 0; iModule < mNumberOfModules; iModule++) { TGeoVolume* moduleVolLeft = createModule("flat"); TGeoVolume* moduleVolRight = createModule("flat"); @@ -243,7 +284,21 @@ TGeoVolume* TRKLayer::createStave(std::string type) transRight->SetTranslation(xRight, 0.2, zPos); // TO BE CHECKED !!! 1mm overlap between the modules LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); staveVol->AddNode(moduleVolRight, iModule * 2 + 1, transRight); - } + }*/ + + // Put the half staves in the correct position + TGeoVolume* halfStaveVolLeft = createHalfStave("flat"); + TGeoVolume* halfStaveVolRight = createHalfStave("flat"); + + TGeoCombiTrans* transLeft = new TGeoCombiTrans(); + transLeft->SetTranslation(-halfstaveWidth / 2 + 0.05, 0, 0); // TO BE CHECKED !!! 1mm overlap between the modules + LOGP(info, "Inserting {} in {} ", halfStaveVolLeft->GetName(), staveVol->GetName()); + staveVol->AddNode(halfStaveVolLeft, 0, transLeft); + + TGeoCombiTrans* transRight = new TGeoCombiTrans(); + transRight->SetTranslation(halfstaveWidth / 2 - 0.05, 0, 0); // TO BE CHECKED !!! 1mm overlap between the modules + LOGP(info, "Inserting {} in {} ", halfStaveVolRight->GetName(), staveVol->GetName()); + staveVol->AddNode(halfStaveVolRight, 1, transRight); } else { LOGP(fatal, "Chip of type '{}' is not implemented", type); } From 684c956415ee0bb923d2830b1d315c68717c47eb Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 15 Oct 2025 16:28:53 +0200 Subject: [PATCH 22/37] Update indexing scheme --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 2 +- .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 44 ++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index b210c54386027..7d4ba3cea4e38 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -79,7 +79,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache void setOwner(bool v) { mOwner = v; } void Print(Option_t* opt = "") const; - void PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const; + void PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const; int getSubDetID(int index) const; int getPetalCase(int index) const; diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index f5b58634992cd..cbd10aa7c7d25 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -246,9 +246,9 @@ int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, i } } else if (subDetID == 1) { // MLOT if (mNumberOfHalfStaves[lay] == 2) { // staggered geometry - return getFirstChipIndex(lay, petalcase, subDetID) + stave * mNumberOfHalfStaves[lay] + halfstave; + return getFirstChipIndex(lay, petalcase, subDetID) + stave * mNumberOfHalfStaves[lay] + halfstave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; } else if (mNumberOfHalfStaves[lay] == 1) { // turbo geometry - return getFirstChipIndex(lay, petalcase, subDetID) + stave; + return getFirstChipIndex(lay, petalcase, subDetID) + stave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; } } return -1; // not found @@ -262,9 +262,9 @@ int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int } else if (subDetID == 1) { // MLOT if (mNumberOfHalfStaves[lay] == 2) { // staggered geometry - return getFirstChipIndex(lay, -1, subDetID) + stave * mNumberOfHalfStaves[lay] + halfstave; + return getFirstChipIndex(lay, -1, subDetID) + stave * mNumberOfHalfStaves[lay] + halfstave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; } else if (mNumberOfHalfStaves[lay] == 1) { // turbo geometry - return getFirstChipIndex(lay, -1, subDetID) + stave; + return getFirstChipIndex(lay, -1, subDetID) + stave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; } } return -1; // not found @@ -289,10 +289,10 @@ bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk TString GeometryTGeo::getMatrixPath(int index) const { - int subDetID, petalcase, disk, layer, stave, halfstave, mod, chip; //// TODO: add chips in a second step + int subDetID, petalcase, disk, layer, stave, halfstave, mod, chip; getChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, mod, chip); - // PrintChipID(index, subDetID, petalcase, disk, layer, stave, halfstave); + // PrintChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, mod, chip); // TString path = "/cave_1/barrel_1/TRKV_2/TRKLayer0_1/TRKStave0_1/TRKChip0_1/TRKSensor0_1/"; /// dummy path, to be used for tests TString path = Form("/cave_1/barrel_1/%s_2/", GeometryTGeo::getTRKVolPattern()); @@ -308,15 +308,15 @@ TString GeometryTGeo::getMatrixPath(int index) const path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalLayerPattern(), layer, getTRKChipPattern(), layer); // PETALCASEx_LAYERy_TRKChipy_1 path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalLayerPattern(), layer, getTRKSensorPattern(), layer); // PETALCASEx_LAYERy_TRKSensory_1 } - } else if (subDetID == 1) { // MLOT - path += Form("%s%d_1/", getTRKLayerPattern(), layer); // TRKLayerx_1 - path += Form("%s%d_%d/", getTRKStavePattern(), layer, stave); // TRKStavex_y - if (mNumberOfHalfStaves[layer] == 2) { // staggered geometry - path += Form("%s%d_%d/", getTRKChipPattern(), layer, halfstave); // TRKChipx_0/1 - } else if (mNumberOfHalfStaves[layer] == 1) { // turbo geometry - path += Form("%s%d_1/", getTRKChipPattern(), layer); // TRKChipx_1 + } else if (subDetID == 1) { // MLOT + path += Form("%s%d_1/", getTRKLayerPattern(), layer); // TRKLayerx_1 + path += Form("%s%d_%d/", getTRKStavePattern(), layer, stave); // TRKStavex_y + if (mNumberOfHalfStaves[layer] == 2) { // staggered geometry + path += Form("%s%d_%d/", getTRKHalfStavePattern(), layer, halfstave); // TRKHalfStavex_y } - path += Form("%s%d_1/", getTRKSensorPattern(), layer); // TRKSensorx_1 + path += Form("%s%d_%d/", getTRKModulePattern(), layer, mod); // TRKModulx_y + path += Form("%s%d_%d/", getTRKChipPattern(), layer, chip); // TRKChipx_y + path += Form("%s%d_1/", getTRKSensorPattern(), layer); // TRKSensorx_1 } return path; } @@ -743,7 +743,7 @@ int GeometryTGeo::extractNumberOfChipsMLOT(int lay) const } //__________________________________________________________________________ -void GeometryTGeo::PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave) const +void GeometryTGeo::PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const { std::cout << "\nindex = " << index << std::endl; std::cout << "subDetID = " << subDetID << std::endl; @@ -753,6 +753,8 @@ void GeometryTGeo::PrintChipID(int index, int subDetID, int petalcase, int disk, std::cout << "first chip index = " << getFirstChipIndex(lay, petalcase, subDetID) << std::endl; std::cout << "stave = " << stave << std::endl; std::cout << "halfstave = " << halfstave << std::endl; + std::cout << "module = " << mod << std::endl; + std::cout << "chip = " << chip << std::endl; } //__________________________________________________________________________ @@ -780,6 +782,18 @@ void GeometryTGeo::Print(Option_t*) const mlot = (i < 4) ? "ML" : "OT"; LOGF(info, "Layer: %d, %s, %d staves, %d half staves per stave", i, mlot.c_str(), mNumberOfStaves[i], mNumberOfHalfStaves[i]); } + LOGF(info, "Number of modules per layer MLOT: "); + for (int i = 0; i < mNumberOfLayersMLOT; i++) { + LOGF(info, "%d", mNumberOfModules[i]); + } + LOGF(info, "Number of chips per module MLOT: "); + for (int i = 0; i < mNumberOfLayersMLOT; i++) { + LOGF(info, "%d", mNumberOfChips[i]); + } + LOGF(info, "Number of chips per layer MLOT: "); + for (int i = 0; i < mNumberOfLayersMLOT; i++) { + LOGF(info, "%d", mNumberOfChipsPerLayerMLOT[i]); + } LOGF(info, "Total number of chips: %d", getNumberOfChips()); std::cout << "mLastChipIndex = ["; From af11dc97d88a6fbcfa6c25cbb1954a14ad722fa4 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 15 Oct 2025 16:35:25 +0200 Subject: [PATCH 23/37] Fix namespace --- Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 29e6077575a21..e2512b78c244c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -198,10 +198,10 @@ TGeoVolume* TRKLayer::createHalfStave(std::string type) halfStaveVol->AddNode(moduleVol, 1, nullptr); } else if (type == "flat") { double moduleLength = constants::moduleMLOT::length; - double staveWidth = constants::ML::width; - double staveLength = constants::ML::length; + double halfStaveWidth = constants::OT::halfstave::width; + double halfStaveLength = constants::moduleMLOT::length * mNumberOfModules; - halfStave = new TGeoBBox(staveWidth / 2, mChipThickness / 2, staveLength / 2); + halfStave = new TGeoBBox(halfStaveWidth / 2, mChipThickness / 2, halfStaveLength / 2); halfStaveVol = new TGeoVolume(halfStaveName.c_str(), halfStave, medAir); for (int iModule = 0; iModule < mNumberOfModules; iModule++) { From e829a3f95b68d0e867cfdaff253349962a74f003 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 15 Oct 2025 17:22:43 +0200 Subject: [PATCH 24/37] Update ProcessHits --- .../include/TRKSimulation/Detector.h | 2 +- .../ALICE3/TRK/simulation/src/Detector.cxx | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h index 8ed5737abcb35..daa2fb8c09db4 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h @@ -109,7 +109,7 @@ class Detector : public o2::base::DetImpl int getNumberOfLayersVD() const { return mPetalCases[0].mPetalLayers.size(); } int getNumberOfDisksVD() const { return mPetalCases[0].mPetalDisks.size(); } - void Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int chipID) const; + void Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int mod, int chip, int chipID) const; template friend class o2::base::DetImpl; diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 6b3b63d6d2d72..0f2523579861c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -444,15 +444,17 @@ bool Detector::ProcessHits(FairVolume* vol) TLorentzVector positionStop; fMC->TrackPosition(positionStop); // Retrieve the indices with the volume path - int stave(0), halfstave(0); + int stave(0), halfstave(0), mod(0), chip(0); if (subDetID == 1) { - fMC->CurrentVolOffID(1, halfstave); - fMC->CurrentVolOffID(2, stave); + fMC->CurrentVolOffID(1, chip); + fMC->CurrentVolOffID(2, mod); + fMC->CurrentVolOffID(3, halfstave); + fMC->CurrentVolOffID(4, stave); } /// if VD, for the moment the volume is the "chipID" so no need to retrieve other elments - int chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave); + int chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip); - Print(vol, volume, subDetID, layer, stave, halfstave, chipID); + Print(vol, volume, subDetID, layer, stave, halfstave, mod, chip, chipID); Hit* p = addHit(stack->GetCurrentTrackNumber(), chipID, mTrackData.mPositionStart.Vect(), positionStop.Vect(), mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(), @@ -475,17 +477,19 @@ o2::itsmft::Hit* Detector::addHit(int trackID, int detID, const TVector3& startP return &(mHits->back()); } -void Detector::Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int chipID) const +void Detector::Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int mod, int chip, int chipID) const { int currentVol(0); LOG(info) << "Current volume name: " << fMC->CurrentVolName() << " and ID " << fMC->CurrentVolID(currentVol); LOG(info) << "volume: " << volume << "/" << mNumberOfVolumes - 1; + LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " chip: " << chip; + LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " module: " << mod; if (subDetID == 1 && mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) { // staggered geometry - LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " halfstave: " << halfstave; - LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " stave: " << stave; + LOG(info) << "off volume name 3 " << fMC->CurrentVolOffName(3) << " halfstave: " << halfstave; + LOG(info) << "off volume name 4 " << fMC->CurrentVolOffName(4) << " stave: " << stave; LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID; } else if (subDetID == 1 && mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) { // turbo geometry - LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " stave: " << stave; + LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(3) << " stave: " << stave; LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID; } else { LOG(info) << "SubDetector ID: " << subDetID << " Chip ID: " << chipID; From a1c3a5a36e4f66d66960307aa802123c4eca8f7a Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 16 Oct 2025 10:52:50 +0200 Subject: [PATCH 25/37] Update indexing scheme - fix bug --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 8 +- .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 148 ++++++++++++++---- .../ALICE3/TRK/simulation/src/Detector.cxx | 3 - 3 files changed, 123 insertions(+), 36 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index 7d4ba3cea4e38..720aa87dd9d6c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -83,14 +83,14 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache int getSubDetID(int index) const; int getPetalCase(int index) const; + int getDisk(int index) const; int getLayer(int index) const; int getStave(int index) const; int getHalfStave(int index) const; - int getDisk(int index) const; int getModule(int index) const; int getChip(int index) const; - /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave /// TODO: retrieve also from chip when chips will be available + /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave, half stave, module, chip /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT /// \param int petalcase The petal case number for VD, from 0 to 3 /// \param int disk The disk number for VD, from 0 to 5 @@ -101,7 +101,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int chip The chip number for MLOT, from 0 to 8 int getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const; - /// This routine computes the chip index number from the subDetID, volume, layer, stave /// TODO: retrieve also from chip when chips will be available + /// This routine computes the chip index number from the subDetID, volume, layer, stave, half stave, module, chip /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT /// \param int volume is needed only with the current configuration for VD where each single element is a volume. // TODO: when the geometry naming scheme will be changed, change this method /// \param int lay The layer number for the MLOT. In the current configuration for VD this is not needed. // TODO: when the geometry naming scheme will be changed, change this method @@ -111,7 +111,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int chip The chip number for MLOT, from 0 to 8 int getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const; - /// This routine computes subDetID, petal, disk, layer, stave given the chip index number /// TODO: copute also from chip when chips will be available + /// This routine computes subDetID, petal, disk, layer, stave, half stave, module, chip, given the chip index number /// \param int index The chip index number, starting from 0 /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT /// \param int petalcase The petal case number for VD, from 0 to 3 diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index cbd10aa7c7d25..8ea6faf443d03 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -148,6 +148,22 @@ int GeometryTGeo::getPetalCase(int index) const return petalcase; } +//__________________________________________________________________________ +int GeometryTGeo::getDisk(int index) const +{ + int subDetID = getSubDetID(index); + int petalcase = getPetalCase(index); + + if (subDetID == 0) { /// VD + if (index % mNumberOfChipsPerPetalVD[petalcase] < mNumberOfLayersVD) { + return -1; /// layers + } + return (index % mNumberOfChipsPerPetalVD[petalcase]) - mNumberOfLayersVD; + } + + return -1; /// not found or ML/OT +} + //__________________________________________________________________________ int GeometryTGeo::getLayer(int index) const { @@ -180,9 +196,23 @@ int GeometryTGeo::getStave(int index) const } else if (subDetID == 1) { /// MLOT int lay = getLayer(index); index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer - return index / mNumberOfHalfStaves[lay]; + + const int Nhs = mNumberOfHalfStaves[lay]; + const int Nmod = mNumberOfModules[lay]; + const int Nchip = mNumberOfChips[lay]; + + if (Nhs == 2) { + int chipsPerModule = Nchip; + int chipsPerHalfStave = Nmod * chipsPerModule; + int chipsPerStave = Nhs * chipsPerHalfStave; + return index / chipsPerStave; + } else if (Nhs == 1) { + int chipsPerModule = Nchip; + int chipsPerStave = Nmod * chipsPerModule; + return index / chipsPerStave; + } } - return -1; /// not found + return -1; } //__________________________________________________________________________ @@ -191,48 +221,85 @@ int GeometryTGeo::getHalfStave(int index) const int subDetID = getSubDetID(index); int lay = getLayer(index); int petalcase = getPetalCase(index); - int stave = getStave(index); if (subDetID == 0) { /// VD return -1; } else if (subDetID == 1) { /// MLOT int lay = getLayer(index); index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer - return index % 2; /// 0 = half stave left, 1 = half stave right, as geometry is filled /// TODO: generalize once chips will be in place. Can it be working also with chips? + + const int Nhs = mNumberOfHalfStaves[lay]; + const int Nmod = mNumberOfModules[lay]; + const int Nchip = mNumberOfChips[lay]; + + int chipsPerModule = Nchip; + int chipsPerHalfStave = Nmod * chipsPerModule; + int chipsPerStave = Nhs * chipsPerHalfStave; + + int rem = index % chipsPerStave; + return rem / chipsPerHalfStave; // 0 = left, 1 = right } - return -1; /// not found + return -1; } //__________________________________________________________________________ -int GeometryTGeo::getDisk(int index) const +int GeometryTGeo::getModule(int index) const { int subDetID = getSubDetID(index); + int lay = getLayer(index); int petalcase = getPetalCase(index); if (subDetID == 0) { /// VD - if (index % mNumberOfChipsPerPetalVD[petalcase] < mNumberOfLayersVD) { - return -1; /// layers + return -1; + } else if (subDetID == 1) { /// MLOT + int lay = getLayer(index); + index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer + + const int Nhs = mNumberOfHalfStaves[lay]; + const int Nmod = mNumberOfModules[lay]; + const int Nchip = mNumberOfChips[lay]; + + if (Nhs == 2) { + int chipsPerModule = Nchip; + int chipsPerHalfStave = Nmod * chipsPerModule; + int rem = index % (Nhs * chipsPerHalfStave); + rem = rem % chipsPerHalfStave; + return rem / chipsPerModule; + } else if (Nhs == 1) { + int chipsPerModule = Nchip; + int rem = index % (Nmod * chipsPerModule); + return rem / chipsPerModule; } - return (index % mNumberOfChipsPerPetalVD[petalcase]) - mNumberOfLayersVD; } - - return -1; /// not found or ML/OT + return -1; } //__________________________________________________________________________ -int GeometryTGeo::getModule(int index) const +int GeometryTGeo::getChip(int index) const { int subDetID = getSubDetID(index); + int lay = getLayer(index); + int petalcase = getPetalCase(index); - return -1; /// not implemented yet -} + if (subDetID == 0) { /// VD + return -1; + } else if (subDetID == 1) { /// MLOT + int lay = getLayer(index); + index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer -//__________________________________________________________________________ -int GeometryTGeo::getChip(int index) const -{ - int subDetID = getSubDetID(index); + const int Nhs = mNumberOfHalfStaves[lay]; + const int Nmod = mNumberOfModules[lay]; + const int Nchip = mNumberOfChips[lay]; - return -1; /// not implemented yet + if (Nhs == 2) { + int chipsPerModule = Nchip; + return index % chipsPerModule; + } else if (Nhs == 1) { + int chipsPerModule = Nchip; + return index % chipsPerModule; + } + } + return -1; } //__________________________________________________________________________ @@ -244,11 +311,20 @@ int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, i } else { // layer return getFirstChipIndex(lay, petalcase, subDetID) + lay; } - } else if (subDetID == 1) { // MLOT - if (mNumberOfHalfStaves[lay] == 2) { // staggered geometry - return getFirstChipIndex(lay, petalcase, subDetID) + stave * mNumberOfHalfStaves[lay] + halfstave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; - } else if (mNumberOfHalfStaves[lay] == 1) { // turbo geometry - return getFirstChipIndex(lay, petalcase, subDetID) + stave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; + } else if (subDetID == 1) { // MLOT + const int Nhs = mNumberOfHalfStaves[lay]; // 1 or 2 + const int Nmod = mNumberOfModules[lay]; // module per half-stave (per stave if Nhs==1) + const int Nchip = mNumberOfChips[lay]; // chips per module + + if (Nhs == 2) { // staggered geometry: layer -> stave -> halfstave -> mod -> chip + int chipsPerModule = Nchip; + int chipsPerHalfStave = Nmod * chipsPerModule; + int chipsPerStave = Nhs * chipsPerHalfStave; + return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip; + } else if (Nhs == 1) { // turbo geometry: layer -> stave -> mod -> chip (no halfstave) + int chipsPerModule = Nchip; + int chipsPerStave = Nmod * chipsPerModule; + return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip; } } return -1; // not found @@ -260,11 +336,20 @@ int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int if (subDetID == 0) { // VD return volume; /// In the current configuration for VD, each volume is the sensor element = chip. // TODO: when the geometry naming scheme will be changed, change this method - } else if (subDetID == 1) { // MLOT - if (mNumberOfHalfStaves[lay] == 2) { // staggered geometry - return getFirstChipIndex(lay, -1, subDetID) + stave * mNumberOfHalfStaves[lay] + halfstave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; - } else if (mNumberOfHalfStaves[lay] == 1) { // turbo geometry - return getFirstChipIndex(lay, -1, subDetID) + stave * mNumberOfModules[lay] + mod * mNumberOfChips[lay] + chip; + } else if (subDetID == 1) { // MLOT + const int Nhs = mNumberOfHalfStaves[lay]; // 1 or 2 + const int Nmod = mNumberOfModules[lay]; // module per half-stave (per stave if Nhs==1) + const int Nchip = mNumberOfChips[lay]; // chips per module + + if (Nhs == 2) { // staggered geometry: layer -> stave -> halfstave -> mod -> chip + int chipsPerModule = Nchip; + int chipsPerHalfStave = Nmod * chipsPerModule; + int chipsPerStave = Nhs * chipsPerHalfStave; + return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip; + } else if (Nhs == 1) { // turbo geometry: layer -> stave -> mod -> chip (no halfstave) + int chipsPerModule = Nchip; + int chipsPerStave = Nmod * chipsPerModule; + return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip; } } return -1; // not found @@ -278,6 +363,11 @@ bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk disk = getDisk(index); lay = getLayer(index); stave = getStave(index); + if (mNumberOfHalfStaves[lay] == 2) { + halfstave = getHalfStave(index); + } else { + halfstave = 0; // if not staggered geometry, return 0 + } halfstave = getHalfStave(index); mod = getModule(index); chip = getChip(index); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 0f2523579861c..80a606d5240a1 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -104,9 +104,6 @@ void Detector::configDefault() mLayers.clear(); LOGP(warning, "Loading Scoping Document configuration for ALICE3 TRK"); - // mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 0.5f, 4, 100.e-4); - // mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 1.2f, 4, 100.e-4); - // mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 2.5f, 4, 100.e-4); mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 3.78f, 10, 100.e-3); mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 7.f, 10, 100.e-3); mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 10, 100.e-3); From f38bff4af9d1f13acc3d072f7316a7b66112f6ad Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 16 Oct 2025 11:51:47 +0200 Subject: [PATCH 26/37] Fix --- Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index e2512b78c244c..7ddd68339899f 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -296,7 +296,7 @@ TGeoVolume* TRKLayer::createStave(std::string type) staveVol->AddNode(halfStaveVolLeft, 0, transLeft); TGeoCombiTrans* transRight = new TGeoCombiTrans(); - transRight->SetTranslation(halfstaveWidth / 2 - 0.05, 0, 0); // TO BE CHECKED !!! 1mm overlap between the modules + transRight->SetTranslation(halfstaveWidth / 2 - 0.05, 0.2, 0); // TO BE CHECKED !!! 1mm overlap between the modules LOGP(info, "Inserting {} in {} ", halfStaveVolRight->GetName(), staveVol->GetName()); staveVol->AddNode(halfStaveVolRight, 1, transRight); } else { From e6ecb475f814aab6cdce09ab53c676d9572af863 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 16 Oct 2025 14:43:58 +0200 Subject: [PATCH 27/37] Fix ID retrieving from Detector --- .../Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 80a606d5240a1..55476e32ddd9f 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -445,8 +445,15 @@ bool Detector::ProcessHits(FairVolume* vol) if (subDetID == 1) { fMC->CurrentVolOffID(1, chip); fMC->CurrentVolOffID(2, mod); - fMC->CurrentVolOffID(3, halfstave); - fMC->CurrentVolOffID(4, stave); + if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) { + fMC->CurrentVolOffID(3, halfstave); + fMC->CurrentVolOffID(4, stave); + } else if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) { + fMC->CurrentVolOffID(3, stave); + } else { + LOGP(fatal, "Wrong number of halfstaves for layer {}", layer); + } + } /// if VD, for the moment the volume is the "chipID" so no need to retrieve other elments int chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip); @@ -486,7 +493,7 @@ void Detector::Print(FairVolume* vol, int volume, int subDetID, int layer, int s LOG(info) << "off volume name 4 " << fMC->CurrentVolOffName(4) << " stave: " << stave; LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID; } else if (subDetID == 1 && mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) { // turbo geometry - LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(3) << " stave: " << stave; + LOG(info) << "off volume name 3 " << fMC->CurrentVolOffName(3) << " stave: " << stave; LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID; } else { LOG(info) << "SubDetector ID: " << subDetID << " Chip ID: " << chipID; From ff5bfe126978ceaf1753aae6b1258608c2c52230 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 16 Oct 2025 14:49:09 +0200 Subject: [PATCH 28/37] Fix --- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 55476e32ddd9f..3eb858060d44b 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -453,7 +453,6 @@ bool Detector::ProcessHits(FairVolume* vol) } else { LOGP(fatal, "Wrong number of halfstaves for layer {}", layer); } - } /// if VD, for the moment the volume is the "chipID" so no need to retrieve other elments int chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip); From e574e156ad71fe1fa1363926b367a35906253d72 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 17 Oct 2025 10:19:49 +0200 Subject: [PATCH 29/37] Created configurable to set overall geometry in buildTRKNewVacuumVessel --- .../TRK/base/include/TRKBase/TRKBaseParam.h | 7 +++ .../ALICE3/TRK/simulation/src/Detector.cxx | 53 +++++++++++++------ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h index 63c95b1e6b2f6..1cbd6b8dc8f7b 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h @@ -20,6 +20,11 @@ namespace o2 namespace trk { +enum eOverallGeom { + kDefaultRadii = 0, // After Upgrade Days March 2024 + kModRadii, +}; + enum eLayout { kCylinder = 0, kTurboStaves, @@ -31,6 +36,8 @@ struct TRKBaseParam : public o2::conf::ConfigurableParamHelper { float serviceTubeX0 = 0.02f; // X0 Al2O3 Bool_t irisOpen = false; + eOverallGeom overallGeom = kDefaultRadii; // Overall geometry option, to be used in Detector::buildTRKNewVacuumVessel + eLayout layoutML = kCylinder; // Type of segmentation for the middle layers eLayout layoutOL = kCylinder; // Type of segmentation for the outer layers diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 3eb858060d44b..804d6811464e7 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -116,25 +116,46 @@ void Detector::configDefault() void Detector::buildTRKNewVacuumVessel() { - // Build the TRK detector according to changes proposed during - // https://indico.cern.ch/event/1407704/ - // to adhere to the changes that were presented at the ALICE 3 Upgrade days in March 2024 - // L3 -> 7 cm, L4 -> 9 cm + auto& trkPars = TRKBaseParam::Instance(); mLayers.clear(); - LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); - mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 10, 100.e-3); - LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); - mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 10, 100.e-3); - mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 10, 100.e-3); - mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 10, 100.e-3); - mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 10, 100.e-3); - mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 20, 100.e-3); - mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 20, 100.e-3); - mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); - - auto& trkPars = TRKBaseParam::Instance(); + switch (trkPars.overallGeom) { + case kDefaultRadii: + // Build the TRK detector according to changes proposed during + // https://indico.cern.ch/event/1407704/ + // to adhere to the changes that were presented at the ALICE 3 Upgrade days in March 2024 + // L3 -> 7 cm, L4 -> 9 cm, L5 -> 12 cm, L6 -> 20 cm + + LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); + LOGP(warning, "Building TRK with new vacuum vessel and L3 at 7 cm, L4 at 9 cm, L5 at 12 cm, L6 at 20 cm"); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 10, 100.e-3); + LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 9.f, 10, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 12.f, 10, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 20.f, 10, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 10, 100.e-3); + mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 20, 100.e-3); + mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 20, 100.e-3); + mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); + break; + case kModRadii: + LOGP(warning, "Loading \"Alternative\" configuration for ALICE3 TRK"); + LOGP(warning, "Building TRK with new vacuum vessel and L3 at 7 cm, L4 at 11 cm, L5 at 15 cm, L6 at 19 cm"); + mLayers.emplace_back(0, GeometryTGeo::getTRKLayerPattern() + std::to_string(0), 7.f, 10, 100.e-3); + LOGP(info, "TRKLayer created. Name: {}", GeometryTGeo::getTRKLayerPattern() + std::to_string(0)); + mLayers.emplace_back(1, GeometryTGeo::getTRKLayerPattern() + std::to_string(1), 11.f, 10, 100.e-3); + mLayers.emplace_back(2, GeometryTGeo::getTRKLayerPattern() + std::to_string(2), 15.f, 10, 100.e-3); + mLayers.emplace_back(3, GeometryTGeo::getTRKLayerPattern() + std::to_string(3), 19.f, 10, 100.e-3); + mLayers.emplace_back(4, GeometryTGeo::getTRKLayerPattern() + std::to_string(4), 30.f, 10, 100.e-3); + mLayers.emplace_back(5, GeometryTGeo::getTRKLayerPattern() + std::to_string(5), 45.f, 20, 100.e-3); + mLayers.emplace_back(6, GeometryTGeo::getTRKLayerPattern() + std::to_string(6), 60.f, 20, 100.e-3); + mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); + break; + default: + LOGP(warning, "Unknown option {} for buildTRKNewVacuumVessel", trkPars.overallGeom); + break; + } // Middle layers mLayers[0].setLayout(trkPars.layoutML); From b3128662adb659bc14eba561d3029d6a24dc5531 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Sat, 18 Oct 2025 14:37:51 +0200 Subject: [PATCH 30/37] Fix --- Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx | 4 ++-- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 8ea6faf443d03..4819abdf430ab 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -785,11 +785,11 @@ int GeometryTGeo::extractNumberOfModulesMLOT(int lay) const { int numberOfModules = 0; - std::string staveName = Form("%s%d", getTRKStavePattern(), lay); + std::string staveName = Form("%s%d", (mNumberOfHalfStaves[lay] == 2 ? getTRKHalfStavePattern() : getTRKStavePattern()), lay); TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str()); if (staveV == nullptr) { - LOG(fatal) << getName() << " volume " << getTRKStavePattern() << " is not in the geometry"; + LOG(fatal) << getName() << " volume " << (mNumberOfHalfStaves[lay] == 2 ? getTRKHalfStavePattern() : getTRKStavePattern()) << " is not in the geometry"; } // Loop on all staveV nodes, count Module volumes by checking names diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 804d6811464e7..fbfb333a3604e 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -386,7 +386,6 @@ bool Detector::ProcessHits(FairVolume* vol) int subDetID = -1; int layer = -1; int volume = 0; - int stave = -1; int volID = vol->getMCid(); bool notSens = false; From c24805da3e21120740cb7fa73a3c26957551ef73 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 24 Oct 2025 16:57:58 +0200 Subject: [PATCH 31/37] Detector --- .../Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index d66369b3bf4e7..bea8435933fd3 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -101,25 +101,12 @@ void Detector::buildTRKMiddleOuterLayers() mLayers.clear(); -<<<<<<< HEAD switch (trkPars.overallGeom) { case kDefaultRadii: // Build the TRK detector according to changes proposed during // https://indico.cern.ch/event/1407704/ // to adhere to the changes that were presented at the ALICE 3 Upgrade days in March 2024 // L3 -> 7 cm, L4 -> 9 cm, L5 -> 12 cm, L6 -> 20 cm -======= - LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); - mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 7.f, 124.f, 100.e-3); - LOGP(info, "TRKLayer created. Name: {}", std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}); - mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 9.f, 124.f, 100.e-3); - mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 12.f, 124.f, 100.e-3); - mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(3)}, 20.f, 124.f, 100.e-3); - mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(4)}, 30.f, 124.f, 100.e-3); - mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(5)}, 45.f, 258.f, 100.e-3); - mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(6)}, 60.f, 258.f, 100.e-3); - mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(7)}, 80.f, 258.f, 100.e-3); ->>>>>>> upstream/dev LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK"); LOGP(warning, "Building TRK with new vacuum vessel and L3 at 7 cm, L4 at 9 cm, L5 at 12 cm, L6 at 20 cm"); From 2fdf62cf2649a5525d25b9e4194cc0c4c2927de2 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 28 Oct 2025 11:55:54 +0100 Subject: [PATCH 32/37] Added trk::Hit + fixed unsigned short ID --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 14 +- .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 14 +- .../ALICE3/TRK/simulation/CMakeLists.txt | 6 +- .../include/TRKSimulation/Detector.h | 30 ++-- .../simulation/include/TRKSimulation/Hit.h | 149 ++++++++++++++++++ .../ALICE3/TRK/simulation/src/Detector.cxx | 16 +- .../ALICE3/TRK/simulation/src/Hit.cxx | 34 ++++ .../TRK/simulation/src/TRKSimulationLinkDef.h | 3 + 8 files changed, 230 insertions(+), 36 deletions(-) create mode 100644 Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h create mode 100644 Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index 004c95ecf03e0..dcac2dd4255f3 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -101,7 +101,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 /// \param int module The module number for MLOT, from 0 to 10 (or 20) /// \param int chip The chip number for MLOT, from 0 to 8 - int getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const; + unsigned short getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const; /// This routine computes the chip index number from the subDetID, volume, layer, stave, half stave, module, chip /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT @@ -111,7 +111,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 /// \param int module The module number for MLOT, from 0 to 10 (or 20) /// \param int chip The chip number for MLOT, from 0 to 8 - int getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const; + unsigned short getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const; /// This routine computes subDetID, petal, disk, layer, stave, half stave, module, chip, given the chip index number /// \param int index The chip index number, starting from 0 @@ -125,8 +125,8 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// \param int chip The chip number for MLOT, from 0 to 8 bool getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& mod, int& chip) const; - int getLastChipIndex(int lay) const { return mLastChipIndex[lay]; } - int getFirstChipIndex(int lay, int petalcase, int subDetID) const + unsigned short getLastChipIndex(int lay) const { return mLastChipIndex[lay]; } + unsigned short getFirstChipIndex(int lay, int petalcase, int subDetID) const { /// Get the first chip index of the active petal (VD) or layer (MLOT) if (subDetID == 0) { // VD @@ -190,9 +190,9 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache // std::vector mNumberOfChipsPerStave; ///< number of chips per stave in ML/OT // std::vector mNumberOfChipsPerHalfStave; ///< number of chips per half stave in ML/OT // std::vector mNumberOfChipsPerModule; ///< number of chips per module in ML/OT - std::vector mLastChipIndex; ///< max ID of the detctor in the petal(VD) or layer(MLOT) - std::vector mLastChipIndexVD; ///< max ID of the detctor in the layer for the VD - std::vector mLastChipIndexMLOT; ///< max ID of the detctor in the layer for the MLOT + std::vector mLastChipIndex; ///< max ID of the detctor in the petal(VD) or layer(MLOT) + std::vector mLastChipIndexVD; ///< max ID of the detctor in the layer for the VD + std::vector mLastChipIndexMLOT; ///< max ID of the detctor in the layer for the MLOT std::array mLayerToWrapper; ///< Layer to wrapper correspondence, not implemented yet diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 5b05a0ecd77d2..bdee2ba7ec503 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -13,6 +13,8 @@ #include #include "TRKBase/SegmentationChip.h" +#include + using Segmentation = o2::trk::SegmentationChip; namespace o2 @@ -304,7 +306,7 @@ int GeometryTGeo::getChip(int index) const } //__________________________________________________________________________ -int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const +unsigned short GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const { if (subDetID == 0) { // VD if (lay == -1) { // disk @@ -328,11 +330,13 @@ int GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, i return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip; } } - return -1; // not found + + LOGP(warning, "Chip index not found for subDetID %d, petalcase %d, disk %d, layer %d, stave %d, halfstave %d, module %d, chip %d, returning numeric limit", subDetID, petalcase, disk, lay, stave, halfstave, mod, chip); + return std::numeric_limits::max(); // not found } //__________________________________________________________________________ -int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const +unsigned short GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const { if (subDetID == 0) { // VD return volume; /// In the current configuration for VD, each volume is the sensor element = chip. // TODO: when the geometry naming scheme will be changed, change this method @@ -353,7 +357,9 @@ int GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip; } } - return -1; // not found + + LOGP(warning, "Chip index not found for subDetID %d, volume %d, layer %d, stave %d, halfstave %d, module %d, chip %d, returning numeric limit", subDetID, volume, lay, stave, halfstave, mod, chip); + return std::numeric_limits::max(); // not found } //__________________________________________________________________________ diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt index 0c3c35d49f722..10f117750d793 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt @@ -10,7 +10,8 @@ # or submit itself to any jurisdiction. o2_add_library(TRKSimulation - SOURCES src/TRKLayer.cxx + SOURCES src/Hit.cxx + src/TRKLayer.cxx src/ChipDigitsContainer.cxx src/ChipSimResponse.cxx src/Detector.cxx @@ -27,7 +28,8 @@ o2_add_library(TRKSimulation O2::SimulationDataFormat) o2_target_root_dictionary(TRKSimulation - HEADERS include/TRKSimulation/ChipDigitsContainer.h + HEADERS include/TRKSimulation/Hit.h + include/TRKSimulation/ChipDigitsContainer.h include/TRKSimulation/ChipSimResponse.h include/TRKSimulation/DigiParams.h include/TRKSimulation/Digitizer.h diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h index 50f73aa99cb9a..32bdc89109269 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h @@ -13,7 +13,7 @@ #define ALICEO2_TRK_DETECTOR_H #include "DetectorsBase/Detector.h" -#include "ITSMFTSimulation/Hit.h" +#include "TRKSimulation/Hit.h" #include "TRKSimulation/TRKLayer.h" #include "TRKSimulation/TRKServices.h" @@ -42,9 +42,9 @@ class Detector : public o2::base::DetImpl void ConstructGeometry() override; - o2::itsmft::Hit* addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos, - const TVector3& startMom, double startE, double endTime, double eLoss, - unsigned char startStatus, unsigned char endStatus); + o2::trk::Hit* addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, + const TVector3& startMom, double startE, double endTime, double eLoss, + unsigned char startStatus, unsigned char endStatus); // Mandatory overrides void BeginPrimary() override { ; } @@ -57,8 +57,8 @@ class Detector : public o2::base::DetImpl void Register() override; void Reset() override; - // Custom memer functions - std::vector* getHits(int iColl) const + // Custom member functions + std::vector* getHits(int iColl) const { if (!iColl) { return mHits; @@ -81,14 +81,14 @@ class Detector : public o2::base::DetImpl // Transient data about track passing the sensor struct TrackData { - bool mHitStarted; // hit creation started - unsigned char mTrkStatusStart; // track status flag - TLorentzVector mPositionStart; // position at entrance - TLorentzVector mMomentumStart; // momentum - double mEnergyLoss; // energy loss - } mTrackData; //! transient data - GeometryTGeo* mGeometryTGeo; //! - std::vector* mHits; // ITSMFT ones for the moment + bool mHitStarted; // hit creation started + unsigned char mTrkStatusStart; // track status flag + TLorentzVector mPositionStart; // position at entrance + TLorentzVector mMomentumStart; // momentum + double mEnergyLoss; // energy loss + } mTrackData; //! transient data + GeometryTGeo* mGeometryTGeo; //! + std::vector* mHits; // ITSMFT ones for the moment std::vector mLayers; TRKServices mServices; // Houses the services of the TRK, but not the Iris tracker @@ -109,7 +109,7 @@ class Detector : public o2::base::DetImpl template friend class o2::base::DetImpl; - ClassDefOverride(Detector, 1); + ClassDefOverride(Detector, 2); }; } // namespace trk } // namespace o2 diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h new file mode 100644 index 0000000000000..a178c30069f14 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h @@ -0,0 +1,149 @@ +// 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 Hit.h +/// \brief Definition of the TRK Hit class + +#ifndef ALICEO2_TRK_POINT_H_ +#define ALICEO2_TRK_POINT_H_ + +#include "SimulationDataFormat/BaseHits.h" // for BasicXYZEHit +#include "Rtypes.h" // for Bool_t, Double_t, Int_t, Double32_t, etc +#include "TVector3.h" // for TVector3 +#include +#include "CommonUtils/ShmAllocator.h" + +namespace o2 +{ +namespace trk +{ + +class Hit : public o2::BasicXYZEHit +{ + + public: + enum HitStatus_t { + kTrackEntering = 0x1, + kTrackInside = 0x1 << 1, + kTrackExiting = 0x1 << 2, + kTrackOut = 0x1 << 3, + kTrackStopped = 0x1 << 4, + kTrackAlive = 0x1 << 5 + }; + + /// Default constructor + Hit() = default; + + /// Class Constructor + /// \param trackID Index of MCTrack + /// \param detID Detector ID + /// \param startPos Coordinates at entrance to active volume [cm] + /// \param pos Coordinates to active volume [cm] + /// \param mom Momentum of track at entrance [GeV] + /// \param endTime Time at entrance [ns] + /// \param time Time since event start [ns] + /// \param eLoss Energy deposit [GeV] + /// \param startStatus: status at entrance + /// \param endStatus: status at exit + inline Hit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& pos, const TVector3& mom, double startE, + double endTime, double eLoss, unsigned char statusStart, unsigned char status); + + // Entrance position getters + math_utils::Point3D GetPosStart() const { return mPosStart; } + Float_t GetStartX() const { return mPosStart.X(); } + Float_t GetStartY() const { return mPosStart.Y(); } + Float_t GetStartZ() const { return mPosStart.Z(); } + template + void GetStartPosition(F& x, F& y, F& z) const + { + x = GetStartX(); + y = GetStartY(); + z = GetStartZ(); + } + // momentum getters + math_utils::Vector3D GetMomentum() const { return mMomentum; } + math_utils::Vector3D& GetMomentum() { return mMomentum; } + Float_t GetPx() const { return mMomentum.X(); } + Float_t GetPy() const { return mMomentum.Y(); } + Float_t GetPz() const { return mMomentum.Z(); } + Float_t GetE() const { return mE; } + Float_t GetTotalEnergy() const { return GetE(); } + + UChar_t GetStatusEnd() const { return mTrackStatusEnd; } + UChar_t GetStatusStart() const { return mTrackStatusStart; } + + Bool_t IsEntering() const { return mTrackStatusEnd & kTrackEntering; } + Bool_t IsInside() const { return mTrackStatusEnd & kTrackInside; } + Bool_t IsExiting() const { return mTrackStatusEnd & kTrackExiting; } + Bool_t IsOut() const { return mTrackStatusEnd & kTrackOut; } + Bool_t IsStopped() const { return mTrackStatusEnd & kTrackStopped; } + Bool_t IsAlive() const { return mTrackStatusEnd & kTrackAlive; } + + Bool_t IsEnteringStart() const { return mTrackStatusStart & kTrackEntering; } + Bool_t IsInsideStart() const { return mTrackStatusStart & kTrackInside; } + Bool_t IsExitingStart() const { return mTrackStatusStart & kTrackExiting; } + Bool_t IsOutStart() const { return mTrackStatusStart & kTrackOut; } + Bool_t IsStoppedStart() const { return mTrackStatusStart & kTrackStopped; } + Bool_t IsAliveStart() const { return mTrackStatusStart & kTrackAlive; } + + // Entrance position setter + void SetPosStart(const math_utils::Point3D& p) { mPosStart = p; } + + /// Output to screen + void Print(const Option_t* opt) const; + friend std::ostream& operator<<(std::ostream& of, const Hit& point) + { + of << "-I- Hit: O2its point for track " << point.GetTrackID() << " in detector " << point.GetDetectorID() << std::endl; + /* + of << " Position (" << point.fX << ", " << point.fY << ", " << point.fZ << ") cm" << std::endl; + of << " Momentum (" << point.fPx << ", " << point.fPy << ", " << point.fPz << ") GeV" << std::endl; + of << " Time " << point.fTime << " ns, Length " << point.fLength << " cm, Energy loss " + << point.fELoss * 1.0e06 << " keV" << std::endl; + */ + return of; + } + + private: + math_utils::Vector3D mMomentum; ///< momentum at entrance + math_utils::Point3D mPosStart; ///< position at entrance (base mPos give position on exit) + Float_t mE; ///< total energy at entrance + UChar_t mTrackStatusEnd; ///< MC status flag at exit + UChar_t mTrackStatusStart; ///< MC status at starting point + + ClassDefNV(Hit, 1); +}; + +Hit::Hit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, const TVector3& startMom, + double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus) + : BasicXYZEHit(endPos.X(), endPos.Y(), endPos.Z(), endTime, eLoss, trackID, detID), + mMomentum(startMom.Px(), startMom.Py(), startMom.Pz()), + mPosStart(startPos.X(), startPos.Y(), startPos.Z()), + mE(startE), + mTrackStatusEnd(endStatus), + mTrackStatusStart(startStatus) +{ +} + +} // namespace trk +} // namespace o2 + +#ifdef USESHM +namespace std +{ +template <> +class allocator : public o2::utils::ShmAllocator +{ +}; +} // namespace std + +#endif + +#endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index bea8435933fd3..1b5185e721002 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -16,7 +16,7 @@ #include #include "DetectorsBase/Stack.h" -#include "ITSMFTSimulation/Hit.h" +#include "TRKSimulation/Hit.h" #include "TRKSimulation/Detector.h" #include "TRKBase/TRKBaseParam.h" #include "TRKSimulation/VDGeometryBuilder.h" @@ -24,7 +24,7 @@ #include -using o2::itsmft::Hit; +using o2::trk::Hit; namespace o2 { @@ -39,14 +39,14 @@ float getDetLengthFromEta(const float eta, const float radius) Detector::Detector() : o2::base::DetImpl("TRK", true), mTrackData(), - mHits(o2::utils::createSimVector()) + mHits(o2::utils::createSimVector()) { } Detector::Detector(bool active) : o2::base::DetImpl("TRK", true), mTrackData(), - mHits(o2::utils::createSimVector()) + mHits(o2::utils::createSimVector()) { auto& trkPars = TRKBaseParam::Instance(); @@ -473,7 +473,7 @@ bool Detector::ProcessHits(FairVolume* vol) } } /// if VD, for the moment the volume is the "chipID" so no need to retrieve other elments - int chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip); + unsigned short chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip); Print(vol, volume, subDetID, layer, stave, halfstave, mod, chip, chipID); @@ -492,9 +492,9 @@ bool Detector::ProcessHits(FairVolume* vol) return true; } -o2::itsmft::Hit* Detector::addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos, - const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus, - unsigned char endStatus) +o2::trk::Hit* Detector::addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, + const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus, + unsigned char endStatus) { mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus); return &(mHits->back()); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx new file mode 100644 index 0000000000000..fe496bc59692f --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx @@ -0,0 +1,34 @@ +// 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 Hit.cxx +/// \brief Implementation of the Hit class + +#include "TRKSimulation/Hit.h" + +#include +#include + +ClassImp(o2::trk::Hit); + +using std::cout; +using std::endl; +using namespace o2::trk; +using namespace o2; //::base; + +void Hit::Print(const Option_t* opt) const +{ + printf( + "Det: %5d Track: %6d E.loss: %.3e P: %+.3e %+.3e %+.3e\n" + "PosIn: %+.3e %+.3e %+.3e PosOut: %+.3e %+.3e %+.3e\n", + GetDetectorID(), GetTrackID(), GetEnergyLoss(), GetPx(), GetPy(), GetPz(), + GetStartX(), GetStartY(), GetStartZ(), GetX(), GetY(), GetZ()); +} diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h index 1a2e93636491c..9af868a2de44c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h @@ -15,6 +15,9 @@ #pragma link off all classes; #pragma link off all functions; +#pragma link C++ class o2::trk::Hit + ; +#pragma link C++ class std::vector < o2::trk::Hit> + ; + #pragma link C++ class o2::trk::TRKLayer + ; #pragma link C++ class o2::trk::VDLayer + ; #pragma link C++ class o2::trk::TRKServices + ; From 4737ce9b700c9865e65c954d4ae41d10a90c6e2e Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 28 Oct 2025 14:19:27 +0100 Subject: [PATCH 33/37] Created metal stack + chenged rotation of the two chip columns in module --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 2 + .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 1 + .../include/TRKSimulation/TRKLayer.h | 4 +- .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 78 ++++++++++++------- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index dcac2dd4255f3..f900065ad738a 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -53,6 +53,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static const char* getTRKChipPattern() { return sChipName.c_str(); } static const char* getTRKSensorPattern() { return sSensorName.c_str(); } static const char* getTRKDeadzonePattern() { return sDeadzoneName.c_str(); } + static const char* getTRKMetalStackPattern() { return sMetalStackName.c_str(); } static const char* getTRKWrapVolPattern() { return sWrapperVolumeName.c_str(); } @@ -171,6 +172,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static std::string sChipName; static std::string sSensorName; static std::string sDeadzoneName; + static std::string sMetalStackName; static std::string sWrapperVolumeName; ///< Wrapper volume name, not implemented at the moment diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index bdee2ba7ec503..80bf88de746dd 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -36,6 +36,7 @@ std::string GeometryTGeo::sModuleName = "TRKModule"; std::string GeometryTGeo::sChipName = "TRKChip"; std::string GeometryTGeo::sSensorName = "TRKSensor"; std::string GeometryTGeo::sDeadzoneName = "TRKDeadzone"; +std::string GeometryTGeo::sMetalStackName = "TRKMetalStack"; std::string GeometryTGeo::sWrapperVolumeName = "TRKUWrapVol"; ///< Wrapper volume name, not implemented at the moment diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index b99686d423382..0a7a45e87bfd8 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -42,6 +42,7 @@ class TRKLayer TGeoVolume* createSensor(std::string type); TGeoVolume* createDeadzone(std::string type); + TGeoVolume* createMetalStack(std::string type); TGeoVolume* createChip(std::string type); TGeoVolume* createModule(std::string type); TGeoVolume* createStave(std::string type); @@ -63,9 +64,10 @@ class TRKLayer float mChipLength; float mChipThickness; float mDeadzoneWidth; + float mSensorThickness; int mHalfNumberOfChips; - ClassDef(TRKLayer, 1); + ClassDef(TRKLayer, 2); }; } // namespace trk diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index 7ddd68339899f..e8832d7e7fc97 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -26,7 +26,7 @@ namespace o2 namespace trk { TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, int numberOfModules, float layerX2X0) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mNumberOfModules(numberOfModules), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mHalfNumberOfChips(4) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mNumberOfModules(numberOfModules), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mSensorThickness(100.e-4), mHalfNumberOfChips(4) { float Si_X0 = 9.5f; mChipThickness = mX2X0 * Si_X0; @@ -34,7 +34,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOu } TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thick) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mNumberOfModules(numberOfModules), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mHalfNumberOfChips(4) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mNumberOfModules(numberOfModules), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mSensorThickness(100.e-4), mHalfNumberOfChips(4) { float Si_X0 = 9.5f; mOuterRadius = rInn + thick; @@ -50,9 +50,9 @@ TGeoVolume* TRKLayer::createSensor(std::string type) TGeoShape* sensor; if (type == "cylinder") { - sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); // TO BE CHECKED !!! + sensor = new TGeoTube(mInnerRadius, mInnerRadius + mSensorThickness, mChipLength / 2); // TO BE CHECKED !!! } else if (type == "flat") { - sensor = new TGeoBBox((mChipWidth - mDeadzoneWidth) / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! + sensor = new TGeoBBox((mChipWidth - mDeadzoneWidth) / 2, mSensorThickness / 2, mChipLength / 2); // TO BE CHECKED !!! } else { LOGP(fatal, "Sensor of type '{}' is not implemented", type); } @@ -71,9 +71,9 @@ TGeoVolume* TRKLayer::createDeadzone(std::string type) TGeoShape* deadzone; if (type == "cylinder") { - deadzone = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); // TO BE CHECKED !!! + deadzone = new TGeoTube(mInnerRadius, mInnerRadius + mSensorThickness, mChipLength / 2); // TO BE CHECKED !!! } else if (type == "flat") { - deadzone = new TGeoBBox(mDeadzoneWidth / 2, mChipThickness / 2, mChipLength / 2); // TO BE CHECKED !!! + deadzone = new TGeoBBox(mDeadzoneWidth / 2, mSensorThickness / 2, mChipLength / 2); // TO BE CHECKED !!! } else { LOGP(fatal, "Deadzone of type '{}' is not implemented", type); } @@ -84,6 +84,27 @@ TGeoVolume* TRKLayer::createDeadzone(std::string type) return deadVol; }; +TGeoVolume* TRKLayer::createMetalStack(std::string type) +{ + TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); + std::string metalName = GeometryTGeo::getTRKMetalStackPattern() + std::to_string(mLayerNumber); + + TGeoShape* metalStack; + + if (type == "cylinder") { + metalStack = new TGeoTube(mInnerRadius + mSensorThickness, mInnerRadius + mChipThickness, mChipLength / 2); // TO BE CHECKED !!! + } else if (type == "flat") { + metalStack = new TGeoBBox(mChipWidth / 2, mChipThickness - mSensorThickness / 2, mChipLength / 2); // TO BE CHECKED !!! + } else { + LOGP(fatal, "Metal stack of type '{}' is not implemented", type); + } + + TGeoVolume* metalVol = new TGeoVolume(metalName.c_str(), metalStack, medSi); + metalVol->SetLineColor(kGray); + + return metalVol; +}; + TGeoVolume* TRKLayer::createChip(std::string type) { TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); @@ -94,14 +115,24 @@ TGeoVolume* TRKLayer::createChip(std::string type) TGeoVolume* sensVol; TGeoVolume* deadVol; + TGeoVolume* metalVol; if (type == "cylinder") { chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mChipLength / 2); chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); sensVol = createSensor("cylinder"); + metalVol = createMetalStack("cylinder"); + + TGeoCombiTrans* transSens = new TGeoCombiTrans(); + transSens->SetTranslation(0, -(mChipThickness - mSensorThickness) / 2, 0); // TO BE CHECKED !!! LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); - chipVol->AddNode(sensVol, 1, nullptr); + chipVol->AddNode(sensVol, 1, transSens); + + TGeoCombiTrans* transMetal = new TGeoCombiTrans(); + transMetal->SetTranslation(0, mSensorThickness / 2, 0); // TO BE CHECKED !!! + LOGP(info, "Inserting {} in {} ", metalVol->GetName(), chipVol->GetName()); + chipVol->AddNode(metalVol, 1, transMetal); // deadVol = createDeadzone("cylinder"); } else if (type == "flat") { @@ -110,16 +141,22 @@ TGeoVolume* TRKLayer::createChip(std::string type) sensVol = createSensor("flat"); deadVol = createDeadzone("flat"); + metalVol = createMetalStack("flat"); TGeoCombiTrans* transSens = new TGeoCombiTrans(); - transSens->SetTranslation(-mDeadzoneWidth / 2, 0, 0); // TO BE CHECKED !!! + transSens->SetTranslation(-mDeadzoneWidth / 2, -(mChipThickness - mSensorThickness) / 2, 0); // TO BE CHECKED !!! LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); chipVol->AddNode(sensVol, 1, transSens); TGeoCombiTrans* transDead = new TGeoCombiTrans(); - transDead->SetTranslation((mChipWidth - mDeadzoneWidth) / 2, 0, 0); // TO BE CHECKED !!! + transDead->SetTranslation((mChipWidth - mDeadzoneWidth) / 2, -(mChipThickness - mSensorThickness) / 2, 0); // TO BE CHECKED !!! LOGP(info, "Inserting {} in {} ", deadVol->GetName(), chipVol->GetName()); chipVol->AddNode(deadVol, 1, transDead); + + TGeoCombiTrans* transMetal = new TGeoCombiTrans(); + transMetal->SetTranslation(0, mSensorThickness / 2, 0); // TO BE CHECKED !!! + LOGP(info, "Inserting {} in {} ", metalVol->GetName(), chipVol->GetName()); + chipVol->AddNode(metalVol, 1, transMetal); } else { LOGP(fatal, "Sensor of type '{}' is not implemented", type); } @@ -169,6 +206,9 @@ TGeoVolume* TRKLayer::createModule(std::string type) TGeoCombiTrans* transRight = new TGeoCombiTrans(); transRight->SetTranslation(xRight, 0, zRight); // TO BE CHECKED !!! + TGeoRotation* rot = new TGeoRotation(); + rot->RotateY(180); + transRight->SetRotation(rot); LOGP(info, "Inserting {} in {} ", chipVolRight->GetName(), moduleVol->GetName()); moduleVol->AddNode(chipVolRight, iChip * 2 + 1, transRight); } @@ -266,26 +306,6 @@ TGeoVolume* TRKLayer::createStave(std::string type) stave = new TGeoBBox(staveWidth / 2, mLogicalVolumeThickness / 2, staveLength / 2); staveVol = new TGeoVolume(staveName.c_str(), stave, medAir); - /*for (int iModule = 0; iModule < mNumberOfModules; iModule++) { - TGeoVolume* moduleVolLeft = createModule("flat"); - TGeoVolume* moduleVolRight = createModule("flat"); - - // Put the modules in the correct position - double xLeft = -moduleWidth / 2 + 0.05; - double xRight = moduleWidth / 2 - 0.05; - double zPos = -0.5 * mNumberOfModules * moduleLength + (iModule + 0.5) * moduleLength; - - TGeoCombiTrans* transLeft = new TGeoCombiTrans(); - transLeft->SetTranslation(xLeft, 0, zPos); // TO BE CHECKED !!! 1mm overlap between the modules - LOGP(info, "Inserting {} in {} ", moduleVolLeft->GetName(), staveVol->GetName()); - staveVol->AddNode(moduleVolLeft, iModule * 2, transLeft); - - TGeoCombiTrans* transRight = new TGeoCombiTrans(); - transRight->SetTranslation(xRight, 0.2, zPos); // TO BE CHECKED !!! 1mm overlap between the modules - LOGP(info, "Inserting {} in {} ", moduleVolRight->GetName(), staveVol->GetName()); - staveVol->AddNode(moduleVolRight, iModule * 2 + 1, transRight); - }*/ - // Put the half staves in the correct position TGeoVolume* halfStaveVolLeft = createHalfStave("flat"); TGeoVolume* halfStaveVolRight = createHalfStave("flat"); From 80f6e4b901022a8712a700acbe704221ee993274 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 28 Oct 2025 15:02:29 +0100 Subject: [PATCH 34/37] Modified Specs.h and TRKLayer correspondingly --- Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h | 6 ++---- Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h index cfea83d37ad33..559d8f6154c59 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h @@ -84,13 +84,11 @@ constexpr int nRows{static_cast(width / pitchX)}; // constexpr int nCols{static_cast(length / pitchZ)}; // number of rows in the chip constexpr double totalThickness{silicon::thickness + metalstack::thickness}; // total thickness of the chip /// Set to 0 for the moment, to be adjusted with the actual design of the chip if needed -static constexpr float PassiveEdgeReadOut = 0.f; // width of the readout edge (Passive bottom) -static constexpr float PassiveEdgeTop = 0.f; // Passive area on top -static constexpr float PassiveEdgeSide = 0.f; // width of Passive area on left/right of the sensor +static constexpr float passiveEdgeReadOut{1.5 * mm}; // width of the readout edge } // namespace chip namespace gaps { -constexpr double interChips{0.2 * mm}; // gap between the chips +constexpr double interChips{50 * mu}; // gap between the chips constexpr double outerEdgeLongSide{1 * mm}; // gap between the chips and the outer edges (long side) constexpr double outerEdgeShortSide{0.1 * mm}; // gap between the chips and the outer edges (short side) } // namespace gaps diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index e8832d7e7fc97..223c8b5c477a1 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -26,7 +26,7 @@ namespace o2 namespace trk { TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, int numberOfModules, float layerX2X0) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mNumberOfModules(numberOfModules), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mSensorThickness(100.e-4), mHalfNumberOfChips(4) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mNumberOfModules(numberOfModules), mX2X0(layerX2X0), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(constants::moduleMLOT::chip::passiveEdgeReadOut), mSensorThickness(constants::moduleMLOT::silicon::thickness), mHalfNumberOfChips(4) { float Si_X0 = 9.5f; mChipThickness = mX2X0 * Si_X0; @@ -34,7 +34,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOu } TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thick) - : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mNumberOfModules(numberOfModules), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(1.5 * 1e-1), mSensorThickness(100.e-4), mHalfNumberOfChips(4) + : mLayerNumber(layerNumber), mLayout(kCylinder), mLayerName(layerName), mInnerRadius(rInn), mNumberOfModules(numberOfModules), mChipThickness(thick), mChipWidth(constants::moduleMLOT::chip::width), mChipLength(constants::moduleMLOT::chip::length), mDeadzoneWidth(constants::moduleMLOT::chip::passiveEdgeReadOut), mSensorThickness(constants::moduleMLOT::silicon::thickness), mHalfNumberOfChips(4) { float Si_X0 = 9.5f; mOuterRadius = rInn + thick; From e470025365c70c8a9d0f10100c67c639ab80402a Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Tue, 28 Oct 2025 17:32:40 +0100 Subject: [PATCH 35/37] Fix for merging from previous PR --- Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 80bf88de746dd..7fe9717313343 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -492,16 +492,11 @@ void GeometryTGeo::fillMatrixCache(int mask) //__________________________________________________________________________ #ifdef ENABLE_UPGRADES -const char* GeometryTGeo::composeSymNameLayer(int d, int lr) -{ - return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::TRK).getName(), d); -} -#endif - const char* GeometryTGeo::composeSymNameLayer(int d, int layer) { return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), layer); } +#endif const char* GeometryTGeo::composeSymNameStave(int d, int layer) { From e5814a7f3d2f9da17ecd46065d82c56228ad95e7 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 30 Oct 2025 09:48:20 +0100 Subject: [PATCH 36/37] Fixed enum casting --- .../Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h | 2 +- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h index 1cbd6b8dc8f7b..3f3f656c4b417 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h @@ -36,7 +36,7 @@ struct TRKBaseParam : public o2::conf::ConfigurableParamHelper { float serviceTubeX0 = 0.02f; // X0 Al2O3 Bool_t irisOpen = false; - eOverallGeom overallGeom = kDefaultRadii; // Overall geometry option, to be used in Detector::buildTRKNewVacuumVessel + eOverallGeom overallGeom = kDefaultRadii; // Overall geometry option, to be used in Detector::buildTRKMiddleOuterLayers eLayout layoutML = kCylinder; // Type of segmentation for the middle layers eLayout layoutOL = kCylinder; // Type of segmentation for the outer layers diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 1b5185e721002..ff9ceb4067632 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -23,6 +23,7 @@ #include "TRKSimulation/VDSensorRegistry.h" #include +#include using o2::trk::Hit; @@ -134,7 +135,7 @@ void Detector::buildTRKMiddleOuterLayers() mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); break; default: - LOGP(warning, "Unknown option {} for buildTRKNewVacuumVessel", trkPars.overallGeom); + LOGP(fatal, "Unknown option {} for buildTRKMiddleOuterLayers", static_cast>(trkPars.overallGeom)); break; } From 210829e386116cf231ee24c355c8b9085ac8ff6b Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 30 Oct 2025 14:19:29 +0100 Subject: [PATCH 37/37] Fixed enum casting --- Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index ff9ceb4067632..4d7e560d50dc2 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -135,7 +135,7 @@ void Detector::buildTRKMiddleOuterLayers() mLayers.emplace_back(7, GeometryTGeo::getTRKLayerPattern() + std::to_string(7), 80.f, 20, 100.e-3); break; default: - LOGP(fatal, "Unknown option {} for buildTRKMiddleOuterLayers", static_cast>(trkPars.overallGeom)); + LOGP(fatal, "Unknown option {} for buildTRKMiddleOuterLayers", static_cast(trkPars.overallGeom)); break; }