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." );
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();