Skip to content

Commit 8beacd0

Browse files
sawenzelclaude
andcommitted
Place the ZEM calorimeters in the barrel volume
This fixes the ZEM calorimeters being placed outside their mother volume, so that they are simulated again. - ZEM and its 27 support volumes were placed in caveRB24 at global z 748 to 858 cm, while caveRB24 begins at z = 864.6 cm, so TGeo could not reach them and they produced no hits. - The barrel volume has owned that z range since commit 5166902, so the 29 placements go there, with the +30 cm offset the barrel carries in the cave. - shCaveTR3 in Cave.cxx grows from R = 80 to R = 105 cm, which the ZEM box walls at R = 95.7 cm need. 105 cm is what caveRB24 had in that range before. - ZEM is not built when FoCal is active, because every point of ZEM lies inside the FOCAL box. - 50 events of 20 muons at 200 GeV into 4.6 < eta < 5.3 give 0 ZDC hits before and 250 ZEM hits at z 757 to 784 cm after. - CheckOverlaps on caveRB24 goes from 29 extrusions to 0. https://its.cern.ch/jira/browse/O2-7156 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent d80c5cb commit 8beacd0

3 files changed

Lines changed: 61 additions & 33 deletions

File tree

Detectors/Passive/src/Cave.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void Cave::ConstructGeometry()
8585
shCaveTR1->DefineSection(0, -706. - 8.6, 0., 790.5);
8686
shCaveTR1->DefineSection(1, 707. + 7.6, 0., 790.5);
8787
TGeoTube* shCaveTR2 = new TGeoTube("shCaveTR2", 0., 150., 110.);
88-
TGeoTube* shCaveTR3 = new TGeoTube("shCaveTR3", 0., 80., 75.);
88+
TGeoTube* shCaveTR3 = new TGeoTube("shCaveTR3", 0., 105., 75.);
8989

9090
TGeoTranslation* transCaveTR2 = new TGeoTranslation("transTR2", 0, 30., -505. - 110.);
9191
TGeoTranslation* transCaveTR3 = new TGeoTranslation("transTR3", 0, 30., 714.6 + 75.);

Detectors/ZDC/simulation/include/ZDCSimulation/Detector.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ class Detector : public o2::base::DetImpl<Detector>
122122
void createMagnets();
123123
void createDetectors();
124124

125+
/// Whether the ZEM calorimeters are built: FoCal occupies the same space, so not
126+
/// when it is active.
127+
static Bool_t withZEM();
128+
125129
// determine detector; sector/tower and impact coordinates given volumename and position
126130
void getDetIDandSecID(TString const& volname, math_utils::Vector3D<float> const& x,
127131
math_utils::Vector3D<float>& xDet, int& detector, int& sector) const;

Detectors/ZDC/simulation/src/Detector.cxx

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <cassert>
3131
#include <fstream>
3232
#include "ZDCSimulation/ZDCSimParam.h"
33+
#include "SimConfig/SimConfig.h"
34+
#include <algorithm>
3335
#ifdef ZDC_FASTSIM_ONNX
3436
#include "Utils.h" // for normal_distribution()
3537
#include "FastSimulations.h" // for fastsim module
@@ -257,7 +259,7 @@ void Detector::defineSensitiveVolumes()
257259
AddSensitiveVolume(vol);
258260
mZEMVolID = vol->GetNumber();
259261
AddSensitiveVolume(gGeoManager->GetVolume("ZEMF"));
260-
} else {
262+
} else if (withZEM()) {
261263
LOG(fatal) << "can't find volume ZEM";
262264
}
263265
}
@@ -2302,6 +2304,10 @@ void Detector::createDetectors()
23022304

23032305
// -------------------------------------------------------------------------------
23042306
// -> EM calorimeter (ZEM)
2307+
if (!withZEM()) {
2308+
LOG(warning) << "ZDC: FoCal is active, so the ZEM calorimeters are not built -- they occupy the same space";
2309+
return;
2310+
}
23052311
int32_t irotzem1, irotzem2;
23062312
double rangzem1[6] = {0., 0., 90., 90., -90., 0.};
23072313
double rangzem2[6] = {180., 0., 90., 45. + 90., 90., 45.};
@@ -2354,16 +2360,19 @@ void Detector::createDetectors()
23542360
TVirtualMC::GetMC()->Gspos("ZEV1", 1, "ZETR", -zemVoidLayer[0] + zemTranLength, 0., 0., 0, "ONLY");
23552361

