ATLAS Offline Software
Loading...
Searching...
No Matches
MuonR4::RpcDigiTool Class Referencefinal

#include <RpcDigiTool.h>

Inheritance diagram for MuonR4::RpcDigiTool:
Collaboration diagram for MuonR4::RpcDigiTool:

Public Member Functions

StatusCode initialize () override final
StatusCode finalize () override final
StatusCode processBunchXing (int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
StatusCode mergeEvent (const EventContext &ctx) override final
StatusCode prepareEvent (const EventContext &ctx, const unsigned int) override final
 When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop.
StatusCode processAllSubEvents (const EventContext &ctx) override final
 alternative interface which uses the PileUpMergeSvc to obtain all the required SubEvents.
StatusCode processAllSubEvents (const EventContext &ctx) const
 Reentrant version of the digitization tool.
 PileUpToolBase (const std::string &type, const std::string &name, const IInterface *parent)

Protected Types

using TimedHit = TimedHitPtr<xAOD::MuonSimHit>
using TimedHits = std::vector<TimedHitPtr<xAOD::MuonSimHit>>
template<class DetType>
using OutDigitCache_t = std::vector<std::unique_ptr<DetType>>
 DigitContainers are sorted by DigitCollections which are the ensemble of all hits in a given MuonChamber.
using DeadTimeMap = std::unordered_map<Identifier, double>

Protected Member Functions

StatusCode digitize (const EventContext &ctx, const TimedHits &hitsToDigit, xAOD::MuonSimHitContainer *sdoContainer) const override final
 Digitize the time ordered hits and write them to the digit format specific for the detector technology.
CLHEP::HepRandomEngine * getRandomEngine (const EventContext &ctx) const
xAOD::MuonSimHit * addSDO (const TimedHit &hit, xAOD::MuonSimHitContainer *sdoContainer) const
 Adds the timed simHit to the output SDO container.
const ActsTrk::GeometryContext & getGeoCtx (const EventContext &ctx) const
 Returns the reference to the ActsTrk::GeometryContext needed to fetch global positions from the Readout geometry.
template<class DigitColl>
DigitColl * fetchCollection (const Identifier &hitId, OutDigitCache_t< DigitColl > &digitCache) const
 Helper function that provides fetches the proper DigitCollection from the DigitCache for a given hit identifier If the Collection is fetched for the first time, it's inserted into the cache first.
template<class DigitCont, class DigitColl>
StatusCode writeDigitContainer (const EventContext &ctx, const SG::WriteHandleKey< DigitCont > &key, OutDigitCache_t< DigitColl > &&digitCache, unsigned int hashMax) const
 Helper function to move the collected digits into the final DigitContainer.

Static Protected Member Functions

static double hitTime (const TimedHit &hit)
 Returns the global time of the hit which is the sum of eventTime & individual hit time.
static bool passDeadTime (const Identifier &channelId, const double hitTime, const double deadTimeWindow, DeadTimeMap &deadTimeMap)
 Returns whether the new digit is within the dead time window.

Protected Attributes

const MuonGMR4::MuonDetectorManager * m_detMgr {nullptr}
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc

Private Types

using EdgeSide = MuonGMR4::RpcReadoutElement::EdgeSide
using DigiCache = OutDigitCache_t<RpcDigitCollection>
using PileUpHits = PileUpMergeSvc::TimedList<xAOD::MuonSimHitContainer>::type
using SimHitLocalCopy
 Create a local copy of the sim hits to ensure overlayed hits across the events remain valid.

Private Member Functions

bool digitizeHit (const TimedHit &simHit, const bool measuresPhi, const Muon::DigitEffiData *effiMap, RpcDigitCollection &outContainer, CLHEP::HepRandomEngine *rndEngine, DeadTimeMap &deadTimes) const
 Digitize the sim hit as Rpc strip 1D hit.
bool digitizeHitBI (const TimedHit &simHit, const Muon::DigitEffiData *effiMap, RpcDigitCollection &outContainer, CLHEP::HepRandomEngine *rndEngine, DeadTimeMap &deadTimes) const
 Digitize the sim hit as Rpc strip 2D hit.
int determineClusterSize (const Identifier &id, CLHEP::HepRandomEngine *rndmEngine, bool isBIRPC) const
 Returns cluster strip molteplicity.
double calculateChargeOnStrip (const TimedHit &simHit, CLHEP::HepRandomEngine *rndmEngine, const double gasGapSize) const
 Returns the charge (fC) after the amplification in gas.
std::vector< double > divideChargeOnStrips (double totalCharge, int n_strips, CLHEP::HepRandomEngine *rndmEngine) const
 Returns a vector with chages (fC) divided on strips.
double getTOT (const double aCharge) const
 Returns Time Over Threshold (ns) for a signal on a strip.
double getTOA (const double aDistance) const
 Returns Time Of Arrival (ns) for a signal on a strip.
StatusCode fillTimedHits (PileUpHits &&hitColl, TimedHits &timedHits) const
 Translates the PileUpHits into the timed hits format.

Private Attributes

SG::WriteHandleKey< RpcDigitContainer > m_writeKey
SG::ReadCondHandleKey< Muon::DigitEffiData > m_effiDataKey
std::array< std::atomic< unsigned >, 2 > m_allHits ATLAS_THREAD_SAFE {}
std::array< std::atomic< unsigned >, 2 > m_acceptedHits ATLAS_THREAD_SAFE {}
Gaudi::Property< double > m_propagationVelocity
Gaudi::Property< double > m_stripTimeResolution
Gaudi::Property< double > m_deadTime
Gaudi::Property< bool > m_digitizeMuonOnly
SG::ReadHandleKey< xAOD::MuonSimHitContainer > m_simHitKey {this, "SimHitKey", ""}
ActsTrk::GeoContextReadKey_t m_geoCtxKey
ServiceHandle< PileUpMergeSvc > m_mergeSvc {this, "PileUpMergeSvc", "PileUpMergeSvc", ""}
Gaudi::Property< std::string > m_streamName {this, "StreamName", ""}
ServiceHandle< IAthRNGSvc > m_rndmSvc {this, "RndmSvc", "AthRNGSvc", ""}
SG::WriteHandleKey< xAOD::MuonSimHitContainer > m_sdoKey {this, "OutputSDOName", ""}
Gaudi::Property< bool > m_onlyUseContainerName
Gaudi::Property< bool > m_includePileUpTruth {this, "IncludePileUpTruth", true, "Include pile-up truth info"}
std::string m_inputObjectName {""}
TimedHits m_timedHits {}
std::vector< SimHitLocalCopy > m_simHits {}

structors and AlgTool implementation

virtual bool toProcess (int bunchXing) const override
 the method this base class helps implementing
virtual bool filterPassed () const override
 dummy implementation of passing filter
virtual void resetFilter () override
 dummy implementation of filter reset
Gaudi::Property< int > m_firstXing
Gaudi::Property< int > m_lastXing
Gaudi::Property< int > m_vetoPileUpTruthLinks
bool m_filterPassed {true}

Detailed Description

Definition at line 17 of file RpcDigiTool.h.

Member Typedef Documentation

◆ DeadTimeMap

using MuonR4::MuonDigitizationTool::DeadTimeMap = std::unordered_map<Identifier, double>
protectedinherited

Definition at line 100 of file MuonDigitizationTool.h.

◆ DigiCache

◆ EdgeSide

◆ OutDigitCache_t

template<class DetType>
using MuonR4::MuonDigitizationTool::OutDigitCache_t = std::vector<std::unique_ptr<DetType>>
protectedinherited

DigitContainers are sorted by DigitCollections which are the ensemble of all hits in a given MuonChamber.

To fill the final DigitContainer thread-safely, the DigitCollections shall be cached pre cached in a OutDigitCache_t vector which is later moved to the final DigitContainer

Definition at line 80 of file MuonDigitizationTool.h.

◆ PileUpHits

◆ SimHitLocalCopy

Initial value:
std::pair<std::unique_ptr<xAOD::MuonSimHitContainer>,
std::unique_ptr<xAOD::MuonSimHitAuxContainer>>

Create a local copy of the sim hits to ensure overlayed hits across the events remain valid.

Definition at line 143 of file MuonDigitizationTool.h.

◆ TimedHit

Definition at line 57 of file MuonDigitizationTool.h.

◆ TimedHits

using MuonR4::MuonDigitizationTool::TimedHits = std::vector<TimedHitPtr<xAOD::MuonSimHit>>
protectedinherited

Definition at line 58 of file MuonDigitizationTool.h.

Member Function Documentation

◆ addSDO()

xAOD::MuonSimHit * MuonR4::MuonDigitizationTool::addSDO ( const TimedHit & hit,
xAOD::MuonSimHitContainer * sdoContainer ) const
protectedinherited

Adds the timed simHit to the output SDO container.

The hit may be rejected if it's originating from pile-up and the pile-up truth skimming strategy is applied

Definition at line 138 of file MuonDigitizationTool.cxx.

139 {
140 if(!sdoContainer) {
141 ATH_MSG_VERBOSE("No SDO container setup of writing");
142 return nullptr;
143 }
145 ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hit->identify())<<" is a pile-up truth link");
146 return nullptr;
147 }
148 ATH_MSG_VERBOSE(m_idHelperSvc->toString(hit->identify())<<", pdgID: "<<hit->pdgId()<< " genParticleLink :"<<hit->genParticleLink());
149 ATH_MSG_VERBOSE("Genparticle: "<<hit->genParticleLink());
150 xAOD::MuonSimHit* sdoHit = sdoContainer->push_back(std::make_unique<xAOD::MuonSimHit>());
151 (*sdoHit) = (*hit);
152 static const SG::Accessor<float> acc_eventTime{"MuSim_evtTime"};
153 static const SG::Accessor<unsigned short> acc_eventID{"MuSim_evtID"};
154 static const SG::Accessor<unsigned short> acc_puType{"MuSim_puType"};
155 acc_eventTime(*sdoHit) = hit.eventTime();
156 acc_eventID(*sdoHit) = hit.eventId();
157 acc_puType(*sdoHit) = hit.pileupType();
158 return sdoHit;
159 }
#define ATH_MSG_VERBOSE(x,...)
bool hit(const Container &ids, int pdgId)
value_type push_back(value_type pElem)
Add an element to the end of the collection.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Gaudi::Property< bool > m_includePileUpTruth
Gaudi::Property< int > m_vetoPileUpTruthLinks
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:573
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12

