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{};
220 negativeMuonInnerEndcap{}, positiveMuonInnerEndcap{},
221 negNavOEndcap{}, posNavOEndcap{}, negativeMuonOuterEndcap{},
222 positiveMuonOuterEndcap{},
barrel{}, negOuterEndcap{},
223 posOuterEndcap{}, negInnerEndcap{}, posInnerEndcap{}, negNavEndcap{},
229 bool msEntryDefined =
false;
231 msEntryDefined =
true;
235 if (!enclosedDetectorBounds) {
236 ATH_MSG_ERROR(
" dynamic cast of enclosed volume to the cylinder bounds failed, aborting MTG build-up ");
239 double enclosedDetectorHalfZ = enclosedDetectorBounds->halflengthZ();
240 double enclosedDetectorOuterRadius =
241 enclosedDetectorBounds->outerRadius();
247 if (!enclosedCentralFaceVolumes.empty()) {
249 if (cylR && cylR->outerRadius() != enclosedDetectorOuterRadius) {
252 "correspond to radius of glue volumes : adjusted ");
255 if (!enclosedNegativeFaceVolumes.empty() &&
256 !enclosedPositiveFaceVolumes.empty()) {
257 double negZ = -enclosedDetectorHalfZ;
258 double posZ = enclosedDetectorHalfZ;
261 negZ = enclosedNegativeFaceVolumes[0]->center().z() - cylN->halflengthZ();
265 posZ = enclosedPositiveFaceVolumes[0]->center().z() +
268 if (std::abs(negZ + enclosedDetectorHalfZ) > 0.001 ||
269 std::abs(
posZ - enclosedDetectorHalfZ) > 0.001) {
270 ATH_MSG_WARNING(
" enclosed volume envelope z dimension does not correspond to that of glue volumes ");
271 if (std::abs(negZ +
posZ) < 0.001) {
272 enclosedDetectorHalfZ =
posZ;
275 ATH_MSG_ERROR(
"assymetric Z dimensions - cannot recover " << negZ <<
"," <<
posZ);
283 ATH_MSG_DEBUG(
" dimensions of enclosed detectors (halfZ,outerR):"
284 << enclosedDetectorHalfZ <<
","<< enclosedDetectorOuterRadius);
287 if (enclosedDetectorOuterRadius > aLVC.m_innerBarrelRadius) {
289 "muon envelope, abandon :R:"
290 << enclosedDetectorOuterRadius);
293 aLVC.m_innerBarrelRadius = enclosedDetectorOuterRadius;
298 <<
"muon envelope, abandon :Z:"<< enclosedDetectorHalfZ);
302 auto barrelZPBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
303 0.5 * (
m_barrelZ - enclosedDetectorHalfZ));
304 auto barrelZMBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
305 0.5 * (
m_barrelZ - enclosedDetectorHalfZ));
306 double zbShift = 0.5 * (
m_barrelZ + enclosedDetectorHalfZ);
309 barrelZPBounds.release(), aLVC.m_muonMaterial,
nullptr,
310 nullptr,
"BarrelRZPosBuffer");
312 barrelZMBounds.release(), aLVC.m_muonMaterial,
nullptr,
313 nullptr,
"BarrelRZNegBuffer");
318 std::move(barrelZPBuffer),
321 std::string nameEncl = msEntryDefined ?
"All::Gaps::Barrel" :
m_entryVolume;
325 std::move(barrelZMBuffer),
341 <<
" m_enclosingEnvelopeSvc "
345 for (
const auto& envelopeDef : envelopeDefs) {
346 rmax =
std::max(envelopeDef.first, rmax);
349 if (!envelopeDefs.empty()) {
350 if (rmax > 0. && rmax <= aLVC.m_innerBarrelRadius &&
352 enclosedBounds = std::make_unique<Trk::CylinderVolumeBounds>(rmax,
zmax);
355 <<
") clashes with MS material, switch to default values (R,Z:"
356 << aLVC.m_innerBarrelRadius <<
"," <<
m_barrelZ <<
")");
361 if (!enclosedBounds) {
362 enclosedBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
m_barrelZ);
365 enclosed = std::make_unique<Trk::TrackingVolume>(
nullptr, enclosedBounds.release(),
366 aLVC.m_muonMaterial,
nullptr,
375 for (
auto& envelopeDef : envelopeDefs) {
378 if (!aLVC.m_msCutoutsIn.empty() &&
379 aLVC.m_msCutoutsIn.back().second == -aLVC.m_outerEndcapZ)
381 if (aLVC.m_msCutoutsIn.empty() ||
382 std::abs(aLVC.m_msCutoutsIn.back().second) >
m_barrelZ ||
383 std::abs(envelopeDef.second) >
m_barrelZ)
384 aLVC.m_msCutoutsIn.push_back(envelopeDef);
385 else if (!aLVC.m_msCutoutsIn.empty() &&
386 aLVC.m_msCutoutsIn.back().second ==
m_barrelZ &&
387 aLVC.m_msCutoutsIn.back().first != aLVC.m_innerBarrelRadius) {
388 aLVC.m_msCutoutsIn.emplace_back(aLVC.m_innerBarrelRadius,
390 aLVC.m_msCutoutsIn.emplace_back(aLVC.m_innerBarrelRadius,
392 aLVC.m_msCutoutsIn.emplace_back(
393 aLVC.m_msCutoutsIn[aLVC.m_msCutoutsIn.size() - 3].first,
399 while (envelopeDefs[
il - 1].
second != -aLVC.m_outerEndcapZ)
401 for (;
il < envelopeDefs.size();
il++)
402 aLVC.m_msCutoutsOut.push_back(envelopeDefs[
il]);
404 for (
unsigned int i = 0;
i < aLVC.m_msCutoutsIn.size();
i++) {
406 <<
i <<
":" << aLVC.m_msCutoutsIn[
i].first <<
","
407 << aLVC.m_msCutoutsIn[
i].second);
409 for (
unsigned int i = 0;
i < aLVC.m_msCutoutsOut.size();
i++) {
411 <<
i <<
":" << aLVC.m_msCutoutsOut[
i].first <<
","
412 << aLVC.m_msCutoutsOut[
i].second);
415 if (aLVC.m_msCutoutsIn[5].second != aLVC.m_innerEndcapZ) {
416 aLVC.m_innerEndcapZ = aLVC.m_msCutoutsIn[5].second;
424 auto negDiskShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
427 negDiskShieldBounds.release());
428 negDiskShield =
processShield(negDiskVol, 2,
"Muons::Detectors::NegativeDiskShield",
431 auto posDiskShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
434 posDiskShieldBounds.release());
435 posDiskShield =
processShield(posDiskVol, 2,
"Muons::Detectors::PositiveDiskShield",
441 std::move(posDiskShield),
443 "Container::CentralP");
446 std::move(negDiskShield),
448 "Container::Central");
450 if (aLVC.m_adjustStatic) {
456 auto barrelBounds = std::make_unique<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
457 aLVC.m_outerBarrelRadius,
459 Trk::Volume barrelVol(
nullptr, barrelBounds.release());
462 if (aLVC.m_adjustStatic && aLVC.m_static3d)
463 muonBarrel =
processVolume(barrelVol, 0,
"Detectors::Barrel",
465 else if (aLVC.m_adjustStatic)
466 muonBarrel =
processVolume(barrelVol, -1,
"Detectors::Barrel",
470 "Detectors::Barrel", aLVC, hasStations);
475 auto negativeSmallWheelBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_innerShieldRadius,
476 aLVC.m_outerBarrelRadius,
477 smallWheelZHalfSize);
480 negativeSmallWheelBounds.release());
481 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
482 negativeMuonSmallWheel =
processVolume(negSWVol, 1,
"Detectors::NegativeSmallWheel",
484 }
else if (aLVC.m_adjustStatic) {
485 negativeMuonSmallWheel =
processVolume(negSWVol, -1,
"Detectors::NegativeSmallWheel",
491 "Detectors::NegativeSmallWheel",
496 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
497 positiveMuonSmallWheel =
processVolume(posSWVol, 1,
"Detectors::PositiveSmallWheel",
499 }
else if (aLVC.m_adjustStatic) {
500 positiveMuonSmallWheel =
processVolume(posSWVol, -1,
"Detectors::PositiveSmallWheel",
509 double ectZHalfSize = 0.5 * (aLVC.m_innerEndcapZ -
m_ectZ);
512 aLVC.m_outerBarrelRadius,
516 negativeECTBounds.release());
517 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
518 negativeECT =
processVolume(negECTVol, 2,
"Detectors::NegativeECT",
520 }
else if (aLVC.m_adjustStatic) {
521 negativeECT =
processVolume(negECTVol, -1,
"Detectors::NegativeECT",
525 "Detectors::NegativeECT", aLVC, hasStations);
532 positiveECT =
processVolume(posECTVol, 2,
"Detectors::PositiveECT",
534 }
else if (aLVC.m_adjustStatic) {
535 positiveECT =
processVolume(posECTVol, -1,
"Detectors::PositiveECT",
546 std::move(negativeMuonSmallWheel),
548 "Container::NegInnerEndcap"));
549 positiveMuonInnerEndcap = (
m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonSmallWheel),
551 std::move(positiveECT),
553 "Container::PosInnerEndcap"));
556 double innerEndcapZHalfSize = 0.5 * (aLVC.m_innerEndcapZ -
m_diskShieldZ);
557 auto negInnerShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
559 innerEndcapZHalfSize);
561 negInnerShieldBounds.release()};
562 negInnerShield =
processShield(negisVol, 1,
"Muons::Detectors::NegativeInnerShield",
565 auto posInnerShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
567 innerEndcapZHalfSize);
569 posInnerShieldBounds.release());
570 posInnerShield =
processShield(posisVol, 1,
"Muons::Detectors::PositiveInnerShield",
576 double outerWheelZHalfSize = 0.5 * (aLVC.m_outerEndcapZ -
m_outerWheel);
577 auto negativeOuterWheelBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_outerShieldRadius,
578 aLVC.m_outerBarrelRadius,
579 outerWheelZHalfSize);
581 outerWheelZHalfSize)),
582 negativeOuterWheelBounds.release());
583 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
584 negativeMuonOuterWheel =
processVolume(negOWVol, 3,
"Detectors::NegativeOuterWheel",
586 }
else if (aLVC.m_adjustStatic) {
587 negativeMuonOuterWheel =
processVolume(negOWVol, -1,
"Detectors::NegativeOuterWheel",
598 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
599 positiveMuonOuterWheel =
processVolume(posOWVol, 3,
"Detectors::PositiveOuterWheel",
601 }
else if (aLVC.m_adjustStatic) {
602 positiveMuonOuterWheel =
processVolume(posOWVol, -1,
"Detectors::PositiveOuterWheel",
611 auto negativeOuterBufferBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_outerShieldRadius,
612 aLVC.m_outerBarrelRadius,
613 outerBufferZHalfSize);
616 outerBufferZHalfSize)),
617 negativeOuterBufferBounds.release());
618 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
619 negativeMuonOuterBuffer =
processVolume(negBuffVol, 3,
"Detectors::NegativeOuterBuffer",
621 }
else if (aLVC.m_adjustStatic) {
622 negativeMuonOuterBuffer =
processVolume(negBuffVol, -1,
"Detectors::NegativeOuterBuffer",
631 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
632 positiveMuonOuterBuffer =
processVolume(posBuffVol, 3,
"Detectors::PositiveOuterBuffer",
634 }
else if (aLVC.m_adjustStatic) {
635 positiveMuonOuterBuffer =
processVolume(posBuffVol, -1,
"Detectors::PositiveOuterBuffer",
643 double bigWheelZHalfSize = 0.5 * (
m_bigWheel - aLVC.m_innerEndcapZ);
644 auto negativeBigWheelBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_outerShieldRadius,
645 aLVC.m_outerBarrelRadius,
650 negativeBigWheelBounds.release());
651 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
652 negativeMuonBigWheel =
processVolume(negBWVol, 3,
"Detectors::NegativeBigWheel",
654 }
else if (aLVC.m_adjustStatic) {
655 negativeMuonBigWheel =
processVolume(negBWVol, -1,
"Detectors::NegativeBigWheel",
665 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
666 positiveMuonBigWheel =
processVolume(posBWVol, 3,
"Detectors::PositiveBigWheel",
668 }
else if (aLVC.m_adjustStatic) {
669 positiveMuonBigWheel =
processVolume(posBWVol, -1,
"Detectors::PositiveBigWheel",
679 std::move(negativeMuonOuterBuffer),
681 "Container::NegOEndcap");
685 std::move(positiveMuonOuterWheel),
687 "Container::PosOEndcap");
692 std::move(negativeMuonBigWheel),
694 "Container::NegOuterEndcap");
696 positiveMuonOuterEndcap =
m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonBigWheel),
698 std::move(posNavOEndcap),
700 "Container::PosOuterEndcap");
703 double outerEndcapZHalfSize = 0.5 * (aLVC.m_outerEndcapZ - aLVC.m_innerEndcapZ);
704 double outerEndcapPosition = 0.5 * (aLVC.m_outerEndcapZ + aLVC.m_innerEndcapZ);
705 auto negOuterShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
707 outerEndcapZHalfSize);
709 negOuterShieldBounds.release());
710 negOuterShield =
processShield(negosVol, 0,
"Muons::Detectors::NegativeOuterShield",
713 auto posOuterShieldBounds = std::make_unique<Trk::CylinderVolumeBounds>(
716 posOuterShieldBounds.release());
717 posOuterShield =
processShield(pososVol, 0,
"Muons::Detectors::PositiveOuterShield",
721 auto negBeamPipeBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
722 outerEndcapZHalfSize + innerEndcapZHalfSize);
723 auto posBeamPipeBounds = std::make_unique<Trk::CylinderVolumeBounds>(
m_beamPipeRadius,
724 outerEndcapZHalfSize + innerEndcapZHalfSize);
726 negBeamPipeBounds.release());
727 negBeamPipe =
processVolume(negbpVol, 1, 1,
"Muons::Gaps::NegativeBeamPipe",
730 posBeamPipeBounds.release());
731 posBeamPipe =
processVolume(posbpVol, 1, 1,
"Muons::Gaps::PositiveBeamPipe",
734 negBeamPipe->registerColorCode(0);
735 posBeamPipe->registerColorCode(0);
747 "All::Container::Barrel");
752 std::move(negOuterShield),
754 "Container::NegativeOuterEndcap");
758 std::move(posOuterShield),
760 "Container::PositiveOuterEndcap");
766 std::move(negInnerShield),
768 "Container::NegativeInnerEndcap");
772 std::move(posInnerShield),
774 "Container::PositiveInnerEndcap");
780 std::move(negInnerEndcap),
782 "Container::NegativeEndcap");
786 std::move(posOuterEndcap),
788 "Container::PositiveEndcap");
794 std::move(negBeamPipe),
796 "All::Container::NegativeEndcap"));
799 std::move(posBeamPipe),
801 "All::Container::PositiveEndcap"));
811 "All::Container::NegDet");
825 trackingGeometry->addToGarbage(std::move(stations));
826 trackingGeometry->addToGarbage(std::move(inertObjs));
828 volumeGarbage.push_back(std::move(negativeMuonOuterWheel));
829 volumeGarbage.push_back(std::move(negativeMuonBigWheel));
830 volumeGarbage.push_back(std::move(negativeMuonOuterBuffer));
831 volumeGarbage.push_back(std::move(positiveMuonOuterWheel));
833 volumeGarbage.push_back(std::move(negativeMuonSmallWheel));
834 volumeGarbage.push_back(std::move(positiveMuonSmallWheel));
835 volumeGarbage.push_back(std::move(negativeECT));
836 volumeGarbage.push_back(std::move(positiveECT));
837 volumeGarbage.push_back(std::move(positiveMuonBigWheel));
839 volumeGarbage.push_back(std::move(positiveMuonOuterBuffer));
840 volumeGarbage.push_back(std::move(negDiskShield));
841 volumeGarbage.push_back(std::move(posDiskShield));
843 trackingGeometry->addToGarbage(std::move(volumeGarbage));
845 ATH_MSG_DEBUG(
" with " << aLVC.m_frameNum <<
" subvolumes at navigation level");
846 ATH_MSG_DEBUG(
"( mean number of enclosed detached volumes:" <<
float(aLVC.m_frameStat) / aLVC.m_frameNum <<
")");
847 return trackingGeometry;