23562362
// --- Positioning the ZEM into the ZDC - rotation for 90 degrees
2357-
// NB -> ZEM is positioned in cave volume
2358-
const float z0 = 1313.3475 + 75.; // center of caveRB24 mother volume
2359-
TVirtualMC::GetMC()->Gspos("ZEM ", 1, "caveRB24", -Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + Geometry::ZEMDIMENSION[0] - z0, irotzem1, "ONLY");
2363+
// NB -> ZEM is positioned in the barrel volume
2364+
// The ZEM calorimeters and their supports occupy 750 < z < 860 cm, a region that
2365+
// belongs to the barrel mother volume (caveRB24 starts only at z = 864.6 cm).
2366+
// The barrel is placed at y = -30 cm in the cave, hence the y0 offset.
2367+
const float y0 = 30.;
2368+
TVirtualMC::GetMC()->Gspos("ZEM ", 1, "barrel", -Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1] + y0, Geometry::ZEMPOSITION[2] + Geometry::ZEMDIMENSION[0], irotzem1, "ONLY");
23602369

23612370
// Second EM ZDC (same side w.r.t. IP, just on the other side w.r.t. beam pipe)
2362-
TVirtualMC::GetMC()->Gspos("ZEM ", 2, "caveRB24", Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + Geometry::ZEMDIMENSION[0] - z0, irotzem1, "ONLY");
2371+
TVirtualMC::GetMC()->Gspos("ZEM ", 2, "barrel", Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1] + y0, Geometry::ZEMPOSITION[2] + Geometry::ZEMDIMENSION[0], irotzem1, "ONLY");
23632372

23642373
// --- Adding last slice at the end of the EM calorimeter
23652374
float zLastSlice = Geometry::ZEMPOSITION[2] + zemPbSlice[0] + 2 * Geometry::ZEMDIMENSION[0];
2366-
TVirtualMC::GetMC()->Gspos("ZEL2", 1, "caveRB24", Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1], zLastSlice - z0, irotzem1, "ONLY");
2375+
TVirtualMC::GetMC()->Gspos("ZEL2", 1, "barrel", Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1] + y0, zLastSlice, irotzem1, "ONLY");
23672376