◆ calculateChargeOnStrip()

double MuonR4::RpcDigiTool::calculateChargeOnStrip ( const TimedHit & simHit,
CLHEP::HepRandomEngine * rndmEngine,
const double gasGapSize ) const
private

Returns the charge (fC) after the amplification in gas.

Parameters
simHitReference to the sim hit to digitize
rndmEngineA random engine

Definition at line 427 of file RpcDigiTool.cxx.

429 {
430
431 // Average energy to create an electron-ion pair inside RPC gas
432 constexpr double W_VALUE_EV = 30.0; // Unit: [eV/pair]
433
434 // RPC BI gas gap thickness
435 const double GAP_THICKNESS_MM = gasGapSize; // Unit: [mm] (1 mm for Phase-II BI RPCs, 2 mm for BM/BO RPCs))
436
437 // Townsend coefficient for gas mixture and operational voltage
438 constexpr double ALPHA_PER_MM = 5.5; // Unit: [1/mm]
439
440 // Energy deposited by Geant4
441 const double energy_deposit_ev = simHit->energyDeposit() / Gaudi::Units::eV;
442
443 // Number of electron-ion pairs created
444 const double N0 = energy_deposit_ev / W_VALUE_EV;
445
446 // Primary ionization poistion inside gas gap
447 const double z_hit_mm =
448 CLHEP::RandFlat::shoot(rndmEngine, 0.0, GAP_THICKNESS_MM); // Unit: [mm]
449
450 // Distance to anode
451 const double z_drift_mm = std::abs(GAP_THICKNESS_MM - z_hit_mm); // Unit: [mm]
452
453 // Avalanche gain
454 const double gas_gain = std::exp(ALPHA_PER_MM * z_drift_mm);
455
456 // Total charge
457 const double total_charge_c = N0 * gas_gain * Gaudi::Units::e_SI; // Unit: [C]
458
459 ATH_MSG_DEBUG(__func__<<"() - "<<__LINE__<<" GAP_THICKNESS_MM: "<<GAP_THICKNESS_MM<<
460 ", "<<energy_deposit_ev<<", z_hit_mm: "<<z_hit_mm<<", N0: "<<N0<<", z_drift_mm: "<<z_drift_mm
461 <<", gas_gain: "<<gas_gain<< "---> Charge on strip (fC): " << total_charge_c * 1e15);
462
463 return total_charge_c * 1e15; // charge in fC
464}
#define ATH_MSG_DEBUG(x,...)

◆ determineClusterSize()

int MuonR4::RpcDigiTool::determineClusterSize ( const Identifier & id,
CLHEP::HepRandomEngine * rndmEngine,
bool isBIRPC ) const
private

Returns cluster strip molteplicity.

Parameters
idReference to the chamber identifier
rndmEnginRandom engine used for probabilities

Definition at line 466 of file RpcDigiTool.cxx.

467 {
468
469 const RpcIdHelper &id_helper{m_idHelperSvc->rpcIdHelper()};
470
471 ATH_MSG_DEBUG("RpcDigitizationTool::in determineClusterSize");
472
473 ATH_MSG_DEBUG("Digit Id = " << id_helper.show_to_string(idGasGap));
474
475 // These cluster size probabilities were taken from the legacy RPC code.
476 // MuonSpectrometer/MuonConfig/python/RPC_DigitizationConfig.py
477 static constexpr std::array<double, 4> ClusterSizeProbabilities{0.610, 0.260,
478 0.083, 0.047};
479 // Compile-time calculation of the cumulative array
480 // Used empty capture list [] since variables are static constexpr
481 static constexpr std::array<double, 4> cumulative = []() {
482 std::array<double, 4> acumulative{};
483 acumulative[0] = ClusterSizeProbabilities[0];
484 for (size_t i = 1; i < ClusterSizeProbabilities.size(); ++i) {
485 acumulative[i] = acumulative[i - 1] + ClusterSizeProbabilities[i];
486 }
487 return acumulative;
488 }();
489
490 // These cluster size probabilities were taken from preliminary
491 // results from the BI RPC Upgrade work in 2025 at BB5.
492 // They could be updated if new results for BI RPCs become available.
493 static constexpr std::array<double, 4> ClusterSizeProbabilitiesBI{0.642, 0.316,
494 0.032, 0.010};
495 // Compile-time calculation of the cumulative array
496 // Used empty capture list [] since variables are static constexpr
497 static constexpr std::array<double, 4> cumulativeBI = []() {
498 std::array<double, 4> acumulative{};
499 acumulative[0] = ClusterSizeProbabilitiesBI[0];
500 for (size_t i = 1; i < ClusterSizeProbabilitiesBI.size(); ++i) {
501 acumulative[i] = acumulative[i - 1] + ClusterSizeProbabilitiesBI[i];
502 }
503 return acumulative;
504 }();
505
506 std::array<double, 4> theCumulative{};
507 if (isBIRPC) {
508 theCumulative=cumulativeBI;
509 } else {
510 theCumulative=cumulative;
511 }
512
513 float rndmCS = CLHEP::RandFlat::shoot(rndmEngine, 1.);
514
515 unsigned ClusterSize{1};
516 while (ClusterSize < theCumulative.size() &&
517 rndmCS > theCumulative[ClusterSize-1])
518 ++ClusterSize;
519
520 if (ClusterSize > theCumulative.size())
521 ClusterSize = theCumulative.size();
522 return ClusterSize;
523}
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form

