ATLAS Offline Software
SiLayerBuilderImpl.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 
13 
14 #include "InDetIdentifier/SCT_ID.h"
16 
17 // Trk include
22 #include "TrkGeometry/DiscLayer.h"
23 #include "TrkSurfaces/DiscBounds.h"
24 
25 
26 // constructor
27 InDet::SiLayerBuilderImpl::SiLayerBuilderImpl(const std::string& t, const std::string& n, const IInterface* p) :
28  AthAlgTool(t,n,p)
29 {
30 }
31 
32 // Athena standard methods
33 // initialize
35 {
36  ATH_MSG_DEBUG( "initialize()" );
37  // get Pixel Detector Description Manager
38  if (m_pixelCase){
39  const InDetDD::PixelDetectorManager* pixMgr = nullptr;
40  if ((detStore()->retrieve(pixMgr, m_siMgrLocation)).isFailure()) {
41  ATH_MSG_ERROR( "Could not get PixelDetectorManager '" << m_siMgrLocation << "', no layers for Pixel Detector will be built. " );
42  } else {
43  ATH_MSG_VERBOSE( "PixelDetectorManager retrieved with key '" << m_siMgrLocation <<"'." );
44  // assign the detector manager to the silicon manager
45  m_siMgr = pixMgr;
46  if (detStore()->retrieve(m_pixIdHelper, "PixelID").isFailure())
47  ATH_MSG_ERROR("Could not get Pixel ID helper");
48  }
49  } else {
50  const InDetDD::SCT_DetectorManager* sctMgr = nullptr;
51  if ((detStore()->retrieve(sctMgr, m_siMgrLocation)).isFailure()) {
52  ATH_MSG_ERROR( "Could not get SCT_DetectorManager '" << m_siMgrLocation << "', no layers for SCT Detector will be built. " );
53  } else {
54  ATH_MSG_VERBOSE( "SCT_DetectorManager retrieved with key '" << m_siMgrLocation <<"'." );
55  // assign the detector manager to the silicon manager
56  m_siMgr = sctMgr;
57  if (detStore()->retrieve(m_sctIdHelper, "SCT_ID").isFailure())
58  ATH_MSG_ERROR("Could not get SCT ID helper");
59  }
60  }
63  return StatusCode::SUCCESS;
64 }
65 
66 
67 // finalize
69 {
70  ATH_MSG_DEBUG( "finalize() successful" );
71  return StatusCode::SUCCESS;
72 }
73 
74 std::unique_ptr<std::vector< Trk::DiscLayer*> >
76 {
77  // save way to estimate the number of barrels
78  unsigned int endcapLayers = 0;
79  for (int i = 0; i < m_siMgr->numerology().numDiskLayers(); i++) {
80  if (not m_layerIndicesEndcap.empty() and
82  if (m_siMgr->numerology().useDiskLayer(i)) {
83  endcapLayers+=m_siMgr->numerology().numDisksForLayer(i);
84  }
85  }
86 
87  ATH_MSG_DEBUG( "Configured to build " << endcapLayers << " *2 disc-like layers (+ additional support layers)." );
88 
89  // prepare the vectors
90  std::vector<double> discZmin(2*endcapLayers,10e10);
91  std::vector<double> discZmax(2*endcapLayers,-10e10);
92  std::vector<double> discZpos(2*endcapLayers,0.);
93  std::vector<double> discRmin(2*endcapLayers,10e10);
94  std::vector<double> discRmax(2*endcapLayers,0);
95  std::vector<double> discThickness(2*endcapLayers,0.);
96  std::vector<int> discPhiSectors(2*endcapLayers,-1);
97  std::vector<double> discPhiMin(2*endcapLayers,10e10);
98  std::vector<double> discPhiMax(2*endcapLayers,-10e10);
99  std::vector< std::vector<Trk::SurfaceOrderPosition> > discSurfaces(2*endcapLayers, std::vector<Trk::SurfaceOrderPosition>());
100 
101  // let's make sure the discs are ordered in z: that's the z / map index
102  std::map< double, int> discZposLayerIndex;
103 
104  int endcapModules = 0;
105  int sumCheckEndcapModules = 0;
106  unsigned int currentdisk = 0;
107  unsigned int currentring = 0;
108  unsigned int currentlayer = 0;
109 
110  // [-A-] ------------------------ first LOOP over Detector Elements of sensitive layers -------------------------------
111  // -- get the missing dimensions by loop over DetElements
112  const InDetDD::SiDetectorElementCollection::const_iterator sidetBegin = siDetElementCollection.begin();
113  const InDetDD::SiDetectorElementCollection::const_iterator sidetEnd = siDetElementCollection.end();
114  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = sidetBegin;
115  for (; sidetIter != sidetEnd; ++sidetIter){
116  // take it - if
117  // a) you have a detector element ... protection
118  // b) the detector element is EC
119  if ( (*sidetIter) && (*sidetIter)->isEndcap() ){
120  // get the identifier & calculate current layer and current disk from it
121  Identifier currentId((*sidetIter)->identify());
122  currentring = m_pixIdHelper->layer_disk(currentId);
123  if (not m_layerIndicesEndcap.empty() and std::find(m_layerIndicesEndcap.begin(), m_layerIndicesEndcap.end(), currentring) == m_layerIndicesEndcap.end())
124  continue;
125 
126  double currentZ = (*sidetIter)->center().z();
127  currentdisk = (unsigned int)m_pixIdHelper->eta_module(currentId);
128  currentlayer = currentdisk;
129  for (unsigned int i = 0; i < currentring; i++) {
130  if (not m_layerIndicesEndcap.empty() and
131  std::find(m_layerIndicesEndcap.begin(), m_layerIndicesEndcap.end(), i)==m_layerIndicesEndcap.end() ) continue;
132  if (m_siMgr->numerology().useDiskLayer(i)) {
133  currentlayer+=m_siMgr->numerology().numDisksForLayer(i);
134  }
135  }
136  // parse all z positions for the mean value of the discs
137  currentlayer += currentZ > 0. ? endcapLayers : 0;
138 
139  // increase the counter of endcap modules
140  endcapModules++;
141 
142  takeSmallerBigger(discZmin[currentlayer],discZmax[currentlayer],currentZ);
143 
144  // set the disc Rmin / Rmax
145  double currentRmin = (*sidetIter)->rMin();
146  double currentRmax = (*sidetIter)->rMax();
147 
148  // the current phi
149  double currentPhi = (*sidetIter)->center().phi();
150  takeSmaller(discRmin[currentlayer],currentRmin);
151  takeBigger( discRmax[currentlayer],currentRmax);
152 
153  //fill the number of phi sectors for the different rings
154  if (discPhiSectors[currentlayer]<0){
155  ATH_MSG_VERBOSE("Pre-processing Elements from Disk/Layer (id from idHelper): " << currentring << "/" << currentdisk );
156  // get the number of phi sectors
157  unsigned int phiSectorsRing = m_siMgr->numerology().numPhiModulesForLayerDisk(currentring, currentdisk);
158  ATH_MSG_VERBOSE("--> has " << phiSectorsRing << " phi sectors");
159  discPhiSectors[currentlayer]=phiSectorsRing;
160  }
161 // we take the phi / r binning only from the closer to IP module
162  // take phi-min and phimax
163  takeSmaller(discPhiMin[currentlayer],currentPhi);
164  takeBigger(discPhiMax[currentlayer],currentPhi);
165 
166  const InDetDD::SiDetectorElement* detElement = (*sidetIter);
167  // get the center position
168  const Amg::Vector3D& orderPosition = detElement->center();
169  // register the chosen side in the object array
170  // Something like
171  // Trk::SharedObject<Trk::Surface> =
172  // std::make_shared<Trk::Surface>(detElement)) could be fine
173  //
174  // As things are now
175  // 1) Notice that basically we couple the DetElement owned
176  // surface to the Tracking Geometry passing a no-op deleter
177  // (no delete happens) to the shared_ptr(SharedObject is
178  // typedef of shared_ptr)
179  // 2) The const_cast here make the
180  // code non MT safe. For now we handle this by being careful
181  // on lifetimes and non-re-entrant TG construction.
182  Trk::SharedObject<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(&(detElement->surface())),
183  Trk::do_not_delete<Trk::Surface>);
184  Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
185  discSurfaces[currentlayer].push_back(surfaceOrder);
186 
187  } else if (!(*sidetIter))
188  ATH_MSG_WARNING("nullptr to Endcap module given by SCT_DetectorManager! Please check db & dict.xml");
189  } // DetElement loop
190 
191  ATH_MSG_VERBOSE("Estimating the average z position and the radius for each disk.");
192  // get the average z-position per layer & estimate thes thickness
193  for (unsigned int iec=0; iec<2*endcapLayers; ++iec){
194  // average it out
195  discZpos[iec] = 0.5 * (discZmin[iec] + discZmax[iec]);
196  discThickness[iec] = std::abs(discZmax[iec]-discZmin[iec]);
197  // make the map z / index
198  discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
199  }
200 
201  // [-B-] ------------------------ Construction of the layers -----------------------------------
202  // construct the layers
203  auto discLayers = std::make_unique<std::vector< Trk::DiscLayer*> >();
204  std::vector<double>::iterator discZposIter = discZpos.begin();
205  int discCounter = 0;
206 
207  for ( ; discZposIter != discZpos.end(); ++discZposIter){
208  // dynamic estimation 1: estimate the layer thickness dynamically
209  double thickness = discThickness[discCounter]+m_endcapEnvelope;
210 
211  // screen output
212  ATH_MSG_DEBUG( "Building a DiscLayer with single R sectors. " );
213  ATH_MSG_DEBUG( " -> At Z - Position : " << discZpos[discCounter] );
214  ATH_MSG_DEBUG( " -> With Thickness : " << thickness << " i- ncludes envelope tolerance : " << m_endcapEnvelope );
215  ATH_MSG_DEBUG( " -> With Rmin/Rmax (est) : " << discRmin[discCounter] << " / " << discRmax[discCounter] );
216 
217  // prepare the binned array, it can be with one to several rings
218  std::unique_ptr<Trk::BinnedArray<Trk::Surface>> currentBinnedArray = nullptr;
219 
220  double halfPhiStep = M_PI/discPhiSectors[discCounter];
221  // protection in case phi value was fluctuating around 0 or M_PI in parsing
222  if (std::abs(discPhiMin[discCounter]+discPhiMax[discCounter])< halfPhiStep && std::abs(discPhiMin[discCounter]) < 0.5*halfPhiStep ){
223  ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
224  ATH_MSG_VERBOSE(" [0 - ] min phi / max phi detected : " << discPhiMin[discCounter] << " / " <<discPhiMax[discCounter]);
225  discPhiMin[discCounter] += 2*halfPhiStep;
226  }
227 
228  // prepare min phi and max phi & eventually a sub stepvalue
229  ATH_MSG_VERBOSE(" [1 - ] min phi / max phi detected : " << discPhiMin[discCounter] << " / " << discPhiMax[discCounter] );
230  double minPhiCorrected = discPhiMin[discCounter]-halfPhiStep;
231  double maxPhiCorrected = discPhiMax[discCounter]+halfPhiStep;
232  // catch if the minPhi falls below M_PI
233  if (minPhiCorrected < -M_PI){
234  minPhiCorrected += 2*halfPhiStep;
235  maxPhiCorrected += 2*halfPhiStep;
236  }
237 
238  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
239  ATH_MSG_VERBOSE("Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = "
240  << minPhiCorrected << " / " << maxPhiCorrected
241  << " (" << discPhiSectors[discCounter] << ")");
242 
243  Trk::BinUtility* currentBinUtility = new Trk::BinUtility(discPhiSectors[discCounter],
244  minPhiCorrected,
245  maxPhiCorrected,
246  Trk::closed,
247  Trk::binPhi);
248 
249  // a one-dimensional BinnedArray is sufficient
250  currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
251 
252  int discSurfacesNum = (discSurfaces[discCounter]).size();
253  ATH_MSG_DEBUG( "Constructed BinnedArray for DiscLayer with "<< discSurfacesNum << " SubSurfaces." );
254 
255  // always run the geometry validation to catch flaws
256 
257  // checking for :
258  // - empty surface bins
259  // - doubly filled bins
260  std::map< Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
261  std::map< Trk::Surface*,Amg::Vector3D >::iterator usmIter = uniqueSurfaceMap.end();
262  // check the registered surfaces in the binned array
263  Trk::BinnedArraySpan<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
264  size_t dsumCheckSurfaces = 0;
265  double lastPhi = 0.;
266  for (const auto & asurfIter : arraySurfaces){
267  if ( asurfIter ) {
268  ++dsumCheckSurfaces;
269  usmIter = uniqueSurfaceMap.find(asurfIter);
270  lastPhi = asurfIter->center().phi();
271  if ( usmIter != uniqueSurfaceMap.end() )
272  ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << asurfIter->center().eta() << " / " << asurfIter->center().phi());
273  else uniqueSurfaceMap[asurfIter] = asurfIter->center();
274  } else
275  ATH_MSG_WARNING("Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);
276  }
277  sumCheckEndcapModules += dsumCheckSurfaces;
278 
279  ATH_MSG_DEBUG( " -> With Rmin/Rmax : " << discRmin[discCounter] << " / " << discRmax[discCounter] );
280 
281  // get the layer material from the helper method
282  const Trk::LayerMaterialProperties& layerMaterial = endcapLayerMaterial(discRmin[discCounter],discRmax[discCounter]);
283 
284  // position & bounds of the active Layer
285  Amg::Transform3D activeLayerTransform;
286  activeLayerTransform = Amg::Translation3D(0.,0.,discZpos[discCounter]);
287 
288  Trk::DiscBounds* activeLayerBounds = new Trk::DiscBounds(discRmin[discCounter],discRmax[discCounter]);
289  std::vector<Trk::BinUtility*>* binUtils = new std::vector<Trk::BinUtility*>;
290  // prepare the right overlap descriptor
291  auto olDescriptor = std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils, true);
292  Trk::BinnedArraySpan<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
293  // layer creation; deletes currentBinnedArray in baseclass 'Layer' upon destruction
294  // activeLayerTransform deleted in 'Surface' baseclass
295  Trk::DiscLayer* activeLayer = new Trk::DiscLayer(
296  activeLayerTransform, activeLayerBounds, std::move(currentBinnedArray),
297  layerMaterial, thickness, std::move(olDescriptor));
298  // register the layer to the surfaces --- if necessary to the other sie as
299  // well
300  registerSurfacesToLayer(layerSurfaces,*activeLayer);
301  discLayers->push_back(activeLayer);
302  // increase the disc counter by one
303  ++discCounter;
304  }
305 
306  ATH_MSG_DEBUG( endcapModules << " Endcap Modules parsed for Disc Layer dimensions." );
307  ATH_MSG_DEBUG( sumCheckEndcapModules << " Endcap Modules filled in Disc Layer Arrays." );
308  if ( endcapModules-sumCheckEndcapModules )
309  ATH_MSG_WARNING( endcapModules-sumCheckEndcapModules << " Modules not registered properly in binned array." );
310 
311 
312  // sort the vector
313  Trk::DiscLayerSorterZ zSorter;
314  std::vector<Trk::DiscLayer*>::iterator sortIter = discLayers->begin();
315  std::vector<Trk::DiscLayer*>::iterator sortEnd = discLayers->end();
316  std::sort(sortIter, sortEnd, zSorter);
317 
318  // if there are additional layers to be built - never build for the DBM loop
319  if (!m_endcapAdditionalLayerPosZ.empty()){
320  // sort also the additional layer z positions
321  auto addLayerIter = m_endcapAdditionalLayerPosZ.begin();
322  auto addLayerIterEnd = m_endcapAdditionalLayerPosZ.end();
323  auto addLayerTypeIter = m_endcapAdditionalLayerType.begin();
324  // reassign the iterators
325  sortIter = discLayers->begin();
326  sortEnd = discLayers->end();
327  // get the last rmin / rmax
328  double lastRmin = 0.;
329  double lastRmax = 0.;
330  // build the additional layers -------------------------------------------
331  for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
332  // cache befor last parameters are overwritten
333  double layerRmin = lastRmin;
334  double layerRmax = lastRmax;
335  double layerZposition = 0.;
336  // check if the z-position is smaller than the
337  if ( sortIter != sortEnd){
338  // get the current z position to guarantee a symmetrical setup
339  layerZposition = (*sortIter)->surfaceRepresentation().center().z();
340  // get the bounds for the rMin / rMax setting
341  const Trk::DiscBounds* currentBounds = dynamic_cast<const Trk::DiscBounds*>(&((*sortIter)->surfaceRepresentation().bounds()));
342  lastRmin = currentBounds ? currentBounds->rMin() : 0.;
343  lastRmax = currentBounds ? currentBounds->rMax() : 0.;
344  ++sortIter;
345  }
346  if ( addLayerIter != addLayerIterEnd){
347  // symmetric setup around 0.
348  double rMin = layerZposition > 0. ? layerRmin : lastRmin;
349  double rMax = layerZposition > 0. ? layerRmax : lastRmax;
350  // the passive layer
351  Trk::DiscLayer* passiveLayer = nullptr;
352  // passive layer creation
353  Amg::Transform3D passiveDiscTransf = Amg::Transform3D(Amg::Translation3D(0., 0., *addLayerIter));
354  if (*addLayerTypeIter) {
355  ATH_MSG_DEBUG("Building an additional DiscLayer w/o sensitive modules at");
356  // create the material and the passive layer
357  const Trk::LayerMaterialProperties& passiveLayerMaterial = endcapLayerMaterial(rMin, rMax);
358  passiveLayer = new Trk::DiscLayer(passiveDiscTransf,
359  new Trk::DiscBounds(rMin, rMax),
360  passiveLayerMaterial,
361  1. * Gaudi::Units::mm);
362  } else {
363  passiveLayer = new Trk::DiscLayer(passiveDiscTransf,
364  new Trk::DiscBounds(rMin, rMax),
365  nullptr);
366  }
367  ATH_MSG_DEBUG( " -> At Z - Position : " << *addLayerIter );
368  ATH_MSG_DEBUG( " -> With Rmin/Rmax (corr) : " << rMin << " / " << rMax );
369 
370  // increase the iterator and push back the new layer
371  ++addLayerIter;
372  discLayers->push_back(passiveLayer);
373  }
374  } // the additional layers are build ------------------------------------
375 
376  // another round of sorting needed after adding the passive layers
377  sortIter = discLayers->begin();
378  sortEnd = discLayers->end();
379  std::sort(sortIter, sortEnd, zSorter);
380  }
381 
382  ATH_MSG_DEBUG("Returning: " << discLayers->size() << " disk-like layers to the volume builder");
383  for (const auto& dl : (*discLayers)){
384  ATH_MSG_VERBOSE(" ----> Disk layer located at : " << dl->surfaceRepresentation().center().z());
385  }
386 
387  return discLayers;
388 }
389 
390 
391 std::unique_ptr<std::vector< Trk::DiscLayer*> >
392 InDet::SiLayerBuilderImpl::createDiscLayersImpl(const InDetDD::SiDetectorElementCollection& siDetElementCollection, std::unique_ptr<std::vector< Trk::DiscLayer*> > discLayers) const
393 {
394  // this is the DBM flag
395  bool isDBM = (discLayers!=nullptr);
396 
397  // save way to estimate the number of barrels
398  unsigned int endcapLayers = 0;
399  if (isDBM){
400  endcapLayers = m_siMgr->numerology().numDisksDBM();
401  ATH_MSG_DEBUG( "Configured to build " << endcapLayers << "*2 disc-like DBM layers" );
402  } else {
403  for (int i = 0; i < m_siMgr->numerology().numDisks(); i++)
404  if (m_siMgr->numerology().useDisk(i)) endcapLayers++;
405  ATH_MSG_DEBUG( "Configured to build " << endcapLayers << " *2 disc-like layers (+ additional support layers)." );
406  }
407 
408  // prepare the vectors
409  std::vector<double> discZmin(2*endcapLayers,10e10);
410  std::vector<double> discZmax(2*endcapLayers,-10e10);
411  std::vector<double> discZpos(2*endcapLayers,0.);
412  std::vector<double> discRmin(2*endcapLayers,10e10);
413  std::vector<double> discRmax(2*endcapLayers,0);
414  std::vector<double> discThickness(2*endcapLayers,0.);
415 
416  std::vector< std::vector<Trk::SurfaceOrderPosition> > discSurfaces;
417  std::vector< std::vector<int> > discPhiSectors;
418  std::vector< std::vector<double> > discPhiMin;
419  std::vector< std::vector<double> > discPhiMax;
420  std::vector< std::vector<double> > discRingMinR;
421  std::vector< std::vector<double> > discRingMaxR;
422 
423  // let's make sure the discs are ordered in z: that's the z / map index
424  std::map< double, int> discZposLayerIndex;
425 
426  // reserve -- better memory management
427  discPhiMin.reserve(2*endcapLayers);
428  discPhiMax.reserve(2*endcapLayers);
429  discPhiSectors.reserve(2*endcapLayers);
430  discSurfaces.reserve(2*endcapLayers);
431  discRingMinR.reserve(2*endcapLayers);
432  discRingMaxR.reserve(2*endcapLayers);
433 
434  // initialize for checks (pos/neg discs -> 2 times discs)
435  for (unsigned int endcap=0; endcap<2*endcapLayers; endcap++){
436  discPhiMin.emplace_back();
437  discPhiMax.emplace_back();
438  discPhiSectors.emplace_back();
439  discSurfaces.emplace_back( );
440  // auto-detection
441  discRingMinR.emplace_back();
442  discRingMaxR.emplace_back();
443  } // end of for loop
444 
445  int endcapModules = 0;
446  int sumCheckEndcapModules = 0;
447  unsigned int currentlayer = 0;
448  unsigned int currentdisk = 0;
449  unsigned int currentring = 0;
450 
451  // [-A1-] ------------------------ first LOOP over Detector Elements of sensitive layers -------------------------------
452  // -- get the missing dimensions by loop over DetElements
453  const InDetDD::SiDetectorElementCollection::const_iterator sidetBegin = siDetElementCollection.begin();
454  const InDetDD::SiDetectorElementCollection::const_iterator sidetEnd = siDetElementCollection.end();
455  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = sidetBegin;
456  for (; sidetIter != sidetEnd; ++sidetIter){
457  // take it - if
458  // a) you have a detector element ... protection
459  // b) the detector element is EC (in the non-DBM case)
460  // c) the detector elemet is DBM in the DBM case
461  if ( (*sidetIter) && ( (!isDBM && (*sidetIter)->isEndcap()) || (isDBM && (*sidetIter)->isDBM())) ){
462 
463  // increase the counter of endcap modules
464  endcapModules++;
465  // parse all z positions for the mean value of the discs
466  double currentZ = (*sidetIter)->center().z();
467  // get the identifier & calculate current layer and current disk from it
468  Identifier currentId((*sidetIter)->identify());
469  currentdisk = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
470  currentlayer = currentdisk;
471  currentlayer += currentZ > 0. ? endcapLayers : 0;
472 
473  // check the current ring
474  currentring = m_pixIdHelper ? m_pixIdHelper->eta_module(currentId) : m_sctIdHelper->eta_module(currentId);
475 
476  takeSmallerBigger(discZmin[currentlayer],discZmax[currentlayer],currentZ);
477 
478  // set the disc Rmin / Rmax
479  double currentRmin = (*sidetIter)->rMin();
480  double currentRmax = (*sidetIter)->rMax();
481 
482  // how many rings do we have ?
483  unsigned int diskRings = isDBM ?
484  m_siMgr->numerology().numRingsForDiskDBM(currentdisk) :
485  m_siMgr->numerology().numRingsForDisk(currentdisk);
486 
487  // the current phi
488  double currentPhi = (*sidetIter)->center().phi();
489  takeSmaller(discRmin[currentlayer],currentRmin);
490  takeBigger( discRmax[currentlayer],currentRmax);
491 
492  //fill the number of phi sectors for the different rings
493  if (discPhiSectors[currentlayer].empty()){
494  ATH_MSG_VERBOSE("Pre-processing Elements from Disk/Layer (id from idHelper): " << currentdisk << "/" << currentlayer );
495  // prepare the ring bins, initialise the first one to be something big
496  discPhiMin[currentlayer] = std::vector<double>(diskRings,100.);
497  discPhiMax[currentlayer] = std::vector<double>(diskRings,-100.);
498  discRingMinR[currentlayer] = std::vector<double>(diskRings,1e10);
499  discRingMaxR[currentlayer] = std::vector<double>(diskRings,0);
500  // fill the phi sectors
501  ATH_MSG_VERBOSE("-> The current disk has " << diskRings << " ring(s)");
502  for (unsigned int iring=0; iring < diskRings; ++iring){
503  unsigned int phiSectorsRing = isDBM ?
504  m_siMgr->numerology().numPhiModulesForDiskRingDBM(currentdisk, iring) :
505  m_siMgr->numerology().numPhiModulesForDiskRing(currentdisk, iring);
506  // get the number of phi sectors
507  ATH_MSG_VERBOSE("--> Ring " << iring << " has " << phiSectorsRing << " phi sectors");
508  discPhiSectors[currentlayer].push_back(phiSectorsRing);
509  }
510  }
511  // we take the phi / r binning only from the closer to IP module
512  if ( !(*sidetIter)->otherSide() || std::abs(currentZ) < std::abs((*sidetIter)->otherSide()->center().z())){
513  // take phi-min and phimax
514  takeSmaller(discPhiMin[currentlayer][currentring],currentPhi);
515  takeBigger(discPhiMax[currentlayer][currentring],currentPhi);
516  // record the smalles ring & biggest ring radius
517  takeSmaller(discRingMinR[currentlayer][currentring],currentRmin);
518  takeBigger(discRingMaxR[currentlayer][currentring],currentRmax);
519  }
520  } else if (!(*sidetIter))
521  ATH_MSG_WARNING("nullptr to Endcap module given by SCT_DetectorManager! Please check db & dict.xml");
522  } // DetElement loop
523 
524  double minRmin = 10e10;
525  double maxRmax = -10e10;
526 
527  ATH_MSG_VERBOSE("Estimating the average z position and the radius for each disk.");
528  // get the average z-position per layer & estimate thes thickness
529  for (unsigned int iec=0; iec<2*endcapLayers; ++iec){
530  takeSmaller(minRmin,discRmin[iec]); takeBigger(maxRmax,discRmax[iec]);
531  // average it out
532  discZpos[iec] = 0.5 * (discZmin[iec] + discZmax[iec]);
533  discThickness[iec] = isDBM ? 1. : std::abs(discZmax[iec]-discZmin[iec]);
534  // make the map z / index
535  discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
536  }
537 
538  // [-A2-] ------------------------ second LOOP over Detector Elements of sensitive layers -------------------------------
539  // fill the elements for the layers into the surface arrays
540  sidetIter = sidetBegin;
541  for (; sidetIter != sidetEnd; ++sidetIter){
542  // Endcap
543  if ( ((*sidetIter) && ((!isDBM && (*sidetIter)->isEndcap()) || (isDBM && (*sidetIter)->isDBM()))) ){
544  // get the identifier & calculate current layer and current disk from it
545  Identifier currentId((*sidetIter)->identify());
546  currentdisk = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
547  currentlayer = currentdisk;
548  currentlayer += (*sidetIter)->center().z() > 0. ? endcapLayers : 0;
549  // decision which module to take
550  const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();
551  bool takeIt = (!otherSide || std::abs((*sidetIter)->center().z()) < std::abs(otherSide->center().z()) );
552  const InDetDD::SiDetectorElement* chosenSide = takeIt ? (*sidetIter) : otherSide;
553  // get the center position
554  const Amg::Vector3D& orderPosition = chosenSide->center();
555  // register the chosen side in the object array
556  // Something like
557  // Trk::SharedObject<Trk::Surface> =
558  // std::make_shared<Trk::Surface>(detElement)) could be fine
559  //
560  // As things are now
561  // 1) Notice that basically we couple the DetElement owned
562  // surface to the Tracking Geometry passing a no-op deleter
563  // (no delete happens) to the shared_ptr(SharedObject is
564  // typedef of shared_ptr)
565  // 2) The const_cast here make the
566  // code non MT safe. For now we handle this by being careful
567  // on lifetimes and non-re-entrant TG construction.
568 
569  Trk::SharedObject<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(&(chosenSide->surface())),
570  [](Trk::Surface*){});
571  Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
572  if (takeIt) (discSurfaces[currentlayer]).push_back(surfaceOrder);
573  }
574  } //end of filling
575 
576  // [-B-] ------------------------ Construction of the layers -----------------------------------
577  // construct the layers
578  if (!discLayers) {
579  discLayers = std::make_unique<std::vector< Trk::DiscLayer* > >();
580  }
581  std::vector<double>::iterator discZposIter = discZpos.begin();
582  int discCounter = 0;
583 
584  for ( ; discZposIter != discZpos.end(); ++discZposIter){
585  // the gathered R sectors
586  size_t discRsectors = (discPhiSectors[discCounter]).size();
587  // dynamic estimation 1: estimate the layer thickness dynamically
588  double thickness = discThickness[discCounter]+m_endcapEnvelope;
589  // put rMin in and sort the bins
590  std::vector<double> discRingMinRcopy = discRingMinR[discCounter];
591  std::sort(discRingMinRcopy.begin(), discRingMinRcopy.end());
592  bool reverseRsectors = !(discRingMinRcopy == discRingMinR[discCounter]);
593 
594  // this causes a reverse order for the phi sectors
595  if (reverseRsectors){
596  ATH_MSG_VERBOSE("Auto-detect: rings in R are in " << ( reverseRsectors ? "reversed" : "standard") << " order.");
597  std::reverse(discPhiSectors[discCounter].begin(),discPhiSectors[discCounter].end());
598  std::reverse(discPhiMin[discCounter].begin(),discPhiMin[discCounter].end());
599  std::reverse(discPhiMax[discCounter].begin(),discPhiMax[discCounter].end());
600  std::reverse(discRingMaxR[discCounter].begin(),discRingMaxR[discCounter].end());
601  }
602  // preperare the rboundaries
603  std::vector<float> discRboundaries;
604  discRboundaries.push_back(float(*discRingMinRcopy.begin()));
605  for (double & ringMaxRIter : discRingMaxR[discCounter])
606  discRboundaries.push_back(float(ringMaxRIter));
607 
608  // screen output
609  ATH_MSG_DEBUG( "Building a DiscLayer with " << discRsectors << " R sectors. " );
610  ATH_MSG_DEBUG( " -> At Z - Position : " << discZpos[discCounter] );
611  ATH_MSG_DEBUG( " -> With Thickness : " << thickness << " i- ncludes envelope tolerance : " << m_endcapEnvelope );
612  ATH_MSG_DEBUG( " -> With Rmin/Rmax (est) : " << discRmin[discCounter] << " / " << discRmax[discCounter] );
613  ATH_MSG_DEBUG( " -> With Rings : " << discRsectors );
614 
615  for (size_t irings=0; irings<discRsectors; ++irings)
616  ATH_MSG_DEBUG( " --> " << irings << " R sector has " << discPhiSectors[discCounter][irings] << " phi sectors. " );
617 
618  // prepare the binned array, it can be with one to several rings
619  std::unique_ptr<Trk::BinnedArray<Trk::Surface>> currentBinnedArray = nullptr;
620  std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
621  bool weOwnSingleBinUtils{true};
622  if (discRsectors==1){
623  double halfPhiStep = M_PI/discPhiSectors[discCounter][0];
624  // protection in case phi value was fluctuating around 0 or M_PI in parsing
625  if (std::abs(discPhiMin[discCounter][0]+discPhiMax[discCounter][0])< halfPhiStep && std::abs(discPhiMin[discCounter][0]) < 0.5*halfPhiStep ){
626  ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
627  ATH_MSG_VERBOSE(" min phi / max phi detected : " << discPhiMin[discCounter][0] << " / " <<discPhiMax[discCounter][0] );
628  discPhiMin[discCounter][0] += 2*halfPhiStep;
629  }
630  // prepare min phi and max phi & eventually a sub stepvalue
631  ATH_MSG_VERBOSE(" min phi / max phi detected : " << discPhiMin[discCounter][0] << " / " << discPhiMax[discCounter][0] );
632  double minPhiCorrected = discPhiMin[discCounter][0]-halfPhiStep;
633  double maxPhiCorrected = discPhiMax[discCounter][0]+halfPhiStep;
634  // catch if the minPhi falls below M_PI
635  if (minPhiCorrected < -M_PI){
636  minPhiCorrected += 2*halfPhiStep;
637  maxPhiCorrected += 2*halfPhiStep;
638  }
639  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
640 
641  ATH_MSG_VERBOSE("Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = "
642  << minPhiCorrected << " / " << maxPhiCorrected
643  << " (" << discPhiSectors[discCounter][0] << ")");
644  // an easier bin utility can be used
645  Trk::BinUtility* currentBinUtility = new Trk::BinUtility(discPhiSectors[discCounter][0] ,
646  minPhiCorrected,
647  maxPhiCorrected,
648  Trk::closed,
649  Trk::binPhi);
650  // a one-dimensional BinnedArray is sufficient
651  currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
652  } else {
653  ATH_MSG_VERBOSE("Constructing a two-dimensional BinnedArray.");
654  // get the binning in R first (can still be improved with non-aequidistant binning)
655  Trk::BinUtility* currentSteerBinUtility = nullptr;
656  if (m_endcapComplexRingBinning && discRsectors > 1 ){
657  // respecting the actual element boundaires
658  ATH_MSG_VERBOSE("Non-equidistant binning detected.");
659  // now create the bin utility
660  currentSteerBinUtility = new Trk::BinUtility(discRboundaries,
661  Trk::open,
662  Trk::binR);
663  } else
664  currentSteerBinUtility = new Trk::BinUtility(discRsectors,
665  discRmin[discCounter],
666  discRmax[discCounter],
667  Trk::open,
668  Trk::binR);
669  ATH_MSG_VERBOSE("Steering bin utility constructed as : " << *currentSteerBinUtility);
670  // the single phi bin utilities
671  //std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
672  singleBinUtils->reserve(discRsectors);
673  for (size_t irings=0; irings < discRsectors; ++irings){
674  double halfPhiStep = M_PI/discPhiSectors[discCounter][irings];
675  ATH_MSG_VERBOSE(" min phi / max phi detected : " << discPhiMin[discCounter][irings] << " / " << discPhiMax[discCounter][irings] );
676  double minPhiCorrected = discPhiMin[discCounter][irings]-halfPhiStep;
677  double maxPhiCorrected = discPhiMax[discCounter][irings]+halfPhiStep;
678  // catch if the minPhi falls below M_PI
679  if (minPhiCorrected < -M_PI){
680  minPhiCorrected += 2*halfPhiStep;
681  maxPhiCorrected += 2*halfPhiStep;
682  }
683  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
684  ATH_MSG_VERBOSE("Constructing for ring " << irings << " phi utility with phiMin / phiMax (bins) = "
685  << minPhiCorrected << " / " << maxPhiCorrected << " (" << discPhiSectors[discCounter][irings] << ")") ;
686  singleBinUtils->push_back(new Trk::BinUtility(discPhiSectors[discCounter][irings],
687  minPhiCorrected,
688  maxPhiCorrected,
689  Trk::closed,
690  Trk::binPhi));
691  }
692  // a two-dimensional BinnedArray is needed ; takes possession of singleBinUtils and
693  weOwnSingleBinUtils = false;
694  currentBinnedArray =
695  std::make_unique<Trk::BinnedArray1D1D<Trk::Surface>>(
696  discSurfaces[discCounter], currentSteerBinUtility,
697  singleBinUtils);
698  }
699 
700  int discSurfacesNum = (discSurfaces[discCounter]).size();
701  ATH_MSG_DEBUG( "Constructed BinnedArray for DiscLayer with "<< discSurfacesNum << " SubSurfaces." );
702 
703  // always run the geometry validation to catch flaws
704 
705  // checking for :
706  // - empty surface bins
707  // - doubly filled bins
708  std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
709  std::map< const Trk::Surface*,Amg::Vector3D >::iterator usmIter = uniqueSurfaceMap.end();
710  // check the registered surfaces in the binned array
711  Trk::BinnedArraySpan<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
712  size_t dsumCheckSurfaces = 0;
713  double lastPhi = 0.;
714  for (const auto & asurfIter : arraySurfaces){
715  if ( asurfIter ) {
716  ++dsumCheckSurfaces;
717  usmIter = uniqueSurfaceMap.find(asurfIter);
718  lastPhi = asurfIter->center().phi();
719  if ( usmIter != uniqueSurfaceMap.end() )
720  ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << asurfIter->center().eta() << " / " << asurfIter->center().phi());
721  else uniqueSurfaceMap[asurfIter] = asurfIter->center();
722  } else
723  ATH_MSG_WARNING("Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);
724  }
725  sumCheckEndcapModules += dsumCheckSurfaces;
726 
727  ATH_MSG_DEBUG( " -> With Rmin/Rmax (corr) : " << minRmin << " / " << maxRmax );
728 
729  // get the layer material from the helper method
730  const Trk::LayerMaterialProperties& layerMaterial = endcapLayerMaterial(minRmin,maxRmax);
731 
732  // position & bounds of the active Layer
733  Amg::Transform3D activeLayerTransform ;
734  activeLayerTransform = Amg::Translation3D(0.,0.,discZpos[discCounter]);
735 
736  Trk::DiscBounds* activeLayerBounds = new Trk::DiscBounds(minRmin,maxRmax);
737  // prepare the right overlap descriptor
738  std::unique_ptr<Trk::OverlapDescriptor> olDescriptor = nullptr;
739  if (m_pixelCase){
740  olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>();
741  } else {
742  std::vector<Trk::BinUtility*>* binUtils =
743  new std::vector<Trk::BinUtility*>;
744  if (singleBinUtils) {
746  singleBinUtils->begin();
747  for (; binIter != singleBinUtils->end(); ++binIter) {
748  binUtils->push_back((*binIter)->clone());
749  }
750  }
751  // DiscOverlapDescriptor takes possession of binUtils, will delete
752  // it on destruction.
753  // but *does not* manage currentBinnedArray.
754  olDescriptor =
755  std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils);
756  }
757  // register the layer to the surfaces --- if necessary to the other sie
758  // as well
759  Trk::BinnedArraySpan<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
760  // layer creation; deletes currentBinnedArray in baseclass 'Layer' upon destruction
761  // activeLayerTransform deleted in 'Surface' baseclass
762  Trk::DiscLayer* activeLayer =
763  new Trk::DiscLayer(activeLayerTransform, activeLayerBounds,
764  std::move(currentBinnedArray), layerMaterial,
765  thickness, std::move(olDescriptor));
766  registerSurfacesToLayer(layerSurfaces,*activeLayer);
767  discLayers->push_back(activeLayer);
768  // increase the disc counter by one
769  ++discCounter;
770  if (weOwnSingleBinUtils){
771  delete singleBinUtils;
772  singleBinUtils=nullptr;
773  }
774  }
775 
776  // multiply the check modules for SCT case
777  sumCheckEndcapModules *= (m_pixelCase) ? 1 : 2;
778  ATH_MSG_DEBUG( endcapModules << " Endcap Modules parsed for Disc Layer dimensions." );
779  ATH_MSG_DEBUG( sumCheckEndcapModules << " Endcap Modules filled in Disc Layer Arrays." );
780  if ( endcapModules-sumCheckEndcapModules )
781  ATH_MSG_WARNING( endcapModules-sumCheckEndcapModules << " Modules not registered properly in binned array." );
782 
783 
784  // sort the vector
785  Trk::DiscLayerSorterZ zSorter;
786  std::vector<Trk::DiscLayer*>::iterator sortIter = discLayers->begin();
787  std::vector<Trk::DiscLayer*>::iterator sortEnd = discLayers->end();
788  std::sort(sortIter, sortEnd, zSorter);
789 
790  // if there are additional layers to be built - never build for the DBM loop
791  if (!m_endcapAdditionalLayerPosZ.empty() && !isDBM){
792  // sort also the additional layer z positions
793  auto addLayerIter = m_endcapAdditionalLayerPosZ.begin();
794  auto addLayerIterEnd = m_endcapAdditionalLayerPosZ.end();
795  auto addLayerTypeIter = m_endcapAdditionalLayerType.begin();
796  // reassign the iterators
797  sortIter = discLayers->begin();
798  sortEnd = discLayers->end();
799  // get the last rmin / rmax
800  double lastRmin = 0.;
801  double lastRmax = 0.;
802  // build the additional layers -------------------------------------------
803  for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
804  // cache befor last parameters are overwritten
805  double layerRmin = lastRmin;
806  double layerRmax = lastRmax;
807  double layerZposition = 0.;
808  // check if the z-position is smaller than the
809  if ( sortIter != sortEnd){
810  // get the current z position to guarantee a symmetrical setup
811  layerZposition = (*sortIter)->surfaceRepresentation().center().z();
812  // get the bounds for the rMin / rMax setting
813  const Trk::DiscBounds* currentBounds = dynamic_cast<const Trk::DiscBounds*>(&((*sortIter)->surfaceRepresentation().bounds()));
814  lastRmin = currentBounds ? currentBounds->rMin() : 0.;
815  lastRmax = currentBounds ? currentBounds->rMax() : 0.;
816  ++sortIter;
817  }
818  if ( addLayerIter != addLayerIterEnd){
819  // symmetric setup around 0.
820  double rMin = layerZposition > 0. ? layerRmin : lastRmin;
821  double rMax = layerZposition > 0. ? layerRmax : lastRmax;
822  // the passive layer
823  Trk::DiscLayer* passiveLayer = nullptr;
824  // passive layer creation
825  Amg::Transform3D passiveDiscTransf =
826  Amg::Transform3D(Amg::Translation3D(0., 0., *addLayerIter));
827  if (*addLayerTypeIter) {
829  "Building an additional DiscLayer w/o sensitive modules at");
830  // create the material and the passive layer
831  const Trk::LayerMaterialProperties& passiveLayerMaterial =
832  endcapLayerMaterial(rMin, rMax);
833  passiveLayer =
834  new Trk::DiscLayer(passiveDiscTransf,
835  new Trk::DiscBounds(rMin, rMax),
836  passiveLayerMaterial,
837  1. * Gaudi::Units::mm);
838  } else
839  passiveLayer = new Trk::DiscLayer(
840  passiveDiscTransf, new Trk::DiscBounds(rMin, rMax), nullptr);
841  ATH_MSG_DEBUG( " -> At Z - Position : " << *addLayerIter );
842  ATH_MSG_DEBUG( " -> With Rmin/Rmax (corr) : " << rMin << " / " << rMax );
843 
844  // increase the iterator and push back the new layer
845  ++addLayerIter;
846  discLayers->push_back(passiveLayer);
847  }
848  } // the additional layers are build ------------------------------------
849 
850  // another round of sorting needed after adding the passive layers
851  sortIter = discLayers->begin();
852  sortEnd = discLayers->end();
853  std::sort(sortIter, sortEnd, zSorter);
854  }
855 
856  return discLayers;
857 }
858 
859 
860 std::unique_ptr<const std::vector<Trk::CylinderLayer*> >
862 {
863  // sanity check for ID Helper
864  if (!m_pixIdHelper && !m_sctIdHelper){
865  ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
866  return nullptr;
867  }
868 
869  // take the numerology
870  const InDetDD::SiNumerology& siNumerology = m_siMgr->numerology();
871 
872  // pre-set parameters for the run
873  size_t barrelLayers = 0;
874  // save way to estimate the number of barrel layers : they can be deactivated hence the useLayer(i) check
875  for (int i = 0; i < siNumerology.numLayers(); i++)
876  if (siNumerology.useLayer(i)) barrelLayers++;
877 
878  if (not m_layerIndicesBarrel.empty())
879  barrelLayers = m_layerIndicesBarrel.size();
880 
881  // screen output
882  ATH_MSG_DEBUG( "Configured to build " << barrelLayers << " (active) barrel layers (out of " << siNumerology.numLayers() << " )" );
883  if (!m_barrelAdditionalLayerR.empty())
884  ATH_MSG_DEBUG( "Additionally " << m_barrelAdditionalLayerR.size() << " material layers will be built.");
885 
886  // for barrels (the statistics for ordering the modules)
887  std::vector<double> layerRadius(barrelLayers,0.);
888  std::vector<double> layerRmin(barrelLayers,10e10);
889  std::vector<double> layerRmax(barrelLayers,0.);
890  std::vector<double> layerThickness(barrelLayers,0.);
891  std::vector<double> layerMinZ(barrelLayers,0.);
892  std::vector<double> layerMaxZ(barrelLayers,0.);
893  std::vector<double> layerHalfLength(barrelLayers,0.);
894  std::vector<double> layerMinPhi(barrelLayers,0.);
895  std::vector<double> layerMaxPhi(barrelLayers,0.);
896  std::vector<size_t> layerPhiSectors(barrelLayers,0);
897  std::vector<size_t> layerZsectors(barrelLayers,0);
898  std::vector< std::vector<float> > layerZboundaries(barrelLayers, std::vector<float>());
899  std::vector< std::vector< Trk::SurfaceOrderPosition > > layerSurfaces(barrelLayers, std::vector< Trk::SurfaceOrderPosition >());
900 
901  // cache needed
902  double minHalflengthZ = 10e10;
903  double maxHalflengthZ = 0;
904  size_t sumCheckBarrelModules = 0;
905  size_t barrelModules = 0;
906 
907  // [-A-] ------------------------ LOOP over Detector Elements of sensitive layers -----------------------------------
908  // iterate over the detector elements for layer dimension, etc.
909  const InDetDD::SiDetectorElementCollection::const_iterator sidetBegin = siDetElementCollection.begin();
910  const InDetDD::SiDetectorElementCollection::const_iterator sidetEnd = siDetElementCollection.end();
911  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = sidetBegin;
912  for (; sidetIter != sidetEnd; ++sidetIter){
913  // Barrel check
914  if ((*sidetIter) && (*sidetIter)->isBarrel()){
915  // get the identifier
916  Identifier currentId((*sidetIter)->identify());
917  int currentlayerIndex = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
918  if (not m_layerIndicesBarrel.empty()) {
919  if (std::find(m_layerIndicesBarrel.begin(), m_layerIndicesBarrel.end(), currentlayerIndex) == m_layerIndicesBarrel.end())
920  continue;
921  }
922  // unit test
923  ++barrelModules;
924  //skip the layer if it is chosen to be switched off
925  if ( !m_siMgr->numerology().useLayer(currentlayerIndex) ) continue;
926  // get layer index considering possible offset
927  int currentlayer = m_layerIndicesBarrel.empty() ?
928  currentlayerIndex : (currentlayerIndex-m_layerIndicesBarrel.value().at(0));
929  // (A) Determination of phi / eta sectors ---------------------------------------------------
930  // only do the exercise if it hasn't been done already
931  if (layerPhiSectors[currentlayer] == 0){
932  ATH_MSG_VERBOSE("Pre-processing Elements from Layer (id from idHelper): " << currentlayer );
933  // set number of phiSectors
934  layerPhiSectors[currentlayer] = m_siMgr->numerology().numPhiModulesForLayer(currentlayerIndex);
935  // set number of etaSectors
936  layerZsectors[currentlayer] = m_siMgr->numerology().numEtaModulesForLayer(currentlayerIndex);
937  // get the HalfLength of the Layer
938  const InDetDD::SiDetectorElement* countPtr = (*sidetIter);
939  // needed for the complex z binning if activated
940  double lastModuleZ = 0.;
941  std::vector<float> zboundaries;
942  zboundaries.reserve(layerZsectors[currentlayer]+1);
943  // walk all along to negative eta
944  while ((countPtr->prevInEta()))
945  countPtr = countPtr->prevInEta();
946  layerMinZ[currentlayer] = countPtr->center().z() - 0.5*std::abs(countPtr->length());
947  zboundaries.push_back(layerMinZ[currentlayer]);
948  lastModuleZ = countPtr->center().z();
949  // register the layer minZ into the zboundaries
950  // now walk all along to positive eta
951  while ((countPtr->nextInEta())) {
952  countPtr = countPtr->nextInEta();
953  // for complex binning
954  double currentModuleZ = countPtr->center().z();
955  double currentZboundary = 0.5*(lastModuleZ+currentModuleZ);
956  zboundaries.push_back(currentZboundary);
957  lastModuleZ = currentModuleZ;
958  }
959  layerMaxZ[currentlayer] = std::abs(countPtr->center().z()) + 0.5*std::abs(countPtr->length());
960  zboundaries.push_back(layerMaxZ[currentlayer]);
961 
962  // complex z binning mode
963  layerZboundaries[currentlayer] = zboundaries;
964  // chose which one to register for the split mode (SLHC)
965  layerHalfLength[currentlayer] = layerMinZ[currentlayer]*layerMinZ[currentlayer] > layerMaxZ[currentlayer]*layerMaxZ[currentlayer] ?
966  std::abs(layerMinZ[currentlayer]) : layerMaxZ[currentlayer];
967  // get the haflength of the layer
968  takeSmaller( minHalflengthZ, layerHalfLength[currentlayer]);
969  takeBigger( maxHalflengthZ, layerHalfLength[currentlayer]);
970  ATH_MSG_VERBOSE(" -> Determined Layer z range with : " << layerMinZ[currentlayer] << " / " << layerMaxZ[currentlayer] );
971  ATH_MSG_VERBOSE(" -> Symmetric half length taken : " << layerHalfLength[currentlayer]);
972  }
973 
974  // (B) Determination of the radius ------------------------------------------------
975  // getting inner module
976  const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();
977  // take the maximum layer radius
978  double currentR = (*sidetIter)->center().perp();
979  double currentRmax = (*sidetIter)->rMax();
980  double currentRmin = (*sidetIter)->rMin();
981  layerRadius[currentlayer] = (currentR > layerRadius[currentlayer]) ? currentR : layerRadius[currentlayer];
982  if (otherSide){
983  takeBigger( currentRmax, (otherSide)->rMax() );
984  takeSmaller( currentRmin, (otherSide)->rMin() );
985  }
986  takeSmaller( layerRmin[currentlayer], currentRmin );
987  takeBigger( layerRmax[currentlayer], currentRmax );
988 
989  // fill the Surface vector
990  Amg::Vector3D orderPosition((*sidetIter)->center());
991  double currentPhi = orderPosition.phi();
992  takeSmaller( layerMinPhi[currentlayer], currentPhi);
993  takeBigger( layerMaxPhi[currentlayer], currentPhi);
994 
995  // decide which one to register on the Radius: always the one with smaller radius
996  bool takeIt = (!otherSide || (*sidetIter)->center().perp() < otherSide->center().perp() );
997  const Trk::Surface* moduleSurface = takeIt ? (&((*sidetIter)->surface())) : (&(otherSide->surface()));
998 
999  // register the module surface
1000  // Trk::SharedObject<Trk::Surface> =
1001  // std::make_shared<Trk::Surface>(.... some det element)) could be fine
1002  //
1003  // As things are now
1004  // 1) Notice that basically we couple the DetElement owned
1005  // surface to the Tracking Geometry passing a no-op deleter
1006  // (no delete happens) to the shared_ptr(SharedObject is
1007  // typedef of shared_ptr)
1008  // 2) The const_cast here make the
1009  // code non MT safe. For now we handle this by being careful
1010  // on lifetimes and non-re-entrant TG construction.
1011  Trk::SharedObject<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(moduleSurface),
1012  Trk::do_not_delete<Trk::Surface>);
1013 
1014  Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
1015  if (takeIt) (layerSurfaces[currentlayer]).push_back(surfaceOrder);
1016 
1017  } else if (!(*sidetIter)) // barrel check and screen output
1018  ATH_MSG_WARNING("nullptr to Barrel module given by SiDetectorManager! Please check db & dict.xml");
1019 
1020  } // SiDet Loop
1021 
1022  // --------------------------- enf of LOOP over Detector Elements of sensitive layers ----------------------------------
1023 
1024  // [-B-] ------------------------ Construction of the layers -----------------------------------
1025  // [-B-1] construct the detection layers
1026  std::vector< Trk::CylinderLayer* > cylinderDetectionLayers;
1027  int layerCounter = 0;
1028  double currentLayerExtend = 0.;
1029 
1030  // construct detection layers
1031  for (auto& layerRadiusIter : layerRadius) {
1032 
1033  Trk::CylinderLayer* activeLayer = nullptr;
1034  // non-equidistant binning used ? auto-detection
1035  bool nonEquidistantBinning = false;
1036  {
1037  // calculate the average bin size
1038  const double averageBinSize = (layerMaxZ[layerCounter]-layerMinZ[layerCounter])/(layerZsectors[layerCounter]);
1039  const double inv_averageBinSize2 = 1. / (averageBinSize*averageBinSize);
1040  // loop over the boundaries and check if theyare outside the tolerance
1041  auto bIter = layerZboundaries[layerCounter].begin();
1042  auto bIterE = layerZboundaries[layerCounter].end();
1043  for ( ++bIter; bIter != bIterE; ++bIter ){
1044  float cZ = (*bIter);
1045  float pZ = (*(bIter-1));
1046  nonEquidistantBinning = (cZ-pZ)*(cZ-pZ)*inv_averageBinSize2 < (1.-m_barrelEdbTolerance) *(1.-m_barrelEdbTolerance);
1047  if (nonEquidistantBinning){
1048  ATH_MSG_VERBOSE("Non-equidistant binning for (Silicon) Surfaces on this layer with radius " << layerRadiusIter << " detected. ");
1049  ATH_MSG_VERBOSE("Difference " << (cZ-pZ)/averageBinSize << " at a allowed tolerance of : " << m_barrelEdbTolerance );
1050  break;
1051  }
1052  }
1053  }
1054 
1055  //(1) the detecting layer : sensitive modules --------------------------------------------------------------------
1056  // create the BinKeyUtility - the phi binning is identical
1057  double halfPhiStep = M_PI/layerPhiSectors[layerCounter];
1058  // protection in case phi value was fluctuating around 0 or M_PI in parsing
1059  if (std::abs(layerMinPhi[layerCounter]+layerMaxPhi[layerCounter])< halfPhiStep && std::abs(M_PI+layerMinPhi[layerCounter]) < 0.5*halfPhiStep ){
1060  ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
1061  ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
1062  layerMinPhi[layerCounter] += 2*halfPhiStep;
1063  }
1064  // now prepare the phi values
1065  ATH_MSG_VERBOSE("Preparing the Phi-binning for : " << layerPhiSectors[layerCounter] << " sectors.");
1066  ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
1067  double minPhiCorrected = layerMinPhi[layerCounter]-halfPhiStep;
1068  double maxPhiCorrected = layerMaxPhi[layerCounter]+halfPhiStep;
1069  // catch if the minPhi falls below M_PI
1070  if (minPhiCorrected < -M_PI){
1071  minPhiCorrected += 2*halfPhiStep;
1072  maxPhiCorrected += 2*halfPhiStep;
1073  }
1074  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
1075 
1076 
1077  Trk::BinUtility* currentBinUtility = new Trk::BinUtility(layerPhiSectors[layerCounter],
1078  minPhiCorrected,
1079  maxPhiCorrected,
1081  if (nonEquidistantBinning)
1082  (*currentBinUtility) += Trk::BinUtility(layerZboundaries[layerCounter],
1083  Trk::open,
1084  Trk::binZ);
1085  else
1086  (*currentBinUtility) += Trk::BinUtility(layerZsectors[layerCounter],
1087  layerMinZ[layerCounter],
1088  layerMaxZ[layerCounter],
1089  Trk::open,
1090  Trk::binZ);
1091  // creating the binned array output
1092  ATH_MSG_VERBOSE("Creating the binned array for the sensitive detector elements with BinUtility :");
1093  ATH_MSG_VERBOSE( *currentBinUtility );
1094  // the binned array for the senstive surfaces to be built
1095  auto currentBinnedArray =
1096  std::make_unique<Trk::BinnedArray2D<Trk::Surface>>(
1097  layerSurfaces[layerCounter], currentBinUtility);
1098  // unit test for sub surface ordering
1099  Trk::BinnedArraySpan<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
1100 
1102  // checking for :
1103  // - empty surface bins
1104  // - doubly filled bins
1105  std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
1106  auto usmIter = uniqueSurfaceMap.end();
1107  // ------- iterate
1108  auto asurfIter = arraySurfaces.begin();
1109  auto asurfIterEnd = arraySurfaces.end();
1110  for ( ; asurfIter != asurfIterEnd; ++asurfIter){
1111  if ( (*asurfIter) ) {
1112  ++sumCheckBarrelModules;
1113  usmIter = uniqueSurfaceMap.find(*asurfIter);
1114  if ( usmIter != uniqueSurfaceMap.end() )
1115  ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << (*asurfIter)->center().eta() << " / " << (*asurfIter)->center().phi());
1116  else uniqueSurfaceMap[(*asurfIter)] = (*asurfIter)->center();
1117  }
1118  else
1119  ATH_MSG_WARNING("Null surface defined in BinUtility ArraySurfaces vector");
1120  }
1121  }
1122 
1123  // dynamic layer extend
1124  currentLayerExtend = layerHalfLength[layerCounter];
1125 
1126  // dynamic layer extend determined by the sensitive layer dimensions
1127  layerRadius[layerCounter] = 0.5*(layerRmax[layerCounter] + layerRmin[layerCounter]);
1128  layerThickness[layerCounter] = layerRmax[layerCounter] - layerRmin[layerCounter];
1129 
1130  // create the material
1131  const Trk::LayerMaterialProperties& layerMaterial = barrelLayerMaterial(layerRadius[layerCounter], currentLayerExtend);
1132  double currentLayerThickness = layerThickness[layerCounter]+m_barrelEnvelope;
1133 
1134  // screen output
1135  ATH_MSG_DEBUG( "Construct BinnedArray for CylinderLayer with "<< (layerSurfaces[layerCounter]).size() << " SubSurfaces." );
1136  ATH_MSG_DEBUG( "Building a CylinderLayer with " << layerPhiSectors[layerCounter]
1137  << " / " << ( nonEquidistantBinning ? layerZboundaries[layerCounter].size() : layerZsectors[layerCounter] ) << " phi/z bins. " );
1138  ATH_MSG_DEBUG( " -> With Radius : " << layerRadius[layerCounter] );
1139  ATH_MSG_DEBUG( " -> With Thickness : " << currentLayerThickness << " - includes envelope tolerance : " << m_barrelEnvelope );
1140  ATH_MSG_DEBUG( " -> With Zmin/Zmax : " << -currentLayerExtend << " / " << currentLayerExtend );
1141 
1142  if ( nonEquidistantBinning && !layerZboundaries[layerCounter].empty() ){
1143  // overrule the min bin - with the min radius
1144  // do the output to screen
1145  double currentZ = -currentLayerExtend;
1146  msg(MSG::DEBUG) << " -> Z binning at : ";
1147  for (size_t zbin = 0; zbin < layerZboundaries[layerCounter].size(); ++zbin) {
1148  currentZ += layerZboundaries[layerCounter][zbin];
1149  msg(MSG::DEBUG) << currentZ;
1150  if (zbin < layerZboundaries[layerCounter].size()-1)
1151  msg(MSG::DEBUG) << ", ";
1152  }
1153  msg(MSG::DEBUG) << endmsg;
1154  }
1155  // prepare the right overlap descriptor
1156  std::unique_ptr<Trk::OverlapDescriptor> olDescriptor = nullptr;
1157  if (m_pixelCase){
1158  olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>(m_addMoreSurfaces);
1159  }
1160  else {
1161  olDescriptor = std::make_unique<InDet::SCT_OverlapDescriptor>(m_addMoreSurfaces);
1162  }
1163 
1164  Trk::BinnedArraySpan<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
1165  // construct the layer (finally)
1166  activeLayer = new Trk::CylinderLayer(
1167  new Trk::CylinderBounds(layerRadius[layerCounter],
1168  currentLayerExtend),
1169  std::move(currentBinnedArray), layerMaterial,
1170  currentLayerThickness, std::move(olDescriptor));
1171  // register the layer to the surfaces
1172  registerSurfacesToLayer(layerSurfaces,*activeLayer);
1173 
1174  // (3) register the layers
1175  cylinderDetectionLayers.push_back(activeLayer);
1176 
1177  // increase the layer counter --- it is built
1178  ++layerCounter;
1179 
1180  } // layer construction
1181  // --------------------------- enf of detection layer construction loop ----------------------------------
1182 
1183  ATH_MSG_DEBUG("Creating the final CylinderLayer collection with (potentially) additional layers.");
1184  std::unique_ptr<std::vector< Trk::CylinderLayer* > > cylinderLayers
1185  = dressCylinderLayers(cylinderDetectionLayers);
1186 
1187  // multiply the check number in case of SCT
1188  sumCheckBarrelModules *= (m_pixelCase) ? 1 : 2;
1189  ATH_MSG_DEBUG( barrelModules << " Barrel Modules parsed for Cylinder Layer dimenstions." );
1190  ATH_MSG_DEBUG( sumCheckBarrelModules << " Barrel Modules filled in Cylinder Layer Arrays." );
1191  if ( barrelModules-sumCheckBarrelModules )
1192  ATH_MSG_WARNING( barrelModules-sumCheckBarrelModules << " Modules not registered properly in binned array." );
1193 
1194  ATH_MSG_DEBUG("Returning " << cylinderLayers->size() << " cylinder layers.");
1195  return cylinderLayers;
1196 }
1197 
1198 
1199 std::unique_ptr<std::vector<Trk::CylinderLayer*> >
1200 InDet::SiLayerBuilderImpl::dressCylinderLayers(const std::vector<Trk::CylinderLayer*>& detectionLayers ) const {
1201 
1202 
1203  auto cylinderLayers = std::make_unique<std::vector<Trk::CylinderLayer*> >();
1204  // --------------------------- start of additional layer construction loop
1205  // ------------------------------- for the additional layer
1206  if (!m_barrelAdditionalLayerR.empty()){
1207  auto cylLayerIter = detectionLayers.begin();
1208  auto cylLayerIterEnd = detectionLayers.end();
1209  auto addLayerIter = m_barrelAdditionalLayerR.begin();
1210  auto addLayerIterEnd = m_barrelAdditionalLayerR.end();
1211  auto addLayerTypeIter = m_barrelAdditionalLayerType.begin();
1212  auto addLayerTypeIterEnd = m_barrelAdditionalLayerType.end();
1213  double cylLayerExtend = 0;
1214  for ( ; addLayerIter != addLayerIterEnd &&
1215  addLayerTypeIter != addLayerTypeIterEnd; ) {
1216  // build the passive layer if it is smaller the current
1217  // cylLayerIter - or if it is the last one
1218  if ( cylLayerIter == cylLayerIterEnd ||
1219  (*addLayerIter) < (*cylLayerIter)->bounds().r() ) {
1220  cylLayerExtend = (cylLayerIter == cylLayerIterEnd)
1221  ? cylLayerExtend
1222  : (*cylLayerIter)->bounds().halflengthZ() ;
1223  if ((*addLayerTypeIter)) {
1224  ATH_MSG_DEBUG("[- M -] Building an additional CylinderLayer w/o "
1225  "sensitive modules");
1226  // the material for the passive layer
1227  const Trk::LayerMaterialProperties& passiveLayerMaterial =
1228  barrelLayerMaterial(*addLayerIter, cylLayerExtend);
1229  // create the passive layer
1230  cylinderLayers->push_back(new Trk::CylinderLayer(
1231  new Trk::CylinderBounds(*addLayerIter,cylLayerExtend),
1232  passiveLayerMaterial,
1233  1.*Gaudi::Units::mm,
1234  nullptr,
1235  0));
1236  } else {
1237  ATH_MSG_DEBUG("[- N -] Building an additional NavigationLayer for "
1238  "volume dimension control");
1239  // create the passive layer
1240  cylinderLayers->push_back(new Trk::CylinderLayer(
1241  new Trk::CylinderBounds(
1242  *addLayerIter,cylLayerExtend),nullptr));
1243  }
1244  ATH_MSG_DEBUG(" -> With Radius : " << *addLayerIter);
1245  // increase the additional layer radii
1246  ++addLayerIter;
1247  ++addLayerTypeIter;
1248  continue;
1249  }
1250  ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
1251  ATH_MSG_DEBUG(" -> With Radius : " << (*cylLayerIter)->bounds().r());
1252  cylinderLayers->push_back(*cylLayerIter);
1253  ++cylLayerIter;
1254  }
1255  } else
1256  for (const auto & cylLayerIter : detectionLayers ) {
1257  ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
1258  ATH_MSG_DEBUG( " -> With Radius : " << cylLayerIter->bounds().r() );
1259  cylinderLayers->push_back(cylLayerIter);
1260  }
1261  return cylinderLayers;
1262 }
1263 
1266 {
1267  // --------------- material estimation ----------------------------------------------------------------
1268  // -- material with 1D binning
1269  Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -hz, hz, Trk::open, Trk::binZ);
1270  auto & layerBinUtility(layerBinUtilityZ);
1271  if (m_barrelLayerBinsPhi!=1u){ // -- material with 2D binning
1272  Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
1273  -r*M_PI, r*M_PI,
1274  Trk::closed,
1275  Trk::binRPhi);
1276  layerBinUtilityRPhiZ += layerBinUtilityZ;
1277  layerBinUtility = layerBinUtilityRPhiZ;
1278  }
1279  // --------------- material estimation ----------------------------------------------------------------
1280  return Trk::BinnedLayerMaterial(layerBinUtility);
1281 }
1282 
1283 
1285 InDet::SiLayerBuilderImpl::endcapLayerMaterial(double rMin, double rMax) const
1286 {
1287  // --------------- material estimation ----------------------------------------------------------------
1288  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,rMin,rMax,Trk::open, Trk::binR);
1289  if (m_endcapLayerBinsPhi!=1u){ // -- material with 2D binning
1291  layerBinUtilityR += layerBinUtilityPhi;
1292  }
1293  //const auto layerMaterial = Trk::BinnedLayerMaterial(layerBinUtilityR);
1294  // --------------- material estimation ----------------------------------------------------------------
1295  return Trk::BinnedLayerMaterial(layerBinUtilityR);
1296 }
1297 
1300  Trk::Layer& lay) const {
1301  if (!m_setLayerAssociation){
1302  return;
1303  }
1304 
1305  auto laySurfIter = layerSurfaces.begin();
1306  const auto laySurfIterEnd = layerSurfaces.end();
1307  // register the surfaces to the layer
1308  for (; laySurfIter != laySurfIterEnd; ++laySurfIter){
1309  if (*laySurfIter) {
1310  // register the current surface
1311  (**laySurfIter).associateLayer(lay);
1312  const InDetDD::SiDetectorElement* detElement
1313  = dynamic_cast<const InDetDD::SiDetectorElement*>((*laySurfIter)->associatedDetectorElement());
1314  // register the backsise if necessary
1315  const InDetDD::SiDetectorElement* otherSideElement = detElement ? detElement->otherSide() : nullptr;
1316  const Trk::Surface* otherSideSurface = otherSideElement ? &(otherSideElement->surface()) : nullptr;
1317  if (otherSideSurface) {
1318  // Needs care for Athena MT
1319  // we bind again to the detElement owned surface
1320  (const_cast<Trk::Surface&>(*otherSideSurface)).associateLayer(lay);
1321  }
1322  }
1323  }
1324 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
beamspotman.r
def r
Definition: beamspotman.py:676
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
TestSUSYToolsAlg.dl
dl
Definition: TestSUSYToolsAlg.py:83
InDet::SiLayerBuilderImpl::endcapLayerMaterial
const Trk::BinnedLayerMaterial endcapLayerMaterial(double rMin, double rMax) const
Definition: SiLayerBuilderImpl.cxx:1285
InDetDD::SiDetectorManager::numerology
const SiNumerology & numerology() const
Access Numerology.
Definition: SiDetectorManager.h:126
InDetDD::SCT_DetectorManager
Definition: SCT_DetectorManager.h:49
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
InDet::SiLayerBuilderImpl::m_setLayerAssociation
BooleanProperty m_setLayerAssociation
Set Layer Association.
Definition: SiLayerBuilderImpl.h:104
DiscBounds.h
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Trk::binZ
@ binZ
Definition: BinningType.h:49
BinnedArray2D.h
takeSmallerBigger
#define takeSmallerBigger(cSmallest, cBiggest, test)
Definition: RobustTrackingGeometryBuilderImpl.h:45
InDetDD::SolidStateDetectorElementBase::center
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
InDet::SiLayerBuilderImpl::m_SCT_ReadKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCT_ReadKey
Definition: SiLayerBuilderImpl.h:133
InDetDD::SiNumerology::useLayer
bool useLayer(int layer) const
Check if layer exists.
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
DiscLayer.h
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDetDD::SolidStateDetectorElementBase::surface
Trk::Surface & surface()
Element Surface.
DiscOverlapDescriptor.h
InDet::SiLayerBuilderImpl::m_layerIndicesBarrel
IntegerArrayProperty m_layerIndicesBarrel
indices to be used for layer creation (used for ITk specific case)
Definition: SiLayerBuilderImpl.h:127
Trk::closed
@ closed
Definition: BinningType.h:41
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
Trk::DiscBounds::rMax
double rMax() const
This method returns outer radius.
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
InDet::SiLayerBuilderImpl::m_addMoreSurfaces
BooleanProperty m_addMoreSurfaces
to add additional surfaces to the PixelOverlapDescriptor, SCT_OverlapDescriptor and DiscOverlapDescri...
Definition: SiLayerBuilderImpl.h:130
InDet::SiLayerBuilderImpl::m_barrelEdbTolerance
DoubleProperty m_barrelEdbTolerance
tolerance in percent how much the bin sizes can change
Definition: SiLayerBuilderImpl.h:113
InDetDD::SiNumerology::numPhiModulesForDiskRing
int numPhiModulesForDiskRing(int disk, int ring) const
Number of sectors in phi for a ring in a disk.
InDetDD::SiNumerology::numRingsForDiskDBM
int numRingsForDiskDBM(int currentdisk) const
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
takeBigger
#define takeBigger(current, test)
Definition: RobustTrackingGeometryBuilderImpl.h:44
InDet::SiLayerBuilderImpl::m_PixelReadKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_PixelReadKey
Definition: SiLayerBuilderImpl.h:134
InDet::SiLayerBuilderImpl::m_endcapLayerBinsR
UnsignedIntegerProperty m_endcapLayerBinsR
Barrel bins for the material in r.
Definition: SiLayerBuilderImpl.h:118
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
BinnedArray1D.h
InDet::SiLayerBuilderImpl::m_endcapAdditionalLayerType
IntegerArrayProperty m_endcapAdditionalLayerType
material layer 1 - navigation layer 0 ( for volume adjustment )
Definition: SiLayerBuilderImpl.h:117
InDet::SiLayerBuilderImpl::cylindricalLayersImpl
std::unique_ptr< const std::vector< Trk::CylinderLayer * > > cylindricalLayersImpl(const InDetDD::SiDetectorElementCollection &siDetElementCollection) const
Definition: SiLayerBuilderImpl.cxx:861
Trk::DiscBounds::rMin
double rMin() const
This method returns inner radius.
InDet::SiLayerBuilderImpl::m_siMgrLocation
StringProperty m_siMgrLocation
the location of the Pixel Manager
Definition: SiLayerBuilderImpl.h:100
InDet::SiLayerBuilderImpl::m_barrelEnvelope
DoubleProperty m_barrelEnvelope
envelope around rMin/rMax
Definition: SiLayerBuilderImpl.h:112
InDetDD::SiDetectorElement::prevInEta
const SiDetectorElement * prevInEta() const
PixelDetectorManager.h
SiLayerBuilderImpl.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
InDetDD::SiNumerology::numPhiModulesForLayerDisk
int numPhiModulesForLayerDisk(int layer, int disk) const
Number of sectors in phi for a disk in a layer (ITk endcap-specific)
InDet::SiLayerBuilderImpl::m_sctIdHelper
const SCT_ID * m_sctIdHelper
sct Id Helper
Definition: SiLayerBuilderImpl.h:102
InDet::SiLayerBuilderImpl::m_endcapAdditionalLayerPosZ
DoubleArrayProperty m_endcapAdditionalLayerPosZ
Create additional endcaps at these z positions.
Definition: SiLayerBuilderImpl.h:116
lumiFormat.i
int i
Definition: lumiFormat.py:92
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
beamspotman.n
n
Definition: beamspotman.py:731
SCT_OverlapDescriptor.h
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
Trk::CylinderBounds
Definition: CylinderBounds.h:46
Trk::LayerMaterialProperties
Definition: LayerMaterialProperties.h:62
InDetDD::SiNumerology::numDisksDBM
int numDisksDBM() const
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
InDetDD::SiNumerology::useDisk
bool useDisk(int disk) const
Check if disk exists.
InDet::SiLayerBuilderImpl::m_barrelAdditionalLayerType
IntegerArrayProperty m_barrelAdditionalLayerType
material layer 1 - navigation layer 0
Definition: SiLayerBuilderImpl.h:109
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CylinderLayer.h
Trk::DiscLayer
Definition: DiscLayer.h:45
BinnedLayerMaterial.h
InDetDD::SiNumerology::numLayers
int numLayers() const
Number of layers.
Trk::BinnedLayerMaterial
Definition: BinnedLayerMaterial.h:33
InDet::SiLayerBuilderImpl::m_endcapEnvelope
DoubleProperty m_endcapEnvelope
envelope around rMin/rMax
Definition: SiLayerBuilderImpl.h:120
InDet::SiLayerBuilderImpl::createDiscLayersImpl
std::unique_ptr< std::vector< Trk::DiscLayer * > > createDiscLayersImpl(const InDetDD::SiDetectorElementCollection &siDetElementCollection, std::unique_ptr< std::vector< Trk::DiscLayer * > > discLayers=nullptr) const
Definition: SiLayerBuilderImpl.cxx:392
InDet::SiLayerBuilderImpl::m_siMgr
const InDetDD::SiDetectorManager * m_siMgr
the Si Detector Manager
Definition: SiLayerBuilderImpl.h:99
InDet::SiLayerBuilderImpl::m_barrelLayerBinsPhi
UnsignedIntegerProperty m_barrelLayerBinsPhi
Barrel bins for the material in phi.
Definition: SiLayerBuilderImpl.h:111
Trk::BinUtility
Definition: BinUtility.h:39
InDet::SiLayerBuilderImpl::m_barrelAdditionalLayerR
DoubleArrayProperty m_barrelAdditionalLayerR
Create an additional layer at these radii.
Definition: SiLayerBuilderImpl.h:108
Trk::CylinderLayer
Definition: CylinderLayer.h:43
PixelID::layer_disk
int layer_disk(const Identifier &id) const
Definition: PixelID.h:626
InDet::SiLayerBuilderImpl::barrelLayerMaterial
const Trk::BinnedLayerMaterial barrelLayerMaterial(double r, double hz) const
helper method to construct endcap material
Definition: SiLayerBuilderImpl.cxx:1265
PixelID::eta_module
int eta_module(const Identifier &id) const
Definition: PixelID.h:651
InDet::SiLayerBuilderImpl::m_layerIndicesEndcap
IntegerArrayProperty m_layerIndicesEndcap
indices to be used for layer creation (used for ITk specific case)
Definition: SiLayerBuilderImpl.h:128
InDetDD::PixelDetectorManager
Definition: PixelDetectorManager.h:47
InDet::SiLayerBuilderImpl::m_pixIdHelper
const PixelID * m_pixIdHelper
pixel Id Helper
Definition: SiLayerBuilderImpl.h:101
InDetDD::SiDetectorElement::otherSide
const SiDetectorElement * otherSide() const
Useful for SCT only.
isDBM
bool isDBM(uint32_t robId)
Definition: PixelRodDecoder.cxx:45
SCT_ID::layer_disk
int layer_disk(const Identifier &id) const
Definition: SCT_ID.h:734
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
takeSmaller
#define takeSmaller(current, test)
Definition: RobustTrackingGeometryBuilderImpl.h:43
InDetDD::SiNumerology
Definition: SiNumerology.h:27
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
InDet::SiLayerBuilderImpl::m_barrelLayerBinsZ
UnsignedIntegerProperty m_barrelLayerBinsZ
Barrel bins for the material in z.
Definition: SiLayerBuilderImpl.h:110
SiDetectorElement.h
InDetDD::SiNumerology::numPhiModulesForDiskRingDBM
int numPhiModulesForDiskRingDBM(int disk, int ring) const
InDet::SiLayerBuilderImpl::m_endcapComplexRingBinning
BooleanProperty m_endcapComplexRingBinning
make std::vector<R> rings, could be different for layers
Definition: SiLayerBuilderImpl.h:121
Trk::open
@ open
Definition: BinningType.h:40
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
Trk::binR
@ binR
Definition: BinningType.h:50
InDet::SiLayerBuilderImpl::initialize
virtual StatusCode initialize() override
AlgTool initialize method.
Definition: SiLayerBuilderImpl.cxx:34
InDetDD::SiDetectorElement::nextInEta
const SiDetectorElement * nextInEta() const
Trk::SharedObject
std::shared_ptr< T > SharedObject
Definition: SharedObject.h:24
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::binRPhi
@ binRPhi
Definition: BinningType.h:52
InDetDD::SiNumerology::useDiskLayer
bool useDiskLayer(int layer) const
Check if layer exists.
InDetDD::SiNumerology::numDisksForLayer
int numDisksForLayer(int layer) const
Number of disks for a layer (ITk endcap-specific)
DEBUG
#define DEBUG
Definition: page_access.h:11
SCT_ID::eta_module
int eta_module(const Identifier &id) const
Definition: SCT_ID.h:746
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
InDet::SiLayerBuilderImpl::createRingLayersImpl
std::unique_ptr< std::vector< Trk::DiscLayer * > > createRingLayersImpl(const InDetDD::SiDetectorElementCollection &siDetElementCollection) const
Definition: SiLayerBuilderImpl.cxx:75
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
InDet::SiLayerBuilderImpl::m_pixelCase
BooleanProperty m_pixelCase
Common properties.
Definition: SiLayerBuilderImpl.h:98
InDetDD::SiNumerology::numPhiModulesForLayer
int numPhiModulesForLayer(int layer) const
Number of sectors in phi for a layer.
PixelOverlapDescriptor.h
fitman.hz
def hz
Definition: fitman.py:516
InDetDD::SolidStateDetectorElementBase::length
double length() const
Length in eta direction (z - barrel, r - endcap)
AthAlgTool
Definition: AthAlgTool.h:26
InDet::SiLayerBuilderImpl::SiLayerBuilderImpl
SiLayerBuilderImpl(const std::string &, const std::string &, const IInterface *)
AlgTool style constructor.
Definition: SiLayerBuilderImpl.cxx:27
SCT_DetectorManager.h
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
InDetDD::SiNumerology::numRingsForDisk
int numRingsForDisk(int disk) const
Number of rings (ie eta_module) in a disk.
InDet::SiLayerBuilderImpl::dressCylinderLayers
std::unique_ptr< std::vector< Trk::CylinderLayer * > > dressCylinderLayers(const std::vector< Trk::CylinderLayer * > &dLayers) const
helper method to construct barrel material
Definition: SiLayerBuilderImpl.cxx:1200
Trk::BinnedArraySpan
std::span< T > BinnedArraySpan
Definition: BinnedArray.h:34
InDet::SiLayerBuilderImpl::m_endcapLayerBinsPhi
UnsignedIntegerProperty m_endcapLayerBinsPhi
Barrel bins for the material in phi.
Definition: SiLayerBuilderImpl.h:119
InDet::SiLayerBuilderImpl::finalize
virtual StatusCode finalize() override
AlgTool finalize method.
Definition: SiLayerBuilderImpl.cxx:68
InDet::SiLayerBuilderImpl::m_runGeometryValidation
BooleanProperty m_runGeometryValidation
run the validation of the geometry ( no empty bins)
Definition: SiLayerBuilderImpl.h:125
InDetDD::SiNumerology::numEtaModulesForLayer
int numEtaModulesForLayer(int layer) const
Number of sectors in eta for a layer.
Trk::DiscBounds
Definition: DiscBounds.h:44
Trk::SurfaceOrderPosition
std::pair< SharedObject< Surface >, Amg::Vector3D > SurfaceOrderPosition
Definition: HGTD_LayerBuilderCond.h:36
Trk::Layer
Definition: Layer.h:73
InDet::SiLayerBuilderImpl::registerSurfacesToLayer
void registerSurfacesToLayer(Trk::BinnedArraySpan< Trk::Surface *const > &layerSurfaces, Trk::Layer &lay) const
Definition: SiLayerBuilderImpl.cxx:1298
Trk::binPhi
@ binPhi
Definition: BinningType.h:51
Trk::DiscLayerSorterZ
Definition: DiscLayer.h:152