23682377
// -------------------------------------------------------------------------------
23692378
// -> ZEM supports
@@ -2376,31 +2385,31 @@ void Detector::createDetectors()
23762385
// Bridge
23772386
TVirtualMC::GetMC()->Gsvolu("ZESH", "BOX ", getMediumID(kAl), const_cast<double*>(zemSupport1), 3);
23782387
float ybridge = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2. * 2. * zemSupportBox[3 + 1] - 5. - zemSupport1[1];
2379-
TVirtualMC::GetMC()->Gspos("ZESH", 1, "caveRB24", Geometry::ZEMPOSITION[0], ybridge, zbox - z0, 0, "ONLY");
2380-
TVirtualMC::GetMC()->Gspos("ZESH", 2, "caveRB24", -Geometry::ZEMPOSITION[0], ybridge, zbox - z0, 0, "ONLY");
2388+
TVirtualMC::GetMC()->Gspos("ZESH", 1, "barrel", Geometry::ZEMPOSITION[0], ybridge + y0, zbox, 0, "ONLY");
2389+
TVirtualMC::GetMC()->Gspos("ZESH", 2, "barrel", -Geometry::ZEMPOSITION[0], ybridge + y0, zbox, 0, "ONLY");
23812390
//
23822391
TVirtualMC::GetMC()->Gsvolu("ZESV", "BOX ", getMediumID(kAl), const_cast<double*>(zemSupport2), 3);
2383-
TVirtualMC::GetMC()->Gspos("ZESV", 1, "caveRB24", Geometry::ZEMPOSITION[0] - zemSupportBox[0] + zemSupport2[0], ybox - zemSupportBox[1] - zemSupport2[1], zbox - z0, 0, "ONLY");
2384-
TVirtualMC::GetMC()->Gspos("ZESV", 2, "caveRB24", Geometry::ZEMPOSITION[0] + zemSupportBox[0] - zemSupport2[0], ybox - zemSupportBox[1] - zemSupport2[1], zbox - z0, 0, "ONLY");
2385-
TVirtualMC::GetMC()->Gspos("ZESV", 3, "caveRB24", -(Geometry::ZEMPOSITION[0] - zemSupportBox[0] + zemSupport2[0]), ybox - zemSupportBox[1] - zemSupport2[1], zbox - z0, 0, "ONLY");
2386-
TVirtualMC::GetMC()->Gspos("ZESV", 4, "caveRB24", -(Geometry::ZEMPOSITION[0] + zemSupportBox[0] - zemSupport2[0]), ybox - zemSupportBox[1] - zemSupport2[1], zbox - z0, 0, "ONLY");
2392+
TVirtualMC::GetMC()->Gspos("ZESV", 1, "barrel", Geometry::ZEMPOSITION[0] - zemSupportBox[0] + zemSupport2[0], ybox - zemSupportBox[1] - zemSupport2[1] + y0, zbox, 0, "ONLY");
2393+
TVirtualMC::GetMC()->Gspos("ZESV", 2, "barrel", Geometry::ZEMPOSITION[0] + zemSupportBox[0] - zemSupport2[0], ybox - zemSupportBox[1] - zemSupport2[1] + y0, zbox, 0, "ONLY");
2394+
TVirtualMC::GetMC()->Gspos("ZESV", 3, "barrel", -(Geometry::ZEMPOSITION[0] - zemSupportBox[0] + zemSupport2[0]), ybox - zemSupportBox[1] - zemSupport2[1] + y0, zbox, 0, "ONLY");
2395+
TVirtualMC::GetMC()->Gspos("ZESV", 4, "barrel", -(Geometry::ZEMPOSITION[0] + zemSupportBox[0] - zemSupport2[0]), ybox - zemSupportBox[1] - zemSupport2[1] + y0, zbox, 0, "ONLY");
23872396

23882397
// Table
23892398
TVirtualMC::GetMC()->Gsvolu("ZETA", "BOX ", getMediumID(kAl), const_cast<double*>(zemSupportTable), 3);
23902399
float ytable = ybridge - zemSupport1[1] - zemSupportTable[1];
2391-
TVirtualMC::GetMC()->Gspos("ZETA", 1, "caveRB24", 0.0, ytable, zbox - z0, 0, "ONLY");
2392-
TVirtualMC::GetMC()->Gspos("ZETA", 2, "caveRB24", 0.0, ytable - 13. + 2. * zemSupportTable[1], zbox - z0, 0, "ONLY");
2400+
TVirtualMC::GetMC()->Gspos("ZETA", 1, "barrel", 0.0, ytable + y0, zbox, 0, "ONLY");
2401+
TVirtualMC::GetMC()->Gspos("ZETA", 2, "barrel", 0.0, ytable - 13. + 2. * zemSupportTable[1] + y0, zbox, 0, "ONLY");
23932402

23942403
//Screens around ZEM
23952404
TVirtualMC::GetMC()->Gsvolu("ZEFL", "BOX ", getMediumID(kAl), const_cast<double*>(zemSupport3), 3);
2396-
TVirtualMC::GetMC()->Gspos("ZEFL", 1, "caveRB24", Geometry::ZEMPOSITION[0], -Geometry::ZEMDIMENSION[1] - zemSupport3[1], zSupport + zemSupport3[2] - z0, 0, "ONLY");
2397-
TVirtualMC::GetMC()->Gspos("ZEFL", 2, "caveRB24", -Geometry::ZEMPOSITION[0], -Geometry::ZEMDIMENSION[1] - zemSupport3[1], zSupport + zemSupport3[2] - z0, 0, "ONLY");
2405+
TVirtualMC::GetMC()->Gspos("ZEFL", 1, "barrel", Geometry::ZEMPOSITION[0], -Geometry::ZEMDIMENSION[1] - zemSupport3[1] + y0, zSupport + zemSupport3[2], 0, "ONLY");
2406+
TVirtualMC::GetMC()->Gspos("ZEFL", 2, "barrel", -Geometry::ZEMPOSITION[0], -Geometry::ZEMDIMENSION[1] - zemSupport3[1] + y0, zSupport + zemSupport3[2], 0, "ONLY");
23982407

