Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
LArVolumeBuilder.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 // LArVolumeBuilder.cxx, (c) ATLAS Detector software
8 
9 // Calo
10 #include "LArVolumeBuilder.h"
11 // LAr
13 // CaloDepth
16 // GeoModel
17 #include "GeoModelKernel/GeoFullPhysVol.h"
18 #include "GeoModelKernel/GeoLogVol.h"
19 #include "GeoModelKernel/GeoShape.h"
20 #include "GeoModelKernel/GeoTubs.h"
21 #include "GeoModelKernel/GeoTube.h"
22 #include "GeoModelKernel/GeoPcon.h"
23 #include "GeoModelKernel/GeoTrd.h"
24 #include "GeoModelKernel/GeoMaterial.h"
28 // Trk
36 #include "TrkGeometry/Material.h"
38 #include "TrkGeometry/DiscLayer.h"
45 #include "TrkSurfaces/DiscBounds.h"
48 
49 // constructor
50 LAr::LArVolumeBuilder::LArVolumeBuilder(const std::string& t, const std::string& n, const IInterface* p) :
51  AthAlgTool(t,n,p)
52 {
53  declareInterface<Trk::ICaloTrackingVolumeBuilder>(this);
54 }
55 
56 // destructor
57 LAr::LArVolumeBuilder::~ LArVolumeBuilder()
58 = default;
59 
60 
61 // Athena standard methods
62 // initialize
64 {
65  // Retrieve the tracking volume helper
66  ATH_CHECK(m_lArTrackingVolumeHelper.retrieve());
67  ATH_MSG_DEBUG( "Retrieved tool " << m_lArTrackingVolumeHelper );
68 
69  // Retrieve the volume creator
70  ATH_CHECK(m_trackingVolumeCreator.retrieve());
71  ATH_MSG_DEBUG( "Retrieved tool " << m_trackingVolumeCreator );
72 
73  if(m_useCaloSurfBuilder){
74  ATH_CHECK(m_calosurf.retrieve());
75  ATH_MSG_DEBUG( "Retrieved tool " << m_calosurf );
76  }
77 
78  ATH_MSG_DEBUG( name() << " initialize() successful" );
79  return StatusCode::SUCCESS;
80 }
81 
82 // finalize
84 {
85  ATH_MSG_DEBUG( "finalize() successful" );
86 
87  // empty the material garbage
88  for ( const auto *mat : m_materialGarbage ) {
89  delete mat;
90  }
91 
92  return StatusCode::SUCCESS;
93 }
94 
95 std::vector<Trk::TrackingVolume*>*
97  , const GeoAlignmentStore* geoAlign) const
98 {
99  // the converter helpers
100  //Trk::GeoShapeConverter geoShapeToVolumeBounds;
101  //Trk::GeoMaterialConverter geoMaterialToMaterialProperties;
102 
103  Trk::Material dummyMaterial;
104 
106  struct GarbageCollector {
107  explicit GarbageCollector(MaterialGarbage& globalGarbage) : globalBin(globalGarbage) {}
108  ~GarbageCollector() {
109  static std::mutex mutex;
110  std::scoped_lock lock(mutex);
111  globalBin.merge(bin);
112  }
114  MaterialGarbage& globalBin;
115  };
116 
117  // Local garbage collector
118  GarbageCollector gc(m_materialGarbage);
119 
120  // get LAr Detector Description Manager
121  const LArDetectorManager* lArMgr=nullptr;
122  if (detStore()->retrieve(lArMgr, m_lArMgrLocation).isFailure()) {
123  ATH_MSG_FATAL( "Could not get LArDetectorManager! Calo TrackingGeometry will not be built");
124  return nullptr;
125  }
126 
127  // out of couriosity
128  unsigned int numTreeTops = lArMgr->getNumTreeTops();
129  ATH_MSG_DEBUG( "Retrieved " << numTreeTops << " tree tops from the LArDetDescrManager. " );
130 
131  for (unsigned int itreetop = 0; itreetop<numTreeTops; ++itreetop){
132  PVConstLink currentVPhysVolLink = lArMgr->getTreeTop(itreetop);
133  const GeoLogVol* currentLogVol = currentVPhysVolLink->getLogVol();
134 
135  unsigned int currentChilds = currentVPhysVolLink->getNChildVols();
136 
137  ATH_MSG_DEBUG( "Processing " << currentLogVol->getName() << "... has "
138  << currentChilds << " childs, position " << currentVPhysVolLink->getX(geoAlign).translation());
139  //printInfo( currentVPhysVolLink,geoAlign,2);
140  }
141 
142 
144  // THE BARREL SECTION
145  ATH_MSG_DEBUG( "============ Barrel Section ======================" );
146 
147  Trk::TrackingVolume* solenoid = nullptr;
148  Trk::TrackingVolume* solenoidLArBarrelGap = nullptr;
149  Trk::TrackingVolume* lArBarrelPresampler = nullptr;
150  Trk::TrackingVolume* lArBarrel = nullptr;
151 
152  Trk::CylinderVolumeBounds* solenoidBounds = nullptr;
153  Trk::CylinderVolumeBounds* solenoidLArBarrelGapBounds = nullptr;
154 
155  // dummy objects
156  Trk::LayerArray* dummyLayers = nullptr;
157  Trk::TrackingVolumeArray* dummyVolumes = nullptr;
158 
159  // default material definition
160  Trk::Material solenoidMaterial = Trk::Material( 69.9, 811.5, 28.9, 13.8, 0.003);
161  const Trk::Material* lArBarrelPresamplerMaterial = new Trk::Material(130., 634.4, 33.7, 15.4, 0.0017);
162  const Trk::Material* lArBarrelMaterial = new Trk::Material( 26.2, 436.3, 65.4, 27.8, 0.0035);
163 
164  gc.bin.insert(lArBarrelPresamplerMaterial);
165  gc.bin.insert(lArBarrelMaterial);
166 
167  // load layer surfaces
168  std::vector<std::pair<const Trk::Surface*, const Trk::Surface*>> entrySurf =
169  m_calosurf->entrySurfaces(&caloDDM);
170  std::vector<std::pair<const Trk::Surface*, const Trk::Surface*>> exitSurf =
171  m_calosurf->exitSurfaces(&caloDDM);
172 
173  StoredPhysVol* storedPV = nullptr;
174 
175  // -> The BARREL Section ---------------------------------------------------------
176  ATH_MSG_DEBUG( "Building Barrel ... " );
177 
178  Trk::CylinderVolumeBounds* lArBarrelPosBounds = nullptr;
179  Trk::CylinderVolumeBounds* lArBarrelNegBounds = nullptr;
180 
181  if(detStore()->contains<StoredPhysVol>("EMB_POS"))
182  {
183  if(detStore()->retrieve(storedPV,"EMB_POS")==StatusCode::FAILURE)
184  {
185  ATH_MSG_DEBUG( "Unable to retrieve Stored PV EMB_POS" );
186  storedPV = nullptr;
187  }
188  }
189  GeoFullPhysVol* lArBarrelPosPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
190 
191  //if (lArBarrelPosPhysVol) printInfo(lArBarrelPosPhysVol,geoAlign,2);
192 
193  if(detStore()->contains<StoredPhysVol>("EMB_NEG"))
194  {
195  if(detStore()->retrieve(storedPV,"EMB_NEG")==StatusCode::FAILURE)
196  {
197  ATH_MSG_DEBUG( "Unable to retrieve Stored PV EMB_NEG" );
198  storedPV = nullptr;
199  }
200  }
201  GeoFullPhysVol* lArBarrelNegPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
202 
203  const GeoLogVol* lArBarrelPosLogVol = lArBarrelPosPhysVol ? lArBarrelPosPhysVol->getLogVol() : nullptr;
204  const GeoLogVol* lArBarrelNegLogVol = lArBarrelNegPhysVol ? lArBarrelNegPhysVol->getLogVol() : nullptr;
205 
206  // get the material : needs averaging
207 
208  double lArBarrelHalflength = 0.;
209  std::vector<double> zBoundaries;
210 
211  // retrival worked out
212  if (lArBarrelPosLogVol && lArBarrelNegLogVol){
213 
214  int poschilds = lArBarrelPosPhysVol->getNChildVols();
215  int negchilds = lArBarrelNegPhysVol->getNChildVols();
216 
217  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArBarrelPosPhysVol->getAbsoluteName()
218  << " (" << poschilds << " childs) ." );
219  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArBarrelNegPhysVol->getAbsoluteName()
220  << " (" << negchilds << " childs) ." );
221 
222  // and the shapes
223  const GeoShape* lArBarrelPosShape = lArBarrelPosLogVol->getShape();
224  const GeoShape* lArBarrelNegShape = lArBarrelNegLogVol->getShape();
225 
226  // dynamic cast to 'Tubs' shape
227  const GeoPcon* lArBarrelPosPcon = dynamic_cast<const GeoPcon*>(lArBarrelPosShape);
228  lArBarrelPosBounds = (lArBarrelPosPcon) ? Trk::GeoShapeConverter::convert(lArBarrelPosPcon, zBoundaries).release() : nullptr;
229  const GeoPcon* lArBarrelNegPcon = dynamic_cast<const GeoPcon*>(lArBarrelNegShape);
230  lArBarrelNegBounds = (lArBarrelNegPcon) ? Trk::GeoShapeConverter::convert(lArBarrelNegPcon, zBoundaries).release() : nullptr;
231 
232  if (lArBarrelPosBounds)
233  ATH_MSG_VERBOSE( " -> Positive Barrel Bounds: " << *lArBarrelPosBounds );
234  if (lArBarrelNegBounds)
235  ATH_MSG_VERBOSE( " -> Negative Barrel Bounds: " << *lArBarrelNegBounds );
236 
237 
238  }
239  // conversion of PreSamplers done -> make one out of two
240  if (lArBarrelPosBounds && lArBarrelNegBounds){
241 
242  // new dimensions
243  double lArBarrelRmin = lArBarrelPosBounds->innerRadius();
244  double lArBarrelRmax = lArBarrelPosBounds->outerRadius();
245  lArBarrelHalflength = zBoundaries[1];
246 
247  // create the static half-bounds
248  Trk::CylinderVolumeBounds* lArBarrelBoundsPos = new Trk::CylinderVolumeBounds( lArBarrelRmin,
249  lArBarrelRmax,
250  0.5*lArBarrelHalflength);
251  Trk::CylinderVolumeBounds* lArBarrelBoundsNeg = lArBarrelBoundsPos->clone();
252 
253  // position static half-volumes
254  Amg::Vector3D lArBPos(0.,0.,0.5*lArBarrelHalflength);
255  Amg::Vector3D lArBNeg(0.,0.,-0.5*lArBarrelHalflength);
256  Amg::Transform3D* lArBPosTransform = new Amg::Transform3D(Amg::Translation3D(lArBPos));
257  Amg::Transform3D* lArBNegTransform = new Amg::Transform3D(Amg::Translation3D(lArBNeg));
258 
259  // layer entry/exit
260 
261  // binned material for LAr : steering in binEta
262  std::vector<Trk::IdentifiedMaterial> matID;
263  // layer material can be adjusted here
264  int baseID = Trk::GeometrySignature(Trk::Calo)*1000;
265  matID.emplace_back(lArBarrelMaterial,0);
266  matID.emplace_back(lArBarrelMaterial,baseID+1);
267  matID.emplace_back(lArBarrelMaterial,baseID+2);
268  matID.emplace_back(lArBarrelMaterial,baseID+3);
269  // scaling factors refer to avZ(avA) change
270  matID.emplace_back(lArBarrelMaterial->scale(1.3),baseID+1);
271  gc.bin.insert(matID.back().first);
272  matID.emplace_back(lArBarrelMaterial->scale(1.3),baseID+2);
273  gc.bin.insert(matID.back().first);
274  matID.emplace_back(lArBarrelMaterial->scale(0.6),baseID+3);
275  gc.bin.insert(matID.back().first);
276  matID.emplace_back(lArBarrelMaterial->scale(0.7),baseID+3);
277  gc.bin.insert(matID.back().first);
278  matID.emplace_back(lArBarrelMaterial->scale(0.8),baseID+3);
279  gc.bin.insert(matID.back().first);
280  matID.emplace_back(lArBarrelMaterial->scale(0.9),baseID+3);
281  gc.bin.insert(matID.back().first);
282  matID.emplace_back(lArBarrelMaterial->scale(1.1),baseID+3);
283  gc.bin.insert(matID.back().first);
284 
285  //
286  Trk::BinUtility* bubn = new Trk::BinUtility(30,-1.5,0.,Trk::open,Trk::binEta);
287  Trk::BinUtility* bubp = new Trk::BinUtility(30, 0.,1.5,Trk::open,Trk::binEta);
288  // array of indices
289  std::vector<std::vector<size_t> > indexP(bubn->bins());
290  std::vector<std::vector<size_t> > indexN;
291  // binned material for LAr : layer depth per eta bin
292  std::vector< Trk::BinUtility*> layBUN(bubn->bins());
293  std::vector< Trk::BinUtility*> layBUP(bubp->bins());
294  // retrieve offset values (from surfaces on negative side)
295  double r1 = entrySurf[CaloCell_ID::EMB1].second->bounds().r(); // first layer has no modulations
296  double r2 = entrySurf[CaloCell_ID::EMB2].second->bounds().r(); // base value
297  double r3 = entrySurf[CaloCell_ID::EMB3].second->bounds().r(); // base value
298 
299  std::vector<float> offset2{};
300  const Trk::SlidingCylinderSurface* scyl2 = dynamic_cast<const Trk::SlidingCylinderSurface* > (entrySurf[CaloCell_ID::EMB2].second);
301  if (scyl2) offset2 = scyl2->offset();
302  std::vector<float> offset3{};
303  const Trk::SlidingCylinderSurface* scyl3 = dynamic_cast<const Trk::SlidingCylinderSurface* > (entrySurf[CaloCell_ID::EMB3].second);
304  if (scyl3) offset3 = scyl3->offset();
305  // construct bin utilities symmetrically
306  std::vector<float> steps;
307  for (unsigned int i=0; i< bubn->bins(); i++) {
308  steps.clear();
309  steps.push_back(lArBarrelBoundsNeg->innerRadius());
310  std::vector<size_t> indx; indx.clear();
311  indx.push_back(0);
312  steps.push_back(r1);
313  indx.push_back( i<14 ? 1:4 );
314  steps.push_back(r2 + offset2[i] );
315  indx.push_back( i<14 ? 2:5 );
316  steps.push_back(r3 + offset3[i]);
317  // 3rd layer complicated
318  if (i>19) indx.push_back(7);
319  else if (i>17) indx.push_back(8);
320  else if (i>15) indx.push_back(9);
321  else if (i>13) indx.push_back(3);
322  else if (i>11) indx.push_back(6);
323  else if (i>9) indx.push_back(7);
324  else if (i>7) indx.push_back(8);
325  else if (i>5) indx.push_back(8);
326  else if (i>4) indx.push_back(9);
327  else indx.push_back(3);
328  // end 3rd layer
329  steps.push_back(lArBarrelBoundsNeg->outerRadius());
331  layBUN[i] = rBU;
332  layBUP[bubp->bins()-1-i] = rBU->clone();
333  indexN.push_back(indx);
334  indexP[bubp->bins()-1-i] = std::vector<size_t>(indx);
335  }
336 
337  const Trk::BinnedMaterial* lArBarrelMaterialBinPos = new Trk::BinnedMaterial(lArBarrelMaterial,bubp,layBUP,indexP,matID);
338  const Trk::BinnedMaterial* lArBarrelMaterialBinNeg = new Trk::BinnedMaterial(lArBarrelMaterial,bubn,layBUN,indexN,matID);
339 
340  Amg::Transform3D* align=nullptr;
341 
342  Trk::AlignableTrackingVolume* lArBarrelPos = new Trk::AlignableTrackingVolume(lArBPosTransform,align,
343  lArBarrelBoundsPos,
344  lArBarrelMaterialBinPos,
345  1,
346  "Calo::Detectors::LAr::BarrelPos");
347 
348  Trk::AlignableTrackingVolume* lArBarrelNeg = new Trk::AlignableTrackingVolume(lArBNegTransform,align,
349  lArBarrelBoundsNeg,
350  lArBarrelMaterialBinNeg,
351  1,
352  "Calo::Detectors::LAr::BarrelNeg");
353 
354  // glue barrel EM
355  std::vector<Trk::TrackingVolume*> volsB;
356  volsB.push_back(lArBarrelNeg);
357  volsB.push_back(lArBarrelPos);
358 
359  lArBarrel = m_trackingVolumeCreator->createContainerTrackingVolume(volsB,
360  dummyMaterial,
361  "Calo::Container::LAr::Barrel");
362  }
363  // cleanup
364  delete lArBarrelPosBounds; lArBarrelPosBounds = nullptr;
365  delete lArBarrelNegBounds; lArBarrelNegBounds = nullptr;
366 
367  // (1) Build the Solenoid ------------------------------------------------------------
368  ATH_MSG_DEBUG( "Building the Solenoid ... " );
369 
370  if(detStore()->contains<StoredPhysVol>("SOLENOID"))
371  {
372  if(detStore()->retrieve(storedPV,"SOLENOID")==StatusCode::FAILURE)
373  {
374  ATH_MSG_DEBUG( "Unable to retrieve Stored PV SOLENOID" );
375  storedPV = nullptr;
376  }
377  }
378  GeoFullPhysVol* solenoidPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
379 
380 
381  const GeoLogVol* solenoidLogVol = solenoidPhysVol ? solenoidPhysVol->getLogVol() : nullptr;
382 
383  // retrival worked out
384  if (solenoidLogVol){
385  int childs = solenoidPhysVol->getNChildVols();
386 
387  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume "
388  << solenoidPhysVol->getAbsoluteName() << " (" << childs << " childs) ." );
389 
390  const GeoShape* solenoidShape = solenoidLogVol->getShape();
391  // dynamic cast to 'Tubs' shape
392  const GeoTubs* solenoidTubs = dynamic_cast<const GeoTubs*>(solenoidShape);
393  solenoidBounds = new Trk::CylinderVolumeBounds(solenoidTubs->getRMin(),solenoidTubs->getRMax(),lArBarrelHalflength);
394  // assing the material
395  const GeoMaterial* solenoidMaterialGM = solenoidLogVol->getMaterial();
396  if (solenoidMaterialGM) {
397  solenoidMaterial = Trk::GeoMaterialConverter::convert(solenoidMaterialGM);
398  }
399  }
400 
401  // conversion ok : create the volume
402  if (solenoidBounds) {
403  // output the bounds
404  ATH_MSG_DEBUG( " -> Solenoid Bounds: " << *solenoidBounds );
405 
406  solenoid = new Trk::TrackingVolume(nullptr,
407  solenoidBounds,
408  solenoidMaterial,
409  dummyLayers, dummyVolumes,
410  "Calo::Solenoid");
411 
412  }
413 
414  // (2) Build the Presampler ------------------------------------------------------------
415  ATH_MSG_DEBUG( "Building Barrel Presampler ... " );
416 
417  Trk::CylinderVolumeBounds* lArBarrelPresamplerPosBounds = nullptr;
418  Trk::CylinderVolumeBounds* lArBarrelPresamplerNegBounds = nullptr;
419 
420  if(detStore()->contains<StoredPhysVol>("PRESAMPLER_B_POS"))
421  {
422  if(detStore()->retrieve(storedPV,"PRESAMPLER_B_POS")==StatusCode::FAILURE)
423  {
424  ATH_MSG_DEBUG( "Unable to retrieve Stored PV PRESAMPLER_B_POS" );
425  storedPV = nullptr;
426  }
427  }
428  GeoFullPhysVol* lArBarrelPresamplerPosPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
429 
430 
431 
432  if(detStore()->contains<StoredPhysVol>("PRESAMPLER_B_NEG"))
433  {
434  if(detStore()->retrieve(storedPV,"PRESAMPLER_B_NEG")==StatusCode::FAILURE)
435  {
436  ATH_MSG_DEBUG( "Unable to retrieve Stored PV PRESAMPLER_B_NEG" );
437  storedPV = nullptr;
438  }
439  }
440  GeoFullPhysVol* lArBarrelPresamplerNegPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
441 
442 
443  const GeoLogVol* lArBarrelPresamplerPosLogVol = lArBarrelPresamplerPosPhysVol ? lArBarrelPresamplerPosPhysVol->getLogVol() : nullptr;
444  const GeoLogVol* lArBarrelPresamplerNegLogVol = lArBarrelPresamplerNegPhysVol ? lArBarrelPresamplerNegPhysVol->getLogVol() : nullptr;
445 
446  // retrival worked out
447  if (lArBarrelPresamplerPosLogVol && lArBarrelPresamplerNegLogVol){
448 
449  int poschilds = lArBarrelPresamplerPosPhysVol->getNChildVols();
450  int negchilds = lArBarrelPresamplerNegPhysVol->getNChildVols();
451 
452  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume "
453  << lArBarrelPresamplerPosPhysVol->getAbsoluteName() << " (" << poschilds << " childs) ." );
454  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume "
455  << lArBarrelPresamplerNegPhysVol->getAbsoluteName() << " (" << negchilds << " childs) ." );
456 
457  Amg::Vector3D lArBPos(0.,0.,0.5*lArBarrelHalflength);
458  Amg::Vector3D lArBNeg(0.,0.,-0.5*lArBarrelHalflength);
459  Amg::Transform3D* lArPBPosTransform = new Amg::Transform3D(Amg::Translation3D(lArBPos));
460  Amg::Transform3D* lArPBNegTransform = new Amg::Transform3D(Amg::Translation3D(lArBNeg));
461 
462  // and the shapes
463  const GeoShape* lArBarrelPresamplerPosShape = lArBarrelPresamplerPosLogVol->getShape();
464 
465  // dynamic cast to 'Tubs' shape
466  const GeoTubs* lArBarrelPresamplerPosTubs = dynamic_cast<const GeoTubs*>(lArBarrelPresamplerPosShape);
467  lArBarrelPresamplerPosBounds = new Trk::CylinderVolumeBounds(lArBarrelPresamplerPosTubs->getRMin(),
468  lArBarrelPresamplerPosTubs->getRMax(),
469  0.5*lArBarrelHalflength);
470 
471 
472  if (lArBarrelPresamplerPosBounds){
473  lArBarrelPresamplerNegBounds = lArBarrelPresamplerPosBounds->clone();
474  ATH_MSG_VERBOSE( " -> Positive Barrel Presampler Bounds: "
475  << *lArBarrelPresamplerPosBounds );
476  }
477  if (lArBarrelPresamplerNegBounds){
478  ATH_MSG_VERBOSE( " -> Negative Barrel Presampler Bounds: "
479  << *lArBarrelPresamplerNegBounds );
480  }
481 
482  // material needs averaging, don't use pure Ar
483 
484  Amg::Transform3D* align=nullptr;
485 
486  // trivial binning
487  std::vector<float> bpsteps{float(lArBarrelPresamplerPosBounds->innerRadius()),
488  float(lArBarrelPresamplerPosBounds->outerRadius())};
489  Trk::BinUtility* rBU = new Trk::BinUtility(bpsteps, Trk::open, Trk::binR);
490  Trk::BinUtility* rBUc = rBU->clone();
491 
492  std::vector<size_t> dummylay (1,0);
493  // binned material for Presampler :
494  std::vector<Trk::IdentifiedMaterial> matBP;
495  // layer material can be adjusted here
496  int baseID = Trk::GeometrySignature(Trk::Calo)*1000;
497  matBP.emplace_back(lArBarrelPresamplerMaterial,baseID);
498 
499  const Trk::BinnedMaterial* lArBarrelPresamplerMaterialBinPos = new Trk::BinnedMaterial(lArBarrelPresamplerMaterial,rBU,dummylay,matBP);
500  const Trk::BinnedMaterial* lArBarrelPresamplerMaterialBinNeg = new Trk::BinnedMaterial(lArBarrelPresamplerMaterial,rBUc,dummylay,matBP);
501 
502  Trk::AlignableTrackingVolume* lArBarrelPresamplerPos = new Trk::AlignableTrackingVolume(lArPBPosTransform, align,
503  lArBarrelPresamplerPosBounds,
504  lArBarrelPresamplerMaterialBinPos,
505  0,
506  "Calo::Detectors::LAr::BarrelPresamplerPos");
507 
508  Trk::AlignableTrackingVolume* lArBarrelPresamplerNeg = new Trk::AlignableTrackingVolume(lArPBNegTransform, align,
509  lArBarrelPresamplerNegBounds,
510  lArBarrelPresamplerMaterialBinNeg,
511  0,
512  "Calo::Detectors::LAr::BarrelPresamplerNeg");
513 
514  // glue barrel presampler
515  std::vector<Trk::TrackingVolume*> volsBP;
516  volsBP.push_back(lArBarrelPresamplerNeg);
517  volsBP.push_back(lArBarrelPresamplerPos);
518 
519  lArBarrelPresampler = m_trackingVolumeCreator->createContainerTrackingVolume(volsBP,
520  dummyMaterial,
521  "Calo::Container::LAr::BarrelPresampler");
522  }
523 
524  // (3) Build the solenoid gap ------------------------------------------------------------
525 
526  if (solenoidBounds && lArBarrelPresamplerPosBounds) {
527  solenoidLArBarrelGapBounds = new Trk::CylinderVolumeBounds(solenoidBounds->outerRadius(),
528  lArBarrelPresamplerPosBounds->innerRadius(),
529  lArBarrelHalflength);
530 
531  //Trk::MaterialProperties solenoidGapMaterial = Trk::MaterialProperties(1., 93.9/0.5, 0.0028*pow(0.5,3), 39.);
532  // Trk::Material solenoidGapMaterial= Trk::Material(534.9, 2871.2, 18.6, 9.1, 0.0004);
533  Trk::Material solenoidGapMaterial= Trk::Material(182.6, 1007., 22.9, 10.9, 0.0012);
534 
535  solenoidLArBarrelGap = new Trk::TrackingVolume(nullptr,
536  solenoidLArBarrelGapBounds,
537  solenoidGapMaterial,
538  dummyLayers, dummyVolumes,
539  "Calo::GapVolumes::LAr::SolenoidPresamplerGap");
540  }
541 
543  // THE ENDCAP SECTION
544  ATH_MSG_DEBUG( "============ Endcap Section ======================" );
545  // PRESAMPLER_EC_POS, PRESAMPLER_EC_NEG
546  // EMEC_POS, EMEC_NEG
547  // HEC1_POS, HEC1_NEG
548  // HEC2_POS, HEC2_NEG
549  // FCAL1_POS, FCAL1_NEG
550  // FCAL2_POS, FCAL2_NEG
551  // FCAL3_POS, FCAL3_NEG
552 
553  // positive Side
554  Trk::TrackingVolume* lArPositiveEndcapInnerGap = nullptr;
555  Trk::TrackingVolume* lArPositiveEndcap = nullptr;
556  Trk::TrackingVolume* lArPositiveHec = nullptr;
557  Trk::TrackingVolume* lArPositiveHecFcalCover = nullptr;
558  Trk::TrackingVolume* lArPositiveFcal = nullptr;
559  Trk::TrackingVolume* lArPosECPresampler = nullptr;
560 
561  // negative Side
562  Trk::TrackingVolume* lArNegativeEndcapInnerGap = nullptr;
563  Trk::TrackingVolume* lArNegativeEndcap = nullptr;
564  Trk::TrackingVolume* lArNegativeHec = nullptr;
565  Trk::TrackingVolume* lArNegativeHecFcalCover = nullptr;
566  Trk::TrackingVolume* lArNegativeFcal = nullptr;
567  Trk::TrackingVolume* lArNegECPresampler = nullptr;
568 
569  // the smoothed ones
570  Trk::CylinderVolumeBounds* lArPositiveHecBounds = nullptr;
571  Trk::CylinderVolumeBounds* lArPositiveHecFcalCoverBounds = nullptr;
572  Trk::CylinderVolumeBounds* lArPositiveFcalBounds = nullptr;
573 
574  Trk::CylinderVolumeBounds* lArNegativeHecBounds = nullptr;
575  Trk::CylinderVolumeBounds* lArNegativeHecFcalCoverBounds = nullptr;
576  Trk::CylinderVolumeBounds* lArNegativeFcalBounds = nullptr;
577 
578  // (1) now parse the EC
579  std::unique_ptr<Trk::CylinderVolumeBounds> lArPositiveEndcapBounds;
580  std::unique_ptr<Trk::CylinderVolumeBounds> lArNegativeEndcapBounds;
581 
582  if(detStore()->contains<StoredPhysVol>("EMEC_POS"))
583  {
584  if(detStore()->retrieve(storedPV,"EMEC_POS")==StatusCode::FAILURE)
585  {
586  ATH_MSG_DEBUG( "Unable to retrieve Stored PV EMEC_POS" );
587  storedPV = nullptr;
588  }
589  }
590  GeoFullPhysVol* lArPositiveEndcapPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
591 
592  const GeoLogVol* lArPositiveEndcapLogVol = lArPositiveEndcapPhysVol ? lArPositiveEndcapPhysVol->getLogVol() : nullptr;
593 
594  if(detStore()->contains<StoredPhysVol>("EMEC_NEG"))
595  {
596  if(detStore()->retrieve(storedPV,"EMEC_NEG")==StatusCode::FAILURE)
597  {
598  ATH_MSG_DEBUG( "Unable to retrieve Stored PV EMEC_NEG" );
599  storedPV = nullptr;
600  }
601  }
602  GeoFullPhysVol* lArNegativeEndcapPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
603 
604  const GeoLogVol* lArNegativeEndcapLogVol = lArNegativeEndcapPhysVol ? lArNegativeEndcapPhysVol->getLogVol() : nullptr;
605 
606  // get the material
607  const GeoMaterial* lArPositiveEndcapMaterial = nullptr;
608  //const GeoMaterial* lArNegativeEndcapMaterial = 0;
609 
610  std::vector<double> positiveEndcapZboundaries;
611  std::vector<double> negativeEndcapZboundaries;
612 
613  double lArEndcapZpos = 0.;
614 
615  // retrival worked out
616  if (lArPositiveEndcapLogVol && lArNegativeEndcapLogVol){
617 
618  int poschilds = lArPositiveEndcapPhysVol->getNChildVols();
619  int negchilds = lArNegativeEndcapPhysVol->getNChildVols();
620 
621  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArPositiveEndcapPhysVol->getAbsoluteName()
622  << " (" << poschilds << " childs)." );
623  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArNegativeEndcapPhysVol->getAbsoluteName()
624  << " (" << negchilds << " childs)." );
625 
626 
627  // and the shapes
628  const GeoShape* lArPositiveEndcapShape = lArPositiveEndcapLogVol->getShape();
629  const GeoShape* lArNegativeEndcapShape = lArNegativeEndcapLogVol->getShape();
630 
631  // get the transforms
632  const Amg::Transform3D& lArPositiveEndcapTransform = geoAlign
633  ? lArPositiveEndcapPhysVol->getCachedAbsoluteTransform(geoAlign)
634  : lArPositiveEndcapPhysVol->getAbsoluteTransform();
635  //const Amg::Transform3D& lArNegativeEndcapTransform = Amg::CLHEPTransformToEigen(lArNegativeEndcapPhysVol->getAbsoluteTransform());
636  Amg::Vector3D lArPositiveEndcapNomPosition = lArPositiveEndcapTransform.translation();
637  //Amg::Vector3D lArNegativeEndcapNomPosition = lArNegativeEndcapTransform.translation();
638 
639  // dynamic cast to 'Tubs' shape
640  const GeoPcon* lArPositiveEndcapPcon = dynamic_cast<const GeoPcon*>(lArPositiveEndcapShape);
641  if (lArPositiveEndcapPcon)
642  lArPositiveEndcapBounds = std::unique_ptr<Trk::CylinderVolumeBounds>
643  (Trk::GeoShapeConverter::convert(lArPositiveEndcapPcon,
644  positiveEndcapZboundaries));
645 
646  const GeoPcon* lArNegativeEndcapPcon = dynamic_cast<const GeoPcon*>(lArNegativeEndcapShape);
647  if (lArNegativeEndcapPcon)
648  lArNegativeEndcapBounds = std::unique_ptr<Trk::CylinderVolumeBounds>
649  (Trk::GeoShapeConverter::convert(lArNegativeEndcapPcon,
650  negativeEndcapZboundaries));
651 
652  if (lArPositiveEndcapBounds)
653  ATH_MSG_DEBUG( " -> Positive Endcap Bounds: " << *lArPositiveEndcapBounds );
654  if (lArNegativeEndcapBounds)
655  ATH_MSG_DEBUG( " -> Negative Endcap Bounds: " << *lArNegativeEndcapBounds );
656 
657  double positiveEndcapZpos = 0.5 *(positiveEndcapZboundaries[1] + positiveEndcapZboundaries[0]);
658 
659  lArEndcapZpos = positiveEndcapZpos+lArPositiveEndcapNomPosition.z();
660 
661  ATH_MSG_DEBUG( " located at z-positions " << lArEndcapZpos << " / " << -lArEndcapZpos );
662 
663  // assing the material
664  lArPositiveEndcapMaterial = lArPositiveEndcapLogVol->getMaterial();
665  //lArNegativeEndcapMaterial = lArNegativeEndcapLogVol->getMaterial();
666 
667  }
668 
669  double lArEndcapHalfZ = 0.;
670  double lArEndcapZmin = 0.;
671  double lArEndcapZmax = 0.;
672  double lArEndcapInnerRadius = 0;
673  double lArEndcapOuterRadius = 0;
674 
675  // now create the Tracking Volumes
676  if (lArPositiveEndcapBounds && lArNegativeEndcapBounds && lArPositiveEndcapMaterial){
677 
678 
679  // create the material
680  //Trk::MaterialProperties lArEndcapMaterial = Trk::MaterialProperties(1., 22.2/0.99, 0.0027*pow(0.99,3), 39.);
681  const Trk::Material* lArEndcapMaterial=new Trk::Material(22.21, 402.2, 72.6, 30.5, 0.0039);
682  gc.bin.insert(lArEndcapMaterial);
683 
684  lArEndcapHalfZ = lArPositiveEndcapBounds->halflengthZ();
685  lArEndcapZmin = lArEndcapZpos - lArPositiveEndcapBounds->halflengthZ();
686  lArEndcapZmax = lArEndcapZpos + lArPositiveEndcapBounds->halflengthZ();
687  lArEndcapInnerRadius = lArPositiveEndcapBounds->innerRadius();
688  lArEndcapOuterRadius = lArPositiveEndcapBounds->outerRadius();
689 
690  Amg::Vector3D lArEndcapPositionPos(0.,0.,lArEndcapZpos);
691  Amg::Vector3D lArEndcapPositionNeg(0.,0.,-lArEndcapZpos);
692  Amg::Transform3D* lArPositiveEndcapTransform = new Amg::Transform3D(Amg::Translation3D(lArEndcapPositionPos));
693  Amg::Transform3D* lArNegativeEndcapTransform = new Amg::Transform3D(Amg::Translation3D(lArEndcapPositionNeg));
694 
695  Amg::Transform3D* align = nullptr;
696  // binned material for LAr
697  Trk::BinUtility* bup = new Trk::BinUtility(37,1.35,3.2,Trk::open,Trk::binEta);
698  Trk::BinUtility* bun = new Trk::BinUtility(37,-3.2,-1.35,Trk::open,Trk::binEta);
699 
700  // binned material for LAr : steering in binEta
701  std::vector<Trk::IdentifiedMaterial> matEID;
702  // layer material can be adjusted here
703  int baseID = Trk::GeometrySignature(Trk::Calo)*1000 + 4;
704  matEID.emplace_back(lArEndcapMaterial,0);
705  matEID.emplace_back(lArEndcapMaterial,baseID+1);
706  matEID.emplace_back(lArEndcapMaterial,baseID+2);
707  matEID.emplace_back(lArEndcapMaterial,baseID+3);
708  // scaled
709  matEID.emplace_back(lArEndcapMaterial->scale(1.05),baseID+1);
710  gc.bin.insert(matEID.back().first);
711  matEID.emplace_back(lArEndcapMaterial->scale(1.1),baseID+1);
712  gc.bin.insert(matEID.back().first);
713  matEID.emplace_back(lArEndcapMaterial->scale(1.15),baseID+1);
714  gc.bin.insert(matEID.back().first);
715  matEID.emplace_back(lArEndcapMaterial->scale(1.2),baseID+1);
716  gc.bin.insert(matEID.back().first);
717  matEID.emplace_back(lArEndcapMaterial->scale(1.25),baseID+1);
718  gc.bin.insert(matEID.back().first);
719  matEID.emplace_back(lArEndcapMaterial->scale(1.3),baseID+1);
720  gc.bin.insert(matEID.back().first);
721  matEID.emplace_back(lArEndcapMaterial->scale(1.35),baseID+1);
722  gc.bin.insert(matEID.back().first);
723  matEID.emplace_back(lArEndcapMaterial->scale(1.4),baseID+1);
724  gc.bin.insert(matEID.back().first);
725  matEID.emplace_back(lArEndcapMaterial->scale(1.05),baseID+2);
726  gc.bin.insert(matEID.back().first);
727  matEID.emplace_back(lArEndcapMaterial->scale(1.1),baseID+2);
728  gc.bin.insert(matEID.back().first);
729  matEID.emplace_back(lArEndcapMaterial->scale(1.15),baseID+2);
730  gc.bin.insert(matEID.back().first);
731  matEID.emplace_back(lArEndcapMaterial->scale(1.2),baseID+2);
732  gc.bin.insert(matEID.back().first);
733  matEID.emplace_back(lArEndcapMaterial->scale(1.25),baseID+2);
734  gc.bin.insert(matEID.back().first);
735  matEID.emplace_back(lArEndcapMaterial->scale(1.3),baseID+2);
736  gc.bin.insert(matEID.back().first);
737  matEID.emplace_back(lArEndcapMaterial->scale(1.35),baseID+2);
738  gc.bin.insert(matEID.back().first);
739  matEID.emplace_back(lArEndcapMaterial->scale(1.4),baseID+2);
740  gc.bin.insert(matEID.back().first);
741  matEID.emplace_back(lArEndcapMaterial->scale(1.45),baseID+2);
742  gc.bin.insert(matEID.back().first);
743  matEID.emplace_back(lArEndcapMaterial->scale(0.7),baseID+3);
744  gc.bin.insert(matEID.back().first);
745  matEID.emplace_back(lArEndcapMaterial->scale(0.75),baseID+3);
746  gc.bin.insert(matEID.back().first);
747  matEID.emplace_back(lArEndcapMaterial->scale(0.8),baseID+3);
748  gc.bin.insert(matEID.back().first);
749  matEID.emplace_back(lArEndcapMaterial->scale(0.85),baseID+3);
750  gc.bin.insert(matEID.back().first);
751  matEID.emplace_back(lArEndcapMaterial->scale(0.9),baseID+3);
752  gc.bin.insert(matEID.back().first);
753  matEID.emplace_back(lArEndcapMaterial->scale(0.95),baseID+3);
754  gc.bin.insert(matEID.back().first);
755  matEID.emplace_back(lArEndcapMaterial->scale(1.05),baseID+3);
756  gc.bin.insert(matEID.back().first);
757  matEID.emplace_back(lArEndcapMaterial->scale(1.1),baseID+3);
758  gc.bin.insert(matEID.back().first);
759  matEID.emplace_back(lArEndcapMaterial->scale(1.15),baseID+3);
760  gc.bin.insert(matEID.back().first);
761  matEID.emplace_back(lArEndcapMaterial->scale(1.2),baseID+3);
762  gc.bin.insert(matEID.back().first);
763 
764  // binned material for LAr : layer depth per eta bin
765  std::vector< Trk::BinUtility*> layEUP(bup->bins());
766  // array of indices
767  std::vector<std::vector<size_t> > indexEP;
768  // retrieve offset values (positive)
769  float z1 = entrySurf[CaloCell_ID::EME1].first->center().z(); // first layer has no modulations
770  float z2 = entrySurf[CaloCell_ID::EME2].first->center().z(); // base value
771  float z3 = entrySurf[CaloCell_ID::EME3].first->center().z(); // base value
772 
773  std::vector<float> offset2;
774  const Trk::SlidingDiscSurface* sd2 = dynamic_cast<const Trk::SlidingDiscSurface* > (entrySurf[CaloCell_ID::EME2].first);
775  if (sd2) offset2 = sd2->offset();
776  std::vector<float>offset3;
777  const Trk::SlidingDiscSurface* sd3 = dynamic_cast<const Trk::SlidingDiscSurface* > (entrySurf[CaloCell_ID::EME3].first);
778  if (sd3) offset3 = sd3->offset();
779  // construct bin utilities
780  std::vector<float> steps;
781  for (unsigned int i=0; i< bup->bins(); i++) {
782  steps.clear();
783  std::vector<size_t> indx; indx.clear();
784  steps.push_back( lArEndcapZmin);
785  indx.push_back(0);
786  steps.push_back(z1);
787  if (i<4) indx.push_back(1);
788  else if (i<6) indx.push_back(4);
789  else if (i<8) indx.push_back(5);
790  else if (i<10) indx.push_back(6);
791  else if (i<12) indx.push_back(7);
792  else if (i<14) indx.push_back(8);
793  else if (i<16) indx.push_back(9);
794  else if (i<18) indx.push_back(10);
795  else if (i<23) indx.push_back(11);
796  else indx.push_back(1);
797 
798  float z2c = z2 + offset2[i];
799  if (z2c!= steps.back()) { steps.push_back(z2c); indx.push_back(2);}
800  else { indx.back()=2; }
801  if (i<4) {}
802  else if (i<6) indx.back()=12;
803  else if (i<8) indx.back()=13;
804  else if (i<10) indx.back()=14;
805  else if (i<12) indx.back()=15;
806  else if (i<14) indx.back()=16;
807  else if (i<16) indx.back()=17;
808  else if (i<18) indx.back()=18;
809  else if (i<21) indx.back()=19;
810  else if (i<23) indx.back()=20;
811  else if (i<25) indx.back()=14;
812  else if (i<27) indx.back()=15;
813  else if (i<29) indx.back()=16;
814  else if (i<31) indx.back()=17;
815  else if (i<33) indx.back()=18;
816  else if (i<35) indx.back()=19;
817  else if (i<37) indx.back()=20;
818 
819  steps.push_back(z3 + offset3[i] );
820  if (i<6) indx.push_back(21);
821  else if (i<8) indx.push_back(22);
822  else if (i<10) indx.push_back(23);
823  else if (i<12) indx.push_back(24);
824  else if (i<14) indx.push_back(25);
825  else if (i<16) indx.push_back(26);
826  else if (i<18) indx.push_back(3);
827  else if (i<20) indx.push_back(28);
828  else if (i<23) indx.push_back(29);
829  else if (i<25) indx.push_back(22);
830  else if (i<27) indx.push_back(23);
831  else if (i<29) indx.push_back(24);
832  else if (i<31) indx.push_back(26);
833  else if (i<33) indx.push_back(3);
834  else if (i<35) indx.push_back(27);
835  else indx.push_back(28);
836  steps.push_back(lArEndcapZmax);
838  layEUP[i] = zBU;
839  indexEP.push_back(indx);
840  }
841 
842  // binned material for LAr : layer depth per eta bin
843  std::vector< Trk::BinUtility*> layEUN(bun->bins());
844  std::vector<std::vector<size_t> > indexEN;
845  for ( int j=indexEP.size()-1; j>-1; j--) {
846  std::vector<size_t> indx; indx.clear();
847  for ( int jj=indexEP[j].size()-1; jj>-1; jj--) {
848  indx.push_back(indexEP[j][jj]);
849  }
850  indexEN.push_back(indx);
851  }
852  // retrieve offset values (negative)
853  z1 = entrySurf[CaloCell_ID::EME1].second->center().z(); // first layer has no modulations
854  z2 = entrySurf[CaloCell_ID::EME2].second->center().z(); // base value
855  z3 = entrySurf[CaloCell_ID::EME3].second->center().z(); // base value
856 
857  offset2.clear();
858  sd2 = dynamic_cast<const Trk::SlidingDiscSurface* > (entrySurf[CaloCell_ID::EME2].second);
859  if (sd2) offset2 = sd2->offset();
860  offset3.clear();
861  sd3 = dynamic_cast<const Trk::SlidingDiscSurface* > (entrySurf[CaloCell_ID::EME3].second);
862  if (sd3) offset3 = sd3->offset();
863  // construct bin utilities ( in increasing ordering )
864  for (unsigned int i=0; i< bun->bins(); i++) {
865  steps.clear();
866  steps.push_back(-lArEndcapZmax);
867  steps.push_back(z3 + offset3[i] );
868  steps.push_back(z2 + offset2[i] );
869  if (z1!= steps.back()) { steps.push_back(z1); }
870  steps.push_back(-lArEndcapZmin);
872  layEUN[i] = zBU;
873  }
874 
875  const Trk::BinnedMaterial* lArEndcapMaterialBinnedPos = new Trk::BinnedMaterial(lArEndcapMaterial,bup,layEUP,indexEP,matEID);
876  const Trk::BinnedMaterial* lArEndcapMaterialBinnedNeg = new Trk::BinnedMaterial(lArEndcapMaterial,bun,layEUN,indexEN,matEID);
877 
878  lArPositiveEndcap = new Trk::AlignableTrackingVolume(lArPositiveEndcapTransform,align,
879  lArPositiveEndcapBounds.release(),
880  lArEndcapMaterialBinnedPos,
881  5,
882  //lpEntries,
883  "Calo::Detectors::LAr::PositiveEndcap");
884 
885  lArNegativeEndcap = new Trk::AlignableTrackingVolume(lArNegativeEndcapTransform,align,
886  lArNegativeEndcapBounds.release(),
887  lArEndcapMaterialBinnedNeg,
888  5,
889  //lnEntries,
890  "Calo::Detectors::LAr::NegativeEndcap");
891  }
892 
893  // presampler
894  ATH_MSG_DEBUG( "Building Endcap Presampler ... " );
895 
896  Trk::CylinderVolumeBounds* lArECPresamplerBounds = nullptr;
897 
898  if(detStore()->contains<StoredPhysVol>("PRESAMPLER_EC_POS"))
899  {
900  if(detStore()->retrieve(storedPV,"PRESAMPLER_EC_POS")==StatusCode::FAILURE)
901  {
902  ATH_MSG_DEBUG( "Unable to retrieve Stored PV PRESAMPLER_EC_POS" );
903  storedPV = nullptr;
904  }
905  }
906  GeoFullPhysVol* lArECPresamplerPhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
907  // if (lArECPresamplerPhysVol) printInfo(lArECPresamplerPhysVol, geoAlign);
908 
909  const GeoLogVol* lArECPresamplerLogVol = lArECPresamplerPhysVol ? lArECPresamplerPhysVol->getLogVol() : nullptr;
910 
911  // binned material for EC Presampler : layers only
912  std::vector<Trk::IdentifiedMaterial> matECP;
913  const Trk::Material* mAr = new Trk::Material(140., 1170./1.4, 40., 18., 0.0014);
914  const Trk::Material* mAl = new Trk::Material(88.93, 388.8, 27., 13., 0.0027);
915  gc.bin.insert(mAr);
916  gc.bin.insert(mAl);
917 
918  // layer material can be adjusted here
919  int baseID = Trk::GeometrySignature(Trk::Calo)*1000 + 4;
920  matECP.emplace_back(mAl,0);
921  matECP.emplace_back(mAr,baseID);
922 
923  if ( lArECPresamplerLogVol ) {
924 
925  const GeoShape* lArECPresamplerShape = lArECPresamplerLogVol->getShape();
926  const Amg::Transform3D& lArECPresamplerTransform = geoAlign
927  ? lArECPresamplerPhysVol->getCachedAbsoluteTransform(geoAlign)
928  : lArECPresamplerPhysVol->getAbsoluteTransform();
929  // dynamic cast to 'Tubs' shape
930  const GeoTubs* psTubs = dynamic_cast<const GeoTubs*>(lArECPresamplerShape);
931 
932  float d = psTubs->getZHalfLength();
933  // presampler is embedded in 65 mm of Alu
934  float ecd = 32.5 ;
935  // the new HepTransforms
936  float zec = lArECPresamplerTransform.translation().z()-ecd+d;
937  Amg::Vector3D lArECPresamplerPos(0.,0.,zec);
938  Amg::Vector3D lArECPresamplerNeg(0.,0.,-zec);
939  Amg::Transform3D* lArPosECPresamplerTransform = new Amg::Transform3D(Amg::Translation3D(lArECPresamplerPos));
940  Amg::Transform3D* lArNegECPresamplerTransform = new Amg::Transform3D(Amg::Translation3D(lArECPresamplerNeg));
941 
942  lArECPresamplerBounds = new Trk::CylinderVolumeBounds(psTubs->getRMin(),psTubs->getRMax(),ecd);
943 
944  // layer binning in Z
945  std::vector<float> ecp;
946  ecp.push_back( zec-ecd);
947  ecp.push_back( zec+ecd-2*d);
948  ecp.push_back( zec+ecd);
950 
951  // material index
952  std::vector<size_t> iep{0,1};
953 
954  // binned material
955  const Trk::BinnedMaterial* lArECPresamplerMaterialBinPos = new Trk::BinnedMaterial( lArBarrelPresamplerMaterial,hecp,iep,matECP);
956 
957  Amg::Transform3D* align=nullptr;
958 
959  lArPosECPresampler = new Trk::AlignableTrackingVolume(lArPosECPresamplerTransform, align,
960  lArECPresamplerBounds,
961  lArECPresamplerMaterialBinPos,
962  4,
963  "Calo::Detectors::LAr::PositiveECPresampler");
964 
965  // layer binning in Z
966  std::vector<float> ecpn;
967  ecpn.push_back(-zec-ecd);
968  ecpn.push_back(-zec-ecd+2*d);
969  ecpn.push_back(-zec+ecd);
971 
972  // material index
973  std::vector<size_t> ien{1,0};
974 
975  // binned material
976  const Trk::BinnedMaterial* lArECPresamplerMaterialBinNeg = new Trk::BinnedMaterial( lArBarrelPresamplerMaterial,hecpn,ien,matECP);
977 
978  lArNegECPresampler = new Trk::AlignableTrackingVolume(lArNegECPresamplerTransform, align,
979  lArECPresamplerBounds->clone(),
980  lArECPresamplerMaterialBinNeg,
981  4,
982  "Calo::Detectors::LAr::NegativeECPresampler");
983 
984 
985  }
986 
987  // (2) now parse the HEC
988  Trk::CylinderVolumeBounds* lArPositiveHec1Bounds = nullptr;
989  Trk::CylinderVolumeBounds* lArPositiveHec2Bounds = nullptr;
990  Trk::CylinderVolumeBounds* lArNegativeHec1Bounds = nullptr;
991  Trk::CylinderVolumeBounds* lArNegativeHec2Bounds = nullptr;
992 
993 
994  if(detStore()->contains<StoredPhysVol>("HEC1_POS")){
995 
996  if(detStore()->retrieve(storedPV,"HEC1_POS")==StatusCode::FAILURE){
997  ATH_MSG_DEBUG( "Unable to retrieve Stored PV HEC1_POS" );
998  storedPV = nullptr;
999  }
1000 
1001  }
1002  GeoFullPhysVol* lArPositiveHec1PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1003 
1004  if(detStore()->contains<StoredPhysVol>("HEC2_POS")){
1005 
1006  if(detStore()->retrieve(storedPV,"HEC2_POS")==StatusCode::FAILURE){
1007  ATH_MSG_DEBUG( "Unable to retrieve Stored PV HEC2_POS" );
1008  storedPV = nullptr;
1009  }
1010 
1011  }
1012  GeoFullPhysVol* lArPositiveHec2PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1013 
1014  if(detStore()->contains<StoredPhysVol>("HEC1_NEG")){
1015 
1016  if(detStore()->retrieve(storedPV,"HEC1_NEG")==StatusCode::FAILURE){
1017  ATH_MSG_DEBUG( "Unable to retrieve Stored PV HEC1_NEG" );
1018  storedPV = nullptr;
1019  }
1020 
1021  }
1022  GeoFullPhysVol* lArNegativeHec1PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1023 
1024  if(detStore()->contains<StoredPhysVol>("HEC2_NEG")){
1025 
1026  if(detStore()->retrieve(storedPV,"HEC2_NEG")==StatusCode::FAILURE){
1027  ATH_MSG_DEBUG("Unable to retrieve Stored PV HEC2_NEG" );
1028  storedPV = nullptr;
1029  }
1030 
1031  }
1032 
1033  GeoFullPhysVol* lArNegativeHec2PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1034 
1035  const GeoLogVol* lArPositiveHec1LogVol = lArPositiveHec1PhysVol ? lArPositiveHec1PhysVol->getLogVol() : nullptr;
1036  const GeoLogVol* lArPositiveHec2LogVol = lArPositiveHec2PhysVol ? lArPositiveHec2PhysVol->getLogVol() : nullptr;
1037  const GeoLogVol* lArNegativeHec1LogVol = lArNegativeHec1PhysVol ? lArNegativeHec1PhysVol->getLogVol() : nullptr;
1038  const GeoLogVol* lArNegativeHec2LogVol = lArNegativeHec2PhysVol ? lArNegativeHec2PhysVol->getLogVol() : nullptr;
1039 
1040  std::vector<double> positiveEndcapZboundariesHec1;
1041  std::vector<double> positiveEndcapZboundariesHec2;
1042  std::vector<double> negativeEndcapZboundariesHec1;
1043  std::vector<double> negativeEndcapZboundariesHec2;
1044  double hecEnd = 0;
1045 
1046  // retrival worked out
1047  if (lArPositiveHec1LogVol && lArPositiveHec2LogVol && lArNegativeHec1LogVol && lArNegativeHec2LogVol){
1048 
1049  int poschildsHec1 = lArPositiveHec1PhysVol->getNChildVols();
1050  int poschildsHec2 = lArPositiveHec2PhysVol->getNChildVols();
1051  int negchildsHec1 = lArNegativeHec1PhysVol->getNChildVols();
1052  int negchildsHec2 = lArNegativeHec2PhysVol->getNChildVols();
1053 
1054  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArPositiveHec1PhysVol->getAbsoluteName()
1055  << " (" << poschildsHec1 << " childs) ." );
1056  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArNegativeHec2PhysVol->getAbsoluteName()
1057  << " (" << poschildsHec2 << " childs) ." );
1058  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArPositiveHec1PhysVol->getAbsoluteName()
1059  << " (" << negchildsHec1 << " childs) ." );
1060  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArNegativeHec2PhysVol->getAbsoluteName()
1061  << " (" << negchildsHec2 << " childs) ." );
1062 
1063  // and the shapes
1064  const GeoShape* lArPositiveHec1Shape = lArPositiveHec1LogVol->getShape();
1065  const GeoShape* lArPositiveHec2Shape = lArPositiveHec2LogVol->getShape();
1066  const GeoShape* lArNegativeHec1Shape = lArNegativeHec1LogVol->getShape();
1067  const GeoShape* lArNegativeHec2Shape = lArNegativeHec2LogVol->getShape();
1068 
1069  // get the transforms
1070  const Amg::Transform3D& lArPositiveHec1Transform = geoAlign
1071  ? lArPositiveHec1PhysVol->getCachedAbsoluteTransform(geoAlign)
1072  : lArPositiveHec1PhysVol->getAbsoluteTransform();
1073  const Amg::Transform3D& lArPositiveHec2Transform = geoAlign
1074  ? lArPositiveHec2PhysVol->getCachedAbsoluteTransform(geoAlign)
1075  : lArPositiveHec2PhysVol->getAbsoluteTransform();
1076  const Amg::Transform3D& lArNegativeHec1Transform = geoAlign
1077  ? lArNegativeHec1PhysVol->getCachedAbsoluteTransform(geoAlign)
1078  : lArNegativeHec1PhysVol->getAbsoluteTransform();
1079  const Amg::Transform3D& lArNegativeHec2Transform = geoAlign
1080  ? lArNegativeHec2PhysVol->getCachedAbsoluteTransform(geoAlign)
1081  : lArNegativeHec2PhysVol->getAbsoluteTransform();
1082 
1083  Amg::Vector3D lArPositiveHec1NomPosition = lArPositiveHec1Transform.translation();
1084  Amg::Vector3D lArPositiveHec2NomPosition = lArPositiveHec2Transform.translation();
1085  Amg::Vector3D lArNegativeHec1NomPosition = lArNegativeHec1Transform.translation();
1086  Amg::Vector3D lArNegativeHec2NomPosition = lArNegativeHec2Transform.translation();
1087 
1088  // dynamic cast to 'Pcon' shape
1089  const GeoPcon* lArPositiveHec1Pcon = dynamic_cast<const GeoPcon*>(lArPositiveHec1Shape);
1090  lArPositiveHec1Bounds = (lArPositiveHec1Pcon) ? Trk::GeoShapeConverter::convert(lArPositiveHec1Pcon,
1091  positiveEndcapZboundariesHec1).release() : nullptr;
1092  const GeoPcon* lArPositiveHec2Pcon = dynamic_cast<const GeoPcon*>(lArPositiveHec2Shape);
1093  lArPositiveHec2Bounds = (lArPositiveHec2Pcon) ? Trk::GeoShapeConverter::convert(lArPositiveHec2Pcon,
1094  positiveEndcapZboundariesHec2).release() : nullptr;
1095  const GeoPcon* lArNegativeHec1Pcon = dynamic_cast<const GeoPcon*>(lArNegativeHec1Shape);
1096  lArNegativeHec1Bounds = (lArNegativeHec1Pcon) ? Trk::GeoShapeConverter::convert(lArNegativeHec1Pcon,
1097  negativeEndcapZboundariesHec1).release() : nullptr;
1098  const GeoPcon* lArNegativeHec2Pcon = dynamic_cast<const GeoPcon*>(lArNegativeHec2Shape);
1099  lArNegativeHec2Bounds = (lArNegativeHec2Pcon) ? Trk::GeoShapeConverter::convert(lArNegativeHec2Pcon,
1100  negativeEndcapZboundariesHec2).release() : nullptr;
1101 
1102  if (lArPositiveHec1Bounds)
1103  ATH_MSG_VERBOSE( " -> Positive Hec1 Bounds: " << *lArPositiveHec1Bounds );
1104  if (lArPositiveHec2Bounds)
1105  ATH_MSG_VERBOSE( " -> Positive Hec2 Bounds: " << *lArPositiveHec2Bounds );
1106 
1107  if (lArNegativeHec1Bounds)
1108  ATH_MSG_VERBOSE( " -> Negative Hec1 Bounds: " << *lArNegativeHec1Bounds );
1109  if (lArNegativeHec2Bounds)
1110  ATH_MSG_VERBOSE( " -> Negative Hec2 Bounds: " << *lArNegativeHec2Bounds );
1111 
1112 
1113  double positiveHec1Zpos = 0.5 *(positiveEndcapZboundariesHec1[1] + positiveEndcapZboundariesHec1[0]);
1114  double positiveHec2Zpos = 0.5 *(positiveEndcapZboundariesHec2[1] + positiveEndcapZboundariesHec2[0]);
1115  double negativeHec1Zpos = -fabs(0.5 *(negativeEndcapZboundariesHec1[1] + negativeEndcapZboundariesHec1[0]));
1116  double negativeHec2Zpos = -fabs(0.5 *(negativeEndcapZboundariesHec2[1] + negativeEndcapZboundariesHec2[0]));
1117 
1118  ATH_MSG_VERBOSE( " Positive parts located at: " << positiveHec1Zpos + lArPositiveHec1NomPosition.z()
1119  << " / " << positiveHec2Zpos + lArPositiveHec2NomPosition.z() );
1120 
1121  ATH_MSG_VERBOSE( " Negative parts located at: " << negativeHec1Zpos + lArNegativeHec1NomPosition.z()
1122  << " / " << negativeHec2Zpos + lArNegativeHec2NomPosition.z() );
1123 
1124  }
1125 
1126  // (3) Browser the FCAL, we construct some things
1127  // from HEC numbers, but we need the radius to build the HEC too
1128  // So we browse the FCAL before building the HEC
1129  // We will build both later
1130  // FCAL1_POS, FCAL1_NEG
1131  // FCAL2_POS, FCAL2_NEG
1132  // FCAL3_POS, FCAL3_NEG
1133  Trk::CylinderVolumeBounds* lArPositiveFcal1Bounds = nullptr;
1134  Trk::CylinderVolumeBounds* lArPositiveFcal2Bounds = nullptr;
1135  Trk::CylinderVolumeBounds* lArPositiveFcal3Bounds = nullptr;
1136 
1137 
1138  Trk::CylinderVolumeBounds* lArNegativeFcal1Bounds = nullptr;
1139  Trk::CylinderVolumeBounds* lArNegativeFcal2Bounds = nullptr;
1140  Trk::CylinderVolumeBounds* lArNegativeFcal3Bounds = nullptr;
1141 
1142  if(detStore()->contains<StoredPhysVol>("FCAL1_POS"))
1143  {
1144  if(detStore()->retrieve(storedPV,"FCAL1_POS")==StatusCode::FAILURE)
1145  {
1146  ATH_MSG_DEBUG( "Unable to retrieve Stored PV FCAL1_POS" );
1147  storedPV = nullptr;
1148  }
1149  }
1150  GeoFullPhysVol* lArPositiveFcal1PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1151 
1152  if(detStore()->contains<StoredPhysVol>("FCAL2_POS"))
1153  {
1154  if(detStore()->retrieve(storedPV,"FCAL2_POS")==StatusCode::FAILURE)
1155  {
1156  ATH_MSG_DEBUG( "Unable to retrieve Stored PV FCAL2_POS" );
1157  storedPV = nullptr;
1158  }
1159  }
1160  GeoFullPhysVol* lArPositiveFcal2PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1161 
1162 
1163  if(detStore()->contains<StoredPhysVol>("FCAL3_POS"))
1164  {
1165  if(detStore()->retrieve(storedPV,"FCAL3_POS")==StatusCode::FAILURE)
1166  {
1167  ATH_MSG_DEBUG( "Unable to retrieve Stored PV FCAL3_POS" );
1168  storedPV = nullptr;
1169  }
1170  }
1171  GeoFullPhysVol* lArPositiveFcal3PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1172 
1173  if(detStore()->contains<StoredPhysVol>("FCAL1_NEG"))
1174  {
1175  if(detStore()->retrieve(storedPV,"FCAL1_NEG")==StatusCode::FAILURE)
1176  {
1177  ATH_MSG_DEBUG( "Unable to retrieve Stored PV FCAL1_NEG" );
1178  storedPV = nullptr;
1179  }
1180  }
1181  GeoFullPhysVol* lArNegativeFcal1PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1182 
1183  if(detStore()->contains<StoredPhysVol>("FCAL2_NEG"))
1184  {
1185  if(detStore()->retrieve(storedPV,"FCAL2_NEG")==StatusCode::FAILURE)
1186  {
1187  ATH_MSG_DEBUG( "Unable to retrieve Stored PV FCAL2_NEG" );
1188  storedPV = nullptr;
1189  }
1190  }
1191  GeoFullPhysVol* lArNegativeFcal2PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1192 
1193  if(detStore()->contains<StoredPhysVol>("FCAL3_NEG"))
1194  {
1195  if(detStore()->retrieve(storedPV,"FCAL3_NEG")==StatusCode::FAILURE)
1196  {
1197  ATH_MSG_DEBUG( "Unable to retrieve Stored PV FCAL3_NEG" );
1198  storedPV = nullptr;
1199  }
1200  }
1201  GeoFullPhysVol* lArNegativeFcal3PhysVol = storedPV ? storedPV->getPhysVol() : nullptr;
1202 
1203  const GeoLogVol* lArPositiveFcal1LogVol = lArPositiveFcal1PhysVol ? lArPositiveFcal1PhysVol->getLogVol() : nullptr;
1204  const GeoLogVol* lArPositiveFcal2LogVol = lArPositiveFcal2PhysVol ? lArPositiveFcal2PhysVol->getLogVol() : nullptr;
1205  const GeoLogVol* lArPositiveFcal3LogVol = lArPositiveFcal3PhysVol ? lArPositiveFcal3PhysVol->getLogVol() : nullptr;
1206 
1207  const GeoLogVol* lArNegativeFcal1LogVol = lArNegativeFcal1PhysVol ? lArNegativeFcal1PhysVol->getLogVol() : nullptr;
1208  const GeoLogVol* lArNegativeFcal2LogVol = lArNegativeFcal2PhysVol ? lArNegativeFcal2PhysVol->getLogVol() : nullptr;
1209  const GeoLogVol* lArNegativeFcal3LogVol = lArNegativeFcal3PhysVol ? lArNegativeFcal3PhysVol->getLogVol() : nullptr;
1210 
1211  // z position - force to be symmetric
1212  double lArFcalHalflength = 0.;
1213  double lArFcalZposition = 0.;
1214  double lArFcalZmin = 0.;
1215  double lArFcalZmax = 0.;
1216 
1217  // retrival worked out
1218  if (lArPositiveFcal1LogVol &&
1219  lArPositiveFcal2LogVol &&
1220  lArPositiveFcal3LogVol &&
1221  lArNegativeFcal1LogVol &&
1222  lArNegativeFcal2LogVol &&
1223  lArNegativeFcal3LogVol){
1224 
1225  int poschildsFcal1 = lArPositiveFcal1PhysVol->getNChildVols();
1226  int poschildsFcal2 = lArPositiveFcal2PhysVol->getNChildVols();
1227  int poschildsFcal3 = lArPositiveFcal3PhysVol->getNChildVols();
1228 
1229  int negchildsFcal1 = lArNegativeFcal1PhysVol->getNChildVols();
1230  int negchildsFcal2 = lArNegativeFcal2PhysVol->getNChildVols();
1231  int negchildsFcal3 = lArNegativeFcal3PhysVol->getNChildVols();
1232 
1233 
1234  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArPositiveFcal1PhysVol->getAbsoluteName()
1235  << " (" << poschildsFcal1 << " childs) ." );
1236  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArPositiveFcal2PhysVol->getAbsoluteName()
1237  << " (" << poschildsFcal2 << " childs) ." );
1238  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArPositiveFcal3PhysVol->getAbsoluteName()
1239  << " (" << poschildsFcal3 << " childs) ." );
1240 
1241  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArNegativeFcal1PhysVol->getAbsoluteName()
1242  << " (" << negchildsFcal1 << " childs) ." );
1243  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArNegativeFcal2PhysVol->getAbsoluteName()
1244  << " (" << negchildsFcal2 << " childs) ." );
1245  ATH_MSG_VERBOSE( " -> Retrieved GeoModel Volume " << lArNegativeFcal3PhysVol->getAbsoluteName()
1246  << " (" << negchildsFcal3 << " childs) ." );
1247 
1248  // and the shapes
1249  const GeoShape* lArPositiveFcal1Shape = lArPositiveFcal1LogVol->getShape();
1250  const GeoShape* lArPositiveFcal2Shape = lArPositiveFcal2LogVol->getShape();
1251  const GeoShape* lArPositiveFcal3Shape = lArPositiveFcal3LogVol->getShape();
1252 
1253  const GeoShape* lArNegativeFcal1Shape = lArNegativeFcal1LogVol->getShape();
1254  const GeoShape* lArNegativeFcal2Shape = lArNegativeFcal2LogVol->getShape();
1255  const GeoShape* lArNegativeFcal3Shape = lArNegativeFcal3LogVol->getShape();
1256 
1257 
1258  // get the transforms
1259  const Amg::Transform3D& lArPositiveFcal1Transform = geoAlign
1260  ? lArPositiveFcal1PhysVol->getCachedAbsoluteTransform(geoAlign)
1261  : lArPositiveFcal1PhysVol->getAbsoluteTransform();
1262  const Amg::Transform3D& lArPositiveFcal2Transform = geoAlign
1263  ? lArPositiveFcal2PhysVol->getCachedAbsoluteTransform(geoAlign)
1264  : lArPositiveFcal2PhysVol->getAbsoluteTransform();
1265  const Amg::Transform3D& lArPositiveFcal3Transform = geoAlign
1266  ? lArPositiveFcal3PhysVol->getCachedAbsoluteTransform(geoAlign)
1267  : lArPositiveFcal3PhysVol->getAbsoluteTransform();
1268 
1269  const Amg::Transform3D& lArNegativeFcal1Transform = geoAlign
1270  ? lArNegativeFcal1PhysVol->getCachedAbsoluteTransform(geoAlign)
1271  : lArNegativeFcal1PhysVol->getAbsoluteTransform();
1272  const Amg::Transform3D& lArNegativeFcal2Transform = geoAlign
1273  ? lArNegativeFcal2PhysVol->getCachedAbsoluteTransform(geoAlign)
1274  : lArNegativeFcal2PhysVol->getAbsoluteTransform();
1275  const Amg::Transform3D& lArNegativeFcal3Transform = geoAlign
1276  ? lArNegativeFcal3PhysVol->getCachedAbsoluteTransform(geoAlign)
1277  : lArNegativeFcal3PhysVol->getAbsoluteTransform();
1278 
1279  Amg::Vector3D lArPositiveFcal1NomPosition = lArPositiveFcal1Transform.translation();
1280  Amg::Vector3D lArPositiveFcal2NomPosition = lArPositiveFcal2Transform.translation();
1281  Amg::Vector3D lArPositiveFcal3NomPosition = lArPositiveFcal3Transform.translation();
1282 
1283  Amg::Vector3D lArNegativeFcal1NomPosition = lArNegativeFcal1Transform.translation();
1284  Amg::Vector3D lArNegativeFcal2NomPosition = lArNegativeFcal2Transform.translation();
1285  Amg::Vector3D lArNegativeFcal3NomPosition = lArNegativeFcal3Transform.translation();
1286 
1287  // dynamic cast to 'Pcon' shape
1288  const GeoTubs* lArPositiveFcal1Tubs = dynamic_cast<const GeoTubs*>(lArPositiveFcal1Shape);
1289  lArPositiveFcal1Bounds = (lArPositiveFcal1Tubs) ? Trk::GeoShapeConverter::convert(lArPositiveFcal1Tubs).release() : nullptr;
1290  const GeoTubs* lArPositiveFcal2Tubs = dynamic_cast<const GeoTubs*>(lArPositiveFcal2Shape);
1291  lArPositiveFcal2Bounds = (lArPositiveFcal2Tubs) ? Trk::GeoShapeConverter::convert(lArPositiveFcal2Tubs).release() : nullptr;
1292  const GeoTubs* lArPositiveFcal3Tubs = dynamic_cast<const GeoTubs*>(lArPositiveFcal3Shape);
1293  lArPositiveFcal3Bounds = (lArPositiveFcal3Tubs) ? Trk::GeoShapeConverter::convert(lArPositiveFcal3Tubs).release() : nullptr;
1294 
1295  const GeoTubs* lArNegativeFcal1Tubs = dynamic_cast<const GeoTubs*>(lArNegativeFcal1Shape);
1296  lArNegativeFcal1Bounds = (lArNegativeFcal1Tubs) ? Trk::GeoShapeConverter::convert(lArNegativeFcal1Tubs).release() : nullptr;
1297  const GeoTubs* lArNegativeFcal2Tubs = dynamic_cast<const GeoTubs*>(lArNegativeFcal2Shape);
1298  lArNegativeFcal2Bounds = (lArNegativeFcal2Tubs) ? Trk::GeoShapeConverter::convert(lArNegativeFcal2Tubs).release() : nullptr;
1299  const GeoTubs* lArNegativeFcal3Tubs = dynamic_cast<const GeoTubs*>(lArNegativeFcal3Shape);
1300  lArNegativeFcal3Bounds = (lArNegativeFcal3Tubs) ? Trk::GeoShapeConverter::convert(lArNegativeFcal3Tubs).release() : nullptr;
1301 
1302  if (lArPositiveFcal1Bounds)
1303  ATH_MSG_VERBOSE( " -> Positive Fcal1 Bounds: " << *lArPositiveFcal1Bounds );
1304  if (lArPositiveFcal2Bounds)
1305  ATH_MSG_VERBOSE( " -> Positive Fcal2 Bounds: " << *lArPositiveFcal2Bounds );
1306  if (lArPositiveFcal3Bounds)
1307  ATH_MSG_VERBOSE( " -> Positive Fcal3 Bounds: " << *lArPositiveFcal3Bounds );
1308 
1309 
1310  if (lArNegativeFcal1Bounds)
1311  ATH_MSG_VERBOSE( " -> Negative Fcal1 Bounds: " << *lArNegativeFcal1Bounds );
1312  if (lArNegativeFcal2Bounds)
1313  ATH_MSG_VERBOSE( " -> Negative Fcal2 Bounds: " << *lArNegativeFcal2Bounds );
1314  if (lArNegativeFcal3Bounds)
1315  ATH_MSG_VERBOSE( " -> Negative Fcal3 Bounds: " << *lArNegativeFcal3Bounds );
1316 
1317 
1318  ATH_MSG_VERBOSE( " Positive parts located at: " << lArPositiveFcal1NomPosition.z()
1319  << " / " << lArPositiveFcal2NomPosition.z() << " / " << lArPositiveFcal3NomPosition.z() );
1320 
1321  ATH_MSG_VERBOSE( " Negative parts located at: " << lArNegativeFcal1NomPosition.z()
1322  << " / " << lArNegativeFcal2NomPosition.z() << " / " << lArNegativeFcal3NomPosition.z() );
1323 
1324  // construct the halflength
1325  // this is actual halflength
1326  // will change to include the cover, but this is left here for future use
1327  lArFcalHalflength = lArPositiveFcal3NomPosition.z() + lArPositiveFcal3Bounds->halflengthZ()
1328  - lArPositiveFcal1NomPosition.z() + lArNegativeFcal1Bounds->halflengthZ();
1329 
1330  lArFcalHalflength *= 0.5;
1331  // construct the z-Position
1332  // this is actual z-Position
1333  // will change to include the cover, but this is left here for future use
1334  lArFcalZposition = lArPositiveFcal3NomPosition.z() + lArPositiveFcal3Bounds->halflengthZ();
1335  lArFcalZposition += lArPositiveFcal1NomPosition.z() - lArNegativeFcal1Bounds->halflengthZ();
1336  lArFcalZposition *= 0.5;
1337  }
1338 
1339  //Building section, we start with the HEC
1340 
1341  // get position and halflength of the Fill-In-Hec
1342  // First HEC, if we do not use calo surface builder will go
1343  // up to sensitive FCAL (too long)
1344  double lArHecZmax = lArFcalZposition - lArFcalHalflength;
1345  double lArHecZmin = 0;
1346  if (lArPositiveEndcap && lArEndcapHalfZ != 0)
1347  lArHecZmin = lArPositiveEndcap->center().z() + lArEndcapHalfZ;
1348  else
1349  ATH_MSG_ERROR("lArPositiveEndcap/Bounds is null!");
1350 
1351  //small offset between caloSurfaceBuilder and GeoModel
1352  double caloSurfZOffset = 0;
1353 
1354  if(m_useCaloSurfBuilder){
1355 
1356  double z, rmin, rmax, hphi, depth;
1358  m_calosurf->get_disk_surface(CaloCell_ID::HEC0, 1, pos, z, rmin, rmax, hphi, depth, &caloDDM);
1359  caloSurfZOffset = lArHecZmin - z;
1360  lArHecZmax = z + depth + caloSurfZOffset;
1361  m_calosurf->get_disk_surface(CaloCell_ID::HEC3, 1, pos, z, rmin, rmax, hphi, depth, &caloDDM);
1362  hecEnd = z + depth + caloSurfZOffset;
1363  }
1364 
1365  // that creates a position
1366  double lArHecZpos = 0.5*(lArHecZmax + lArHecZmin);
1367  double lArHecHalflength = 0.5*(lArHecZmax - lArHecZmin);
1368 
1369  double hecFcalCoverHalflength = 0.5*(hecEnd - lArHecZmax);
1370  double hecFcalCoverZpos = 0.5*(lArHecZmax + hecEnd);
1371 
1372  lArFcalHalflength = hecFcalCoverHalflength;
1373  lArFcalZposition = hecFcalCoverZpos;
1374 
1375  // binned material for HEC : layers only
1376  std::vector<Trk::IdentifiedMaterial> matHEC;
1377  //Trk::MaterialProperties lArHecFcalCoverMaterial = geoMaterialToMaterialProperties.convert(lArPositiveHec1Material);
1378  //Trk::MaterialProperties lArHecFcalCoverMaterial = Trk::MaterialProperties(1., 18.6, 0.00345, 27.);
1379  const Trk::Material* lArHecFcalCoverMaterial=new Trk::Material(18.4, 201.9, 57.2, 26.1, 0.0071);
1380  const Trk::Material* lArHecMaterial = new Trk::Material(19., 224.4, 56.7, 25.8, 0.007);
1381  gc.bin.insert(lArHecFcalCoverMaterial);
1382  gc.bin.insert(lArHecMaterial);
1383 
1384  // layer material can be adjusted here
1385  baseID = Trk::GeometrySignature(Trk::Calo)*1000 + 8;
1386  matHEC.emplace_back(lArHecFcalCoverMaterial->scale(0.13*m_scale_HECmaterial),0);
1387  gc.bin.insert(matHEC.back().first);
1388  matHEC.emplace_back(lArHecMaterial->scale(m_scale_HECmaterial),baseID);
1389  gc.bin.insert(matHEC.back().first);
1390  matHEC.emplace_back(lArHecFcalCoverMaterial->scale(0.93*m_scale_HECmaterial),baseID+1);
1391  gc.bin.insert(matHEC.back().first);
1392  matHEC.emplace_back(lArHecFcalCoverMaterial->scale(1.09*m_scale_HECmaterial),baseID+2);
1393  gc.bin.insert(matHEC.back().first);
1394  matHEC.emplace_back(lArHecFcalCoverMaterial->scale(1.12*m_scale_HECmaterial),baseID+3);
1395  gc.bin.insert(matHEC.back().first);
1396 
1397  // divide the HEC into two parts per EC :
1398  // - fit one around the FCAL - and adopt to LAr Endcap outer radius
1399  if (lArPositiveFcal1Bounds && lArNegativeFcal1Bounds){
1400  // cleanup the HecBounds
1401  delete lArPositiveHec1Bounds; lArPositiveHec1Bounds = nullptr;
1402  delete lArPositiveHec2Bounds; lArPositiveHec2Bounds = nullptr;
1403  delete lArNegativeHec1Bounds; lArNegativeHec1Bounds = nullptr;
1404  delete lArNegativeHec2Bounds; lArNegativeHec2Bounds = nullptr;
1405 
1406  // adopt the boundaries
1407  lArPositiveHecFcalCoverBounds = new Trk::CylinderVolumeBounds(lArPositiveFcal1Bounds->outerRadius(),
1408  lArEndcapOuterRadius,
1409  hecFcalCoverHalflength);
1410 
1411  lArNegativeHecFcalCoverBounds = lArPositiveHecFcalCoverBounds->clone();
1412  // output
1413  ATH_MSG_DEBUG( "Smoothed LAr Hec (Fcal covering part) bounds : " << *lArPositiveHecFcalCoverBounds );
1414  ATH_MSG_DEBUG( " -> at z-position: +/- " << hecFcalCoverZpos );
1415 
1416  // the new HepTransforms
1417  Amg::Vector3D lArPositiveHecFcalCoverPos(0.,0.,hecFcalCoverZpos);
1418  Amg::Vector3D lArPositiveHecFcalCoverNeg(0.,0.,-hecFcalCoverZpos);
1419  Amg::Transform3D* lArPositiveHecFcalCoverTransform = new Amg::Transform3D(Amg::Translation3D(lArPositiveHecFcalCoverPos));
1420  Amg::Transform3D* lArNegativeHecFcalCoverTransform = new Amg::Transform3D(Amg::Translation3D(lArPositiveHecFcalCoverNeg));
1421 
1422  // building dense volume here
1423  Amg::Transform3D* align = nullptr;
1424 
1425  // layer binning in Z
1426  std::vector<float> spCover;
1427  spCover.push_back(hecFcalCoverZpos-hecFcalCoverHalflength);
1428  spCover.push_back(entrySurf[CaloCell_ID::HEC1].first->center().z());
1429  spCover.push_back(entrySurf[CaloCell_ID::HEC2].first->center().z());
1430  spCover.push_back(entrySurf[CaloCell_ID::HEC3].first->center().z());
1431  spCover.push_back(hecFcalCoverZpos+hecFcalCoverHalflength);
1432  Trk::BinUtility* hfp = new Trk::BinUtility(spCover,Trk::open,Trk::binZ);
1433 
1434  // material index
1435  std::vector<size_t> hfc{0,2,3,4};
1436 
1437  // binned material
1438  const Trk::BinnedMaterial* lArHecFcalCoverMaterialBinPos = new Trk::BinnedMaterial( lArHecFcalCoverMaterial,hfp,hfc,matHEC);
1439 
1440  lArPositiveHecFcalCover = new Trk::AlignableTrackingVolume(lArPositiveHecFcalCoverTransform, align,
1441  lArPositiveHecFcalCoverBounds,
1442  lArHecFcalCoverMaterialBinPos,
1443  9,
1444  //hpEntries,
1445  "Calo::Detectors::LAr::PositiveHecFcalCover");
1446  // layer binning in Z
1447  std::vector<float> snCover;
1448  snCover.push_back(-hecFcalCoverZpos-hecFcalCoverHalflength);
1449  snCover.push_back(entrySurf[CaloCell_ID::HEC3].second->center().z());
1450  snCover.push_back(entrySurf[CaloCell_ID::HEC2].second->center().z());
1451  snCover.push_back(entrySurf[CaloCell_ID::HEC1].second->center().z());
1452  snCover.push_back(-hecFcalCoverZpos+hecFcalCoverHalflength);
1454 
1455  // material index
1456  std::vector<size_t> hfcn{4,3,2,0};
1457 
1458  // binned material
1459  const Trk::BinnedMaterial* lArHecFcalCoverMaterialBinNeg = new Trk::BinnedMaterial( lArHecFcalCoverMaterial,hfn,hfcn,matHEC);
1460 
1461  lArNegativeHecFcalCover = new Trk::AlignableTrackingVolume(lArNegativeHecFcalCoverTransform, align,
1462  lArNegativeHecFcalCoverBounds,
1463  lArHecFcalCoverMaterialBinNeg,
1464  9,
1465  //hnEntries,
1466  "Calo::Detectors::LAr::NegativeHecFcalCover");
1467  }
1468 
1469 
1470  // the second part of the HEC between LAr Endcap and FCAL/HEC cover
1471  if (lArPositiveFcal1Bounds && lArEndcapOuterRadius != 0){
1472 
1473  // get the inner radius
1474  // ST Hec lower radius moved up
1475  double lArHecRmin = 0.5*(lArPositiveFcal1Bounds->outerRadius()+lArEndcapInnerRadius);
1476  double lArHecRmax = lArEndcapOuterRadius;
1477  Amg::Vector3D lArHecZposition(0.,0.,lArHecZpos);
1478  // bounds
1479  lArPositiveHecBounds = new Trk::CylinderVolumeBounds(lArHecRmin, lArHecRmax, lArHecHalflength);
1480  lArNegativeHecBounds = lArPositiveHecBounds->clone();
1481  // output
1482  ATH_MSG_DEBUG( "Smoothed LAr Hec bounds : " << *lArPositiveHecBounds );
1483  ATH_MSG_DEBUG( " -> at z-position: +/- " << lArHecZpos );
1484 
1485  // the new HepTransforms
1486  Amg::Vector3D lArPositiveHecPos(0.,0.,lArHecZpos);
1487  Amg::Vector3D lArPositiveHecNeg(0.,0.,-lArHecZpos);
1488  Amg::Transform3D* lArPositiveHecTransform = new Amg::Transform3D(Amg::Translation3D(lArPositiveHecPos));
1489  Amg::Transform3D* lArNegativeHecTransform = new Amg::Transform3D(Amg::Translation3D(lArPositiveHecNeg));
1490 
1491  // building dense volume here
1492  Amg::Transform3D* align = nullptr;
1493 
1494  // layer binning in Z
1495  std::vector<float> sphec;
1496  sphec.push_back(lArHecZpos-lArHecHalflength);
1497  sphec.push_back(entrySurf[CaloCell_ID::HEC0].first->center().z());
1498  sphec.push_back(lArHecZpos+lArHecHalflength);
1500 
1501  // material index
1502  std::vector<size_t> hf{0,1};
1503 
1504  // binned material
1505  const Trk::BinnedMaterial* lArHecMaterialBinPos = new Trk::BinnedMaterial( lArHecMaterial,hp,hf,matHEC);
1506 
1507  lArPositiveHec = new Trk::AlignableTrackingVolume(lArPositiveHecTransform,align,
1508  lArPositiveHecBounds,
1509  lArHecMaterialBinPos,
1510  8,
1511  //hpEntries,
1512  "Calo::Detectors::LAr::PositiveHec");
1513 
1514  // layer binning in Z
1515  std::vector<float> snhec;
1516  snhec.push_back(-lArHecZpos-lArHecHalflength);
1517  snhec.push_back(entrySurf[CaloCell_ID::HEC0].second->center().z());
1518  snhec.push_back(-lArHecZpos+lArHecHalflength);
1520 
1521  // material index
1522  std::vector<size_t> hfn{1,0};
1523 
1524  // binned material
1525  const Trk::BinnedMaterial* lArHecMaterialBinNeg = new Trk::BinnedMaterial( lArHecMaterial,hn,hfn,matHEC);
1526 
1527  lArNegativeHec = new Trk::AlignableTrackingVolume(lArNegativeHecTransform,align,
1528  lArNegativeHecBounds,
1529  lArHecMaterialBinNeg,
1530  8,
1531  //hnEntries,
1532  "Calo::Detectors::LAr::NegativeHec");
1533  }
1534 
1535  // Now the FCAL
1536  // binned material for FCAL : layers only
1537  std::vector<Trk::IdentifiedMaterial> matFCAL;
1538  // convert the Material
1539  const Trk::Material* lArFcalMaterial =new Trk::Material(8.4, 175.5, 100.8, 42.1, 0.0097);
1540  const Trk::Material* lArFcalMaterial0 =new Trk::Material(96., 560., 30.3, 14.3, 0.0025);
1541  gc.bin.insert(lArFcalMaterial);
1542  gc.bin.insert(lArFcalMaterial0);
1543 
1544  // layer material can be adjusted here
1545  baseID = Trk::GeometrySignature(Trk::Calo)*1000 + 20;
1546  matFCAL.emplace_back(lArFcalMaterial0,0);
1547  matFCAL.emplace_back(lArFcalMaterial->scale(0.5),baseID+1);
1548  gc.bin.insert(matFCAL.back().first);
1549  matFCAL.emplace_back(lArFcalMaterial->scale(1.5),baseID+2);
1550  gc.bin.insert(matFCAL.back().first);
1551  matFCAL.emplace_back(lArFcalMaterial->scale(1.4),baseID+3);
1552  gc.bin.insert(matFCAL.back().first);
1553 
1554  // smooth the FCal to Tube form
1555  if (lArPositiveFcal1Bounds && lArPositiveFcal2Bounds && lArPositiveFcal3Bounds &&
1556  lArNegativeFcal1Bounds && lArNegativeFcal2Bounds && lArNegativeFcal3Bounds){
1557 
1558  // get the minimum/maximmum of the three radii - it's the one of FCAL1
1559  double lArFcalRmin = lArPositiveFcal1Bounds->innerRadius();
1560  double lArFcalRmax = lArPositiveFcal1Bounds->outerRadius();
1561  // assign the bounds
1562  lArPositiveFcalBounds = new Trk::CylinderVolumeBounds(lArFcalRmin, lArFcalRmax, lArFcalHalflength);
1563  lArNegativeFcalBounds = lArPositiveFcalBounds->clone();
1564  // output
1565  ATH_MSG_DEBUG( "Smoothed LAr Fcal bounds : " << *lArPositiveFcalBounds );
1566  ATH_MSG_DEBUG( " -> at z-position: +/- " << lArFcalZposition );
1567 
1568  // get min and max for the Layer Creation
1569  lArFcalZmin = lArFcalZposition - lArFcalHalflength;
1570  lArFcalZmax = lArFcalZposition + lArFcalHalflength;
1571 
1572  // cleanup
1573  delete lArPositiveFcal1Bounds; lArPositiveFcal1Bounds = nullptr;
1574  delete lArPositiveFcal2Bounds; lArPositiveFcal2Bounds = nullptr;
1575  delete lArPositiveFcal3Bounds; lArPositiveFcal3Bounds = nullptr;
1576 
1577  delete lArNegativeFcal1Bounds; lArNegativeFcal1Bounds = nullptr;
1578  delete lArNegativeFcal2Bounds; lArNegativeFcal2Bounds = nullptr;
1579  delete lArNegativeFcal3Bounds; lArNegativeFcal3Bounds = nullptr;
1580 
1581  // layer binning in Z
1582  std::vector<float> spfc;
1583  spfc.push_back(lArFcalZmin);
1584  spfc.push_back(entrySurf[CaloCell_ID::FCAL0].first->center().z());
1585  spfc.push_back(entrySurf[CaloCell_ID::FCAL1].first->center().z());
1586  spfc.push_back(entrySurf[CaloCell_ID::FCAL2].first->center().z());
1587  spfc.push_back(lArFcalZmax);
1589 
1590  // material index
1591  std::vector<size_t> hf{0,1,2,3};
1592 
1593  // binned material
1594  const Trk::BinnedMaterial* lArFcalMaterialBinPos = new Trk::BinnedMaterial( lArFcalMaterial,fcp,hf,matFCAL);
1595 
1596  // layer binning in Z
1597  std::vector<float> snfc;
1598  snfc.push_back(-lArFcalZmax);
1599  snfc.push_back(entrySurf[CaloCell_ID::FCAL2].second->center().z());
1600  snfc.push_back(entrySurf[CaloCell_ID::FCAL1].second->center().z());
1601  snfc.push_back(entrySurf[CaloCell_ID::FCAL0].second->center().z());
1602  snfc.push_back(-lArFcalZmin);
1604 
1605  // material index
1606  std::vector<size_t> hfn{3,2,1,0};
1607 
1608  // binned material
1609  const Trk::BinnedMaterial* lArFcalMaterialBinNeg = new Trk::BinnedMaterial( lArFcalMaterial,fcn,hfn,matFCAL);
1610 
1611  // the new HepTransforms
1612  Amg::Vector3D lArPositiveFcalPos(0.,0.,lArFcalZposition);
1613  Amg::Vector3D lArPositiveFcalNeg(0.,0.,-lArFcalZposition);
1614  Amg::Transform3D* lArPositiveFcalTransform = new Amg::Transform3D(Amg::Translation3D(lArPositiveFcalPos));
1615  Amg::Transform3D* lArNegativeFcalTransform = new Amg::Transform3D(Amg::Translation3D(lArPositiveFcalNeg));
1616 
1617  // building dense volume here
1618  Amg::Transform3D* align = nullptr;
1619 
1620  lArPositiveFcal = new Trk::AlignableTrackingVolume(lArPositiveFcalTransform, align,
1621  lArPositiveFcalBounds,
1622  lArFcalMaterialBinPos,
1623  21,
1624  //fcpEntries,
1625  "Calo::Detectors::LAr::PositiveFcal");
1626 
1627  lArNegativeFcal = new Trk::AlignableTrackingVolume(lArNegativeFcalTransform, align,
1628  lArNegativeFcalBounds,
1629  lArFcalMaterialBinNeg,
1630  21,
1631  //fcnEntries,
1632  "Calo::Detectors::LAr::NegativeFcal");
1633  }
1634 
1635  // fill in the inner Gap
1636  // ST this better to be done by CaloTrackingGeometry ( to glue with BeamPipe )
1637  // pass MBTS info to CaloTG
1638  // MBTS
1639  const PVConstLink topEC = lArMgr->getTreeTop(1U);
1640  Amg::Transform3D trIn= topEC->getX(geoAlign);
1641  Amg::Transform3D tr2(trIn);
1642  const PVConstLink mbts= getChild(topEC,"MBTS_mother",trIn);
1643 
1644  float mbtsZ{-1}; // MBTS layer position
1645  float mbts_rmin{0}; // MBTS layer dimensions
1646  float mbts_rmax{0}; // MBTS layer dimensions
1647 
1648  if (mbts) {
1649  //printChildren(mbts,-1,0,Amg::Transform3D(trIn));
1650  const PVConstLink mbts1= getChild(mbts,"MBTS1",trIn);
1651  if (mbts1) mbtsZ=fabs(trIn.translation().z());
1652  if (mbts1) {
1653  ATH_MSG_VERBOSE("MBTS1 layer found at z "<<mbtsZ);
1654  // retrieve Rmin
1655  const GeoLogVol* clv = mbts1->getLogVol();
1656  const GeoTrd* trd=dynamic_cast<const GeoTrd*> (clv->getShape());
1657  if (trd) mbts_rmin = trIn.translation().perp()-trd->getZHalfLength();
1658  }
1659  // retrieve MBTS2 for Rmax
1660  const PVConstLink mbts2= getChild(mbts,"MBTS2",tr2);
1661  if (mbts2) {
1662  const GeoLogVol* clv = mbts2->getLogVol();
1663  const GeoTrd* trd=dynamic_cast<const GeoTrd*> (clv->getShape());
1664  if (trd) mbts_rmax = (tr2.translation().perp()+trd->getZHalfLength())/cos(acos(-1.)/8);
1665  }
1666  ATH_MSG_VERBOSE("MBTS layer span in R "<<mbts_rmin<<","<<mbts_rmax);
1667 
1668  } else {
1669  ATH_MSG_VERBOSE("MBTS not found ");
1670  }
1671 
1672  if (mbtsZ>0. && mbts_rmin>0. && mbts_rmax>0.){
1673  // create the dummy volume to pass on the MBTS position
1674  Trk::CylinderVolumeBounds* lArNegativeMBTSBounds = new Trk::CylinderVolumeBounds(
1675  mbts_rmin,
1676  mbts_rmax,
1677  10. );
1678 
1679  ATH_MSG_DEBUG( "Filled in LAr MBTS bounds : " << *lArNegativeMBTSBounds );
1680  ATH_MSG_DEBUG( " -> at z-position: +/- " << mbtsZ );
1681 
1682 
1683  Amg::Vector3D lArEndcapInnerGapPos(0.,0., mbtsZ);
1684  Amg::Vector3D lArEndcapInnerGapNeg(0.,0.,-mbtsZ);
1685  Amg::Transform3D* lArPositiveMBTSTransform = new Amg::Transform3D(Amg::Translation3D(lArEndcapInnerGapPos));
1686  Amg::Transform3D* lArNegativeMBTSTransform = new Amg::Transform3D(Amg::Translation3D(lArEndcapInnerGapNeg));
1687 
1688  // building dense volume here
1689  lArPositiveEndcapInnerGap = new Trk::TrackingVolume(lArPositiveMBTSTransform,
1690  lArNegativeMBTSBounds->clone(),
1691  dummyMaterial,
1692  dummyLayers, dummyVolumes,
1693  "Calo::Detectors::MBTS");
1694 
1695  lArNegativeEndcapInnerGap = new Trk::TrackingVolume(lArNegativeMBTSTransform,
1696  lArNegativeMBTSBounds,
1697  dummyMaterial,
1698  dummyLayers, dummyVolumes,
1699  "Calo::Detectors::MBTS");
1700  }
1701 
1702  if (msgLvl(MSG::DEBUG)) {
1703  ATH_MSG_DEBUG( "Checking the existence of all Tracking Volumes:" );
1704  ATH_MSG_DEBUG( " -> Calo::Solenoid ");
1705  printCheckResult(msg(MSG::DEBUG), solenoid);
1706  ATH_MSG_DEBUG( " -> Calo::GapVolumes::LAr::SolenoidPresamplerGap ");
1707  printCheckResult(msg(MSG::DEBUG), solenoidLArBarrelGap);
1708  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::BarrelPresampler ");
1709  printCheckResult(msg(MSG::DEBUG), lArBarrelPresampler);
1710  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::Barrel ");
1711  printCheckResult(msg(MSG::DEBUG), lArBarrel);
1712  if (lArPositiveEndcapInnerGap) {
1713  ATH_MSG_DEBUG( " -> Calo::GapVolumes::LAr::PositiveEndcapInnerGap ");
1714  printCheckResult(msg(MSG::DEBUG), lArPositiveEndcapInnerGap);
1715  }
1716  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::PositiveEndcap ");
1717  printCheckResult(msg(MSG::DEBUG), lArPositiveEndcap);
1718  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::PositiveHec ");
1719  printCheckResult(msg(MSG::DEBUG), lArPositiveHec);
1720  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::PositiveFcal ");
1721  printCheckResult(msg(MSG::DEBUG), lArPositiveFcal);
1722  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::LArPositiveHecFcalCover ");
1723  printCheckResult(msg(MSG::DEBUG), lArPositiveHecFcalCover);
1724  if (lArNegativeEndcapInnerGap) {
1725  ATH_MSG_DEBUG( " -> Calo::GapVolumes::LAr::NegativeEndcapInnerGap ");
1726  printCheckResult(msg(MSG::DEBUG), lArNegativeEndcapInnerGap);
1727  }
1728  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::NegativeEndcap ");
1729  printCheckResult(msg(MSG::DEBUG), lArNegativeEndcap);
1730  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::NegativeHec ");
1731  printCheckResult(msg(MSG::DEBUG), lArNegativeHec);
1732  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::NegativeFcal ");
1733  printCheckResult(msg(MSG::DEBUG), lArNegativeFcal);
1734  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::LArNegativeHecFcalCover ");
1735  printCheckResult(msg(MSG::DEBUG), lArNegativeHecFcalCover);
1736  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::LArPositiveECPresampler ");
1737  printCheckResult(msg(MSG::DEBUG), lArPosECPresampler);
1738  ATH_MSG_DEBUG( " -> Calo::Detectors::LAr::LArNegativeECPresampler ");
1739  printCheckResult(msg(MSG::DEBUG), lArNegECPresampler);
1740  } // end of detailed output
1741 
1742  // the return vector
1743  std::vector<Trk::TrackingVolume*>* lArTrackingVolumes = new std::vector<Trk::TrackingVolume*>;
1744 
1745  // check if everything went fine
1746  if (solenoid && solenoidLArBarrelGap && lArBarrelPresampler && lArBarrel &&
1747  lArPositiveEndcap && lArPositiveHec && lArPositiveFcal && lArPositiveHecFcalCover &&
1748  lArNegativeEndcap && lArNegativeHec && lArNegativeFcal && lArNegativeHecFcalCover){
1749 
1750  // + register color code for displaying
1751 
1752  // Barrel Part
1753  lArTrackingVolumes->push_back(solenoid); // 0
1754  solenoid->registerColorCode(6);
1755  lArTrackingVolumes->push_back(solenoidLArBarrelGap); // 1
1756  solenoidLArBarrelGap->registerColorCode(21);
1757  lArTrackingVolumes->push_back(lArBarrelPresampler); // 2
1758  lArBarrelPresampler->registerColorCode(7);
1759  lArTrackingVolumes->push_back(lArBarrel); // 3
1760  lArBarrel->registerColorCode(3);
1761  // Positive Endcap Part
1762  lArTrackingVolumes->push_back(lArPositiveEndcapInnerGap); //4
1763  lArTrackingVolumes->push_back(lArPositiveEndcap); //5
1764  lArPositiveEndcap->registerColorCode(3);
1765  lArTrackingVolumes->push_back(lArPositiveHec); //6
1766  lArPositiveHec->registerColorCode(9);
1767  lArTrackingVolumes->push_back(lArPositiveFcal); //7
1768  lArPositiveFcal->registerColorCode(8);
1769  lArTrackingVolumes->push_back(lArPositiveHecFcalCover); //8
1770  lArPositiveHecFcalCover->registerColorCode(9);
1771  // Positive Endcap Part
1772  lArTrackingVolumes->push_back(lArNegativeEndcapInnerGap); //9
1773  lArTrackingVolumes->push_back(lArNegativeEndcap); //10
1774  lArNegativeEndcap->registerColorCode(3);
1775  lArTrackingVolumes->push_back(lArNegativeHec); //11
1776  lArNegativeHec->registerColorCode(9);
1777  lArTrackingVolumes->push_back(lArNegativeFcal); //12
1778  lArNegativeFcal->registerColorCode(8);
1779  lArTrackingVolumes->push_back(lArNegativeHecFcalCover); //13
1780  lArNegativeHecFcalCover->registerColorCode(9);
1781  lArTrackingVolumes->push_back(lArPosECPresampler); //14
1782  lArPosECPresampler->registerColorCode(7);
1783  lArTrackingVolumes->push_back(lArNegECPresampler); //15
1784  lArNegECPresampler->registerColorCode(7);
1785 
1786  }
1787  return lArTrackingVolumes;
1788 }
1789 
1791 {
1792  if (vol) log << "... ok" << endmsg;
1793  else log << "... missing" << endmsg;
1794 }
1795 
1796 void LAr::LArVolumeBuilder::printInfo(const PVConstLink& pv, const GeoAlignmentStore* gas, int gen) const
1797 {
1798  const GeoLogVol* lv = pv->getLogVol();
1799  ATH_MSG_VERBOSE( "New LAr Object:"<<lv->getName()<<", made of"<<lv->getMaterial()->getName()<<","<<lv->getShape()->type());
1800  const GeoTrd* trd=dynamic_cast<const GeoTrd*> (lv->getShape());
1801  if (trd) ATH_MSG_VERBOSE("trddim:"<< trd->getXHalfLength1()<<","<<trd->getXHalfLength2()<<","<<trd->getYHalfLength1()<<","<<trd->getYHalfLength2()<<","<<trd->getZHalfLength());
1802  const GeoTubs* tub=dynamic_cast<const GeoTubs*> (lv->getShape());
1803  if (tub) ATH_MSG_VERBOSE("tubdim:"<< tub->getRMin()<<","<<tub->getRMax()<<","<<tub->getZHalfLength());
1804  const GeoTube* tube=dynamic_cast<const GeoTube*> (lv->getShape());
1805  if (tube) ATH_MSG_VERBOSE("tubdim:"<< tube->getRMin()<<","<<tube->getRMax()<<","<<tube->getZHalfLength());
1806  const GeoPcon* con=dynamic_cast<const GeoPcon*> (lv->getShape());
1807  if (con) {
1808  const unsigned int nPlanes=con->getNPlanes();
1809  for (unsigned int i=0; i<nPlanes; i++) {
1810  ATH_MSG_VERBOSE("polycone:"<<i<<":"<< con->getRMinPlane(i)<<","<<con->getRMaxPlane(i)<<","<<con->getZPlane(i));
1811  }
1812  }
1813  Amg::Transform3D transf = pv->getX(gas);
1814  ATH_MSG_VERBOSE( "position:"<< "R:"<<transf.translation().perp()<<",phi:"<< transf.translation().phi()<<",x:"<<transf.translation().x()<<",y:"<<transf.translation().y()<<",z:"<<transf.translation().z());
1815  int igen = 0;
1816  printChildren(pv,gen,igen,transf);
1817 }
1818 
1819 void LAr::LArVolumeBuilder::printChildren(const PVConstLink& pv,int gen, int igen, const Amg::Transform3D& trIn) const
1820 {
1821  // subcomponents
1822  unsigned int nc = pv->getNChildVols();
1823  igen++;
1824  if (gen>-1 && igen>gen) return;
1825  std::string cname;
1826  for (unsigned int ic=0; ic<nc; ic++) {
1827  Amg::Transform3D transf = trIn*pv->getXToChildVol(ic);
1828  const PVConstLink cv = pv->getChildVol(ic);
1829  const GeoLogVol* clv = cv->getLogVol();
1830  ATH_MSG_VERBOSE(" ");
1831  ATH_MSG_VERBOSE( "subcomponent:"<<igen<<":"<<ic<<":"<<clv->getName()<<", made of"<<clv->getMaterial()->getName()<<","<<clv->getShape()->type());
1832  ATH_MSG_VERBOSE( "position:"<< "R:"<<transf.translation().perp()<<",phi:"<< transf.translation().phi()<<",x:"<<transf.translation().x()<<",y:"<<transf.translation().y()<<",z:"<<transf.translation().z());
1833  const GeoTrd* trd=dynamic_cast<const GeoTrd*> (clv->getShape());
1834  if (trd) ATH_MSG_VERBOSE("trddim:"<< trd->getXHalfLength1()<<","<<trd->getXHalfLength2()<<","<<trd->getYHalfLength1()<<","<<trd->getYHalfLength2()<<","<<trd->getZHalfLength());
1835  const GeoTubs* tub=dynamic_cast<const GeoTubs*> (clv->getShape());
1836  if (tub) ATH_MSG_VERBOSE("tubdim:"<< tub->getRMin()<<","<<tub->getRMax()<<","<<tub->getZHalfLength());
1837  const GeoTube* tube=dynamic_cast<const GeoTube*> (clv->getShape());
1838  if (tube) ATH_MSG_VERBOSE("tubdim:"<< tube->getRMin()<<","<<tube->getRMax()<<","<<tube->getZHalfLength());
1839  const GeoPcon* con=dynamic_cast<const GeoPcon*> (clv->getShape());
1840  if (con) {
1841  const unsigned int nPlanes=con->getNPlanes();
1842  for (unsigned int i=0; i<nPlanes; i++) {
1843  ATH_MSG_VERBOSE("polycone:"<<i<<":"<< con->getRMinPlane(i)<<","<<con->getRMaxPlane(i)<<","<<con->getZPlane(i));
1844  }
1845  }
1846 
1847  if (ic==0 || cname != clv->getName() ) {
1848  printChildren(cv,gen,igen,transf);
1849  cname = clv->getName();
1850  }
1851  }
1852 
1853 }
1854 
1855 GeoPVConstLink LAr::LArVolumeBuilder::getChild(const GeoPVConstLink& mother, const std::string& name, Amg::Transform3D& trIn) const
1856 {
1857  // subcomponents
1858  for (const GeoVolumeVec_t::value_type& p : geoGetVolumes (&*mother))
1859  {
1860  Amg::Transform3D transf = trIn*p.second;
1861  GeoPVConstLink cv = p.first;
1862  const GeoLogVol* clv = cv->getLogVol();
1863  if (clv->getName().substr(0,name.size())==name) { trIn = transf; return cv; }
1864  GeoPVConstLink next=getChild(cv,name,transf);
1865  if (next) {trIn = transf; return next; }
1866  }
1867  return nullptr;
1868 }
BinnedMaterial.h
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
geoGetVolumes
GeoVolumeVec_t geoGetVolumes(const GeoGraphNode *node, int depthLimit=1, int sizeHint=20)
Return the child volumes and associated transforms.
Definition: GeoVisitVolumes.cxx:211
GeoAlignmentStore
Ensure that the extensions for the Vector3D are properly loaded.
Definition: GeoAlignmentStore.h:24
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
SlidingCylinderSurface.h
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
egammaParameters::depth
@ depth
pointing depth of the shower as calculated in egammaqgcld
Definition: egammaParamDefs.h:276
Example_ReadSampleNoise.hfn
hfn
Definition: Example_ReadSampleNoise.py:46
Trk::SlidingDiscSurface
Definition: SlidingDiscSurface.h:45
LAr::LArVolumeBuilder::printChildren
void printChildren(const GeoPVConstLink &pv, int gen, int igen, const Amg::Transform3D &tr) const
Definition: LArVolumeBuilder.cxx:1819
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
DiscBounds.h
GeometrySignature.h
LAr::LArVolumeBuilder::finalize
virtual StatusCode finalize() override final
AlgTool finalize method.
Definition: LArVolumeBuilder.cxx:83
Trk::binZ
@ binZ
Definition: BinningType.h:49
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
hist_file_dump.d
d
Definition: hist_file_dump.py:143
LArDetectorManager::getTreeTop
virtual PVConstLink getTreeTop(unsigned int i) const override
Gets the ith tree top.
Definition: LArDetectorManager.cxx:21
mat
GeoMaterial * mat
Definition: LArDetectorConstructionTBEC.cxx:55
BinnedArray.h
Trk::BinnedMaterial
Definition: BinnedMaterial.h:38
CaloDepthTool.h
Declaration of CaloDepthTool. Created by Claire Bourdarios, 25.10.2004.
Trk::GeoMaterialConverter::convert
static Material convert(const GeoMaterial *gm)
Single conversion , input type GeoMaterial - output type Trk::MaterialProperties.
Definition: GeoMaterialConverter.cxx:18
DiscLayer.h
bin
Definition: BinsDiffFromStripMedian.h:43
CaloCell_ID_FCS::FCAL1
@ FCAL1
Definition: FastCaloSim_CaloCell_ID.h:41
LAr::LArVolumeBuilder::trackingVolumes
virtual std::vector< Trk::TrackingVolume * > * trackingVolumes(const CaloDetDescrManager &caloDDM, const GeoAlignmentStore *geoAlign) const override final
TrackingVolumeBuilder interface method - returns vector of Volumes.
Definition: LArVolumeBuilder.cxx:96
LArDetectorManager::getNumTreeTops
virtual unsigned int getNumTreeTops() const override
Gets the number of tree tops.
Definition: LArDetectorManager.cxx:26
Trk::binEta
@ binEta
Definition: BinningType.h:54
CaloCell_ID_FCS::HEC2
@ HEC2
Definition: FastCaloSim_CaloCell_ID.h:29
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::Calo
@ Calo
Definition: GeometrySignature.h:28
Trk::TrackingVolume::registerColorCode
void registerColorCode(unsigned int icolor)
Register the color code.
LAr::LArVolumeBuilder::MaterialGarbage
std::set< const Trk::Material * > MaterialGarbage
Definition: LArVolumeBuilder.h:117
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
master.gen
gen
Definition: master.py:32
Trk::BinUtility::bins
size_t bins(size_t ba=0) const
Number of bins.
Definition: BinUtility.h:223
RunTileMonitoring.mbts
mbts
Definition: RunTileMonitoring.py:133
StoredPhysVol
Definition: StoredPhysVol.h:27
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GeometryStatics.h
GeoVisitVolumes.h
Visitor to process all volumes under a GeoModel node.
CylinderVolumeBounds.h
StoredPhysVol::getPhysVol
GeoFullPhysVol * getPhysVol()
Destructor.
Definition: StoredPhysVol.cxx:20
Trk::GeometrySignature
GeometrySignature
Definition: GeometrySignature.h:24
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
beamspotman.steps
int steps
Definition: beamspotman.py:505
CaloCell_ID_FCS::HEC1
@ HEC1
Definition: FastCaloSim_CaloCell_ID.h:28
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
SlidingDiscSurface.h
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
beamspotman.n
n
Definition: beamspotman.py:731
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
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
LAr::LArVolumeBuilder::printCheckResult
static void printCheckResult(MsgStream &log, const Trk::TrackingVolume *vol)
Definition: LArVolumeBuilder.cxx:1790
Trk::SlidingDiscSurface::offset
const std::vector< float > & offset() const
This method allows access to the radial offset values.
Definition: SlidingDiscSurface.h:128
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
CylinderSurface.h
Trk::CylinderVolumeBounds::halflengthZ
double halflengthZ() const
This method returns the halflengthZ.
Definition: CylinderVolumeBounds.h:207
Trk::SlidingCylinderSurface::offset
const std::vector< float > & offset() const
This method allows access to the radial offset values.
Definition: SlidingCylinderSurface.h:82
constants.EME1
int EME1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CylinderLayer.h
Trk::Volume::center
const Amg::Vector3D & center() const
returns the center of the volume
Definition: Volume.h:86
LArDetectorManager
Stored in storegate. Provides access to EMB, EMEC, HEC and FCAL Detector Managers....
Definition: LArDetectorManager.h:26
Trk::BinUtility
Definition: BinUtility.h:39
grepfile.ic
int ic
Definition: grepfile.py:33
LAr::LArVolumeBuilder::getChild
GeoPVConstLink getChild(const GeoPVConstLink &mother, const std::string &name, Amg::Transform3D &trIn) const
Definition: LArVolumeBuilder.cxx:1855
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
GeoAlignmentStore.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
CaloCell_ID_FCS::EME3
@ EME3
Definition: FastCaloSim_CaloCell_ID.h:26
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
GeoMaterialConverter.h
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
LArDetectorManager.h
LAr::LArVolumeBuilder::initialize
virtual StatusCode initialize() override final
AlgTool initialize method.
Definition: LArVolumeBuilder.cxx:63
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
CaloCell_ID_FCS::HEC0
@ HEC0
Definition: FastCaloSim_CaloCell_ID.h:27
Trk::open
@ open
Definition: BinningType.h:40
CylinderBounds.h
Trk::binR
@ binR
Definition: BinningType.h:50
TrackingVolume.h
Trk::GeoShapeConverter::convert
static std::unique_ptr< CylinderVolumeBounds > convert(const GeoTubs *gtub)
Convert a tubs.
Definition: GeoShapeConverter.cxx:57
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
LArVolumeBuilder.h
DeMoScan.first
bool first
Definition: DeMoScan.py:536
DEBUG
#define DEBUG
Definition: page_access.h:11
LAr::LArVolumeBuilder::printInfo
void printInfo(const GeoPVConstLink &pv, const GeoAlignmentStore *gas, int gen=-1) const
Definition: LArVolumeBuilder.cxx:1796
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
Trk::BinUtility::clone
BinUtility * clone() const
Implizit Constructor.
Definition: BinUtility.h:130
python.changerun.pv
pv
Definition: changerun.py:81
GeoShapeConverter.h
DiscSurface.h
Trk::SlidingCylinderSurface
Definition: SlidingCylinderSurface.h:34
Trk::Material::scale
Material * scale(float sf) const
scaling method
Definition: Material.h:239
CaloCell_ID_FCS::FCAL2
@ FCAL2
Definition: FastCaloSim_CaloCell_ID.h:42
Trk::Material
Definition: Material.h:116
LAr::LArVolumeBuilder::LArVolumeBuilder
LArVolumeBuilder(const std::string &, const std::string &, const IInterface *)
AlgTool style constructor.
Definition: LArVolumeBuilder.cxx:50
Trk::BinnedArray
Definition: BinnedArray.h:38
AthAlgTool
Definition: AthAlgTool.h:26
CaloCell_ID_FCS::HEC3
@ HEC3
Definition: FastCaloSim_CaloCell_ID.h:30
CaloCell_ID_FCS::FCAL0
@ FCAL0
Definition: FastCaloSim_CaloCell_ID.h:40
Trk::TrackingVolume
Definition: TrackingVolume.h:121
Trk::CylinderVolumeBounds::clone
CylinderVolumeBounds * clone() const override
Virtual constructor.
Definition: CylinderVolumeBounds.h:171
CaloCell_ID_FCS::EMB3
@ EMB3
Definition: FastCaloSim_CaloCell_ID.h:22
Material
@ Material
Definition: MaterialTypes.h:8
AlignableTrackingVolume.h
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
calibdata.tube
tube
Definition: calibdata.py:31
plotBeamSpotMon.nc
int nc
Definition: plotBeamSpotMon.py:83
Material.h
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
LayerMaterialProperties.h
StoredPhysVol.h
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65
Trk::AlignableTrackingVolume
Definition: AlignableTrackingVolume.h:36