◆ digitize()

StatusCode MuonR4::RpcDigiTool::digitize ( const EventContext & ctx,
const TimedHits & hitsToDigit,
xAOD::MuonSimHitContainer * sdoContainer ) const
finaloverrideprotectedvirtual

Digitize the time ordered hits and write them to the digit format specific for the detector technology.

A new MuonSimHitContainer pointer is parsed to also create the MuonSDO. If a new SDO should be added to the container plese use the addSDO() method as defined below.

Fetch the conditions for efficiency calculations

Standard digitization path

Write everything at the end into the final digit container

Implements MuonR4::MuonDigitizationTool.

Definition at line 59 of file RpcDigiTool.cxx.

60 {
61 const RpcIdHelper &idHelper{m_idHelperSvc->rpcIdHelper()};
62 // Prepare the temporary cache
63 DigiCache digitCache{};
65 const Muon::DigitEffiData *efficiencyMap{nullptr};
66 ATH_CHECK(SG::get(efficiencyMap, m_effiDataKey, ctx));
67
68 CLHEP::HepRandomEngine *rndEngine = getRandomEngine(ctx);
69 xAOD::ChamberViewer viewer{hitsToDigit, m_idHelperSvc.get()};
70 do {
71 DeadTimeMap deadTimes{};
72 for (const TimedHit &simHit : viewer) {
73 if (m_digitizeMuonOnly && !MC::isMuon(simHit)) {
74 continue;
75 }
76 const Identifier hitId{simHit->identify()};
77 RpcDigitCollection *digiColl = fetchCollection(hitId, digitCache);
78 const std::size_t beforeDigiSize = digiColl->size();
79 xAOD::MuonSimHit* sdo{nullptr};
80 if (m_detMgr->getRpcReadoutElement(hitId)->nPhiStrips() > 0) {
82
83 const bool digitizedPhi = digitizeHit(simHit, true, efficiencyMap,
84 *digiColl, rndEngine, deadTimes);
85 const bool digitizedEta = digitizeHit(simHit, false, efficiencyMap,
86 *digiColl, rndEngine, deadTimes);
87 if (digitizedEta || digitizedPhi) {
88 sdo = addSDO(simHit, sdoContainer);
89 }
90 } else if (digitizeHitBI(simHit, efficiencyMap, *digiColl, rndEngine,
91 deadTimes)) {
92 sdo = addSDO(simHit, sdoContainer);
93 }
94 if (sdo) {
95 sdo->setIdentifier(digiColl->back()->identify());
96 dec_etaChannel(*sdo).clear();
97 dec_phiChannel(*sdo).clear();
98 for (std::size_t newDigit = beforeDigiSize; newDigit< digiColl->size(); ++newDigit) {
99 const Identifier id = digiColl->at(newDigit)->identify();
100 ChVec_t& ch{idHelper.measuresPhi(id)? dec_phiChannel(*sdo) : dec_etaChannel(*sdo)};
101 ch.push_back(idHelper.channel(id));
102 }
103 }
104 }
105 } while (viewer.next());
107 ATH_CHECK(writeDigitContainer(ctx, m_writeKey, std::move(digitCache),
108 idHelper.module_hash_max()));
109 return StatusCode::SUCCESS;
110}
#define ATH_CHECK
Evaluate an expression and check for errors.
const T * back() const
Access the last element in the collection as an rvalue.
const T * at(size_type n) const
Access an element, as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
Identifier identify() const
Definition MuonDigit.h:30
size_type module_hash_max() const
the maximum hash value
xAOD::MuonSimHit * addSDO(const TimedHit &hit, xAOD::MuonSimHitContainer *sdoContainer) const
Adds the timed simHit to the output SDO container.
CLHEP::HepRandomEngine * getRandomEngine(const EventContext &ctx) const
TimedHitPtr< xAOD::MuonSimHit > TimedHit
DigitColl * fetchCollection(const Identifier &hitId, OutDigitCache_t< DigitColl > &digitCache) const
Helper function that provides fetches the proper DigitCollection from the DigitCache for a given hit ...
const MuonGMR4::MuonDetectorManager * m_detMgr
StatusCode writeDigitContainer(const EventContext &ctx, const SG::WriteHandleKey< DigitCont > &key, OutDigitCache_t< DigitColl > &&digitCache, unsigned int hashMax) const
Helper function to move the collected digits into the final DigitContainer.
std::unordered_map< Identifier, double > DeadTimeMap
bool digitizeHit(const TimedHit &simHit, const bool measuresPhi, const Muon::DigitEffiData *effiMap, RpcDigitCollection &outContainer, CLHEP::HepRandomEngine *rndEngine, DeadTimeMap &deadTimes) const
Digitize the sim hit as Rpc strip 1D hit.
Gaudi::Property< bool > m_digitizeMuonOnly
Definition RpcDigiTool.h:81
SG::ReadCondHandleKey< Muon::DigitEffiData > m_effiDataKey
Definition RpcDigiTool.h:62
SG::WriteHandleKey< RpcDigitContainer > m_writeKey
Definition RpcDigiTool.h:59
OutDigitCache_t< RpcDigitCollection > DigiCache
Definition RpcDigiTool.h:58
bool digitizeHitBI(const TimedHit &simHit, const Muon::DigitEffiData *effiMap, RpcDigitCollection &outContainer, CLHEP::HepRandomEngine *rndEngine, DeadTimeMap &deadTimes) const
Digitize the sim hit as Rpc strip 2D hit.
int channel(const Identifier &id) const override
bool measuresPhi(const Identifier &id) const override
void setIdentifier(const Identifier &id)
Sets the global ATLAS identifier.
bool isMuon(const T &p)
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.

◆ digitizeHit()

bool MuonR4::RpcDigiTool::digitizeHit ( const TimedHit & simHit,
const bool measuresPhi,
const Muon::DigitEffiData * effiMap,
RpcDigitCollection & outContainer,
CLHEP::HepRandomEngine * rndEngine,
DeadTimeMap & deadTimes ) const
private

Digitize the sim hit as Rpc strip 1D hit.

Parameters
simHitReference to the sim hit to digitize
measuresPhiProcess an eta or a phi strip
effiMapPointer to an efficiency look-up table
outContainerDigitCollection to push the new digit into
rndEngineRandom engine used for smearing
deadTimesReference to the last digitized times in order to apply the dead time model

Definition at line 111 of file RpcDigiTool.cxx.

