6#include "CLHEP/Random/RandGaussZiggurat.h"
7#include "GaudiKernel/SystemOfUnits.h"
13 constexpr double percentage(
unsigned int numerator,
unsigned int denom) {
14 return 100. * numerator / std::max(denom, 1u);
16 using ChVec_t = std::vector<std::uint16_t>;
28 return StatusCode::SUCCESS;
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;
46 constexpr std::array<double, 3> coeffs{19.9587, 0.10081, -0.00017};
49 return polynomialSum(aCharge, coeffs);
72 for (
const TimedHit &simHit : viewer) {
78 const std::size_t beforeDigiSize = digiColl->
size();
80 if (
m_detMgr->getRpcReadoutElement(hitId)->nPhiStrips() > 0) {
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);
90 }
else if (
digitizeHitBI(simHit, efficiencyMap, *digiColl, rndEngine,
92 sdo =
addSDO(simHit, sdoContainer);
96 dec_etaChannel(*sdo).clear();
97 dec_phiChannel(*sdo).clear();
98 for (std::size_t newDigit = beforeDigiSize; newDigit< digiColl->
size(); ++newDigit) {
100 ChVec_t& ch{idHelper.
measuresPhi(
id)? dec_phiChannel(*sdo) : dec_etaChannel(*sdo)};
101 ch.push_back(idHelper.
channel(
id));
105 }
while (viewer.
next());
109 return StatusCode::SUCCESS;
114 CLHEP::HepRandomEngine *rndEngine,
117 ++(m_allHits[measuresPhi]);
121 m_detMgr->getRpcReadoutElement(gasGapId);
139 const Amg::Vector2D locPos2D = layerDesign->to2D(locHitPos, measuresPhi);
143 <<
" is outside of the trapezoid bounds for "
151 <<
" cannot trigger any signal in a strip for "
158 const bool effiSignal =
160 CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
161 if (!effiSignal)
return false;
164 const double DistanceToEdge =
168 const double TotalChargeOnStrip =
178 if (clusterSize > 1) {
179 int halfCluster = clusterSize / 2;
180 minStrip =
strip - halfCluster;
181 if (clusterSize % 2 == 0) {
183 int side = Acts::copySign(1,CLHEP::RandFlat::shoot(rndEngine, 0., 1.) + 0.5);
186 maxStrip = minStrip + clusterSize - 1;
193 clusterSize = (maxStrip - minStrip) + 1;
196 const std::vector<double> StripCharges =
200 bool hasAcceptedStrip=
false;
201 for (
int aStrip = minStrip; aStrip <= maxStrip; aStrip++) {
212 <<
", strip: " << aStrip);
221 outContainer.
push_back(std::make_unique<RpcDigit>(
224 getTOT(StripCharges[aStrip-minStrip])));
229 ++(m_acceptedHits[measuresPhi]);
230 hasAcceptedStrip=
true;
233 return hasAcceptedStrip;
240 CLHEP::HepRandomEngine *rndEngine,
243 ++(m_allHits[
false]);
246 m_detMgr->getRpcReadoutElement(gasGapId);
258 const Amg::Vector2D locHitPosition{locHitPos.x(), locHitPos.y()};
261 <<
" is outside of the trapezoid bounds for "
268 const double DistanceToReadOut =
270 const double DistanceToHV =
274 const double TotalChargeOnStrip =
286 <<
" cannot trigger any signal in a strip for "
294 const bool effiSignal1 =
296 CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
297 const bool effiSignal2 =
299 CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
300 if (!effiSignal1 && !effiSignal2)
return false;
304 if (clusterSize > 1) {
305 int halfCluster = clusterSize / 2;
306 minStrip =
strip - halfCluster;
307 if (clusterSize % 2 == 0) {
309 int side = Acts::copySign(1,CLHEP::RandFlat::shoot(rndEngine, 0., 1.) + 0.5);
312 maxStrip = minStrip + clusterSize - 1;
319 clusterSize = (maxStrip - minStrip) + 1;
322 const std::vector<double> StripCharges =
326 bool hasAcceptedStrip=
false;
327 for (
int aStrip = minStrip; aStrip <= maxStrip; aStrip++) {
337 <<
", strip: " << aStrip);
347 outContainer.
push_back(std::make_unique<RpcDigit>(
350 getTOT(StripCharges[aStrip-minStrip])));
353 outContainer.
push_back(std::make_unique<RpcDigit>(
356 getTOT(StripCharges[aStrip-minStrip]),
true));
358 if (effiSignal1 || effiSignal2) {
363 ++(m_acceptedHits[
false]);
364 hasAcceptedStrip=
true;
368 return hasAcceptedStrip;
373 CLHEP::HepRandomEngine *rndmEngine)
const {
375 std::vector<double> charges;
380 charges.push_back(totalCharge);
386 double f = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.5, 0.15);
389 f = std::clamp(f, 0., 1.);
391 charges.push_back(f * totalCharge);
392 charges.push_back((1.0 - f) * totalCharge);
401 charges.push_back(0.20 * totalCharge);
402 charges.push_back(0.60 * totalCharge);
403 charges.push_back(0.20 * totalCharge);
412 charges.push_back(0.15 * totalCharge);
413 charges.push_back(0.35 * totalCharge);
414 charges.push_back(0.35 * totalCharge);
415 charges.push_back(0.15 * totalCharge);
428 CLHEP::HepRandomEngine *rndmEngine,
429 const double gasGapSize)
const {
432 constexpr double W_VALUE_EV = 30.0;
435 const double GAP_THICKNESS_MM = gasGapSize;
438 constexpr double ALPHA_PER_MM = 5.5;
441 const double energy_deposit_ev = simHit->
energyDeposit() / Gaudi::Units::eV;
444 const double N0 = energy_deposit_ev / W_VALUE_EV;
447 const double z_hit_mm =
448 CLHEP::RandFlat::shoot(rndmEngine, 0.0, GAP_THICKNESS_MM);
451 const double z_drift_mm = std::abs(GAP_THICKNESS_MM - z_hit_mm);
454 const double gas_gain = std::exp(ALPHA_PER_MM * z_drift_mm);
457 const double total_charge_c = N0 * gas_gain * Gaudi::Units::e_SI;
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);
463 return total_charge_c * 1e15;
467 const Identifier &idGasGap, CLHEP::HepRandomEngine *rndmEngine,
bool isBIRPC)
const {
471 ATH_MSG_DEBUG(
"RpcDigitizationTool::in determineClusterSize");
477 static constexpr std::array<double, 4> ClusterSizeProbabilities{0.610, 0.260,
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];
493 static constexpr std::array<double, 4> ClusterSizeProbabilitiesBI{0.642, 0.316,
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];
506 std::array<double, 4> theCumulative{};
508 theCumulative=cumulativeBI;
510 theCumulative=cumulative;
513 float rndmCS = CLHEP::RandFlat::shoot(rndmEngine, 1.);
515 unsigned ClusterSize{1};
516 while (ClusterSize < theCumulative.size() &&
517 rndmCS > theCumulative[ClusterSize-1])
520 if (ClusterSize > theCumulative.size())
521 ClusterSize = theCumulative.size();
#define ATH_CHECK
Evaluate an expression and check for errors.
bool isValid() const
Test to see if the link can be dereferenced.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
ATLAS-specific HepMC functions.
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
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.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
This is a "hash" representation of an Identifier.
Identifier identify() const
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.
const parameterBook & getParameters() const
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3).
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.
size_type module_hash_max() const
the maximum hash value
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 channel(const Identifier &id) const override
int doubletPhi(const Identifier &id) const
bool measuresPhi(const Identifier &id) const override
int doubletZ(const Identifier &id) const
bool next()
Loads the hits from the next chamber.
void setIdentifier(const Identifier &id)
Sets the global ATLAS identifier.
Identifier identify() const
Returns the global ATLAS identifier of the SimHit.
float energyDeposit() const
Returns the energy deposited by the traversing particle inside the gas volume.
ConstVectorMap< 3 > localPosition() const
Returns the local postion of the traversing particle.
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
This header ties the generic definitions in this package.
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
MuonSimHitContainer_v1 MuonSimHitContainer
Define the version of the pixel cluster container.
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.