Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
CaloTrackingGeometryBuilderImpl.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Calo
7 // Trk
15 //
18 #include "TrkGeometry/DiscLayer.h"
24 //
25 #include "TrkSurfaces/DiscBounds.h"
30 //
31 #include <memory>
32 //
34 #include "GaudiKernel/SystemOfUnits.h"
35 
36 // constructor
38  const std::string& t, const std::string& n, const IInterface* p)
39  : AthAlgTool(t, n, p) {
40 }
41 
42 // destructor
44 
45 // Athena standard methods
46 // initialize
48 
49  // Retrieve the tracking volume array creator
50  // -------------------------------------------------
51  if (m_trackingVolumeArrayCreator.retrieve().isFailure()) {
52  ATH_MSG_FATAL("Failed to retrieve tool " << m_trackingVolumeArrayCreator);
53  return StatusCode::FAILURE;
54  } else
55  ATH_MSG_INFO("Retrieved tool " << m_trackingVolumeArrayCreator);
56 
57  // Retrieve the tracking volume helper
58  // -------------------------------------------------
59  if (m_trackingVolumeHelper.retrieve().isFailure()) {
60  ATH_MSG_FATAL("Failed to retrieve tool " << m_trackingVolumeHelper);
61  return StatusCode::FAILURE;
62  } else
63  ATH_MSG_INFO("Retrieved tool " << m_trackingVolumeHelper);
64 
65  // Retrieve the second volume creator
66  if (m_buildMBTS && m_trackingVolumeCreator.retrieve().isFailure()) {
67  ATH_MSG_FATAL("Failed to retrieve tool " << m_trackingVolumeCreator);
68  return StatusCode::FAILURE;
69  } else
70  ATH_MSG_INFO("Retrieved tool " << m_trackingVolumeCreator);
71 
72  // Retrieve the volume builders
73 
74  // Retrieve the tracking volume array creator
75  // -------------------------------------------------
76  if (m_lArVolumeBuilder.retrieve().isFailure()) {
77  ATH_MSG_FATAL("Failed to retrieve tool " << m_lArVolumeBuilder);
78  return StatusCode::FAILURE;
79  } else
80  ATH_MSG_INFO("Retrieved tool " << m_lArVolumeBuilder);
81 
82  // Retrieve the tracking volume helper
83  // -------------------------------------------------
84  if (m_tileVolumeBuilder.retrieve().isFailure()) {
85  ATH_MSG_FATAL("Failed to retrieve tool " << m_tileVolumeBuilder);
86  return StatusCode::FAILURE;
87  } else
88  ATH_MSG_INFO("Retrieved tool " << m_tileVolumeBuilder);
89 
90  ATH_MSG_INFO("initialize() succesful");
91 
92  return StatusCode::SUCCESS;
93 }
94 
95 std::unique_ptr<Trk::TrackingGeometry>
97  , const CaloDetDescrManager* caloDDM
98  , const GeoAlignmentStore* geoAlign) const {
99 
100  ATH_MSG_VERBOSE("Starting to build CaloTrackingGeometry ...");
101 
102  Trk::TrackingVolume* calorimeter = nullptr;
103 
104  // the key dimensions
105  RZPairVector keyDim;
106 
107  // the enclosed input volume (ID)
108  double enclosedInnerSectorHalflength = 0.;
109  double enclosedInnerSectorRadius = 0.;
110 
111  // dummy objects
112  Trk::LayerArray* dummyLayers = nullptr;
113  Trk::TrackingVolumeArray* dummyVolumes = nullptr;
114 
115  if (innerVol) {
116  ATH_MSG_VERBOSE("Got Inner Detector Volume: " << innerVol->volumeName());
117  innerVol->screenDump(msg(MSG::VERBOSE));
118 
119  // retrieve dimensions
120  const Trk::CylinderVolumeBounds* innerDetectorBounds =
121  dynamic_cast<const Trk::CylinderVolumeBounds*>(
122  &(innerVol->volumeBounds()));
123  if (!innerDetectorBounds)
124  std::abort();
125 
126  enclosedInnerSectorHalflength = innerDetectorBounds->halflengthZ();
127  enclosedInnerSectorRadius = innerDetectorBounds->outerRadius();
128 
129  keyDim.emplace_back(enclosedInnerSectorRadius, enclosedInnerSectorHalflength);
130  }
131  // get the dimensions from the envelope service
132  const RZPairVector& envelopeDefsIn =
133  m_enclosingEnvelopeSvc->getCaloRZBoundary();
134 
135  // find the max,max pair
136  unsigned int ii = 0;
137  for (unsigned int i = 0; i < envelopeDefsIn.size(); i++) {
138  if (envelopeDefsIn[i].second > envelopeDefsIn[ii].second)
139  ii = i;
140  else if (envelopeDefsIn[i].second == envelopeDefsIn[ii].second &&
141  envelopeDefsIn[i].first > envelopeDefsIn[ii].first)
142  ii = i;
143  }
144 
145  // find the sense of rotation
146  int irot = 1;
147  unsigned int inext = ii + 1;
148  if (inext == envelopeDefsIn.size())
149  inext = 0;
150  if (envelopeDefsIn[inext].second != envelopeDefsIn[ii].second) {
151  irot = -1;
152  inext = ii > 0 ? ii - 1 : envelopeDefsIn.size() - 1;
153  }
154 
155  // fill starting with upper low edge, end with upper high edge
156  RZPairVector envelopeDefs;
157  if (irot > 0) {
158  for (unsigned int i = inext; i < envelopeDefsIn.size(); i++)
159  envelopeDefs.push_back(envelopeDefsIn[i]);
160  if (inext > 0)
161  for (unsigned int i = 0; i <= inext - 1; i++)
162  envelopeDefs.push_back(envelopeDefsIn[i]);
163  } else {
164  int i = inext;
165  while (i >= 0) {
166  envelopeDefs.push_back(envelopeDefsIn[i]);
167  i = i - 1;
168  };
169  inext = envelopeDefsIn.size() - 1;
170  while (inext >= ii) {
171  envelopeDefs.push_back(envelopeDefsIn[inext]);
172  inext = inext - 1;
173  };
174  }
175 
176  double envEnclosingVolumeHalfZ = m_caloDefaultHalflengthZ;
177 
178  ATH_MSG_VERBOSE("Calo envelope definition retrieved:");
179  RZPairVector msCutouts;
180  for (unsigned int i = 0; i < envelopeDefs.size(); i++) {
181  ATH_MSG_VERBOSE("Rz pair:" << i << ":" << envelopeDefs[i].first << ","
182  << envelopeDefs[i].second);
183  if (std::abs(envelopeDefs[i].second) < envEnclosingVolumeHalfZ)
184  envEnclosingVolumeHalfZ = std::abs(envelopeDefs[i].second);
185  // ID dimensions : pick 1100 < R < 1200
186  if (envelopeDefs[i].first > 1100. && envelopeDefs[i].first < 1200. &&
187  envelopeDefs[i].second > 0.) {
188  // check that radial size of ID envelope fits
189  if (enclosedInnerSectorRadius != envelopeDefs[i].first)
190  ATH_MSG_INFO(
191  "Enclosed ID volume radius does not match ID envelope, adjusting "
192  "Calo.");
193  envEnclosingVolumeHalfZ = envelopeDefs[i].second;
194  if (!innerVol) {
195  enclosedInnerSectorRadius = envelopeDefs[i].first;
196  enclosedInnerSectorHalflength = envelopeDefs[i].second;
197  }
198  }
199  // collect outer cutouts, process those with |z| < 6785.mm ( this cut should
200  // be synchronized with MS default size,
201  // MS builder would crash for a longer input volume )
202  if (envelopeDefs[i].second > 0. && envelopeDefs[i].second < 6785. &&
203  (envelopeDefs[i].first > 1200. ||
204  envelopeDefs[i].second > envEnclosingVolumeHalfZ)) {
205  if (msCutouts.empty())
206  msCutouts.push_back(envelopeDefs[i]);
207  else {
208  RZPairVector::iterator envIter = msCutouts.begin();
209  while (envIter != msCutouts.end() &&
210  (*envIter).second < envelopeDefs[i].second)
211  ++envIter;
212  while (envIter != msCutouts.end() &&
213  (*envIter).second == envelopeDefs[i].second &&
214  (*envIter).first > envelopeDefs[i].first)
215  ++envIter;
216  msCutouts.insert(envIter, envelopeDefs[i]);
217  }
218  }
219  // end outer (MS) cutouts
220  }
221  if (msgLvl(MSG::VERBOSE)) {
222  for (unsigned int i = 0; i < msCutouts.size(); i++)
223  ATH_MSG_VERBOSE("MS cutouts to be processed by Calo:"
224  << i << ":" << msCutouts[i].first << ","
225  << msCutouts[i].second);
226  }
227 
228  // first member of msCutouts redefines the default central cylinder dimension
229  double caloDefaultRadius = m_caloDefaultRadius;
230  double caloDefaultHalflengthZ = m_caloDefaultHalflengthZ;
231 
232  if (!msCutouts.empty()) {
233  caloDefaultRadius = msCutouts[0].first;
234  caloDefaultHalflengthZ = msCutouts[0].second;
236  " Calo central cylinder dimensions adjusted using EnvelopeSvc:"
237  << m_caloDefaultRadius << "," << m_caloDefaultHalflengthZ);
238  }
239 
240  // create dummy ID if not built already
241 
242  if (!innerVol) {
244  enclosedInnerSectorRadius, enclosedInnerSectorHalflength);
245 
246  Amg::Transform3D* idTr = new Amg::Transform3D(Trk::s_idTransform);
247 
248  innerVol =
249  new Trk::TrackingVolume(idTr, idBounds, m_caloMaterial, dummyLayers,
250  dummyVolumes, "Calo::GapVolumes::DummyID");
251 
252  keyDim.emplace_back(enclosedInnerSectorRadius, enclosedInnerSectorHalflength);
253  }
254 
255  // BEAM PIPE
256  const RZPairVector& bpDefs = m_enclosingEnvelopeSvc->getBeamPipeRZBoundary();
257 
258  ATH_MSG_VERBOSE("BeamPipe envelope definition retrieved:");
259  RZPairVector bpCutouts;
260  for (unsigned int i = 0; i < bpDefs.size(); i++) {
261  ATH_MSG_VERBOSE("Rz pair:" << i << ":" << bpDefs[i].first << ","
262  << bpDefs[i].second);
263  // beam pipe within calo : pick 10. < R < 200; envEnclosingVolumeHalfZ =<
264  // z <= msCutouts.back().second;
265  if (bpDefs[i].first > 10. && bpDefs[i].first < 200. &&
266  bpDefs[i].second >= envEnclosingVolumeHalfZ &&
267  bpDefs[i].second <= msCutouts.back().second) {
268  bpCutouts.push_back(bpDefs[i]);
269  }
270  if (i > 0 && i < 4)
271  keyDim.push_back(bpDefs[i]);
272  }
273 
274  // no beam pipe within ID
275  // if (bpCutouts[0].second == envEnclosingVolumeHalfZ && bpCutouts[0].first >
276  // 0 ) bpCutouts[0].first=0.;
277  // last not needed
278  if (bpCutouts.size() > 1 &&
279  bpCutouts.back().second == bpCutouts[bpCutouts.size() - 2].second)
280  bpCutouts.erase(bpCutouts.end() - 1);
281  // end beam pipe envelope within Calo
282  for (unsigned int i = 0; i < bpCutouts.size(); i++)
283  ATH_MSG_VERBOSE("Beam pipe dimensions to be used by Calo:"
284  << i << ":" << bpCutouts[i].first << ","
285  << bpCutouts[i].second);
286 
287  keyDim.emplace_back(caloDefaultRadius, caloDefaultHalflengthZ);
288 
291 
292  // PART 1 : Liquid Argon Volumes
293  // ===========================================================================================
294  // get the Tracking Volumes from the LAr Builder
295  //
296  const std::vector<Trk::TrackingVolume*>* lArVolumes =
297  m_lArVolumeBuilder->trackingVolumes(*caloDDM,geoAlign);
298 
299  ATH_MSG_INFO(lArVolumes->size()
300  << " volumes retrieved from " << m_lArVolumeBuilder.name());
301 
302  // LAr Barrel part
303  Trk::TrackingVolume* solenoid = (*lArVolumes)[0];
304  Trk::TrackingVolume* solenoidlArPresamplerGap = (*lArVolumes)[1];
305  Trk::TrackingVolume* lArBarrelPresampler = (*lArVolumes)[2];
306  Trk::TrackingVolume* lArBarrel = (*lArVolumes)[3];
307 
308  // LAr Positive Endcap part
309  Trk::TrackingVolume* lArPositiveMBTS = (*lArVolumes)[4];
310  Trk::TrackingVolume* lArPositiveEndcap = (*lArVolumes)[5];
311  Trk::TrackingVolume* lArPositiveHec = (*lArVolumes)[6];
312  Trk::TrackingVolume* lArPositiveFcal = (*lArVolumes)[7];
313  Trk::TrackingVolume* lArPositiveHecFcalCover = (*lArVolumes)[8];
314  // LAr Negative Endcap part
315  Trk::TrackingVolume* lArNegativeMBTS = (*lArVolumes)[9];
316  Trk::TrackingVolume* lArNegativeEndcap = (*lArVolumes)[10];
317  Trk::TrackingVolume* lArNegativeHec = (*lArVolumes)[11];
318  Trk::TrackingVolume* lArNegativeFcal = (*lArVolumes)[12];
319  Trk::TrackingVolume* lArNegativeHecFcalCover = (*lArVolumes)[13];
320  Trk::TrackingVolume* lArPosECPresampler = (*lArVolumes)[14];
321  Trk::TrackingVolume* lArNegECPresampler = (*lArVolumes)[15];
322 
323  // PART 2 : Tile Volumes
324  // ===========================================================================================
325  // get the Tracking Volumes from the Tile Builder
326  std::vector<Trk::TrackingVolume*>* tileVolumes =
327  m_tileVolumeBuilder->trackingVolumes(*caloDDM,geoAlign);
328 
329  ATH_MSG_INFO(tileVolumes->size()
330  << " volumes retrieved from " << m_tileVolumeBuilder.name());
331  if (msgLvl(MSG::INFO)) {
332  ATH_MSG_INFO(
333  "--------------- detailed output "
334  "---------------------------------------------------------- ");
335  std::vector<Trk::TrackingVolume*>::const_iterator tileVolIter =
336  tileVolumes->begin();
337  std::vector<Trk::TrackingVolume*>::const_iterator tileVolIterEnd =
338  tileVolumes->end();
339  for (; tileVolIter != tileVolIterEnd;
340  (*tileVolIter)->screenDump(msg(MSG::VERBOSE)), ++tileVolIter)
341  ;
342  }
343 
344  // Tile Barrel part
345  Trk::TrackingVolume* tileCombined = (*tileVolumes)[0];
346  // Tile Positive Extended Part
347  Trk::TrackingVolume* tilePositiveExtendedBarrel = (*tileVolumes)[1];
348 
349  const Trk::CylinderVolumeBounds* ebBounds =
350  dynamic_cast<const Trk::CylinderVolumeBounds*>(
351  &(tilePositiveExtendedBarrel->volumeBounds()));
352 
353  double rTileMin = ebBounds ? ebBounds->innerRadius() : 2288.;
354  double zTileMin = ebBounds ? tilePositiveExtendedBarrel->center().z() -
355  ebBounds->halflengthZ()
356  : 3559.5;
357 
358  keyDim.emplace_back(rTileMin, zTileMin);
359  for (unsigned int i = 0; i < keyDim.size(); i++) {
360  ATH_MSG_VERBOSE("key dimensions:" << i << ":" << keyDim[i].first << ","
361  << keyDim[i].second);
362  }
363 
364  // The Bounds needed for the Gap Volume creation
365  const Trk::CylinderVolumeBounds* solenoidBounds =
366  dynamic_cast<const Trk::CylinderVolumeBounds*>(
367  &(solenoid->volumeBounds()));
368  if (!solenoidBounds)
369  std::abort();
370  const Trk::CylinderVolumeBounds* lArBarrelBounds =
371  dynamic_cast<const Trk::CylinderVolumeBounds*>(
372  &(lArBarrel->volumeBounds()));
373  if (!lArBarrelBounds)
374  std::abort();
375  const Trk::CylinderVolumeBounds* lArPositiveEndcapBounds =
376  dynamic_cast<const Trk::CylinderVolumeBounds*>(
377  &(lArPositiveEndcap->volumeBounds()));
378  if (!lArPositiveEndcapBounds)
379  std::abort();
380  const Trk::CylinderVolumeBounds* lArNegativeEndcapBounds =
381  dynamic_cast<const Trk::CylinderVolumeBounds*>(
382  &(lArNegativeEndcap->volumeBounds()));
383  if (!lArNegativeEndcapBounds)
384  std::abort();
385  const Trk::CylinderVolumeBounds* lArPositiveHecBounds =
386  dynamic_cast<const Trk::CylinderVolumeBounds*>(
387  &(lArPositiveHec->volumeBounds()));
388  if (!lArPositiveHecBounds)
389  std::abort();
390  const Trk::CylinderVolumeBounds* lArPositiveFcalBounds =
391  dynamic_cast<const Trk::CylinderVolumeBounds*>(
392  &(lArPositiveFcal->volumeBounds()));
393  if (!lArPositiveFcalBounds)
394  std::abort();
395  const Trk::CylinderVolumeBounds* lArNegativeFcalBounds =
396  dynamic_cast<const Trk::CylinderVolumeBounds*>(
397  &(lArNegativeFcal->volumeBounds()));
398  if (!lArNegativeFcalBounds)
399  std::abort();
400 
401  const Trk::CylinderVolumeBounds* tileCombinedBounds =
402  dynamic_cast<const Trk::CylinderVolumeBounds*>(
403  &(tileCombined->volumeBounds()));
404  if (!tileCombinedBounds)
405  std::abort();
406 
407  // Create the gap volumes
408  // ======================================================================
409  Trk::TrackingVolume* lArTileCentralSectorGap = nullptr;
410 
411  Trk::TrackingVolume* lArPositiveSectorInnerGap = nullptr;
412  Trk::TrackingVolume* lArPositiveSectorOuterGap = nullptr;
413  Trk::TrackingVolume* lArPositiveSectorOuterGap0 = nullptr;
414  Trk::TrackingVolume* lArCentralPositiveGap = nullptr;
415 
416  Trk::TrackingVolume* lArNegativeSectorInnerGap = nullptr;
417  Trk::TrackingVolume* lArNegativeSectorOuterGap = nullptr;
418  Trk::TrackingVolume* lArNegativeSectorOuterGap0 = nullptr;
419  Trk::TrackingVolume* lArCentralNegativeGap = nullptr;
420 
421  Trk::TrackingVolume* trtSolenoidGap = nullptr;
422 
423  double caloPositiveOuterBoundary = tileCombinedBounds->halflengthZ();
424 
425  double lArPositiveOuterBoundary = lArPositiveFcal->center().z();
426  lArPositiveOuterBoundary += lArPositiveFcalBounds->halflengthZ();
427 
428  // No. 1
429  // building dense volume here
430  Trk::Material tilePositiveSectorInnerGapMaterial =
431  Trk::Material(58., 565., 30.7, 14.6, 0.0025);
432 
433  // calo sensitive volume outer radius/z extent defined (for example) here
434  float caloVolsOuterRadius = tileCombinedBounds->outerRadius();
435  float caloVolsExtendZ = caloPositiveOuterBoundary;
436 
438  // LAr InnerGap sector + beam pipe
439 
440  Trk::Material lArSectorInnerGapMaterial =
441  Trk::Material(361., 1370., 14.5, 7., 0.0009); // ???
442 
443  // create beam pipe volumes for InnerGap/MBTS and return their outer radius
444  float rInnerGapBP = 0.;
445  std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*> innerGapBP =
446  createBeamPipeVolumes(
447  bpCutouts, keyDim[0].second,
448  // lArPositiveEndcap->center().z()-lArPositiveEndcapBounds->halflengthZ(),
449  keyDim.back().second, "InnerGap", rInnerGapBP);
450 
451  double z = 0.5 * (keyDim.back().second + keyDim[0].second);
452 
453  auto mbtsNegLayers = std::make_unique<std::vector<Trk::Layer*>>();
454  auto mbtsPosLayers = std::make_unique<std::vector<Trk::Layer*>>();
455 
456  if (lArPositiveMBTS && lArNegativeMBTS) {
457  // Disc
458  const Trk::CylinderVolumeBounds* mbtsBounds =
459  dynamic_cast<const Trk::CylinderVolumeBounds*>(
460  &(lArPositiveMBTS->volumeBounds()));
461  if (mbtsBounds && m_buildMBTS) {
462  float rmin = mbtsBounds->innerRadius();
463  float rmax = mbtsBounds->outerRadius();
464  // float d = mbtsBounds->halflengthZ();
465  Trk::DiscBounds* dibo = new Trk::DiscBounds(rmin, rmax);
466  // MBTS positions
467  Amg::Transform3D mbtsNegZpos =
468  Amg::Transform3D(Amg::Translation3D(lArNegativeMBTS->center()));
469  Amg::Transform3D mbtsPosZpos =
470  Amg::Transform3D(Amg::Translation3D(lArPositiveMBTS->center()));
471  // create the two Layers ( TODO: add trd surface subarray )
472  Trk::DiscLayer* mbtsNegLayer = new Trk::DiscLayer(
473  mbtsNegZpos, dibo,
474  // mbtsNegLayerSurfArray,
476  Trk::MaterialProperties(m_caloMaterial, 1.), 1.),
477  1.);
478  Trk::DiscLayer* mbtsPosLayer = new Trk::DiscLayer(
479  mbtsPosZpos, dibo->clone(),
480  // mbtsPosLayerSurfArray,
482  Trk::MaterialProperties(m_caloMaterial, 1.), 1.),
483  1. * Gaudi::Units::mm);
484 
485  mbtsNegLayers->push_back(mbtsNegLayer);
486  mbtsPosLayers->push_back(mbtsPosLayer);
487  }
488  }
489 
490  // building inner gap
492  rInnerGapBP,
493  // lArPositiveEndcapBounds->outerRadius(),
494  keyDim[0].first, 0.5 * (keyDim.back().second - keyDim[0].second));
495 
496  Amg::Transform3D* lArG1P =
498  lArPositiveSectorInnerGap = new Trk::TrackingVolume(
499  lArG1P, lArG1Bounds, lArSectorInnerGapMaterial, mbtsPosLayers.release(),
500  "Calo::GapVolumes::LAr::PositiveSectorInnerGap");
501 
502  Amg::Transform3D* lArG1N =
504  lArNegativeSectorInnerGap = new Trk::TrackingVolume(
505  lArG1N, lArG1Bounds->clone(), lArSectorInnerGapMaterial,
506  mbtsNegLayers.release(), "Calo::GapVolumes::LAr::NegativeSectorInnerGap");
507 
508  // glue InnerGap with beam pipe volumes
509  Trk::TrackingVolume* positiveInnerGap = nullptr;
510  if (innerGapBP.first) {
511  std::vector<Trk::TrackingVolume*> volsInnerGap;
512  volsInnerGap.push_back(innerGapBP.first);
513  volsInnerGap.push_back(lArPositiveSectorInnerGap);
514  positiveInnerGap = m_trackingVolumeCreator->createContainerTrackingVolume(
515  volsInnerGap, m_caloMaterial, "Calo::Container::PositiveInnerGap");
516  } else
517  positiveInnerGap = lArPositiveSectorInnerGap;
518 
519  Trk::TrackingVolume* negativeInnerGap = nullptr;
520  if (innerGapBP.second) {
521  std::vector<Trk::TrackingVolume*> volsInnerGap;
522  volsInnerGap.push_back(innerGapBP.second);
523  volsInnerGap.push_back(lArNegativeSectorInnerGap);
524  negativeInnerGap = m_trackingVolumeCreator->createContainerTrackingVolume(
525  volsInnerGap, m_caloMaterial, "Calo::Container::NegativeInnerGap");
526  } else
527  negativeInnerGap = lArNegativeSectorInnerGap;
528 
529  // glue MBTS volumes with ID
530  std::vector<Trk::TrackingVolume*> inBufferVolumes;
531  inBufferVolumes.push_back(negativeInnerGap);
532  inBufferVolumes.push_back(innerVol);
533  inBufferVolumes.push_back(positiveInnerGap);
534 
535  Trk::TrackingVolume* inDetEnclosed =
536  m_trackingVolumeCreator->createContainerTrackingVolume(
537  inBufferVolumes, m_caloMaterial,
538  "Calo::Container::EnclosedInnerDetector");
539 
540  ATH_MSG_DEBUG(" Inner detector enclosed (MBTS volumes)");
541 
543  // LAr endcap sector including the beam pipe
544  // create beam pipe volumes for Endcap and return their outer radius
545  float rEndcapBP = 0.;
546  std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*> endcapBP =
547  createBeamPipeVolumes(bpCutouts, keyDim.back().second,
548  lArPositiveEndcap->center().z() +
549  lArPositiveEndcapBounds->halflengthZ(),
550  "Endcap", rEndcapBP);
551 
552  // build lAr vessel around EC Presampler
553  const Trk::CylinderVolumeBounds* ecpBounds =
554  dynamic_cast<const Trk::CylinderVolumeBounds*>(
555  &(lArPosECPresampler->volumeBounds()));
556  if (!ecpBounds)
557  std::abort();
558 
559  float ecpHz = ecpBounds->halflengthZ();
560  float ecpRmin = ecpBounds->innerRadius();
561  float ecpRmax = ecpBounds->outerRadius();
562 
563  Amg::Transform3D* ecpPos =
564  new Amg::Transform3D(lArPosECPresampler->transform());
565  Amg::Transform3D* ecpNeg =
566  new Amg::Transform3D(lArNegECPresampler->transform());
567 
568  Trk::CylinderVolumeBounds* ecpUpBounds =
569  new Trk::CylinderVolumeBounds(ecpRmax, keyDim.back().first, ecpHz);
570  Trk::CylinderVolumeBounds* ecpDownBounds =
571  new Trk::CylinderVolumeBounds(rEndcapBP, ecpRmin, ecpHz);
572 
573  Trk::TrackingVolume* ecPresamplerCoverPos = new Trk::TrackingVolume(
574  ecpPos, ecpUpBounds, m_Al, dummyLayers, dummyVolumes,
575  "Calo::GapVolumes::LAr::PositiveECPresamplerCover");
576  Trk::TrackingVolume* ecPresamplerCoverNeg = new Trk::TrackingVolume(
577  ecpNeg, ecpUpBounds->clone(), m_Al, dummyLayers, dummyVolumes,
578  "Calo::GapVolumes::LAr::NegativeECPresamplerCover");
579  Trk::TrackingVolume* ecPresamplerInnerPos = new Trk::TrackingVolume(
580  new Amg::Transform3D(*ecpPos), ecpDownBounds, m_Al, dummyLayers,
581  dummyVolumes, "Calo::GapVolumes::LAr::PositiveECPresamplerInner");
582  Trk::TrackingVolume* ecPresamplerInnerNeg = new Trk::TrackingVolume(
583  new Amg::Transform3D(*ecpNeg), ecpDownBounds->clone(), m_Al, dummyLayers,
584  dummyVolumes, "Calo::GapVolumes::LAr::NegativeECPresamplerInner");
585 
586  // glue EC presampler radially
587  std::vector<Trk::TrackingVolume*> volsECP;
588  volsECP.push_back(ecPresamplerInnerPos);
589  volsECP.push_back(lArPosECPresampler);
590  volsECP.push_back(ecPresamplerCoverPos);
591  Trk::TrackingVolume* positiveECP =
592  m_trackingVolumeCreator->createContainerTrackingVolume(
593  volsECP, m_caloMaterial, "Calo::Container::PositiveECPresamplerR");
594  std::vector<Trk::TrackingVolume*> volsECN;
595  volsECN.push_back(ecPresamplerInnerNeg);
596  volsECN.push_back(lArNegECPresampler);
597  volsECN.push_back(ecPresamplerCoverNeg);
598  Trk::TrackingVolume* negativeECP =
599  m_trackingVolumeCreator->createContainerTrackingVolume(
600  volsECN, m_caloMaterial, "Calo::Container::NegativeECPresamplerR");
601 
602  // add surrounding buffers
603  z = lArPosECPresampler->center().z() - ecpHz;
604  float z1 = lArPosECPresampler->center().z() + ecpHz;
605  float z2 =
606  lArPositiveEndcap->center().z() - lArPositiveEndcapBounds->halflengthZ();
608  Amg::Vector3D(0., 0., 0.5 * (z + keyDim.back().second))));
610  Amg::Vector3D(0., 0., -0.5 * (z + keyDim.back().second))));
612  rEndcapBP, keyDim.back().first, 0.5 * (z - keyDim.back().second));
613  Amg::Transform3D* ecOPos = new Amg::Transform3D(
614  Amg::Translation3D(Amg::Vector3D(0., 0., 0.5 * (z1 + z2))));
615  Amg::Transform3D* ecONeg = new Amg::Transform3D(
616  Amg::Translation3D(Amg::Vector3D(0., 0., -0.5 * (z1 + z2))));
618  rEndcapBP, keyDim.back().first, 0.5 * (z2 - z1));
619 
620  Trk::TrackingVolume* ecPresamplerInPos = new Trk::TrackingVolume(
621  ecIPos, ecpIBounds, m_Ar, dummyLayers, dummyVolumes,
622  "Calo::GapVolumes::LAr::PositiveECPresamplerIn");
623  Trk::TrackingVolume* ecPresamplerInNeg = new Trk::TrackingVolume(
624  ecINeg, ecpIBounds->clone(), m_Ar, dummyLayers, dummyVolumes,
625  "Calo::GapVolumes::LAr::NegativeECPresamplerIn");
626  Trk::TrackingVolume* ecPresamplerOutPos = new Trk::TrackingVolume(
627  ecOPos, ecpOBounds, m_Ar, dummyLayers, dummyVolumes,
628  "Calo::GapVolumes::LAr::PositiveECPresamplerOut");
629  Trk::TrackingVolume* ecPresamplerOutNeg = new Trk::TrackingVolume(
630  ecONeg, ecpOBounds->clone(), m_Ar, dummyLayers, dummyVolumes,
631  "Calo::GapVolumes::LAr::NegativeECPresamplerOut");
632 
633  // glue EC presampler in z
634  std::vector<Trk::TrackingVolume*> volECP;
635  volECP.push_back(ecPresamplerInPos);
636  volECP.push_back(positiveECP);
637  volECP.push_back(ecPresamplerOutPos);
638  Trk::TrackingVolume* positiveEP =
639  m_trackingVolumeCreator->createContainerTrackingVolume(
640  volECP, m_caloMaterial, "Calo::Container::PositiveECPresampler");
641  std::vector<Trk::TrackingVolume*> volECN;
642  volECN.push_back(ecPresamplerOutNeg);
643  volECN.push_back(negativeECP);
644  volECN.push_back(ecPresamplerInNeg);
645  Trk::TrackingVolume* negativeEP =
646  m_trackingVolumeCreator->createContainerTrackingVolume(
647  volECN, m_caloMaterial, "Calo::Container::NegativeECPresampler");
648 
649  // build lAr vessel around EMEC
650  ecpHz = lArPositiveEndcapBounds->halflengthZ();
651  ecpRmin = lArPositiveEndcapBounds->innerRadius();
652  ecpRmax = lArPositiveEndcapBounds->outerRadius();
653 
654  Amg::Transform3D* ecPos =
655  new Amg::Transform3D(lArPositiveEndcap->transform());
656  Amg::Transform3D* ecNeg =
657  new Amg::Transform3D(lArNegativeEndcap->transform());
658 
659  Trk::CylinderVolumeBounds* ecUpBounds =
660  new Trk::CylinderVolumeBounds(ecpRmax, keyDim.back().first, ecpHz);
661  Trk::CylinderVolumeBounds* ecDownBounds =
662  new Trk::CylinderVolumeBounds(rEndcapBP, ecpRmin, ecpHz);
663 
664  Trk::TrackingVolume* ecCoverPos = new Trk::TrackingVolume(
665  ecPos, ecUpBounds, m_Ar, dummyLayers, dummyVolumes,
666  "Calo::GapVolumes::LAr::PositiveEndcapCover");
667  Trk::TrackingVolume* ecCoverNeg = new Trk::TrackingVolume(
668  ecNeg, ecUpBounds->clone(), m_Ar, dummyLayers, dummyVolumes,
669  "Calo::GapVolumes::LAr::NegativeEndcapCover");
670  Trk::TrackingVolume* ecInnerPos = new Trk::TrackingVolume(
671  new Amg::Transform3D(*ecPos), ecDownBounds, m_Al, dummyLayers,
672  dummyVolumes, "Calo::GapVolumes::LAr::PositiveEndcapInner");
673  Trk::TrackingVolume* ecInnerNeg = new Trk::TrackingVolume(
674  new Amg::Transform3D(*ecNeg), ecDownBounds->clone(), m_Al, dummyLayers,
675  dummyVolumes, "Calo::GapVolumes::LAr::NegativeEndcapInner");
676 
677  // glue EMEC radially
678  std::vector<Trk::TrackingVolume*> volsEC;
679  volsEC.push_back(ecInnerPos);
680  volsEC.push_back(lArPositiveEndcap);
681  volsEC.push_back(ecCoverPos);
682  Trk::TrackingVolume* positiveEC =
683  m_trackingVolumeCreator->createContainerTrackingVolume(
684  volsEC, m_caloMaterial, "Calo::Container::PositiveEndcapR");
685  std::vector<Trk::TrackingVolume*> volsEN;
686  volsEN.push_back(ecInnerNeg);
687  volsEN.push_back(lArNegativeEndcap);
688  volsEN.push_back(ecCoverNeg);
689  Trk::TrackingVolume* negativeEC =
690  m_trackingVolumeCreator->createContainerTrackingVolume(
691  volsEN, m_caloMaterial, "Calo::Container::NegativeEndcapR");
692 
693  // glue presampler with EMEC
694  std::vector<Trk::TrackingVolume*> volEEP;
695  volEEP.push_back(positiveEP);
696  volEEP.push_back(positiveEC);
697  Trk::TrackingVolume* positiveEEP =
698  m_trackingVolumeCreator->createContainerTrackingVolume(
699  volEEP, m_caloMaterial, "Calo::Container::PositiveEMEC");
700  std::vector<Trk::TrackingVolume*> volEEN;
701  volEEN.push_back(negativeEC);
702  volEEN.push_back(negativeEP);
703  Trk::TrackingVolume* negativeEEP =
704  m_trackingVolumeCreator->createContainerTrackingVolume(
705  volEEN, m_caloMaterial, "Calo::Container::NegativeEMEC");
706 
707  // glue EMEC sector with beam pipe volumes
708 
709  std::vector<Trk::TrackingVolume*> volsEndcapPos;
710  if (endcapBP.first)
711  volsEndcapPos.push_back(endcapBP.first);
712  volsEndcapPos.push_back(positiveEEP);
713 
714  std::unique_ptr<Trk::TrackingVolume> positiveEndcap(
715  m_trackingVolumeCreator->createContainerTrackingVolume(
716  volsEndcapPos, m_caloMaterial, "Calo::Container::PositiveEndcap"));
717 
718  std::vector<Trk::TrackingVolume*> volsEndcapNeg;
719  if (endcapBP.second)
720  volsEndcapNeg.push_back(endcapBP.second);
721  volsEndcapNeg.push_back(negativeEEP);
722 
723  std::unique_ptr<Trk::TrackingVolume> negativeEndcap(
724  m_trackingVolumeCreator->createContainerTrackingVolume(
725  volsEndcapNeg, m_caloMaterial, "Calo::Container::NegativeEndcap"));
726 
728  // Hec sector + beam pipe + lAr cover
729  // create beam pipe volumes for Hec and return their outer radius
730  float rHecBP = 0.;
731  std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*> hecBP =
732  createBeamPipeVolumes(
733  bpCutouts,
734  lArPositiveHec->center().z() - lArPositiveHecBounds->halflengthZ(),
735  lArPositiveHec->center().z() + lArPositiveHecBounds->halflengthZ(),
736  "Hec", rHecBP);
737  // HecInnerGap (new gap volume )
738  Trk::Material lArHecInnerGapMaterial =
739  Trk::Material(390., 1223., 18., 9., 0.0014);
740 
741  // create the Bounds
742  Trk::CylinderVolumeBounds* lArHecInnerGapBounds =
743  new Trk::CylinderVolumeBounds(rHecBP, lArPositiveHecBounds->innerRadius(),
744  lArPositiveHecBounds->halflengthZ());
745 
746  Amg::Transform3D* lArHecPos = new Amg::Transform3D(
747  Amg::Translation3D(Amg::Vector3D(0., 0., lArPositiveHec->center().z())));
748  Amg::Transform3D* lArHecNeg = new Amg::Transform3D(
749  Amg::Translation3D(Amg::Vector3D(0., 0., lArNegativeHec->center().z())));
750 
751  Trk::TrackingVolume* lArPositiveHecInnerGap = new Trk::TrackingVolume(
752  lArHecPos, lArHecInnerGapBounds, m_Al, dummyLayers, dummyVolumes,
753  "Calo::GapVolumes::LAr::PositiveHecInnerGap");
754 
755  Trk::TrackingVolume* lArNegativeHecInnerGap = new Trk::TrackingVolume(
756  lArHecNeg, lArHecInnerGapBounds->clone(), m_Al, dummyLayers, dummyVolumes,
757  "Calo::GapVolumes::LAr::NegativeHecInnerGap");
758  // create the Bounds
759  Trk::CylinderVolumeBounds* lArHecOuterGapBounds =
760  new Trk::CylinderVolumeBounds(lArPositiveHecBounds->outerRadius(),
761  keyDim.back().first,
762  lArPositiveHecBounds->halflengthZ());
763 
764  Trk::TrackingVolume* lArPositiveHecOuterGap = new Trk::TrackingVolume(
765  new Amg::Transform3D(*lArHecPos), lArHecOuterGapBounds, m_Ar, dummyLayers,
766  dummyVolumes, "Calo::GapVolumes::LAr::PositiveHecOuterGap");
767 
768  Trk::TrackingVolume* lArNegativeHecOuterGap = new Trk::TrackingVolume(
769  new Amg::Transform3D(*lArHecNeg), lArHecOuterGapBounds->clone(), m_Ar,
770  dummyLayers, dummyVolumes, "Calo::GapVolumes::LAr::NegativeHecOuterGap");
771 
772  // glue Hec sector with beam pipe volumes
773 
774  std::vector<Trk::TrackingVolume*> volsHecPos;
775  if (hecBP.first)
776  volsHecPos.push_back(hecBP.first);
777  volsHecPos.push_back(lArPositiveHecInnerGap);
778  volsHecPos.push_back(lArPositiveHec);
779  volsHecPos.push_back(lArPositiveHecOuterGap);
780 
781  std::unique_ptr<Trk::TrackingVolume> positiveHec(
782  m_trackingVolumeCreator->createContainerTrackingVolume(
783  volsHecPos, m_caloMaterial, "Calo::Container::PositiveHec"));
784 
785  std::vector<Trk::TrackingVolume*> volsHecNeg;
786  if (hecBP.second)
787  volsHecNeg.push_back(hecBP.second);
788  volsHecNeg.push_back(lArNegativeHecInnerGap);
789  volsHecNeg.push_back(lArNegativeHec);
790  volsHecNeg.push_back(lArNegativeHecOuterGap);
791 
792  std::unique_ptr<Trk::TrackingVolume> negativeHec(
793  m_trackingVolumeCreator->createContainerTrackingVolume(
794  volsHecNeg, m_caloMaterial, "Calo::Container::NegativeHec"));
795 
797  // Fcal sector + beam pipe + lAr cover
798 
799  // create beam pipe volumes for Fcal and return their outer radius
800  float rFcalBP = 0.;
801  std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*> fcalBP =
802  createBeamPipeVolumes(
803  bpCutouts,
804  lArPositiveFcal->center().z() - lArPositiveFcalBounds->halflengthZ(),
805  lArPositiveFcal->center().z() + lArPositiveFcalBounds->halflengthZ(),
806  "Fcal", rFcalBP);
807  // FcalInnerGap (new gap volume )
808  // Trk::Material lArFcalInnerGapMaterial = Trk::Material(390.,
809  // 1223., 40.,18., 0.0014);
810 
811  if (rFcalBP > lArPositiveFcalBounds->innerRadius()) {
812  ATH_MSG_ERROR("PROBLEM : beam pipe collide with Fcal:"
813  << rFcalBP << ">" << lArPositiveFcalBounds->innerRadius()
814  << ", abort");
815  return nullptr;
816  }
817 
818  // create the Bounds
819  Trk::CylinderVolumeBounds* lArFcalInnerGapBounds =
820  new Trk::CylinderVolumeBounds(rFcalBP,
821  lArPositiveFcalBounds->innerRadius(),
822  lArPositiveFcalBounds->halflengthZ());
823 
824  Amg::Transform3D* lArFcalPos = new Amg::Transform3D(
825  Amg::Translation3D(Amg::Vector3D(0., 0., lArPositiveFcal->center().z())));
826  Amg::Transform3D* lArFcalNeg = new Amg::Transform3D(
827  Amg::Translation3D(Amg::Vector3D(0., 0., lArNegativeFcal->center().z())));
828 
829  Trk::TrackingVolume* lArPositiveFcalInnerGap = new Trk::TrackingVolume(
830  lArFcalPos, lArFcalInnerGapBounds, m_Al, dummyLayers, dummyVolumes,
831  "Calo::GapVolumes::LAr::PositiveFcalInnerGap");
832 
833  Trk::TrackingVolume* lArNegativeFcalInnerGap = new Trk::TrackingVolume(
834  lArFcalNeg, lArFcalInnerGapBounds->clone(), m_Al, dummyLayers,
835  dummyVolumes, "Calo::GapVolumes::LAr::NegativeFcalInnerGap");
836 
837  // create the Bounds
838  Trk::CylinderVolumeBounds* lArFcalOuterGapBounds =
839  new Trk::CylinderVolumeBounds(lArPositiveHecBounds->outerRadius(),
840  keyDim.back().first,
841  lArPositiveFcalBounds->halflengthZ());
842 
843  Trk::TrackingVolume* lArPositiveFcalOuterGap = new Trk::TrackingVolume(
844  new Amg::Transform3D(*lArFcalPos), lArFcalOuterGapBounds, m_Ar,
845  dummyLayers, dummyVolumes, "Calo::GapVolumes::LAr::PositiveFcalOuterGap");
846 
847  Trk::TrackingVolume* lArNegativeFcalOuterGap = new Trk::TrackingVolume(
848  new Amg::Transform3D(*lArFcalNeg), lArFcalOuterGapBounds->clone(), m_Ar,
849  dummyLayers, dummyVolumes, "Calo::GapVolumes::LAr::NegativeFcalOuterGap");
850 
851  // glue Fcal sector with beam pipe volumes
852 
853  std::vector<Trk::TrackingVolume*> volsFcalPos;
854  if (fcalBP.first)
855  volsFcalPos.push_back(fcalBP.first);
856  volsFcalPos.push_back(lArPositiveFcalInnerGap);
857  volsFcalPos.push_back(lArPositiveFcal);
858  volsFcalPos.push_back(lArPositiveHecFcalCover);
859  volsFcalPos.push_back(lArPositiveFcalOuterGap);
860 
861  std::unique_ptr<Trk::TrackingVolume> positiveFcal(
862  m_trackingVolumeCreator->createContainerTrackingVolume(
863  volsFcalPos, m_caloMaterial, "Calo::Container::PositiveFcal"));
864 
865  std::vector<Trk::TrackingVolume*> volsFcalNeg;
866  if (fcalBP.second)
867  volsFcalNeg.push_back(fcalBP.second);
868  volsFcalNeg.push_back(lArNegativeFcalInnerGap);
869  volsFcalNeg.push_back(lArNegativeFcal);
870  volsFcalNeg.push_back(lArNegativeHecFcalCover);
871  volsFcalNeg.push_back(lArNegativeFcalOuterGap);
872 
873  std::unique_ptr<Trk::TrackingVolume> negativeFcal(
874  m_trackingVolumeCreator->createContainerTrackingVolume(
875  volsFcalNeg, m_caloMaterial, "Calo::Container::NegativeFcal"));
876 
878  // Outer endcap sector + beam pipe
879 
880  // create beam pipe volumes for Outer sector and return their outer radius
881  float rOutBP = 0.;
882  std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*> outBP =
883  createBeamPipeVolumes(bpCutouts, lArPositiveOuterBoundary,
884  caloPositiveOuterBoundary, "Outer", rOutBP);
885 
886  Trk::Material lArSectorOuterGapMat =
887  Trk::Material(20.5, 723., 64., 28., 0.0084);
888 
889  Trk::CylinderVolumeBounds* lArSectorOuterG0Bounds =
891  rOutBP, 430.,
892  // lArPositiveEndcapBounds->outerRadius(),
893  0.5 * (caloPositiveOuterBoundary - lArPositiveOuterBoundary));
894 
895  Trk::CylinderVolumeBounds* lArSectorOuterG1Bounds =
897  430., keyDim.back().first,
898  // lArPositiveEndcapBounds->outerRadius(),
899  0.5 * (caloPositiveOuterBoundary - lArPositiveOuterBoundary));
900 
901  z = 0.5 * (caloPositiveOuterBoundary + lArPositiveOuterBoundary);
902 
903  Amg::Transform3D* lArSecOutG1P =
905  Amg::Transform3D* lArSecOutG0P =
907 
908  lArPositiveSectorOuterGap0 = new Trk::TrackingVolume(
909  lArSecOutG0P, lArSectorOuterG0Bounds, lArSectorOuterGapMat, dummyLayers,
910  dummyVolumes, "Calo::GapVolumes::LAr::PositiveSectorOuterGap0");
911 
912  lArPositiveSectorOuterGap = new Trk::TrackingVolume(
913  lArSecOutG1P, lArSectorOuterG1Bounds, m_Ar, dummyLayers, dummyVolumes,
914  "Calo::GapVolumes::LAr::PositiveSectorOuterGap");
915 
916  Amg::Transform3D* lArSecOutG1N =
918  Amg::Transform3D* lArSecOutG0N =
920 
921  lArNegativeSectorOuterGap0 =
922  new Trk::TrackingVolume(lArSecOutG0N, lArSectorOuterG0Bounds->clone(),
923  lArSectorOuterGapMat, dummyLayers, dummyVolumes,
924  "Calo::GapVolumes::LAr::NegativeSectorOuterGap0");
925 
926  lArNegativeSectorOuterGap = new Trk::TrackingVolume(
927  lArSecOutG1N, lArSectorOuterG1Bounds->clone(), m_Ar, dummyLayers,
928  dummyVolumes, "Calo::GapVolumes::LAr::NegativeSectorOuterGap");
929 
930  // glue OuterGap with beam pipe volumes
931  std::vector<Trk::TrackingVolume*> volsOuterGapP;
932  if (outBP.first)
933  volsOuterGapP.push_back(outBP.first);
934  volsOuterGapP.push_back(lArPositiveSectorOuterGap0);
935  volsOuterGapP.push_back(lArPositiveSectorOuterGap);
936  std::unique_ptr<Trk::TrackingVolume> positiveOuterGap(
937  m_trackingVolumeCreator->createContainerTrackingVolume(
938  volsOuterGapP, m_caloMaterial, "Calo::Container::PositiveOuterGap"));
939 
940  std::vector<Trk::TrackingVolume*> volsOuterGapN;
941  if (outBP.second)
942  volsOuterGapN.push_back(outBP.second);
943  volsOuterGapN.push_back(lArNegativeSectorOuterGap0);
944  volsOuterGapN.push_back(lArNegativeSectorOuterGap);
945  std::unique_ptr<Trk::TrackingVolume> negativeOuterGap(
946  m_trackingVolumeCreator->createContainerTrackingVolume(
947  volsOuterGapN, m_caloMaterial, "Calo::Container::NegativeOuterGap"));
948 
949  ATH_MSG_DEBUG("Endcap volumes ready");
950 
951  // ++ (ii) lArNegativeSector
952  Trk::TrackingVolume* lArNegativeSector = nullptr;
953  // +++ has 4 sub volumes in Z
954  std::vector<Trk::TrackingVolume*> lArNegativeSectorVolumes;
955  // +++ (A) -> Outer sector
956  lArNegativeSectorVolumes.push_back(negativeOuterGap.release());
957  // +++ (B) -> Fcal sector
958  lArNegativeSectorVolumes.push_back(negativeFcal.release());
959  // +++ (C) -> Hec sector
960  lArNegativeSectorVolumes.push_back(negativeHec.release());
961  // +++ (D) -> Endcap sector
962  lArNegativeSectorVolumes.push_back(negativeEndcap.release());
963  // +++ all exists : create super volume (ii)
964  lArNegativeSector = m_trackingVolumeCreator->createContainerTrackingVolume(
965  lArNegativeSectorVolumes, m_caloMaterial,
966  "Calo::LAr::Container::NegativeSector");
967 
968  // ++ (ii) lArPositiveSector
969  Trk::TrackingVolume* lArPositiveSector = nullptr;
970  // +++ has 4 sub volumes in Z
971  std::vector<Trk::TrackingVolume*> lArPositiveSectorVolumes;
972  // +++ (A) -> Endcap sector
973  lArPositiveSectorVolumes.push_back(positiveEndcap.release());
974  // +++ (B) -> Hec sector
975  lArPositiveSectorVolumes.push_back(positiveHec.release());
976  // +++ (C) -> Fcal sector
977  lArPositiveSectorVolumes.push_back(positiveFcal.release());
978  // +++ (D) -> OuterGap
979  lArPositiveSectorVolumes.push_back(positiveOuterGap.release());
980  // +++ all exists : create super volume (ii)
981  lArPositiveSector = m_trackingVolumeCreator->createContainerTrackingVolume(
982  lArPositiveSectorVolumes, m_caloMaterial,
983  "Calo::LAr::Container::PositiveSector");
984 
986  // central LAr barrel
987  //
988  // solenoid gap
990  keyDim[0].first, solenoidBounds->innerRadius(),
991  solenoidBounds->halflengthZ());
992 
993  // solenoid gap is not completely empty
994  Trk::Material solGapMat(535., 2871., 18.6, 9.1, 0.00038);
995 
996  trtSolenoidGap =
997  new Trk::TrackingVolume(nullptr, trtSolGapBounds, solGapMat, dummyLayers,
998  dummyVolumes, "Calo::GapVolumes::SolenoidGap");
999 
1000  Trk::CylinderVolumeBounds* lArTileCentralG1Bounds =
1001  new Trk::CylinderVolumeBounds(lArBarrelBounds->outerRadius(),
1002  tileCombinedBounds->innerRadius(),
1003  lArBarrelBounds->halflengthZ());
1004 
1005  lArTileCentralSectorGap = new Trk::TrackingVolume(
1006  nullptr, lArTileCentralG1Bounds, m_Ar, dummyLayers, dummyVolumes,
1007  "Calo::GapVolumes::LArTileCentralSectorGap");
1008 
1009  Trk::TrackingVolume* lArCentralBarrelSector = nullptr;
1010  // ++ has 6 sub volumes in R
1011  std::vector<Trk::TrackingVolume*> lArCentralBarrelSectorVolumes;
1012  // ++++ (a) -> solenoid gap
1013  lArCentralBarrelSectorVolumes.push_back(trtSolenoidGap);
1014  // ++++ (b) -> solenoid (exists already)
1015  lArCentralBarrelSectorVolumes.push_back(solenoid);
1016  // ++++ (c) -> solenoidlArPresamplerGap (exists already)
1017  lArCentralBarrelSectorVolumes.push_back(solenoidlArPresamplerGap);
1018  // ++++ (d) -> lArBarrelPresampler (exists already)
1019  lArCentralBarrelSectorVolumes.push_back(lArBarrelPresampler);
1020  // ++++ (e) -> lArBarrel (exists already)
1021  lArCentralBarrelSectorVolumes.push_back(lArBarrel);
1022  // ++++ (f) -> lArTile gap
1023  lArCentralBarrelSectorVolumes.push_back(lArTileCentralSectorGap);
1024  // ++++ all sub volumes exist: build the super volume
1025  lArCentralBarrelSector =
1026  m_trackingVolumeCreator->createContainerTrackingVolume(
1027  lArCentralBarrelSectorVolumes, m_caloMaterial,
1028  "Calo::Containers::LAr::CentralBarrelSector", false, true);
1030  // side buffers
1031  // the Tile Crack volume (TileGap3, enum 17) inserted here
1032  // binned material for Crack : steering in binEta
1033  // TODO turn into 2D binned array
1034  std::vector<Trk::IdentifiedMaterial> matCrack;
1035  // layer material can be adjusted here
1036  int baseID = Trk::GeometrySignature(Trk::Calo) * 1000 + 17;
1037  matCrack.emplace_back(&m_Scint, baseID);
1038  matCrack.emplace_back(&m_caloMaterial, -1);
1039  matCrack.emplace_back(&m_Al, -1);
1040  //
1041  double etadist;
1042  // if TileGap3 goes above 1.6 in eta - it's RUN3 geometry
1043  int nbins =
1044  (caloDDM->is_in(1.65, 0.0, CaloCell_ID::TileGap3, etadist)) ? 6 : 3;
1045  Trk::BinUtility* bun =
1046  new Trk::BinUtility(nbins, -1.8, -1.2, Trk::open, Trk::binEta);
1047  Trk::BinUtility* bup =
1048  new Trk::BinUtility(nbins, 1.2, 1.8, Trk::open, Trk::binEta);
1049  // array of indices
1050  std::vector<std::vector<size_t>> indexP;
1051  std::vector<std::vector<size_t>> indexN;
1052  // binned material for LAr : layer depth per eta bin
1053  std::vector<Trk::BinUtility*> layDN(bun->bins());
1054  std::vector<Trk::BinUtility*> layUP(bup->bins());
1055  double crackZ1 = 3532.;
1056  double crackZ2 = 3540.;
1057  // construct bin utilities
1058  std::vector<float> steps;
1059  for (unsigned int i = 0; i < bup->bins(); i++) {
1060  steps.clear();
1061  std::vector<size_t> indx;
1062  indx.clear();
1063  steps.push_back(crackZ1);
1064  indx.push_back(i < bup->bins() - 1 ? 0 : 1);
1065  steps.push_back(crackZ2);
1066  indx.push_back(2);
1067  steps.push_back(keyDim.back().second);
1069  layUP[i] = zBU;
1070  indexP.push_back(indx);
1071  }
1072 
1073  const Trk::BinnedMaterial* crackBinPos =
1074  new Trk::BinnedMaterial(&m_crackMaterial, bup, layUP, indexP, matCrack);
1075 
1076  Amg::Transform3D* align = nullptr;
1077 
1079  keyDim[0].first, tileCombinedBounds->innerRadius(),
1080  0.5 * (keyDim.back().second - crackZ1));
1081  z = 0.5 * (keyDim.back().second + crackZ1);
1082  Amg::Transform3D* crackPosTransform =
1084 
1086  crackPosTransform, align, crackBoundsPos, crackBinPos, 17,
1087  "Calo::Detectors::Tile::CrackPos");
1088 
1089  for (unsigned int i = 0; i < bun->bins(); i++) {
1090  steps.clear();
1091  std::vector<size_t> indx;
1092  indx.clear();
1093  steps.push_back(-keyDim.back().second);
1094  indx.push_back(2);
1095  steps.push_back(-crackZ2);
1096  indx.push_back(i > 0 ? 0 : 1);
1097  steps.push_back(-crackZ1);
1099  layDN[i] = zBU;
1100  indexN.push_back(indx);
1101  }
1102 
1103  Trk::BinnedMaterial* crackBinNeg =
1104  new Trk::BinnedMaterial(&m_crackMaterial, bun, layDN, indexN, matCrack);
1105 
1106  align = nullptr;
1107 
1108  Amg::Transform3D* crackNegTransform =
1110 
1112  crackNegTransform, align, crackBoundsPos->clone(), crackBinNeg, 17,
1113  "Calo::Detectors::Tile::CrackNeg");
1115 
1116  Trk::CylinderVolumeBounds* lArCentralG1Bounds = new Trk::CylinderVolumeBounds(
1117  keyDim[0].first, tileCombinedBounds->innerRadius(),
1118  0.5 * (crackZ1 - lArBarrelBounds->halflengthZ()));
1119 
1120  z = 0.5 * (crackZ1 + lArBarrelBounds->halflengthZ());
1121  Amg::Transform3D* lArCentralG1P =
1123 
1124  lArCentralPositiveGap = new Trk::TrackingVolume(
1125  lArCentralG1P, lArCentralG1Bounds, m_Ar, dummyLayers, dummyVolumes,
1126  "Calo::GapVolumes::LArCentralPositiveGap");
1127 
1128  Amg::Transform3D* lArCentralG1N =
1130 
1131  lArCentralNegativeGap = new Trk::TrackingVolume(
1132  lArCentralG1N, lArCentralG1Bounds->clone(), m_Ar, dummyLayers,
1133  dummyVolumes, "Calo::GapVolumes::LArCentralNegativeGap");
1134 
1135  // glue laterally
1136  Trk::TrackingVolume* lArCentralSector = nullptr;
1137  // ++ has 5 sub volumes in z
1138  std::vector<Trk::TrackingVolume*> lArCentralSectorVolumes;
1139  // ++++ (a) -> negative crack
1140  lArCentralSectorVolumes.push_back(crackNeg);
1141  // ++++ (b) -> negative gap
1142  lArCentralSectorVolumes.push_back(lArCentralNegativeGap);
1143  // ++++ (c) -> central barrel
1144  lArCentralSectorVolumes.push_back(lArCentralBarrelSector);
1145  // ++++ (d) -> positive gap
1146  lArCentralSectorVolumes.push_back(lArCentralPositiveGap);
1147  // ++++ (e) -> positive crack
1148  lArCentralSectorVolumes.push_back(crackPos);
1149  // ++++ all sub volumes exist: build the super volume
1150  lArCentralSector = m_trackingVolumeCreator->createContainerTrackingVolume(
1151  lArCentralSectorVolumes, m_caloMaterial,
1152  "Calo::Containers::LAr::CentralSector");
1153 
1154  // glue with ID sector
1155  Trk::TrackingVolume* caloCentralSector = nullptr;
1156  // ++ has 2 sub volumes in R
1157  std::vector<Trk::TrackingVolume*> caloCentralSectorVolumes;
1158  // ++++ (a) -> ID sector
1159  caloCentralSectorVolumes.push_back(inDetEnclosed);
1160  // ++++ (b) -> LAr sector
1161  caloCentralSectorVolumes.push_back(lArCentralSector);
1162  // ++++ all sub volumes exist: build the super volume
1163  caloCentralSector = m_trackingVolumeCreator->createContainerTrackingVolume(
1164  caloCentralSectorVolumes, m_caloMaterial,
1165  "Calo::Containers::CaloCentralSector");
1166 
1168 
1169  // glue laterally with endcaps
1170  Trk::TrackingVolume* lArCombined = nullptr;
1171  // ++ has 3 sub volumes in z
1172  std::vector<Trk::TrackingVolume*> lArCombinedVolumes;
1173  // ++++ (a) -> negative endcap
1174  lArCombinedVolumes.push_back(lArNegativeSector);
1175  // ++++ (b) -> barrel
1176  lArCombinedVolumes.push_back(caloCentralSector);
1177  // ++++ (a) -> positive endcap
1178  lArCombinedVolumes.push_back(lArPositiveSector);
1179  // ++++ all sub volumes exist: build the super volume
1180  lArCombined = m_trackingVolumeCreator->createContainerTrackingVolume(
1181  lArCombinedVolumes, m_caloMaterial, "Calo::Containers::LAr::Combined");
1182 
1183  // glue with LAr sector
1184  Trk::TrackingVolume* caloCombined = nullptr;
1185  // ++ has 2 sub volumes in R
1186  std::vector<Trk::TrackingVolume*> caloVolumes;
1187  // ++++ (a) -> LAr sector
1188  caloVolumes.push_back(lArCombined);
1189  // ++++ (b) -> Tile sector
1190  caloVolumes.push_back(tileCombined);
1191  // ++++ all sub volumes exist: build the super volume
1192  caloCombined = m_trackingVolumeCreator->createContainerTrackingVolume(
1193  caloVolumes, m_caloMaterial, "Calo::Containers::CombinedCalo");
1194 
1196 
1197  // build the radial buffer volume to synchronize the radial envelope
1198  // dimensions
1199  Trk::TrackingVolume* centralBuffer = nullptr;
1200  Trk::TrackingVolume* ecPosBuffer = nullptr;
1201  Trk::TrackingVolume* ecNegBuffer = nullptr;
1202 
1203  if (caloVolsOuterRadius > caloDefaultRadius) {
1205  "Calo volumes exceeds envelope radius: adjusting envelope "
1206  "(de-synchronizing...)");
1207  caloDefaultRadius = caloVolsOuterRadius;
1208  }
1209 
1210  if (caloVolsOuterRadius < caloDefaultRadius) {
1212  "Build radial buffer to synchronize the boundaries in between R "
1213  << caloVolsOuterRadius << " and " << caloDefaultRadius);
1214 
1215  Trk::CylinderVolumeBounds* centralSynBounds = new Trk::CylinderVolumeBounds(
1216  caloVolsOuterRadius, caloDefaultRadius, caloVolsExtendZ);
1217  centralBuffer = new Trk::TrackingVolume(
1218  nullptr, centralSynBounds, m_caloMaterial, dummyLayers, dummyVolumes,
1219  "Calo::GapVolumes::EnvelopeBuffer");
1220  }
1221 
1222  if (caloVolsExtendZ < caloDefaultHalflengthZ) {
1224  "Build longitudinal buffers to synchronize the boundaries in between Z "
1225  << caloVolsExtendZ << " and " << caloDefaultHalflengthZ);
1226 
1228  0., caloDefaultRadius,
1229  0.5 * (caloDefaultHalflengthZ - caloVolsExtendZ));
1230  // endcap buffers not empty
1231  Trk::Material ecBuffMat(53. / 0.38, 355. / 0.38, 20., 10.,
1232  0.0053 * pow(0.38, 3));
1233 
1234  float zPos = 0.5 * (caloDefaultHalflengthZ + caloVolsExtendZ);
1235  ecPosBuffer = new Trk::TrackingVolume(
1237  endcapSynBounds, m_Ar, dummyLayers, dummyVolumes,
1238  "Calo::GapVolumes::PosECBuffer");
1239 
1240  ecNegBuffer = new Trk::TrackingVolume(
1241  new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0., 0., -zPos))),
1242  endcapSynBounds->clone(), m_Ar, dummyLayers, dummyVolumes,
1243  "Calo::GapVolumes::NegECBuffer");
1244  }
1245 
1247  "All gap volumes for the Calorimeter created. Starting to build Volume "
1248  "Hiearchy.");
1249 
1251 
1252  ATH_MSG_VERBOSE("Resolve MS cutouts:");
1253 
1254  // resolve number of additional cutout volumes
1255  int nCutVol = 0;
1256  std::vector<float> zCutStep;
1257  std::vector<float> rCutStep;
1258  if (msCutouts.size() > 1) {
1259  zCutStep.push_back(msCutouts[0].second);
1260  rCutStep.push_back(msCutouts[0].first);
1261  for (unsigned int i = 1; i < msCutouts.size(); i++) {
1262  if (msCutouts[i].second == zCutStep.back())
1263  rCutStep.push_back(msCutouts[i].first);
1264  else
1265  zCutStep.push_back(msCutouts[i].second);
1266  }
1267  nCutVol = zCutStep.size() - 1;
1268  }
1269  if (nCutVol > 0)
1270  ATH_MSG_VERBOSE(nCutVol << " MS cutout volume(s) required ");
1271 
1272  std::vector<Trk::TrackingVolume*> forwardCutoutVols;
1273  std::vector<Trk::TrackingVolume*> backwardCutoutVols;
1274 
1275  // cutout region not empty
1276  std::vector<Trk::Material> cutOutMat;
1277  cutOutMat.emplace_back(19.9, 213., 50., 23.,
1278  0.0065); // 3.5 Fe + 1 Ar : verify
1279  cutOutMat.push_back(m_caloMaterial);
1280  // cutOutMat.push_back(Trk::Material(18.74, 200.9, 52.36, 24.09, 0.0069));
1281 
1282  if (nCutVol > 0) {
1283  // loop over zCutStep, rCutStep[0] gives the fixed outer radius, rCutStep[i]
1284  // the cutout radius for ith volume
1285  float rout = rCutStep[0];
1286  float zlow = zCutStep[0];
1287  for (unsigned int i = 1; i < zCutStep.size(); i++) {
1288  float zup = zCutStep[i];
1289  float rcut = rCutStep[i];
1290  std::stringstream ss;
1291  ss << i;
1292  // get beam pipe volumes
1293  float rCutOutBP = 0.;
1294  std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*> cutOutBP =
1295  createBeamPipeVolumes(bpCutouts, zlow, zup, "CutOuts" + ss.str(),
1296  rCutOutBP);
1297 
1298  // build inner part ( -> Calo )
1299  unsigned int mindex = i > 1 ? 1 : i;
1300 
1301  Trk::CylinderVolumeBounds* cutInBounds =
1302  new Trk::CylinderVolumeBounds(rCutOutBP, rcut, 0.5 * (zup - zlow));
1303  Trk::TrackingVolume* caloInPos = new Trk::TrackingVolume(
1304  new Amg::Transform3D(
1305  Amg::Translation3D(Amg::Vector3D(0., 0., 0.5 * (zup + zlow)))),
1306  cutInBounds, cutOutMat[mindex], dummyLayers, dummyVolumes,
1307  "Calo::GapVolumes::CaloPositiveCutIn" + ss.str());
1308  Trk::TrackingVolume* caloInNeg = new Trk::TrackingVolume(
1309  new Amg::Transform3D(
1310  Amg::Translation3D(Amg::Vector3D(0., 0., -0.5 * (zup + zlow)))),
1311  cutInBounds->clone(), cutOutMat[mindex], dummyLayers, dummyVolumes,
1312  "Calo::GapVolumes::CaloNegativeCutIn" + ss.str());
1313  // build cutout ( -> MS ) : geometry signature needs to be resolved later
1314  // : follow naming convention
1315  Trk::CylinderVolumeBounds* cutOutBounds =
1316  new Trk::CylinderVolumeBounds(rcut, rout, 0.5 * (zup - zlow));
1317  Trk::TrackingVolume* caloOutPos = new Trk::TrackingVolume(
1318  new Amg::Transform3D(
1319  Amg::Translation3D(Amg::Vector3D(0., 0., 0.5 * (zup + zlow)))),
1320  cutOutBounds, m_caloMaterial, dummyLayers, dummyVolumes,
1321  "Muon::GapVolumes::CaloPositiveCutOut" + ss.str());
1322  Trk::TrackingVolume* caloOutNeg = new Trk::TrackingVolume(
1323  new Amg::Transform3D(
1324  Amg::Translation3D(Amg::Vector3D(0., 0., -0.5 * (zup + zlow)))),
1325  cutOutBounds->clone(), m_caloMaterial, dummyLayers, dummyVolumes,
1326  "Muon::GapVolumes::CaloNegativeCutOut" + ss.str());
1327 
1328  // sign
1329  caloOutPos->sign(Trk::MS);
1330  caloOutNeg->sign(Trk::MS);
1331 
1332  // glue radially and save for final gluing
1333  std::vector<Trk::TrackingVolume*> cvPos;
1334  cvPos.push_back(cutOutBP.first);
1335  cvPos.push_back(caloInPos);
1336  cvPos.push_back(caloOutPos);
1337  Trk::TrackingVolume* cutOutPos =
1338  m_trackingVolumeCreator->createContainerTrackingVolume(
1339  cvPos, m_caloMaterial,
1340  "Calo::GapVolumes::CaloPositiveCutoutVolume" + ss.str());
1341  forwardCutoutVols.push_back(cutOutPos);
1342  //
1343  std::vector<Trk::TrackingVolume*> cvNeg;
1344  cvNeg.push_back(cutOutBP.second);
1345  cvNeg.push_back(caloInNeg);
1346  cvNeg.push_back(caloOutNeg);
1347  Trk::TrackingVolume* cutOutNeg =
1348  m_trackingVolumeCreator->createContainerTrackingVolume(
1349  cvNeg, m_caloMaterial,
1350  "Calo::GapVolumes::CaloNegativeCutoutVolume" + ss.str());
1351  backwardCutoutVols.insert(backwardCutoutVols.begin(), cutOutNeg);
1352 
1353  zlow = zup;
1354  }
1355  }
1356 
1358 
1359  if (!centralBuffer) { //(XX)
1360  // all volumes exist : create the super volume at top level
1361  calorimeter = caloCombined;
1362 
1363  } else { //(X)
1364 
1365  std::vector<Trk::TrackingVolume*> envRVols;
1366  envRVols.push_back(caloCombined);
1367  envRVols.push_back(centralBuffer);
1368 
1369  // add cutouts - final step
1370  if (!forwardCutoutVols.empty() || ecNegBuffer) {
1371 
1372  Trk::TrackingVolume* caloRVolume =
1373  m_trackingVolumeCreator->createContainerTrackingVolume(
1374  envRVols, m_caloMaterial, "Calo::Containers::CombinedRCalo");
1375  std::vector<Trk::TrackingVolume*> envZVols;
1376  envZVols.reserve(backwardCutoutVols.size());
1377  for (auto& backwardCutoutVol : backwardCutoutVols)
1378  envZVols.push_back(backwardCutoutVol);
1379  if (ecNegBuffer)
1380  envZVols.push_back(ecNegBuffer);
1381  envZVols.push_back(caloRVolume);
1382  if (ecPosBuffer)
1383  envZVols.push_back(ecPosBuffer);
1384  for (auto& forwardCutoutVol : forwardCutoutVols)
1385  envZVols.push_back(forwardCutoutVol);
1386 
1387  calorimeter = m_trackingVolumeCreator->createContainerTrackingVolume(
1388  envZVols, m_caloMaterial, m_exitVolume);
1389 
1390  } else { // if no cutouts or endcap buffers, this is the top calo volume
1391 
1392  calorimeter = m_trackingVolumeCreator->createContainerTrackingVolume(
1393  envRVols, m_caloMaterial, m_exitVolume);
1394  }
1395  }
1396 
1398  "TrackingVolume 'Calorimeter' built successfully. Wrap it in "
1399  "TrackingGeometry.");
1400 
1401  delete lArVolumes;
1402  lArVolumes = nullptr;
1403  delete tileVolumes;
1404  tileVolumes = nullptr;
1405 
1406  auto caloTrackingGeometry =
1407  std::make_unique<Trk::TrackingGeometry>(calorimeter);
1408 
1409  if (msgLvl(MSG::VERBOSE) && caloTrackingGeometry){
1410  caloTrackingGeometry->printVolumeHierarchy(msg(MSG::VERBOSE));
1411  }
1412 
1413  if (m_indexStaticLayers && caloTrackingGeometry){
1414  caloTrackingGeometry->indexStaticLayers(signature());
1415  }
1416 
1417  return caloTrackingGeometry;
1418 }
1419 
1421  Trk::LayerIndexSampleMap& licsMap,
1422  const std::vector<CaloCell_ID::CaloSample>& ccid, const Trk::TrackingVolume& vol,
1423  int side) const {
1424 
1425  ATH_MSG_VERBOSE("[+] Registering layers of TrackingVolume '"
1426  << vol.volumeName() << "' in LayerIndex/CaloCell_ID map");
1427 
1428  // get the confined Layers from the TrackingVolume
1429  const Trk::LayerArray* confinedLayers = vol.confinedLayers();
1430  if (!confinedLayers)
1431  return;
1432 
1434  confinedLayers->arrayObjects();
1436  layerObjects.begin();
1438  layerObjects.end();
1439 
1440  // now pick out the material layers (and skip the navigation ones)
1441  std::vector<const Trk::Layer*> materialLayers;
1442  for (; layerObjIter != layerObjEnd; ++layerObjIter)
1443  if ((*layerObjIter)->layerMaterialProperties())
1444  materialLayers.push_back((*layerObjIter));
1445 
1446  unsigned int matLaySize = materialLayers.size();
1447  unsigned int ccidSize = ccid.size();
1448 
1449  ATH_MSG_VERBOSE("[+] Found " << matLaySize << " material layers ( "
1450  << ccidSize << " CaloSample ids )");
1451  if (matLaySize != ccidSize)
1452  return;
1453 
1454  // everything's fine for side > 0
1455  if (side > 0) {
1456  // match 1-to-1
1457  std::vector<const Trk::Layer*>::const_iterator layerIt = materialLayers.begin();
1458  std::vector<const Trk::Layer*>::const_iterator layerItEnd = materialLayers.end();
1459  std::vector<CaloCell_ID::CaloSample>::const_iterator ccidIt = ccid.begin();
1460  std::vector<CaloCell_ID::CaloSample>::const_iterator ccidItEnd = ccid.end();
1461 
1462  for (; layerIt != layerItEnd && ccidIt != ccidItEnd; ++layerIt, ++ccidIt)
1463  licsMap.insert(std::make_pair((*layerIt)->layerIndex(), int(*ccidIt)));
1464 
1465  } else {
1466  // the order needs to be reversed, because TG has z-ordering positive
1467  // defined
1468 
1469  std::vector<CaloCell_ID::CaloSample>::const_iterator ccidIt = ccid.begin();
1470  std::vector<CaloCell_ID::CaloSample>::const_iterator ccidItEnd = ccid.end();
1471 
1472  for (; ccidIt != ccidItEnd; ++ccidIt, --matLaySize)
1473  licsMap.insert(std::make_pair(
1474  (materialLayers[matLaySize - 1])->layerIndex(), int(*ccidIt)));
1475  }
1476 }
1477 
1478 std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*>
1480  const RZPairVector& bpCutouts, float zmin, float zmax,
1481  const std::string& name, float& outerRadius) const {
1482  outerRadius = 0.;
1483 
1484  // dummy objects
1485  Trk::LayerArray* dummyLayers = nullptr;
1486  Trk::TrackingVolumeArray* dummyVolumes = nullptr;
1487 
1488  // beam pipe thickness along the z distance
1489  if (bpCutouts.empty()) {
1490  return std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*>(0, 0);
1491  }
1492 
1493  RZPairVector dim;
1494  dim.emplace_back(bpCutouts[0].first, zmin);
1495  float rOut = bpCutouts[0].first;
1496  for (const auto& bpCutout : bpCutouts) {
1497  if (bpCutout.second <= dim[0].second)
1498  dim[0].first = bpCutout.first;
1499  else if (bpCutout.second <= zmax)
1500  dim.push_back(bpCutout);
1501  if (bpCutout.second <= zmax)
1502  rOut = bpCutout.first;
1503  }
1504 
1505  if (dim.back().second < zmax)
1506  dim.emplace_back(rOut, zmax);
1507 
1508  if (dim.size() == 2) { // simple case
1509 
1510  outerRadius = dim[0].first;
1511 
1512  Trk::CylinderVolumeBounds* bpBounds =
1513  new Trk::CylinderVolumeBounds(0., outerRadius, 0.5 * (zmax - zmin));
1514 
1515  Amg::Transform3D* bpPos = new Amg::Transform3D(
1516  Amg::Translation3D(Amg::Vector3D(0., 0., 0.5 * (zmin + zmax))));
1517 
1518  Trk::TrackingVolume* bpVolPos =
1519  new Trk::TrackingVolume(bpPos, bpBounds, m_caloMaterial, dummyLayers,
1520  dummyVolumes, "BeamPipe::Positive" + name);
1521 
1522  Amg::Transform3D* bpNeg = new Amg::Transform3D(
1523  Amg::Translation3D(Amg::Vector3D(0., 0., -0.5 * (zmin + zmax))));
1524 
1525  Trk::TrackingVolume* bpVolNeg = new Trk::TrackingVolume(
1526  bpNeg, bpBounds->clone(), m_caloMaterial, dummyLayers, dummyVolumes,
1527  "BeamPipe::Negative" + name);
1528 
1529  // geometry signature
1530  bpVolPos->sign(Trk::BeamPipe);
1531  bpVolNeg->sign(Trk::BeamPipe);
1532 
1533  return std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*>(bpVolPos,
1534  bpVolNeg);
1535  }
1536 
1537  // cutout included
1538 
1539  outerRadius = dim[0].first;
1540 
1541  // find rMax
1542  for (unsigned int i = 1; i < dim.size(); i++)
1543  if (dim[i].first > outerRadius)
1544  outerRadius = dim[i].first;
1545 
1546  // loop over z sections, prepare volumes for gluing
1547  std::vector<Trk::TrackingVolume*> posVols;
1548 
1549  for (unsigned int i = 0; i < dim.size() - 1; i++) {
1550 
1551  if (dim[i].second == dim[i + 1].second)
1552  continue;
1553 
1554  // beam pipe volume
1556  0., dim[i].first, 0.5 * (dim[i + 1].second - dim[i].second));
1557 
1559  Amg::Vector3D(0., 0., 0.5 * (dim[i + 1].second + dim[i].second))));
1560 
1561  Trk::TrackingVolume* bpVolPos =
1562  new Trk::TrackingVolume(bpPos, bpBounds, m_caloMaterial, dummyLayers,
1563  dummyVolumes, "BeamPipe::Positive" + name);
1564  bpVolPos->sign(Trk::BeamPipe);
1565 
1566  Trk::TrackingVolume* bpVolGap = nullptr;
1567  if (dim[i].first < outerRadius) {
1568 
1570  dim[i].first, outerRadius, 0.5 * (dim[i + 1].second - dim[i].second));
1571 
1572  Amg::Transform3D* bpPB = new Amg::Transform3D(*bpPos);
1573 
1574  bpVolGap = new Trk::TrackingVolume(bpPB, bpGB, m_caloMaterial,
1575  dummyLayers, dummyVolumes,
1576  "Calo::GapVolumes::Positive" + name);
1577  }
1578 
1579  Trk::TrackingVolume* bpSector = bpVolPos;
1580 
1581  if (bpVolGap) {
1582  std::vector<Trk::TrackingVolume*> gapVols;
1583  gapVols.push_back(bpVolPos);
1584  gapVols.push_back(bpVolGap);
1585  bpSector = m_trackingVolumeCreator->createContainerTrackingVolume(
1586  gapVols, m_caloMaterial, "Calo::Container::PositiveBPSector" + name);
1587  }
1588  posVols.push_back(bpSector);
1589  }
1590 
1591  Trk::TrackingVolume* bpPosSector =
1592  m_trackingVolumeCreator->createContainerTrackingVolume(
1593  posVols, m_caloMaterial, "Calo::Container::PositiveBP" + name);
1594 
1595  // loop over z sections, prepare volumes for gluing
1596  std::vector<Trk::TrackingVolume*> negVols;
1597 
1598  for (unsigned int i = 0; i < dim.size() - 1; i++) {
1599 
1600  float zmax2 = -1. * (dim[i].second);
1601  float zmin2 = -1. * (dim[i + 1].second);
1602 
1603  if (zmin2 == zmax2)
1604  continue;
1605 
1606  // beam pipe volume
1607  Trk::CylinderVolumeBounds* bpBounds =
1608  new Trk::CylinderVolumeBounds(0., dim[i].first, 0.5 * (zmax2 - zmin2));
1609 
1610  Amg::Transform3D* bpNeg = new Amg::Transform3D(
1611  Amg::Translation3D(Amg::Vector3D(0., 0., 0.5 * (zmin2 + zmax2))));
1612 
1613  Trk::TrackingVolume* bpVolNeg =
1614  new Trk::TrackingVolume(bpNeg, bpBounds, m_caloMaterial, dummyLayers,
1615  dummyVolumes, "BeamPipe::Negative" + name);
1616  bpVolNeg->sign(Trk::BeamPipe);
1617 
1618  Trk::TrackingVolume* bpVolGap =
1619  dim[i].first < outerRadius
1620  ? new Trk::TrackingVolume(
1621  new Amg::Transform3D(*bpNeg),
1622  new Trk::CylinderVolumeBounds(dim[i].first, outerRadius,
1623  0.5 * (zmax2 - zmin2)),
1624  m_caloMaterial, dummyLayers, dummyVolumes,
1625  "Calo::GapVolumes::Negative" + name)
1626  : nullptr;
1627 
1628  Trk::TrackingVolume* bpSector = bpVolNeg;
1629 
1630  if (bpVolGap) {
1631  std::vector<Trk::TrackingVolume*> gapVols;
1632  gapVols.push_back(bpVolNeg);
1633  gapVols.push_back(bpVolGap);
1634  bpSector = m_trackingVolumeCreator->createContainerTrackingVolume(
1635  gapVols, m_caloMaterial, "Calo::Container::NegativeBPSector" + name);
1636  }
1637 
1638  if (negVols.empty())
1639  negVols.push_back(bpSector);
1640  else
1641  negVols.insert(negVols.begin(), bpSector);
1642  }
1643 
1644  Trk::TrackingVolume* bpNegSector =
1645  m_trackingVolumeCreator->createContainerTrackingVolume(
1646  negVols, m_caloMaterial, "Calo::Container::NegativeBP" + name);
1647 
1648  return std::pair<Trk::TrackingVolume*, Trk::TrackingVolume*>(bpPosSector,
1649  bpNegSector);
1650 }
1651 
BinnedMaterial.h
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
TrapezoidBounds.h
GeoAlignmentStore
Ensure that the extensions for the Vector3D are properly loaded.
Definition: GeoAlignmentStore.h:24
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
DiscBounds.h
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
MaterialProperties.h
RZPairVector
std::vector< RZPair > RZPairVector
Definition: RZPair.h:18
Trk::binZ
@ binZ
Definition: BinningType.h:49
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
Calo::CaloTrackingGeometryBuilderImpl::initialize
virtual StatusCode initialize() override
AlgTool initailize method.
Definition: CaloTrackingGeometryBuilderImpl.cxx:47
BinnedArray.h
Calo::CaloTrackingGeometryBuilderImpl::createTrackingGeometry
std::unique_ptr< Trk::TrackingGeometry > createTrackingGeometry(Trk::TrackingVolume *innerVol, const CaloDetDescrManager *caloDDM, const GeoAlignmentStore *geoAlign) const
TrackingGeometry Interface method.
Definition: CaloTrackingGeometryBuilderImpl.cxx:96
Trk::BinnedMaterial
Definition: BinnedMaterial.h:38
BinUtility.h
DiscLayer.h
VolumeBounds.h
HomogeneousLayerMaterial.h
BinnedArray1D1D.h
Calo::CaloTrackingGeometryBuilderImpl::registerInLayerIndexCaloSampleMap
void registerInLayerIndexCaloSampleMap(Trk::LayerIndexSampleMap &licsMAp, const std::vector< CaloCell_ID::CaloSample > &ccid, const Trk::TrackingVolume &vol, int side=1) const
method to establish a link between the LayerIndex and the CaloCell_ID in an associative container
Definition: CaloTrackingGeometryBuilderImpl.cxx:1420
Trk::binEta
@ binEta
Definition: BinningType.h:54
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CaloTrackingGeometryBuilderImpl.h
Trk::Calo
@ Calo
Definition: GeometrySignature.h:28
CaloCell_ID_FCS::TileGap3
@ TileGap3
Definition: FastCaloSim_CaloCell_ID.h:36
ILayerArrayCreator.h
Trk::BinUtility::bins
size_t bins(size_t ba=0) const
Number of bins.
Definition: BinUtility.h:223
Trk::BeamPipe
@ BeamPipe
Definition: GeometrySignature.h:27
Trk::LayerIndexSampleMap
std::map< Trk::LayerIndex, int > LayerIndexSampleMap
Definition: LayerIndexSampleMap.h:29
TRT::Hit::side
@ side
Definition: HitInfo.h:83
Trk::MS
@ MS
Definition: GeometrySignature.h:29
Trk::TrackingVolume::confinedLayers
const LayerArray * confinedLayers() const
Return the subLayer array.
Calo::CaloTrackingGeometryBuilderImpl::~CaloTrackingGeometryBuilderImpl
virtual ~CaloTrackingGeometryBuilderImpl()
Destructor.
GeometryStatics.h
CylinderVolumeBounds.h
Trk::GeometrySignature
GeometrySignature
Definition: GeometrySignature.h:24
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
beamspotman.steps
int steps
Definition: beamspotman.py:505
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::DiscBounds::clone
virtual DiscBounds * clone() const override final
Virtual constructor.
Calo::CaloTrackingGeometryBuilderImpl::createBeamPipeVolumes
std::pair< Trk::TrackingVolume *, Trk::TrackingVolume * > createBeamPipeVolumes(const RZPairVector &bpCutouts, float, float, const std::string &, float &) const
method to build enclosed beam pipe volumes
Definition: CaloTrackingGeometryBuilderImpl.cxx:1479
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Trk::CylinderVolumeBounds::halflengthZ
double halflengthZ() const
This method returns the halflengthZ.
Definition: CylinderVolumeBounds.h:207
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
Trk::Volume::center
const Amg::Vector3D & center() const
returns the center of the volume
Definition: Volume.h:86
plotting.yearwise_luminosity_vs_mu.bins
bins
Definition: yearwise_luminosity_vs_mu.py:30
Trk::DiscLayer
Definition: DiscLayer.h:45
SharedObject.h
Trk::BinUtility
Definition: BinUtility.h:39
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
IOVInfiniteRange.h
Trk::TrackingVolume::volumeName
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
GlueVolumesDescriptor.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
Trk::CylinderVolumeBounds::outerRadius
double outerRadius() const
This method returns the outer radius.
Definition: CylinderVolumeBounds.h:191
Trk::BinnedArray::arrayObjects
virtual BinnedArraySpan< T *const > arrayObjects()=0
Return all objects of the Array non-const we can still modify the T.
Trk::Volume::transform
const Amg::Transform3D & transform() const
Return methods for geometry transform.
Definition: Volume.h:81
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
CaloDetDescrManager_Base::is_in
bool is_in(double eta, double phi, CaloCell_ID::CaloSample sample, double &etadist) const
return true if direction eta,phi crosses ANY of the corresponding descriptors
Definition: CaloDetDescrManager.cxx:1348
Trk::open
@ open
Definition: BinningType.h:40
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
IDynamicLayerCreator.h
Trk::MaterialProperties
Definition: MaterialProperties.h:40
TrackingVolume.h
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
Trk::CylinderVolumeBounds::innerRadius
double innerRadius() const
This method returns the inner radius.
Definition: CylinderVolumeBounds.h:187
Calo::CaloTrackingGeometryBuilderImpl::CaloTrackingGeometryBuilderImpl
CaloTrackingGeometryBuilderImpl(const std::string &, const std::string &, const IInterface *)
Constructor.
Definition: CaloTrackingGeometryBuilderImpl.cxx:37
Trk::TrackingVolume::sign
void sign(GeometrySignature signat, GeometryType gtype=Static)
sign the volume - the geometry builder has to do that
Definition: TrackingVolume.cxx:941
DeMoScan.first
bool first
Definition: DeMoScan.py:536
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
Trk::Volume::volumeBounds
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
Definition: Volume.h:97
DiscSurface.h
TrackingGeometry.h
Trk::Material
Definition: Material.h:116
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Trk::BinnedArray
Definition: BinnedArray.h:38
AthAlgTool
Definition: AthAlgTool.h:26
Trk::HomogeneousLayerMaterial
Definition: HomogeneousLayerMaterial.h:53
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
Trk::TrackingVolume
Definition: TrackingVolume.h:121
Trk::CylinderVolumeBounds::clone
CylinderVolumeBounds * clone() const override
Virtual constructor.
Definition: CylinderVolumeBounds.h:171
Material
@ Material
Definition: MaterialTypes.h:8
AlignableTrackingVolume.h
Trk::BinnedArraySpan
std::span< T > BinnedArraySpan
Definition: BinnedArray.h:34
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
Trk::DiscBounds
Definition: DiscBounds.h:44
Trk::TrackingVolume::screenDump
void screenDump(MsgStream &msg) const
Definition: TrackingVolume.cxx:1506
Trk::AlignableTrackingVolume
Definition: AlignableTrackingVolume.h:36