23992408
TVirtualMC::GetMC()->Gsvolu("ZELA", "PARA", getMediumID(kAl), const_cast<double*>(zemSupport4), 6);
2400-
TVirtualMC::GetMC()->Gspos("ZELA", 1, "caveRB24", Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - zemSupport4[2], Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + zemSupport4[0] - z0, irotzem1, "ONLY");
2401-
TVirtualMC::GetMC()->Gspos("ZELA", 2, "caveRB24", Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + zemSupport4[2], Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + zemSupport4[0] - z0, irotzem1, "ONLY");
2402-
TVirtualMC::GetMC()->Gspos("ZELA", 3, "caveRB24", -(Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - zemSupport4[2]), Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + zemSupport4[0] - z0, irotzem1, "ONLY");
2403-
TVirtualMC::GetMC()->Gspos("ZELA", 4, "caveRB24", -(Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + zemSupport4[2]), Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + zemSupport4[0] - z0, irotzem1, "ONLY");
2409+
TVirtualMC::GetMC()->Gspos("ZELA", 1, "barrel", Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - zemSupport4[2], Geometry::ZEMPOSITION[1] + y0, Geometry::ZEMPOSITION[2] + zemSupport4[0], irotzem1, "ONLY");
2410+
TVirtualMC::GetMC()->Gspos("ZELA", 2, "barrel", Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + zemSupport4[2], Geometry::ZEMPOSITION[1] + y0, Geometry::ZEMPOSITION[2] + zemSupport4[0], irotzem1, "ONLY");
2411+
TVirtualMC::GetMC()->Gspos("ZELA", 3, "barrel", -(Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - zemSupport4[2]), Geometry::ZEMPOSITION[1] + y0, Geometry::ZEMPOSITION[2] + zemSupport4[0], irotzem1, "ONLY");
2412+
TVirtualMC::GetMC()->Gspos("ZELA", 4, "barrel", -(Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + zemSupport4[2]), Geometry::ZEMPOSITION[1] + y0, Geometry::ZEMPOSITION[2] + zemSupport4[0], irotzem1, "ONLY");
24042413

