85 bool hasStations = inertObjs.size() || stations.size();
88 LocalVariablesContainer aLVC;
98 if (!aLVC.m_adjustStatic || !aLVC.m_static3d) {
99 ATH_MSG_INFO(
" diluted inert material hardcoded for 3D "
100 "volume frame, adjusting setup");
101 aLVC.m_adjustStatic =
true;
102 aLVC.m_static3d =
true;
115 aLVC.m_muonMaterial =
Trk::Material(10e10, 10e10, 0., 0., 0.);
129 for (
unsigned int i = 0;
i < envelopeDefsIn.size();
i++) {
132 else if (envelopeDefsIn[
i].
second == envelopeDefsIn[ii].
second &&
133 envelopeDefsIn[
i].
first > envelopeDefsIn[ii].
first)
139 unsigned int inext = ii + 1;
140 if (inext == envelopeDefsIn.size())
142 if (envelopeDefsIn[inext].
second != envelopeDefsIn[ii].
second) {
144 inext = ii > 0 ? ii - 1 : envelopeDefsIn.size() - 1;
149 for (
unsigned int i = inext;
i < envelopeDefsIn.size();
i++)
150 envelopeDefs.push_back(envelopeDefsIn[
i]);
152 for (
unsigned int i = 0;
i <= inext - 1;
i++)
153 envelopeDefs.push_back(envelopeDefsIn[
i]);
157 envelopeDefs.push_back(envelopeDefsIn[
i]);
160 inext = envelopeDefsIn.size() - 1;
161 while (inext >= ii) {
162 envelopeDefs.push_back(envelopeDefsIn[inext]);
169 for (
auto& envelopeDef : envelopeDefs) {
170 if (envelopeDef.first > maxR)
171 maxR = envelopeDef.first;
174 aLVC.m_outerBarrelRadius = maxR;
175 aLVC.m_outerEndcapZ = envelopeDefs[0].second;
178 << aLVC.m_outerBarrelRadius <<
","
179 << aLVC.m_outerEndcapZ);
183 for (
unsigned int i = 0;
i < envelopeDefs.size();
i++) {
185 <<
"," << envelopeDefs[
i].
second);
192 auto globalBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_outerBarrelRadius, aLVC.m_outerEndcapZ);
193 auto topVolume = std::make_unique<Trk::TrackingVolume>(
nullptr, globalBounds.release(), aLVC.m_muonMaterial,
194 nullptr,
nullptr,
"GlobalVolume");
195 return std::make_unique<Trk::TrackingGeometry>(topVolume.release());
204 std::vector<TrackingVolumePtr> volumeGarbage{};
207 negativeMuonBigWheel{}, negativeMuonOuterBuffer{},
208 positiveMuonOuterWheel{}, negativeMuonSmallWheel{},
209 positiveMuonSmallWheel{}, negativeECT{}, positiveECT{},
210 positiveMuonBigWheel{}, positiveMuonOuterBuffer{};
212 TrackingVolumePtr negBeamPipe{}, posBeamPipe{}, negDiskShield{}, posDiskShield{},
213 negInnerShield{}, posInnerShield{}, negOuterShield{}, posOuterShield{};
215 std::unique_ptr<Trk::CylinderVolumeBounds> enclosedBounds{};
219 negativeMuonInnerEndcap{}, positiveMuonInnerEndcap{},
220 negNavOEndcap{}, posNavOEndcap{}, negativeMuonOuterEndcap{},
221 positiveMuonOuterEndcap{},
barrel{}, negOuterEndcap{},
222 posOuterEndcap{}, negInnerEndcap{}, posInnerEndcap{}, negNavEndcap{},
228 bool msEntryDefined =
false;
230 msEntryDefined =
true;
234 if (!enclosedDetectorBounds) {
235 ATH_MSG_ERROR(
" dynamic cast of enclosed volume to the cylinder bounds failed, aborting MTG build-up ");
238 double enclosedDetectorHalfZ = enclosedDetectorBounds->halflengthZ();
239 double enclosedDetectorOuterRadius =
240 enclosedDetectorBounds->outerRadius();
246 if (!enclosedCentralFaceVolumes.empty()) {
248 if (cylR && cylR->outerRadius() != enclosedDetectorOuterRadius) {
251 "correspond to radius of glue volumes : adjusted ");
254 if (!enclosedNegativeFaceVolumes.empty() &&
255 !enclosedPositiveFaceVolumes.empty()) {
256 double negZ = -enclosedDetectorHalfZ;
257 double posZ = enclosedDetectorHalfZ;
260 negZ = enclosedNegativeFaceVolumes[0]->center().z() - cylN->halflengthZ();
264 posZ = enclosedPositiveFaceVolumes[0]->center().z() +
267 if (std::abs(negZ + enclosedDetectorHalfZ) > 0.001 ||
268 std::abs(
posZ - enclosedDetectorHalfZ) > 0.001) {
269 ATH_MSG_WARNING(
" enclosed volume envelope z dimension does not correspond to that of glue volumes ");
270 if (std::abs(negZ +
posZ) < 0.001) {
271 enclosedDetectorHalfZ =
posZ;
274 ATH_MSG_ERROR(
"assymetric Z dimensions - cannot recover " << negZ <<
"," <<
posZ);
282 ATH_MSG_DEBUG(
" dimensions of enclosed detectors (halfZ,outerR):"
283 << enclosedDetectorHalfZ <<
","<< enclosedDetectorOuterRadius);
286 if (enclosedDetectorOuterRadius > aLVC.m_innerBarrelRadius) {
288 "muon envelope, abandon :R:"
289 << enclosedDetectorOuterRadius);
292 aLVC.m_innerBarrelRadius = enclosedDetectorOuterRadius;
297 <<
"muon envelope, abandon :Z:"<< enclosedDetectorHalfZ);
301 auto barrelZPBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
302 0.5 * (
m_barrelZ - enclosedDetectorHalfZ));
303 auto barrelZMBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
304 0.5 * (
m_barrelZ - enclosedDetectorHalfZ));
305 double zbShift = 0.5 * (
m_barrelZ + enclosedDetectorHalfZ);
308 barrelZPBounds.release(), aLVC.m_muonMaterial,
nullptr,
309 nullptr,
"BarrelRZPosBuffer");
311 barrelZMBounds.release(), aLVC.m_muonMaterial,
nullptr,
312 nullptr,
"BarrelRZNegBuffer");
317 std::move(barrelZPBuffer),
320 std::string nameEncl = msEntryDefined ?
"All::Gaps::Barrel" :
m_entryVolume;
324 std::move(barrelZMBuffer),
340 <<
" m_enclosingEnvelopeSvc "
344 for (
const auto& envelopeDef : envelopeDefs) {
345 rmax =
std::max(envelopeDef.first, rmax);
348 if (!envelopeDefs.empty()) {
349 if (rmax > 0. && rmax <= aLVC.m_innerBarrelRadius &&
351 enclosedBounds = std::make_unique<Trk::CylinderVolumeBounds>(rmax,
zmax);
354 <<
") clashes with MS material, switch to default values (R,Z:"
355 << aLVC.m_innerBarrelRadius <<
"," <<
m_barrelZ <<
")");
360 if (!enclosedBounds) {
361 enclosedBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
m_barrelZ);
364 enclosed = std::make_unique<Trk::TrackingVolume>(
nullptr, enclosedBounds.release(),
365 aLVC.m_muonMaterial,
nullptr,
374 for (
auto& envelopeDef : envelopeDefs) {
377 if (!aLVC.m_msCutoutsIn.empty() &&
378 aLVC.m_msCutoutsIn.back().second == -aLVC.m_outerEndcapZ)
380 if (aLVC.m_msCutoutsIn.empty() ||
381 std::abs(aLVC.m_msCutoutsIn.back().second) >
m_barrelZ ||
382 std::abs(envelopeDef.second) >
m_barrelZ)
383 aLVC.m_msCutoutsIn.push_back(envelopeDef);
384 else if (!aLVC.m_msCutoutsIn.empty() &&
385 aLVC.m_msCutoutsIn.back().second ==
m_barrelZ &&
386 aLVC.m_msCutoutsIn.back().first != aLVC.m_innerBarrelRadius) {
387 aLVC.m_msCutoutsIn.emplace_back(aLVC.m_innerBarrelRadius,
389 aLVC.m_msCutoutsIn.emplace_back(aLVC.m_innerBarrelRadius,
391 aLVC.m_msCutoutsIn.emplace_back(
392 aLVC.m_msCutoutsIn[aLVC.m_msCutoutsIn.size() - 3].first,
398 while (envelopeDefs[
il - 1].
second != -aLVC.m_outerEndcapZ)
400 for (;
il < envelopeDefs.size();
il++)
401 aLVC.m_msCutoutsOut.push_back(envelopeDefs[
il]);
403 for (
unsigned int i = 0;
i < aLVC.m_msCutoutsIn.size();
i++) {
405 <<
i <<
":" << aLVC.m_msCutoutsIn[
i].first <<
","
406 << aLVC.m_msCutoutsIn[
i].second);
408 for (
unsigned int i = 0;
i < aLVC.m_msCutoutsOut.size();
i++) {
410 <<
i <<
":" << aLVC.m_msCutoutsOut[
i].first <<
","
411 << aLVC.m_msCutoutsOut[
i].second);
414 if (aLVC.m_msCutoutsIn[5].second != aLVC.m_innerEndcapZ) {
415 aLVC.m_innerEndcapZ = aLVC.m_msCutoutsIn[5].second;
423 auto negDiskShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
426 negDiskShieldBounds.release());
427 negDiskShield =
processShield(negDiskVol, 2,
"Muons::Detectors::NegativeDiskShield",
430 auto posDiskShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
433 posDiskShieldBounds.release());
434 posDiskShield =
processShield(posDiskVol, 2,
"Muons::Detectors::PositiveDiskShield",
440 std::move(posDiskShield),
442 "Container::CentralP");
445 std::move(negDiskShield),
447 "Container::Central");
449 if (aLVC.m_adjustStatic) {
455 auto barrelBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
456 aLVC.m_outerBarrelRadius,
458 Trk::Volume barrelVol(
nullptr, barrelBounds.release());
461 if (aLVC.m_adjustStatic && aLVC.m_static3d)
462 muonBarrel =
processVolume(barrelVol, 0,
"Detectors::Barrel",
464 else if (aLVC.m_adjustStatic)
465 muonBarrel =
processVolume(barrelVol, -1,
"Detectors::Barrel",
469 "Detectors::Barrel", aLVC, hasStations);
474 auto negativeSmallWheelBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_innerShieldRadius,
475 aLVC.m_outerBarrelRadius,
476 smallWheelZHalfSize);
479 negativeSmallWheelBounds.release());
480 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
481 negativeMuonSmallWheel =
processVolume(negSWVol, 1,
"Detectors::NegativeSmallWheel",
483 }
else if (aLVC.m_adjustStatic) {
484 negativeMuonSmallWheel =
processVolume(negSWVol, -1,
"Detectors::NegativeSmallWheel",
490 "Detectors::NegativeSmallWheel",
495 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
496 positiveMuonSmallWheel =
processVolume(posSWVol, 1,
"Detectors::PositiveSmallWheel",
498 }
else if (aLVC.m_adjustStatic) {
499 positiveMuonSmallWheel =
processVolume(posSWVol, -1,
"Detectors::PositiveSmallWheel",
508 double ectZHalfSize = 0.5 * (aLVC.m_innerEndcapZ -
m_ectZ);
511 aLVC.m_outerBarrelRadius,
515 negativeECTBounds.release());
516 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
517 negativeECT =
processVolume(negECTVol, 2,
"Detectors::NegativeECT",
519 }
else if (aLVC.m_adjustStatic) {
520 negativeECT =
processVolume(negECTVol, -1,
"Detectors::NegativeECT",
524 "Detectors::NegativeECT", aLVC, hasStations);
531 positiveECT =
processVolume(posECTVol, 2,
"Detectors::PositiveECT",
533 }
else if (aLVC.m_adjustStatic) {
534 positiveECT =
processVolume(posECTVol, -1,
"Detectors::PositiveECT",
545 std::move(negativeMuonSmallWheel),
547 "Container::NegInnerEndcap"));
548 positiveMuonInnerEndcap = (
m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonSmallWheel),
550 std::move(positiveECT),
552 "Container::PosInnerEndcap"));
555 double innerEndcapZHalfSize = 0.5 * (aLVC.m_innerEndcapZ -
m_diskShieldZ);
556 auto negInnerShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
558 innerEndcapZHalfSize);
560 negInnerShieldBounds.release()};
561 negInnerShield =
processShield(negisVol, 1,
"Muons::Detectors::NegativeInnerShield",
564 auto posInnerShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
566 innerEndcapZHalfSize);
568 posInnerShieldBounds.release());
569 posInnerShield =
processShield(posisVol, 1,
"Muons::Detectors::PositiveInnerShield",
575 double outerWheelZHalfSize = 0.5 * (aLVC.m_outerEndcapZ -
m_outerWheel);
576 auto negativeOuterWheelBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_outerShieldRadius,
577 aLVC.m_outerBarrelRadius,
578 outerWheelZHalfSize);
580 outerWheelZHalfSize)),
581 negativeOuterWheelBounds.release());
582 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
583 negativeMuonOuterWheel =
processVolume(negOWVol, 3,
"Detectors::NegativeOuterWheel",
585 }
else if (aLVC.m_adjustStatic) {
586 negativeMuonOuterWheel =
processVolume(negOWVol, -1,
"Detectors::NegativeOuterWheel",
597 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
598 positiveMuonOuterWheel =
processVolume(posOWVol, 3,
"Detectors::PositiveOuterWheel",
600 }
else if (aLVC.m_adjustStatic) {
601 positiveMuonOuterWheel =
processVolume(posOWVol, -1,
"Detectors::PositiveOuterWheel",
610 auto negativeOuterBufferBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_outerShieldRadius,
611 aLVC.m_outerBarrelRadius,
612 outerBufferZHalfSize);
615 outerBufferZHalfSize)),
616 negativeOuterBufferBounds.release());
617 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
618 negativeMuonOuterBuffer =
processVolume(negBuffVol, 3,
"Detectors::NegativeOuterBuffer",
620 }
else if (aLVC.m_adjustStatic) {
621 negativeMuonOuterBuffer =
processVolume(negBuffVol, -1,
"Detectors::NegativeOuterBuffer",
630 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
631 positiveMuonOuterBuffer =
processVolume(posBuffVol, 3,
"Detectors::PositiveOuterBuffer",
633 }
else if (aLVC.m_adjustStatic) {
634 positiveMuonOuterBuffer =
processVolume(posBuffVol, -1,
"Detectors::PositiveOuterBuffer",
642 double bigWheelZHalfSize = 0.5 * (
m_bigWheel - aLVC.m_innerEndcapZ);
643 auto negativeBigWheelBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_outerShieldRadius,
644 aLVC.m_outerBarrelRadius,
649 negativeBigWheelBounds.release());
650 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
651 negativeMuonBigWheel =
processVolume(negBWVol, 3,
"Detectors::NegativeBigWheel",
653 }
else if (aLVC.m_adjustStatic) {
654 negativeMuonBigWheel =
processVolume(negBWVol, -1,
"Detectors::NegativeBigWheel",
664 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
665 positiveMuonBigWheel =
processVolume(posBWVol, 3,
"Detectors::PositiveBigWheel",
667 }
else if (aLVC.m_adjustStatic) {
668 positiveMuonBigWheel =
processVolume(posBWVol, -1,
"Detectors::PositiveBigWheel",
678 std::move(negativeMuonOuterBuffer),
680 "Container::NegOEndcap");
684 std::move(positiveMuonOuterWheel),
686 "Container::PosOEndcap");
691 std::move(negativeMuonBigWheel),
693 "Container::NegOuterEndcap");
695 positiveMuonOuterEndcap =
m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonBigWheel),
697 std::move(posNavOEndcap),
699 "Container::PosOuterEndcap");
702 double outerEndcapZHalfSize = 0.5 * (aLVC.m_outerEndcapZ - aLVC.m_innerEndcapZ);
703 double outerEndcapPosition = 0.5 * (aLVC.m_outerEndcapZ + aLVC.m_innerEndcapZ);
704 auto negOuterShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
706 outerEndcapZHalfSize);
708 negOuterShieldBounds.release());
709 negOuterShield =
processShield(negosVol, 0,
"Muons::Detectors::NegativeOuterShield",
712 auto posOuterShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
715 posOuterShieldBounds.release());
716 posOuterShield =
processShield(pososVol, 0,
"Muons::Detectors::PositiveOuterShield",
720 auto negBeamPipeBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
721 outerEndcapZHalfSize + innerEndcapZHalfSize);
722 auto posBeamPipeBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
723 outerEndcapZHalfSize + innerEndcapZHalfSize);
725 negBeamPipeBounds.release());
726 negBeamPipe =
processVolume(negbpVol, 1, 1,
"Muons::Gaps::NegativeBeamPipe",
729 posBeamPipeBounds.release());
730 posBeamPipe =
processVolume(posbpVol, 1, 1,
"Muons::Gaps::PositiveBeamPipe",
733 negBeamPipe->registerColorCode(0);
734 posBeamPipe->registerColorCode(0);
746 "All::Container::Barrel");
751 std::move(negOuterShield),
753 "Container::NegativeOuterEndcap");
757 std::move(posOuterShield),
759 "Container::PositiveOuterEndcap");
765 std::move(negInnerShield),
767 "Container::NegativeInnerEndcap");
771 std::move(posInnerShield),
773 "Container::PositiveInnerEndcap");
779 std::move(negInnerEndcap),
781 "Container::NegativeEndcap");
785 std::move(posOuterEndcap),
787 "Container::PositiveEndcap");
793 std::move(negBeamPipe),
795 "All::Container::NegativeEndcap"));
798 std::move(posBeamPipe),
800 "All::Container::PositiveEndcap"));
810 "All::Container::NegDet");
824 trackingGeometry->addToGarbage(std::move(stations));
825 trackingGeometry->addToGarbage(std::move(inertObjs));
827 volumeGarbage.push_back(std::move(negativeMuonOuterWheel));
828 volumeGarbage.push_back(std::move(negativeMuonBigWheel));
829 volumeGarbage.push_back(std::move(negativeMuonOuterBuffer));
830 volumeGarbage.push_back(std::move(positiveMuonOuterWheel));
832 volumeGarbage.push_back(std::move(negativeMuonSmallWheel));
833 volumeGarbage.push_back(std::move(positiveMuonSmallWheel));
834 volumeGarbage.push_back(std::move(negativeECT));
835 volumeGarbage.push_back(std::move(positiveECT));
836 volumeGarbage.push_back(std::move(positiveMuonBigWheel));
838 volumeGarbage.push_back(std::move(positiveMuonOuterBuffer));
839 volumeGarbage.push_back(std::move(negDiskShield));
840 volumeGarbage.push_back(std::move(posDiskShield));
842 trackingGeometry->addToGarbage(std::move(volumeGarbage));
844 ATH_MSG_DEBUG(
" with " << aLVC.m_frameNum <<
" subvolumes at navigation level");
845 ATH_MSG_DEBUG(
"( mean number of enclosed detached volumes:" <<
float(aLVC.m_frameStat) / aLVC.m_frameNum <<
")");
846 return trackingGeometry;