393{
394
395 bool isDBM = (discLayers!=
nullptr);
396
397
398 unsigned int endcapLayers = 0;
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
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
424 std::map< double, int> discZposLayerIndex;
425
426
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
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
441 discRingMinR.emplace_back();
442 discRingMaxR.emplace_back();
443 }
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
452
456 for (; sidetIter != sidetEnd; ++sidetIter){
457
458
459
460
461 if ( (*sidetIter) && ( (!
isDBM && (*sidetIter)->isEndcap()) || (
isDBM && (*sidetIter)->isDBM())) ){
462
463
464 endcapModules++;
465
466 double currentZ = (*sidetIter)->center().z();
467
468 Identifier currentId((*sidetIter)->identify());
470 currentlayer = currentdisk;
471 currentlayer += currentZ > 0. ? endcapLayers : 0;
472
473
475
477
478
479 double currentRmin = (*sidetIter)->rMin();
480 double currentRmax = (*sidetIter)->rMax();
481
482
483 unsigned int diskRings =
isDBM ?
484 m_siMgr->numerology().numRingsForDiskDBM(currentdisk) :
485 m_siMgr->numerology().numRingsForDisk(currentdisk);
486
487
488 double currentPhi = (*sidetIter)->center().phi();
490 takeBigger( discRmax[currentlayer],currentRmax);
491
492
493 if (discPhiSectors[currentlayer].
empty()){
494 ATH_MSG_VERBOSE(
"Pre-processing Elements from Disk/Layer (id from idHelper): " << currentdisk <<
"/" << currentlayer );
495
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
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
507 ATH_MSG_VERBOSE(
"--> Ring " << iring <<
" has " << phiSectorsRing <<
" phi sectors");
508 discPhiSectors[currentlayer].push_back(phiSectorsRing);
509 }
510 }
511
512 if ( !(*sidetIter)->otherSide() || std::abs(currentZ) < std::abs((*sidetIter)->otherSide()->center().z())){
513
514 takeSmaller(discPhiMin[currentlayer][currentring],currentPhi);
515 takeBigger(discPhiMax[currentlayer][currentring],currentPhi);
516
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 }
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
529 for (unsigned int iec=0; iec<2*endcapLayers; ++iec){
531
532 discZpos[iec] = 0.5 * (discZmin[iec] + discZmax[iec]);
533 discThickness[iec] =
isDBM ? 1. : std::abs(discZmax[iec]-discZmin[iec]);
534
535 discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
536 }
537
538
539
540 sidetIter = sidetBegin;
541 for (; sidetIter != sidetEnd; ++sidetIter){
542
543 if ( ((*sidetIter) && ((!
isDBM && (*sidetIter)->isEndcap()) || (
isDBM && (*sidetIter)->isDBM()))) ){
544
545 Identifier currentId((*sidetIter)->identify());
547 currentlayer = currentdisk;
548 currentlayer += (*sidetIter)->center().z() > 0. ? endcapLayers : 0;
549
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
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569 std::shared_ptr<Trk::Surface> sharedSurface(
const_cast<Trk::Surface*
>(&(chosenSide->
surface())),
570 [](Trk::Surface*){});
572 if (takeIt) (discSurfaces[currentlayer]).push_back(surfaceOrder);
573 }
574 }
575
576
577
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
586 size_t discRsectors = (discPhiSectors[discCounter]).
size();
587
589
590 std::vector<double> discRingMinRcopy = discRingMinR[discCounter];
591 std::sort(discRingMinRcopy.begin(), discRingMinRcopy.end());
592 bool reverseRsectors = !(discRingMinRcopy == discRingMinR[discCounter]);
593
594
595 if (reverseRsectors){
596 ATH_MSG_VERBOSE(
"Auto-detect: rings in R are in " << ( reverseRsectors ?
"reversed" :
"standard") <<
" order.");
601 }
602
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
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] );
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
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
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
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
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
644 auto currentBinUtility = Trk::BinUtility(discPhiSectors[discCounter][0] ,
645 minPhiCorrected,
646 maxPhiCorrected,
649
650 currentBinnedArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(discSurfaces[discCounter],currentBinUtility);
651 } else {
653
654 Trk::BinUtility currentSteerBinUtility{};
656
658
659 currentSteerBinUtility = Trk::BinUtility(discRboundaries,
662 } else
663 currentSteerBinUtility = Trk::BinUtility(discRsectors,
664 discRmin[discCounter],
665 discRmax[discCounter],
668 ATH_MSG_VERBOSE(
"Steering bin utility constructed as : " << currentSteerBinUtility);
669
670
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
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
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
702
703
704
705 std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
706 std::map< const Trk::Surface*,Amg::Vector3D >::iterator usmIter = uniqueSurfaceMap.end();
707
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
728
729
732
733 auto activeLayerBounds = std::make_shared<Trk::DiscBounds>(minRmin,maxRmax);
734
735 std::unique_ptr<Trk::OverlapDescriptor> olDescriptor = nullptr;
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
747
748
749 olDescriptor =
750 std::make_unique<InDet::DiscOverlapDescriptor>(currentBinnedArray.get(), binUtils);
751 }
752
753
754 std::span<Trk::Surface * const> layerSurfaces = currentBinnedArray->arrayObjects();
755
756
757 Trk::DiscLayer* activeLayer =
758 new Trk::DiscLayer(activeLayerTransform, std::move(activeLayerBounds),
759 std::move(currentBinnedArray), layerMaterial,
760 thickness, std::move(olDescriptor));
762 discLayers->push_back(activeLayer);
763
764 ++discCounter;
765 }
766
767
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
776 Trk::DiscLayerSorterZ zSorter;
777 std::vector<Trk::DiscLayer*>::iterator sortIter = discLayers->begin();
778 std::vector<Trk::DiscLayer*>::iterator sortEnd = discLayers->end();
780
781
783
787
788 sortIter = discLayers->begin();
789 sortEnd = discLayers->end();
790
791 double lastRmin = 0.;
792 double lastRmax = 0.;
793
794 for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
795
796 double layerRmin = lastRmin;
797 double layerRmax = lastRmax;
798 double layerZposition = 0.;
799
800 if ( sortIter != sortEnd){
801
802 layerZposition = (*sortIter)->surfaceRepresentation().center().z();
803
804 const Trk::DiscBounds* currentBounds = dynamic_cast<const Trk::DiscBounds*>(&((*sortIter)->surfaceRepresentation().bounds()));
805 lastRmin = currentBounds ? currentBounds->
rMin() : 0.;
806 lastRmax = currentBounds ? currentBounds->
rMax() : 0.;
807 ++sortIter;
808 }
809 if ( addLayerIter != addLayerIterEnd){
810
811 double rMin = layerZposition > 0. ? layerRmin : lastRmin;
812 double rMax = layerZposition > 0. ? layerRmax : lastRmax;
813
814 Trk::DiscLayer* passiveLayer = nullptr;
815
818 if (*addLayerTypeIter) {
820 "Building an additional DiscLayer w/o sensitive modules at");
821
822 const Trk::LayerMaterialProperties& passiveLayerMaterial =
824 passiveLayer =
825 new Trk::DiscLayer(passiveDiscTransf,
826 std::make_shared<Trk::DiscBounds>(rMin, rMax),
827 passiveLayerMaterial,
828 1. * Gaudi::Units::mm);
829 } else
830 passiveLayer = new Trk::DiscLayer(
831 passiveDiscTransf, std::make_shared<Trk::DiscBounds>(rMin, rMax), nullptr);
833 ATH_MSG_DEBUG(
" -> With Rmin/Rmax (corr) : " << rMin <<
" / " << rMax );
834
835
836 ++addLayerIter;
837 discLayers->push_back(passiveLayer);
838 }
839 }
840
841
842 sortIter = discLayers->begin();
843 sortEnd = discLayers->end();
845 }
846
847 return discLayers;
848}
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool isDBM(uint32_t robId)
#define takeSmaller(current, test)
#define takeSmallerBigger(cSmallest, cBiggest, test)
#define takeBigger(current, test)
static const Attributes_t empty
DataModel_detail::const_iterator< DataVector > const_iterator
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.
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
Trk::Surface & surface()
Element Surface.
void registerSurfacesToLayer(std::span< Trk::Surface *const > &layerSurfaces, Trk::Layer &lay) const
DoubleProperty m_endcapEnvelope
envelope around rMin/rMax
DoubleArrayProperty m_endcapAdditionalLayerPosZ
Create additional endcaps at these z positions.
const Trk::BinnedLayerMaterial endcapLayerMaterial(double rMin, double rMax) const
const PixelID * m_pixIdHelper
pixel Id Helper
const InDetDD::SiDetectorManager * m_siMgr
the Si Detector Manager
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
double rMax() const
This method returns outer radius.
double rMin() const
This method returns inner radius.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
std::pair< std::shared_ptr< Surface >, Amg::Vector3D > SurfaceOrderPosition
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.