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;
453 const InDetDD::SiDetectorElementCollection::const_iterator sidetBegin = siDetElementCollection.begin();
454 const InDetDD::SiDetectorElementCollection::const_iterator sidetEnd = siDetElementCollection.end();
455 InDetDD::SiDetectorElementCollection::const_iterator sidetIter = sidetBegin;
456 for (; sidetIter != sidetEnd; ++sidetIter){
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()) );
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 std::vector<Trk::BinUtility*>* singleBinUtils =
new std::vector<Trk::BinUtility*>;
621 bool weOwnSingleBinUtils{
true};
622 if (discRsectors==1){
623 double halfPhiStep =
M_PI/discPhiSectors[discCounter][0];
625 if (std::abs(discPhiMin[discCounter][0]+discPhiMax[discCounter][0])< halfPhiStep && std::abs(discPhiMin[discCounter][0]) < 0.5*halfPhiStep ){
626 ATH_MSG_VERBOSE(
"Detected module fluctuation around +/- M_PI, correcting for it.");
627 ATH_MSG_VERBOSE(
" min phi / max phi detected : " << discPhiMin[discCounter][0] <<
" / " <<discPhiMax[discCounter][0] );
628 discPhiMin[discCounter][0] += 2*halfPhiStep;
631 ATH_MSG_VERBOSE(
" min phi / max phi detected : " << discPhiMin[discCounter][0] <<
" / " << discPhiMax[discCounter][0] );
632 double minPhiCorrected = discPhiMin[discCounter][0]-halfPhiStep;
633 double maxPhiCorrected = discPhiMax[discCounter][0]+halfPhiStep;
635 if (minPhiCorrected < -
M_PI){
636 minPhiCorrected += 2*halfPhiStep;
637 maxPhiCorrected += 2*halfPhiStep;
639 ATH_MSG_VERBOSE(
" min phi / max phi corrected : " << minPhiCorrected <<
" / " << maxPhiCorrected );
641 ATH_MSG_VERBOSE(
"Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = "
642 << minPhiCorrected <<
" / " << maxPhiCorrected
643 <<
" (" << discPhiSectors[discCounter][0] <<
")");
651 currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
665 discRmin[discCounter],
666 discRmax[discCounter],
669 ATH_MSG_VERBOSE(
"Steering bin utility constructed as : " << *currentSteerBinUtility);
672 singleBinUtils->reserve(discRsectors);
673 for (
size_t irings=0; irings < discRsectors; ++irings){
674 double halfPhiStep =
M_PI/discPhiSectors[discCounter][irings];
675 ATH_MSG_VERBOSE(
" min phi / max phi detected : " << discPhiMin[discCounter][irings] <<
" / " << discPhiMax[discCounter][irings] );
676 double minPhiCorrected = discPhiMin[discCounter][irings]-halfPhiStep;
677 double maxPhiCorrected = discPhiMax[discCounter][irings]+halfPhiStep;
679 if (minPhiCorrected < -
M_PI){
680 minPhiCorrected += 2*halfPhiStep;
681 maxPhiCorrected += 2*halfPhiStep;
683 ATH_MSG_VERBOSE(
" min phi / max phi corrected : " << minPhiCorrected <<
" / " << maxPhiCorrected );
684 ATH_MSG_VERBOSE(
"Constructing for ring " << irings <<
" phi utility with phiMin / phiMax (bins) = "
685 << minPhiCorrected <<
" / " << maxPhiCorrected <<
" (" << discPhiSectors[discCounter][irings] <<
")") ;
686 singleBinUtils->push_back(
new Trk::BinUtility(discPhiSectors[discCounter][irings],
693 weOwnSingleBinUtils =
false;
695 std::make_unique<Trk::BinnedArray1D1D<Trk::Surface>>(
696 discSurfaces[discCounter], currentSteerBinUtility,
700 int discSurfacesNum = (discSurfaces[discCounter]).
size();
701 ATH_MSG_DEBUG(
"Constructed BinnedArray for DiscLayer with "<< discSurfacesNum <<
" SubSurfaces." );
708 std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
712 size_t dsumCheckSurfaces = 0;
714 for (
const auto & asurfIter : arraySurfaces){
717 usmIter = uniqueSurfaceMap.find(asurfIter);
718 lastPhi = asurfIter->center().phi();
719 if ( usmIter != uniqueSurfaceMap.end() )
720 ATH_MSG_WARNING(
"Non-unique surface found with eta/phi = " << asurfIter->center().eta() <<
" / " << asurfIter->center().phi());
721 else uniqueSurfaceMap[asurfIter] = asurfIter->center();
723 ATH_MSG_WARNING(
"Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);
725 sumCheckEndcapModules += dsumCheckSurfaces;
727 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (corr) : " << minRmin <<
" / " << maxRmax );
738 std::unique_ptr<Trk::OverlapDescriptor> olDescriptor =
nullptr;
740 olDescriptor = std::make_unique<InDet::PixelOverlapDescriptor>();
742 std::vector<Trk::BinUtility*>* binUtils =
743 new std::vector<Trk::BinUtility*>;
744 if (singleBinUtils) {
746 singleBinUtils->begin();
747 for (; binIter != singleBinUtils->end(); ++binIter) {
748 binUtils->push_back((*binIter)->clone());
755 std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils);
764 std::move(currentBinnedArray), layerMaterial,
765 thickness, std::move(olDescriptor));
767 discLayers->push_back(activeLayer);
770 if (weOwnSingleBinUtils){
771 delete singleBinUtils;
772 singleBinUtils=
nullptr;
778 ATH_MSG_DEBUG( endcapModules <<
" Endcap Modules parsed for Disc Layer dimensions." );
779 ATH_MSG_DEBUG( sumCheckEndcapModules <<
" Endcap Modules filled in Disc Layer Arrays." );
780 if ( endcapModules-sumCheckEndcapModules )
781 ATH_MSG_WARNING( endcapModules-sumCheckEndcapModules <<
" Modules not registered properly in binned array." );
797 sortIter = discLayers->begin();
798 sortEnd = discLayers->end();
800 double lastRmin = 0.;
801 double lastRmax = 0.;
803 for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
805 double layerRmin = lastRmin;
806 double layerRmax = lastRmax;
807 double layerZposition = 0.;
809 if ( sortIter != sortEnd){
811 layerZposition = (*sortIter)->surfaceRepresentation().center().z();
814 lastRmin = currentBounds ? currentBounds->
rMin() : 0.;
815 lastRmax = currentBounds ? currentBounds->
rMax() : 0.;
818 if ( addLayerIter != addLayerIterEnd){
820 double rMin = layerZposition > 0. ? layerRmin : lastRmin;
821 double rMax = layerZposition > 0. ? layerRmax : lastRmax;
827 if (*addLayerTypeIter) {
829 "Building an additional DiscLayer w/o sensitive modules at");
836 passiveLayerMaterial,
842 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (corr) : " << rMin <<
" / " << rMax );
846 discLayers->push_back(passiveLayer);
851 sortIter = discLayers->begin();
852 sortEnd = discLayers->end();