From 53690be0646fc72f8e791a1473ce04a662a072a4 Mon Sep 17 00:00:00 2001 From: Berkin Ulukutlu Date: Tue, 22 Sep 2026 16:57:07 +0200 Subject: [PATCH 1/4] ALICE3/FT3: fix magnetic field silently disabled when FT3 is active FT3Module::initialize_materials() registered its six support materials via raw `new TGeoMedium(name, id, mat), bypassing o2::base::MaterialManager. That 3-argument TGeoMedium constructor leaves all tracking parameters, including ifield, at 0, and since these ids were never coordinated with MaterialManager's auto-assigned global ids, they collided with other detectors' media -notably the CAVE air medium that fills the gaps between TRK's barrel layers. Route these six materials/media through MaterialManager instead. --- .../TRKFT3/FT3/simulation/src/FT3Module.cxx | 101 ++++++++++++------ 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx index 98832e6d0507f..82e8c97fa7217 100644 --- a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx @@ -14,6 +14,8 @@ #include "FT3Simulation/FT3Module.h" #include "FT3Base/FT3BaseParam.h" +#include "DetectorsBase/MaterialManager.h" +#include "DetectorsBase/Detector.h" #include #include #include @@ -54,42 +56,77 @@ void FT3Module::initialize_materials() return; } - TGeoManager* geoManager = gGeoManager; - - auto* itsH = new TGeoElement("FT3_H", "Hydrogen", 1, 1.00794); - auto* itsC = new TGeoElement("FT3_C", "Carbon", 6, 12.0107); - auto* itsO = new TGeoElement("FT3_O", "Oxygen", 8, 15.994); - - siliconMat = new TGeoMaterial("FT3_Silicon", 28.0855, 14, 2.33); - siliconMed = new TGeoMedium("FT3_Silicon", 1, siliconMat); - - copperMat = new TGeoMaterial("FT3_Copper", 63.546, 29, 8.96); - copperMed = new TGeoMedium("FT3_Copper", 2, copperMat); - - TGeoMixture* kaptonMat = new TGeoMixture("FT3_Kapton", 4, 1.346); // C22 H10 N2 O5 - - kaptonMat->DefineElement(0, 12.0107, 6, 0.5641); // Carbon - kaptonMat->DefineElement(1, 1.00794, 1, 0.2564); // Hydrogen - kaptonMat->DefineElement(2, 14.0067, 7, 0.0513); // Nitrogen - kaptonMat->DefineElement(3, 15.999, 8, 0.1282); // Oxygen - kaptonMed = new TGeoMedium("FT3_Kapton", 3, kaptonMat); + // NOTE: these materials/media used to be registered directly via + // `new TGeoMaterial(...)` / `new TGeoMedium(name, rawId, ...)` with small + // hand-picked ids (1-6). That bypasses o2::base::MaterialManager, whose job + // is to hand out globally-unique medium ids across all detectors. Since the + // 3-argument TGeoMedium constructor also leaves all tracking parameters + // (including ifield) at 0, and Geant4VMC's TG4GeometryManager:: + // FillMediumMapFromRoot() maps ALL TGeoMedium objects into one global table + // keyed purely by that raw numeric id (last one processed wins), these raw + // ids collided with other detectors' properly-assigned medium ids (e.g. the + // CAVE air medium that fills the gaps between TRK layers) and silently + // switched the magnetic field off for them. Route through MaterialManager + // instead, like every other detector (incl. FT3's own Detector.cxx) does, + // so ids are safely auto-assigned and never collide. + auto& matmgr = o2::base::MaterialManager::Instance(); + + int ifield = 2; + float fieldm = 10.0; + o2::base::Detector::initFieldTrackingParams(ifield, fieldm); + + float tmaxfdSi = 0.1; + float stemaxSi = 0.0075; + float deemaxSi = 0.1; + float epsilSi = 1.0E-4; + float stminSi = 0.0; + + float tmaxfdPas = 0.1; + float stemaxPas = 1.0; + float deemaxPas = 0.1; + float epsilPas = 1.0E-4; + float stminPas = 0.0; + + // local ids 10-15: chosen to not clash with FT3's own createMaterials() (1, 3) + matmgr.Material("FT3", 10, "Silicon", 28.0855, 14, 2.33, 0, 0); + matmgr.Medium("FT3", 10, "Silicon", 10, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi); + siliconMed = matmgr.getTGeoMedium("FT3", 10); + siliconMat = siliconMed->GetMaterial(); + + matmgr.Material("FT3", 11, "Copper", 63.546, 29, 8.96, 0, 0); + matmgr.Medium("FT3", 11, "Copper", 11, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas); + copperMed = matmgr.getTGeoMedium("FT3", 11); + copperMat = copperMed->GetMaterial(); + + // Kapton: C22 H10 N2 O5, by weight fraction + float aKapton[4] = {12.0107, 1.00794, 14.0067, 15.999}; + float zKapton[4] = {6., 1., 7., 8.}; + float wKapton[4] = {0.5641, 0.2564, 0.0513, 0.1282}; + matmgr.Mixture("FT3", 12, "Kapton", aKapton, zKapton, 1.346, 4, wKapton); + matmgr.Medium("FT3", 12, "Kapton", 12, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas); + kaptonMed = matmgr.getTGeoMedium("FT3", 12); + kaptonMat = dynamic_cast(kaptonMed->GetMaterial()); // TODO: Check with Rene the exact type of carbon fiber - carbonFiberMat = new TGeoMaterial("FT3_Carbon", 12.0107, 6, 1.8); - carbonFiberMed = new TGeoMedium("FT3_Carbon", 6, carbonFiberMat); - - // Epoxy: C18 H19 O3 - auto* itsEpoxy = new TGeoMixture("FT3_Epoxy", 3); - itsEpoxy->AddElement(itsC, 18); - itsEpoxy->AddElement(itsH, 19); - itsEpoxy->AddElement(itsO, 3); - itsEpoxy->SetDensity(2.186); - - epoxyMed = new TGeoMedium("FT3_Epoxy", 4, itsEpoxy); + matmgr.Material("FT3", 13, "Carbon", 12.0107, 6, 1.8, 0, 0); + matmgr.Medium("FT3", 13, "Carbon", 13, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas); + carbonFiberMed = matmgr.getTGeoMedium("FT3", 13); + carbonFiberMat = carbonFiberMed->GetMaterial(); + + // Epoxy: C18 H19 O3, by atom count (negative nlmat) + float aEpoxy[3] = {12.0107, 1.00794, 15.999}; + float zEpoxy[3] = {6., 1., 8.}; + float wEpoxy[3] = {18., 19., 3.}; + matmgr.Mixture("FT3", 14, "Epoxy", aEpoxy, zEpoxy, 2.186, -3, wEpoxy); + matmgr.Medium("FT3", 14, "Epoxy", 14, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas); + epoxyMed = matmgr.getTGeoMedium("FT3", 14); epoxyMat = epoxyMed->GetMaterial(); - AluminumMat = new TGeoMaterial("Aluminum", 26.98, 13, 2.7); - AluminumMed = new TGeoMedium("Aluminum", 5, AluminumMat); + matmgr.Material("FT3", 15, "Aluminum", 26.98, 13, 2.7, 0, 0); + matmgr.Medium("FT3", 15, "Aluminum", 15, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas); + AluminumMed = matmgr.getTGeoMedium("FT3", 15); + AluminumMat = AluminumMed->GetMaterial(); + LOG(debug) << "FT3Module: done initialize_materials"; } From 4746c2786711d4a53fa2d0feaced2e3b3347db9b Mon Sep 17 00:00:00 2001 From: Berkin Ulukutlu Date: Tue, 22 Sep 2026 17:05:59 +0200 Subject: [PATCH 2/4] Clean up comments on material registration process Removed commented-out code regarding material registration and its implications. --- .../TRKFT3/FT3/simulation/src/FT3Module.cxx | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx index 82e8c97fa7217..bea858770b399 100644 --- a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx @@ -55,20 +55,7 @@ void FT3Module::initialize_materials() if (siliconMat) { return; } - - // NOTE: these materials/media used to be registered directly via - // `new TGeoMaterial(...)` / `new TGeoMedium(name, rawId, ...)` with small - // hand-picked ids (1-6). That bypasses o2::base::MaterialManager, whose job - // is to hand out globally-unique medium ids across all detectors. Since the - // 3-argument TGeoMedium constructor also leaves all tracking parameters - // (including ifield) at 0, and Geant4VMC's TG4GeometryManager:: - // FillMediumMapFromRoot() maps ALL TGeoMedium objects into one global table - // keyed purely by that raw numeric id (last one processed wins), these raw - // ids collided with other detectors' properly-assigned medium ids (e.g. the - // CAVE air medium that fills the gaps between TRK layers) and silently - // switched the magnetic field off for them. Route through MaterialManager - // instead, like every other detector (incl. FT3's own Detector.cxx) does, - // so ids are safely auto-assigned and never collide. + auto& matmgr = o2::base::MaterialManager::Instance(); int ifield = 2; From 4c67e112a8e07ad21cfe6db21ef83e53d3bb5b1c Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Tue, 22 Sep 2026 15:06:54 +0000 Subject: [PATCH 3/4] Please consider the following formatting changes --- .../Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx index bea858770b399..4438fb8a72a1d 100644 --- a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx @@ -55,7 +55,7 @@ void FT3Module::initialize_materials() if (siliconMat) { return; } - + auto& matmgr = o2::base::MaterialManager::Instance(); int ifield = 2; From b8968e726ff0aa2ffa082322948361997eb96357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 23 Sep 2026 06:20:34 +0200 Subject: [PATCH 4/4] Update FT3Module.cxx --- .../ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx index 4438fb8a72a1d..8ffcde04b12d7 100644 --- a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx @@ -58,8 +58,8 @@ void FT3Module::initialize_materials() auto& matmgr = o2::base::MaterialManager::Instance(); - int ifield = 2; - float fieldm = 10.0; + int ifield; // Initialized below + float fieldm; // Initialized below o2::base::Detector::initFieldTrackingParams(ifield, fieldm); float tmaxfdSi = 0.1; @@ -74,7 +74,9 @@ void FT3Module::initialize_materials() float epsilPas = 1.0E-4; float stminPas = 0.0; - // local ids 10-15: chosen to not clash with FT3's own createMaterials() (1, 3) + // FT3-local material/medium IDs: 10-15. Keep them distinct from IDs 1 and 3, + // which are already used by FT3 Detector::createMaterials() for AIR and SILICON. + // MaterialManager maps these local IDs to globally unique VMC medium IDs. matmgr.Material("FT3", 10, "Silicon", 28.0855, 14, 2.33, 0, 0); matmgr.Medium("FT3", 10, "Silicon", 10, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi); siliconMed = matmgr.getTGeoMedium("FT3", 10);