From 63cd5f4cc91d5cf65c01c14331a0d6e147afd7f2 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 3 Sep 2026 17:28:45 +0200 Subject: [PATCH 1/4] Give the FT0 cable container a hole for the beam pipe This fixes an overlap between the FT0 A-side cable container and the beam pipe. - 0CAA is a 40 x 40 x 0.5 cm air box centred on the beam axis, so it crosses the pipe wall and fills the pipe bore. - The box is now a composite shape with a 3 cm hole. The pipe outer radius there is 2.5 cm and the nearest cable sits at r = 5.68 cm. Co-Authored-By: Claude Opus 5 --- Detectors/FIT/FT0/simulation/src/Detector.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Detectors/FIT/FT0/simulation/src/Detector.cxx b/Detectors/FIT/FT0/simulation/src/Detector.cxx index fb756adba7df5..342da8df726a0 100644 --- a/Detectors/FIT/FT0/simulation/src/Detector.cxx +++ b/Detectors/FIT/FT0/simulation/src/Detector.cxx @@ -294,6 +294,13 @@ void Detector::SetCablesA(TGeoVolume* stl) TVirtualMC::GetMC()->Gsvolu("0CAA", "BOX", getMediumID(kAir), pcableplane, 3); // container for cables TGeoVolume* cableplane = gGeoManager->GetVolume("0CAA"); + // A hole for the beam pipe. The cable container spans the whole A-side face and + // would otherwise fill the pipe bore, which belongs to the beam-pipe vacuum. The + // pipe outer radius here is 2.5 cm and the nearest cable sits at r = 5.68 cm. + const float kBeamPipeHoleRadius = 3.; + new TGeoBBox("0CAAbox", pcableplane[0], pcableplane[1], pcableplane[2]); + new TGeoTube("0CAAhole", 0., kBeamPipeHoleRadius, pcableplane[2] + 0.1); + cableplane->SetShape(new TGeoCompositeShape("0CAAshape", "0CAAbox-0CAAhole")); // float zcableplane = -mStartA[2] + 2 * mInStart[2] + pcableplane[2]; int na = 0; double xcell[24], ycell[24]; From 844f0ecd2c8fb07a8f1e62dfd4f8b043e54d72e3 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 3 Sep 2026 17:28:45 +0200 Subject: [PATCH 2/4] Fix the unreachable vacuum of the A-side beam pipe This fixes a problem in the A-side beam pipe, whose vacuum volume occupied no space. - aluSideAVac was a daughter of aluSideA, a hollow Pcon that does not contain its own bore, so the navigator never descended into it. - The beam line from z = 44.5 cm to z = 426 cm was CAVE_Air, not PIPE_VACUUM. - The vacuum is now a daughter of the barrel. - Its bore stays at the third section's inner radius up to kZ36. The wider flange bore beyond it is occupied by the RB24 vacuum modules. Co-Authored-By: Claude Opus 5 --- Detectors/Passive/src/Pipe.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Detectors/Passive/src/Pipe.cxx b/Detectors/Passive/src/Pipe.cxx index 60c2256ba04bd..defd0dd0fd8ea 100644 --- a/Detectors/Passive/src/Pipe.cxx +++ b/Detectors/Passive/src/Pipe.cxx @@ -741,21 +741,22 @@ void Pipe::ConstructGeometry() zPos = aluSideA->GetZ(13) + flangeASteelRing->GetDz(); barrel->AddNode(voflangeASteelRing, 1, new TGeoTranslation(0., 30., zPos)); - // The vacuum inside aluSideA and flangeASteelRing - TGeoPcon* aluSideAVac = new TGeoPcon(0., 360., 8); + // The vacuum inside the aluminium section. aluSideA is a hollow Pcon, so it does + // not contain its own bore and the vacuum is a daughter of the barrel. The bore + // is kept at the third section's inner radius all the way to kZ36: the wider + // flange bore beyond it is occupied by the RB24 vacuum modules. + TGeoPcon* aluSideAVac = new TGeoPcon(0., 360., 6); aluSideAVac->DefineSection(0, aluSideA->GetZ(0), 0., aluSideA->GetRmin(0)); aluSideAVac->DefineSection(1, aluSideA->GetZ(1), 0., aluSideA->GetRmin(1)); aluSideAVac->DefineSection(2, aluSideA->GetZ(2), 0., aluSideA->GetRmin(2)); aluSideAVac->DefineSection(3, aluSideA->GetZ(7), 0., aluSideA->GetRmin(7)); aluSideAVac->DefineSection(4, aluSideA->GetZ(8), 0., aluSideA->GetRmin(8)); - aluSideAVac->DefineSection(5, aluSideA->GetZ(11), 0., aluSideA->GetRmin(11)); - aluSideAVac->DefineSection(6, aluSideA->GetZ(12), 0., aluSideA->GetRmin(12)); - aluSideAVac->DefineSection(7, aluSideA->GetZ(13), 0., aluSideA->GetRmin(13)); + aluSideAVac->DefineSection(5, aluSideA->GetZ(13), 0., aluSideA->GetRmin(9)); TGeoVolume* voaluSideAVac = new TGeoVolume("aluSideAVac", aluSideAVac, kMedVac); voaluSideAVac->SetLineColor(kGreen); voaluSideAVac->SetVisibility(1); - voaluSideA->AddNode(voaluSideAVac, 1, gGeoIdentity); + barrel->AddNode(voaluSideAVac, 1, new TGeoTranslation(0., 30., 0.)); // The support ring on A Side TGeoTube* sideASuppRing = new TGeoTube(kAluminum2ndSectionOuterRadius, kSupportRingRmax, kSupportRingLength / 2.); From fd9939ab5c29087996d299825c6bc52c4ffd9909 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 3 Sep 2026 17:28:45 +0200 Subject: [PATCH 3/4] Fix the buried Inox layers of the MCH station 1 quadrant frame This fixes a problem in the station 1 quadrant frame, where two Inox layers carried no material. - SQ03 and SQ05toSQ07 were placed at +kHzOuterFrameInox, their own half thickness, so each sat entirely inside the Epoxy layer it is stacked on. - They are now placed at +kHzOuterFrameEpoxy, the convention SQ17to23 and SQ18to24 already use. - This affects both quadrant chambers, SQM1 and SQM2. Co-Authored-By: Claude Opus 5 --- .../MCH/Geometry/Creator/src/Station1Geometry.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Detectors/MUON/MCH/Geometry/Creator/src/Station1Geometry.cxx b/Detectors/MUON/MCH/Geometry/Creator/src/Station1Geometry.cxx index 1820f22afe25d..f1289f72b3700 100644 --- a/Detectors/MUON/MCH/Geometry/Creator/src/Station1Geometry.cxx +++ b/Detectors/MUON/MCH/Geometry/Creator/src/Station1Geometry.cxx @@ -892,18 +892,18 @@ void createFrame(int chamber) y = 2 * (kHyInHFrame + kHyH1mm) + kIAF + kHyV1mm; Mlayer->AddNode(gGeoManager->GetVolume("SQ01"), 1, new TGeoTranslation(x, y, z)); - // TopFrameAnode - place 2 layers of TopFrameAnode cuboids + // TopFrameAnode - place 2 layers of TopFrameAnode cuboids. The Inox layer is + // stacked on top of the Epoxy one, as for SQ17to23/SQ18to24 below, so its centre + // sits at the Epoxy half-thickness and not at its own. x = kHxTFA; y = 2 * (kHyInHFrame + kHyH1mm + kHyInVFrame) + kIAF + kHyTFA; - z = kHzOuterFrameInox; - Mlayer->AddNode(gGeoManager->GetVolume("SQ02"), 1, new TGeoTranslation(x, y, -z)); - Mlayer->AddNode(gGeoManager->GetVolume("SQ03"), 1, new TGeoTranslation(x, y, z)); + Mlayer->AddNode(gGeoManager->GetVolume("SQ02"), 1, new TGeoTranslation(x, y, -kHzOuterFrameInox)); + Mlayer->AddNode(gGeoManager->GetVolume("SQ03"), 1, new TGeoTranslation(x, y, kHzOuterFrameEpoxy)); // TopFrameAnode - place 2 layers of 2 trapezoids (SQ04 - SQ07) x += kHxTFA + 2 * kH1FAA; - z = kHzOuterFrameInox; - Mlayer->AddNode(gGeoManager->GetVolume("SQ04toSQ06"), 1, new TGeoTranslation(x, y, -z)); - Mlayer->AddNode(gGeoManager->GetVolume("SQ05toSQ07"), 1, new TGeoTranslation(x, y, z)); + Mlayer->AddNode(gGeoManager->GetVolume("SQ04toSQ06"), 1, new TGeoTranslation(x, y, -kHzOuterFrameInox)); + Mlayer->AddNode(gGeoManager->GetVolume("SQ05toSQ07"), 1, new TGeoTranslation(x, y, kHzOuterFrameEpoxy)); // TopAnode1 - place 2 layers x = 6.8 + kDeltaQuadLHC; From f9516491bc2f95f82afe3d5e3dc810f1c853b631 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 3 Sep 2026 17:28:45 +0200 Subject: [PATCH 4/4] Give the two HMPID absorber plates distinct names This gives each HMPID absorber plate its own volume name and copy number. - createAbsorber was called twice, so both plates became a volume named Habs placed with copy number 0. - GetVolume("Habs") returned only the 40 mm plate, and both node paths were /cave_1/barrel_1/Habs_0, so the 80 mm plate could not be addressed at all. - The GDML export had to invent Habs0x2, Habs0x3 and Habs_00x1 for it. - The plates are now Habs2 and Habs4, with copy numbers 2 and 4. - The geometry is unchanged: same shapes, same media, same placements. https://its.cern.ch/jira/browse/O2-4136 Co-Authored-By: Claude Opus 5 --- .../simulation/include/HMPIDSimulation/Detector.h | 2 +- Detectors/HMPID/simulation/src/Detector.cxx | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Detectors/HMPID/simulation/include/HMPIDSimulation/Detector.h b/Detectors/HMPID/simulation/include/HMPIDSimulation/Detector.h index 9e9a78914049e..c37452c167430 100644 --- a/Detectors/HMPID/simulation/include/HMPIDSimulation/Detector.h +++ b/Detectors/HMPID/simulation/include/HMPIDSimulation/Detector.h @@ -55,7 +55,7 @@ class Detector : public o2::base::DetImpl void EndOfEvent() override { Reset(); } // for the geometry sub-parts - TGeoVolume* createAbsorber(float tickness); + TGeoVolume* createAbsorber(int chamber, float tickness); TGeoVolume* createChamber(int number); TGeoVolume* CreateCradle(); TGeoVolume* CradleBaseVolume(TGeoMedium* med, double l[7], const char* name); diff --git a/Detectors/HMPID/simulation/src/Detector.cxx b/Detectors/HMPID/simulation/src/Detector.cxx index 83bab71e7177d..6205d6781c446 100644 --- a/Detectors/HMPID/simulation/src/Detector.cxx +++ b/Detectors/HMPID/simulation/src/Detector.cxx @@ -538,12 +538,15 @@ void Detector::createMaterials() Medium(kAr, "Ar", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); } //************************************************************************************************** -TGeoVolume* Detector::createAbsorber(float tickness) +TGeoVolume* Detector::createAbsorber(int chamber, float tickness) { double cm = 1, mm = 0.1 * cm, um = 0.001 * mm; // default is cm auto& matmgr = o2::base::MaterialManager::Instance(); TGeoMedium* al = matmgr.getTGeoMedium("HMP_Al"); - TGeoVolume* abs = gGeoManager->MakeBox("Habs", al, tickness * mm / 2, 1300.00 * mm / 2, 1300 * mm / 2); + // one volume per chamber: the two plates differ in thickness, so a shared name + // would leave two different volumes answering to "Habs" and two placements whose + // node paths are both /cave_1/barrel_1/Habs_0 + TGeoVolume* abs = gGeoManager->MakeBox(Form("Habs%d", chamber), al, tickness * mm / 2, 1300.00 * mm / 2, 1300 * mm / 2); return abs; } //************************************************************************************************** @@ -1260,8 +1263,8 @@ void Detector::ConstructGeometry() TGeoVolume* hmpcradle = CreateCradle(); - TGeoVolume* hmpidabs_cham2 = createAbsorber(40.0); - TGeoVolume* hmpidabs_cham4 = createAbsorber(80.0); + TGeoVolume* hmpidabs_cham2 = createAbsorber(2, 40.0); + TGeoVolume* hmpidabs_cham4 = createAbsorber(4, 80.0); double theta = 33.5; @@ -1270,14 +1273,14 @@ void Detector::ConstructGeometry() pMatrixAbs2->SetTranslation(trans2); pMatrixAbs2->RotateZ(theta); - gGeoManager->GetVolume("barrel")->AddNode(hmpidabs_cham2, 0, pMatrixAbs2); + gGeoManager->GetVolume("barrel")->AddNode(hmpidabs_cham2, 2, pMatrixAbs2); TGeoHMatrix* pMatrixAbs4 = new TGeoHMatrix; const double trans4[] = {435., 0., 155.}; pMatrixAbs4->SetTranslation(trans4); pMatrixAbs4->RotateZ(theta); - gGeoManager->GetVolume("barrel")->AddNode(hmpidabs_cham4, 0, pMatrixAbs4); + gGeoManager->GetVolume("barrel")->AddNode(hmpidabs_cham4, 4, pMatrixAbs4); for (Int_t iCh = 0; iCh <= 6; iCh++) { // place 7 chambers TGeoVolume* hmpid = createChamber(iCh);