115 {
116
117 ++(m_allHits[measuresPhi]); // Count all hits separately for eta and phi ([0] and [1], respectively)
118
119 const Identifier gasGapId = simHit->identify();
120 const MuonGMR4::RpcReadoutElement *reEle =
121 m_detMgr->getRpcReadoutElement(gasGapId);
122
123 const RpcIdHelper &idHelper{m_idHelperSvc->rpcIdHelper()};
124
125 bool isValid{false};
126
127 const Identifier layerId = idHelper.channelID(
128 gasGapId, idHelper.doubletZ(gasGapId), idHelper.doubletPhi(gasGapId),
129 idHelper.gasGap(gasGapId), measuresPhi, 1, isValid);
130 const IdentifierHash layHash = reEle->layerHash(gasGapId);
131
132 const MuonGMR4::StripLayerPtr &layerDesign =
133 reEle->sensorLayout(reEle->layerHash(layerId));
134
135 const MuonGMR4::StripDesign &design{layerDesign->design(measuresPhi)};
136
137 Amg::Vector3D locHitPos{xAOD::toEigen(simHit->localPosition())};
138
139 const Amg::Vector2D locPos2D = layerDesign->to2D(locHitPos, measuresPhi);
140 if (!design.insideTrapezoid(locPos2D)) {
141 ATH_MSG_VERBOSE("The hit " << Amg::toString(locHitPos) << " / "
142 << Amg::toString(locPos2D)
143 << " is outside of the trapezoid bounds for "
144 << m_idHelperSvc->toString(layerId));
145 return false;
146 }
147 const int strip = design.stripNumber(locPos2D);
148 if (strip < 0) {
149 ATH_MSG_VERBOSE("Hit " << Amg::toString(locHitPos) << " / "
150 << Amg::toString(locPos2D)
151 << " cannot trigger any signal in a strip for "
152 << m_idHelperSvc->toString(layerId) << std::endl
153 << design);
154 return false;
155 }
156
157 // Check whether the digit is actually efficient
158 const bool effiSignal =
159 !effiMap || effiMap->getEfficiency(gasGapId) >=
160 CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
161 if (!effiSignal) return false;
162
163 // Calculate distance from readout
164 const double DistanceToEdge =
165 reEle->distanceToEdge(layHash, locHitPos, EdgeSide::readOut); // mm
166
167 // Calculate charge deposited
168 const double TotalChargeOnStrip =
169 calculateChargeOnStrip(simHit, rndEngine, 2.0); // 2 mm gap for BM/BO chambers
170 ATH_MSG_VERBOSE(" total charge (fC): " << TotalChargeOnStrip);
171
172 // Calculate cluster size (number of strips)
173 int clusterSize = determineClusterSize(gasGapId, rndEngine, false);
174 ATH_MSG_VERBOSE(" cluster size: " << clusterSize);
175
176 // Get min and max strips
177 int minStrip{strip}, maxStrip{strip}; // case strip number is 1
178 if (clusterSize > 1) {
179 int halfCluster = clusterSize / 2; // half cluster size (int)
180 minStrip = strip - halfCluster; // min strip number
181 if (clusterSize % 2 == 0) { // if clusterSize is even, we have to randomly
182 // assign one strip on left or right side
183 int side = Acts::copySign(1,CLHEP::RandFlat::shoot(rndEngine, 0., 1.) + 0.5);
184 minStrip += side; // if side==1 move the min strip to right
185 }
186 maxStrip = minStrip + clusterSize - 1;
187 // Check design strip boundaries
188 minStrip = std::max(minStrip, design.firstStripNumber());
189 maxStrip = std::min(design.firstStripNumber() + design.numStrips() - 1, maxStrip);
190 }
191
192 // Recalculate cluster size with minStrip and maxStrip
193 clusterSize = (maxStrip - minStrip) + 1;
194
195 // Divide charge on N strips
196 const std::vector<double> StripCharges =
197 divideChargeOnStrips(TotalChargeOnStrip, clusterSize, rndEngine);
198
199 // Digitize each strip
200 bool hasAcceptedStrip=false;
201 for (int aStrip = minStrip; aStrip <= maxStrip; aStrip++) {
202
203 bool isValid{false};
204 const Identifier digitId{idHelper.channelID(
205 gasGapId, idHelper.doubletZ(gasGapId), idHelper.doubletPhi(gasGapId),
206 idHelper.gasGap(gasGapId), measuresPhi, aStrip, isValid)};
207
208 // Check digitID is valid
209 if (!isValid) {
210 ATH_MSG_WARNING("Failed to create a valid strip "
211 << m_idHelperSvc->toStringGasGap(gasGapId)
212 << ", strip: " << aStrip);
213 return false;
214 }
215 // Check is not dead time
216 if (!passDeadTime(digitId, hitTime(simHit), m_deadTime, deadTimes)) {
217 ATH_MSG_VERBOSE("Reject hit due to dead map constraint");
218 return false;
219 }
220
221 outContainer.push_back(std::make_unique<RpcDigit>(
222 digitId,
223 hitTime(simHit) + getTOA(DistanceToEdge) + CLHEP::RandGaussZiggurat::shoot(rndEngine, 0.0, m_stripTimeResolution),
224 getTOT(StripCharges[aStrip-minStrip])));
225
226 ATH_MSG_VERBOSE("Digitize hit "
227 << m_idHelperSvc->toString(digitId)
228 << " located at: " << Amg::toString(locHitPos) );
229 ++(m_acceptedHits[measuresPhi]); // Count accepted hits for eta ([0]) or phi ([1])
230 hasAcceptedStrip=true;
231 }
232
233 return hasAcceptedStrip;
234}
#define ATH_MSG_WARNING(x,...)
double distanceToEdge(const IdentifierHash &measHash, const Amg::Vector3D &posInStripPlane, const EdgeSide side) const
Returns the disance to the readout.
IdentifierHash layerHash(const Identifier &measId) const override final
The layer hash removes the bits from the IdentifierHash corresponding to the measurement's channel nu...
const StripLayerPtr & sensorLayout(const IdentifierHash &measHash) const
Access to the StripLayer associated to a given measurement Hash.
int firstStripNumber() const
Returns the number of the first strip.
bool insideTrapezoid(const Amg::Vector2D &extPos) const
Checks whether an external point is inside the trapezoidal area.
virtual int stripNumber(const Amg::Vector2D &pos) const
Calculates the number of the strip whose center is closest to the given point.
virtual int numStrips() const
Number of strips on the panel.
static bool passDeadTime(const Identifier &channelId, const double hitTime, const double deadTimeWindow, DeadTimeMap &deadTimeMap)
Returns whether the new digit is within the dead time window.
static double hitTime(const TimedHit &hit)
Returns the global time of the hit which is the sum of eventTime & individual hit time.
Gaudi::Property< double > m_stripTimeResolution
Definition RpcDigiTool.h:74
double getTOT(const double aCharge) const
Returns Time Over Threshold (ns) for a signal on a strip.
Gaudi::Property< double > m_deadTime
Definition RpcDigiTool.h:78
std::vector< double > divideChargeOnStrips(double totalCharge, int n_strips, CLHEP::HepRandomEngine *rndmEngine) const
Returns a vector with chages (fC) divided on strips.
int determineClusterSize(const Identifier &id, CLHEP::HepRandomEngine *rndmEngine, bool isBIRPC) const
Returns cluster strip molteplicity.
double calculateChargeOnStrip(const TimedHit &simHit, CLHEP::HepRandomEngine *rndmEngine, const double gasGapSize) const
Returns the charge (fC) after the amplification in gas.
double getTOA(const double aDistance) const
Returns Time Of Arrival (ns) for a signal on a strip.
double getEfficiency(const Identifier &channelId, bool isInnerQ1=false) const
Returns the signal generation efficiency of the sTgc channel.
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
int gasGap(const Identifier &id) const override
get the hashes
int doubletPhi(const Identifier &id) const
int doubletZ(const Identifier &id) const
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
GeoModel::TransientConstSharedPtr< StripLayer > StripLayerPtr
Definition StripLayer.h:100

◆ digitizeHitBI()

bool MuonR4::RpcDigiTool::digitizeHitBI ( const TimedHit & simHit,
const Muon::DigitEffiData * effiMap,
RpcDigitCollection & outContainer,
CLHEP::HepRandomEngine * rndEngine,
DeadTimeMap & deadTimes ) const
private

Digitize the sim hit as Rpc strip 2D hit.

Parameters
simHitReference to the sim hit to digitize
effiMapPointer to an efficiency look-up table
outContainerDigitCollection to push the new digit into
rndEngineRandom engine used for smearing
deadTimesReference to the last digitized times in order to apply the dead time model

Definition at line 237 of file RpcDigiTool.cxx.

