ATLAS Offline Software
SiLayerBuilderImpl.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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"
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();
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  // std::shared_ptr<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  std::shared_ptr<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  auto currentBinUtility = 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  std::span<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  auto activeLayerBounds = std::make_shared<Trk::DiscBounds>(discRmin[discCounter],discRmax[discCounter]);
289  std::vector<Trk::BinUtility> binUtils = std::vector<Trk::BinUtility>();
290  // prepare the right overlap descriptor
291  auto olDescriptor = std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils, true);
292  std::span<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, std::move(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  std::make_shared<Trk::DiscBounds>(rMin, rMax),
360  passiveLayerMaterial,
361  1. * Gaudi::Units::mm);
362  } else {
363  passiveLayer = new Trk::DiscLayer(passiveDiscTransf,
364  std::make_shared<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();
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  // std::shared_ptr<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  std::shared_ptr<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  auto singleBinUtils = std::vector<Trk::BinUtility>();
621  if (discRsectors==1){
622  double halfPhiStep = M_PI/discPhiSectors[discCounter][0];
623  // protection in case phi value was fluctuating around 0 or M_PI in parsing
624  if (std::abs(discPhiMin[discCounter][0]+discPhiMax[discCounter][0])< halfPhiStep && std::abs(discPhiMin[discCounter][0]) < 0.5*halfPhiStep ){
625  ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
626  ATH_MSG_VERBOSE(" min phi / max phi detected : " << discPhiMin[discCounter][0] << " / " <<discPhiMax[discCounter][0] );
627  discPhiMin[discCounter][0] += 2*halfPhiStep;
628  }
629  // prepare min phi and max phi & eventually a sub stepvalue
630  ATH_MSG_VERBOSE(" min phi / max phi detected : " << discPhiMin[discCounter][0] << " / " << discPhiMax[discCounter][0] );
631  double minPhiCorrected = discPhiMin[discCounter][0]-halfPhiStep;
632  double maxPhiCorrected = discPhiMax[discCounter][0]+halfPhiStep;
633  // catch if the minPhi falls below M_PI
634  if (minPhiCorrected < -M_PI){
635  minPhiCorrected += 2*halfPhiStep;
636  maxPhiCorrected += 2*halfPhiStep;
637  }
638  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
639 
640  ATH_MSG_VERBOSE("Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = "
641  << minPhiCorrected << " / " << maxPhiCorrected
642  << " (" << discPhiSectors[discCounter][0] << ")");
643  // an easier bin utility can be used
644  auto currentBinUtility = Trk::BinUtility(discPhiSectors[discCounter][0] ,
645  minPhiCorrected,
646  maxPhiCorrected,
647  Trk::closed,
648  Trk::binPhi);
649  // a one-dimensional BinnedArray is sufficient
650  currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
651  } else {
652  ATH_MSG_VERBOSE("Constructing a two-dimensional BinnedArray.");
653  // get the binning in R first (can still be improved with non-aequidistant binning)
654  Trk::BinUtility currentSteerBinUtility{};
655  if (m_endcapComplexRingBinning && discRsectors > 1 ){
656  // respecting the actual element boundaires
657  ATH_MSG_VERBOSE("Non-equidistant binning detected.");
658  // now create the bin utility
659  currentSteerBinUtility = Trk::BinUtility(discRboundaries,
660  Trk::open,
661  Trk::binR);
662  } else
663  currentSteerBinUtility = Trk::BinUtility(discRsectors,
664  discRmin[discCounter],
665  discRmax[discCounter],
666  Trk::open,
667  Trk::binR);
668  ATH_MSG_VERBOSE("Steering bin utility constructed as : " << currentSteerBinUtility);
669  // the single phi bin utilities
670  //std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
671  singleBinUtils.reserve(discRsectors);
672  for (size_t irings=0; irings < discRsectors; ++irings){
673  double halfPhiStep = M_PI/discPhiSectors[discCounter][irings];
674  ATH_MSG_VERBOSE(" min phi / max phi detected : " << discPhiMin[discCounter][irings] << " / " << discPhiMax[discCounter][irings] );
675  double minPhiCorrected = discPhiMin[discCounter][irings]-halfPhiStep;
676  double maxPhiCorrected = discPhiMax[discCounter][irings]+halfPhiStep;
677  // catch if the minPhi falls below M_PI
678  if (minPhiCorrected < -M_PI){
679  minPhiCorrected += 2*halfPhiStep;
680  maxPhiCorrected += 2*halfPhiStep;
681  }
682  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
683  ATH_MSG_VERBOSE("Constructing for ring " << irings << " phi utility with phiMin / phiMax (bins) = "
684  << minPhiCorrected << " / " << maxPhiCorrected << " (" << discPhiSectors[discCounter][irings] << ")") ;
685  singleBinUtils.emplace_back(discPhiSectors[discCounter][irings],
686  minPhiCorrected,
687  maxPhiCorrected,
688  Trk::closed,
689  Trk::binPhi);
690  }
691  // a two-dimensional BinnedArray is needed
692  currentBinnedArray =
693  std::make_unique<Trk::BinnedArray1D1D<Trk::Surface>>(
694  discSurfaces[discCounter], currentSteerBinUtility,
695  singleBinUtils);
696  }
697 
698  int discSurfacesNum = (discSurfaces[discCounter]).size();
699  ATH_MSG_DEBUG( "Constructed BinnedArray for DiscLayer with "<< discSurfacesNum << " SubSurfaces." );
700 
701  // always run the geometry validation to catch flaws
702  // checking for :
703  // - empty surface bins
704  // - doubly filled bins
705  std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
706  std::map< const Trk::Surface*,Amg::Vector3D >::iterator usmIter = uniqueSurfaceMap.end();
707  // check the registered surfaces in the binned array
708  std::span<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
709  size_t dsumCheckSurfaces = 0;
710  double lastPhi = 0.;
711  for (const auto & asurfIter : arraySurfaces){
712  if ( asurfIter ) {
713  ++dsumCheckSurfaces;
714  usmIter = uniqueSurfaceMap.find(asurfIter);
715  lastPhi = asurfIter->center().phi();
716  if ( usmIter != uniqueSurfaceMap.end() )
717  ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << asurfIter->center().eta() << " / " << asurfIter->center().phi());
718  else uniqueSurfaceMap[asurfIter] = asurfIter->center();
719  } else
720  ATH_MSG_WARNING("Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);
721  }
722  sumCheckEndcapModules += dsumCheckSurfaces;
723 
724  ATH_MSG_DEBUG( " -> With Rmin/Rmax (corr) : " << minRmin << " / " << maxRmax );
725 
726  // get the layer material from the helper method
727  const Trk::LayerMaterialProperties& layerMaterial = endcapLayerMaterial(minRmin,maxRmax);
728 
729  // position & bounds of the active Layer
730  Amg::Transform3D activeLayerTransform ;
731  activeLayerTransform = Amg::Translation3D(0.,0.,discZpos[discCounter]);
732 
733  auto activeLayerBounds = std::make_shared<Trk::DiscBounds>(minRmin,maxRmax);
734  // prepare the right overlap descriptor
735  std::unique_ptr<Trk::OverlapDescriptor> olDescriptor = nullptr;
736  if (m_pixelCase){
737  olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>();
738  } else {
739  auto binUtils = std::vector<Trk::BinUtility>();
740  if (!singleBinUtils.empty()) {
741  auto binIter = singleBinUtils.begin();
742  for (; binIter != singleBinUtils.end(); ++binIter) {
743  binUtils.push_back((*binIter));
744  }
745  }
746  // DiscOverlapDescriptor takes possession of binUtils, will delete
747  // it on destruction.
748  // but *does not* manage currentBinnedArray.
749  olDescriptor =
750  std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils);
751  }
752  // register the layer to the surfaces --- if necessary to the other sie
753  // as well
754  std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
755  // layer creation; deletes currentBinnedArray in baseclass 'Layer' upon destruction
756  // activeLayerTransform deleted in 'Surface' baseclass
757  Trk::DiscLayer* activeLayer =
758  new Trk::DiscLayer(activeLayerTransform, std::move(activeLayerBounds),
759  std::move(currentBinnedArray), layerMaterial,
760  thickness, std::move(olDescriptor));
761  registerSurfacesToLayer(layerSurfaces,*activeLayer);
762  discLayers->push_back(activeLayer);
763  // increase the disc counter by one
764  ++discCounter;
765  }
766 
767  // multiply the check modules for SCT case
768  sumCheckEndcapModules *= (m_pixelCase) ? 1 : 2;
769  ATH_MSG_DEBUG( endcapModules << " Endcap Modules parsed for Disc Layer dimensions." );
770  ATH_MSG_DEBUG( sumCheckEndcapModules << " Endcap Modules filled in Disc Layer Arrays." );
771  if ( endcapModules-sumCheckEndcapModules )
772  ATH_MSG_WARNING( endcapModules-sumCheckEndcapModules << " Modules not registered properly in binned array." );
773 
774 
775  // sort the vector
776  Trk::DiscLayerSorterZ zSorter;
777  std::vector<Trk::DiscLayer*>::iterator sortIter = discLayers->begin();
778  std::vector<Trk::DiscLayer*>::iterator sortEnd = discLayers->end();
779  std::sort(sortIter, sortEnd, zSorter);
780 
781  // if there are additional layers to be built - never build for the DBM loop
782  if (!m_endcapAdditionalLayerPosZ.empty() && !isDBM){
783  // sort also the additional layer z positions
784  auto addLayerIter = m_endcapAdditionalLayerPosZ.begin();
785  auto addLayerIterEnd = m_endcapAdditionalLayerPosZ.end();
786  auto addLayerTypeIter = m_endcapAdditionalLayerType.begin();
787  // reassign the iterators
788  sortIter = discLayers->begin();
789  sortEnd = discLayers->end();
790  // get the last rmin / rmax
791  double lastRmin = 0.;
792  double lastRmax = 0.;
793  // build the additional layers -------------------------------------------
794  for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
795  // cache befor last parameters are overwritten
796  double layerRmin = lastRmin;
797  double layerRmax = lastRmax;
798  double layerZposition = 0.;
799  // check if the z-position is smaller than the
800  if ( sortIter != sortEnd){
801  // get the current z position to guarantee a symmetrical setup
802  layerZposition = (*sortIter)->surfaceRepresentation().center().z();
803  // get the bounds for the rMin / rMax setting
804  const Trk::DiscBounds* currentBounds = dynamic_cast<const Trk::DiscBounds*>(&((*sortIter)->surfaceRepresentation().bounds()));
805  lastRmin = currentBounds ? currentBounds->rMin() : 0.;
806  lastRmax = currentBounds ? currentBounds->rMax() : 0.;
807  ++sortIter;
808  }
809  if ( addLayerIter != addLayerIterEnd){
810  // symmetric setup around 0.
811  double rMin = layerZposition > 0. ? layerRmin : lastRmin;
812  double rMax = layerZposition > 0. ? layerRmax : lastRmax;
813  // the passive layer
814  Trk::DiscLayer* passiveLayer = nullptr;
815  // passive layer creation
816  Amg::Transform3D passiveDiscTransf =
817  Amg::Transform3D(Amg::Translation3D(0., 0., *addLayerIter));
818  if (*addLayerTypeIter) {
820  "Building an additional DiscLayer w/o sensitive modules at");
821  // create the material and the passive layer
822  const Trk::LayerMaterialProperties& passiveLayerMaterial =
823  endcapLayerMaterial(rMin, rMax);
824  passiveLayer =
825  new Trk::DiscLayer(passiveDiscTransf,
826  std::make_shared<Trk::DiscBounds>(rMin, rMax),
827  passiveLayerMaterial,
828  1. * Gaudi::Units::mm);
829  } else
830  passiveLayer = new Trk::DiscLayer(
831  passiveDiscTransf, std::make_shared<Trk::DiscBounds>(rMin, rMax), nullptr);
832  ATH_MSG_DEBUG( " -> At Z - Position : " << *addLayerIter );
833  ATH_MSG_DEBUG( " -> With Rmin/Rmax (corr) : " << rMin << " / " << rMax );
834 
835  // increase the iterator and push back the new layer
836  ++addLayerIter;
837  discLayers->push_back(passiveLayer);
838  }
839  } // the additional layers are build ------------------------------------
840 
841  // another round of sorting needed after adding the passive layers
842  sortIter = discLayers->begin();
843  sortEnd = discLayers->end();
844  std::sort(sortIter, sortEnd, zSorter);
845  }
846 
847  return discLayers;
848 }
849 
850 
851 std::unique_ptr<const std::vector<Trk::CylinderLayer*> >
853 {
854  // sanity check for ID Helper
855  if (!m_pixIdHelper && !m_sctIdHelper){
856  ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
857  return nullptr;
858  }
859 
860  // take the numerology
861  const InDetDD::SiNumerology& siNumerology = m_siMgr->numerology();
862 
863  // pre-set parameters for the run
864  size_t barrelLayers = 0;
865  // save way to estimate the number of barrel layers : they can be deactivated hence the useLayer(i) check
866  for (int i = 0; i < siNumerology.numLayers(); i++)
867  if (siNumerology.useLayer(i)) barrelLayers++;
868 
869  if (not m_layerIndicesBarrel.empty())
870  barrelLayers = m_layerIndicesBarrel.size();
871 
872  // screen output
873  ATH_MSG_DEBUG( "Configured to build " << barrelLayers << " (active) barrel layers (out of " << siNumerology.numLayers() << " )" );
874  if (!m_barrelAdditionalLayerR.empty())
875  ATH_MSG_DEBUG( "Additionally " << m_barrelAdditionalLayerR.size() << " material layers will be built.");
876 
877  // for barrels (the statistics for ordering the modules)
878  std::vector<double> layerRadius(barrelLayers,0.);
879  std::vector<double> layerRmin(barrelLayers,10e10);
880  std::vector<double> layerRmax(barrelLayers,0.);
881  std::vector<double> layerThickness(barrelLayers,0.);
882  std::vector<double> layerMinZ(barrelLayers,0.);
883  std::vector<double> layerMaxZ(barrelLayers,0.);
884  std::vector<double> layerHalfLength(barrelLayers,0.);
885  std::vector<double> layerMinPhi(barrelLayers,0.);
886  std::vector<double> layerMaxPhi(barrelLayers,0.);
887  std::vector<size_t> layerPhiSectors(barrelLayers,0);
888  std::vector<size_t> layerZsectors(barrelLayers,0);
889  std::vector< std::vector<float> > layerZboundaries(barrelLayers, std::vector<float>());
890  std::vector< std::vector< Trk::SurfaceOrderPosition > > layerSurfaces(barrelLayers, std::vector< Trk::SurfaceOrderPosition >());
891 
892  // cache needed
893  double minHalflengthZ = 10e10;
894  double maxHalflengthZ = 0;
895  size_t sumCheckBarrelModules = 0;
896  size_t barrelModules = 0;
897 
898  // [-A-] ------------------------ LOOP over Detector Elements of sensitive layers -----------------------------------
899  // iterate over the detector elements for layer dimension, etc.
900  const InDetDD::SiDetectorElementCollection::const_iterator sidetBegin = siDetElementCollection.begin();
901  const InDetDD::SiDetectorElementCollection::const_iterator sidetEnd = siDetElementCollection.end();
903  for (; sidetIter != sidetEnd; ++sidetIter){
904  // Barrel check
905  if ((*sidetIter) && (*sidetIter)->isBarrel()){
906  // get the identifier
907  Identifier currentId((*sidetIter)->identify());
908  int currentlayerIndex = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
909  if (not m_layerIndicesBarrel.empty()) {
910  if (std::find(m_layerIndicesBarrel.begin(), m_layerIndicesBarrel.end(), currentlayerIndex) == m_layerIndicesBarrel.end())
911  continue;
912  }
913  // unit test
914  ++barrelModules;
915  //skip the layer if it is chosen to be switched off
916  if ( !m_siMgr->numerology().useLayer(currentlayerIndex) ) continue;
917  // get layer index considering possible offset
918  int currentlayer = m_layerIndicesBarrel.empty() ?
919  currentlayerIndex : (currentlayerIndex-m_layerIndicesBarrel.value().at(0));
920  // (A) Determination of phi / eta sectors ---------------------------------------------------
921  // only do the exercise if it hasn't been done already
922  if (layerPhiSectors[currentlayer] == 0){
923  ATH_MSG_VERBOSE("Pre-processing Elements from Layer (id from idHelper): " << currentlayer );
924  // set number of phiSectors
925  layerPhiSectors[currentlayer] = m_siMgr->numerology().numPhiModulesForLayer(currentlayerIndex);
926  // set number of etaSectors
927  layerZsectors[currentlayer] = m_siMgr->numerology().numEtaModulesForLayer(currentlayerIndex);
928  // get the HalfLength of the Layer
929  const InDetDD::SiDetectorElement* countPtr = (*sidetIter);
930  // needed for the complex z binning if activated
931  double lastModuleZ = 0.;
932  std::vector<float> zboundaries;
933  zboundaries.reserve(layerZsectors[currentlayer]+1);
934  // walk all along to negative eta
935  while ((countPtr->prevInEta()))
936  countPtr = countPtr->prevInEta();
937  layerMinZ[currentlayer] = countPtr->center().z() - 0.5*std::abs(countPtr->length());
938  zboundaries.push_back(layerMinZ[currentlayer]);
939  lastModuleZ = countPtr->center().z();
940  // register the layer minZ into the zboundaries
941  // now walk all along to positive eta
942  while ((countPtr->nextInEta())) {
943  countPtr = countPtr->nextInEta();
944  // for complex binning
945  double currentModuleZ = countPtr->center().z();
946  double currentZboundary = 0.5*(lastModuleZ+currentModuleZ);
947  zboundaries.push_back(currentZboundary);
948  lastModuleZ = currentModuleZ;
949  }
950  layerMaxZ[currentlayer] = std::abs(countPtr->center().z()) + 0.5*std::abs(countPtr->length());
951  zboundaries.push_back(layerMaxZ[currentlayer]);
952 
953  // complex z binning mode
954  layerZboundaries[currentlayer] = zboundaries;
955  // chose which one to register for the split mode (SLHC)
956  layerHalfLength[currentlayer] = layerMinZ[currentlayer]*layerMinZ[currentlayer] > layerMaxZ[currentlayer]*layerMaxZ[currentlayer] ?
957  std::abs(layerMinZ[currentlayer]) : layerMaxZ[currentlayer];
958  // get the haflength of the layer
959  takeSmaller( minHalflengthZ, layerHalfLength[currentlayer]);
960  takeBigger( maxHalflengthZ, layerHalfLength[currentlayer]);
961  ATH_MSG_VERBOSE(" -> Determined Layer z range with : " << layerMinZ[currentlayer] << " / " << layerMaxZ[currentlayer] );
962  ATH_MSG_VERBOSE(" -> Symmetric half length taken : " << layerHalfLength[currentlayer]);
963  }
964 
965  // (B) Determination of the radius ------------------------------------------------
966  // getting inner module
967  const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();
968  // take the maximum layer radius
969  double currentR = (*sidetIter)->center().perp();
970  double currentRmax = (*sidetIter)->rMax();
971  double currentRmin = (*sidetIter)->rMin();
972  layerRadius[currentlayer] = (currentR > layerRadius[currentlayer]) ? currentR : layerRadius[currentlayer];
973  if (otherSide){
974  takeBigger( currentRmax, (otherSide)->rMax() );
975  takeSmaller( currentRmin, (otherSide)->rMin() );
976  }
977  takeSmaller( layerRmin[currentlayer], currentRmin );
978  takeBigger( layerRmax[currentlayer], currentRmax );
979 
980  // fill the Surface vector
981  Amg::Vector3D orderPosition((*sidetIter)->center());
982  double currentPhi = orderPosition.phi();
983  takeSmaller( layerMinPhi[currentlayer], currentPhi);
984  takeBigger( layerMaxPhi[currentlayer], currentPhi);
985 
986  // decide which one to register on the Radius: always the one with smaller radius
987  bool takeIt = (!otherSide || (*sidetIter)->center().perp() < otherSide->center().perp() );
988  const Trk::Surface* moduleSurface = takeIt ? (&((*sidetIter)->surface())) : (&(otherSide->surface()));
989 
990  // register the module surface
991  // std::shared_ptr<Trk::Surface> =
992  // std::make_shared<Trk::Surface>(.... some det element)) could be fine
993  //
994  // As things are now
995  // 1) Notice that basically we couple the DetElement owned
996  // surface to the Tracking Geometry passing a no-op deleter
997  // (no delete happens) to the shared_ptr(SharedObject is
998  // typedef of shared_ptr)
999  // 2) The const_cast here make the
1000  // code non MT safe. For now we handle this by being careful
1001  // on lifetimes and non-re-entrant TG construction.
1002  std::shared_ptr<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(moduleSurface),
1003  Trk::do_not_delete<Trk::Surface>);
1004 
1005  Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
1006  if (takeIt) (layerSurfaces[currentlayer]).push_back(surfaceOrder);
1007 
1008  } else if (!(*sidetIter)) // barrel check and screen output
1009  ATH_MSG_WARNING("nullptr to Barrel module given by SiDetectorManager! Please check db & dict.xml");
1010 
1011  } // SiDet Loop
1012 
1013  // --------------------------- enf of LOOP over Detector Elements of sensitive layers ----------------------------------
1014 
1015  // [-B-] ------------------------ Construction of the layers -----------------------------------
1016  // [-B-1] construct the detection layers
1017  std::vector< Trk::CylinderLayer* > cylinderDetectionLayers;
1018  int layerCounter = 0;
1019  double currentLayerExtend = 0.;
1020 
1021  // construct detection layers
1022  for (auto& layerRadiusIter : layerRadius) {
1023 
1024  Trk::CylinderLayer* activeLayer = nullptr;
1025  // non-equidistant binning used ? auto-detection
1026  bool nonEquidistantBinning = false;
1027  {
1028  // calculate the average bin size
1029  const double averageBinSize = (layerMaxZ[layerCounter]-layerMinZ[layerCounter])/(layerZsectors[layerCounter]);
1030  const double inv_averageBinSize2 = 1. / (averageBinSize*averageBinSize);
1031  // loop over the boundaries and check if theyare outside the tolerance
1032  auto bIter = layerZboundaries[layerCounter].begin();
1033  auto bIterE = layerZboundaries[layerCounter].end();
1034  for ( ++bIter; bIter != bIterE; ++bIter ){
1035  float cZ = (*bIter);
1036  float pZ = (*(bIter-1));
1037  nonEquidistantBinning = (cZ-pZ)*(cZ-pZ)*inv_averageBinSize2 < (1.-m_barrelEdbTolerance) *(1.-m_barrelEdbTolerance);
1038  if (nonEquidistantBinning){
1039  ATH_MSG_VERBOSE("Non-equidistant binning for (Silicon) Surfaces on this layer with radius " << layerRadiusIter << " detected. ");
1040  ATH_MSG_VERBOSE("Difference " << (cZ-pZ)/averageBinSize << " at a allowed tolerance of : " << m_barrelEdbTolerance );
1041  break;
1042  }
1043  }
1044  }
1045 
1046  //(1) the detecting layer : sensitive modules --------------------------------------------------------------------
1047  // create the BinKeyUtility - the phi binning is identical
1048  double halfPhiStep = M_PI/layerPhiSectors[layerCounter];
1049  // protection in case phi value was fluctuating around 0 or M_PI in parsing
1050  if (std::abs(layerMinPhi[layerCounter]+layerMaxPhi[layerCounter])< halfPhiStep && std::abs(M_PI+layerMinPhi[layerCounter]) < 0.5*halfPhiStep ){
1051  ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
1052  ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
1053  layerMinPhi[layerCounter] += 2*halfPhiStep;
1054  }
1055  // now prepare the phi values
1056  ATH_MSG_VERBOSE("Preparing the Phi-binning for : " << layerPhiSectors[layerCounter] << " sectors.");
1057  ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
1058  double minPhiCorrected = layerMinPhi[layerCounter]-halfPhiStep;
1059  double maxPhiCorrected = layerMaxPhi[layerCounter]+halfPhiStep;
1060  // catch if the minPhi falls below M_PI
1061  if (minPhiCorrected < -M_PI){
1062  minPhiCorrected += 2*halfPhiStep;
1063  maxPhiCorrected += 2*halfPhiStep;
1064  }
1065  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
1066 
1067 
1068  auto currentBinUtility = Trk::BinUtility(layerPhiSectors[layerCounter],
1069  minPhiCorrected,
1070  maxPhiCorrected,
1072  if (nonEquidistantBinning)
1073  currentBinUtility += Trk::BinUtility(layerZboundaries[layerCounter],
1074  Trk::open,
1075  Trk::binZ);
1076  else
1077  currentBinUtility += Trk::BinUtility(layerZsectors[layerCounter],
1078  layerMinZ[layerCounter],
1079  layerMaxZ[layerCounter],
1080  Trk::open,
1081  Trk::binZ);
1082  // creating the binned array output
1083  ATH_MSG_VERBOSE("Creating the binned array for the sensitive detector elements with BinUtility :");
1084  ATH_MSG_VERBOSE( currentBinUtility );
1085  // the binned array for the senstive surfaces to be built
1086  auto currentBinnedArray =
1087  std::make_unique<Trk::BinnedArray2D<Trk::Surface>>(
1088  layerSurfaces[layerCounter], currentBinUtility);
1089  // unit test for sub surface ordering
1090  std::span<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
1091 
1093  // checking for :
1094  // - empty surface bins
1095  // - doubly filled bins
1096  std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
1097  auto usmIter = uniqueSurfaceMap.end();
1098  // ------- iterate
1099  auto asurfIter = arraySurfaces.begin();
1100  auto asurfIterEnd = arraySurfaces.end();
1101  for ( ; asurfIter != asurfIterEnd; ++asurfIter){
1102  if ( (*asurfIter) ) {
1103  ++sumCheckBarrelModules;
1104  usmIter = uniqueSurfaceMap.find(*asurfIter);
1105  if ( usmIter != uniqueSurfaceMap.end() )
1106  ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << (*asurfIter)->center().eta() << " / " << (*asurfIter)->center().phi());
1107  else uniqueSurfaceMap[(*asurfIter)] = (*asurfIter)->center();
1108  }
1109  else
1110  ATH_MSG_WARNING("Null surface defined in BinUtility ArraySurfaces vector");
1111  }
1112  }
1113 
1114  // dynamic layer extend
1115  currentLayerExtend = layerHalfLength[layerCounter];
1116 
1117  // dynamic layer extend determined by the sensitive layer dimensions
1118  layerRadius[layerCounter] = 0.5*(layerRmax[layerCounter] + layerRmin[layerCounter]);
1119  layerThickness[layerCounter] = layerRmax[layerCounter] - layerRmin[layerCounter];
1120 
1121  // create the material
1122  const Trk::LayerMaterialProperties& layerMaterial = barrelLayerMaterial(layerRadius[layerCounter], currentLayerExtend);
1123  double currentLayerThickness = layerThickness[layerCounter]+m_barrelEnvelope;
1124 
1125  // screen output
1126  ATH_MSG_DEBUG( "Construct BinnedArray for CylinderLayer with "<< (layerSurfaces[layerCounter]).size() << " SubSurfaces." );
1127  ATH_MSG_DEBUG( "Building a CylinderLayer with " << layerPhiSectors[layerCounter]
1128  << " / " << ( nonEquidistantBinning ? layerZboundaries[layerCounter].size() : layerZsectors[layerCounter] ) << " phi/z bins. " );
1129  ATH_MSG_DEBUG( " -> With Radius : " << layerRadius[layerCounter] );
1130  ATH_MSG_DEBUG( " -> With Thickness : " << currentLayerThickness << " - includes envelope tolerance : " << m_barrelEnvelope );
1131  ATH_MSG_DEBUG( " -> With Zmin/Zmax : " << -currentLayerExtend << " / " << currentLayerExtend );
1132 
1133  if ( nonEquidistantBinning && !layerZboundaries[layerCounter].empty() ){
1134  // overrule the min bin - with the min radius
1135  // do the output to screen
1136  double currentZ = -currentLayerExtend;
1137  msg(MSG::DEBUG) << " -> Z binning at : ";
1138  for (size_t zbin = 0; zbin < layerZboundaries[layerCounter].size(); ++zbin) {
1139  currentZ += layerZboundaries[layerCounter][zbin];
1140  msg(MSG::DEBUG) << currentZ;
1141  if (zbin < layerZboundaries[layerCounter].size()-1)
1142  msg(MSG::DEBUG) << ", ";
1143  }
1144  msg(MSG::DEBUG) << endmsg;
1145  }
1146  // prepare the right overlap descriptor
1147  std::unique_ptr<Trk::OverlapDescriptor> olDescriptor = nullptr;
1148  if (m_pixelCase){
1149  olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>(m_addMoreSurfaces);
1150  }
1151  else {
1152  olDescriptor = std::make_unique<InDet::SCT_OverlapDescriptor>(m_addMoreSurfaces);
1153  }
1154 
1155  std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
1156  // construct the layer (finally)
1157  activeLayer = new Trk::CylinderLayer(
1158  std::make_shared<Trk::CylinderBounds>(layerRadius[layerCounter],
1159  currentLayerExtend),
1160  std::move(currentBinnedArray), layerMaterial, currentLayerThickness,
1161  std::move(olDescriptor));
1162  // register the layer to the surfaces
1163  registerSurfacesToLayer(layerSurfaces,*activeLayer);
1164 
1165  // (3) register the layers
1166  cylinderDetectionLayers.push_back(activeLayer);
1167 
1168  // increase the layer counter --- it is built
1169  ++layerCounter;
1170 
1171  } // layer construction
1172  // --------------------------- enf of detection layer construction loop ----------------------------------
1173 
1174  ATH_MSG_DEBUG("Creating the final CylinderLayer collection with (potentially) additional layers.");
1175  std::unique_ptr<std::vector< Trk::CylinderLayer* > > cylinderLayers
1176  = dressCylinderLayers(cylinderDetectionLayers);
1177 
1178  // multiply the check number in case of SCT
1179  sumCheckBarrelModules *= (m_pixelCase) ? 1 : 2;
1180  ATH_MSG_DEBUG( barrelModules << " Barrel Modules parsed for Cylinder Layer dimenstions." );
1181  ATH_MSG_DEBUG( sumCheckBarrelModules << " Barrel Modules filled in Cylinder Layer Arrays." );
1182  if ( barrelModules-sumCheckBarrelModules )
1183  ATH_MSG_WARNING( barrelModules-sumCheckBarrelModules << " Modules not registered properly in binned array." );
1184 
1185  ATH_MSG_DEBUG("Returning " << cylinderLayers->size() << " cylinder layers.");
1186  return cylinderLayers;
1187 }
1188 
1189 
1190 std::unique_ptr<std::vector<Trk::CylinderLayer*> >
1191 InDet::SiLayerBuilderImpl::dressCylinderLayers(const std::vector<Trk::CylinderLayer*>& detectionLayers ) const {
1192 
1193 
1194  auto cylinderLayers = std::make_unique<std::vector<Trk::CylinderLayer*> >();
1195  // --------------------------- start of additional layer construction loop
1196  // ------------------------------- for the additional layer
1197  if (!m_barrelAdditionalLayerR.empty()){
1198  auto cylLayerIter = detectionLayers.begin();
1199  auto cylLayerIterEnd = detectionLayers.end();
1200  auto addLayerIter = m_barrelAdditionalLayerR.begin();
1201  auto addLayerIterEnd = m_barrelAdditionalLayerR.end();
1202  auto addLayerTypeIter = m_barrelAdditionalLayerType.begin();
1203  auto addLayerTypeIterEnd = m_barrelAdditionalLayerType.end();
1204  double cylLayerExtend = 0;
1205  for ( ; addLayerIter != addLayerIterEnd &&
1206  addLayerTypeIter != addLayerTypeIterEnd; ) {
1207  // build the passive layer if it is smaller the current
1208  // cylLayerIter - or if it is the last one
1209  if ( cylLayerIter == cylLayerIterEnd ||
1210  (*addLayerIter) < (*cylLayerIter)->bounds().r() ) {
1211  cylLayerExtend = (cylLayerIter == cylLayerIterEnd)
1212  ? cylLayerExtend
1213  : (*cylLayerIter)->bounds().halflengthZ() ;
1214  if ((*addLayerTypeIter)) {
1215  ATH_MSG_DEBUG("[- M -] Building an additional CylinderLayer w/o "
1216  "sensitive modules");
1217  // the material for the passive layer
1218  const Trk::LayerMaterialProperties& passiveLayerMaterial =
1219  barrelLayerMaterial(*addLayerIter, cylLayerExtend);
1220  // create the passive layer
1221  cylinderLayers->push_back(new Trk::CylinderLayer(
1222  std::make_shared<Trk::CylinderBounds>(*addLayerIter, cylLayerExtend),
1223  passiveLayerMaterial, 1. * Gaudi::Units::mm, nullptr, 0));
1224  } else {
1225  ATH_MSG_DEBUG("[- N -] Building an additional NavigationLayer for "
1226  "volume dimension control");
1227  // create the passive layer
1228  cylinderLayers->push_back(new Trk::CylinderLayer(
1229  std::make_shared<Trk::CylinderBounds>(*addLayerIter, cylLayerExtend), nullptr));
1230  }
1231  ATH_MSG_DEBUG(" -> With Radius : " << *addLayerIter);
1232  // increase the additional layer radii
1233  ++addLayerIter;
1234  ++addLayerTypeIter;
1235  continue;
1236  }
1237  ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
1238  ATH_MSG_DEBUG(" -> With Radius : " << (*cylLayerIter)->bounds().r());
1239  cylinderLayers->push_back(*cylLayerIter);
1240  ++cylLayerIter;
1241  }
1242  } else
1243  for (const auto & cylLayerIter : detectionLayers ) {
1244  ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
1245  ATH_MSG_DEBUG( " -> With Radius : " << cylLayerIter->bounds().r() );
1246  cylinderLayers->push_back(cylLayerIter);
1247  }
1248  return cylinderLayers;
1249 }
1250 
1253 {
1254  // --------------- material estimation ----------------------------------------------------------------
1255  // -- material with 1D binning
1256  Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -hz, hz, Trk::open, Trk::binZ);
1257  auto & layerBinUtility(layerBinUtilityZ);
1258  if (m_barrelLayerBinsPhi!=1u){ // -- material with 2D binning
1259  Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
1260  -r*M_PI, r*M_PI,
1261  Trk::closed,
1262  Trk::binRPhi);
1263  layerBinUtilityRPhiZ += layerBinUtilityZ;
1264  layerBinUtility = layerBinUtilityRPhiZ;
1265  }
1266  // --------------- material estimation ----------------------------------------------------------------
1267  return Trk::BinnedLayerMaterial(layerBinUtility);
1268 }
1269 
1270 
1272 InDet::SiLayerBuilderImpl::endcapLayerMaterial(double rMin, double rMax) const
1273 {
1274  // --------------- material estimation ----------------------------------------------------------------
1275  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,rMin,rMax,Trk::open, Trk::binR);
1276  if (m_endcapLayerBinsPhi!=1u){ // -- material with 2D binning
1278  layerBinUtilityR += layerBinUtilityPhi;
1279  }
1280  //const auto layerMaterial = Trk::BinnedLayerMaterial(layerBinUtilityR);
1281  // --------------- material estimation ----------------------------------------------------------------
1282  return Trk::BinnedLayerMaterial(layerBinUtilityR);
1283 }
1284 
1286  std::span<Trk::Surface* const>& layerSurfaces,
1287  Trk::Layer& lay) const {
1288  if (!m_setLayerAssociation){
1289  return;
1290  }
1291 
1292  auto laySurfIter = layerSurfaces.begin();
1293  const auto laySurfIterEnd = layerSurfaces.end();
1294  // register the surfaces to the layer
1295  for (; laySurfIter != laySurfIterEnd; ++laySurfIter){
1296  if (*laySurfIter) {
1297  // register the current surface
1298  (**laySurfIter).associateLayer(lay);
1299  const InDetDD::SiDetectorElement* detElement
1300  = dynamic_cast<const InDetDD::SiDetectorElement*>((*laySurfIter)->associatedDetectorElement());
1301  // register the backsise if necessary
1302  const InDetDD::SiDetectorElement* otherSideElement = detElement ? detElement->otherSide() : nullptr;
1303  const Trk::Surface* otherSideSurface = otherSideElement ? &(otherSideElement->surface()) : nullptr;
1304  if (otherSideSurface) {
1305  // Needs care for Athena MT
1306  // we bind again to the detElement owned surface
1307  (const_cast<Trk::Surface&>(*otherSideSurface)).associateLayer(lay);
1308  }
1309  }
1310  }
1311 }
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:674
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
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:81
InDet::SiLayerBuilderImpl::endcapLayerMaterial
const Trk::BinnedLayerMaterial endcapLayerMaterial(double rMin, double rMax) const
Definition: SiLayerBuilderImpl.cxx:1272
InDetDD::SiDetectorManager::numerology
const SiNumerology & numerology() const
Access Numerology.
Definition: SiDetectorManager.h:128
InDetDD::SCT_DetectorManager
Definition: SCT_DetectorManager.h:49
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
InDet::SiLayerBuilderImpl::m_setLayerAssociation
BooleanProperty m_setLayerAssociation
Set Layer Association.
Definition: SiLayerBuilderImpl.h:104
DiscBounds.h
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:27
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Trk::binZ
@ binZ
Definition: BinningType.h:49
SharedDoNoDelete.h
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
Trk::DiscBounds::rMax
double rMax() const
This method returns outer radius.
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
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:92
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:852
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
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
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:85
beamspotman.n
n
Definition: beamspotman.py:729
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::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
Trk::SurfaceOrderPosition
std::pair< std::shared_ptr< Surface >, Amg::Vector3D > SurfaceOrderPosition
Definition: HGTD_LayerBuilderCond.h:36
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::registerSurfacesToLayer
void registerSurfacesToLayer(std::span< Trk::Surface *const > &layerSurfaces, Trk::Layer &lay) const
Definition: SiLayerBuilderImpl.cxx:1285
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:622
InDet::SiLayerBuilderImpl::barrelLayerMaterial
const Trk::BinnedLayerMaterial barrelLayerMaterial(double r, double hz) const
helper method to construct endcap material
Definition: SiLayerBuilderImpl.cxx:1252
PixelID::eta_module
int eta_module(const Identifier &id) const
Definition: PixelID.h:647
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
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
Trk::open
@ open
Definition: BinningType.h:40
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
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
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:79
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:1191
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.
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Trk::DiscBounds
Definition: DiscBounds.h:44
Trk::Layer
Definition: Layer.h:72
Trk::binPhi
@ binPhi
Definition: BinningType.h:51
Trk::DiscLayerSorterZ
Definition: DiscLayer.h:152
Identifier
Definition: IdentifierFieldParser.cxx:14