ATLAS Offline Software
Loading...
Searching...
No Matches
SiLayerBuilderImpl.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
9
13
16
17// Trk include
25
26// constructor
27InDet::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 }
62 ATH_CHECK(m_PixelReadKey.initialize());
63 return StatusCode::SUCCESS;
64}
65
66
67// finalize
69{
70 ATH_MSG_DEBUG( "finalize() successful" );
71 return StatusCode::SUCCESS;
72}
73
74std::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
81 std::find(m_layerIndicesEndcap.begin(), m_layerIndicesEndcap.end(), i)==m_layerIndicesEndcap.end() ) continue;
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())),
184 Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
185 discSurfaces[currentlayer].push_back(std::move(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,
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
391std::unique_ptr<std::vector< Trk::DiscLayer*> >
392InDet::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(std::move(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,
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,
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 //
784 const std::size_t originalSize = discLayers->size();
785 std::size_t layerIndex = 0;
786 //
787 // sort also the additional layer z positions
788 auto addLayerIter = m_endcapAdditionalLayerPosZ.begin();
789 auto addLayerTypeIter = m_endcapAdditionalLayerType.begin();
790 // get the last rmin / rmax
791 double lastRmin = 0.;
792 double lastRmax = 0.;
793 //
794 while (layerIndex < originalSize || addLayerIter != m_endcapAdditionalLayerPosZ.end() ){
795 // cache before 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 ( layerIndex < originalSize){
801 const auto * layer = (*discLayers)[layerIndex];
802 // get the current z position to guarantee a symmetrical setup
803 layerZposition = layer->surfaceRepresentation().center().z();
804 // get the bounds for the rMin / rMax setting
805 const auto* bounds = dynamic_cast<const Trk::DiscBounds*>(&layer->surfaceRepresentation().bounds());
806 lastRmin = bounds ? bounds->rMin() : 0.;
807 lastRmax = bounds ? bounds->rMax() : 0.;
808 ++layerIndex;
809 }
810 if ( addLayerIter != m_endcapAdditionalLayerPosZ.end()){
811 // symmetric setup around 0.
812 double rMin = layerZposition > 0. ? layerRmin : lastRmin;
813 double rMax = layerZposition > 0. ? layerRmax : lastRmax;
814 // the passive layer
815 Trk::DiscLayer* passiveLayer = nullptr;
816 // passive layer creation
817 Amg::Transform3D passiveDiscTransf =
818 Amg::Transform3D(Amg::Translation3D(0., 0., *addLayerIter));
819 if (*addLayerTypeIter) {
820 ATH_MSG_DEBUG( "Building an additional DiscLayer w/o sensitive modules at");
821 // create the material and the passive layer
822 const Trk::LayerMaterialProperties& passiveLayerMaterial = endcapLayerMaterial(rMin, rMax);
823 passiveLayer = new Trk::DiscLayer(passiveDiscTransf,
824 std::make_shared<Trk::DiscBounds>(rMin, rMax),
825 passiveLayerMaterial,
826 1. * Gaudi::Units::mm);
827 } else
828 passiveLayer = new Trk::DiscLayer(
829 passiveDiscTransf, std::make_shared<Trk::DiscBounds>(rMin, rMax), nullptr);
830 ATH_MSG_DEBUG( " -> At Z - Position : " << *addLayerIter );
831 ATH_MSG_DEBUG( " -> With Rmin/Rmax (corr) : " << rMin << " / " << rMax );
832
833 // increase the iterator and push back the new layer
834 ++addLayerIter;
835 ++addLayerTypeIter;
836 discLayers->push_back(passiveLayer);
837 }
838 } // the additional layers are built
839
840 // another round of sorting needed after adding the passive layers
841
842 std::ranges::sort(*discLayers,zSorter);
843 }
844
845 return discLayers;
846}
847
848
849std::unique_ptr<const std::vector<Trk::CylinderLayer*> >
851{
852 // sanity check for ID Helper
854 ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
855 return nullptr;
856 }
857
858 // take the numerology
859 const InDetDD::SiNumerology& siNumerology = m_siMgr->numerology();
860
861 // pre-set parameters for the run
862 size_t barrelLayers = 0;
863 // save way to estimate the number of barrel layers : they can be deactivated hence the useLayer(i) check
864 for (int i = 0; i < siNumerology.numLayers(); i++)
865 if (siNumerology.useLayer(i)) barrelLayers++;
866
867 if (not m_layerIndicesBarrel.empty())
868 barrelLayers = m_layerIndicesBarrel.size();
869
870 // screen output
871 ATH_MSG_DEBUG( "Configured to build " << barrelLayers << " (active) barrel layers (out of " << siNumerology.numLayers() << " )" );
872 if (!m_barrelAdditionalLayerR.empty())
873 ATH_MSG_DEBUG( "Additionally " << m_barrelAdditionalLayerR.size() << " material layers will be built.");
874
875 // for barrels (the statistics for ordering the modules)
876 std::vector<double> layerRadius(barrelLayers,0.);
877 std::vector<double> layerRmin(barrelLayers,10e10);
878 std::vector<double> layerRmax(barrelLayers,0.);
879 std::vector<double> layerThickness(barrelLayers,0.);
880 std::vector<double> layerMinZ(barrelLayers,0.);
881 std::vector<double> layerMaxZ(barrelLayers,0.);
882 std::vector<double> layerHalfLength(barrelLayers,0.);
883 std::vector<double> layerMinPhi(barrelLayers,0.);
884 std::vector<double> layerMaxPhi(barrelLayers,0.);
885 std::vector<size_t> layerPhiSectors(barrelLayers,0);
886 std::vector<size_t> layerZsectors(barrelLayers,0);
887 std::vector< std::vector<float> > layerZboundaries(barrelLayers, std::vector<float>());
888 std::vector< std::vector< Trk::SurfaceOrderPosition > > layerSurfaces(barrelLayers, std::vector< Trk::SurfaceOrderPosition >());
889
890 // cache needed
891 double minHalflengthZ = 10e10;
892 double maxHalflengthZ = 0;
893 size_t sumCheckBarrelModules = 0;
894 size_t barrelModules = 0;
895
896 // [-A-] ------------------------ LOOP over Detector Elements of sensitive layers -----------------------------------
897 // iterate over the detector elements for layer dimension, etc.
898 const InDetDD::SiDetectorElementCollection::const_iterator sidetBegin = siDetElementCollection.begin();
899 const InDetDD::SiDetectorElementCollection::const_iterator sidetEnd = siDetElementCollection.end();
901 for (; sidetIter != sidetEnd; ++sidetIter){
902 // Barrel check
903 if ((*sidetIter) && (*sidetIter)->isBarrel()){
904 // get the identifier
905 Identifier currentId((*sidetIter)->identify());
906 int currentlayerIndex = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
907 if (not m_layerIndicesBarrel.empty()) {
908 if (std::find(m_layerIndicesBarrel.begin(), m_layerIndicesBarrel.end(), currentlayerIndex) == m_layerIndicesBarrel.end())
909 continue;
910 }
911 // unit test
912 ++barrelModules;
913 //skip the layer if it is chosen to be switched off
914 if ( !m_siMgr->numerology().useLayer(currentlayerIndex) ) continue;
915 // get layer index considering possible offset
916 int currentlayer = m_layerIndicesBarrel.empty() ?
917 currentlayerIndex : (currentlayerIndex-m_layerIndicesBarrel.value().at(0));
918 // (A) Determination of phi / eta sectors ---------------------------------------------------
919 // only do the exercise if it hasn't been done already
920 if (layerPhiSectors[currentlayer] == 0){
921 ATH_MSG_VERBOSE("Pre-processing Elements from Layer (id from idHelper): " << currentlayer );
922 // set number of phiSectors
923 layerPhiSectors[currentlayer] = m_siMgr->numerology().numPhiModulesForLayer(currentlayerIndex);
924 // set number of etaSectors
925 layerZsectors[currentlayer] = m_siMgr->numerology().numEtaModulesForLayer(currentlayerIndex);
926 // get the HalfLength of the Layer
927 const InDetDD::SiDetectorElement* countPtr = (*sidetIter);
928 // needed for the complex z binning if activated
929 double lastModuleZ = 0.;
930 std::vector<float> zboundaries;
931 zboundaries.reserve(layerZsectors[currentlayer]+1);
932 // walk all along to negative eta
933 while ((countPtr->prevInEta()))
934 countPtr = countPtr->prevInEta();
935 layerMinZ[currentlayer] = countPtr->center().z() - 0.5*std::abs(countPtr->length());
936 zboundaries.push_back(layerMinZ[currentlayer]);
937 lastModuleZ = countPtr->center().z();
938 // register the layer minZ into the zboundaries
939 // now walk all along to positive eta
940 while ((countPtr->nextInEta())) {
941 countPtr = countPtr->nextInEta();
942 // for complex binning
943 double currentModuleZ = countPtr->center().z();
944 double currentZboundary = 0.5*(lastModuleZ+currentModuleZ);
945 zboundaries.push_back(currentZboundary);
946 lastModuleZ = currentModuleZ;
947 }
948 layerMaxZ[currentlayer] = std::abs(countPtr->center().z()) + 0.5*std::abs(countPtr->length());
949 zboundaries.push_back(layerMaxZ[currentlayer]);
950
951 // complex z binning mode
952 layerZboundaries[currentlayer] = std::move(zboundaries);
953 // chose which one to register for the split mode (SLHC)
954 layerHalfLength[currentlayer] = layerMinZ[currentlayer]*layerMinZ[currentlayer] > layerMaxZ[currentlayer]*layerMaxZ[currentlayer] ?
955 std::abs(layerMinZ[currentlayer]) : layerMaxZ[currentlayer];
956 // get the haflength of the layer
957 takeSmaller( minHalflengthZ, layerHalfLength[currentlayer]);
958 takeBigger( maxHalflengthZ, layerHalfLength[currentlayer]);
959 ATH_MSG_VERBOSE(" -> Determined Layer z range with : " << layerMinZ[currentlayer] << " / " << layerMaxZ[currentlayer] );
960 ATH_MSG_VERBOSE(" -> Symmetric half length taken : " << layerHalfLength[currentlayer]);
961 }
962
963 // (B) Determination of the radius ------------------------------------------------
964 // getting inner module
965 const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();
966 // take the maximum layer radius
967 double currentR = (*sidetIter)->center().perp();
968 double currentRmax = (*sidetIter)->rMax();
969 double currentRmin = (*sidetIter)->rMin();
970 layerRadius[currentlayer] = (currentR > layerRadius[currentlayer]) ? currentR : layerRadius[currentlayer];
971 if (otherSide){
972 takeBigger( currentRmax, (otherSide)->rMax() );
973 takeSmaller( currentRmin, (otherSide)->rMin() );
974 }
975 takeSmaller( layerRmin[currentlayer], currentRmin );
976 takeBigger( layerRmax[currentlayer], currentRmax );
977
978 // fill the Surface vector
979 Amg::Vector3D orderPosition((*sidetIter)->center());
980 double currentPhi = orderPosition.phi();
981 takeSmaller( layerMinPhi[currentlayer], currentPhi);
982 takeBigger( layerMaxPhi[currentlayer], currentPhi);
983
984 // decide which one to register on the Radius: always the one with smaller radius
985 bool takeIt = (!otherSide || (*sidetIter)->center().perp() < otherSide->center().perp() );
986 const Trk::Surface* moduleSurface = takeIt ? (&((*sidetIter)->surface())) : (&(otherSide->surface()));
987
988 // register the module surface
989 // std::shared_ptr<Trk::Surface> =
990 // std::make_shared<Trk::Surface>(.... some det element)) could be fine
991 //
992 // As things are now
993 // 1) Notice that basically we couple the DetElement owned
994 // surface to the Tracking Geometry passing a no-op deleter
995 // (no delete happens) to the shared_ptr(SharedObject is
996 // typedef of shared_ptr)
997 // 2) The const_cast here make the
998 // code non MT safe. For now we handle this by being careful
999 // on lifetimes and non-re-entrant TG construction.
1000 std::shared_ptr<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(moduleSurface),
1002
1003 Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
1004 if (takeIt) (layerSurfaces[currentlayer]).push_back(std::move(surfaceOrder));
1005
1006 } else if (!(*sidetIter)) // barrel check and screen output
1007 ATH_MSG_WARNING("nullptr to Barrel module given by SiDetectorManager! Please check db & dict.xml");
1008
1009 } // SiDet Loop
1010
1011 // --------------------------- enf of LOOP over Detector Elements of sensitive layers ----------------------------------
1012
1013 // [-B-] ------------------------ Construction of the layers -----------------------------------
1014 // [-B-1] construct the detection layers
1015 std::vector< Trk::CylinderLayer* > cylinderDetectionLayers;
1016 int layerCounter = 0;
1017 double currentLayerExtend = 0.;
1018
1019 // construct detection layers
1020 for (auto& layerRadiusIter : layerRadius) {
1021
1022 Trk::CylinderLayer* activeLayer = nullptr;
1023 // non-equidistant binning used ? auto-detection
1024 bool nonEquidistantBinning = false;
1025 {
1026 // calculate the average bin size
1027 const double averageBinSize = (layerMaxZ[layerCounter]-layerMinZ[layerCounter])/(layerZsectors[layerCounter]);
1028 const double inv_averageBinSize2 = 1. / (averageBinSize*averageBinSize);
1029 // loop over the boundaries and check if theyare outside the tolerance
1030 auto bIter = layerZboundaries[layerCounter].begin();
1031 auto bIterE = layerZboundaries[layerCounter].end();
1032 for ( ++bIter; bIter != bIterE; ++bIter ){
1033 float cZ = (*bIter);
1034 float pZ = (*(bIter-1));
1035 nonEquidistantBinning = (cZ-pZ)*(cZ-pZ)*inv_averageBinSize2 < (1.-m_barrelEdbTolerance) *(1.-m_barrelEdbTolerance);
1036 if (nonEquidistantBinning){
1037 ATH_MSG_VERBOSE("Non-equidistant binning for (Silicon) Surfaces on this layer with radius " << layerRadiusIter << " detected. ");
1038 ATH_MSG_VERBOSE("Difference " << (cZ-pZ)/averageBinSize << " at a allowed tolerance of : " << m_barrelEdbTolerance );
1039 break;
1040 }
1041 }
1042 }
1043
1044 //(1) the detecting layer : sensitive modules --------------------------------------------------------------------
1045 // create the BinKeyUtility - the phi binning is identical
1046 double halfPhiStep = M_PI/layerPhiSectors[layerCounter];
1047 // protection in case phi value was fluctuating around 0 or M_PI in parsing
1048 if (std::abs(layerMinPhi[layerCounter]+layerMaxPhi[layerCounter])< halfPhiStep && std::abs(M_PI+layerMinPhi[layerCounter]) < 0.5*halfPhiStep ){
1049 ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
1050 ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
1051 layerMinPhi[layerCounter] += 2*halfPhiStep;
1052 }
1053 // now prepare the phi values
1054 ATH_MSG_VERBOSE("Preparing the Phi-binning for : " << layerPhiSectors[layerCounter] << " sectors.");
1055 ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
1056 double minPhiCorrected = layerMinPhi[layerCounter]-halfPhiStep;
1057 double maxPhiCorrected = layerMaxPhi[layerCounter]+halfPhiStep;
1058 // catch if the minPhi falls below M_PI
1059 if (minPhiCorrected < -M_PI){
1060 minPhiCorrected += 2*halfPhiStep;
1061 maxPhiCorrected += 2*halfPhiStep;
1062 }
1063 ATH_MSG_VERBOSE(" min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
1064
1065
1066 auto currentBinUtility = Trk::BinUtility(layerPhiSectors[layerCounter],
1067 minPhiCorrected,
1068 maxPhiCorrected,
1070 if (nonEquidistantBinning)
1071 currentBinUtility += Trk::BinUtility(layerZboundaries[layerCounter],
1072 Trk::open,
1073 Trk::binZ);
1074 else
1075 currentBinUtility += Trk::BinUtility(layerZsectors[layerCounter],
1076 layerMinZ[layerCounter],
1077 layerMaxZ[layerCounter],
1078 Trk::open,
1079 Trk::binZ);
1080 // creating the binned array output
1081 ATH_MSG_VERBOSE("Creating the binned array for the sensitive detector elements with BinUtility :");
1082 ATH_MSG_VERBOSE( currentBinUtility );
1083 // the binned array for the senstive surfaces to be built
1084 auto currentBinnedArray =
1085 std::make_unique<Trk::BinnedArray2D<Trk::Surface>>(
1086 layerSurfaces[layerCounter], currentBinUtility);
1087 // unit test for sub surface ordering
1088 std::span<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
1089
1091 // checking for :
1092 // - empty surface bins
1093 // - doubly filled bins
1094 std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
1095 auto usmIter = uniqueSurfaceMap.end();
1096 // ------- iterate
1097 auto asurfIter = arraySurfaces.begin();
1098 auto asurfIterEnd = arraySurfaces.end();
1099 for ( ; asurfIter != asurfIterEnd; ++asurfIter){
1100 if ( (*asurfIter) ) {
1101 ++sumCheckBarrelModules;
1102 usmIter = uniqueSurfaceMap.find(*asurfIter);
1103 if ( usmIter != uniqueSurfaceMap.end() )
1104 ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << (*asurfIter)->center().eta() << " / " << (*asurfIter)->center().phi());
1105 else uniqueSurfaceMap[(*asurfIter)] = (*asurfIter)->center();
1106 }
1107 else
1108 ATH_MSG_WARNING("Null surface defined in BinUtility ArraySurfaces vector");
1109 }
1110 }
1111
1112 // dynamic layer extend
1113 currentLayerExtend = layerHalfLength[layerCounter];
1114
1115 // dynamic layer extend determined by the sensitive layer dimensions
1116 layerRadius[layerCounter] = 0.5*(layerRmax[layerCounter] + layerRmin[layerCounter]);
1117 layerThickness[layerCounter] = layerRmax[layerCounter] - layerRmin[layerCounter];
1118
1119 // create the material
1120 const Trk::LayerMaterialProperties& layerMaterial = barrelLayerMaterial(layerRadius[layerCounter], currentLayerExtend);
1121 double currentLayerThickness = layerThickness[layerCounter]+m_barrelEnvelope;
1122
1123 // screen output
1124 ATH_MSG_DEBUG( "Construct BinnedArray for CylinderLayer with "<< (layerSurfaces[layerCounter]).size() << " SubSurfaces." );
1125 ATH_MSG_DEBUG( "Building a CylinderLayer with " << layerPhiSectors[layerCounter]
1126 << " / " << ( nonEquidistantBinning ? layerZboundaries[layerCounter].size() : layerZsectors[layerCounter] ) << " phi/z bins. " );
1127 ATH_MSG_DEBUG( " -> With Radius : " << layerRadius[layerCounter] );
1128 ATH_MSG_DEBUG( " -> With Thickness : " << currentLayerThickness << " - includes envelope tolerance : " << m_barrelEnvelope );
1129 ATH_MSG_DEBUG( " -> With Zmin/Zmax : " << -currentLayerExtend << " / " << currentLayerExtend );
1130
1131 if ( nonEquidistantBinning && !layerZboundaries[layerCounter].empty() ){
1132 // overrule the min bin - with the min radius
1133 // do the output to screen
1134 double currentZ = -currentLayerExtend;
1135 msg(MSG::DEBUG) << " -> Z binning at : ";
1136 for (size_t zbin = 0; zbin < layerZboundaries[layerCounter].size(); ++zbin) {
1137 currentZ += layerZboundaries[layerCounter][zbin];
1138 msg(MSG::DEBUG) << currentZ;
1139 if (zbin < layerZboundaries[layerCounter].size()-1)
1140 msg(MSG::DEBUG) << ", ";
1141 }
1142 msg(MSG::DEBUG) << endmsg;
1143 }
1144 // prepare the right overlap descriptor
1145 std::unique_ptr<Trk::OverlapDescriptor> olDescriptor = nullptr;
1146 if (m_pixelCase){
1147 olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>(m_addMoreSurfaces);
1148 }
1149 else {
1150 olDescriptor = std::make_unique<InDet::SCT_OverlapDescriptor>(m_addMoreSurfaces);
1151 }
1152
1153 std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
1154 // construct the layer (finally)
1155 activeLayer = new Trk::CylinderLayer(
1156 std::make_shared<Trk::CylinderBounds>(layerRadius[layerCounter],
1157 currentLayerExtend),
1158 std::move(currentBinnedArray), layerMaterial, currentLayerThickness,
1159 std::move(olDescriptor));
1160 // register the layer to the surfaces
1161 registerSurfacesToLayer(layerSurfaces,*activeLayer);
1162
1163 // (3) register the layers
1164 cylinderDetectionLayers.push_back(activeLayer);
1165
1166 // increase the layer counter --- it is built
1167 ++layerCounter;
1168
1169 } // layer construction
1170 // --------------------------- enf of detection layer construction loop ----------------------------------
1171
1172 ATH_MSG_DEBUG("Creating the final CylinderLayer collection with (potentially) additional layers.");
1173 std::unique_ptr<std::vector< Trk::CylinderLayer* > > cylinderLayers
1174 = dressCylinderLayers(cylinderDetectionLayers);
1175
1176 // multiply the check number in case of SCT
1177 sumCheckBarrelModules *= (m_pixelCase) ? 1 : 2;
1178 ATH_MSG_DEBUG( barrelModules << " Barrel Modules parsed for Cylinder Layer dimenstions." );
1179 ATH_MSG_DEBUG( sumCheckBarrelModules << " Barrel Modules filled in Cylinder Layer Arrays." );
1180 if ( barrelModules-sumCheckBarrelModules )
1181 ATH_MSG_WARNING( barrelModules-sumCheckBarrelModules << " Modules not registered properly in binned array." );
1182
1183 ATH_MSG_DEBUG("Returning " << cylinderLayers->size() << " cylinder layers.");
1184 return cylinderLayers;
1185}
1186
1187
1188std::unique_ptr<std::vector<Trk::CylinderLayer*> >
1189InDet::SiLayerBuilderImpl::dressCylinderLayers(const std::vector<Trk::CylinderLayer*>& detectionLayers ) const {
1190
1191
1192 auto cylinderLayers = std::make_unique<std::vector<Trk::CylinderLayer*> >();
1193 // --------------------------- start of additional layer construction loop
1194 // ------------------------------- for the additional layer
1195 if (!m_barrelAdditionalLayerR.empty()){
1196 auto cylLayerIter = detectionLayers.begin();
1197 auto cylLayerIterEnd = detectionLayers.end();
1198 auto addLayerIter = m_barrelAdditionalLayerR.begin();
1199 auto addLayerIterEnd = m_barrelAdditionalLayerR.end();
1200 auto addLayerTypeIter = m_barrelAdditionalLayerType.begin();
1201 auto addLayerTypeIterEnd = m_barrelAdditionalLayerType.end();
1202 double cylLayerExtend = 0;
1203 for ( ; addLayerIter != addLayerIterEnd && addLayerTypeIter != addLayerTypeIterEnd; ) {
1204 // build the passive layer if it is smaller the current
1205 // cylLayerIter - or if it is the last one
1206 const bool lastLayer = (cylLayerIter == cylLayerIterEnd);
1207 if ( lastLayer || (*addLayerIter) < (*cylLayerIter)->bounds().r() ) {
1208 //cppcheck-suppress derefInvalidIteratorRedundantCheck
1209 cylLayerExtend = lastLayer ? cylLayerExtend : (*cylLayerIter)->bounds().halflengthZ() ;
1210 if ((*addLayerTypeIter)) {
1211 ATH_MSG_DEBUG("[- M -] Building an additional CylinderLayer w/o "
1212 "sensitive modules");
1213 // the material for the passive layer
1214 const Trk::LayerMaterialProperties& passiveLayerMaterial = barrelLayerMaterial(*addLayerIter, cylLayerExtend);
1215 // create the passive layer
1216 cylinderLayers->push_back(new Trk::CylinderLayer(std::make_shared<Trk::CylinderBounds>(*addLayerIter, cylLayerExtend),
1217 passiveLayerMaterial, 1. * Gaudi::Units::mm, nullptr, 0));
1218 } else {
1219 ATH_MSG_DEBUG("[- N -] Building an additional NavigationLayer for "
1220 "volume dimension control");
1221 // create the passive layer
1222 cylinderLayers->push_back(new Trk::CylinderLayer(
1223 std::make_shared<Trk::CylinderBounds>(*addLayerIter, cylLayerExtend), nullptr));
1224 }
1225 ATH_MSG_DEBUG(" -> With Radius : " << *addLayerIter);
1226 // increase the additional layer radii
1227 ++addLayerIter;
1228 ++addLayerTypeIter;
1229 continue;
1230 }
1231 ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
1232 ATH_MSG_DEBUG(" -> With Radius : " << (*cylLayerIter)->bounds().r());
1233 cylinderLayers->push_back(*cylLayerIter);
1234 ++cylLayerIter;
1235 }
1236 } else
1237 for (const auto & cylLayerIter : detectionLayers ) {
1238 ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
1239 ATH_MSG_DEBUG( " -> With Radius : " << cylLayerIter->bounds().r() );
1240 cylinderLayers->push_back(cylLayerIter);
1241 }
1242 return cylinderLayers;
1243}
1244
1247{
1248 // --------------- material estimation ----------------------------------------------------------------
1249 // -- material with 1D binning
1250 Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -hz, hz, Trk::open, Trk::binZ);
1251 auto & layerBinUtility(layerBinUtilityZ);
1252 if (m_barrelLayerBinsPhi!=1u){ // -- material with 2D binning
1253 Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
1254 -r*M_PI, r*M_PI,
1256 Trk::binRPhi);
1257 layerBinUtilityRPhiZ += layerBinUtilityZ;
1258 layerBinUtility = std::move(layerBinUtilityRPhiZ);
1259 }
1260 // --------------- material estimation ----------------------------------------------------------------
1261 return Trk::BinnedLayerMaterial(layerBinUtility);
1262}
1263
1264
1267{
1268 // --------------- material estimation ----------------------------------------------------------------
1269 Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,rMin,rMax,Trk::open, Trk::binR);
1270 if (m_endcapLayerBinsPhi!=1u){ // -- material with 2D binning
1272 layerBinUtilityR += layerBinUtilityPhi;
1273 }
1274 //const auto layerMaterial = Trk::BinnedLayerMaterial(layerBinUtilityR);
1275 // --------------- material estimation ----------------------------------------------------------------
1276 return Trk::BinnedLayerMaterial(layerBinUtilityR);
1277}
1278
1280 std::span<Trk::Surface* const>& layerSurfaces,
1281 Trk::Layer& lay) const {
1283 return;
1284 }
1285
1286 auto laySurfIter = layerSurfaces.begin();
1287 const auto laySurfIterEnd = layerSurfaces.end();
1288 // register the surfaces to the layer
1289 for (; laySurfIter != laySurfIterEnd; ++laySurfIter){
1290 if (*laySurfIter) {
1291 // register the current surface
1292 (**laySurfIter).associateLayer(lay);
1293 const InDetDD::SiDetectorElement* detElement
1294 = dynamic_cast<const InDetDD::SiDetectorElement*>((*laySurfIter)->associatedDetectorElement());
1295 // register the backsise if necessary
1296 const InDetDD::SiDetectorElement* otherSideElement = detElement ? detElement->otherSide() : nullptr;
1297 const Trk::Surface* otherSideSurface = otherSideElement ? &(otherSideElement->surface()) : nullptr;
1298 if (otherSideSurface) {
1299 // Needs care for Athena MT
1300 // we bind again to the detElement owned surface
1301 (const_cast<Trk::Surface&>(*otherSideSurface)).associateLayer(lay);
1302 }
1303 }
1304 }
1305}
#define M_PI
Scalar perp() const
perp method - perpendicular length
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
This is an Identifier helper class for the Pixel subdetector.
bool isDBM(uint32_t robId)
#define takeSmaller(current, test)
#define takeSmallerBigger(cSmallest, cBiggest, test)
#define takeBigger(current, test)
This is an Identifier helper class for the SCT subdetector.
size_t size() const
Number of registered mappings.
static const Attributes_t empty
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
MsgStream & msg() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:861
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated pixel ...
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
Class to hold the SiDetectorElement objects to be put in the detector store.
Class to hold geometrical description of a silicon detector element.
const SiDetectorElement * otherSide() const
Useful for SCT only.
const SiDetectorElement * prevInEta() const
const SiDetectorElement * nextInEta() const
Class to extract numerology for Pixel and SCT.
bool useLayer(int layer) const
Check if layer exists.
int numLayers() const
Number of layers.
double length() const
Length in eta direction (z - barrel, r - endcap).
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
Trk::Surface & surface()
Element Surface.
DoubleProperty m_barrelEnvelope
envelope around rMin/rMax
BooleanProperty m_setLayerAssociation
Set Layer Association.
IntegerArrayProperty m_layerIndicesBarrel
indices to be used for layer creation (used for ITk specific case)
virtual StatusCode finalize() override
AlgTool finalize method.
BooleanProperty m_addMoreSurfaces
to add additional surfaces to the PixelOverlapDescriptor, SCT_OverlapDescriptor and DiscOverlapDescri...
UnsignedIntegerProperty m_endcapLayerBinsR
Barrel bins for the material in r.
std::unique_ptr< std::vector< Trk::CylinderLayer * > > dressCylinderLayers(const std::vector< Trk::CylinderLayer * > &dLayers) const
helper method to construct barrel material
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_PixelReadKey
void registerSurfacesToLayer(std::span< Trk::Surface *const > &layerSurfaces, Trk::Layer &lay) const
BooleanProperty m_runGeometryValidation
run the validation of the geometry ( no empty bins)
DoubleProperty m_endcapEnvelope
envelope around rMin/rMax
DoubleArrayProperty m_endcapAdditionalLayerPosZ
Create additional endcaps at these z positions.
UnsignedIntegerProperty m_barrelLayerBinsPhi
Barrel bins for the material in phi.
std::unique_ptr< std::vector< Trk::DiscLayer * > > createRingLayersImpl(const InDetDD::SiDetectorElementCollection &siDetElementCollection) const
DoubleArrayProperty m_barrelAdditionalLayerR
Create an additional layer at these radii.
const Trk::BinnedLayerMaterial endcapLayerMaterial(double rMin, double rMax) const
UnsignedIntegerProperty m_endcapLayerBinsPhi
Barrel bins for the material in phi.
const PixelID * m_pixIdHelper
pixel Id Helper
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCT_ReadKey
IntegerArrayProperty m_barrelAdditionalLayerType
material layer 1 - navigation layer 0
const InDetDD::SiDetectorManager * m_siMgr
the Si Detector Manager
SiLayerBuilderImpl(const std::string &, const std::string &, const IInterface *)
AlgTool style constructor.
DoubleProperty m_barrelEdbTolerance
tolerance in percent how much the bin sizes can change
std::unique_ptr< std::vector< Trk::DiscLayer * > > createDiscLayersImpl(const InDetDD::SiDetectorElementCollection &siDetElementCollection, std::unique_ptr< std::vector< Trk::DiscLayer * > > discLayers=nullptr) const
std::unique_ptr< const std::vector< Trk::CylinderLayer * > > cylindricalLayersImpl(const InDetDD::SiDetectorElementCollection &siDetElementCollection) const
IntegerArrayProperty m_endcapAdditionalLayerType
material layer 1 - navigation layer 0 ( for volume adjustment )
BooleanProperty m_endcapComplexRingBinning
make std::vector<R> rings, could be different for layers
BooleanProperty m_pixelCase
Common properties.
const SCT_ID * m_sctIdHelper
sct Id Helper
IntegerArrayProperty m_layerIndicesEndcap
indices to be used for layer creation (used for ITk specific case)
const Trk::BinnedLayerMaterial barrelLayerMaterial(double r, double hz) const
helper method to construct endcap material
StringProperty m_siMgrLocation
the location of the Pixel Manager
virtual StatusCode initialize() override
AlgTool initialize method.
UnsignedIntegerProperty m_barrelLayerBinsZ
Barrel bins for the material in z.
A generic symmetric BinUtility, for fully symmetric binning in terms of binning grid and binning type...
Definition BinUtility.h:39
It extends the LayerMaterialProperties base class.
Class to describe a cylindrical detector layer for tracking, it inhertis from both,...
Class to describe the bounds for a planar DiscSurface.
Definition DiscBounds.h:44
double rMax() const
This method returns outer radius.
double rMin() const
This method returns inner radius.
simple helper function to allow sorting of DiscLayers in z
Definition DiscLayer.h:152
Class to describe a disc-like detector layer for tracking, it inhertis from both, Layer base class an...
Definition DiscLayer.h:45
This virtual base class encapsulates the logics to build pre/post/full update material for Layer stru...
Base Class for a Detector Layer in the Tracking realm.
Definition Layer.h:72
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
int r
Definition globals.cxx:22
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
std::pair< std::shared_ptr< Surface >, Amg::Vector3D > SurfaceOrderPosition
const auto do_not_delete
@ open
Definition BinningType.h:40
@ closed
Definition BinningType.h:41
@ binR
Definition BinningType.h:50
@ binPhi
Definition BinningType.h:51
@ binRPhi
Definition BinningType.h:52
@ binZ
Definition BinningType.h:49
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.