241 {
242
243 ++(m_allHits[false]); // Count all hits for eta ([0]) since there are no phi strips in BI chambers
244 const Identifier gasGapId = simHit->identify();
245 const MuonGMR4::RpcReadoutElement *reEle =
246 m_detMgr->getRpcReadoutElement(gasGapId);
247 const Amg::Vector3D locHitPos = xAOD::toEigen(simHit->localPosition());
248 const MuonGMR4::StripDesign &design{*reEle->getParameters().etaDesign};
249 const RpcIdHelper &idHelper{m_idHelperSvc->rpcIdHelper()};
250
251 /* with RpcReadoutElement reEle you can access infor about the readout like */
252 ATH_MSG_VERBOSE("RpcDigiTool::digitizeHitBI reEle->nGasGaps "<< reEle->nGasGaps());
253 /* with StripDesign you can access the strip information of the readout
254 * element for instance: */
255 ATH_MSG_VERBOSE("RpcDigiTool::digitizeHitBI design: "<< design);
256
257 // Check the correctness of the local hit position
258 const Amg::Vector2D locHitPosition{locHitPos.x(), locHitPos.y()};
259 if (!design.insideTrapezoid(locHitPosition)) {
260 ATH_MSG_VERBOSE("The hit " << Amg::toString(locHitPosition)
261 << " is outside of the trapezoid bounds for "
262 << m_idHelperSvc->toStringGasGap(gasGapId));
263 return false;
264 }
265
266 // Calculate distance to strip edges (mm)
267 const IdentifierHash layHash = reEle->layerHash(gasGapId);
268 const double DistanceToReadOut =
269 reEle->distanceToEdge(layHash, locHitPos, EdgeSide::readOut); // mm
270 const double DistanceToHV =
271 reEle->distanceToEdge(layHash, locHitPos, EdgeSide::highVoltage); // mm
272
273 // Calculate charge deposited
274 const double TotalChargeOnStrip =
275 calculateChargeOnStrip(simHit, rndEngine, 1.0); // 1 mm gap for BI chambers
276 ATH_MSG_VERBOSE(" total charge (fC): " << TotalChargeOnStrip);
277
278 // Calculate cluster size (number of strips)
279 int clusterSize = determineClusterSize(gasGapId, rndEngine, true);
280 ATH_MSG_VERBOSE(" cluster size: " << clusterSize);
281
282 // Get corresponding strip number and apply checks
283 const int strip = design.stripNumber(locHitPosition);
284 if (strip < 0) {
285 ATH_MSG_VERBOSE("Hit " << Amg::toString(locHitPosition)
286 << " cannot trigger any signal in a strip for "
287 << m_idHelperSvc->toStringGasGap(gasGapId)
288 << std::endl
289 << design);
290 return false;
291 }
292
293 // Check whether the digit is actually efficient
294 const bool effiSignal1 =
295 !effiMap || effiMap->getEfficiency(gasGapId) >=
296 CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
297 const bool effiSignal2 =
298 !effiMap || effiMap->getEfficiency(gasGapId) >=
299 CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
300 if (!effiSignal1 && !effiSignal2) return false;
301
302 // Get min and max strips
303 int minStrip{strip}, maxStrip{strip}; // case strip number is 1
304 if (clusterSize > 1) {
305 int halfCluster = clusterSize / 2; // half cluster size (int)
306 minStrip = strip - halfCluster; // min strip number
307 if (clusterSize % 2 == 0) { // if clusterSize is even, we have to randomly
308 // assign one strip on left or right side
309 int side = Acts::copySign(1,CLHEP::RandFlat::shoot(rndEngine, 0., 1.) + 0.5);
310 minStrip += side; // if side==1 move the min strip to right
311 }
312 maxStrip = minStrip + clusterSize - 1;
313 // Check design strip boundaries
314 minStrip = std::max(minStrip, design.firstStripNumber());
315 maxStrip = std::min(design.firstStripNumber() + design.numStrips() - 1, maxStrip);
316 }
317
318 // Recalculate cluster size with minStrip and maxStrip
319 clusterSize = (maxStrip - minStrip) + 1;
320
321 // Divide charge on N strips
322 const std::vector<double> StripCharges =
323 divideChargeOnStrips(TotalChargeOnStrip, clusterSize, rndEngine);
324
325 // Digitize each strip
326 bool hasAcceptedStrip=false;
327 for (int aStrip = minStrip; aStrip <= maxStrip; aStrip++) {
328 bool isValid{false};
329 const Identifier digitId{idHelper.channelID(
330 gasGapId, idHelper.doubletZ(gasGapId), idHelper.doubletPhi(gasGapId),
331 idHelper.gasGap(gasGapId), false, aStrip, isValid)};
332
333 // Check digitID is valid
334 if (!isValid) {
335 ATH_MSG_WARNING("Failed to create a valid strip "
336 << m_idHelperSvc->toStringGasGap(gasGapId)
337 << ", strip: " << aStrip);
338 return false;
339 }
340 // Check is not dead time
341 if (!passDeadTime(digitId, hitTime(simHit), m_deadTime, deadTimes)) {
342 ATH_MSG_VERBOSE("Reject hit due to dead map constraint");
343 return false;
344 }
345
346 if (effiSignal1) {
347 outContainer.push_back(std::make_unique<RpcDigit>(
348 digitId,
349 hitTime(simHit) + getTOA(DistanceToHV) + CLHEP::RandGaussZiggurat::shoot(rndEngine, 0.0, m_stripTimeResolution),
350 getTOT(StripCharges[aStrip-minStrip])));
351 }
352 if (effiSignal2) {
353 outContainer.push_back(std::make_unique<RpcDigit>(
354 digitId,
355 hitTime(simHit) + getTOA(DistanceToReadOut) + CLHEP::RandGaussZiggurat::shoot(rndEngine, 0.0, m_stripTimeResolution),
356 getTOT(StripCharges[aStrip-minStrip]), true));
357 }
358 if (effiSignal1 || effiSignal2) {
359 ATH_MSG_VERBOSE("Digitize hit "
360 << m_idHelperSvc->toString(digitId)
361 << " located at: " << Amg::toString(locHitPos)
362 << ", SDO: " << Amg::toString(locHitPosition));
363 ++(m_acceptedHits[false]); // Count accepted hits for eta ([0]) since there are no phi strips in BI chambers
364 hasAcceptedStrip=true;
365 }
366 }
367
368 return hasAcceptedStrip;
369}
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3).

◆ divideChargeOnStrips()

std::vector< double > MuonR4::RpcDigiTool::divideChargeOnStrips ( double totalCharge,
int n_strips,
CLHEP::HepRandomEngine * rndmEngine ) const
private

Returns a vector with chages (fC) divided on strips.

Parameters
totalChargetotal charge from a single spike (fC)
n_stripsnumber of strips to divide the charge over
rndmEngineA random engine

Definition at line 372 of file RpcDigiTool.cxx.

373 {
374
375 std::vector<double> charges;
376
377 switch (n_strips) {
378 case 1: {
379 // Trivial case, all charge on a single strip
380 charges.push_back(totalCharge);
381 break;
382 }
383 case 2: {
384 // We use a Gaussian distribution centered over 0.5 to simulate
385 // a charge sharing that is on average 50/50 but includes fluctuations
386 double f = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.5, 0.15);
387
388 // Make sure fraction is bounded between 0 and 1
389 f = std::clamp(f, 0., 1.);
390
391 charges.push_back(f * totalCharge);
392 charges.push_back((1.0 - f) * totalCharge);
393 break;
394 }
395 case 3: {
396 // These fractions are guesses on a reasonable charge
397 // sharing when three strips are activated.
398 // These fractions must be updated once the final
399 // distributions of TOT from Phase-II BI RPCs
400 // are available.
401 charges.push_back(0.20 * totalCharge); // left strip
402 charges.push_back(0.60 * totalCharge); // center strip
403 charges.push_back(0.20 * totalCharge); // right strip
404 break;
405 }
406 case 4: {
407 // These fractions are guesses on a reasonable charge
408 // sharing when four strips are activated.
409 // These fractions must be updated once the final
410 // distributions of TOT from Phase-II BI RPCs
411 // are available.
412 charges.push_back(0.15 * totalCharge); // left external strip
413 charges.push_back(0.35 * totalCharge); // left internal strip
414 charges.push_back(0.35 * totalCharge); // right internal strip
415 charges.push_back(0.15 * totalCharge); // right external strip
416 break;
417 }
418 default: {
419 // return empy vector
420 break;
421 }
422 }
423
424 return charges;
425}

