402{
403
406 rngWrapper->
setSeed( rngName, ctx );
407 CLHEP::HepRandomEngine *rndmEngine = rngWrapper->
getEngine(ctx);
408
409 SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(
m_pixelDetEleCollKey, ctx);
410 const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
411 if (not pixelDetEleHandle.isValid() or elements==nullptr) {
413 return StatusCode::FAILURE;
414 }
415
417
420
421 SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle(
m_chargeDataKey, ctx);
422 const PixelChargeCalibCondData *calibData = *calibDataHandle;
424 std::vector<int> truthIdList;
425 std::vector<Identifier> detEl;
426
428
430
431 truthIdList.clear();
432 detEl.clear();
433
434 while (i != e) {
435
436 const TimedHitPtr<SiHit>& hit(*i++);
437
438
440 const int barrelEC = hit->getBarrelEndcap();
441 const int layerDisk = hit->getLayerDisk();
442 const int phiModule = hit->getPhiModule();
443 const int etaModule = hit->getEtaModule();
444
445 const Identifier moduleID =
m_pixel_ID->wafer_id(barrelEC, layerDisk, phiModule, etaModule);
446 const IdentifierHash waferHash =
m_pixel_ID->wafer_hash(moduleID);
447 const InDetDD::SiDetectorElement* hitSiDetElement = elements->getDetectorElement(waferHash);
448 if (!hitSiDetElement) {
ATH_MSG_ERROR(
" could not get detector element ");
continue;}
449
450 if (!(hitSiDetElement->
isPixel())) {
continue;}
451
452
453
454 std::vector<HepMcParticleLink> hit_vector;
455
456 const int truthID = (currentLink.
barcode() !=0 && currentLink.
id() == 0) ? 3 : currentLink.
id();
457
458 const Identifier hitId = hitSiDetElement->
identify();
459
460
461
462 bool isRep = false;
463
464 for (int j : truthIdList) {
465 for (auto & k : detEl) {
466 if ((truthID > 0) && (truthID == j) && (hitId == k)) {isRep = true; break;}
467 }
468 if (isRep) break;
469 }
470
471 if (isRep) continue;
472
473 truthIdList.push_back(truthID);
474 detEl.push_back(hitId);
475
476 HepGeom::Point3D<double> localStartPosition = hit->localStartPosition();
477 HepGeom::Point3D<double> localEndPosition = hit->localEndPosition();
478
481
482 int isEndcap = (barrelEC==0) ? 0:1;
483
486
487
488
489
490 Diffuse(localStartPosition, localEndPosition, shiftX, shiftY);
491
492 const Amg::Vector3D localDirection(localEndPosition.x()-localStartPosition.x(), localEndPosition.y()-localStartPosition.y(), localEndPosition.z()-localStartPosition.z());
493
494 Amg::Vector3D entryPoint(localStartPosition.x(),localStartPosition.y(),localStartPosition.z());
495 Amg::Vector3D exitPoint(localEndPosition.x(),localEndPosition.y(),localEndPosition.z());
496
497 const InDetDD::PixelModuleDesign* design(
dynamic_cast<const InDetDD::PixelModuleDesign*
>(&hitSiDetElement->
design()));
498 if (not design){
499 ATH_MSG_FATAL(
"Failed to cast the hitSiDetElement::design pointer to a PixelModuleDesign*; aborting due to null pointer");
500 return StatusCode::FAILURE;
501 }
502 const Amg::Vector2D localEntry(localStartPosition.x(),localStartPosition.y());
503 const Amg::Vector2D localExit(localEndPosition.x(),localEndPosition.y());
504
507
510
511 double halfthickness = hitSiDetElement->
thickness()*0.5;
512
513 bool EntryValid(entryCellId.
isValid());
514 bool ExitValid(exitCellId.
isValid());
515
517
518 Identifier diodeID = hitId;
521
523
524
525
526
527
528
529 pixMinimalPathCut=th0;
530
531 if (!EntryValid || !ExitValid)
532 {
533
534
535 if ( !EntryValid && !ExitValid) continue;
536
538
540
542 {
543 ATH_MSG_WARNING(
"ATTENTION THE INTERSECTION COORDINATE IS OUT OF THE MODULE");
544 continue;
545 }
546
547 const Amg::Vector2D Intersection_2d(Intersection.x(),Intersection.y());
549
550 InDetDD::SiCellId Intersection_2dCellId = hitSiDetElement->
cellIdFromIdentifier(Intersection_2dId);
551
552
553 if(!Intersection_2dCellId.
isValid())
continue;
554
555 if(EntryValid)
556 exitPoint = Intersection;
557 else
558 entryPoint = Intersection;
559
560
561 }
562
563
564
566 if(!digitizationModule){
568 return StatusCode::FAILURE;
569 }
570
571
572 std::vector<Trk::DigitizationStep> digitizationSteps =
m_digitizationStepper->cellSteps(*digitizationModule,entryPoint,exitPoint);
573
574
575
576
577 std::unique_ptr<InDet::PixelCluster>
pixelCluster =
nullptr;
579
580 std::vector<Identifier> rdoList;
581 std::vector<int> totList;
582
583 const bool isGanged = false;
584 int lvl1a = 0;
585
586 double accumulatedPathLength=0.;
587
588
589 int phiIndexMax = -999999;
590 int phiIndexMin = 1000000;
591 int etaIndexMax = -999999;
592 int etaIndexMin = 1000000;
593
594
595 for (auto& dStep : digitizationSteps){
596
597 double pathlength = dStep.stepLength;
598
600
604 pathlength *= (1.+sPar);
605 }
606
607
608 if (pathlength < pixMinimalPathCut) continue;
609
610
613 InDetDD::SiCellId diode = hitSiDetElement->
cellIdOfPosition(PositionOnModule);
614
615
617 continue;
618
620
622 clusterPosition += pathlength * chargeCenterPosition;
623
624 int currentEtaIndex = diode.
etaIndex();
625 int currentPhiIndex = diode.
phiIndex();
626 if(currentEtaIndex > etaIndexMax) etaIndexMax = currentEtaIndex;
627 if(currentEtaIndex < etaIndexMin) etaIndexMin = currentEtaIndex;
628 if(currentPhiIndex > phiIndexMax) phiIndexMax = currentPhiIndex;
629 if(currentPhiIndex < phiIndexMin) phiIndexMin = currentPhiIndex;
630
631
632
633 accumulatedPathLength += pathlength;
634
635 rdoList.push_back(rdoId);
637
638 }
639
640 delete digitizationModule;
641
642
643 int siDeltaPhiCut = phiIndexMax-phiIndexMin+1;
644 int siDeltaEtaCut = etaIndexMax-etaIndexMin+1;
645
646 int totalToT=std::accumulate(totList.begin(), totList.end(), 0);;
647
648
649 if (rdoList.empty() || accumulatedPathLength < pixMinimalPathCut || totalToT == 0) {
650 if (totalToT == 0 && !rdoList.empty() )
ATH_MSG_WARNING(
"The total ToT of the cluster is 0, this should never happen");
651 continue;
652 }
653
654
655 clusterPosition *= 1./accumulatedPathLength;
657
658
659
660
661 bool merged = false;
663
664 for(Pixel_detElement_RIO_map::iterator currentClusIter = PixelDetElClusterMap.begin(); currentClusIter != PixelDetElClusterMap.end();) {
665
666 Pixel_detElement_RIO_map::iterator clusIter = currentClusIter++;
667 InDet::PixelCluster* currentCluster = clusIter->second;
668 const std::vector<Identifier> ¤tRdoList = currentCluster->
rdoList();
669 bool areNb = false;
670 for (auto rdoIter : rdoList) {
672 if (areNb) { break; }
673 }
674 if (areNb) {
675 const std::vector<int> ¤tTotList = currentCluster->
totList();
676 rdoList.insert(rdoList.end(), currentRdoList.begin(), currentRdoList.end() );
677 totList.insert(totList.end(), currentTotList.begin(), currentTotList.end() );
679 float c1 = (
float)currentRdoList.size();
680 float c2 = (
float)rdoList.size();
681 clusterPosition = (clusterPosition*
c2 + currentClusterPosition*
c1)/((c1 + c2));
683 merged = true;
684 PixelDetElClusterMap.erase(clusIter);
685
686
687 std::pair<PRD_MultiTruthCollection::iterator,PRD_MultiTruthCollection::iterator> saved_hit =
m_pixPrdTruth->equal_range(currentCluster->
identify());
688 for (PRD_MultiTruthCollection::iterator this_hit = saved_hit.first; this_hit != saved_hit.second; ++this_hit)
689 {
690 hit_vector.push_back(this_hit->second);
691 }
692
694 delete currentCluster;
695
696 }
697 }
698 }
699
700 bool not_valid = false;
701 for (auto & entry : rdoList) {
702 if (!(
entry.is_valid())) { not_valid =
true;
break;}
703 }
704
705 if (not_valid) continue;
706
707 if(merged) {
708
709 for (auto rdoIter : rdoList) {
711
712 int chargePhiIndex = chargeCellId.
phiIndex();
713 int chargeEtaIndex = chargeCellId.
etaIndex();
714
715 phiIndexMin = chargePhiIndex < phiIndexMin ? chargePhiIndex : phiIndexMin;
716 phiIndexMax = chargePhiIndex > phiIndexMax ? chargePhiIndex : phiIndexMax;
717 etaIndexMin = chargeEtaIndex < etaIndexMin ? chargeEtaIndex : etaIndexMin;
718 etaIndexMax = chargeEtaIndex > etaIndexMax ? chargeEtaIndex : etaIndexMax;
719 }
720 siDeltaPhiCut = (phiIndexMax-phiIndexMin)+1;
721 siDeltaEtaCut = (etaIndexMax-etaIndexMin)+1;
722 }
723
724
725
726
727
728
729
730
731
732
734
735
736 const auto* pixModDesign =
737 dynamic_cast<const InDetDD::PixelModuleDesign*>(
738 &hitSiDetElement->
design());
739 if (!pixModDesign) {
740 return StatusCode::FAILURE;
741 }
742 double etaWidth =
743 pixModDesign->widthFromColumnRange(etaIndexMin, etaIndexMax);
744
746 pixModDesign->widthFromRowRange(phiIndexMin, phiIndexMax);
747
748 InDet::SiWidth siWidth(
Amg::Vector2D(siDeltaPhiCut, siDeltaEtaCut),
750
751
754 clusterId, clusterPosition, std::vector<Identifier>(rdoList),
755 lvl1a, std::vector<int>(totList), siWidth,
757 false, 0.0, 0.0, calibData, *offlineCalibData, ctx));
758 if (isGanged) {
760 }
761 } else {
763 "[ cluster - pix ] No pixels errors provided, but configured to "
764 "use them.");
766 " -> No pixels cluster will be created.");
767 continue;
768 }
769
772 continue;
773 }
774
777 continue;
778 }
779
781 PixelDetElClusterMap.insert(Pixel_detElement_RIO_map::value_type(
784
788 std::make_pair(insertedCluster->
identify(), currentLink));
790 << insertedCluster
791 << " and link = " << currentLink);
792 }
793 } else {
795 "Particle link NOT valid!! Truth map NOT filled with cluster"
796 << insertedCluster << " and link = " << currentLink);
797 }
798
799
800 for (const HepMcParticleLink& p : hit_vector) {
801
803 }
804
805 hit_vector.clear();
806 }
807
808
809 (void)
m_pixelClusterMap->insert(PixelDetElClusterMap.begin(), PixelDetElClusterMap.end());
810
811
812 }
813
814
815 return StatusCode::SUCCESS;
816}
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
int id() const
Return the id of the target particle.
bool isValid() const
Validity check.
static HepMcParticleLink getRedirectedLink(const HepMcParticleLink &particleLink, uint32_t eventIndex, const EventContext &ctx)
Return a HepMcParticleLink pointing at the same particle, but in a different GenEvent.
int barcode() const
Return the barcode of the target particle.
int phiIndex() const
Get phi index. Equivalent to strip().
bool isValid() const
Test if its in a valid state.
int etaIndex() const
Get eta index.
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
HepGeom::Point3D< double > hitLocalToLocal3D(const HepGeom::Point3D< double > &hitPosition) const
Same as previuos method but 3D.
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
Amg::Vector2D rawLocalPositionOfCell(const SiCellId &cellId) const
Returns position (center) of cell.
const std::vector< int > & totList() const
PixelChargeCalib::Thresholds getThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
bool nextDetectorElement(const_iterator &b, const_iterator &e)
sets an iterator range with the hits of current detector element returns a bool when done
TimedVector::const_iterator const_iterator
const Segmentation & segmentation() const
return the segmenation
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
virtual const Amg::Vector2D cellPosition(const DigitizationCell &dCell) const =0
calculate the cell Position from the Id
Eigen::Matrix< double, 2, 1 > Vector2D
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
std::pair< size_t, size_t > DigitizationCell
PixelCluster_v1 PixelCluster
Define the version of the pixel cluster class.