24052414
// Containers for ZEM calorimeters
24062415
TVirtualMC::GetMC()->Gsvolu("ZEW1", "BOX ", getMediumID(kAl), const_cast<double*>(zemWallH), 3);
@@ -2410,22 +2419,37 @@ void Detector::createDetectors()
24102419
//
24112420
float yh1 = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2 * zemSupport3[1] - zemWallH[1];
24122421
float zh1 = zSupport + zemWallH[2];
2413-
TVirtualMC::GetMC()->Gspos("ZEW1", 1, "caveRB24", Geometry::ZEMPOSITION[0], yh1, zh1 - z0, 0, "ONLY");
2414-
TVirtualMC::GetMC()->Gspos("ZEW1", 2, "caveRB24", Geometry::ZEMPOSITION[0], yh1 + 2 * zemSupportBox[1], zh1 - z0, 0, "ONLY");
2415-
TVirtualMC::GetMC()->Gspos("ZEW1", 3, "caveRB24", -Geometry::ZEMPOSITION[0], yh1, zh1 - z0, 0, "ONLY");
2416-
TVirtualMC::GetMC()->Gspos("ZEW1", 4, "caveRB24", -Geometry::ZEMPOSITION[0], yh1 + 2 * zemSupportBox[1], zh1 - z0, 0, "ONLY");
2422+
TVirtualMC::GetMC()->Gspos("ZEW1", 1, "barrel", Geometry::ZEMPOSITION[0], yh1 + y0, zh1, 0, "ONLY");
2423+
TVirtualMC::GetMC()->Gspos("ZEW1", 2, "barrel", Geometry::ZEMPOSITION[0], yh1 + 2 * zemSupportBox[1] + y0, zh1, 0, "ONLY");
2424+
TVirtualMC::GetMC()->Gspos("ZEW1", 3, "barrel", -Geometry::ZEMPOSITION[0], yh1 + y0, zh1, 0, "ONLY");
2425+
TVirtualMC::GetMC()->Gspos("ZEW1", 4, "barrel", -Geometry::ZEMPOSITION[0], yh1 + 2 * zemSupportBox[1] + y0, zh1, 0, "ONLY");
24172426
//
2418-
TVirtualMC::GetMC()->Gspos("ZEW2", 1, "caveRB24", Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1], zSupport - zemWallVfwd[2] - z0, 0, "ONLY");
2419-
TVirtualMC::GetMC()->Gspos("ZEW3", 1, "caveRB24", Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1], zSupport + 2 * zemWallH[2] - z0, 0, "ONLY");
2420-
TVirtualMC::GetMC()->Gspos("ZEW2", 2, "caveRB24", -Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1], zSupport - zemWallVfwd[2] - z0, 0, "ONLY");
2421-
TVirtualMC::GetMC()->Gspos("ZEW3", 2, "caveRB24", -Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1], zSupport + 2 * zemWallH[2] - z0, 0, "ONLY");
2427+
TVirtualMC::GetMC()->Gspos("ZEW2", 1, "barrel", Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1] + y0, zSupport - zemWallVfwd[2], 0, "ONLY");
2428+
TVirtualMC::GetMC()->Gspos("ZEW3", 1, "barrel", Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1] + y0, zSupport + 2 * zemWallH[2], 0, "ONLY");
2429+
TVirtualMC::GetMC()->Gspos("ZEW2", 2, "barrel", -Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1] + y0, zSupport - zemWallVfwd[2], 0, "ONLY");
2430+
TVirtualMC::GetMC()->Gspos("ZEW3", 2, "barrel", -Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1] + y0, zSupport + 2 * zemWallH[2], 0, "ONLY");
24222431
//
24232432
float xl1 = Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - 2. * zemSupport4[2] - zemWallVside[0];
24242433
float xl2 = Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + 2. * zemSupport4[2] + zemWallVside[0];
2425-
TVirtualMC::GetMC()->Gspos("ZEW4", 1, "caveRB24", xl1, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY");
2426-
TVirtualMC::GetMC()->Gspos("ZEW4", 2, "caveRB24", xl2, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY");
2427-
TVirtualMC::GetMC()->Gspos("ZEW4", 3, "caveRB24", -xl1, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY");
2428-
TVirtualMC::GetMC()->Gspos("ZEW4", 4, "caveRB24", -xl2, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY");
2434+
TVirtualMC::GetMC()->Gspos("ZEW4", 1, "barrel", xl1, yh1 + zemSupportBox[1] + y0, zh1, 0, "ONLY");
2435+
TVirtualMC::GetMC()->Gspos("ZEW4", 2, "barrel", xl2, yh1 + zemSupportBox[1] + y0, zh1, 0, "ONLY");
2436+
TVirtualMC::GetMC()->Gspos("ZEW4", 3, "barrel", -xl1, yh1 + zemSupportBox[1] + y0, zh1, 0, "ONLY");
2437+
TVirtualMC::GetMC()->Gspos("ZEW4", 4, "barrel", -xl2, yh1 + zemSupportBox[1] + y0, zh1, 0, "ONLY");
2438+
}
2439+
2440+
//_____________________________________________________________________________
2441+
/// FoCal occupies the space the ZEM calorimeters sit in -- every point of ZEM lies
2442+
/// inside the FOCAL box -- so the two cannot both be built. Which of them the Run 4
2443+
/// layout keeps, and where a Run 4 ZEM would go, is for the ZDC and FoCal groups to
2444+
/// settle; until they do, FoCal wins, which is what the geometry did by accident
2445+
/// while ZEM was placed outside its mother and unreachable.
2446+
///
2447+
/// An empty active-module list (a geometry built outside o2-sim) means Run 3, and
2448+
/// ZEM is built.
2449+
Bool_t Detector::withZEM()
2450+
{
2451+
const auto& modules = o2::conf::SimConfig::Instance().getActiveModules();
2452+
return std::find(modules.begin(), modules.end(), "FOC") == modules.end();
24292453
}
24302454

24312455
//_____________________________________________________________________________

0 commit comments

Comments
 (0)