◆ fetchCollection()

template<class DigitColl>
DigitColl * MuonR4::MuonDigitizationTool::fetchCollection ( const Identifier & hitId,
OutDigitCache_t< DigitColl > & digitCache ) const
protectedinherited

Helper function that provides fetches the proper DigitCollection from the DigitCache for a given hit identifier If the Collection is fetched for the first time, it's inserted into the cache first.

◆ fillTimedHits()

StatusCode MuonR4::MuonDigitizationTool::fillTimedHits ( PileUpHits && hitColl,
TimedHits & timedHits ) const
privateinherited

Translates the PileUpHits into the timed hits format.

Definition at line 48 of file MuonDigitizationTool.cxx.

48 {
49 for (const auto& [timeIndex, simHitColl] : hitColl) {
50 timedHits.reserve(timedHits.capacity() + simHitColl->size());
51 for (const xAOD::MuonSimHit* simHit : *simHitColl) {
52 timedHits.emplace_back(timeIndex.time(), timeIndex.index(), simHit, timeIndex.type());
53 }
54 }
55 std::stable_sort(timedHits.begin(), timedHits.end(),
56 [](const TimedHit& a, const TimedHit& b){
57 if (a->identify() != b->identify()){
58 return a->identify() < b->identify();
59 }
60 if (a.eventId() != b.eventId()) {
61 return a.eventId() < b.eventId();
62 }
63 return a.eventTime() < b.eventTime();
64 });
65 return StatusCode::SUCCESS;
66 }
static Double_t a
if(pathvar)
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.

◆ filterPassed()

virtual bool PileUpToolBase::filterPassed ( ) const
inlineoverridevirtualinherited

dummy implementation of passing filter

Definition at line 49 of file PileUpToolBase.h.

49{ return m_filterPassed; }

◆ finalize()

StatusCode MuonR4::RpcDigiTool::finalize ( )
finaloverride

Definition at line 31 of file RpcDigiTool.cxx.

31 {
32 ATH_MSG_INFO("Tried to convert "
33 << m_allHits[0] << "/" << m_allHits[1] << " hits. In, "
34 << percentage(m_acceptedHits[0], m_allHits[0]) << "/"
35 << percentage(m_acceptedHits[1], m_allHits[1])
36 << "% of the cases, the conversion was successful");
37 return StatusCode::SUCCESS;
38}
#define ATH_MSG_INFO(x,...)

◆ getGeoCtx()

const ActsTrk::GeometryContext & MuonR4::MuonDigitizationTool::getGeoCtx ( const EventContext & ctx) const
protectedinherited

Returns the reference to the ActsTrk::GeometryContext needed to fetch global positions from the Readout geometry.

Definition at line 131 of file MuonDigitizationTool.cxx.

131 {
132 const ActsTrk::GeometryContext* gctx{};
133 if (!SG::get(gctx, m_geoCtxKey, ctx).isSuccess()) {
134 THROW_EXCEPTION("Failed to retrieve the geometry context "<<m_geoCtxKey.fullKey());
135 }
136 return *gctx;
137 }
ActsTrk::GeoContextReadKey_t m_geoCtxKey
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

◆ getRandomEngine()

CLHEP::HepRandomEngine * MuonR4::MuonDigitizationTool::getRandomEngine ( const EventContext & ctx) const
protectedinherited

Definition at line 125 of file MuonDigitizationTool.cxx.

125 {
126 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_streamName);
127 std::string rngName = m_streamName;
128 rngWrapper->setSeed(rngName, ctx);
129 return rngWrapper->getEngine(ctx);
130 }
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:154
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:108
ServiceHandle< IAthRNGSvc > m_rndmSvc
Gaudi::Property< std::string > m_streamName

◆ getTOA()

double MuonR4::RpcDigiTool::getTOA ( const double aDistance) const
private

Returns Time Of Arrival (ns) for a signal on a strip.

Parameters
aDistancedistance from hit to strip edge (m)

Definition at line 51 of file RpcDigiTool.cxx.

51 {
52 // A 2.0 ns offset is due to the signal formation and is obtained from a detailed model for RPC signal emulation.
53 // See presentation by L. Pezzotti: https://indico.cern.ch/event/1602299/contributions/6751266/attachments/3160083/5614107/lopezzot_muonsw_23_10_2025.pdf
54
55 return aDistance/m_propagationVelocity+2.0;
56 }
Gaudi::Property< double > m_propagationVelocity
Definition RpcDigiTool.h:70

◆ getTOT()

double MuonR4::RpcDigiTool::getTOT ( const double aCharge) const
private

Returns Time Over Threshold (ns) for a signal on a strip.

Parameters
aChargeelectric charge deposited on the strip (fC)

Definition at line 41 of file RpcDigiTool.cxx.

41 {
42 // This is a parameterization of BIRPC TOT (ns) values corresponding to
43 // a charge (fC), it was obtained from a detailed model for
44 // RPC signal emulation.
45 // See presentation by L. Pezzotti: https://indico.cern.ch/event/1602299/contributions/6751266/attachments/3160083/5614107/lopezzot_muonsw_23_10_2025.pdf
46 constexpr std::array<double, 3> coeffs{19.9587, 0.10081, -0.00017};
47 using namespace Acts::detail;
48
49 return polynomialSum(aCharge, coeffs);
50 }

◆ hitTime()

double MuonR4::MuonDigitizationTool::hitTime ( const TimedHit & hit)
staticprotectedinherited

Returns the global time of the hit which is the sum of eventTime & individual hit time.

Definition at line 67 of file MuonDigitizationTool.cxx.

67 {
68 return hit.eventTime() + hit->globalTime();
69 }

◆ initialize()

StatusCode MuonR4::RpcDigiTool::initialize ( )
finaloverridevirtual

Reimplemented from MuonR4::MuonDigitizationTool.

Definition at line 24 of file RpcDigiTool.cxx.

24 {
26 ATH_CHECK(m_writeKey.initialize());
27 ATH_CHECK(m_effiDataKey.initialize(!m_effiDataKey.empty()));
28 return StatusCode::SUCCESS;
29}

◆ mergeEvent()

StatusCode MuonR4::MuonDigitizationTool::mergeEvent ( const EventContext & ctx)
finaloverrideinherited

Definition at line 92 of file MuonDigitizationTool.cxx.

92 {
93 ATH_MSG_DEBUG("mergeEvent()");
94
95 SDOFiller_t sdoContainer{};
96 ATH_CHECK(digitize(ctx, m_timedHits, !m_sdoKey.empty() ? sdoContainer.get() : nullptr));
97 ATH_CHECK(sdoContainer.record(m_sdoKey, ctx));
98 m_timedHits.clear();
99 m_simHits.clear();
100 return StatusCode::SUCCESS;
101 }
xAOD::FillContainer< xAOD::MuonSimHitContainer, xAOD::MuonSimHitAuxContainer > SDOFiller_t
std::vector< SimHitLocalCopy > m_simHits
virtual StatusCode digitize(const EventContext &ctx, const TimedHits &hitsToDigit, xAOD::MuonSimHitContainer *sdoContainer) const =0
Digitize the time ordered hits and write them to the digit format specific for the detector technolog...
SG::WriteHandleKey< xAOD::MuonSimHitContainer > m_sdoKey
StatusCode record(const SG::WriteHandleKey< Cont_t > &key, const EventContext &ctx)
Record the container to store gate using the passed write handle key.
Cont_t * get() const
get operator

