Digitization functionality shared with RPC_PileUpTool.
Use special jitter consant for BIS & BIL chambers.
467 {
468 ATHRNG::RNGWrapper* rngWrapper =
m_rndmSvc->getEngine(
this);
470 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->
getEngine(ctx);
471
472 const MuonGM::MuonDetectorManager* detMgr{nullptr};
474
475
476 std::unique_ptr<RPCSimHitCollection> inputSimHitColl{std::make_unique<RPCSimHitCollection>("RPC_Hits")};
477
478
479
480
482
483
486 return StatusCode::FAILURE;
487 }
488
489 struct SimDataContent {
491 std::vector<MuonSimData::Deposit> deposits;
493 double simTime{0.};
494 };
495
496 while (
m_thpcRPC->nextDetectorElement(i, e)) {
497
498
499 std::map<Identifier, SimDataContent> channelSimDataMap;
500
501
502 while (i != e) {
504
505 TimedHitPtr<RPCSimHit> phit(*i++);
506
507
508 const RPCSimHit&
hit(*phit);
509
510 const int idHit =
hit.RPCid();
511
512 const double globalHitTime{
hitTime(phit)};
513
514 const double G4Time{
hit.globalTime()};
515
516 const double bunchTime{globalHitTime -
hit.globalTime()};
517
518 ATH_MSG_DEBUG(
"Global time " << globalHitTime <<
" G4 time " << G4Time <<
" Bunch time " << bunchTime);
519
521 ATH_MSG_VERBOSE(
"Validation: globalHitTime, G4Time, BCtime = " << globalHitTime <<
" " << G4Time <<
" " << bunchTime);
522 inputSimHitColl->Emplace(idHit, globalHitTime,
hit.localPosition(),
524 hit.postLocalPosition(),
525 hit.energyDeposit(),
hit.stepLength(),
hit.particleEncoding(),
hit.kineticEnergy());
526 }
527
528
536
538
539
541 const Identifier elementID =
m_idHelper->elementID(stationName,stationEta,stationPhi,doubletR,
isValid);
543 ATH_MSG_WARNING(
"Failed to construct the element ID from "<<stationName
544 <<", stationEta: "<<stationEta<<", stationPhi: "<<stationPhi<<", doubletR: "<<doubletR);
545 continue;
546 }
547
549 << " stationName " << stationName << " stationEta " << stationEta << " stationPhi " << stationPhi << " doubletR "
550 << doubletR << " doubletZ " << doubletZ << " doubletPhi " << doubletPhi << " gasGap " << gasGap);
551 const Identifier detElId{
m_idHelper->channelID(elementID, doubletZ, doubletPhi, 1,0, 1,
isValid)};
553 continue;
554 }
559 }
560
561
562 bool isValidEta{false}, isValidPhi{false};
563 const Identifier idpaneleta =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 0, 1, isValidEta);
564 const Identifier idpanelphi =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 1, 1, isValidPhi);
565 if (!isValidEta || !isValidPhi) {
567 << " stationName " << stationName << " stationEta " << stationEta << " stationPhi " << stationPhi
568 << " doubletR " << doubletR << " doubletZ " << doubletZ << " doubletPhi " << doubletPhi << " gasGap "
569 << gasGap);
570 continue;
571 }
572
573
577 const double corrtimejitter = tmp_CorrJitter > 0.01 ?
578 CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., tmp_CorrJitter) : 0.;
579
580
581
582
583
587
588 std::array<int, 3> pcseta =
physicalClusterSize(ctx, reEle, idpaneleta, gapCentre, rndmEngine);
589 ATH_MSG_VERBOSE(
"Simulated cluster on eta panel: size/first/last= " << pcseta[0] <<
"/" << pcseta[1] <<
"/" << pcseta[2]);
590 std::array<int, 3> pcsphi =
physicalClusterSize(ctx, reEle, idpanelphi, gapCentre, rndmEngine);
591 ATH_MSG_VERBOSE(
"Simulated cluster on phi panel: size/first/last= " << pcsphi[0] <<
"/" << pcsphi[1] <<
"/" << pcsphi[2]);
592
593
594
595
596 const Identifier atlasRpcIdeta =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 0, pcseta[1], isValidEta);
597 const Identifier atlasRpcIdphi =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 1, pcsphi[1], isValidPhi);
598
600 const auto [etaStripOn, phiStripOn] =
detectionEfficiency(ctx, idpaneleta, idpanelphi, rndmEngine, particleLink);
601 ATH_MSG_DEBUG(
"SetPhiOn " << phiStripOn <<
" SetEtaOn " << etaStripOn);
602
603 for (bool imeasphi : {false, true}) {
604 if (!imeasphi && (!etaStripOn || !isValidEta)) continue;
605 if (imeasphi && (!phiStripOn || !isValidPhi)) continue;
606
607
608
609 const Identifier& atlasId = !imeasphi ? atlasRpcIdeta : atlasRpcIdphi;
610 std::array<int, 3>
pcs{!imeasphi ? pcseta : pcsphi};
611
612 ATH_MSG_DEBUG(
"SetOn: stationName " << stationName <<
" stationEta " << stationEta <<
" stationPhi " << stationPhi
613 << " doubletR " << doubletR << " doubletZ " << doubletZ << " doubletPhi " << doubletPhi
614 << " gasGap " << gasGap << " measphi " << imeasphi);
615
616
618 if (pcs[2] < 0){
619 continue;
620 }
621
622 ATH_MSG_DEBUG(
"Simulated cluster1: size/first/last= " << pcs[0] <<
"/" << pcs[1] <<
"/" << pcs[2]);
623
624
627
629 <<
" hit "<<
m_idHelper->print_to_string(atlasId)
637
638
640
641 double tns = G4Time + proptime + corrtimejitter;
642 ATH_MSG_VERBOSE(
"TOF+propagation time " << tns <<
" /s where proptime " << proptime <<
"/s");
643
644 double time = tns + bunchTime;
646
647
649
650 double*
b =
reinterpret_cast<double*
>(&packedMCword);
651
653
654
655
657
658
659
661 if (std::abs(
hit.particleEncoding()) == 13 ||
hit.particleEncoding() == 0) {
662 if (channelSimDataMap.find(atlasId) == channelSimDataMap.end()) {
663 SimDataContent&
content = channelSimDataMap[atlasId];
665 content.deposits.push_back(deposit);
670 }
671 }
672 }
673
674
675
676
677
678
679
681 for (
int clus = pcs[1]; clus <=
pcs[2]; ++clus) {
682 Identifier newId =
m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ,
683 doubletPhi, gasGap, imeasphi, clus,
isValid);
685 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
"Channel "<< stationName<<
" "<<stationEta<<
" "<<stationPhi<<
" "<< doubletR<<
" "<<doubletZ
686 <<" "<< doubletPhi<<" "<< gasGap <<" "<< imeasphi<<" "<< clus<<" is invalid");
687 continue;
688 }
689
692 ATH_MSG_WARNING(
"Temporary skipping creation of RPC digit for stationName="
693 << stationName << ", eta=" << stationEta << ", phi=" << stationPhi << ", doubletR=" << doubletR
694 << ", doubletZ=" << doubletZ << ", doubletPhi=" << doubletPhi << ", gasGap=" << gasGap
695 << ", measuresPhi=" << imeasphi << ", strip=" << clus << ", cf. ATLASRECTS-6124");
696 return StatusCode::SUCCESS;
697 } else {
700 return StatusCode::FAILURE;
701 }
702 }
703
707
709 std::vector<MuonSimData::Deposit> newdeps;
710 newdeps.push_back(deposit);
711 m_sdo_tmp_map.insert(std::map<Identifier, std::vector<MuonSimData::Deposit>>::value_type(newId, newdeps));
712 } else {
714 }
715 }
716 }
717 }
718
720 for (auto it = channelSimDataMap.begin(); it != channelSimDataMap.end(); ++it) {
721 MuonSimData
simData(
it->second.deposits, 0);
724 auto insertResult = sdoContainer->insert(std::make_pair(
it->first,
simData));
725 if (!insertResult.second)
726 ATH_MSG_WARNING(
"Attention: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
727 }
728 }
729
730 }
731
733
734 std::map<Identifier, std::vector<MuonSimData::Deposit>>::iterator map_iter =
m_sdo_tmp_map.begin();
736
738
739 const Identifier theId = (*map_iter).first;
741
742 const std::vector<MuonSimData::Deposit> theDeps = (*map_iter).second;
743
744
746 std::multimap<double, MuonSimData::Deposit>
times;
747
748
749 for (
unsigned int k = 0;
k < theDeps.size();
k++) {
750 double time = theDeps[
k].second.secondEntry();
751 times.insert(std::multimap<double, MuonSimData::Deposit>::value_type(time, theDeps[k]));
752 }
753
754
755
756 IdContext rpcContext =
m_idHelper->module_context();
757
758 std::multimap<double, MuonSimData::Deposit>::iterator map_dep_iter =
times.begin();
759
760
761 double last_time = -10000;
762 for (; map_dep_iter !=
times.end(); ++map_dep_iter) {
763 double currTime = (*map_dep_iter).first;
765
767
768
769 if (sdoContainer->find(theId) != sdoContainer->end())
770 {
771 std::map<Identifier, MuonSimData>::const_iterator
it = sdoContainer->find(theId);
772 std::vector<MuonSimData::Deposit> deps = ((*it).second).getdeposits();
773 deps.push_back((*map_dep_iter).second);
774 } else
775 {
776 std::vector<MuonSimData::Deposit> deposits;
777 deposits.push_back((*map_dep_iter).second);
778 std::pair<std::map<Identifier, MuonSimData>::iterator, bool> insertResult =
779 sdoContainer->insert(std::make_pair(theId, MuonSimData(deposits, 0)));
780 if (!insertResult.second)
782 "Attention TEMP: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
783 }
784 }
785
786 if (std::abs(currTime - last_time) > (
m_deadTime)) {
787 ATH_MSG_DEBUG(
"deposit with time " << currTime <<
" is distant enough from previous (if any) hit on teh same strip");
788 last_time = (*map_dep_iter).first;
789
790
791 double uncorrjitter = 0;
794 if (tmp_UncorrJitter > 0.01) uncorrjitter = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., tmp_UncorrJitter);
795
796
797
798
802
804 double newDigit_time = currTime + uncorrjitter +
m_rpc_time_shift - tp - propTimeFromStripCenter;
805
806 double digi_ToT = -1.;
808
809 ATH_MSG_VERBOSE(
"last_time=currTime " << last_time <<
" jitter " << uncorrjitter <<
" TOFcorrection " << tp <<
" shift "
811
812
813 bool outsideDigitizationWindow =
outsideWindow(newDigit_time);
814 if (outsideDigitizationWindow) {
815 ATH_MSG_VERBOSE(
"hit outside digitization window - do not produce digits");
819
820 continue;
821 }
822
823
824 last_time = (*map_dep_iter).first;
825
826 std::unique_ptr<RpcDigit> newDigit = std::make_unique<RpcDigit>(theId, newDigit_time, digi_ToT, false);
827
828 Identifier elemId =
m_idHelper->elementID(theId);
829 RpcDigitCollection* digitCollection = nullptr;
830
831 IdentifierHash coll_hash;
832 if (
m_idHelper->get_hash(elemId, coll_hash, &rpcContext)) {
833 ATH_MSG_ERROR(
"Unable to get RPC hash id from RPC Digit collection "
834 <<
"context begin_index = " << rpcContext.
begin_index()
835 <<
" context end_index = " << rpcContext.
end_index() <<
" the identifier is \n"<<elemId);
836 }
837
838
840
841
842 if (coll_hash >= collections.size()) {
843 collections.resize (coll_hash+1);
844 }
845 digitCollection = collections[coll_hash].
get();
846 if (!digitCollection) {
847 collections[coll_hash] = std::make_unique<RpcDigitCollection>(elemId, coll_hash);
848 digitCollection = collections[coll_hash].
get();
849 }
850 digitCollection->
push_back(std::move(newDigit));
851
853
854 if (sdoContainer->find(theId) != sdoContainer->end()) {
855 std::map<Identifier, MuonSimData>::const_iterator
it = sdoContainer->find(theId);
856 std::vector<MuonSimData::Deposit> deps = ((*it).second).getdeposits();
857 deps.push_back((*map_dep_iter).second);
858 } else {
859 std::vector<MuonSimData::Deposit> deposits;
860 deposits.push_back((*map_dep_iter).second);
861 std::pair<std::map<Identifier, MuonSimData>::iterator, bool> insertResult =
862 sdoContainer->insert(std::make_pair(theId, MuonSimData(deposits, 0)));
863 if (!insertResult.second)
865 "Attention: this sdo is not recorded, since teh identifier already exists in the sdoContainer map");
866 }
867 }
868
869 } else
870 ATH_MSG_DEBUG(
"discarding digit due to dead time: " << (*map_dep_iter).first <<
" " << last_time);
871 }
872
873 }
874
875
880 }
881
882 return StatusCode::SUCCESS;
883}
float hitTime(const AFP_SIDSimHit &hit)
#define ATH_CHECK
Evaluate an expression and check for errors.
bool isValid() const
Test to see if the link can be dereferenced.
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.
const T * get(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
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.
size_type begin_index() const
size_type end_index() const
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
const RpcReadoutElement * getRpcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
bool rotatedRpcModule() const
Amg::Vector3D stripPos(const Identifier &id) const
Amg::Transform3D localToGlobalTransf(const Identifier &id) const
std::pair< HepMcParticleLink, MuonMCData > Deposit
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
TimedVector::const_iterator const_iterator
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 3, 1 > Vector3D
time(flags, cells_name, *args, **kw)
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
constexpr uint8_t stationPhi
station Phi 1 to 8