ATLAS Offline Software
Loading...
Searching...
No Matches
MuonTrackingGeometryBuilderImpl.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// MuonTrackingGeometryBuilderImpl.cxx, (c) ATLAS Detector software
8
9// Muon
12
13
15// Amg
17// Units
18#include "GaudiKernel/SystemOfUnits.h"
19// Trk
41
42// Athena
44
45// STD
46#include <cmath>
47#include <fstream>
48#include <map>
49#include <memory>
50
51namespace Muon {
52
58// constructor
60 const std::string& t, const std::string& n, const IInterface* p)
61 : AthAlgTool(t, n, p) {}
62
63// Athena standard methods
64// initialize
65
67 // Retrieve the tracking volume helper
68 // -------------------------------------------------
71 if (m_loadMSentry) {
72 // retrieve envelope definition service
73 // --------------------------------------------------
75 }
76
77 ATH_MSG_DEBUG( " initialize() successful");
78 return StatusCode::SUCCESS;
79}
80
81std::unique_ptr<Trk::TrackingGeometry>
83 DetachedVolVec && inertObjs,
84 Trk::TrackingVolume* tvol) const {
85 ATH_MSG_DEBUG( " building tracking geometry");
86 bool hasStations = !inertObjs.empty() || !stations.empty();
87
88 // load local variables to container
97 // check setup
99 if (!aLVC.m_adjustStatic || !aLVC.m_static3d) {
100 ATH_MSG_INFO( " diluted inert material hardcoded for 3D "
101 "volume frame, adjusting setup");
102 aLVC.m_adjustStatic = true;
103 aLVC.m_static3d = true;
104 }
105 }
106 // find object's span with tolerance for the alignment
107
108 aLVC.m_stationSpan = findVolumesSpan(stations, 100. * m_alignTolerance,
109 m_alignTolerance * Gaudi::Units::deg, aLVC);
110
111 aLVC.m_inertSpan = findVolumesSpan(inertObjs, 0., 0., aLVC);
112
113 // 0) Preparation
114 // //////////////////////////////////////////////////////////////////////////////////////
115
116 aLVC.m_muonMaterial = Trk::Material(10e10, 10e10, 0., 0., 0.); // default material properties
117
118
119
121 // Envelope definition (cutouts)
123 RZPairVector envelopeDefs;
125 // get the dimensions from the envelope service
126 const RZPairVector& envelopeDefsIn = m_enclosingEnvelopeSvc->getMuonRZBoundary();
127
128 // find the max,max pair
129 unsigned int ii = 0;
130 for (unsigned int i = 0; i < envelopeDefsIn.size(); i++) {
131 if (envelopeDefsIn[i].second > envelopeDefsIn[ii].second)
132 ii = i;
133 else if (envelopeDefsIn[i].second == envelopeDefsIn[ii].second &&
134 envelopeDefsIn[i].first > envelopeDefsIn[ii].first)
135 ii = i;
136 }
137
138 // find the sense of rotation
139 int irot = 1;
140 unsigned int inext = ii + 1;
141 if (inext == envelopeDefsIn.size())
142 inext = 0;
143 if (envelopeDefsIn[inext].second != envelopeDefsIn[ii].second) {
144 irot = -1;
145 inext = ii > 0 ? ii - 1 : envelopeDefsIn.size() - 1;
146 }
147
148 // fill starting with upper low edge, end with upper high edge
149 if (irot > 0) {
150 for (unsigned int i = inext; i < envelopeDefsIn.size(); i++)
151 envelopeDefs.push_back(envelopeDefsIn[i]);
152 if (inext > 0)
153 for (unsigned int i = 0; i <= inext - 1; i++)
154 envelopeDefs.push_back(envelopeDefsIn[i]);
155 } else {
156 int i = inext;
157 while (i >= 0) {
158 envelopeDefs.push_back(envelopeDefsIn[i]);
159 i = i - 1;
160 };
161 inext = envelopeDefsIn.size() - 1;
162 while (inext >= ii) {
163 envelopeDefs.push_back(envelopeDefsIn[inext]);
164 inext = inext - 1;
165 };
166 }
167
168 // find maximal z,R extent
169 double maxR = 0.;
170 for (auto& envelopeDef : envelopeDefs) {
171 if (envelopeDef.first > maxR)
172 maxR = envelopeDef.first;
173 }
174
175 aLVC.m_outerBarrelRadius = maxR;
176 aLVC.m_outerEndcapZ = envelopeDefs[0].second;
177
178 ATH_MSG_VERBOSE("Muon envelope definition retrieved: outer R,Z:"
179 << aLVC.m_outerBarrelRadius << ","
180 << aLVC.m_outerEndcapZ);
181
182 // construct inner and outer envelope
183
184 for (unsigned int i = 0; i < envelopeDefs.size(); i++) {
185 ATH_MSG_VERBOSE("Rz pair:" << i << ":" << envelopeDefs[i].first
186 << "," << envelopeDefs[i].second);
187 }
188 }
189
191
192 if (m_muonSimple) {
193 auto globalBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_outerBarrelRadius, aLVC.m_outerEndcapZ);
194 auto topVolume = std::make_unique<Trk::TrackingVolume>(nullptr, std::move(globalBounds), aLVC.m_muonMaterial,
195 nullptr, nullptr, "GlobalVolume");
196 return std::make_unique<Trk::TrackingGeometry>(topVolume.release());
197 }
198
199 ATH_MSG_DEBUG( "building barrel+innerEndcap+outerEndcap");
200
202 // MuonSpectrometer contains:
203 // - Barrel
204 // - Endcaps inner/outer
205 std::vector<TrackingVolumePtr> volumeGarbage{};
206
207 TrackingVolumePtr muonBarrel{}, negativeMuonOuterWheel{},
208 negativeMuonBigWheel{}, negativeMuonOuterBuffer{},
209 positiveMuonOuterWheel{}, negativeMuonSmallWheel{},
210 positiveMuonSmallWheel{}, negativeECT{}, positiveECT{},
211 positiveMuonBigWheel{}, positiveMuonOuterBuffer{};
212 // volumes needed to close the geometry
213 TrackingVolumePtr negBeamPipe{}, posBeamPipe{}, negDiskShield{}, posDiskShield{},
214 negInnerShield{}, posInnerShield{}, negOuterShield{}, posOuterShield{};
215
216 std::shared_ptr<Trk::CylinderVolumeBounds> enclosedBounds{};
217
218 TrackingVolumePtr barrelZPBuffer{}, barrelZMBuffer{};
219 TrackingVolumePtr barrelZP{}, centralP{}, central{},
220 negativeMuonInnerEndcap{}, positiveMuonInnerEndcap{},
221 negNavOEndcap{}, posNavOEndcap{}, negativeMuonOuterEndcap{},
222 positiveMuonOuterEndcap{}, barrel{}, negOuterEndcap{},
223 posOuterEndcap{}, negInnerEndcap{}, posInnerEndcap{}, negNavEndcap{},
224 posNavEndcap{}, negEndcap{}, posEndcap{}, negDet{}, detector{}, enclosed{};
225
226
227 // if input, redefine dimensions to fit expected MS entry
228 if (tvol) {
229 bool msEntryDefined = false;
230 if (tvol->volumeName() == m_entryVolume)
231 msEntryDefined = true;
232 // get dimensions
233 ATH_MSG_DEBUG(" msEntryDefined " << msEntryDefined);
234 const auto *enclosedDetectorBounds =dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tvol->volumeBounds()));
235 if (!enclosedDetectorBounds) {
236 ATH_MSG_ERROR(" dynamic cast of enclosed volume to the cylinder bounds failed, aborting MTG build-up ");
237 return nullptr;
238 }
239 double enclosedDetectorHalfZ = enclosedDetectorBounds->halflengthZ();
240 double enclosedDetectorOuterRadius =
241 enclosedDetectorBounds->outerRadius();
242 // get subvolumes at navigation level and check THEIR dimensions
243 Trk::GlueVolumesDescriptor& enclosedDetGlueVolumes = tvol->glueVolumesDescriptor();
244 std::vector<Trk::TrackingVolume*> enclosedCentralFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::cylinderCover);
245 std::vector<Trk::TrackingVolume*> enclosedNegativeFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::negativeFaceXY);
246 std::vector<Trk::TrackingVolume*> enclosedPositiveFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::positiveFaceXY);
247 if (!enclosedCentralFaceVolumes.empty()) {
248 const auto *cylR = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(enclosedCentralFaceVolumes[0]->volumeBounds()));
249 if (cylR && cylR->outerRadius() != enclosedDetectorOuterRadius) {
250 enclosedDetectorOuterRadius = cylR->outerRadius();
251 ATH_MSG_WARNING(" enclosed volume envelope outer radius does not "
252 "correspond to radius of glue volumes : adjusted ");
253 }
254 }
255 if (!enclosedNegativeFaceVolumes.empty() &&
256 !enclosedPositiveFaceVolumes.empty()) {
257 double negZ = -enclosedDetectorHalfZ;
258 double posZ = enclosedDetectorHalfZ;
259 const auto *cylN = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(enclosedNegativeFaceVolumes[0]->volumeBounds()));
260 if (cylN){
261 negZ = enclosedNegativeFaceVolumes[0]->center().z() - cylN->halflengthZ();
262 }
263 const auto *cylP =dynamic_cast<const Trk::CylinderVolumeBounds*>(&(enclosedPositiveFaceVolumes[0]->volumeBounds()));
264 if (cylP) {
265 posZ = enclosedPositiveFaceVolumes[0]->center().z() +
266 cylP->halflengthZ();
267 }
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;
273 ATH_MSG_WARNING( " z adjusted ");
274 } else {
275 ATH_MSG_ERROR("assymetric Z dimensions - cannot recover " << negZ << "," << posZ);
276 return nullptr;
277 }
278 }
279 }
280 //
281
282 //
283 ATH_MSG_DEBUG(" dimensions of enclosed detectors (halfZ,outerR):"
284 << enclosedDetectorHalfZ << ","<< enclosedDetectorOuterRadius);
285 // check if input makes sense - gives warning if cuts into muon envelope
286 // adjust radius
287 if (enclosedDetectorOuterRadius > aLVC.m_innerBarrelRadius) {
288 ATH_MSG_WARNING( " enclosed volume too wide, cuts into "
289 "muon envelope, abandon :R:"
290 << enclosedDetectorOuterRadius);
291 return nullptr;
292 }
293 aLVC.m_innerBarrelRadius = enclosedDetectorOuterRadius;
294
295 // adjust z
296 if (enclosedDetectorHalfZ > m_barrelZ) {
297 ATH_MSG_WARNING( " enclosed volume too long, cuts into "
298 <<"muon envelope, abandon :Z:"<< enclosedDetectorHalfZ);
299 return nullptr;
300 } else {
301 if (enclosedDetectorHalfZ < m_barrelZ) {
302 auto barrelZPBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
303 0.5 * (m_barrelZ - enclosedDetectorHalfZ));
304 auto barrelZMBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
305 0.5 * (m_barrelZ - enclosedDetectorHalfZ));
306 double zbShift = 0.5 * (m_barrelZ + enclosedDetectorHalfZ);
307
308 barrelZPBuffer = std::make_unique<Trk::TrackingVolume>(makeTransform(Amg::getTranslateZ3D(zbShift)),
309 std::move(barrelZPBounds), aLVC.m_muonMaterial, nullptr,
310 nullptr, "BarrelRZPosBuffer");
311 barrelZMBuffer = std::make_unique<Trk::TrackingVolume>(makeTransform(Amg::getTranslateZ3D(-zbShift)),
312 std::move(barrelZMBounds), aLVC.m_muonMaterial, nullptr,
313 nullptr, "BarrelRZNegBuffer");
314
315 ATH_MSG_DEBUG( "glue barrel R + barrel Z buffer");
316 barrelZP = (m_trackingVolumeHelper->glueTrackingVolumeArrays(TrackingVolumePtr(tvol),
318 std::move(barrelZPBuffer),
319 Trk::negativeFaceXY, "All::Gaps::BarrelZP"));
320 // set name
321 std::string nameEncl = msEntryDefined ? "All::Gaps::Barrel" : m_entryVolume.value();
322 ATH_MSG_DEBUG(" nameEncl " << nameEncl);
323 enclosed = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(barrelZP),
325 std::move(barrelZMBuffer),
327 nameEncl);
328
329 } else{
331 enclosed.reset(tvol);
332 }
333 }
334
335 } else { // no input, create the enclosed volume
337 const RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZBoundary();
338 // to be implemented in detail - for the moment, take just maximal
339 // extent
340 ATH_MSG_DEBUG(" m_loadMSentry " << m_loadMSentry
341 << " m_enclosingEnvelopeSvc "
343 double rmax = 0.;
344 double zmax = 0.;
345 for (const auto& envelopeDef : envelopeDefs) {
346 rmax = std::max(envelopeDef.first, rmax);
347 zmax = std::max(std::abs(envelopeDef.second), zmax);
348 }
349 if (!envelopeDefs.empty()) {
350 if (rmax > 0. && rmax <= aLVC.m_innerBarrelRadius &&
351 zmax > 0. && zmax <= m_barrelZ) {
352 enclosedBounds = std::make_unique<Trk::CylinderVolumeBounds>(rmax, zmax);
353 } else {
354 ATH_MSG_DEBUG( " input MSEntrance size (R,Z:"<< rmax << "," << zmax
355 << ") clashes with MS material, switch to default values (R,Z:"
356 << aLVC.m_innerBarrelRadius << "," << m_barrelZ << ")");
357 }
358 }
359 }
360
361 if (!enclosedBounds) {
362 enclosedBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius, m_barrelZ);
363 }
364 {
365 enclosed = std::make_unique<Trk::TrackingVolume>(nullptr, std::move(enclosedBounds),
366 aLVC.m_muonMaterial, nullptr,
367 nullptr, m_entryVolume);
368 enclosed->registerColorCode(0);
369 }
370 ATH_MSG_DEBUG(" register Barrel m_entryVolume " << m_entryVolume);
371 }
372
373 // construct inner and outer envelope
374
375 for (auto& envelopeDef : envelopeDefs) {
376 // ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<<
377 // envelopeDefs[i].first<<","<<envelopeDefs[i].second );
378 if (!aLVC.m_msCutoutsIn.empty() &&
379 aLVC.m_msCutoutsIn.back().second == -aLVC.m_outerEndcapZ)
380 break;
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,
389 m_barrelZ);
390 aLVC.m_msCutoutsIn.emplace_back(aLVC.m_innerBarrelRadius,
391 -m_barrelZ);
392 aLVC.m_msCutoutsIn.emplace_back(
393 aLVC.m_msCutoutsIn[aLVC.m_msCutoutsIn.size() - 3].first,
394 -m_barrelZ);
395 }
396 }
397
398 unsigned int il = 1;
399 while (envelopeDefs[il - 1].second != -aLVC.m_outerEndcapZ)
400 il++;
401 for (; il < envelopeDefs.size(); il++)
402 aLVC.m_msCutoutsOut.push_back(envelopeDefs[il]);
403
404 for (unsigned int i = 0; i < aLVC.m_msCutoutsIn.size(); i++) {
405 ATH_MSG_VERBOSE("Rz pair for inner MS envelope:"
406 << i << ":" << aLVC.m_msCutoutsIn[i].first << ","
407 << aLVC.m_msCutoutsIn[i].second);
408 }
409 for (unsigned int i = 0; i < aLVC.m_msCutoutsOut.size(); i++) {
410 ATH_MSG_VERBOSE("Rz pair for outer MS envelope:"
411 << i << ":" << aLVC.m_msCutoutsOut[i].first << ","
412 << aLVC.m_msCutoutsOut[i].second);
413 }
414
415 if (aLVC.m_msCutoutsIn[5].second != aLVC.m_innerEndcapZ) {
416 aLVC.m_innerEndcapZ = aLVC.m_msCutoutsIn[5].second;
417 }
418 ATH_MSG_VERBOSE("inner endcap Z set to:" << aLVC.m_innerEndcapZ);
419
420 // create central volume ("enclosed" + disk shields ) - this is to allow
421 // safe gluing with 3D MS binning
422 getShieldParts(aLVC);
423
424 auto negDiskShieldBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
425 0.5 * (m_diskShieldZ - m_barrelZ));
427 std::move(negDiskShieldBounds));
428 negDiskShield = processShield(negDiskVol, 2, "Muons::Detectors::NegativeDiskShield",
429 aLVC, hasStations);
430
431 auto posDiskShieldBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
432 0.5 * (m_diskShieldZ - m_barrelZ));
434 std::move(posDiskShieldBounds));
435 posDiskShield = processShield(posDiskVol, 2, "Muons::Detectors::PositiveDiskShield",
436 aLVC, hasStations);
437
438 ATH_MSG_DEBUG( "glue enclosed + disk shields");
439 centralP = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(enclosed),
441 std::move(posDiskShield),
443 "Container::CentralP");
444 central = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(centralP),
446 std::move(negDiskShield),
448 "Container::Central");
449 // define basic volumes
450 if (aLVC.m_adjustStatic) {
451 getZParts(aLVC);
452 getHParts(aLVC);
453 }
454
455 // muon barrel
456 auto barrelBounds = std::make_shared<Trk::CylinderVolumeBounds>(aLVC.m_innerBarrelRadius,
459 Trk::Volume barrelVol(nullptr, std::move(barrelBounds));
460 // process volume
461 // barrel
462 if (aLVC.m_adjustStatic && aLVC.m_static3d)
463 muonBarrel = processVolume(barrelVol, 0, "Detectors::Barrel",
464 aLVC, hasStations);
465 else if (aLVC.m_adjustStatic)
466 muonBarrel = processVolume(barrelVol, -1, "Detectors::Barrel",
467 aLVC, hasStations);
468 else
469 muonBarrel = processVolume(barrelVol, m_barrelEtaPartition, m_phiPartition,
470 "Detectors::Barrel", aLVC, hasStations);
471 // inner Endcap
472 // build as smallWheel+ECT
473 // small wheel
474 double smallWheelZHalfSize = 0.5 * (m_ectZ - m_diskShieldZ);
475 auto negativeSmallWheelBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_innerShieldRadius,
477 smallWheelZHalfSize);
478
479 Trk::Volume negSWVol(makeTransform(Amg::getTranslateZ3D(-m_ectZ + smallWheelZHalfSize)),
480 std::move(negativeSmallWheelBounds));
481 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
482 negativeMuonSmallWheel = processVolume(negSWVol, 1, "Detectors::NegativeSmallWheel",
483 aLVC, hasStations);
484 } else if (aLVC.m_adjustStatic) {
485 negativeMuonSmallWheel = processVolume(negSWVol, -1, "Detectors::NegativeSmallWheel",
486 aLVC, hasStations);
487 } else {
488 negativeMuonSmallWheel = processVolume(negSWVol,
491 "Detectors::NegativeSmallWheel",
492 aLVC, hasStations);
493 }
494 //
495 Trk::Volume posSWVol(negSWVol, Amg::getTranslateZ3D(2 * (m_ectZ - smallWheelZHalfSize)));
496 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
497 positiveMuonSmallWheel = processVolume(posSWVol, 1, "Detectors::PositiveSmallWheel",
498 aLVC, hasStations);
499 } else if (aLVC.m_adjustStatic) {
500 positiveMuonSmallWheel = processVolume(posSWVol, -1, "Detectors::PositiveSmallWheel",
501 aLVC, hasStations);
502 } else {
503 positiveMuonSmallWheel = processVolume(posSWVol, m_innerEndcapEtaPartition,
504 m_phiPartition, "Detectors::PositiveSmallWheel",
505 aLVC, hasStations);
506 }
507 // checkVolume(positiveMuonSmallWheel);
508 // ECT
509 double ectZHalfSize = 0.5 * (aLVC.m_innerEndcapZ - m_ectZ);
510
511 auto negativeECTBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_innerShieldRadius,
513 ectZHalfSize);
514
515 Trk::Volume negECTVol(makeTransform(Amg::getTranslateZ3D(-m_ectZ - ectZHalfSize)),
516 std::move(negativeECTBounds));
517 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
518 negativeECT = processVolume(negECTVol, 2, "Detectors::NegativeECT",
519 aLVC, hasStations);
520 } else if (aLVC.m_adjustStatic) {
521 negativeECT = processVolume(negECTVol, -1, "Detectors::NegativeECT",
522 aLVC, hasStations);
523 } else {
525 "Detectors::NegativeECT", aLVC, hasStations);
526 }
527 // checkVolume(negativeECT);
528 //
529 Trk::Volume posECTVol(negECTVol,
530 Amg::getTranslateZ3D(2 * (m_ectZ + ectZHalfSize)));
531 if (aLVC.m_adjustStatic && m_static3d) {
532 positiveECT = processVolume(posECTVol, 2, "Detectors::PositiveECT",
533 aLVC, hasStations);
534 } else if (aLVC.m_adjustStatic) {
535 positiveECT = processVolume(posECTVol, -1, "Detectors::PositiveECT",
536 aLVC, hasStations);
537 } else {
538 positiveECT = processVolume(posECTVol, m_innerEndcapEtaPartition,
539 m_phiPartition, "Detectors::PositiveECT",
540 aLVC, hasStations);
541 }
542 // checkVolume(positiveECT);
543 // glue
544 negativeMuonInnerEndcap = (m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negativeECT),
546 std::move(negativeMuonSmallWheel),
548 "Container::NegInnerEndcap"));
549 positiveMuonInnerEndcap = (m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonSmallWheel),
551 std::move(positiveECT),
553 "Container::PosInnerEndcap"));
554
555 // inner shields
556 double innerEndcapZHalfSize = 0.5 * (aLVC.m_innerEndcapZ - m_diskShieldZ);
557 auto negInnerShieldBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_beamPipeRadius,
559 innerEndcapZHalfSize);
560 Trk::Volume negisVol{makeTransform(Amg::getTranslateZ3D(-m_diskShieldZ - innerEndcapZHalfSize)),
561 std::move(negInnerShieldBounds)};
562 negInnerShield = processShield(negisVol, 1, "Muons::Detectors::NegativeInnerShield",
563 aLVC, hasStations);
564
565 auto posInnerShieldBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_beamPipeRadius,
567 innerEndcapZHalfSize);
568 Trk::Volume posisVol(makeTransform(Amg::getTranslateZ3D(m_diskShieldZ + innerEndcapZHalfSize)),
569 std::move(posInnerShieldBounds));
570 posInnerShield = processShield(posisVol, 1, "Muons::Detectors::PositiveInnerShield",
571 aLVC, hasStations);
572
573 // outer Endcap
574 // build as bigWheel+buffer+outerWheel
575 // outer wheel
576 double outerWheelZHalfSize = 0.5 * (aLVC.m_outerEndcapZ - m_outerWheel);
577 auto negativeOuterWheelBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_outerShieldRadius,
579 outerWheelZHalfSize);
581 outerWheelZHalfSize)),
582 std::move(negativeOuterWheelBounds));
583 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
584 negativeMuonOuterWheel = processVolume(negOWVol, 3, "Detectors::NegativeOuterWheel",
585 aLVC, hasStations);
586 } else if (aLVC.m_adjustStatic) {
587 negativeMuonOuterWheel = processVolume(negOWVol, -1, "Detectors::NegativeOuterWheel",
588 aLVC, hasStations);
589 } else {
590 negativeMuonOuterWheel = processVolume(negOWVol, m_outerEndcapEtaPartition,
591 m_phiPartition, "Detectors::NegativeOuterWheel",
592 aLVC, hasStations);
593 }
594 //
595 Trk::Volume posOWVol(negOWVol,
596 Amg::getTranslateZ3D(2 * (aLVC.m_outerEndcapZ - outerWheelZHalfSize)));
597
598 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
599 positiveMuonOuterWheel = processVolume(posOWVol, 3, "Detectors::PositiveOuterWheel",
600 aLVC, hasStations);
601 } else if (aLVC.m_adjustStatic) {
602 positiveMuonOuterWheel = processVolume(posOWVol, -1, "Detectors::PositiveOuterWheel",
603 aLVC, hasStations);
604 } else {
605 positiveMuonOuterWheel = processVolume(posOWVol, m_outerEndcapEtaPartition,
606 m_phiPartition, "Detectors::PositiveOuterWheel",
607 aLVC, hasStations);
608 }
609 // outer buffer
610 double outerBufferZHalfSize = 0.5 * (m_outerWheel - m_bigWheel);
611 auto negativeOuterBufferBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_outerShieldRadius,
613 outerBufferZHalfSize);
614
616 outerBufferZHalfSize)),
617 std::move(negativeOuterBufferBounds));
618 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
619 negativeMuonOuterBuffer = processVolume(negBuffVol, 3, "Detectors::NegativeOuterBuffer",
620 aLVC, hasStations);
621 } else if (aLVC.m_adjustStatic) {
622 negativeMuonOuterBuffer = processVolume(negBuffVol, -1, "Detectors::NegativeOuterBuffer",
623 aLVC, hasStations);
624 } else {
625 negativeMuonOuterBuffer = processVolume(negBuffVol, m_outerEndcapEtaPartition,
626 m_phiPartition, "Detectors::NegativeOuterBuffer",
627 aLVC, hasStations);
628 }
629 //
630 Trk::Volume posBuffVol(negBuffVol, Amg::getTranslateZ3D(2 *(m_bigWheel + outerBufferZHalfSize)));
631 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
632 positiveMuonOuterBuffer = processVolume(posBuffVol, 3, "Detectors::PositiveOuterBuffer",
633 aLVC, hasStations);
634 } else if (aLVC.m_adjustStatic) {
635 positiveMuonOuterBuffer = processVolume(posBuffVol, -1, "Detectors::PositiveOuterBuffer",
636 aLVC, hasStations);
637 } else {
638 positiveMuonOuterBuffer = processVolume(posBuffVol, m_outerEndcapEtaPartition,
639 m_phiPartition, "Detectors::PositiveOuterBuffer",
640 aLVC, hasStations);
641 }
642 // big wheel
643 double bigWheelZHalfSize = 0.5 * (m_bigWheel - aLVC.m_innerEndcapZ);
644 auto negativeBigWheelBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_outerShieldRadius,
646 bigWheelZHalfSize);
647
649 bigWheelZHalfSize)),
650 std::move(negativeBigWheelBounds));
651 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
652 negativeMuonBigWheel = processVolume(negBWVol, 3, "Detectors::NegativeBigWheel",
653 aLVC, hasStations);
654 } else if (aLVC.m_adjustStatic) {
655 negativeMuonBigWheel = processVolume(negBWVol, -1, "Detectors::NegativeBigWheel",
656 aLVC, hasStations);
657 } else {
658 negativeMuonBigWheel = processVolume(negBWVol, m_outerEndcapEtaPartition,
659 m_phiPartition, "Detectors::NegativeBigWheel",
660 aLVC, hasStations);
661 }
662 //
663 Trk::Volume posBWVol(negBWVol,
664 Amg::getTranslateZ3D(2 * (aLVC.m_innerEndcapZ + bigWheelZHalfSize)));
665 if (aLVC.m_adjustStatic && aLVC.m_static3d) {
666 positiveMuonBigWheel = processVolume(posBWVol, 3, "Detectors::PositiveBigWheel",
667 aLVC, hasStations);
668 } else if (aLVC.m_adjustStatic) {
669 positiveMuonBigWheel = processVolume(posBWVol, -1, "Detectors::PositiveBigWheel",
670 aLVC, hasStations);
671 } else {
672 positiveMuonBigWheel = processVolume(posBWVol, m_outerEndcapEtaPartition,
673 m_phiPartition, "Detectors::PositiveBigWheel",
674 aLVC, hasStations);
675 }
676 // glue
677 negNavOEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negativeMuonOuterWheel),
679 std::move(negativeMuonOuterBuffer),
681 "Container::NegOEndcap");
682
683 posNavOEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonOuterBuffer),
685 std::move(positiveMuonOuterWheel),
687 "Container::PosOEndcap");
688
689
690 negativeMuonOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negNavOEndcap),
692 std::move(negativeMuonBigWheel),
694 "Container::NegOuterEndcap");
695
696 positiveMuonOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonBigWheel),
698 std::move(posNavOEndcap),
700 "Container::PosOuterEndcap");
701
702 // outer shields
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_shared<Trk::CylinderVolumeBounds>(m_beamPipeRadius,
707 outerEndcapZHalfSize);
708 Trk::Volume negosVol(makeTransform(Amg::getTranslateZ3D(-outerEndcapPosition)),
709 std::move(negOuterShieldBounds));
710 negOuterShield = processShield(negosVol, 0, "Muons::Detectors::NegativeOuterShield",
711 aLVC, hasStations);
712
713 auto posOuterShieldBounds = std::make_shared<Trk::CylinderVolumeBounds>(
714 m_beamPipeRadius, m_outerShieldRadius, outerEndcapZHalfSize);
715 Trk::Volume pososVol(makeTransform(Amg::getTranslateZ3D(outerEndcapPosition)),
716 std::move(posOuterShieldBounds));
717 posOuterShield = processShield(pososVol, 0, "Muons::Detectors::PositiveOuterShield",
718 aLVC, hasStations);
719
720 // beamPipe
721 auto negBeamPipeBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_beamPipeRadius,
722 outerEndcapZHalfSize + innerEndcapZHalfSize);
723 auto posBeamPipeBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_beamPipeRadius,
724 outerEndcapZHalfSize + innerEndcapZHalfSize);
725 Trk::Volume negbpVol(makeTransform(Amg::getTranslateZ3D(-aLVC.m_outerEndcapZ + innerEndcapZHalfSize + outerEndcapZHalfSize)),
726 std::move(negBeamPipeBounds));
727 negBeamPipe = processVolume(negbpVol, 1, 1, "Muons::Gaps::NegativeBeamPipe",
728 aLVC, hasStations);
729 Trk::Volume posbpVol(makeTransform(Amg::getTranslateZ3D(aLVC.m_outerEndcapZ - innerEndcapZHalfSize - outerEndcapZHalfSize)),
730 std::move(posBeamPipeBounds));
731 posBeamPipe = processVolume(posbpVol, 1, 1, "Muons::Gaps::PositiveBeamPipe",
732 aLVC, hasStations);
733
734 negBeamPipe->registerColorCode(0);
735 posBeamPipe->registerColorCode(0);
736
737 ATH_MSG_DEBUG( " volumes defined ");
738 //
739 // glue volumes at navigation level, create enveloping volume
740 // radially
741 // central + barrel
742 ATH_MSG_DEBUG( "glue barrel+enclosed volumes");
743 barrel = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(muonBarrel),
745 std::move(central),
747 "All::Container::Barrel");
748 // shield+outerEndcap
749 ATH_MSG_DEBUG( "glue shield+outerEndcap");
750 negOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negativeMuonOuterEndcap),
752 std::move(negOuterShield),
754 "Container::NegativeOuterEndcap");
755
756 posOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonOuterEndcap),
758 std::move(posOuterShield),
760 "Container::PositiveOuterEndcap");
761
762 // shield+innerEndcap
763 ATH_MSG_DEBUG( "glue shield+innerEndcap");
764 negInnerEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negativeMuonInnerEndcap),
766 std::move(negInnerShield),
768 "Container::NegativeInnerEndcap");
769 // checkVolume(negInnerEndcap);
770 posInnerEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(positiveMuonInnerEndcap),
772 std::move(posInnerShield),
774 "Container::PositiveInnerEndcap");
775 // checkVolume(posInnerEndcap);
776 // inner+outerEndcap
777 ATH_MSG_DEBUG( "glue inner+outerEndcap");
778 negNavEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negOuterEndcap),
780 std::move(negInnerEndcap),
782 "Container::NegativeEndcap");
783
784 posNavEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(posInnerEndcap),
786 std::move(posOuterEndcap),
788 "Container::PositiveEndcap");
789
790 // beam pipe + endcaps
791 ATH_MSG_DEBUG( "glue beamPipe+endcaps");
792 negEndcap = (m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negNavEndcap),
794 std::move(negBeamPipe),
796 "All::Container::NegativeEndcap"));
797 posEndcap = (m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(posNavEndcap),
799 std::move(posBeamPipe),
801 "All::Container::PositiveEndcap"));
802 // checkVolume(negEndcap);
803 // checkVolume(posEndcap);
804 // barrel + endcaps
805 ATH_MSG_DEBUG( "glue barrel+endcaps");
806
807 negDet = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(negEndcap),
809 std::move(barrel),
811 "All::Container::NegDet");
812 detector = m_trackingVolumeHelper->glueTrackingVolumeArrays(std::move(posEndcap),
814 std::move(negDet),
817 // blend material
819 blendMaterial(aLVC);
820
821 // tracking geometry
822 auto trackingGeometry = std::make_unique<Trk::TrackingGeometry>(detector.release(), Trk::globalSearch);
823
824
825 trackingGeometry->addToGarbage(std::move(stations));
826 trackingGeometry->addToGarbage(std::move(inertObjs));
827
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));
832
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));
838
839 volumeGarbage.push_back(std::move(positiveMuonOuterBuffer));
840 volumeGarbage.push_back(std::move(negDiskShield));
841 volumeGarbage.push_back(std::move(posDiskShield));
842
843 trackingGeometry->addToGarbage(std::move(volumeGarbage));
844 ATH_MSG_DEBUG( " returning tracking geometry ");
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;
848}
849
852 double zTol,
853 double phiTol,
854 const LocalVariablesContainer& aLVC) const {
855 VolumeSpanArray spans{};
856
857 if (objs.empty()) {
858 return spans;
859 }
860
861 for (const auto& obj : objs) {
862 VolumeSpanPtr span{m_volumeConverter.findVolumeSpan(obj->trackingVolume()->volumeBounds(),
863 obj->trackingVolume()->transform(), zTol, phiTol)};
864 double x0 = obj->trackingVolume()->X0;
865 double intX0 = std::abs(span->zMin - span->zMax) / (x0 + 0.000000001);
866 double l0 = obj->trackingVolume()->L0;
867 ATH_MSG_DEBUG("span:" << obj->name() << "," << span->zMin << ","
868 << span->zMax << "," << span->phiMin << ","
869 << span->phiMax << "," << span->rMin << ","
870 << span->rMax << " X0 " << x0 << " L0 " << l0
871 << " intX0 for span0 span1 " << intX0);
872
873 int nspans = 0;
874 // negative outer wheel
875 if (span->zMin < -m_bigWheel) {
876 spans[0].emplace_back(obj.get(), span);
877 nspans++;
878 }
879 // negative big wheel
880 if (span->zMin < -aLVC.m_innerEndcapZ && span->zMax > -m_bigWheel) {
881 spans[1].emplace_back(obj.get(), span);
882 nspans++;
883 }
884 // neg.ect
885 if (span->zMin < -m_ectZ && span->zMax > -aLVC.m_innerEndcapZ) {
886 spans[2].emplace_back(obj.get(), span);
887 nspans++;
888 }
889 // neg.small wheel
890 if (span->zMin < -m_diskShieldZ && span->zMax > -m_ectZ) {
891 spans[3].emplace_back(obj.get(), span);
892 nspans++;
893 }
894 // barrel
895 if (span->zMin < m_diskShieldZ && span->zMax > -m_diskShieldZ) {
896 spans[4].emplace_back(obj.get(), span);
897 nspans++;
898 }
899 // pos.small wheel
900 if (span->zMin < m_ectZ && span->zMax > m_diskShieldZ) {
901 spans[5].emplace_back(obj.get(), span);
902 nspans++;
903 }
904 // pos.ect
905 if (span->zMin < aLVC.m_innerEndcapZ && span->zMax > m_ectZ) {
906 spans[6].emplace_back(obj.get(), span);
907 nspans++;
908 }
909 // positive big wheel
910 if (span->zMin < m_bigWheel && span->zMax > aLVC.m_innerEndcapZ) {
911 spans[7].emplace_back(obj.get(), span);
912 nspans++;
913 }
914 // positive outer wheel
915 if (span->zMax > m_bigWheel) {
916 spans[8].emplace_back(obj.get(), span);
917 nspans++;
918 }
919
920 if (nspans == 0)
921 ATH_MSG_WARNING(" object not selected in span regions "
922 << obj->name());
923 if (nspans > 1)
924 ATH_MSG_VERBOSE(" object selected in " << nspans << " span regions "
925 << obj->name());
926 }
927
928 return spans;
929}
930
932 int etaN, int phiN,
933 const std::string& volumeName,
935 bool hasStations) const {
936 TrackingVolumePtr tVol{};
937
938 unsigned int colorCode = m_colorCode;
939
940 std::vector<Trk::DetachedTrackingVolume*> blendVols;
941
942 // partitions ? include protection against wrong setup
943 if (etaN < 1 || phiN < 1) {
944 ATH_MSG_ERROR( "wrong partition setup");
945 etaN = 1;
946 phiN = 1;
947 }
948 if (etaN * phiN > 1) { // partition
949 const auto *cyl = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(vol.volumeBounds()));
950 if (!cyl) {
951 ATH_MSG_ERROR(" process volume: volume cylinder boundaries not retrieved, return 0 ");
952 return nullptr;
953 }
954 double phiSect = M_PI / phiN;
955 double etaSect = (cyl->halflengthZ()) / etaN;
956
957 auto subBds = std::make_shared<Trk::CylinderVolumeBounds>(cyl->innerRadius(), cyl->outerRadius(), phiSect, etaSect);
958 auto protVol = std::make_unique<Trk::Volume>(nullptr, std::move(subBds));
959
960 // create subvolumes & BinnedArray
961 std::vector<Trk::TrackingVolumeOrderPosition> subVolumes;
962 std::vector<Trk::TrackingVolume*> sVols; // for gluing
963 std::vector<Trk::TrackingVolume*> sVolsNeg; // for gluing
964 std::vector<Trk::TrackingVolume*> sVolsPos; // for gluing
965 for (int eta = 0; eta < etaN; eta++) {
966 if (colorCode > 0)
967 colorCode = 26 - colorCode;
968 // reference point for the check of envelope
969 double posZ = vol.center().z() + etaSect * (2. * eta + 1. - etaN);
970 double posR = 0.5 * (cyl->innerRadius() + cyl->outerRadius());
971 int geoSignature = 4;
972 // loop over inner cutouts
973 for (unsigned int in = 1; in < aLVC.m_msCutoutsIn.size(); in++) {
974 if (posZ >= aLVC.m_msCutoutsIn[in].second &&
975 posZ <= aLVC.m_msCutoutsIn[in - 1].second) {
976 if (posR < aLVC.m_msCutoutsIn[in].first)
977 geoSignature = 2;
978 break;
979 }
980 }
981 if (geoSignature == 4) {
982 // loop over outer cutouts
983 for (unsigned int io = 1; io < aLVC.m_msCutoutsOut.size();
984 io++) {
985 if (posZ >= aLVC.m_msCutoutsOut[io - 1].second &&
986 posZ <= aLVC.m_msCutoutsOut[io].second) {
987 if (posR > aLVC.m_msCutoutsOut[io].first)
988 geoSignature = 5;
989 break;
990 }
991 }
992 }
993 for (int phi = 0; phi < phiN; phi++) {
994 if (colorCode > 0)
995 colorCode = 26 - colorCode;
996 // define subvolume
997 const Amg::Transform3D transf = Amg::getRotateZ3D(phiSect * (2 * phi + 1)) *
999 auto subVol = std::make_unique<Trk::Volume>(*protVol, transf);
1000 // enclosed muon objects ?
1001 std::string volName = volumeName + MuonGM::buildString(eta, 2) +
1003 blendVols.clear();
1004 std::vector<Trk::DetachedTrackingVolume*> detVols{};
1005 if (hasStations) {
1006 detVols = getDetachedObjects(*subVol, blendVols, aLVC);
1007 }
1008 auto detVolVecPtr = std::make_unique<std::vector<Trk::DetachedTrackingVolume*>>(detVols);
1009 auto sVol = std::make_unique<Trk::TrackingVolume>(*subVol, aLVC.m_muonMaterial,
1010 std::move(detVolVecPtr), volName);
1011 // statistics
1012 ++aLVC.m_frameNum;
1013 aLVC.m_frameStat += detVols.size();
1014 // prepare blending
1015 if (m_blendInertMaterial && !blendVols.empty()) {
1016 for (auto& blendVol : blendVols) {
1017 aLVC.m_blendMap[blendVol].push_back(sVol.get());
1018 }
1019 }
1020 //
1021 if (geoSignature == 2) {
1022 sVol->sign(Trk::BeamPipe);
1023 }
1024 if (geoSignature == 5) {
1025 sVol->sign(Trk::Cavern);
1026 }
1027 sVol->registerColorCode(colorCode);
1028 // reference position
1029 const Amg::Vector3D gp = cyl->outerRadius() *
1030 Amg::Vector3D::UnitX();;
1031 // glue subVolumes
1032 sVols.push_back(sVol.get());
1033 if (eta == 0)
1034 sVolsNeg.push_back(sVol.get());
1035 if (eta == etaN - 1)
1036 sVolsPos.push_back(sVol.get());
1037 // in phi
1038 if (phiN > 1 && phi > 0) {
1039 m_trackingVolumeHelper->glueTrackingVolumes(*sVol,
1041 *sVols[eta * phiN + phi - 1],
1043 if (phi == phiN - 1)
1044 m_trackingVolumeHelper->glueTrackingVolumes(*sVols[eta * phiN],
1046 *sVol,
1048 }
1049 // in eta
1050 if (etaN > 1 && eta > 0)
1051 m_trackingVolumeHelper->glueTrackingVolumes(*sVol,
1053 *sVols[(eta - 1) * phiN + phi],
1055 //
1056 subVolumes.emplace_back(std::move(sVol), transf * gp);
1057 }
1058 }
1059
1061 const Amg::Vector3D volCenter{vol.transform().translation()};
1062 const Trk::BinUtility buZ(etaN,
1063 volCenter.z() - cyl->halflengthZ(),
1064 volCenter.z() + cyl->halflengthZ(),
1066 buPhi += buZ;
1067
1068 auto volBinUtil = Trk::BinUtility(buPhi);
1069 auto subVols = std::make_unique<Trk::BinnedArray2D<Trk::TrackingVolume>>(std::move(subVolumes),
1070 volBinUtil);
1071
1072 tVol = std::make_unique<Trk::TrackingVolume>(vol, aLVC.m_muonMaterial, nullptr,
1073 std::move(subVols), volumeName);
1074 // register glue volumes
1075 Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
1076 volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover, sVols);
1077 volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover, sVols);
1078 volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY, sVolsNeg);
1079 volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY, sVolsPos);
1080
1081 } else {
1082 // enclosed muon objects ?
1083 blendVols.clear();
1084 std::vector<Trk::DetachedTrackingVolume*> muonObjs{};
1085 if (hasStations) {
1086 muonObjs = getDetachedObjects(vol, blendVols, aLVC);
1087 }
1088 auto muonObjsPtr = std::make_unique<std::vector<Trk::DetachedTrackingVolume*>>(muonObjs);
1089
1090 tVol = std::make_unique<Trk::TrackingVolume>(vol, aLVC.m_muonMaterial, std::move(muonObjsPtr),
1091 volumeName);
1092 // statistics
1093 ++aLVC.m_frameNum;
1094 aLVC.m_frameStat += muonObjs.size();
1095 // prepare blending
1096 if (m_blendInertMaterial && !blendVols.empty()) {
1097 for (auto& blendVol : blendVols) {
1098 aLVC.m_blendMap[blendVol].push_back(tVol.get());
1099 }
1100 }
1101 }
1102
1103 return tVol;
1104}
1105
1107 int mode,
1108 const std::string& volumeName,
1110 bool hasStations) const {
1111 ATH_MSG_VERBOSE( "processing volume in mode:" << mode);
1112
1113 // mode : -1 ( adjusted z/phi partition )
1114 // 0 ( -"- plus barrel H binning )
1115 // 0 ( -"- plus inner endcap H binning )
1116 // 0 ( -"- plus outer endcap H binning )
1117
1118 TrackingVolumePtr tVol{};
1119
1120 unsigned int colorCode = m_colorCode;
1121
1122 std::vector<Trk::DetachedTrackingVolume*> blendVols;
1123
1124 // getPartitionFromMaterial(vol);
1125
1126 // retrieve cylinder
1127 const auto *cyl = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(vol.volumeBounds()));
1128 if (!cyl) {
1129 ATH_MSG_ERROR(" process volume: volume cylinder boundaries not retrieved, return 0 ");
1130 return nullptr;
1131 }
1132 // create vector of zSteps for this volume
1133 std::vector<float> zSteps;
1134 std::vector<int> zTypes;
1135 double zPos = vol.center().z();
1136 double hz = cyl->halflengthZ();
1137 double z1 = zPos - hz;
1138 double z2 = zPos + hz;
1139 zSteps.push_back(z1);
1140 for (unsigned int iz = 0; iz < aLVC.m_zPartitions.size(); iz++) {
1141 if (aLVC.m_zPartitions[iz] == zSteps.front())
1142 zTypes.push_back(aLVC.m_zPartitionsType[iz]);
1143 if (aLVC.m_zPartitions[iz] > z1 && aLVC.m_zPartitions[iz] < z2) {
1144 zSteps.push_back(aLVC.m_zPartitions[iz]);
1145 if (zTypes.empty()) {
1146 if (iz == 0)
1147 zTypes.push_back(0);
1148 else
1149 zTypes.push_back(aLVC.m_zPartitionsType[iz - 1]);
1150 }
1151 zTypes.push_back(aLVC.m_zPartitionsType[iz]);
1152 z1 = aLVC.m_zPartitions[iz];
1153 }
1154 }
1155 zSteps.push_back(z2);
1156
1157 for (unsigned int iz = 0; iz < zSteps.size(); iz++)
1158 ATH_MSG_DEBUG("z partition in volume:" << volumeName << ":" << iz << ":"
1159 << zSteps[iz]);
1160
1161 // phi binning
1162 if (std::abs(zPos) > m_barrelZ &&
1163 cyl->outerRadius() < aLVC.m_outerBarrelRadius)
1164 getPhiParts(0, aLVC);
1165 else if (std::abs(zPos) <= m_ectZ)
1166 getPhiParts(2, aLVC);
1167 else if (std::abs(zPos) <= aLVC.m_innerEndcapZ)
1168 getPhiParts(3, aLVC);
1169 else if (std::abs(zPos) > m_outerWheel &&
1170 cyl->outerRadius() > m_outerShieldRadius)
1171 getPhiParts(1, aLVC);
1172 else if (std::abs(zPos) > aLVC.m_innerEndcapZ &&
1173 std::abs(zPos) < m_bigWheel &&
1174 cyl->outerRadius() > m_outerShieldRadius)
1175 getPhiParts(1, aLVC);
1176 else
1177 getPhiParts(0, aLVC);
1178
1179 // R/H binning ?
1180 unsigned int etaN = zSteps.size() - 1;
1181 unsigned int phiN = aLVC.m_adjustedPhi.size();
1182
1183 int phiTypeMax = 0; // count different partitions
1184
1185 if (mode > -1) {
1186 // create z,phi bin utilities
1187 auto zBinUtil = Trk::BinUtility(zSteps, Trk::open, Trk::binZ);
1188 auto pBinUtil = Trk::BinUtility(aLVC.m_adjustedPhi, Trk::closed, Trk::binPhi);
1189 std::vector<std::vector<Trk::BinUtility>> hBinUtil{};
1190 for (unsigned iz = 0; iz < zSteps.size() - 1; iz++) {
1191 std::vector<Trk::BinUtility> phBinUtil{};
1192 for (unsigned ip = 0; ip < aLVC.m_adjustedPhi.size(); ip++) {
1193 // retrieve reference phi
1194 float phiRef = 0.5 * aLVC.m_adjustedPhi[ip];
1195 if (ip < aLVC.m_adjustedPhi.size() - 1)
1196 phiRef += 0.5 * aLVC.m_adjustedPhi[ip + 1];
1197 else
1198 phiRef += 0.5 * aLVC.m_adjustedPhi[0] + M_PI;
1199
1200 if (aLVC.m_adjustedPhiType[ip] > phiTypeMax)
1201 phiTypeMax = aLVC.m_adjustedPhiType[ip];
1202 for (std::pair<int, float> i :
1203 aLVC.m_hPartitions[mode][zTypes[iz]]
1204 [aLVC.m_adjustedPhiType[ip]]) {
1205 ATH_MSG_VERBOSE(" mode " << mode << " phiRef " << phiRef
1206 << " zTypes[iz] " << zTypes[iz]
1207 << " m_adjustedPhiType[ip] "
1208 << aLVC.m_adjustedPhiType[ip]
1209 << " hPartitions " << i.second);
1210 }
1211 phBinUtil.emplace_back(phiRef,
1212 aLVC.m_hPartitions[mode][zTypes[iz]][aLVC.m_adjustedPhiType[ip]]);
1213 }
1214 hBinUtil.push_back(std::move(phBinUtil));
1215 }
1216
1217 // create subvolumes & BinnedArray
1218 std::vector<Trk::TrackingVolumeOrderPosition> subVolumesVect;
1219 std::vector<std::vector<std::vector<Trk::TrackingVolume*>>> subVolumes;
1220 std::vector<std::vector<std::shared_ptr<Trk::BinnedArray<Trk::TrackingVolume> > > >
1221 hBins;
1222 std::vector<Trk::TrackingVolume*> sVolsInn; // for gluing
1223 std::vector<Trk::TrackingVolume*> sVolsOut; // for gluing
1224 std::vector<Trk::TrackingVolume*> sVolsNeg; // for gluing
1225 std::vector<Trk::TrackingVolume*> sVolsPos; // for gluing
1226 for (unsigned int eta = 0; eta < zSteps.size() - 1; eta++) {
1227 if (colorCode > 0) {
1228 colorCode = 6 - colorCode;
1229 }
1230 double posZ = 0.5 * (zSteps[eta] + zSteps[eta + 1]);
1231 double hZ = 0.5 * std::abs(zSteps[eta + 1] - zSteps[eta]);
1232 std::vector<std::vector<Trk::TrackingVolume*> > phiSubs;
1233 std::vector<std::shared_ptr<Trk::BinnedArray<Trk::TrackingVolume>>> phBins;
1234 std::vector<int> phiType(phiTypeMax + 1, -1);
1235 std::vector<std::vector<Trk::Volume*> > garbVol(phiTypeMax + 1);
1236 unsigned int pCode = 1;
1237 for (unsigned int phi = 0; phi < phiN; phi++) {
1238 pCode = (colorCode > 0) ? 3 - pCode : 0;
1239 double posPhi = 0.5 * aLVC.m_adjustedPhi[phi];
1240 double phiSect = 0.;
1241 if (phi < phiN - 1) {
1242 posPhi += 0.5 * aLVC.m_adjustedPhi[phi + 1];
1243 phiSect = 0.5 * std::abs(aLVC.m_adjustedPhi[phi + 1] -
1244 aLVC.m_adjustedPhi[phi]);
1245 } else {
1246 posPhi += 0.5 * aLVC.m_adjustedPhi[0] + M_PI;
1247 phiSect = 0.5 * std::abs(aLVC.m_adjustedPhi[0] + 2 * M_PI -
1248 aLVC.m_adjustedPhi[phi]);
1249 }
1250 std::vector<std::pair<int, float> > hSteps =
1251 aLVC.m_hPartitions[mode][zTypes[eta]]
1252 [aLVC.m_adjustedPhiType[phi]];
1253 std::vector<Trk::TrackingVolume*> hSubs;
1254 std::vector<Trk::TrackingVolumeOrderPosition> hSubsTr;
1255 int phiP = phiType[aLVC.m_adjustedPhiType[phi]];
1256
1257 unsigned int hCode = 1;
1258 for (unsigned int h = 0; h < hSteps.size() - 1; h++) {
1259 hCode = colorCode > 0 ? 1 - hCode : 0;
1260 // similar volume may exist already
1261 std::unique_ptr<Trk::Volume> subVol{};
1262 const Amg::Transform3D transf = Amg::getRotateZ3D(posPhi) * Amg::getTranslateZ3D(posZ);
1263 //
1264 int volType = 0; // cylinder
1265 if (hSteps[h].first == 1 && hSteps[h + 1].first == 0)
1266 volType = 1;
1267 if (hSteps[h].first == 0 && hSteps[h + 1].first == 1)
1268 volType = 2;
1269 if (hSteps[h].first == 1 && hSteps[h + 1].first == 1)
1270 volType = 3;
1271 // define subvolume
1272 if (phiP > -1) {
1273 subVol = std::make_unique<Trk::Volume>(*phiSubs[phiP][h],
1274 transf *phiSubs[phiP][h]->transform().inverse());
1275 } else if (phiSect < 0.5 * M_PI) {
1276 auto subBds = std::make_shared<Trk::BevelledCylinderVolumeBounds>(hSteps[h].second,
1277 hSteps[h + 1].second,
1278 phiSect,
1279 hZ, volType);
1280 subVol = std::make_unique<Trk::Volume>(makeTransform(transf), std::move(subBds));
1281 } else {
1282 auto subBds = std::make_shared<Trk::CylinderVolumeBounds>(hSteps[h].second,
1283 hSteps[h + 1].second,
1284 phiSect, hZ);
1285 subVol = std::make_unique<Trk::Volume>(makeTransform(transf), std::move(subBds));
1286 }
1287
1288 // enclosed muon objects ? also adjusts material properties
1289 // in case of material blend
1290 std::string volName = volumeName +
1294 blendVols.clear();
1295 std::vector<Trk::DetachedTrackingVolume*> detVols{};
1296 if (hasStations) {
1297 detVols = getDetachedObjects(*subVol, blendVols, aLVC);
1298 }
1299 auto detVolsPtr = std::make_unique<std::vector<Trk::DetachedTrackingVolume*>>(detVols);
1300 auto sVol = std::make_unique<Trk::TrackingVolume>(*subVol,
1301 aLVC.m_muonMaterial,
1302 std::move(detVolsPtr),
1303 volName);
1304
1305 // statistics
1306 ++aLVC.m_frameNum;
1307 aLVC.m_frameStat += detVols.size();
1308 // prepare blending
1309 if (m_blendInertMaterial && !blendVols.empty()) {
1310 for (auto& blendVol : blendVols) {
1311 aLVC.m_blendMap[blendVol].push_back(sVol.get());
1312 }
1313 }
1314 // reference point for the check of envelope
1315 double posR = 0.5 * (hSteps[h].second + hSteps[h + 1].second);
1316 // loop over inner cutouts
1317 for (unsigned int in = 1; in < aLVC.m_msCutoutsIn.size(); ++in) {
1318 if (posZ >= aLVC.m_msCutoutsIn[in].second &&
1319 posZ <= aLVC.m_msCutoutsIn[in - 1].second) {
1320 if (posR < aLVC.m_msCutoutsIn[in].first) {
1321 sVol->sign(Trk::BeamPipe);
1322 }
1323 break;
1324 }
1325 }
1326 // loop over outer cutouts
1327 for (unsigned int io = 1; io < aLVC.m_msCutoutsOut.size(); ++io) {
1328 if (posZ >= aLVC.m_msCutoutsOut[io - 1].second &&
1329 posZ <= aLVC.m_msCutoutsOut[io].second) {
1330 if (posR > aLVC.m_msCutoutsOut[io].first){
1331 sVol->sign(Trk::Cavern);
1332 }
1333 break;
1334 }
1335 }
1336 //
1337 sVol->registerColorCode(colorCode + pCode + hCode);
1338 // reference position
1339 const Amg::Vector3D gp =
1340 0.5 * (hSteps[h].second + hSteps[h + 1].second) * Amg::Vector3D::UnitX();
1341 hSubs.push_back(sVol.get());
1342
1343 // glue subVolume
1344 if (h == 0)
1345 sVolsInn.push_back(sVol.get());
1346 if (h == hSteps.size() - 2)
1347 sVolsOut.push_back(sVol.get());
1348 if (eta == 0)
1349 sVolsNeg.push_back(sVol.get());
1350 if (eta == etaN - 1)
1351 sVolsPos.push_back(sVol.get());
1352 // in R/H
1353 if (h > 0) { // glue 'manually'
1354 if (volType == 1 || volType == 3) { // plane surface
1355 m_trackingVolumeHelper->setOutsideTrackingVolume(*sVol,
1357 hSubs[h - 1]);
1358 m_trackingVolumeHelper->setOutsideTrackingVolume(*hSubs[h - 1],
1360 sVol.get());
1361 } else { // cylinder surface
1362 m_trackingVolumeHelper->setInsideTrackingVolume(*sVol,
1364 hSubs[h - 1]);
1365 m_trackingVolumeHelper->setOutsideTrackingVolume(*hSubs[h - 1],
1367 sVol.get());
1368 }
1369 }
1370 // in phi
1371 if (phiN > 1 && phi > 0) {
1372 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol,
1374 phBins[phi - 1]);
1375 if (phi == phiN - 1){
1376 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol,
1378 phBins[0]);
1379 }
1380 }
1381 // in eta
1382 if (etaN > 1 && eta > 0) {
1383 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol,
1385 hBins[eta - 1][phi]);
1386 }
1387 //We need to be careful here
1388 //This will end up in subVols.
1389 //subVols will end up in the volume we create.
1390 //That volume will manage it
1391 subVolumesVect.emplace_back(std::move(sVol), transf * gp);
1392 //The following is used for glueing of volumes to volumes
1393 //Notice that we effectively have a "view" ptr.
1394 auto& back = subVolumesVect.back();
1395 auto ptrNoDelete = std::shared_ptr<Trk::TrackingVolume>(
1396 back.first.get(),
1398 hSubsTr.push_back({ptrNoDelete,back.second});
1399 }
1400 phiSubs.push_back(hSubs);
1401 auto volBinArray = std::make_unique<Trk::BinnedArray1D<Trk::TrackingVolume>>(hSubsTr,
1402 hBinUtil[eta][phi]);
1403 phBins.emplace_back(std::move(volBinArray));
1404 // save link to current partition for cloning
1405 if (phiP < 0)
1406 phiType[aLVC.m_adjustedPhiType[phi]] = phi;
1407
1408 // finish phi gluing
1409 if (phiN > 1 && phi > 0) {
1410 for (auto& j : phiSubs[phi - 1]) {
1411 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*j,
1413 phBins[phi]);
1414 }
1415 }
1416 if (phiN > 1 && phi == phiN - 1) {
1417 for (auto& j : phiSubs[0]) {
1418 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*j,
1420 phBins[phi]);
1421 }
1422 }
1423 // finish eta gluing
1424 if (etaN > 1 && eta > 0) {
1425 for (auto& j: subVolumes[eta - 1][phi]) {
1426 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*j, Trk::positiveFaceXY,
1427 phBins[phi]);
1428 }
1429 }
1430 }
1431 subVolumes.push_back(phiSubs);
1432 hBins.push_back(phBins);
1433 }
1434
1435 auto hBinVecPtr = hBinUtil;
1436 auto subVols = std::make_unique<Trk::BinnedArray1D1D1D<Trk::TrackingVolume>>(subVolumesVect,
1437 zBinUtil,
1438 pBinUtil,
1439 hBinVecPtr);
1440
1441 tVol = std::make_unique<Trk::TrackingVolume>(vol, aLVC.m_muonMaterial, nullptr,
1442 std::move(subVols), volumeName);
1443 // register glue volumes
1444 Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
1445 volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover, sVolsInn);
1446 volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover, sVolsOut);
1447 volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY, sVolsNeg);
1448 volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY, sVolsPos);
1449
1450 return tVol;
1451 }
1452
1453 // proceed with 2D z/phi binning
1454 // partitions ? include protection against wrong setup
1455 if (phiN < 1) {
1456 ATH_MSG_ERROR( "wrong partition setup");
1457 phiN = 1;
1458 } else {
1459 ATH_MSG_VERBOSE("partition setup:(z,phi):" << etaN << "," << phiN);
1460 }
1461
1462 if (etaN * phiN > 1) { // partition
1463 // subvolume boundaries
1464
1465 // create subvolumes & BinnedArray
1466 std::vector<Trk::TrackingVolumeOrderPosition> subVolumes(etaN * phiN);
1467 std::vector<Trk::TrackingVolume*> sVols(etaN * phiN); // for gluing
1468 std::vector<Trk::TrackingVolume*> sVolsNeg(phiN); // for gluing
1469 std::vector<Trk::TrackingVolume*> sVolsPos(phiN); // for gluing
1470 for (unsigned int eta = 0; eta < zSteps.size() - 1; ++eta) {
1471 double posZ = 0.5 * (zSteps[eta] + zSteps[eta + 1]);
1472 double hZ = 0.5 * std::abs(zSteps[eta + 1] - zSteps[eta]);
1473 colorCode = 26 - colorCode;
1474 for (unsigned int phi = 0; phi < phiN; phi++) {
1475 colorCode = 26 - colorCode;
1476 double posPhi = 0.5 * aLVC.m_adjustedPhi[phi];
1477 double phiSect = 0.;
1478 if (phi < phiN - 1) {
1479 posPhi += 0.5 * aLVC.m_adjustedPhi[phi + 1];
1480 phiSect = 0.5 * std::abs(aLVC.m_adjustedPhi[phi + 1] -
1481 aLVC.m_adjustedPhi[phi]);
1482 } else {
1483 posPhi += 0.5 * aLVC.m_adjustedPhi[0] + M_PI;
1484 phiSect = 0.5 * std::abs(aLVC.m_adjustedPhi[0] + 2 * M_PI -
1485 aLVC.m_adjustedPhi[phi]);
1486 }
1487 // define subvolume
1488 auto subBds = std::make_shared<Trk::CylinderVolumeBounds>(cyl->innerRadius(), cyl->outerRadius(), phiSect, hZ);
1489 const Amg::Transform3D transf = Amg::getRotateZ3D(posPhi) *
1491 Trk::Volume subVol(makeTransform(transf), std::move(subBds));
1492 // enclosed muon objects ?
1493 std::string volName = volumeName + MuonGM::buildString(eta, 2) +
1495
1496 Trk::Material mat = aLVC.m_muonMaterial;
1497 blendVols.clear();
1498 std::vector<Trk::DetachedTrackingVolume*> detVols{} ;
1499 if (hasStations) {
1500 detVols = getDetachedObjects(subVol, blendVols, aLVC);
1501 }
1502 auto detVolPtr = std::make_unique<std::vector<Trk::DetachedTrackingVolume*>>(detVols);
1503 auto sVol = std::make_unique<Trk::TrackingVolume>(subVol, aLVC.m_muonMaterial,
1504 std::move(detVolPtr),
1505 volName);
1506 // statistics
1507 ++aLVC.m_frameNum;
1508 aLVC.m_frameStat += detVols.size();
1509 // prepare blending
1510 if (m_blendInertMaterial && !blendVols.empty()) {
1511 for (auto& blendVol : blendVols) {
1512 aLVC.m_blendMap[blendVol].push_back(sVol.get());
1513 }
1514 }
1515 // reference point for the check of envelope
1516 double posR = 0.5 * (cyl->innerRadius() + cyl->outerRadius());
1517 // loop over inner cutouts
1518 for (unsigned int in = 1; in < aLVC.m_msCutoutsIn.size(); ++in) {
1519 if (posZ >= aLVC.m_msCutoutsIn[in].second &&
1520 posZ <= aLVC.m_msCutoutsIn[in - 1].second) {
1521 if (posR < aLVC.m_msCutoutsIn[in].first)
1522 sVol->sign(Trk::BeamPipe);
1523 break;
1524 }
1525 }
1526 // loop over outer cutouts
1527 for (unsigned int io = 1; io < aLVC.m_msCutoutsOut.size(); ++io) {
1528 if (posZ >= aLVC.m_msCutoutsOut[io - 1].second &&
1529 posZ <= aLVC.m_msCutoutsOut[io].second) {
1530 if (posR > aLVC.m_msCutoutsOut[io].first)
1531 sVol->sign(Trk::Cavern);
1532 break;
1533 }
1534 }
1535 sVol->registerColorCode(colorCode);
1536 // reference position
1537 const Amg::Vector3D gp = cyl->outerRadius() * Amg::Vector3D::UnitX();
1538 // glue subVolumes
1539 // sVols[phi*etaN+eta] = sVol;
1540 sVols[phiN * eta + phi] = sVol.get();
1541 if (eta == 0){
1542 sVolsNeg[phi] = sVol.get();
1543 }
1544 if (eta == etaN - 1) {
1545 sVolsPos[phi] = sVol.get();
1546 }
1547 // in phi
1548 if (phiN > 1 && phi > 0) {
1549 m_trackingVolumeHelper->glueTrackingVolumes(*sVol,
1551 *sVols[eta * phiN + phi - 1],
1553 if (phi == phiN - 1) {
1554 m_trackingVolumeHelper->glueTrackingVolumes(*sVols[eta * phiN],
1556 *sVol,
1558 }
1559 }
1560 // in eta
1561 if (etaN > 1 && eta > 0) {
1562 m_trackingVolumeHelper->glueTrackingVolumes(*sVol,
1564 *sVols[(eta - 1) * phiN + phi],
1566 }
1567 //
1568 subVolumes[phi * etaN + eta] = std::make_pair(std::move(sVol), transf * gp);
1569
1570 }
1571 }
1572
1573 // Trk::BinUtility2DZF* volBinUtil=new
1574 // Trk::BinUtility2DZF(zSteps,m_adjustedPhi,new
1575 // Amg::Transform3D(vol->transform()));
1578 const Trk::BinUtility pBinUtil(aLVC.m_adjustedPhi,
1581
1582 zBinUtil += pBinUtil;
1583
1584 auto volBinUtil = Trk::BinUtility(zBinUtil); // TODO verify ordering PhiZ vs. ZPhi
1585
1586 auto subVols = std::make_unique<Trk::BinnedArray2D<Trk::TrackingVolume>>(subVolumes,
1587 volBinUtil);
1588
1589 tVol = std::make_unique<Trk::TrackingVolume>(vol, aLVC.m_muonMaterial, nullptr,
1590 std::move(subVols), volumeName);
1591 // register glue volumes
1592 Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
1593 volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover, sVols);
1594 volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover, sVols);
1595 volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY, sVolsNeg);
1596 volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY, sVolsPos);
1597
1598 } else {
1599 // enclosed muon objects ?
1600 blendVols.clear();
1601 std::vector<Trk::DetachedTrackingVolume*> muonObjs{};
1602 if (hasStations) {
1603 muonObjs = getDetachedObjects(vol, blendVols, aLVC);
1604 }
1605 auto muonObjPtr = std::make_unique<std::vector<Trk::DetachedTrackingVolume*>>(muonObjs);
1606 tVol = std::make_unique<Trk::TrackingVolume>(vol, aLVC.m_muonMaterial,
1607 std::move(muonObjPtr),
1608 volumeName);
1609 // statistics
1610 ++aLVC.m_frameNum;
1611 aLVC.m_frameStat += muonObjs.size();
1612 // prepare blending
1613 if (m_blendInertMaterial && !blendVols.empty()) {
1614 for (auto& blendVol : blendVols) {
1615 aLVC.m_blendMap[blendVol].push_back(tVol.get());
1616 }
1617 }
1618 }
1619
1620 return tVol;
1621}
1622
1624 int type,
1625 const std::string& volumeName,
1627 bool hasStations) const {
1628 ATH_MSG_VERBOSE( "processing shield volume " << volumeName
1629 << " in mode:" << type);
1630
1631 TrackingVolumePtr tVol{};
1632
1633 unsigned int colorCode = m_colorCode;
1634
1635 std::vector<Trk::DetachedTrackingVolume*> blendVols;
1636
1637 // getPartitionFromMaterial(vol);
1638
1639 // retrieve cylinder
1640 const auto *cyl = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(vol.volumeBounds()));
1641 if (!cyl) {
1642 ATH_MSG_ERROR(" process volume: volume cylinder boundaries not retrieved, return 0 ");
1643 return nullptr;
1644 }
1645 // create vector of zSteps for this volume
1646 std::vector<float> zSteps;
1647 zSteps.clear();
1648 double zPos = vol.center().z();
1649 double hz = cyl->halflengthZ();
1650 double z1 = zPos - hz;
1651 double z2 = zPos + hz;
1652 zSteps.push_back(z1);
1653 for (double iz : aLVC.m_shieldZPart) {
1654 if (iz > z1 && iz < z2) {
1655 zSteps.push_back(iz);
1656 z1 = iz;
1657 }
1658 }
1659 zSteps.push_back(z2);
1660
1661 // phi binning trivial
1662 aLVC.m_adjustedPhi.clear();
1663 aLVC.m_adjustedPhi.push_back(0.);
1664
1665 unsigned int etaN = zSteps.size() - 1;
1666
1667 // create z,h bin utilities
1668 auto zBinUtil = Trk::BinUtility(zSteps, Trk::BinningOption::open,
1672 std::vector<std::vector<Trk::BinUtility>> hBinUtil{};
1673 float phiRef = 0.;
1674 for (unsigned iz = 0; iz < zSteps.size() - 1; iz++) {
1675 std::vector<Trk::BinUtility> phBinUtil;
1676 phBinUtil.emplace_back(phiRef, aLVC.m_shieldHPart[type]);
1677 hBinUtil.push_back(std::move(phBinUtil));
1678 }
1679
1680
1681 // create subvolumes & BinnedArray
1682 std::vector<Trk::TrackingVolumeOrderPosition> subVolumesVect;
1683 std::vector<std::vector<std::vector<Trk::TrackingVolume*>>> subVolumes;
1684 std::vector<std::vector<std::shared_ptr<Trk::BinnedArray<Trk::TrackingVolume>>>> hBins;
1685 std::vector<Trk::TrackingVolume*> sVolsInn; // for gluing
1686 std::vector<Trk::TrackingVolume*> sVolsOut; // for gluing
1687 std::vector<Trk::TrackingVolume*> sVolsNeg; // for gluing
1688 std::vector<Trk::TrackingVolume*> sVolsPos; // for gluing
1689 for (unsigned int eta = 0; eta < zSteps.size() - 1; eta++) {
1690 if (colorCode > 0)
1691 colorCode = 26 - colorCode;
1692 double posZ = 0.5 * (zSteps[eta] + zSteps[eta + 1]);
1693 double hZ = 0.5 * std::abs(zSteps[eta + 1] - zSteps[eta]);
1694 std::vector<std::vector<Trk::TrackingVolume*> > phiSubs;
1695 std::vector<std::shared_ptr<Trk::BinnedArray<Trk::TrackingVolume>>> phBins{};
1696 int phi = 0;
1697 double posPhi = 0.;
1698 double phiSect = M_PI;
1699 std::vector<std::pair<int, float> > hSteps = aLVC.m_shieldHPart[type];
1700 std::vector<Trk::TrackingVolume*> hSubs;
1701 std::vector<Trk::TrackingVolumeOrderPosition> hSubsTr;
1702 unsigned int hCode = 1;
1703 for (unsigned int h = 0; h < hSteps.size() - 1; h++) {
1704 hCode = (colorCode > 0) ? 1 - hCode : 0;
1705 // define subvolume
1706 auto subBds = std::make_shared<Trk::CylinderVolumeBounds>(hSteps[h].second, hSteps[h + 1].second, phiSect, hZ);
1707 const double mediumRadius = subBds->mediumRadius();
1709 Trk::Volume subVol(makeTransform(transf), std::move(subBds));
1710
1711 // enclosed muon objects ? also adjusts material properties in case
1712 // of material blend
1713 std::string volName = volumeName + MuonGM::buildString(eta, 2) +
1716 blendVols.clear();
1717 std::vector<Trk::DetachedTrackingVolume*> detVols{};
1718 if (hasStations) {
1719 detVols = getDetachedObjects(subVol, blendVols, aLVC);
1720 }
1721 auto detVolPtr = std::make_unique<std::vector<Trk::DetachedTrackingVolume*>>(detVols);
1722 auto sVol = std::make_unique<Trk::TrackingVolume>(subVol, aLVC.m_muonMaterial,
1723 std::move(detVolPtr), volName);
1724
1725 // statistics
1726 ++aLVC.m_frameNum;
1727 aLVC.m_frameStat += detVols.size();
1728 // prepare blending
1729 if (m_blendInertMaterial && !blendVols.empty()) {
1730 for (auto& blendVol : blendVols) {
1731 aLVC.m_blendMap[blendVol].push_back(sVol.get());
1732 }
1733 }
1734 // reference point for the check of envelope
1735 double posR = 0.5 * (hSteps[h].second + hSteps[h + 1].second);
1736 // loop over inner cutouts
1737 for (unsigned int in = 1; in < aLVC.m_msCutoutsIn.size(); in++) {
1738 if (posZ >= aLVC.m_msCutoutsIn[in].second &&
1739 posZ <= aLVC.m_msCutoutsIn[in - 1].second) {
1740 if (posR < aLVC.m_msCutoutsIn[in].first)
1741 sVol->sign(Trk::BeamPipe);
1742 break;
1743 }
1744 }
1745 //
1746 sVol->registerColorCode(colorCode + hCode);
1747 // reference position
1748 const Amg::Vector3D gp = mediumRadius * Amg::Vector3D::UnitX();
1749 hSubs.push_back(sVol.get());
1750
1751 // glue subVolume
1752 if (h == 0)
1753 sVolsInn.push_back(sVol.get());
1754 if (h == hSteps.size() - 2)
1755 sVolsOut.push_back(sVol.get());
1756 if (eta == 0)
1757 sVolsNeg.push_back(sVol.get());
1758 if (eta == etaN - 1)
1759 sVolsPos.push_back(sVol.get());
1760 // in R/H
1761 if (h > 0) { // glue 'manually'
1762 m_trackingVolumeHelper->setInsideTrackingVolume(*sVol,
1764 hSubs[h - 1]);
1765 m_trackingVolumeHelper->setOutsideTrackingVolume(*hSubs[h - 1],
1767 sVol.get());
1768 }
1769 // in eta
1770 if (etaN > 1 && eta > 0)
1771 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol,
1773 hBins[eta - 1][phi]);
1774 // We need to be careful here
1775 // This will end up in subVols.
1776 // subVols will end up in the volume we create.
1777 // That volume will manage it
1778 subVolumesVect.emplace_back(std::move(sVol), transf * gp);
1779 // The following is used for glueing of volumes to volumes
1780 //Notice that we effectively have a "view" ptr.
1781 auto& back = subVolumesVect.back();
1782 auto ptrNoDelete = std::shared_ptr<Trk::TrackingVolume>(
1783 back.first.get(), Trk::do_not_delete<Trk::TrackingVolume>);
1784 hSubsTr.push_back({ptrNoDelete, back.second});
1785 }
1786 phiSubs.push_back(hSubs);
1788 auto volBinArray = std::make_unique<Trk::BinnedArray1D<Trk::TrackingVolume>>(hSubsTr, hBinUtil[eta][phi]);
1789 phBins.push_back(std::move(volBinArray));
1790
1791 // finish eta gluing
1792 if (etaN > 1 && eta > 0) {
1793 for (auto& j : subVolumes[eta - 1][phi]) {
1794 m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*j,
1796 phBins[phi]);
1797 }
1798 }
1799 subVolumes.push_back(phiSubs);
1800 hBins.push_back(phBins);
1801 }
1802
1803 auto hBinVecPtr = hBinUtil;
1804 auto subVols = std::make_unique<Trk::BinnedArray1D1D1D<Trk::TrackingVolume>>(subVolumesVect,
1805 zBinUtil,
1806 pBinUtil,
1807 hBinVecPtr);
1808
1809 tVol = std::make_unique<Trk::TrackingVolume>(vol, aLVC.m_muonMaterial, nullptr,
1810 std::move(subVols), volumeName);
1811 // register glue volumes
1812 Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
1813 volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover, sVolsInn);
1814 volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover, sVolsOut);
1815 volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY, sVolsNeg);
1816 volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY, sVolsPos);
1817
1818 return tVol;
1819}
1820
1821std::vector<Trk::DetachedTrackingVolume*>
1823 std::vector<Trk::DetachedTrackingVolume*>& blendVols,
1825 int mode) const {
1826 // mode : 0 all, 1 active only, 2 inert only
1827
1828 std::vector<Trk::DetachedTrackingVolume*> detTVs{};
1829
1830 // get min/max Z/Phi from volume (allways a cylinder/bevelled cylinder
1831 // volume )
1832 const auto *cyl = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(vol.volumeBounds()));
1833 const auto *bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*>(&(vol.volumeBounds()));
1834
1835 double rmed{0.}, dphi{0.}, hz{0.}, rMin{0.}, rMax{0.}, rMaxc{0.};
1836 int type = 0;
1837 if (cyl) {
1838 rmed = cyl->mediumRadius();
1839 dphi = cyl->halfPhiSector();
1840 hz = cyl->halflengthZ();
1841 rMin = cyl->innerRadius();
1842 rMax = cyl->outerRadius();
1843 rMaxc = rMax;
1844 } else if (bcyl) {
1845 rmed = bcyl->mediumRadius();
1846 dphi = bcyl->halfPhiSector();
1847 hz = bcyl->halflengthZ();
1848 rMin = bcyl->innerRadius();
1849 rMax = bcyl->outerRadius();
1850 rMaxc = rMax;
1851 type = bcyl->type();
1852 if (type > 1)
1853 rMaxc *= 1. / cos(dphi);
1854 } else {
1855 return detTVs;
1856 }
1857 const Amg::Vector3D center = vol.transform() * (rmed *Amg::Vector3D::UnitX());
1858
1859 double zMin = center[2] - hz;
1860 double zMax = center[2] + hz;
1861 double pMin = 0.;
1862 double pMax = +2 * M_PI;
1863 bool phiLim = false;
1864 if (dphi < M_PI) {
1865 pMin = center.phi() - dphi + M_PI;
1866 pMax = center.phi() + dphi + M_PI;
1867 phiLim = true;
1868 }
1869
1870 ATH_MSG_VERBOSE(" zMin " << zMin << " zMax " << zMax << " rMin " << rMin
1871 << " rMax " << rMax << " rMaxc " << rMaxc
1872 << " phi limits " << pMin << " phiMax " << pMax
1873 << " phiLim " << phiLim);
1874
1875 // define detector region : can extend over several
1876 int gMin = (zMax <= -m_bigWheel) ? 0 : 1;
1877 if (zMin >= m_bigWheel)
1878 gMin = 8;
1879 else if (zMin >= aLVC.m_innerEndcapZ)
1880 gMin = 7;
1881 else if (zMin >= m_ectZ)
1882 gMin = 6;
1883 else if (zMin >= m_diskShieldZ)
1884 gMin = 5;
1885 else if (zMin >= -m_diskShieldZ)
1886 gMin = 4;
1887 else if (zMin >= -m_ectZ)
1888 gMin = 3;
1889 else if (zMin >= -aLVC.m_innerEndcapZ)
1890 gMin = 2;
1891 int gMax = (zMax >= m_bigWheel) ? 8 : 7;
1892 if (zMax <= -m_bigWheel)
1893 gMax = 0;
1894 else if (zMax <= -aLVC.m_innerEndcapZ)
1895 gMax = 1;
1896 else if (zMax <= -m_ectZ)
1897 gMax = 2;
1898 else if (zMax <= -m_diskShieldZ)
1899 gMax = 3;
1900 else if (zMax <= m_diskShieldZ)
1901 gMax = 4;
1902 else if (zMax <= m_ectZ)
1903 gMax = 5;
1904 else if (zMax <= aLVC.m_innerEndcapZ)
1905 gMax = 6;
1906
1907 ATH_MSG_VERBOSE(" active volumes gMin " << gMin << " gMax " << gMax);
1908
1909 // active, use corrected rMax
1910 if (mode < 2 && !aLVC.m_stationSpan.empty()) {
1911 for (int gMode = gMin; gMode <= gMax; gMode++) {
1912 for (const auto&[station, s] : (aLVC.m_stationSpan)[gMode]) {
1913 bool rLimit = !aLVC.m_static3d || (s->rMin <= rMaxc && s->rMax >= rMin);
1914 // Check meanZ for BME stations
1915 bool meanZOK = false;
1916 if (station->name() == "BME1_Station" ||
1917 station->name() == "BME2_Station") {
1918 if ((s->zMin + s->zMax) / 2. < zMax &&
1919 (s->zMin + s->zMax) / 2. > zMin)
1920 meanZOK = true;
1921 if ((s->phiMin + s->phiMax) / 2 < pMin && phiLim)
1922 meanZOK = false;
1923 // if ((s->phiMin + s->phiMax) / 2 < pMin && phiLim)
1924 // meanZOK = false;
1925 }
1926 if (rLimit &&
1927 ((s->zMin < zMax && s->zMax > zMin) || meanZOK)) {
1928 bool accepted = false;
1929 if (phiLim) {
1930 if (pMin >= 0 && pMax <= 2 * M_PI) {
1931 if (s->phiMin <= s->phiMax &&
1932 s->phiMin <= pMax && s->phiMax >= pMin)
1933 accepted = true;
1934 if (s->phiMin > s->phiMax &&
1935 (s->phiMin <= pMax || s->phiMax >= pMin))
1936 accepted = true;
1937 } else if (pMin < 0) {
1938 if (s->phiMin <= s->phiMax &&
1939 (s->phiMin <= pMax ||
1940 s->phiMax >= pMin + 2 * M_PI))
1941 accepted = true;
1942 if (s->phiMin > s->phiMax)
1943 accepted = true;
1944 } else if (pMax > 2 * M_PI) {
1945 if (s->phiMin <= s->phiMax &&
1946 (s->phiMin <= pMax - 2 * M_PI ||
1947 s->phiMax >= pMin))
1948 accepted = true;
1949 if (s->phiMin > s->phiMax)
1950 accepted = true;
1951 }
1952 } else
1953 accepted = true;
1954 if (meanZOK)
1955 accepted = true;
1956 if (accepted) {
1957 detTVs.push_back(station);
1958 ATH_MSG_VERBOSE(" active volume accepted by rLimit "
1959 << station->name() << " zMin " << zMin
1960 << " zMax " << zMax << " rMin " << rMin
1961 << " rMax " << rMax << " PhiMin "
1962 << pMin << " PhiMax " << pMax);
1963 }
1964 }
1965 }
1966 }
1967 }
1968 // passive
1969 if (mode != 1 && !aLVC.m_inertSpan.empty()) {
1970 for (int gMode = gMin; gMode <= gMax; gMode++) {
1971 for (const auto& [inert, s]: (aLVC.m_inertSpan)[gMode]) {
1972 bool rLimit = (!aLVC.m_static3d ||
1973 (s->rMin <= rMaxc && s->rMax >= rMin));
1974 if (rLimit && s->zMin < zMax && s->zMax > zMin) {
1975 bool accepted = false;
1976 if (phiLim) {
1977 if (pMin >= 0 && pMax <= 2 * M_PI) {
1978 if (s->phiMin <= s->phiMax &&
1979 s->phiMin <= pMax && s->phiMax >= pMin)
1980 accepted = true;
1981 if (s->phiMin > s->phiMax &&
1982 (s->phiMin <= pMax || s->phiMax >= pMin))
1983 accepted = true;
1984 } else if (pMin < 0) {
1985 if (s->phiMin <= s->phiMax &&
1986 (s->phiMin <= pMax ||
1987 s->phiMax >= pMin + 2 * M_PI))
1988 accepted = true;
1989 if (s->phiMin > s->phiMax)
1990 accepted = true;
1991 } else if (pMax > 2 * M_PI) {
1992 if (s->phiMin <= s->phiMax &&
1993 (s->phiMin <= pMax - 2 * M_PI ||
1994 s->phiMax >= pMin))
1995 accepted = true;
1996 if (s->phiMin > s->phiMax)
1997 accepted = true;
1998 }
1999 } else
2000 accepted = true;
2001 if (accepted) {
2002 bool perm =
2003 inert->name().compare(inert->name().size() - 4, 4,
2004 "PERM") == 0;
2005 if (!m_blendInertMaterial || !m_removeBlended || perm)
2006 detTVs.push_back(inert);
2007 if (m_blendInertMaterial && !perm)
2008 blendVols.push_back(inert);
2009 ATH_MSG_VERBOSE(" Inert volume accepted by rLimit "
2010 << inert->name() << " zMin " << zMin
2011 << " zMax " << zMax << " rMin " << rMin
2012 << " rMax " << rMax << " PhiMin "
2013 << pMin << " PhiMax " << pMax);
2014 }
2015 }
2016 }
2017 }
2018 }
2019 return detTVs;
2020}
2021
2023 const Trk::VolumeSpan& span,
2024 LocalVariablesContainer& aLVC) const {
2025 bool encl = false;
2026 constexpr double tol = 1.;
2027 constexpr double ptol = 0.11; // 0.08 for BT, 0.11 feet
2028
2029 // get min/max Z/Phi from volume (allways a cylinder/bevelled cylinder
2030 // volume )
2031 const auto *cyl = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(vol.volumeBounds()));
2032 const auto *bcyl =dynamic_cast<const Trk::BevelledCylinderVolumeBounds*>(&(vol.volumeBounds()));
2033
2034 double rmed{0.}, dphi{0.}, hz{0.}, rMin{0.}, rMax{0.};
2035 if (cyl) {
2036 rmed = cyl->mediumRadius();
2037 dphi = cyl->halfPhiSector();
2038 hz = cyl->halflengthZ();
2039 rMin = cyl->innerRadius();
2040 rMax = cyl->outerRadius();
2041 } else if (bcyl) {
2042 rmed = bcyl->mediumRadius();
2043 dphi = bcyl->halfPhiSector();
2044 hz = bcyl->halflengthZ();
2045 rMin = bcyl->innerRadius();
2046 rMax = bcyl->outerRadius();
2047 } else
2048 return false;
2049
2050 const Amg::Vector3D center = vol.transform() * (rmed* Amg::Vector3D::UnitX());
2051
2052 double zMin = center[2] - hz;
2053 double zMax = center[2] + hz;
2054 double pMin = 0.;
2055 double pMax = +2 * M_PI;
2056 bool phiLim = false;
2057 if (dphi < M_PI) {
2058 pMin = center.phi() - dphi + M_PI;
2059 pMax = center.phi() + dphi + M_PI;
2060 phiLim = true;
2061 }
2062 //
2063 ATH_MSG_VERBOSE("enclosing volume:z:" << zMin << "," << zMax
2064 << ":r:" << rMin << "," << rMax
2065 << ":phi:" << pMin << "," << pMax);
2066 //
2067 bool rLimit = (!aLVC.m_static3d ||
2068 (span.rMin < rMax - tol && span.rMax > rMin + tol));
2069 if (rLimit && span.zMin < zMax - tol && span.zMax > zMin + tol) {
2070 if (phiLim) {
2071 if (pMin >= 0 && pMax <= 2 * M_PI) {
2072 if (span.phiMin <= span.phiMax && span.phiMin < pMax + ptol &&
2073 span.phiMax > pMin - ptol)
2074 return true;
2075 if (span.phiMin > span.phiMax &&
2076 (span.phiMin < pMax - ptol || span.phiMax > pMin + ptol))
2077 return true;
2078 } else if (pMin < 0) {
2079 if (span.phiMin <= span.phiMax &&
2080 (span.phiMin < pMax + ptol ||
2081 span.phiMax > pMin - ptol + 2 * M_PI))
2082 return true;
2083 if (span.phiMin > span.phiMax)
2084 return true;
2085 } else if (pMax > 2 * M_PI) {
2086 if (span.phiMin <= span.phiMax &&
2087 (span.phiMin < pMax + ptol - 2 * M_PI ||
2088 span.phiMax > pMin - ptol))
2089 return true;
2090 if (span.phiMin > span.phiMax)
2091 return true;
2092 }
2093 } else {
2094 return true;
2095 }
2096 }
2097 return encl;
2098}
2100 LocalVariablesContainer& aLVC) const {
2101 // activeAdjustLevel: 1: separate MDT stations
2102 // +(inertLevel=0) barrel Z partition
2103 // 2: split TGC
2104 // +(inertLevel=0) barrel R partition
2105 // 3: split TGC supports
2106 // inertAdjustLevel: 1: BT,ECT
2107
2108 // hardcode for the moment
2109 aLVC.m_zPartitions.clear();
2110 aLVC.m_zPartitionsType.clear();
2111 aLVC.m_zPartitions.reserve(120);
2112 aLVC.m_zPartitionsType.reserve(120);
2113
2114 // outer endcap
2115 aLVC.m_zPartitions.push_back(-aLVC.m_outerEndcapZ);
2116 aLVC.m_zPartitionsType.push_back(1); // EO
2117 aLVC.m_zPartitions.push_back(-23001.);
2118 aLVC.m_zPartitionsType.push_back(1); // oute envelope change
2119 // if (m_activeAdjustLevel>0) { m_zPartitions.push_back(-21630.);
2120 // m_zPartitionsType.push_back(1); } // EOL
2121 aLVC.m_zPartitions.push_back(-22030.);
2122 aLVC.m_zPartitionsType.push_back(1); // EOL
2123 aLVC.m_zPartitions.push_back(-m_outerWheel);
2124 aLVC.m_zPartitionsType.push_back(0); // Octogon
2125 // m_zPartitions.push_back(-17990.); m_zPartitionsType.push_back(0); //
2126 // buffer
2127 aLVC.m_zPartitions.push_back(-18650.);
2128 aLVC.m_zPartitionsType.push_back(0); // buffer
2129 aLVC.m_zPartitions.push_back(-m_bigWheel);
2130 aLVC.m_zPartitionsType.push_back(1); // TGC3
2131 if (m_activeAdjustLevel > 2) {
2132 aLVC.m_zPartitions.push_back(-15225.);
2133 aLVC.m_zPartitionsType.push_back(1);
2134 }
2135 if (m_activeAdjustLevel > 1) {
2136 aLVC.m_zPartitions.push_back(-15172.);
2137 aLVC.m_zPartitionsType.push_back(1);
2138 } // end supp
2139 if (m_activeAdjustLevel > 2) {
2140 aLVC.m_zPartitions.push_back(-15128.);
2141 aLVC.m_zPartitionsType.push_back(1);
2142 } // supp
2143 if (m_activeAdjustLevel > 2) {
2144 aLVC.m_zPartitions.push_back(-15070.);
2145 aLVC.m_zPartitionsType.push_back(1);
2146 }
2147 if (m_activeAdjustLevel > 0) {
2148 aLVC.m_zPartitions.push_back(-14940.);
2149 aLVC.m_zPartitionsType.push_back(1);
2150 } //
2151 if (m_activeAdjustLevel > 2) {
2152 aLVC.m_zPartitions.push_back(-14805.);
2153 aLVC.m_zPartitionsType.push_back(1);
2154 }
2155 if (m_activeAdjustLevel > 1) {
2156 aLVC.m_zPartitions.push_back(-14733.);
2157 aLVC.m_zPartitionsType.push_back(1);
2158 } // end supp.
2159 if (m_activeAdjustLevel > 2) {
2160 aLVC.m_zPartitions.push_back(-14708.);
2161 aLVC.m_zPartitionsType.push_back(1);
2162 } // supp.
2163 if (m_activeAdjustLevel > 2) {
2164 aLVC.m_zPartitions.push_back(-14650.);
2165 aLVC.m_zPartitionsType.push_back(1);
2166 } //
2167 if (m_activeAdjustLevel > 0) {
2168 aLVC.m_zPartitions.push_back(-14560.);
2169 aLVC.m_zPartitionsType.push_back(1);
2170 } // EML
2171 if (m_activeAdjustLevel > 0) {
2172 aLVC.m_zPartitions.push_back(-14080.);
2173 aLVC.m_zPartitionsType.push_back(1);
2174 } // EMS
2175 if (m_activeAdjustLevel > 0) {
2176 aLVC.m_zPartitions.push_back(-13620.);
2177 aLVC.m_zPartitionsType.push_back(1);
2178 } // TGC
2179 if (m_activeAdjustLevel > 2) {
2180 aLVC.m_zPartitions.push_back(-13525.);
2181 aLVC.m_zPartitionsType.push_back(1);
2182 } // TGC
2183 if (m_activeAdjustLevel > 1) {
2184 aLVC.m_zPartitions.push_back(-13448.5);
2185 aLVC.m_zPartitionsType.push_back(1);
2186 } // end supp.
2187 if (m_activeAdjustLevel > 2) {
2188 aLVC.m_zPartitions.push_back(-13421.5);
2189 aLVC.m_zPartitionsType.push_back(1);
2190 } // supp.
2191 if (m_activeAdjustLevel > 2) {
2192 aLVC.m_zPartitions.push_back(-13346);
2193 aLVC.m_zPartitionsType.push_back(1);
2194 } // TGC
2195
2196 // inner endcap
2197 aLVC.m_zPartitions.push_back(-aLVC.m_innerEndcapZ);
2198 aLVC.m_zPartitionsType.push_back(0); //
2199 if (m_inertAdjustLevel > 0) {
2200 aLVC.m_zPartitions.push_back(-12790);
2201 aLVC.m_zPartitionsType.push_back(0);
2202 } // ECT
2203 if (m_inertAdjustLevel > 1) {
2204 aLVC.m_zPartitions.push_back(-12100.);
2205 aLVC.m_zPartitionsType.push_back(0);
2206 } //
2207 if (m_inertAdjustLevel > 0) {
2208 aLVC.m_zPartitions.push_back(-12000.);
2209 aLVC.m_zPartitionsType.push_back(0);
2210 } //
2211 if (m_inertAdjustLevel > 0) {
2212 aLVC.m_zPartitions.push_back(-11210.);
2213 aLVC.m_zPartitionsType.push_back(1);
2214 } // BT
2215 if (m_inertAdjustLevel > 0) {
2216 aLVC.m_zPartitions.push_back(-10480.);
2217 aLVC.m_zPartitionsType.push_back(0);
2218 } //
2219 if (m_inertAdjustLevel > 0) {
2220 aLVC.m_zPartitions.push_back(-9700.);
2221 aLVC.m_zPartitionsType.push_back(0);
2222 } //
2223 if (m_inertAdjustLevel > 1) {
2224 aLVC.m_zPartitions.push_back(-9300.);
2225 aLVC.m_zPartitionsType.push_back(0);
2226 } // rib
2227 if (m_inertAdjustLevel > 1) {
2228 aLVC.m_zPartitions.push_back(-8800.);
2229 aLVC.m_zPartitionsType.push_back(0);
2230 } // ect
2231 if (m_inertAdjustLevel > 0) {
2232 aLVC.m_zPartitions.push_back(-8610.);
2233 aLVC.m_zPartitionsType.push_back(1);
2234 } // BT
2235 if (m_inertAdjustLevel > 0) {
2236 aLVC.m_zPartitions.push_back(-8000.);
2237 aLVC.m_zPartitionsType.push_back(1);
2238 } // BT
2239 aLVC.m_zPartitions.push_back(-m_ectZ);
2240 aLVC.m_zPartitionsType.push_back(0); // ECT/small wheel
2241 if (m_activeAdjustLevel > 0) {
2242 aLVC.m_zPartitions.push_back(-7450.);
2243 aLVC.m_zPartitionsType.push_back(0);
2244 } // EIS
2245 if (m_activeAdjustLevel > 2) {
2246 aLVC.m_zPartitions.push_back(-7364.);
2247 aLVC.m_zPartitionsType.push_back(0);
2248 } // EIS
2249 if (m_activeAdjustLevel > 0 || m_inertAdjustLevel > 0) {
2250 aLVC.m_zPartitions.push_back(-7170.);
2251 aLVC.m_zPartitionsType.push_back(0);
2252 } // cone assembly,TGC
2253 if (m_activeAdjustLevel > 0) {
2254 aLVC.m_zPartitions.push_back(-7030.);
2255 aLVC.m_zPartitionsType.push_back(0);
2256 } // TGC
2257 if (m_activeAdjustLevel > 2) {
2258 aLVC.m_zPartitions.push_back(-6978.);
2259 aLVC.m_zPartitionsType.push_back(0);
2260 } // TGC
2261
2262 // barrel
2263 aLVC.m_zPartitions.push_back(-m_diskShieldZ);
2264 aLVC.m_zPartitionsType.push_back(0); // disk
2265 if (m_inertAdjustLevel > 0) {
2266 aLVC.m_zPartitions.push_back(-6829.);
2267 aLVC.m_zPartitionsType.push_back(0);
2268 } // back disk
2269 // if (m_inertAdjustLevel>1) { (*m_zPartitions).push_back(-6600.);
2270 // m_zPartitionsType.push_back(0); } //
2271 aLVC.m_zPartitions.push_back(-6550.);
2272 aLVC.m_zPartitionsType.push_back(0); // outer envelope change
2273 if (m_activeAdjustLevel > 0) {
2274 aLVC.m_zPartitions.push_back(-6100.);
2275 aLVC.m_zPartitionsType.push_back(0);
2276 }
2277 if (m_inertAdjustLevel > 0) {
2278 aLVC.m_zPartitions.push_back(-5503.);
2279 aLVC.m_zPartitionsType.push_back(1);
2280 } // BT
2281 if (m_inertAdjustLevel > 0) {
2282 aLVC.m_zPartitions.push_back(-4772.);
2283 aLVC.m_zPartitionsType.push_back(0);
2284 } //
2285 if (m_activeAdjustLevel > 0) {
2286 aLVC.m_zPartitions.push_back(-4300.);
2287 aLVC.m_zPartitionsType.push_back(0);
2288 } //
2289 aLVC.m_zPartitions.push_back(-4000.);
2290 aLVC.m_zPartitionsType.push_back(0); // outer envelope change
2291 if (m_inertAdjustLevel > 1) {
2292 aLVC.m_zPartitions.push_back(-3700.);
2293 aLVC.m_zPartitionsType.push_back(0);
2294 } //
2295 if (m_inertAdjustLevel > 1) {
2296 aLVC.m_zPartitions.push_back(-3300.);
2297 aLVC.m_zPartitionsType.push_back(0);
2298 } //
2299 if (m_activeAdjustLevel > 0) {
2300 aLVC.m_zPartitions.push_back(-2600.);
2301 aLVC.m_zPartitionsType.push_back(0);
2302 } //
2303 if (m_inertAdjustLevel > 0) {
2304 aLVC.m_zPartitions.push_back(-2078.);
2305 aLVC.m_zPartitionsType.push_back(1);
2306 } // BT
2307 if (m_inertAdjustLevel > 0) {
2308 aLVC.m_zPartitions.push_back(-1347.);
2309 aLVC.m_zPartitionsType.push_back(1);
2310 } // cryoring
2311 if (m_activeAdjustLevel > 0) {
2312 aLVC.m_zPartitions.push_back(-800.);
2313 aLVC.m_zPartitionsType.push_back(1);
2314 } // cryoring
2315 if (m_inertAdjustLevel > 1) {
2316 aLVC.m_zPartitions.push_back(-300.);
2317 aLVC.m_zPartitionsType.push_back(0);
2318 } //
2319 if (static_cast<int>(m_inertAdjustLevel) +
2320 static_cast<int>(m_activeAdjustLevel) <
2321 1) {
2322 aLVC.m_zPartitions.push_back(-0.7 * m_diskShieldZ);
2323 aLVC.m_zPartitionsType.push_back(0);
2324 } //
2325
2326 unsigned int zSiz = aLVC.m_zPartitions.size();
2327 for (unsigned int i = 0; i < zSiz; i++) {
2328 aLVC.m_zPartitions.push_back(-aLVC.m_zPartitions[zSiz - 1 - i]);
2329 if (i < zSiz - 1)
2330 aLVC.m_zPartitionsType.push_back(
2331 aLVC.m_zPartitionsType[zSiz - 2 - i]);
2332 }
2333}
2334
2336 int mode, LocalVariablesContainer& aLVC) const {
2337 if (mode == 0) { // trivial
2338 aLVC.m_adjustedPhi.clear();
2339 aLVC.m_adjustedPhiType.clear();
2340 aLVC.m_adjustedPhi.push_back(0.);
2341 aLVC.m_adjustedPhiType.push_back(0);
2342
2343 } else if (mode == 1) {
2344 int phiNum = 1;
2345 if (m_activeAdjustLevel > 0)
2346 phiNum = m_phiPartition;
2347 aLVC.m_adjustedPhi.resize(phiNum);
2348 aLVC.m_adjustedPhiType.resize(phiNum);
2349 aLVC.m_adjustedPhi[0] = 0.;
2350 aLVC.m_adjustedPhiType[0] = 0;
2351 int ic = 0;
2352 while (ic < phiNum - 1) {
2353 ic++;
2354 aLVC.m_adjustedPhi[ic] =
2355 aLVC.m_adjustedPhi[ic - 1] + 2. * M_PI / phiNum;
2356 aLVC.m_adjustedPhiType[ic] = 0;
2357 }
2358
2359 } else if (mode == 2) { // barrel(BT)
2360 // hardcode for the moment
2361 aLVC.m_adjustedPhi.resize(16);
2362 aLVC.m_adjustedPhiType.resize(16);
2363
2364 double phiSect[2];
2365 phiSect[0] = (M_PI / 8 - 0.105);
2366 phiSect[1] = 0.105;
2367
2368 aLVC.m_adjustedPhi[0] = -phiSect[0];
2369 aLVC.m_adjustedPhiType[0] = 0;
2370 int ic = 0;
2371 int is = 1;
2372
2373 while (ic < 15) {
2374 ic++;
2375 is = 1 - is;
2376 aLVC.m_adjustedPhi[ic] =
2377 aLVC.m_adjustedPhi[ic - 1] + 2 * phiSect[is];
2378 aLVC.m_adjustedPhiType[ic] = 1 - is;
2379 }
2380
2381 } else if (mode == 3) { // ECT(+BT)
2382 // hardcode for the moment
2383 aLVC.m_adjustedPhi.resize(32);
2384 aLVC.m_adjustedPhiType.resize(32);
2385
2386 double phiSect[3];
2387 phiSect[0] = 0.126;
2388 phiSect[2] = 0.105;
2389 phiSect[1] = 0.5 * (M_PI / 8. - phiSect[0] - phiSect[2]);
2390
2391 aLVC.m_adjustedPhi[0] = -phiSect[0];
2392 aLVC.m_adjustedPhiType[0] = 0;
2393 aLVC.m_adjustedPhi[1] = aLVC.m_adjustedPhi[0] + 2 * phiSect[0];
2394 aLVC.m_adjustedPhiType[1] = 1;
2395 int ic = 1;
2396 int is = 0;
2397
2398 while (ic < 31) {
2399 ic++;
2400 is = 2 - is;
2401 aLVC.m_adjustedPhi[ic] =
2402 aLVC.m_adjustedPhi[ic - 1] + 2 * phiSect[1];
2403 aLVC.m_adjustedPhiType[ic] = is;
2404 ic++;
2405 aLVC.m_adjustedPhi[ic] =
2406 aLVC.m_adjustedPhi[ic - 1] + 2 * phiSect[is];
2407 aLVC.m_adjustedPhiType[ic] = 1;
2408 }
2409 }
2410}
2411
2413 LocalVariablesContainer& aLVC) const {
2414 // hardcode for the moment
2415 aLVC.m_hPartitions.clear(); // barrel, inner endcap, outer endcap
2416
2417 // 0: barrel 2x2
2418 // non BT sector
2419 std::vector<std::pair<int, float> > barrelZ0F0;
2420 barrelZ0F0.emplace_back(0, aLVC.m_innerBarrelRadius);
2421 if (m_activeAdjustLevel > 0) {
2422 barrelZ0F0.emplace_back(0, 4450.); // for DiskShieldingBackDisk
2423 barrelZ0F0.emplace_back(0, 6500.); // BI/BM
2424 barrelZ0F0.emplace_back(0, 8900.); // BM/BO
2425 barrelZ0F0.emplace_back(0, 13000.); // outer envelope
2426 }
2427 barrelZ0F0.emplace_back(0, aLVC.m_outerBarrelRadius);
2428
2429 std::vector<std::pair<int, float> > barrelZ0F1;
2430 barrelZ0F1.emplace_back(0, aLVC.m_innerBarrelRadius);
2431 if (m_inertAdjustLevel > 0) {
2432 barrelZ0F1.emplace_back(1, 4500.);
2433 barrelZ0F1.emplace_back(1, 5900.);
2434 } else if (m_activeAdjustLevel > 0)
2435 barrelZ0F1.emplace_back(0, 4450.);
2436 if (m_activeAdjustLevel > 0)
2437 barrelZ0F1.emplace_back(0, 6500.);
2438 if (m_inertAdjustLevel > 0)
2439 barrelZ0F1.emplace_back(1, 8900.);
2440 else if (m_activeAdjustLevel > 0)
2441 barrelZ0F1.emplace_back(0, 8900.);
2442 if (m_inertAdjustLevel > 0)
2443 barrelZ0F1.emplace_back(1, 10100.);
2444 barrelZ0F1.emplace_back(0, 13000.); // outer envelope
2445 barrelZ0F1.emplace_back(0, aLVC.m_outerBarrelRadius);
2446
2447 // BT sector
2448 std::vector<std::pair<int, float> > barrelZ1F0;
2449 barrelZ1F0.emplace_back(0, aLVC.m_innerBarrelRadius);
2450 if (static_cast<int>(m_activeAdjustLevel) +
2451 static_cast<int>(m_inertAdjustLevel) >
2452 0)
2453 barrelZ1F0.emplace_back(0, 4450.);
2454 if (m_inertAdjustLevel > 0) {
2455 barrelZ1F0.emplace_back(1, 5800.);
2456 barrelZ1F0.emplace_back(1, 6500.);
2457 } else if (m_activeAdjustLevel > 0)
2458 barrelZ1F0.emplace_back(0, 6500.);
2459 if (m_inertAdjustLevel > 0) {
2460 barrelZ1F0.emplace_back(1, 6750.);
2461 barrelZ1F0.emplace_back(1, 8400.);
2462 }
2463 if (m_activeAdjustLevel > 0)
2464 barrelZ1F0.emplace_back(0, 8770.); // adapted for cryoring (from 8900)
2465 if (m_inertAdjustLevel > 0)
2466 barrelZ1F0.emplace_back(1, 9850.); // adapted for cryoring (from 9600)
2467 barrelZ1F0.emplace_back(0, 13000.); // outer envelope
2468 barrelZ1F0.emplace_back(0, aLVC.m_outerBarrelRadius);
2469
2470 std::vector<std::pair<int, float> > barrelZ1F1;
2471 barrelZ1F1.emplace_back(0, aLVC.m_innerBarrelRadius);
2472 if (m_inertAdjustLevel > 0) {
2473 barrelZ1F1.emplace_back(1, 4500.);
2474 barrelZ1F1.emplace_back(1, 6000.);
2475 } else if (m_activeAdjustLevel > 0)
2476 barrelZ1F1.emplace_back(0, 4450.);
2477 if (m_activeAdjustLevel > 0)
2478 barrelZ1F1.emplace_back(0, 6500.);
2479 if (m_inertAdjustLevel > 0)
2480 barrelZ1F1.emplace_back(1, 6800.);
2481 if (m_inertAdjustLevel > 0) {
2482 barrelZ1F1.emplace_back(1, 8900.);
2483 barrelZ1F1.emplace_back(1, 10100.);
2484 } else if (m_activeAdjustLevel > 0)
2485 barrelZ1F1.emplace_back(0, 8900.);
2486 barrelZ1F1.emplace_back(0, 13000.); // outer envelope
2487 barrelZ1F1.emplace_back(0, aLVC.m_outerBarrelRadius);
2488
2489 std::vector<std::vector<std::vector<std::pair<int, float> > > > barrelZF(2);
2490 barrelZF[0].push_back(barrelZ0F0);
2491 barrelZF[0].push_back(barrelZ0F1);
2492 barrelZF[1].push_back(barrelZ1F0);
2493 barrelZF[1].push_back(barrelZ1F1);
2494
2495 // small wheel 1x2 ( no z BT sector)
2496 // non BT sector
2497 std::vector<std::pair<int, float> > swZ0F0;
2498 swZ0F0.emplace_back(0, m_innerShieldRadius);
2499 if (m_activeAdjustLevel > 1) {
2500 swZ0F0.emplace_back(0, 2700.);
2501 }
2502 if (static_cast<int>(m_activeAdjustLevel) +
2503 static_cast<int>(m_inertAdjustLevel) >
2504 0)
2505 swZ0F0.emplace_back(0, 4450.);
2506 if (m_activeAdjustLevel > 0) {
2507 swZ0F0.emplace_back(0, 6560.); // BI/BM
2508 swZ0F0.emplace_back(0, 8900.); // BM/BO
2509 }
2510 swZ0F0.emplace_back(0, aLVC.m_outerBarrelRadius);
2511
2512 // phi BT sector
2513 std::vector<std::pair<int, float> > swZ0F1;
2514 swZ0F1.emplace_back(0, m_innerShieldRadius);
2515 if (m_activeAdjustLevel > 1)
2516 swZ0F1.emplace_back(0, 2700.);
2517 if (static_cast<int>(m_inertAdjustLevel) +
2518 static_cast<int>(m_activeAdjustLevel) >
2519 0)
2520 swZ0F1.emplace_back(0, 4450.);
2521 if (m_inertAdjustLevel > 0)
2522 swZ0F1.emplace_back(1, 5900.);
2523 if (m_activeAdjustLevel > 0)
2524 swZ0F1.emplace_back(0, 6560.);
2525 if (m_inertAdjustLevel > 0) {
2526 swZ0F1.emplace_back(1, 8900.);
2527 swZ0F1.emplace_back(1, 10100.);
2528 } else if (m_activeAdjustLevel > 0)
2529 swZ0F1.emplace_back(0, 8900.);
2530 swZ0F1.emplace_back(0, aLVC.m_outerBarrelRadius);
2531
2532 std::vector<std::vector<std::vector<std::pair<int, float> > > > swZF(1);
2533 swZF[0].push_back(swZ0F0);
2534 swZF[0].push_back(swZ0F1);
2535
2536 // inner endcap/ECT 2x3
2537 // ect coil, non-BT z
2538 std::vector<std::pair<int, float> > innerZ0F0;
2539 innerZ0F0.emplace_back(0, m_innerShieldRadius);
2540 if (m_inertAdjustLevel > 0)
2541 innerZ0F0.emplace_back(0, 1100.);
2542 if (m_inertAdjustLevel > 1)
2543 innerZ0F0.emplace_back(1, 5150.);
2544 if (m_inertAdjustLevel > 0)
2545 innerZ0F0.emplace_back(1, 5300.);
2546 if (m_activeAdjustLevel > 0) {
2547 innerZ0F0.emplace_back(0, 6500.);
2548 innerZ0F0.emplace_back(0, 8900.);
2549 }
2550 innerZ0F0.emplace_back(0, aLVC.m_outerBarrelRadius);
2551
2552 // coil gap, non-BT z
2553 std::vector<std::pair<int, float> > innerZ0F1;
2554 innerZ0F1.emplace_back(0, m_innerShieldRadius);
2555 if (m_inertAdjustLevel > 0)
2556 innerZ0F1.emplace_back(0, 1100.);
2557 if (m_inertAdjustLevel > 1) {
2558 innerZ0F1.emplace_back(1, 1400.);
2559 innerZ0F1.emplace_back(1, 1685.);
2560 }
2561 if (m_inertAdjustLevel > 0) {
2562 innerZ0F1.emplace_back(1, 4700.);
2563 innerZ0F1.emplace_back(1, 5900.);
2564 }
2565 if (m_activeAdjustLevel > 0) {
2566 innerZ0F1.emplace_back(0, 6500.);
2567 innerZ0F1.emplace_back(0, 8900.);
2568 }
2569 innerZ0F1.emplace_back(0, aLVC.m_outerBarrelRadius);
2570
2571 // BT coil, no-BT z
2572 std::vector<std::pair<int, float> > innerZ0F2;
2573 innerZ0F2.emplace_back(0, m_innerShieldRadius);
2574 if (m_inertAdjustLevel > 0)
2575 innerZ0F2.emplace_back(0, 1100.);
2576 if (m_inertAdjustLevel > 1) {
2577 innerZ0F2.emplace_back(1, 1400.);
2578 innerZ0F2.emplace_back(1, 1685.);
2579 }
2580 if (m_inertAdjustLevel > 0) {
2581 innerZ0F2.emplace_back(1, 4450.);
2582 innerZ0F2.emplace_back(1, 5900.);
2583 }
2584 if (m_activeAdjustLevel > 0)
2585 innerZ0F2.emplace_back(0, 6500.);
2586 if (m_inertAdjustLevel > 0) {
2587 innerZ0F2.emplace_back(1, 8900.);
2588 innerZ0F2.emplace_back(1, 10100.);
2589 } else if (m_activeAdjustLevel > 0)
2590 innerZ0F2.emplace_back(0, 8900.);
2591 innerZ0F2.emplace_back(0, aLVC.m_outerBarrelRadius);
2592
2593 // ect coil, z BT sector
2594 std::vector<std::pair<int, float> > innerZ1F0;
2595 innerZ1F0.emplace_back(0, m_innerShieldRadius);
2596 if (m_inertAdjustLevel > 0)
2597 innerZ1F0.emplace_back(0, 1100.);
2598 if (m_inertAdjustLevel > 1)
2599 innerZ1F0.emplace_back(1, 5150.);
2600 if (m_inertAdjustLevel > 0)
2601 innerZ1F0.emplace_back(1, 5300.);
2602 if (m_inertAdjustLevel > 0)
2603 innerZ1F0.emplace_back(1, 5800.);
2604 if (m_inertAdjustLevel > 0)
2605 innerZ1F0.emplace_back(1, 6750.);
2606 else if (m_activeAdjustLevel > 0)
2607 innerZ1F0.emplace_back(0, 6500.);
2608 if (m_inertAdjustLevel > 0) {
2609 innerZ1F0.emplace_back(1, 8400.);
2610 innerZ1F0.emplace_back(1, 9600.);
2611 } else if (m_activeAdjustLevel > 0)
2612 innerZ1F0.emplace_back(0, 8900.);
2613 innerZ1F0.emplace_back(0, aLVC.m_outerBarrelRadius);
2614
2615 // coil gap, BT z sector
2616 std::vector<std::pair<int, float> > innerZ1F1;
2617 innerZ1F1.emplace_back(0, m_innerShieldRadius);
2618 if (m_inertAdjustLevel > 0)
2619 innerZ1F1.emplace_back(0, 1100.);
2620 if (m_inertAdjustLevel > 1) {
2621 innerZ1F1.emplace_back(1, 1400.);
2622 innerZ1F1.emplace_back(1, 1685.);
2623 }
2624 if (m_inertAdjustLevel > 0) {
2625 innerZ1F1.emplace_back(1, 4700.);
2626 innerZ1F1.emplace_back(1, 5800.);
2627 innerZ1F1.emplace_back(1, 6750.);
2628 } else if (m_activeAdjustLevel > 0)
2629 innerZ1F1.emplace_back(0, 6500.);
2630 if (m_inertAdjustLevel > 0) {
2631 innerZ1F1.emplace_back(1, 8400.);
2632 innerZ1F1.emplace_back(1, 9600.);
2633 } else if (m_activeAdjustLevel > 0)
2634 innerZ1F1.emplace_back(0, 8900.);
2635 innerZ1F1.emplace_back(0, aLVC.m_outerBarrelRadius);
2636
2637 // BT coil, BT z sector
2638 std::vector<std::pair<int, float> > innerZ1F2;
2639 innerZ1F2.emplace_back(0, m_innerShieldRadius);
2640 if (m_inertAdjustLevel > 0)
2641 innerZ1F2.emplace_back(0, 1100.);
2642 if (m_inertAdjustLevel > 1) {
2643 innerZ1F2.emplace_back(1, 1400.);
2644 innerZ1F2.emplace_back(1, 1685.);
2645 }
2646 innerZ1F2.emplace_back(0, 4150.);
2647 if (m_inertAdjustLevel > 0) {
2648 innerZ1F2.emplace_back(1, 4700.);
2649 innerZ1F2.emplace_back(1, 5900.);
2650 innerZ1F2.emplace_back(1, 6800.);
2651 } else if (m_activeAdjustLevel > 0)
2652 innerZ1F2.emplace_back(0, 6500.);
2653 if (m_inertAdjustLevel > 0) {
2654 innerZ1F2.emplace_back(1, 8900.);
2655 innerZ1F2.emplace_back(1, 10100.);
2656 } else if (m_activeAdjustLevel > 0)
2657 innerZ1F2.emplace_back(0, 8900.);
2658 innerZ1F2.emplace_back(0, aLVC.m_outerBarrelRadius);
2659
2660 std::vector<std::vector<std::vector<std::pair<int, float> > > > innerZF(2);
2661 innerZF[0].push_back(innerZ0F0);
2662 innerZF[0].push_back(innerZ0F1);
2663 innerZF[0].push_back(innerZ0F2);
2664 innerZF[1].push_back(innerZ1F0);
2665 innerZF[1].push_back(innerZ1F1);
2666 innerZF[1].push_back(innerZ1F2);
2667
2668 // outer 1x1
2669 std::vector<std::pair<int, float> > outerZ0F0;
2670 outerZ0F0.emplace_back(0, m_outerShieldRadius);
2671 outerZ0F0.emplace_back(0, 2750.); // outer envelope
2672 outerZ0F0.emplace_back(0, 12650.); // outer envelope
2673 outerZ0F0.emplace_back(0, 13400.); // outer envelope
2674 outerZ0F0.emplace_back(0, aLVC.m_outerBarrelRadius);
2675
2676 std::vector<std::pair<int, float> > outerZ0F1;
2677 outerZ0F1.emplace_back(0, m_outerShieldRadius);
2678 outerZ0F1.emplace_back(0, 2750.); // outer envelope
2679 if (m_activeAdjustLevel > 0) {
2680 outerZ0F1.emplace_back(0, 3600.);
2681 outerZ0F1.emplace_back(0, 5300.);
2682 outerZ0F1.emplace_back(0, 7000.);
2683 outerZ0F1.emplace_back(0, 8500.);
2684 outerZ0F1.emplace_back(0, 10000.);
2685 outerZ0F1.emplace_back(0, 12000.);
2686 }
2687 outerZ0F1.emplace_back(0, 12650.); // outer envelope
2688 outerZ0F1.emplace_back(0, 13400.); // outer envelope
2689 outerZ0F1.emplace_back(0, aLVC.m_outerBarrelRadius);
2690
2691 std::vector<std::vector<std::vector<std::pair<int, float> > > > outerZF(2);
2692 outerZF[0].push_back(outerZ0F0);
2693 outerZF[0].push_back(outerZ0F0);
2694 outerZF[0].push_back(outerZ0F0);
2695 outerZF[1].push_back(outerZ0F1);
2696 outerZF[1].push_back(outerZ0F1);
2697 outerZF[1].push_back(outerZ0F1);
2698
2699 // collect everything
2700 aLVC.m_hPartitions.push_back(barrelZF);
2701 aLVC.m_hPartitions.push_back(swZF);
2702 aLVC.m_hPartitions.push_back(innerZF);
2703 aLVC.m_hPartitions.push_back(outerZF);
2704}
2705
2708 aLVC.m_shieldZPart.resize(18);
2709
2710 aLVC.m_shieldZPart[0] = -21900.; // elm2
2711 aLVC.m_shieldZPart[1] = -21500.; // elm1
2712 aLVC.m_shieldZPart[2] = -21000.; // octogon
2713 aLVC.m_shieldZPart[3] = -18000.; // tube
2714 aLVC.m_shieldZPart[4] = -12882.; // ect
2715 aLVC.m_shieldZPart[5] = -7930.; // ect
2716 aLVC.m_shieldZPart[6] = -7914.; // cone
2717 aLVC.m_shieldZPart[7] = -6941.; // disk
2718 aLVC.m_shieldZPart[8] = -6783.; //
2719 for (unsigned int i = 9; i < 18; i++)
2720 aLVC.m_shieldZPart[i] = -aLVC.m_shieldZPart[17 - i];
2721
2722 aLVC.m_shieldHPart.clear();
2723
2724 std::vector<std::pair<int, float> > outerShield;
2725 outerShield.emplace_back(0, m_beamPipeRadius);
2726 outerShield.emplace_back(0, 279.); // outer envelope
2727 outerShield.emplace_back(0, 436.7); // outer envelope
2728 outerShield.emplace_back(0, 1050.); // outer envelope
2729 outerShield.emplace_back(0, m_outerShieldRadius);
2730 aLVC.m_shieldHPart.push_back(outerShield);
2731
2732 std::vector<std::pair<int, float> > innerShield;
2733 innerShield.emplace_back(0, m_beamPipeRadius);
2734 innerShield.emplace_back(0, 530.);
2735 innerShield.emplace_back(0, m_innerShieldRadius);
2736 aLVC.m_shieldHPart.push_back(innerShield);
2737
2738 std::vector<std::pair<int, float> > diskShield;
2739 diskShield.emplace_back(0, 0.);
2740 diskShield.emplace_back(0, 540.);
2741 diskShield.emplace_back(0, 750.);
2742 diskShield.emplace_back(0, 2700.);
2743 diskShield.emplace_back(0, 4255.);
2744 aLVC.m_shieldHPart.push_back(diskShield);
2745}
2746
2748 LocalVariablesContainer& aLVC) const {
2749 // loop over map
2750 // std::map<const Trk::DetachedTrackingVolume*,std::vector<const
2751 // Trk::TrackingVolume*>* >::iterator mIter = m_blendMap.begin();
2752 for (const auto&[viter, vv] : aLVC.m_blendMap) {
2753 // find material source
2754 const Trk::Material* detMat = viter->trackingVolume();
2755 double csVol = m_volumeConverter.calculateVolume(*viter->trackingVolume());
2756 std::unique_ptr<const Trk::VolumeSpan> span{m_volumeConverter.findVolumeSpan(viter->trackingVolume()->volumeBounds(),
2757 viter->trackingVolume()->transform(), 0., 0.)};
2758 if (span && csVol > 0) {
2759 double enVol = 0.;
2760 // loop over frame volumes, check if confined
2761 std::vector<bool> fEncl;
2762 // blending factors can be saved, and not recalculated for each
2763 // clone
2764 for (auto *const fIter : vv) {
2765 fEncl.push_back(enclosed(*fIter, *span, aLVC));
2766 if (fEncl.back())
2767 enVol += m_volumeConverter.calculateVolume(*fIter);
2768 }
2769 // diluting factor
2770 double dil = enVol > 0. ? csVol / enVol : 0.;
2771 if (dil > 0.) {
2772 for (auto fIter = vv.begin(); fIter != vv.end(); ++fIter) {
2773 if (fEncl[fIter - vv.begin()]) {
2774 Trk::TrackingVolume* vol = (*fIter);
2775 vol->addMaterial(*detMat, dil);
2776 if (m_colorCode == 0) {
2777 vol->registerColorCode(12);
2778 }
2779 ATH_MSG_VERBOSE((*fIter)->volumeName()
2780 << " acquires material from "
2781 << viter->name());
2782 }
2783 }
2784 ATH_MSG_VERBOSE("diluting factor:" << dil << " for "
2785 << viter->name()
2786 << ", blended ");
2787
2788 } else {
2789 ATH_MSG_VERBOSE("diluting factor:" << dil << " for "
2790 << viter->name()
2791 << ", not blended ");
2792 }
2793 }
2794 }
2795}
2796}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< RZPair > RZPairVector
Definition RZPair.h:18
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Header file for AthHistogramAlgorithm.
static constexpr double m_ectZ
minimal extent in z of the ECT
VolumeSpanArray findVolumesSpan(const DetachedVolVec &objs, double zTol, double phiTol, const LocalVariablesContainer &aLVC) const
Private method to filter detached volumes in z span.
static constexpr double m_outerWheel
minimal extend in z of the outer wheel (EO)
virtual StatusCode initialize() override
AlgTool initailize method.
std::pair< Trk::DetachedTrackingVolume *, VolumeSpanPtr > DetachedVolSpanPair
bool enclosed(const Trk::Volume &volume, const Trk::VolumeSpan &span, LocalVariablesContainer &aLVC) const
Private method to check if constituent enclosed.
void getHParts(LocalVariablesContainer &aLVC) const
Private method to retrieve h partition.
static void getShieldParts(LocalVariablesContainer &aLVC)
Private method to retrieve shield partition.
std::unique_ptr< Trk::DetachedTrackingVolume > DetachedVolPtr
TrackingGeometry Interface method.
Gaudi::Property< double > m_barrelZ
maximal extend in z of the inner part of muon endcap
TrackingVolumePtr processVolume(const Trk::Volume &, int, int, const std::string &, LocalVariablesContainer &aLVC, bool hasStations) const
Private methods to define subvolumes and fill them with detached volumes.
static constexpr double m_bigWheel
maximal extend in z of the big wheel
ServiceHandle< IEnvelopeDefSvc > m_enclosingEnvelopeSvc
service to provide input volume size
std::unique_ptr< Trk::TrackingGeometry > trackingGeometryImpl(DetachedVolVec &&stations, DetachedVolVec &&inertObjs, Trk::TrackingVolume *tvol) const
MuonTrackingGeometryBuilderImpl(const std::string &, const std::string &, const IInterface *)
Gaudi::Property< double > m_outerBarrelRadius
maximal extend in z of the muon barrel
ToolHandle< Trk::ITrackingVolumeHelper > m_trackingVolumeHelper
Helper Tool to create TrackingVolumes.
std::array< std::vector< DetachedVolSpanPair >, 9 > VolumeSpanArray
void blendMaterial(LocalVariablesContainer &aLVC) const
Private method to blend the inert material.
Gaudi::Property< double > m_innerEndcapZ
maximal extend in z of the outer part of muon endcap
std::vector< Trk::DetachedTrackingVolume * > getDetachedObjects(const Trk::Volume &trkVol, std::vector< Trk::DetachedTrackingVolume * > &, LocalVariablesContainer &aLVC, int mode=0) const
Private method to find detached volumes.
void getZParts(LocalVariablesContainer &aLVC) const
Private method to retrieve z partition.
std::unique_ptr< Trk::TrackingVolume > TrackingVolumePtr
Gaudi::Property< double > m_innerBarrelRadius
< minimal extend in radial dimension of the muon barrel
ToolHandle< Trk::ITrackingVolumeArrayCreator > m_trackingVolumeArrayCreator
Helper Tool to create TrackingVolume Arrays.
Trk::VolumeConverter m_volumeConverter
Volume helper to find geometrical span of enclosed volumes.
std::shared_ptr< const Trk::VolumeSpan > VolumeSpanPtr
TrackingVolumePtr processShield(const Trk::Volume &, int, const std::string &, LocalVariablesContainer &aLVC, bool hasStations) const
void getPhiParts(int, LocalVariablesContainer &aLVC) const
Private method to retrieve phi partition.
Bounds for a cylindrical Volume, the decomposeToSurfaces method creates a vector of up to 6 surfaces:
A generic symmetric BinUtility, for fully symmetric binning in terms of binning grid and binning type...
Definition BinUtility.h:39
Bounds for a cylindrical Volume, the decomposeToSurfaces method creates a vector of up to 6 surfaces:
double halflengthZ() const
This method returns the halflengthZ.
Descriptor class to hold GlueVolumes of a TrackingGeometry object.
const std::vector< TrackingVolume * > & glueVolumes(BoundarySurfaceFace)
retrieve them again
void registerGlueVolumes(BoundarySurfaceFace, std::vector< TrackingVolume * > &)
register the volumes
A common object to be contained by.
Definition Material.h:117
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
void registerColorCode(unsigned int icolor)
Register the color code.
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
void addMaterial(const Material &mat, float fact=1.)
add Material
GlueVolumesDescriptor & glueVolumesDescriptor()
Base class for all volumes inside the tracking realm, it defines the interface for inherited Volume c...
Definition Volume.h:36
const Amg::Vector3D & center() const
returns the center of the volume
Definition Volume.h:90
const Amg::Transform3D & transform() const
Return methods for geometry transform.
Definition Volume.h:83
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
Definition Volume.h:96
Amg::Transform3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
std::string buildString(int i, int ncha)
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
std::unique_ptr< Amg::Transform3D > makeTransform(const Amg::Transform3D &trf)
MuonTrackingGeometryBuilderImpl::TrackingVolumePtr TrackingVolumePtr
MuonTrackingGeometryBuilderImpl::DetachedVolPtr DetachedVolPtr
MuonTrackingGeometryBuilderImpl::DetachedVolVec DetachedVolVec
MuonTrackingGeometryBuilderImpl::VolumeSpanArray VolumeSpanArray
MuonTrackingGeometryBuilderImpl::DetachedVolSpanPair DetachedVolSpanPair
const auto do_not_delete
@ open
Definition BinningType.h:40
@ closed
Definition BinningType.h:41
@ tubeSectorPositivePhi
@ tubeSectorInnerCover
@ tubeSectorOuterCover
@ tubeSectorNegativePhi
@ binPhi
Definition BinningType.h:51
@ binZ
Definition BinningType.h:49
ElementLink_p1< typename GenerateELinkIndexType_p1< typename LINK::index_type >::type > type
Private struct to contain local variables we dont want to be global in this class.
std::map< Trk::DetachedTrackingVolume *, std::vector< Trk::TrackingVolume * > > m_blendMap
std::vector< std::vector< std::pair< int, float > > > m_shieldHPart
std::vector< std::vector< std::vector< std::vector< std::pair< int, float > > > > > m_hPartitions