◆ passDeadTime()

bool MuonR4::MuonDigitizationTool::passDeadTime ( const Identifier & channelId,
const double hitTime,
const double deadTimeWindow,
DeadTimeMap & deadTimeMap )
staticprotectedinherited

Returns whether the new digit is within the dead time window.

channelId: Identifier of the fired channel

hitTime: Current hit time

deadTimeWindow: Dead time to pass before the next hit may be accepted

deadTimeMap: Map storing the last hit times from each Identifier

Channel not seen before

Update dead time map & accept hit

Definition at line 160 of file MuonDigitizationTool.cxx.

163 {
164 auto insertItr = deadTimeMap.insert(std::make_pair(channelId,hitTime));
166 if (insertItr.second) {
167 return true;
168 }
169 if (hitTime - insertItr.first->second < deadTimeWindow) {
170 return false;
171 }
173 insertItr.first->second = hitTime;
174 return true;
175 }

◆ PileUpToolBase()

PileUpToolBase::PileUpToolBase ( const std::string & type,
const std::string & name,
const IInterface * parent )
inherited

Definition at line 22 of file PileUpToolBase.cxx.

10 : base_class(type, name, parent)
11{
12}

◆ prepareEvent()

StatusCode MuonR4::MuonDigitizationTool::prepareEvent ( const EventContext & ctx,
const unsigned int nInputEvents )
finaloverrideinherited

When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop.

Not able to access SubEvents

Definition at line 39 of file MuonDigitizationTool.cxx.

40 {
41
42 ATH_MSG_DEBUG("prepareEvent() called for " << nInputEvents << " input events");
43 m_timedHits.clear();
44 m_simHits.clear();
45 return StatusCode::SUCCESS;
46 }

◆ processAllSubEvents() [1/2]

StatusCode MuonR4::MuonDigitizationTool::processAllSubEvents ( const EventContext & ctx) const
inherited

Reentrant version of the digitization tool.

In case of single hits container just load the collection using read handles

Definition at line 75 of file MuonDigitizationTool.cxx.

75 {
76 PileUpHits hitCollList{};
77 TimedHits timedHits{};
80 const xAOD::MuonSimHitContainer* hitCollection{nullptr};
81 ATH_CHECK(SG::get(hitCollection, m_simHitKey, ctx));
82 hitCollList.emplace_back(PileUpTimeEventIndex(0), hitCollection);
83 } else {
84 ATH_CHECK(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList));
85 }
86 ATH_CHECK(fillTimedHits(std::move(hitCollList), timedHits));
87 SDOFiller_t sdoContainer{};
88 ATH_CHECK(digitize(ctx, timedHits, !m_sdoKey.empty() ? sdoContainer.get() : nullptr));
89 ATH_CHECK(sdoContainer.record(m_sdoKey, ctx));
90 return StatusCode::SUCCESS;
91 }
ServiceHandle< PileUpMergeSvc > m_mergeSvc
std::vector< TimedHitPtr< xAOD::MuonSimHit > > TimedHits
Gaudi::Property< bool > m_onlyUseContainerName
SG::ReadHandleKey< xAOD::MuonSimHitContainer > m_simHitKey
StatusCode fillTimedHits(PileUpHits &&hitColl, TimedHits &timedHits) const
Translates the PileUpHits into the timed hits format.
PileUpMergeSvc::TimedList< xAOD::MuonSimHitContainer >::type PileUpHits
MuonSimHitContainer_v1 MuonSimHitContainer
Define the version of the pixel cluster container.

◆ processAllSubEvents() [2/2]

StatusCode MuonR4::MuonDigitizationTool::processAllSubEvents ( const EventContext & ctx)
finaloverridevirtualinherited

alternative interface which uses the PileUpMergeSvc to obtain all the required SubEvents.

Reimplemented from PileUpToolBase.

Definition at line 70 of file MuonDigitizationTool.cxx.

70 {
71 const MuonDigitizationTool* digiTool = this;
72 return digiTool->processAllSubEvents(ctx);
73 }

◆ processBunchXing()

StatusCode MuonR4::MuonDigitizationTool::processBunchXing ( int bunchXing,
SubEventIterator bSubEvents,
SubEventIterator eSubEvents )
finaloverridevirtualinherited

Reimplemented from PileUpToolBase.

Definition at line 104 of file MuonDigitizationTool.cxx.

106 {
107 ATH_MSG_DEBUG("processBunchXing()" << bunchXing);
108 PileUpHits hitList{}, hitListPermanent{};
109 ATH_CHECK(m_mergeSvc->retrieveSubSetEvtData(m_inputObjectName, hitList, bunchXing, bSubEvents, eSubEvents));
110 ATH_MSG_VERBOSE(hitList.size() << " hits in xAODMuonSimHitContainer " << m_inputObjectName << " found");
111 for (auto& [hitPtr, hitContainer] : hitList) {
112 auto copyContainer = std::make_unique<xAOD::MuonSimHitContainer>();
113 auto copyAuxContainer = std::make_unique<xAOD::MuonSimHitAuxContainer>();
114 copyContainer->setStore(copyAuxContainer.get());
115 for (const xAOD::MuonSimHit* copyMe : *hitContainer) {
116 (*copyContainer->push_back(std::make_unique<xAOD::MuonSimHit>())) = (*copyMe);
117 }
118 hitListPermanent.emplace_back(hitPtr, copyContainer.get());
119 m_simHits.emplace_back(std::move(copyContainer), std::move(copyAuxContainer));
120 }
121 ATH_CHECK(fillTimedHits(std::move(hitListPermanent), m_timedHits));
122 return StatusCode::SUCCESS;
123 }

◆ resetFilter()

virtual void PileUpToolBase::resetFilter ( )
inlineoverridevirtualinherited

dummy implementation of filter reset

Reimplemented in MergeTruthJetsTool.

Definition at line 51 of file PileUpToolBase.h.

51{ m_filterPassed=true; }

◆ toProcess()

virtual bool PileUpToolBase::toProcess ( int bunchXing) const
inlineoverridevirtualinherited

the method this base class helps implementing

Reimplemented in MergeHijingParsTool, and MergeTrackRecordCollTool.

Definition at line 32 of file PileUpToolBase.h.

32 {
33 //closed interval [m_firstXing,m_lastXing]
34 return !((m_firstXing > bunchXing) || (bunchXing > m_lastXing));
35 }
Gaudi::Property< int > m_firstXing
Gaudi::Property< int > m_lastXing

◆ writeDigitContainer()

template<class DigitCont, class DigitColl>
StatusCode MuonR4::MuonDigitizationTool::writeDigitContainer ( const EventContext & ctx,
const SG::WriteHandleKey< DigitCont > & key,
OutDigitCache_t< DigitColl > && digitCache,
unsigned int hashMax ) const
protectedinherited

Helper function to move the collected digits into the final DigitContainer.

The function needs the maximal size of the container in advance which is provided by calling the module_hash_max() function of the corresponding MuonIdHelper.

Member Data Documentation

◆ ATLAS_THREAD_SAFE [1/2]

std::array<std::atomic<unsigned>, 2> m_acceptedHits MuonR4::RpcDigiTool::ATLAS_THREAD_SAFE {}
mutableprivate

Definition at line 68 of file RpcDigiTool.h.

68{};

◆ ATLAS_THREAD_SAFE [2/2]

std::array<std::atomic<unsigned>, 2> m_allHits MuonR4::RpcDigiTool::ATLAS_THREAD_SAFE {}
mutableprivate

Definition at line 66 of file RpcDigiTool.h.

66{};

◆ m_deadTime

Gaudi::Property<double> MuonR4::RpcDigiTool::m_deadTime
private
Initial value:
{this, "deadTime",
100. * Gaudi::Units::nanosecond}

Definition at line 78 of file RpcDigiTool.h.

