63 return StatusCode::SUCCESS;
71 return StatusCode::SUCCESS;
74 std::unique_ptr<std::vector< Trk::DiscLayer*> >
78 unsigned int endcapLayers = 0;
87 ATH_MSG_DEBUG(
"Configured to build " << endcapLayers <<
" *2 disc-like layers (+ additional support layers)." );
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>());
102 std::map< double, int> discZposLayerIndex;
104 int endcapModules = 0;
105 int sumCheckEndcapModules = 0;
106 unsigned int currentdisk = 0;
107 unsigned int currentring = 0;
108 unsigned int currentlayer = 0;
115 for (; sidetIter != sidetEnd; ++sidetIter){
119 if ( (*sidetIter) && (*sidetIter)->isEndcap() ){
121 Identifier currentId((*sidetIter)->identify());
126 double currentZ = (*sidetIter)->center().z();
128 currentlayer = currentdisk;
129 for (
unsigned int i = 0;
i < currentring;
i++) {
137 currentlayer += currentZ > 0. ? endcapLayers : 0;
145 double currentRmin = (*sidetIter)->rMin();
146 double currentRmax = (*sidetIter)->rMax();
149 double currentPhi = (*sidetIter)->center().phi();
151 takeBigger( discRmax[currentlayer],currentRmax);
154 if (discPhiSectors[currentlayer]<0){
155 ATH_MSG_VERBOSE(
"Pre-processing Elements from Disk/Layer (id from idHelper): " << currentring <<
"/" << currentdisk );
159 discPhiSectors[currentlayer]=phiSectorsRing;
164 takeBigger(discPhiMax[currentlayer],currentPhi);
182 std::shared_ptr<Trk::Surface> sharedSurface(
const_cast<Trk::Surface*
>(&(detElement->
surface())),
183 Trk::do_not_delete<Trk::Surface>);
185 discSurfaces[currentlayer].push_back(surfaceOrder);
187 }
else if (!(*sidetIter))
188 ATH_MSG_WARNING(
"nullptr to Endcap module given by SCT_DetectorManager! Please check db & dict.xml");
191 ATH_MSG_VERBOSE(
"Estimating the average z position and the radius for each disk.");
193 for (
unsigned int iec=0; iec<2*endcapLayers; ++iec){
195 discZpos[iec] = 0.5 * (discZmin[iec] + discZmax[iec]);
196 discThickness[iec] = std::abs(discZmax[iec]-discZmin[iec]);
198 discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
203 auto discLayers = std::make_unique<std::vector< Trk::DiscLayer*> >();
207 for ( ; discZposIter != discZpos.end(); ++discZposIter){
212 ATH_MSG_DEBUG(
"Building a DiscLayer with single R sectors. " );
213 ATH_MSG_DEBUG(
" -> At Z - Position : " << discZpos[discCounter] );
215 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (est) : " << discRmin[discCounter] <<
" / " << discRmax[discCounter] );
218 std::unique_ptr<Trk::BinnedArray<Trk::Surface>> currentBinnedArray =
nullptr;
220 double halfPhiStep =
M_PI/discPhiSectors[discCounter];
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;
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;
233 if (minPhiCorrected < -
M_PI){
234 minPhiCorrected += 2*halfPhiStep;
235 maxPhiCorrected += 2*halfPhiStep;
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] <<
")");
250 currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
252 int discSurfacesNum = (discSurfaces[discCounter]).
size();
253 ATH_MSG_DEBUG(
"Constructed BinnedArray for DiscLayer with "<< discSurfacesNum <<
" SubSurfaces." );
260 std::map< Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
263 std::span<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
264 size_t dsumCheckSurfaces = 0;
266 for (
const auto & asurfIter : arraySurfaces){
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();
275 ATH_MSG_WARNING(
"Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);
277 sumCheckEndcapModules += dsumCheckSurfaces;
279 ATH_MSG_DEBUG(
" -> With Rmin/Rmax : " << discRmin[discCounter] <<
" / " << discRmax[discCounter] );
288 auto activeLayerBounds = std::make_shared<Trk::DiscBounds>(discRmin[discCounter],discRmax[discCounter]);
289 std::vector<Trk::BinUtility> binUtils = std::vector<Trk::BinUtility>();
291 auto olDescriptor = std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils,
true);
292 std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
296 activeLayerTransform, std::move(activeLayerBounds), std::move(currentBinnedArray),
297 layerMaterial, thickness, std::move(olDescriptor));
301 discLayers->push_back(activeLayer);
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." );
316 std::sort(sortIter, sortEnd, zSorter);
325 sortIter = discLayers->begin();
326 sortEnd = discLayers->end();
328 double lastRmin = 0.;
329 double lastRmax = 0.;
331 for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
333 double layerRmin = lastRmin;
334 double layerRmax = lastRmax;
335 double layerZposition = 0.;
337 if ( sortIter != sortEnd){
339 layerZposition = (*sortIter)->surfaceRepresentation().center().z();
342 lastRmin = currentBounds ? currentBounds->
rMin() : 0.;
343 lastRmax = currentBounds ? currentBounds->
rMax() : 0.;
346 if ( addLayerIter != addLayerIterEnd){
348 double rMin = layerZposition > 0. ? layerRmin : lastRmin;
349 double rMax = layerZposition > 0. ? layerRmax : lastRmax;
354 if (*addLayerTypeIter) {
355 ATH_MSG_DEBUG(
"Building an additional DiscLayer w/o sensitive modules at");
359 std::make_shared<Trk::DiscBounds>(rMin, rMax),
360 passiveLayerMaterial,
364 std::make_shared<Trk::DiscBounds>(rMin, rMax),
368 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (corr) : " << rMin <<
" / " << rMax );
372 discLayers->push_back(passiveLayer);
377 sortIter = discLayers->begin();
378 sortEnd = discLayers->end();
379 std::sort(sortIter, sortEnd, zSorter);
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());
391 std::unique_ptr<std::vector< Trk::DiscLayer*> >
395 bool isDBM = (discLayers!=
nullptr);
398 unsigned int endcapLayers = 0;
401 ATH_MSG_DEBUG(
"Configured to build " << endcapLayers <<
"*2 disc-like DBM layers" );
405 ATH_MSG_DEBUG(
"Configured to build " << endcapLayers <<
" *2 disc-like layers (+ additional support layers)." );
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.);
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;
424 std::map< double, int> discZposLayerIndex;
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);
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( );
441 discRingMinR.emplace_back();
442 discRingMaxR.emplace_back();
445 int endcapModules = 0;
446 int sumCheckEndcapModules = 0;
447 unsigned int currentlayer = 0;
448 unsigned int currentdisk = 0;
449 unsigned int currentring = 0;
456 for (; sidetIter != sidetEnd; ++sidetIter){
461 if ( (*sidetIter) && ( (!
isDBM && (*sidetIter)->isEndcap()) || (
isDBM && (*sidetIter)->isDBM())) ){
466 double currentZ = (*sidetIter)->center().z();
468 Identifier currentId((*sidetIter)->identify());
470 currentlayer = currentdisk;
471 currentlayer += currentZ > 0. ? endcapLayers : 0;
479 double currentRmin = (*sidetIter)->rMin();
480 double currentRmax = (*sidetIter)->rMax();
483 unsigned int diskRings =
isDBM ?
488 double currentPhi = (*sidetIter)->center().phi();
490 takeBigger( discRmax[currentlayer],currentRmax);
493 if (discPhiSectors[currentlayer].empty()){
494 ATH_MSG_VERBOSE(
"Pre-processing Elements from Disk/Layer (id from idHelper): " << currentdisk <<
"/" << currentlayer );
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);
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 ?
507 ATH_MSG_VERBOSE(
"--> Ring " << iring <<
" has " << phiSectorsRing <<
" phi sectors");
508 discPhiSectors[currentlayer].push_back(phiSectorsRing);
512 if ( !(*sidetIter)->otherSide() || std::abs(currentZ) < std::abs((*sidetIter)->otherSide()->center().z())){
514 takeSmaller(discPhiMin[currentlayer][currentring],currentPhi);
515 takeBigger(discPhiMax[currentlayer][currentring],currentPhi);
517 takeSmaller(discRingMinR[currentlayer][currentring],currentRmin);
518 takeBigger(discRingMaxR[currentlayer][currentring],currentRmax);
520 }
else if (!(*sidetIter))
521 ATH_MSG_WARNING(
"nullptr to Endcap module given by SCT_DetectorManager! Please check db & dict.xml");
524 double minRmin = 10e10;
525 double maxRmax = -10e10;
527 ATH_MSG_VERBOSE(
"Estimating the average z position and the radius for each disk.");
529 for (
unsigned int iec=0; iec<2*endcapLayers; ++iec){
532 discZpos[iec] = 0.5 * (discZmin[iec] + discZmax[iec]);
533 discThickness[iec] =
isDBM ? 1. : std::abs(discZmax[iec]-discZmin[iec]);
535 discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
540 sidetIter = sidetBegin;
541 for (; sidetIter != sidetEnd; ++sidetIter){
543 if ( ((*sidetIter) && ((!
isDBM && (*sidetIter)->isEndcap()) || (
isDBM && (*sidetIter)->isDBM()))) ){
545 Identifier currentId((*sidetIter)->identify());
547 currentlayer = currentdisk;
548 currentlayer += (*sidetIter)->center().z() > 0. ? endcapLayers : 0;
551 bool takeIt = (!otherSide || std::abs((*sidetIter)->center().z()) < std::abs(otherSide->
center().z()) );
569 std::shared_ptr<Trk::Surface> sharedSurface(
const_cast<Trk::Surface*
>(&(chosenSide->
surface())),
572 if (takeIt) (discSurfaces[currentlayer]).push_back(surfaceOrder);
579 discLayers = std::make_unique<std::vector< Trk::DiscLayer* > >();
584 for ( ; discZposIter != discZpos.end(); ++discZposIter){
586 size_t discRsectors = (discPhiSectors[discCounter]).
size();
590 std::vector<double> discRingMinRcopy = discRingMinR[discCounter];
591 std::sort(discRingMinRcopy.begin(), discRingMinRcopy.end());
592 bool reverseRsectors = !(discRingMinRcopy == discRingMinR[discCounter]);
595 if (reverseRsectors){
596 ATH_MSG_VERBOSE(
"Auto-detect: rings in R are in " << ( reverseRsectors ?
"reversed" :
"standard") <<
" order.");
603 std::vector<float> discRboundaries;
604 discRboundaries.push_back(
float(*discRingMinRcopy.begin()));
605 for (
double & ringMaxRIter : discRingMaxR[discCounter])
606 discRboundaries.push_back(
float(ringMaxRIter));
609 ATH_MSG_DEBUG(
"Building a DiscLayer with " << discRsectors <<
" R sectors. " );
610 ATH_MSG_DEBUG(
" -> At Z - Position : " << discZpos[discCounter] );
612 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (est) : " << discRmin[discCounter] <<
" / " << discRmax[discCounter] );
615 for (
size_t irings=0; irings<discRsectors; ++irings)
616 ATH_MSG_DEBUG(
" --> " << irings <<
" R sector has " << discPhiSectors[discCounter][irings] <<
" phi sectors. " );
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];
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;
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;
634 if (minPhiCorrected < -
M_PI){
635 minPhiCorrected += 2*halfPhiStep;
636 maxPhiCorrected += 2*halfPhiStep;
638 ATH_MSG_VERBOSE(
" min phi / max phi corrected : " << minPhiCorrected <<
" / " << maxPhiCorrected );
640 ATH_MSG_VERBOSE(
"Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = "
641 << minPhiCorrected <<
" / " << maxPhiCorrected
642 <<
" (" << discPhiSectors[discCounter][0] <<
")");
644 auto currentBinUtility =
Trk::BinUtility(discPhiSectors[discCounter][0] ,
650 currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
664 discRmin[discCounter],
665 discRmax[discCounter],
668 ATH_MSG_VERBOSE(
"Steering bin utility constructed as : " << currentSteerBinUtility);
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;
678 if (minPhiCorrected < -
M_PI){
679 minPhiCorrected += 2*halfPhiStep;
680 maxPhiCorrected += 2*halfPhiStep;
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],
693 std::make_unique<Trk::BinnedArray1D1D<Trk::Surface>>(
694 discSurfaces[discCounter], currentSteerBinUtility,
698 int discSurfacesNum = (discSurfaces[discCounter]).
size();
699 ATH_MSG_DEBUG(
"Constructed BinnedArray for DiscLayer with "<< discSurfacesNum <<
" SubSurfaces." );
705 std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
708 std::span<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
709 size_t dsumCheckSurfaces = 0;
711 for (
const auto & asurfIter : arraySurfaces){
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();
720 ATH_MSG_WARNING(
"Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);
722 sumCheckEndcapModules += dsumCheckSurfaces;
724 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (corr) : " << minRmin <<
" / " << maxRmax );
733 auto activeLayerBounds = std::make_shared<Trk::DiscBounds>(minRmin,maxRmax);
735 std::unique_ptr<Trk::OverlapDescriptor> olDescriptor =
nullptr;
737 olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>();
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));
750 std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils);
754 std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
758 new Trk::DiscLayer(activeLayerTransform, std::move(activeLayerBounds),
759 std::move(currentBinnedArray), layerMaterial,
760 thickness, std::move(olDescriptor));
762 discLayers->push_back(activeLayer);
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." );
779 std::sort(sortIter, sortEnd, zSorter);
788 sortIter = discLayers->begin();
789 sortEnd = discLayers->end();
791 double lastRmin = 0.;
792 double lastRmax = 0.;
794 for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
796 double layerRmin = lastRmin;
797 double layerRmax = lastRmax;
798 double layerZposition = 0.;
800 if ( sortIter != sortEnd){
802 layerZposition = (*sortIter)->surfaceRepresentation().center().z();
805 lastRmin = currentBounds ? currentBounds->
rMin() : 0.;
806 lastRmax = currentBounds ? currentBounds->
rMax() : 0.;
809 if ( addLayerIter != addLayerIterEnd){
811 double rMin = layerZposition > 0. ? layerRmin : lastRmin;
812 double rMax = layerZposition > 0. ? layerRmax : lastRmax;
818 if (*addLayerTypeIter) {
820 "Building an additional DiscLayer w/o sensitive modules at");
826 std::make_shared<Trk::DiscBounds>(rMin, rMax),
827 passiveLayerMaterial,
831 passiveDiscTransf, std::make_shared<Trk::DiscBounds>(rMin, rMax),
nullptr);
833 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (corr) : " << rMin <<
" / " << rMax );
837 discLayers->push_back(passiveLayer);
842 sortIter = discLayers->begin();
843 sortEnd = discLayers->end();
844 std::sort(sortIter, sortEnd, zSorter);
851 std::unique_ptr<const std::vector<Trk::CylinderLayer*> >
856 ATH_MSG_ERROR(
"Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
864 size_t barrelLayers = 0;
867 if (siNumerology.
useLayer(
i)) barrelLayers++;
873 ATH_MSG_DEBUG(
"Configured to build " << barrelLayers <<
" (active) barrel layers (out of " << siNumerology.
numLayers() <<
" )" );
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 >());
893 double minHalflengthZ = 10e10;
894 double maxHalflengthZ = 0;
895 size_t sumCheckBarrelModules = 0;
896 size_t barrelModules = 0;
903 for (; sidetIter != sidetEnd; ++sidetIter){
905 if ((*sidetIter) && (*sidetIter)->isBarrel()){
907 Identifier currentId((*sidetIter)->identify());
922 if (layerPhiSectors[currentlayer] == 0){
923 ATH_MSG_VERBOSE(
"Pre-processing Elements from Layer (id from idHelper): " << currentlayer );
931 double lastModuleZ = 0.;
932 std::vector<float> zboundaries;
933 zboundaries.reserve(layerZsectors[currentlayer]+1);
937 layerMinZ[currentlayer] = countPtr->
center().z() - 0.5*std::abs(countPtr->
length());
938 zboundaries.push_back(layerMinZ[currentlayer]);
939 lastModuleZ = countPtr->
center().z();
945 double currentModuleZ = countPtr->
center().z();
946 double currentZboundary = 0.5*(lastModuleZ+currentModuleZ);
947 zboundaries.push_back(currentZboundary);
948 lastModuleZ = currentModuleZ;
950 layerMaxZ[currentlayer] = std::abs(countPtr->
center().z()) + 0.5*std::abs(countPtr->
length());
951 zboundaries.push_back(layerMaxZ[currentlayer]);
954 layerZboundaries[currentlayer] = zboundaries;
956 layerHalfLength[currentlayer] = layerMinZ[currentlayer]*layerMinZ[currentlayer] > layerMaxZ[currentlayer]*layerMaxZ[currentlayer] ?
957 std::abs(layerMinZ[currentlayer]) : layerMaxZ[currentlayer];
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]);
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];
974 takeBigger( currentRmax, (otherSide)->rMax() );
977 takeSmaller( layerRmin[currentlayer], currentRmin );
978 takeBigger( layerRmax[currentlayer], currentRmax );
982 double currentPhi = orderPosition.phi();
983 takeSmaller( layerMinPhi[currentlayer], currentPhi);
984 takeBigger( layerMaxPhi[currentlayer], currentPhi);
987 bool takeIt = (!otherSide || (*sidetIter)->
center().perp() < otherSide->
center().perp() );
988 const Trk::Surface* moduleSurface = takeIt ? (&((*sidetIter)->surface())) : (&(otherSide->
surface()));
1002 std::shared_ptr<Trk::Surface> sharedSurface(
const_cast<Trk::Surface*
>(moduleSurface),
1003 Trk::do_not_delete<Trk::Surface>);
1006 if (takeIt) (layerSurfaces[currentlayer]).push_back(surfaceOrder);
1008 }
else if (!(*sidetIter))
1009 ATH_MSG_WARNING(
"nullptr to Barrel module given by SiDetectorManager! Please check db & dict.xml");
1017 std::vector< Trk::CylinderLayer* > cylinderDetectionLayers;
1018 int layerCounter = 0;
1019 double currentLayerExtend = 0.;
1022 for (
auto& layerRadiusIter : layerRadius) {
1026 bool nonEquidistantBinning =
false;
1029 const double averageBinSize = (layerMaxZ[layerCounter]-layerMinZ[layerCounter])/(layerZsectors[layerCounter]);
1030 const double inv_averageBinSize2 = 1. / (averageBinSize*averageBinSize);
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));
1038 if (nonEquidistantBinning){
1039 ATH_MSG_VERBOSE(
"Non-equidistant binning for (Silicon) Surfaces on this layer with radius " << layerRadiusIter <<
" detected. ");
1048 double halfPhiStep =
M_PI/layerPhiSectors[layerCounter];
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;
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;
1061 if (minPhiCorrected < -
M_PI){
1062 minPhiCorrected += 2*halfPhiStep;
1063 maxPhiCorrected += 2*halfPhiStep;
1065 ATH_MSG_VERBOSE(
" min phi / max phi corrected : " << minPhiCorrected <<
" / " << maxPhiCorrected );
1068 auto currentBinUtility =
Trk::BinUtility(layerPhiSectors[layerCounter],
1072 if (nonEquidistantBinning)
1078 layerMinZ[layerCounter],
1079 layerMaxZ[layerCounter],
1083 ATH_MSG_VERBOSE(
"Creating the binned array for the sensitive detector elements with BinUtility :");
1086 auto currentBinnedArray =
1087 std::make_unique<Trk::BinnedArray2D<Trk::Surface>>(
1088 layerSurfaces[layerCounter], currentBinUtility);
1090 std::span<Trk::Surface * const> arraySurfaces = currentBinnedArray->arrayObjects();
1096 std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
1097 auto usmIter = uniqueSurfaceMap.end();
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();
1110 ATH_MSG_WARNING(
"Null surface defined in BinUtility ArraySurfaces vector");
1115 currentLayerExtend = layerHalfLength[layerCounter];
1118 layerRadius[layerCounter] = 0.5*(layerRmax[layerCounter] + layerRmin[layerCounter]);
1119 layerThickness[layerCounter] = layerRmax[layerCounter] - layerRmin[layerCounter];
1123 double currentLayerThickness = layerThickness[layerCounter]+
m_barrelEnvelope;
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] );
1131 ATH_MSG_DEBUG(
" -> With Zmin/Zmax : " << -currentLayerExtend <<
" / " << currentLayerExtend );
1133 if ( nonEquidistantBinning && !layerZboundaries[layerCounter].empty() ){
1136 double currentZ = -currentLayerExtend;
1138 for (
size_t zbin = 0; zbin < layerZboundaries[layerCounter].size(); ++zbin) {
1139 currentZ += layerZboundaries[layerCounter][zbin];
1141 if (zbin < layerZboundaries[layerCounter].
size()-1)
1147 std::unique_ptr<Trk::OverlapDescriptor> olDescriptor =
nullptr;
1149 olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>(
m_addMoreSurfaces);
1152 olDescriptor = std::make_unique<InDet::SCT_OverlapDescriptor>(
m_addMoreSurfaces);
1155 std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
1158 std::make_shared<Trk::CylinderBounds>(layerRadius[layerCounter],
1159 currentLayerExtend),
1160 std::move(currentBinnedArray), layerMaterial, currentLayerThickness,
1161 std::move(olDescriptor));
1166 cylinderDetectionLayers.push_back(activeLayer);
1174 ATH_MSG_DEBUG(
"Creating the final CylinderLayer collection with (potentially) additional layers.");
1175 std::unique_ptr<std::vector< Trk::CylinderLayer* > > cylinderLayers
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." );
1185 ATH_MSG_DEBUG(
"Returning " << cylinderLayers->size() <<
" cylinder layers.");
1186 return cylinderLayers;
1190 std::unique_ptr<std::vector<Trk::CylinderLayer*> >
1194 auto cylinderLayers = std::make_unique<std::vector<Trk::CylinderLayer*> >();
1198 auto cylLayerIter = detectionLayers.begin();
1199 auto cylLayerIterEnd = detectionLayers.end();
1204 double cylLayerExtend = 0;
1205 for ( ; addLayerIter != addLayerIterEnd &&
1206 addLayerTypeIter != addLayerTypeIterEnd; ) {
1209 if ( cylLayerIter == cylLayerIterEnd ||
1210 (*addLayerIter) < (*cylLayerIter)->bounds().r() ) {
1211 cylLayerExtend = (cylLayerIter == cylLayerIterEnd)
1213 : (*cylLayerIter)->bounds().halflengthZ() ;
1214 if ((*addLayerTypeIter)) {
1215 ATH_MSG_DEBUG(
"[- M -] Building an additional CylinderLayer w/o "
1216 "sensitive modules");
1222 std::make_shared<Trk::CylinderBounds>(*addLayerIter, cylLayerExtend),
1225 ATH_MSG_DEBUG(
"[- N -] Building an additional NavigationLayer for "
1226 "volume dimension control");
1229 std::make_shared<Trk::CylinderBounds>(*addLayerIter, cylLayerExtend),
nullptr));
1237 ATH_MSG_DEBUG(
"[- D -] Registering detection CylinderLayer");
1238 ATH_MSG_DEBUG(
" -> With Radius : " << (*cylLayerIter)->bounds().r());
1239 cylinderLayers->push_back(*cylLayerIter);
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);
1248 return cylinderLayers;
1257 auto & layerBinUtility(layerBinUtilityZ);
1263 layerBinUtilityRPhiZ += layerBinUtilityZ;
1264 layerBinUtility = layerBinUtilityRPhiZ;
1278 layerBinUtilityR += layerBinUtilityPhi;
1286 std::span<Trk::Surface* const>& layerSurfaces,
1292 auto laySurfIter = layerSurfaces.begin();
1293 const auto laySurfIterEnd = layerSurfaces.end();
1295 for (; laySurfIter != laySurfIterEnd; ++laySurfIter){
1298 (**laySurfIter).associateLayer(lay);
1303 const Trk::Surface* otherSideSurface = otherSideElement ? &(otherSideElement->
surface()) :
nullptr;
1304 if (otherSideSurface) {
1307 (
const_cast<Trk::Surface&
>(*otherSideSurface)).associateLayer(lay);