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