78 {this, "deadTime",
79 100. * Gaudi::Units::nanosecond};

◆ m_detMgr

const MuonGMR4::MuonDetectorManager* MuonR4::MuonDigitizationTool::m_detMgr {nullptr}
protectedinherited

Definition at line 111 of file MuonDigitizationTool.h.

111{nullptr};

◆ m_digitizeMuonOnly

Gaudi::Property<bool> MuonR4::RpcDigiTool::m_digitizeMuonOnly
private
Initial value:
{
this, "ProcessTrueMuonsOnly", false,
"If set to true hit with pdgId != 13 are skipped"}

Definition at line 81 of file RpcDigiTool.h.

81 {
82 this, "ProcessTrueMuonsOnly", false,
83 "If set to true hit with pdgId != 13 are skipped"};

◆ m_effiDataKey

SG::ReadCondHandleKey<Muon::DigitEffiData> MuonR4::RpcDigiTool::m_effiDataKey
private
Initial value:
{
this, "EffiDataKey", "RpcDigitEff",
"Efficiency constants of the individual Rpc gasGaps"}

Definition at line 62 of file RpcDigiTool.h.

62 {
63 this, "EffiDataKey", "RpcDigitEff",
64 "Efficiency constants of the individual Rpc gasGaps"};

◆ m_filterPassed

bool PileUpToolBase::m_filterPassed {true}
protectedinherited

Definition at line 60 of file PileUpToolBase.h.

60{true};

◆ m_firstXing

Gaudi::Property<int> PileUpToolBase::m_firstXing
protectedinherited
Initial value:
{this, "FirstXing", -999,
"First bunch-crossing in which det is live"}

Definition at line 54 of file PileUpToolBase.h.

54 {this, "FirstXing", -999,
55 "First bunch-crossing in which det is live"};

◆ m_geoCtxKey

ActsTrk::GeoContextReadKey_t MuonR4::MuonDigitizationTool::m_geoCtxKey
privateinherited
Initial value:
{this, "AlignmentKey", "ActsAlignment",
"Geometry context"}

Definition at line 123 of file MuonDigitizationTool.h.

123 {this, "AlignmentKey", "ActsAlignment",
124 "Geometry context"};

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> MuonR4::MuonDigitizationTool::m_idHelperSvc
protectedinherited
Initial value:
{this, "MuonIdHelperSvc",
"Muon::MuonIdHelperSvc/MuonIdHelperSvc"}

Definition at line 113 of file MuonDigitizationTool.h.

113 {this, "MuonIdHelperSvc",
114 "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};

◆ m_includePileUpTruth

Gaudi::Property<bool> MuonR4::MuonDigitizationTool::m_includePileUpTruth {this, "IncludePileUpTruth", true, "Include pile-up truth info"}
privateinherited

Definition at line 137 of file MuonDigitizationTool.h.

137{this, "IncludePileUpTruth", true, "Include pile-up truth info"};

◆ m_inputObjectName

std::string MuonR4::MuonDigitizationTool::m_inputObjectName {""}
privateinherited

Definition at line 139 of file MuonDigitizationTool.h.

139{""};

◆ m_lastXing

Gaudi::Property<int> PileUpToolBase::m_lastXing
protectedinherited
Initial value:
{this, "LastXing", 999,
"Last bunch-crossing in which det is live"}

Definition at line 56 of file PileUpToolBase.h.

56 {this, "LastXing", 999,
57 "Last bunch-crossing in which det is live"};

◆ m_mergeSvc

ServiceHandle<PileUpMergeSvc> MuonR4::MuonDigitizationTool::m_mergeSvc {this, "PileUpMergeSvc", "PileUpMergeSvc", ""}
privateinherited

Definition at line 126 of file MuonDigitizationTool.h.

126{this, "PileUpMergeSvc", "PileUpMergeSvc", ""};

◆ m_onlyUseContainerName

Gaudi::Property<bool> MuonR4::MuonDigitizationTool::m_onlyUseContainerName
privateinherited
Initial value:
{this, "OnlyUseContainerName", false,
"Don't use the ReadHandleKey directly. Just extract the container name from it."}

Definition at line 134 of file MuonDigitizationTool.h.

134 {this, "OnlyUseContainerName", false,
135 "Don't use the ReadHandleKey directly. Just extract the container name from it."};

◆ m_propagationVelocity

Gaudi::Property<double> MuonR4::RpcDigiTool::m_propagationVelocity
private
Initial value:
{
this, "propSpeed", 2.0/3.0 * Gaudi::Units::c_light,
"Propagation speed of the signal inside the strip"}

Definition at line 70 of file RpcDigiTool.h.

70 {
71 this, "propSpeed", 2.0/3.0 * Gaudi::Units::c_light,
72 "Propagation speed of the signal inside the strip"}; // measured: 20 cm/ns

◆ m_rndmSvc

ServiceHandle<IAthRNGSvc> MuonR4::MuonDigitizationTool::m_rndmSvc {this, "RndmSvc", "AthRNGSvc", ""}
privateinherited

Definition at line 130 of file MuonDigitizationTool.h.

130{this, "RndmSvc", "AthRNGSvc", ""}; // Random number service

◆ m_sdoKey

SG::WriteHandleKey<xAOD::MuonSimHitContainer> MuonR4::MuonDigitizationTool::m_sdoKey {this, "OutputSDOName", ""}
privateinherited

Definition at line 132 of file MuonDigitizationTool.h.

132{this, "OutputSDOName", ""};

◆ m_simHitKey

SG::ReadHandleKey<xAOD::MuonSimHitContainer> MuonR4::MuonDigitizationTool::m_simHitKey {this, "SimHitKey", ""}
privateinherited

Definition at line 121 of file MuonDigitizationTool.h.

121{this, "SimHitKey", ""};

◆ m_simHits

std::vector<SimHitLocalCopy> MuonR4::MuonDigitizationTool::m_simHits {}
privateinherited

Definition at line 145 of file MuonDigitizationTool.h.

145{};

◆ m_streamName

Gaudi::Property<std::string> MuonR4::MuonDigitizationTool::m_streamName {this, "StreamName", ""}
privateinherited

Definition at line 128 of file MuonDigitizationTool.h.

128{this, "StreamName", ""};

◆ m_stripTimeResolution

Gaudi::Property<double> MuonR4::RpcDigiTool::m_stripTimeResolution
private
Initial value:
{
this, "timeResolution", 0.29 * Gaudi::Units::nanosecond,
"Estimated time resolution of the strip readout"}

Definition at line 74 of file RpcDigiTool.h.

74 {
75 this, "timeResolution", 0.29 * Gaudi::Units::nanosecond,
76 "Estimated time resolution of the strip readout"}; // measured: 0.29 ns https://indico.cern.ch/event/1722258/contributions/7264004/attachments/3339594/5984842/BI-DCT_performance_2026_09_08.pdf

◆ m_timedHits

TimedHits MuonR4::MuonDigitizationTool::m_timedHits {}
privateinherited

Definition at line 141 of file MuonDigitizationTool.h.

141{};

◆ m_vetoPileUpTruthLinks

Gaudi::Property<int> PileUpToolBase::m_vetoPileUpTruthLinks
protectedinherited
Initial value:
{this, "VetoPileUpTruthLinks", true,
"Ignore links to suppressed pile-up truth"}

Definition at line 58 of file PileUpToolBase.h.

58 {this, "VetoPileUpTruthLinks", true,
59 "Ignore links to suppressed pile-up truth"};

◆ m_writeKey

SG::WriteHandleKey<RpcDigitContainer> MuonR4::RpcDigiTool::m_writeKey
private
Initial value:
{this, "OutputObjectName",
"RPC_DIGITS"}

Definition at line 59 of file RpcDigiTool.h.

59 {this, "OutputObjectName",
60 "RPC_DIGITS"};

The documentation for this class was generated from the following files: