ATLAS Offline Software
Loading...
Searching...
No Matches
MuonR4::sTgcDigitMaker Class Reference

#include <sTgcDigitMaker.h>

Inheritance diagram for MuonR4::sTgcDigitMaker:
Collaboration diagram for MuonR4::sTgcDigitMaker:

Classes

struct  DigiConditions
 Holds necessary conditions and data for digitization. More...
struct  DigiInput
 Helper struct to carry the digit information around. More...
struct  GammaParameter
 Stores gamma distribution parameters for estimating digit time. More...
struct  Ionization
 Holds information about ionization points in the gas volume. More...

Public Types

enum class  digitMode : std::uint8_t { StripsOnly = 1 , StripsAndPads = 2 , AllChType = 3 }
 Constructor initializing digitization parameters. More...
using TimedHit = TimedHitPtr<xAOD::MuonSimHit>
using ReadoutChannelType = sTgcIdHelper::sTgcChannelTypes
using sTgcDigitVec = std::vector<std::unique_ptr<sTgcDigit>>
 Digitize a given hit.

Public Member Functions

 sTgcDigitMaker (const MuonGMR4::MuonDetectorManager *detMgr, digitMode mode, double meanGasGain, bool doPadChargeSharing)
virtual ~sTgcDigitMaker ()
 Destructor.
StatusCode initialize ()
 Initialize digitization parameters, including reading necessary data files.
sTgcDigitVec executeDigi (const DigiConditions &condContainers, const TimedHit &hit) const
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Member Functions

bool getIonizationPoint (const TimedHit &hit, const DigiConditions &condContainers, Ionization &ionization) const
 Computes the ionization point for a hit.
double calculateTotalCharge (double energyDeposit, CLHEP::HepRandomEngine *rndEngine) const
 Calculates total charge from energy deposit, including gas gain.
sTgcDigitVec processStripDigitization (const DigiConditions &condContainers, const DigiInput &digiInput) const
 Processes strip digitization for a given hit.
sTgcDigitVec processPadDigitization (const DigiInput &digiInput) const
 Processes pad digitization for a given hit.
sTgcDigitVec processWireDigitization (const DigiInput &digiInput) const
 Processes wire digitization for a given hit.
sTgcDigitVec processStripChargeSharing (const DigiInput &digiInput, const double peak_position, const int stripNumber) const
 Handles charge sharing for strip clusters.
sTgcDigitVec processPadChargeSharing (const DigiInput &digiInput, const int padEta, const int padPhi) const
 Handles charge sharing for pad clusters.
StatusCode readFileOfTimeArrival ()
 Reads time arrival data file.
StatusCode readFileOfTimeOffsetStrip ()
 Reads strip time offset data file.
Ionization pointClosestApproach (const MuonGMR4::StripLayer &stripLayer, int wireNumber, const Amg::Vector3D &locHitPos, const Amg::Vector3D &locHitDir, const double stepLength) const
 Computes the closest approach between a trajectory and a wire segment.
double getTimeOffsetStrip (size_t neighbor_index) const
 Gets the time offset for a strip cluster.
GammaParameter getGammaParameter (double distance) const
 Retrieves gamma distribution parameters based on distance.
double getMostProbableArrivalTime (double distance) const
 Computes the most probable arrival time based on the distance of closest approach.
double chargeIntegral (double N, double M) const
void initMessaging () const
 Initialize our message level and MessageSvc.

Static Private Member Functions

static void addDigit (sTgcDigitVec &digits, const Identifier &id, double digittime, double charge)
 Adds a digit to the appropriate cache.
static double getPadChargeFraction (double distance)
 Computes charge fraction shared among pads.

Private Attributes

std::vector< GammaParameterm_gammaParameter
std::array< double, 5 > m_mostProbableArrivalTime {make_array<double, 5>(0.)}
std::array< double, 6 > m_timeOffsetStrip {make_array<double, 6>(0.)}
const MuonGMR4::MuonDetectorManagerm_detMgr {nullptr}
const Muon::IMuonIdHelperSvcm_idHelperSvc {m_detMgr->idHelperSvc()}
const sTgcIdHelperm_idHelper {m_idHelperSvc->stgcIdHelper()}
digitMode m_digitMode {digitMode::AllChType}
 define offsets and widths of time windows for signals from wiregroups and strips.
double m_theta {10}
double m_meanGasGain {5.e4}
bool m_doPadSharing {false}
bool m_doTimeOffsetStrip {false}
double m_StripResolution {0.0949}
double m_posResIncident {1.}
double m_posResAngular {0.305/m_StripResolution}
double m_chargeAngularFactor {4.0}
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging)

Static Private Attributes

static constexpr std::array< double, 2 > m_clusterParams {0.573, 1.092}

Detailed Description

Member Typedef Documentation

◆ ReadoutChannelType

◆ sTgcDigitVec

using MuonR4::sTgcDigitMaker::sTgcDigitVec = std::vector<std::unique_ptr<sTgcDigit>>

Digitize a given hit.

Parameters
condContainersConditions required for digitization.
hitThe simulated hit to be digitized.

Definition at line 79 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/sTgcDigitizationR4/sTgcDigitMaker.h.

◆ TimedHit

Member Enumeration Documentation

◆ digitMode

enum class MuonR4::sTgcDigitMaker::digitMode : std::uint8_t
strong

Constructor initializing digitization parameters.

Enumerator
StripsOnly 
StripsAndPads 
AllChType 

Definition at line 41 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/sTgcDigitizationR4/sTgcDigitMaker.h.

41 : std::uint8_t {
42 StripsOnly = 1,
43 StripsAndPads = 2,
44 AllChType = 3,
45 };

Constructor & Destructor Documentation

◆ sTgcDigitMaker()

sTgcDigitMaker::sTgcDigitMaker ( const MuonGMR4::MuonDetectorManager * detMgr,
digitMode mode,
double meanGasGain,
bool doPadChargeSharing )

◆ ~sTgcDigitMaker()

sTgcDigitMaker::~sTgcDigitMaker ( )
virtualdefault

Destructor.

Member Function Documentation

◆ addDigit()

void sTgcDigitMaker::addDigit ( sTgcDigitVec & digits,
const Identifier & id,
double digittime,
double charge )
staticprivate

Adds a digit to the appropriate cache.

Definition at line 632 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

635 {
636
637 constexpr double tolerance = 0.1;
638 if (!std::ranges::any_of(digits, [&](std::unique_ptr<sTgcDigit>& known) {
639 return known->identify() == id && std::abs(digittime - known->time()) < tolerance;
640 })) {
641 digits.push_back(std::make_unique<sTgcDigit>(id, 0, digittime, charge, 0, 0));
642 }
643}
double charge(const T &p)
Definition AtlasPID.h:997
constexpr double tolerance

◆ calculateTotalCharge()

double sTgcDigitMaker::calculateTotalCharge ( double energyDeposit,
CLHEP::HepRandomEngine * rndEngine ) const
private

Calculates total charge from energy deposit, including gas gain.

Definition at line 182 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

182 {
183 // Ionized charge in pC per keV deposited
184 const double ionized_charge = (5.65E-6) * energyDeposit / CLHEP::keV;
185
186 // Calculate avalanche gain using gamma distribution (Polya function approximation)
187 const double gain = CLHEP::RandGamma::shoot(rndEngine, 1. + m_theta, (1. + m_theta) / m_meanGasGain);
188
189 return gain * ionized_charge;
190}

◆ chargeIntegral()

double sTgcDigitMaker::chargeIntegral ( double N,
double M ) const
private

Definition at line 711 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

711 {
712
713 double term1 = 0.25 * std::erf( M / (std::sqrt(2) * m_clusterParams[0]));
714 double term2 = 0.25 * std::erf( N / (std::sqrt(2) * m_clusterParams[0]));
715 double term3 = 0.25 * std::erf( M / (std::sqrt(2) * m_clusterParams[1]));
716 double term4 = 0.25 * std::erf( N / (std::sqrt(2) * m_clusterParams[1]));
717
718 return (term1 - term2 + term3 - term4);
719}

◆ executeDigi()

sTgcDigitVec sTgcDigitMaker::executeDigi ( const DigiConditions & condContainers,
const TimedHit & hit ) const

Definition at line 195 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

196 {
197 sTgcDigitVec allDigits{};
198 // Extract energy deposit from the hit
199 const double energyDeposit = hit->energyDeposit();
200 if (energyDeposit < std::numeric_limits<float>::epsilon()) {
201 return allDigits; // Ignore hits with no energy deposit
202 }
203
204 // Retrieve the detector element for the given hit
205 const Identifier hitId = hit->identify();
206
207 // HV efficiency correction
208 if (condContainers.efficiencies) {
209 const double efficiency = condContainers.efficiencies->getEfficiency(hitId);
210 if (CLHEP::RandFlat::shoot(condContainers.rndEngine,0.0,1.0) > efficiency) {
211 return allDigits;
212 }
213 }
214
215
216 ATH_MSG_DEBUG("Retrieving detector element for: "<< m_idHelperSvc->toStringDetEl(hitId)
217 << " energyDeposit "<< energyDeposit );
218
219
220 // Get ionization point and time
221 Ionization ionization{};
222 if (!getIonizationPoint(hit, condContainers, ionization)) {
223 ATH_MSG_DEBUG("Failed to get ionization point for hit "<< m_idHelperSvc->toStringDetEl(hitId));
224 return allDigits;
225 }
226
227 DigiInput digiInput{};
228 digiInput.hitId = hitId;
229 digiInput.totalCharge = calculateTotalCharge(energyDeposit, condContainers.rndEngine);
230 digiInput.time = ionization.time;
231 digiInput.posOnSurf = ionization.posOnWire;
232 digiInput.hitDir = xAOD::toEigen(hit->localDirection());
233 digiInput.reEle = m_detMgr->getsTgcReadoutElement(hitId);
234
235 ATH_MSG_DEBUG("Ionization_info: distance: " << ionization.distance
236 << " locHitPos: " <<Amg::toString(xAOD::toEigen(hit->localPosition()), 3)
237 << " locHitDir: " <<Amg::toString(xAOD::toEigen(hit->localDirection()), 3)
238 << " posOnTrack: " <<Amg::toString(ionization.posOnSegment, 3)
239 << " posOnWire: " << Amg::toString(ionization.posOnWire, 3)
240 << " total charge: " << calculateTotalCharge(energyDeposit, condContainers.rndEngine)
241 << " EDep: " << energyDeposit
242 <<" "<<m_idHelperSvc->toStringGasGap(hitId));
243
244 //##################################################################################
245 //######################################### strip readout ##########################
246 //##################################################################################
247 sTgcDigitVec stripDigits = processStripDigitization(condContainers, digiInput);
248
250 ATH_MSG_WARNING("Only digitize strip response !");
251 return stripDigits;
252 }
253 allDigits.insert(allDigits.end(),
254 std::make_move_iterator(stripDigits.begin()),
255 std::make_move_iterator(stripDigits.end()));
256
257 //##################################################################################
258 //######################################### pad readout ############################
259 //##################################################################################
260 sTgcDigitVec padDigits = processPadDigitization(digiInput);
261
262 allDigits.insert(allDigits.end(),
263 std::make_move_iterator(padDigits.begin()),
264 std::make_move_iterator(padDigits.end()));
265
267 ATH_MSG_WARNING("Only digitize strip/pad response !");
268 return allDigits;
269 }
270
271 //##################################################################################
272 //######################################### wire readout ###########################
273 //##################################################################################
274 sTgcDigitVec wireDigits = processWireDigitization(digiInput);
275 allDigits.insert(allDigits.end(),
276 std::make_move_iterator(wireDigits.begin()),
277 std::make_move_iterator(wireDigits.end()));
278
279 return allDigits;
280}
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< std::unique_ptr< sTgcDigit > > sTgcDigitVec
Digitize a given hit.
sTgcDigitVec processWireDigitization(const DigiInput &digiInput) const
Processes wire digitization for a given hit.
sTgcDigitVec processPadDigitization(const DigiInput &digiInput) const
Processes pad digitization for a given hit.
bool getIonizationPoint(const TimedHit &hit, const DigiConditions &condContainers, Ionization &ionization) const
Computes the ionization point for a hit.
sTgcDigitVec processStripDigitization(const DigiConditions &condContainers, const DigiInput &digiInput) const
Processes strip digitization for a given hit.
double calculateTotalCharge(double energyDeposit, CLHEP::HepRandomEngine *rndEngine) const
Calculates total charge from energy deposit, including gas gain.
void efficiency(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
@ energyDeposit

◆ getGammaParameter()

sTgcDigitMaker::GammaParameter sTgcDigitMaker::getGammaParameter ( double distance) const
private

Retrieves gamma distribution parameters based on distance.

Definition at line 685 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

685 {
686 const double d = std::abs(distance);
687 // Find the parameters assuming the container is sorted in ascending order of 'lowEdge'
688 if (d < m_gammaParameter.front().lowEdge) {
689 return m_gammaParameter.front();
690 }
691 int index{-1};
692 for (const auto& par: m_gammaParameter) {
693 if (d < par.lowEdge) {
694 break;
695 }
696 ++index;
697 }
698 return m_gammaParameter.at(index);
699}
str index
Definition DeMoScan.py:362

◆ getIonizationPoint()

bool sTgcDigitMaker::getIonizationPoint ( const TimedHit & hit,
const DigiConditions & condContainers,
Ionization & ionization ) const
private

Computes the ionization point for a hit.

Definition at line 57 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

59 {
60 const MuonGMR4::sTgcReadoutElement* reEle = m_detMgr->getsTgcReadoutElement(hit->identify());
61
62 // Projecting the hit position on wire surface
63 const Amg::Vector3D locHitDir = xAOD::toEigen(hit->localDirection());
64 const Amg::Vector3D locHitPos = xAOD::toEigen(hit->localPosition());
65 ATH_MSG_VERBOSE("sTgc hit: time " << hit->globalTime()
66 << " position " << Amg::toString(locHitPos, 2) << " direction" << Amg::toString(locHitDir, 2)
67 << " mclink " << hit->genParticleLink() << " PDG ID " << hit->pdgId() );
68
69 Amg::Vector3D hitOnWireSurf = locHitPos;
70 const double scale = Amg::intersect<3>(locHitPos, locHitDir, Amg::Vector3D::UnitZ(), 0.).value_or(0);
71 const double halfStep = 0.5 * hit->stepLength();
72
73 // If Geant step length is smaller than the scale to wire plane, use the steplength
74 // to find the closest point to the wire plane.
75 if (std::abs(scale) <= halfStep) {
76 hitOnWireSurf = locHitPos + scale * locHitDir;
77 }
78 else {
79 hitOnWireSurf = locHitPos + Acts::copySign(halfStep, scale) * locHitDir;
80 }
81
82 const Identifier hitId = hit->identify();
83 const IdentifierHash wireLayHash = reEle->createHash(m_idHelper.gasGap(hitId),
84 ReadoutChannelType::Wire, 1);
85 const MuonGMR4::WireGroupDesign& wireDesign{reEle->wireDesign(wireLayHash)};
86 const MuonGMR4::StripLayer& stripLayer = reEle->stripLayer(wireLayHash);
87 const Amg::Vector2D hitOnWire2D = stripLayer.to2D(hitOnWireSurf, true);
88
89 if(!wireDesign.insideTrapezoid(hitOnWire2D)) {
90 return false;
91 }
92
93 // Check to see if a valid wire exists for the hit on wire surface, if not
94 // revert back to hit position, prestep and poststep, and check if there is a
95 // wire close to it, else, skip the hit.
96 std::pair<int, int> wireGrpWireNum = wireDesign.wireNumber(hitOnWire2D);
97
98 // Check if hit position gives valid wire group number
99 if (wireGrpWireNum.first < 0) {
100 const Amg::Vector2D locHitPos2D = stripLayer.to2D(locHitPos, true);
101 wireGrpWireNum = wireDesign.wireNumber(locHitPos2D);
102
103 // Check if prestep position gives valid wire group number
104 if (wireGrpWireNum.first < 0) {
105 const Amg::Vector3D preStepPos = locHitPos - halfStep * locHitDir;
106 const Amg::Vector2D preStepPos2D = stripLayer.to2D(preStepPos, true);
107 wireGrpWireNum = wireDesign.wireNumber(preStepPos2D);
108
109 // Check if poststep position gives valid wire group number
110 if (wireGrpWireNum.first < 0) {
111 const Amg::Vector3D postStepPos = locHitPos + halfStep * locHitDir;
112 const Amg::Vector2D postStepPos2D = stripLayer.to2D(postStepPos, true);
113 wireGrpWireNum = wireDesign.wireNumber(postStepPos2D);
114
115 // else return empty digit
116 if (wireGrpWireNum.first < 0) {
117 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Unable to retrieve the wire number, skipping the hit: "
118 << m_idHelperSvc->toString(hitId)<<" @"<<Amg::toString(locHitPos2D));
119 return false;
120 }
121 }
122 }
123 }
124 int wireNumber = wireDesign.numPitchesToGroup(wireGrpWireNum.first) + wireGrpWireNum.second;
125 const int numWires = wireDesign.nAllWires();
126
127 if((wireNumber < 1) || (wireNumber > numWires)) {
128 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Unable to retrieve the wire number, skipping the hit: "
129 << m_idHelperSvc->toString(hitId)<<" @"<<Amg::toString(hitOnWire2D));
130 return false;
131 }
132
133 // Compute the position of the ionization and its distance to the closest wire
134 ionization = pointClosestApproach(stripLayer, wireNumber, locHitPos, locHitDir, hit->stepLength());
135 double distToWire = ionization.distance;
136
137 if(distToWire > 0.) {
138 // Determine on which side of the wire does the particle cross
139 int adjacent = Acts::copySign(1, ionization.posOnSegment.y() - ionization.posOnWire.y());
140
141 Ionization ionizationAdj = pointClosestApproach(stripLayer, wireNumber+adjacent, locHitPos, locHitDir, hit->stepLength());
142 double distToWireAdj = ionizationAdj.distance;
143
144 if ((distToWireAdj > 0.) && (distToWireAdj < distToWire)) {
145 distToWire = distToWireAdj;
146 wireNumber += adjacent;
147 ionization = std::move(ionizationAdj);
148 }
149 } else {
150 ATH_MSG_DEBUG("Failed to get the distance between the wire " << wireNumber << " and hit " << Amg::toString(hitOnWire2D, 2));
151 return false;
152 }
153
154 // Do not digitize hits that are too far from the nearest wire
155 if (distToWire > wireDesign.stripPitch()) {
156 ATH_MSG_DEBUG("Distance to nearest wire: " << distToWire << " greater than wirePitch.");
157 return false;
158 }
159
160 // Get the gamma pdf parameters and calculate digit time
161 const GammaParameter gamParam = getGammaParameter(distToWire);
162 const double most_prob_time = getMostProbableArrivalTime(distToWire);
163 const double gamma_mpv = std::max((gamParam.kParameter - 1) * gamParam.thetaParameter, 0.);
164 const double t0_par = most_prob_time - gamma_mpv;
165 const double inv_theta = 1./gamParam.thetaParameter;
166
167 double digitTime = t0_par + CLHEP::RandGamma::shoot(condContainers.rndEngine, gamParam.kParameter, inv_theta);
168
169 constexpr unsigned shoot_limit = 4;
170 unsigned shoot_counter = 0;
171 while (digitTime < 0. && ++shoot_counter <= shoot_limit) {
172 digitTime = t0_par + CLHEP::RandGamma::shoot(condContainers.rndEngine, gamParam.kParameter,inv_theta);
173 }
174
175 ionization.time = std::max(0., digitTime);
176 return true;
177}
#define ATH_MSG_VERBOSE(x)
double stripPitch() const
Distance between two adjacent strips.
bool insideTrapezoid(const Amg::Vector2D &extPos) const
Checks whether an external point is inside the trapezoidal area.
Amg::Vector2D to2D(const Amg::Vector3D &vec, const bool phiView) const
Transforms a 3D vector from the strip design into a 2D vector.
unsigned int numPitchesToGroup(unsigned int groupNum) const
Returns the number of wire pitches to reach the given group.
std::pair< int, int > wireNumber(const Amg::Vector2D &extPos) const
Returns a pair where the first component indicate the wire group number and the second one returns th...
unsigned int nAllWires() const
Returns the number of all wires.
const WireGroupDesign & wireDesign(const IdentifierHash &measHash) const
Retrieves the readoutElement Layer given the Identifier/Hash.
static IdentifierHash createHash(const unsigned gasGap, const unsigned channelType, const unsigned channel, const unsigned wireInGrp=0)
Create a measurement hash from the Identifier fields.
const StripLayer & stripLayer(const IdentifierHash &measId) const
GammaParameter getGammaParameter(double distance) const
Retrieves gamma distribution parameters based on distance.
double getMostProbableArrivalTime(double distance) const
Computes the most probable arrival time based on the distance of closest approach.
Ionization pointClosestApproach(const MuonGMR4::StripLayer &stripLayer, int wireNumber, const Amg::Vector3D &locHitPos, const Amg::Vector3D &locHitDir, const double stepLength) const
Computes the closest approach between a trajectory and a wire segment.
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.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
bool adjacent(unsigned int strip1, unsigned int strip2)

◆ getMostProbableArrivalTime()

double sTgcDigitMaker::getMostProbableArrivalTime ( double distance) const
private

Computes the most probable arrival time based on the distance of closest approach.

Definition at line 704 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

704 {
705 return Acts::detail::polynomialSum(std::abs(distance), m_mostProbableArrivalTime);
706}

◆ getPadChargeFraction()

double sTgcDigitMaker::getPadChargeFraction ( double distance)
staticprivate

Computes charge fraction shared among pads.

Definition at line 768 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

768 {
769 // The charge fraction that is found past a distance x away from the
770 // centre of a 2D gaussian distribution of width of cluster profile is
771 // described by a modified error function.
772
773 // The modified error function perfectly describes
774 // the pad charge sharing distribution figure 16 of the sTGC
775 // testbeam paper https://arxiv.org/pdf/1509.06329.pdf
776 return 0.5 * (1.0 - std::erf( distance / (std::sqrt(2) * m_clusterParams[1])));
777}

◆ getTimeOffsetStrip()

double sTgcDigitMaker::getTimeOffsetStrip ( size_t neighbor_index) const
private

Gets the time offset for a strip cluster.

Get digit time offset of a strip depending on its relative position to the strip at the centre of the cluster. It returns 0 ns by default, as well as when it fails or container is empty.

Definition at line 761 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

761 {
762 return m_timeOffsetStrip.at(std::min(neighbor_index, m_timeOffsetStrip.size() -1));
763}

◆ initialize()

StatusCode sTgcDigitMaker::initialize ( )

Initialize digitization parameters, including reading necessary data files.

Definition at line 42 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

42 {
43 // Read arrival time data
45
46 // Read strip time correction if enabled
49 }
50
51 return StatusCode::SUCCESS;
52}
#define ATH_CHECK
Evaluate an expression and check for errors.
StatusCode readFileOfTimeOffsetStrip()
Reads strip time offset data file.

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 167 of file AthMessaging.h.

168{
169 MsgStream* ms = m_msg_tls.get();
170 if (!ms) {
171 if (!m_initialized.test_and_set()) initMessaging();
172 ms = new MsgStream(m_imsg,m_nm);
173 m_msg_tls.reset( ms );
174 }
175
176 ms->setLevel (m_lvl);
177 return *ms;
178}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 182 of file AthMessaging.h.

183{ return msg() << lvl; }
MsgStream & msg() const
The standard message stream.

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 // If user did not set explicit message level we have to initialize
154 // the messaging and retrieve the default via the MessageSvc.
155 if (m_lvl==MSG::NIL && !m_initialized.test_and_set()) initMessaging();
156
157 if (m_lvl <= lvl) {
158 msg() << lvl;
159 return true;
160 } else {
161 return false;
162 }
163}

◆ pointClosestApproach()

sTgcDigitMaker::Ionization sTgcDigitMaker::pointClosestApproach ( const MuonGMR4::StripLayer & stripLayer,
int wireNumber,
const Amg::Vector3D & locHitPos,
const Amg::Vector3D & locHitDir,
const double stepLength ) const
private

Computes the closest approach between a trajectory and a wire segment.

Given two segments, e.g. a particle trajectory and a sTGC wire, solve for the two points, the point on the trajectory and the point on the wire, where the distance between the two segments is the smallest.

Positions returned are in the local coordinate frame of the wire plane. Returns an object with distance of -9.99 in case of error.

Definition at line 563 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

567 {
568
569 constexpr double angular_tolerance = 1e-3;
570 // Position of the ionization
571 Ionization ionization;
572 // Finding smallest distance and the points at the smallest distance.
573 // The smallest distance between two lines is perpendicular to both lines.
574 // Previous logic was to find the perpendicular distance between two lines using projection geometry
575 // We can construct two lines in the wire surface local coordinate frame:
576 // - one for the hit segment with equation h0 + t * v_h, where h0 is a point
577 // and v_h is the unit vector of the hit segment
578 // - another for the wire with similar equation w0 + s * v_w, where w0 is a
579 // point and v_w is the unit vector of the wire line
580 // Then it is possible to determine the closest points on each line
581 // by requiring that the vector between them is perpendicular to both:
582 // 1. (h0 + t*v_h - w0 - s*v_w) · v_h = 0
583 // 2. (h0 + t*v_h - w0 - s*v_w) · v_w = 0
584
585 // We have replaced this logic with using Amg::intersect<3> method
586 const MuonGMR4::WireGroupDesign& wireDesign = static_cast<const MuonGMR4::WireGroupDesign&>(stripLayer.design(true));
587 // Geometry setup defined in the eta surface local coordinate frame
588 const double wirePitch = wireDesign.stripPitch();
589 const double wirePosX = wireDesign.firstStripPos().x() + (wireNumber - 1) * wirePitch;
590 const Amg::Vector3D wireDir{stripLayer.to3D(wireDesign.stripDir(),true)};
591 const Amg::Vector3D wirePos(locHitPos.x(), -wirePosX, 0.);
592
593 // Use Amg::intersect to find closest point on hit segment to wire plane
594 std::optional<double> scaleHit = Amg::intersect<3>(locHitPos, locHitDir, Amg::Vector3D::UnitZ(), 0);
595 if (!scaleHit || std::abs(std::abs(wireDir.dot(locHitDir)) - 1.0) < angular_tolerance) {
596 ATH_MSG_DEBUG("The track segment is parallel to the wire, position of digit is undefined");
597 ionization.posOnSegment = locHitPos;
598 ionization.posOnWire = wirePos;
599 ionization.distance = std::hypot(locHitPos.y() + wirePosX, locHitPos.z());
600 if (ionization.distance > wirePitch) {
601 ATH_MSG_DEBUG(" localHitPos: " << Amg::toString(locHitPos, 2) << " localHitDir: " << Amg::toString(locHitDir, 2) << " scaleHit: " << scaleHit.value()
602 << " wirePos: " << Amg::toString(wirePos, 2) << " IonizationDistance: " << ionization.distance);
603 }
604 return ionization;
605 }
606 // Position on hit segment
607 Amg::Vector3D ionizationPos = locHitPos + scaleHit.value() * locHitDir;
608
609 if (scaleHit.value() > stepLength) {
610 ionization.posOnSegment = locHitPos;
611 const Amg::Vector3D closestPointToWirePlane = locHitPos + stepLength * locHitDir;
612 ionization.posOnWire = wirePos;
613 ionization.distance = std::abs(closestPointToWirePlane.z());
614 return ionization;
615 }
616
617 // Project ionization position onto the wire line
618 const double scaleWire = (ionizationPos - wirePos).dot(wireDir);
619 const Amg::Vector3D closestPointOnWire = wirePos + scaleWire * wireDir;
620
621 // Fill ionization result
622 ionization.posOnSegment = ionizationPos;
623 ionization.posOnWire = closestPointOnWire;
624 ionization.distance = (ionizationPos - closestPointOnWire).mag();
625
626 return ionization;
627}
Scalar mag() const
mag method
const Amg::Vector2D & firstStripPos() const
Vector indicating the first strip position.
const Amg::Vector2D & stripDir() const
Vector pointing along the strip.
const StripDesign & design(bool phiView=false) const
Returns the underlying strip design.
Amg::Vector3D to3D(CheckVector2D &&vec, const bool phiView) const
Transforms the 2D vector from the strip design into a 3D vector If phi view is switched on,...
dot(G, fn, nodesToHighlight=[])
Definition dot.py:5

◆ processPadChargeSharing()

sTgcDigitVec sTgcDigitMaker::processPadChargeSharing ( const DigiInput & digiInput,
const int padEta,
const int padPhi ) const
private

Handles charge sharing for pad clusters.

Definition at line 430 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

432 {
433
434 bool isValid = false;
435 const int gasGap = m_idHelper.gasGap(digiInput.hitId);
436 const Identifier padHitId = m_idHelper.padID(digiInput.hitId,
437 digiInput.reEle->multilayer(),
438 gasGap, ReadoutChannelType::Pad, padEta, padPhi, isValid);
439 if(!isValid) {
440 return {};
441 }
442 sTgcDigitVec digits{};
443
444 const IdentifierHash padHitHash = digiInput.reEle->measurementHash(padHitId);
445 const MuonGMR4::PadDesign& padDesign{digiInput.reEle->padDesign(padHitHash)};
446
447 const Amg::Vector2D padPos = digiInput.reEle->localChannelPosition(padHitHash);
448 const Amg::Vector2D hitOnPadSurf = digiInput.reEle->stripLayer(padHitHash).to2D(digiInput.posOnSurf, true);
449
450 const Amg::Vector2D diff = hitOnPadSurf - padPos;
451 const double halfPadHeight = 0.5 * digiInput.reEle->padHeight(padHitHash);
452
453 const std::array<Amg::Vector2D, 4> padHitCorners = padDesign.padCorners(std::make_pair(padEta, padPhi));
454 const double padBottomBase = (padHitCorners[0] - padHitCorners[1]).norm();
455 const double padTopBase = (padHitCorners[2] - padHitCorners[3]).norm();
456 const double halfPadWidth = 0.5 * padBottomBase + 0.25 * (1 + diff.y()/halfPadHeight) * (padTopBase - padBottomBase);
457
458 double deltaX = halfPadWidth - std::abs(diff.x());
459 double deltaY = halfPadHeight - std::abs(diff.y());
460 const bool isNeighX = deltaX < 2.5*m_clusterParams[1];
461 const bool isNeighY = deltaY < 2.5*m_clusterParams[1];
462
463 if (deltaX < 0.) {
464 deltaX = 0.1;
465 }
466 if (deltaY < 0.) {
467 deltaY = 0.1;
468 }
469
470 if (m_doPadSharing && (isNeighX || isNeighY)) {
471 unsigned newPhi = padPhi - Acts::copySign(1, diff.x());
472 unsigned newEta = padEta + Acts::copySign(1, diff.y());
473 bool validEta = newEta > 0 && newEta <= digiInput.reEle->numPadEta(padHitHash);
474 bool validPhi = newPhi > 0 && newPhi <= digiInput.reEle->numPadPhi(padHitHash);
475
476 if (isNeighX && isNeighY && validEta && validPhi) {
477 const Identifier neigh_ID_X = m_idHelper.padID(padHitId, digiInput.reEle->multilayer(),
478 gasGap, ReadoutChannelType::Pad,
479 padEta, newPhi);
480 const Identifier neigh_ID_Y = m_idHelper.padID(padHitId, digiInput.reEle->multilayer(), gasGap,
481 ReadoutChannelType::Pad, newEta, padPhi);
482 const Identifier neigh_ID_XY = m_idHelper.padID(padHitId, digiInput.reEle->multilayer(), gasGap,
483 ReadoutChannelType::Pad, newEta, newPhi);
484 double xQfraction = getPadChargeFraction(deltaX);
485 double yQfraction = getPadChargeFraction(deltaY);
486
487 addDigit(digits, neigh_ID_X, digiInput.time, xQfraction*(1.-yQfraction)*0.5*digiInput.totalCharge);
488 addDigit(digits, neigh_ID_Y, digiInput.time, yQfraction*(1.-xQfraction)*0.5*digiInput.totalCharge);
489 addDigit(digits, neigh_ID_XY, digiInput.time, xQfraction*yQfraction*0.5*digiInput.totalCharge);
490 addDigit(digits, padHitId, digiInput.time, (1.-xQfraction-yQfraction+xQfraction*yQfraction)*0.5*digiInput.totalCharge);
491 } else if (isNeighX && validPhi){
492 const Identifier neigh_ID = m_idHelper.padID(padHitId, digiInput.reEle->multilayer(), gasGap,
493 ReadoutChannelType::Pad, padEta, newPhi);
494 double xQfraction = getPadChargeFraction(deltaX);
495 addDigit(digits, padHitId, digiInput.time, (1.-xQfraction)*0.5*digiInput.totalCharge);
496 addDigit(digits, neigh_ID, digiInput.time, xQfraction*0.5*digiInput.totalCharge);
497 }
498 else if (isNeighY && validEta){
499 const Identifier neigh_ID = m_idHelper.padID(padHitId, digiInput.reEle->multilayer(), gasGap,
500 ReadoutChannelType::Pad, newEta, padPhi);
501 double yQfraction = getPadChargeFraction(deltaY);
502 addDigit(digits, padHitId, digiInput.time, (1.-yQfraction)*0.5*digiInput.totalCharge);
503 addDigit(digits, neigh_ID, digiInput.time, yQfraction*0.5*digiInput.totalCharge);
504 }
505 } else{
506 addDigit(digits, padHitId, digiInput.time, 0.5*digiInput.totalCharge);
507 }
508 return digits;
509}
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
static double getPadChargeFraction(double distance)
Computes charge fraction shared among pads.
static void addDigit(sTgcDigitVec &digits, const Identifier &id, double digittime, double charge)
Adds a digit to the appropriate cache.

◆ processPadDigitization()

sTgcDigitVec sTgcDigitMaker::processPadDigitization ( const DigiInput & digiInput) const
private

Processes pad digitization for a given hit.

Definition at line 394 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

394 {
395 ATH_MSG_DEBUG("sTgcDigitMaker::pad response ");
396
397 const int gasGap = m_idHelper.gasGap(digiInput.hitId);
398 const IdentifierHash padLayHash = digiInput.reEle->createHash(gasGap,ReadoutChannelType::Pad, 1);
399 const Amg::Vector2D hitOnPadSurf = digiInput.reEle->stripLayer(padLayHash).to2D(digiInput.posOnSurf, true);
400 const MuonGMR4::PadDesign& padDesign{digiInput.reEle->padDesign(padLayHash)};
401 if(!padDesign.insideTrapezoid(hitOnPadSurf)) {
402 ATH_MSG_DEBUG(__func__<<"() -"<<__LINE__<<" Outside of the pad surface boundary :"
403 << m_idHelperSvc->toString(digiInput.hitId)
404 << " local position " <<Amg::toString(hitOnPadSurf, 2));
405 return {};
406 }
407
408 constexpr double tolerance_length = 0.01*Gaudi::Units::mm;
409 auto [padEta, padPhi] = padDesign.channelNumber(hitOnPadSurf);
410
411 if( padEta < 1 || padPhi < 1){
412 const double newPosX = hitOnPadSurf.x() - std::copysign(tolerance_length, hitOnPadSurf.x());
413 const double newPosY = hitOnPadSurf.y() - std::copysign(tolerance_length, hitOnPadSurf.y());
414 const Amg::Vector2D newPosition(newPosX, newPosY);
415 auto [newPadEta, newPadPhi] = padDesign.channelNumber(newPosition);
416 padEta = newPadEta;
417 padPhi = newPadPhi;
418 if( padEta < 1 || padPhi < 1) {
419 ATH_MSG_WARNING("Failed to obtain pad number for " << m_idHelperSvc->toString(digiInput.hitId) );
420 return {};
421 }
422 }
423
424 return processPadChargeSharing(digiInput, padEta, padPhi);
425}
std::pair< int, int > channelNumber(const Amg::Vector2D &hitPos) const
Function to retrieve the pad eta and phi given a local position coordinate.
sTgcDigitVec processPadChargeSharing(const DigiInput &digiInput, const int padEta, const int padPhi) const
Handles charge sharing for pad clusters.

◆ processStripChargeSharing()

sTgcDigitVec sTgcDigitMaker::processStripChargeSharing ( const DigiInput & digiInput,
const double peak_position,
const int stripNumber ) const
private

Handles charge sharing for strip clusters.

Definition at line 330 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

332 {
333
334 const double norm = 0.5 * digiInput.totalCharge;
335
336 sTgcDigitVec digits{};
337 const double tan_theta = digiInput.hitDir.perp() / digiInput.hitDir.z();
338
339 constexpr double tolerance_charge = 0.0005;
340 constexpr int max_neighbor = 10;
341
342 const int gasGap = m_idHelper.gasGap(digiInput.hitId);
343 const auto& design = digiInput.reEle->stripDesign(digiInput.reEle->measurementHash(digiInput.hitId));
344 // Upper half of the strip cluster
345 for (int sign : {-1, 1}) {
346 for (int iStrip = 0; iStrip <= max_neighbor; ++iStrip) {
347
348 if (iStrip == 0 && sign == +1) continue; // center only once
349 int currentStrip = stripNumber + sign*iStrip;
350 if (currentStrip > design.numStrips() || currentStrip < 1) {
351 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Breaking the upper half strip loop stripNumber: "
352 << currentStrip << " > " << design.numStrips());
353 break;
354 }
355 bool isValid = false;
356 const Identifier currentStripId = m_idHelper.channelID(digiInput.hitId,
357 digiInput.reEle->multilayer(),
358 gasGap, ReadoutChannelType::Strip,
359 currentStrip, isValid);
360 if (!isValid) {
361 continue;
362 }
363 const Amg::Vector2D currentStripPos = digiInput.reEle->localChannelPosition(digiInput.reEle->measurementHash(currentStripId));
364 const double x_relative = (currentStripPos.x() - peak_position);
365 const double normX = x_relative / design.stripPitch();
366 const double charge = std::hypot(1., m_chargeAngularFactor * tan_theta) * norm *
367 chargeIntegral(normX - 0.5, normX + 0.5);
368
369 if (charge < tolerance_charge) {
370 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Breaking the upper half strip loop stripCharge: "
371 << charge << " < " << tolerance_charge);
372 break;
373 }
374
375 double strip_time = digiInput.time;
377 const bool shift = ((iStrip > 0) && ((x_relative + (0.5*0.75 - iStrip) * design.stripPitch()) < 0));
378 strip_time += getTimeOffsetStrip(iStrip - shift);
379 }
380
381 addDigit(digits, currentStripId, strip_time, charge);
382 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Created a strip digit: strip number = "
383 << currentStrip << ", charge = " << charge);
384 }
385 }
386
387 return digits;
388}
int sign(int a)
double getTimeOffsetStrip(size_t neighbor_index) const
Gets the time offset for a strip cluster.

◆ processStripDigitization()

sTgcDigitVec sTgcDigitMaker::processStripDigitization ( const DigiConditions & condContainers,
const DigiInput & digiInput ) const
private

Processes strip digitization for a given hit.

Definition at line 285 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

286 {
287 ATH_MSG_DEBUG("sTgcDigitMaker::strip response ");
288
289 const int gasGap = m_idHelper.gasGap(digiInput.hitId);
290 const IdentifierHash stripLayHash = digiInput.reEle->createHash(gasGap,
291 ReadoutChannelType::Strip, 1);
292 const Identifier stripLayId = digiInput.reEle->measurementId(stripLayHash);
293 const MuonGMR4::StripDesign& stripDesign{digiInput.reEle->stripDesign(stripLayHash)};
294 const Amg::Vector2D hitOnStripSurf = digiInput.reEle->stripLayer(stripLayHash).to2D(digiInput.posOnSurf, false);
295
296 if(!stripDesign.insideTrapezoid(hitOnStripSurf)) {
297 ATH_MSG_DEBUG("Outside of the strip surface boundary : "
298 << m_idHelperSvc->toString(stripLayId)
299 << "; local position " <<Amg::toString(hitOnStripSurf, 2));
300 return {};
301 }
302
303 constexpr double tolerance_length = 0.01*Gaudi::Units::mm;
304 int stripNumber = stripDesign.stripNumber(hitOnStripSurf);
305 if( stripNumber < 0){
306 const double newPosX = hitOnStripSurf.x() - std::copysign(tolerance_length, hitOnStripSurf.x());
307 const Amg::Vector2D newPos(newPosX, hitOnStripSurf.y());
308 stripNumber = stripDesign.stripNumber(newPos);
309 if (stripNumber < 0) {
310 ATH_MSG_WARNING("Failed to obtain strip number " << m_idHelperSvc->toString(stripLayId) );
311 return {};
312 }
313 }
314
315
316 const double tan_theta = digiInput.hitDir.perp() / digiInput.hitDir.z();
317 const double angle_dependency = std::hypot(m_posResIncident, m_posResAngular * tan_theta);
318
319 const double peak_position = CLHEP::RandGaussZiggurat::shoot(condContainers.rndEngine,
320 hitOnStripSurf.x(), m_StripResolution*angle_dependency);
321 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Smeared hit from "<<hitOnStripSurf.x()<<" -> "<<
322 peak_position<<". Assign strip charges");
323 return processStripChargeSharing(digiInput,
324 peak_position,
325 stripNumber);
326}
virtual int stripNumber(const Amg::Vector2D &pos) const
Calculates the number of the strip whose center is closest to the given point.
sTgcDigitVec processStripChargeSharing(const DigiInput &digiInput, const double peak_position, const int stripNumber) const
Handles charge sharing for strip clusters.

◆ processWireDigitization()

sTgcDigitVec sTgcDigitMaker::processWireDigitization ( const DigiInput & digiInput) const
private

Processes wire digitization for a given hit.

Definition at line 515 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

515 {
516 ATH_MSG_DEBUG("sTgcDigitMaker::wire response ");
517
518 const int gasGap = m_idHelper.gasGap(digiInput.hitId);
519 const IdentifierHash wireLayHash = digiInput.reEle->createHash(gasGap,
520 ReadoutChannelType::Wire, 1);
521 const MuonGMR4::WireGroupDesign& wireDesign{digiInput.reEle->wireDesign(wireLayHash)};
522
523 const Amg::Vector2D hitOnWireSurf = digiInput.reEle->stripLayer(wireLayHash).to2D(digiInput.posOnSurf, true);
524 if(!wireDesign.insideTrapezoid(hitOnWireSurf)) {
525 ATH_MSG_DEBUG("Outside of the wire surface boundary :" << m_idHelperSvc->toString(digiInput.hitId)
526 << " local position " <<Amg::toString(hitOnWireSurf, 2));
527 return {};
528 }
529
530 if (digiInput.reEle->isEtaZero(digiInput.reEle->measurementHash(digiInput.hitId), digiInput.posOnSurf.block<2,1>(0,0))) {
531 ATH_MSG_DEBUG("Hit inside wireCutout :" << m_idHelperSvc->toString(digiInput.hitId)
532 << " local position " <<Amg::toString(hitOnWireSurf, 2));
533 return {};
534 }
535
536 constexpr double tolerance_length = 0.01*Gaudi::Units::mm;
537 int wiregroupNumber = (wireDesign.wireNumber(hitOnWireSurf)).first;
538 if( wiregroupNumber < 1) {
539 const double newPosX = hitOnWireSurf.x() - std::copysign(tolerance_length, hitOnWireSurf.x());
540 const Amg::Vector2D newPos{newPosX, hitOnWireSurf.y()};
541 wiregroupNumber = (wireDesign.wireNumber(newPos)).first;
542 if (wiregroupNumber < 1) {
543 ATH_MSG_WARNING("Failed to obtain wire number " << m_idHelperSvc->toString(digiInput.hitId) );
544 return {};
545 }
546 }
547
548 bool isValid = false;
549 const Identifier wireGroupHitId = m_idHelper.channelID(digiInput.hitId, digiInput.reEle->multilayer(), gasGap,
550 ReadoutChannelType::Wire, wiregroupNumber, isValid);
551
552 if(!isValid) {
553 return {};
554 }
555 sTgcDigitVec digits{};
556 addDigit(digits, wireGroupHitId, digiInput.time, digiInput.totalCharge);
557 return digits;
558}

◆ readFileOfTimeArrival()

StatusCode sTgcDigitMaker::readFileOfTimeArrival ( )
private

Reads time arrival data file.

Definition at line 648 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

648 {
649 const std::string file_name = "sTGC_Digitization_timeArrival.dat";
650 std::string file_path = PathResolver::find_file(file_name, "DATAPATH");
651 if(file_path.empty()) {
652 ATH_MSG_FATAL("readFileOfTimeWindowOffset(): Could not find file " << file_name );
653 return StatusCode::FAILURE;
654 }
655
656 std::ifstream ifs{file_path, std::ios::in};
657 if(ifs.bad()) {
658 ATH_MSG_FATAL("sTgcDigitMaker: Failed to open time of arrival file " << file_name );
659 return StatusCode::FAILURE;
660 }
661
662 // Read the sTGC_Digitization_timeWindowOffset.dat file
663 std::string line;
664 GammaParameter param{};
665 while (std::getline(ifs, line)) {
666 std::string key;
667 std::istringstream iss(line);
668 iss >> key;
669 if (key == "bin") {
670 iss >> param.lowEdge >> param.kParameter >> param.thetaParameter;
671 m_gammaParameter.push_back(param);
672 } else if (key == "mpv") {
673 double mpt{};
674 int idx{0};
675 while (iss >> mpt) {m_mostProbableArrivalTime[idx++] = mpt;}
676 }
677 }
678 ifs.close();
679 return StatusCode::SUCCESS;
680}
#define ATH_MSG_FATAL(x)
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
file_path
Definition athena.py:92

◆ readFileOfTimeOffsetStrip()

StatusCode sTgcDigitMaker::readFileOfTimeOffsetStrip ( )
private

Reads strip time offset data file.

Definition at line 723 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/src/sTgcDigitMaker.cxx.

723 {
724 const std::string file_name = "sTGC_Digitization_timeOffsetStrip.dat";
725 std::string file_path = PathResolver::find_file(file_name, "DATAPATH");
726 if(file_path.empty()) {
727 ATH_MSG_FATAL("readFileOfTimeWindowOffset(): Could not find file " << file_name );
728 return StatusCode::FAILURE;
729 }
730
731 // Open the sTGC_Digitization_timeOffsetStrip.dat file
732 std::ifstream ifs{file_path, std::ios::in};
733 if(ifs.bad()) {
734 ATH_MSG_FATAL("Failed to open time of arrival file " << file_name );
735 return StatusCode::FAILURE;
736 }
737
738 // Initialize the container to store the time offset.
739 // The number of parameters, 6, corresponds to the number of lines to be read
740 // from sTGC_Digitization_timeOffsetStrip.dat.
741 // Setting the default offset to 0 ns.
742 std::string line;
743 size_t index{0};
744 double value{0.0};
745 while (std::getline(ifs, line)) {
746 std::string key;
747 std::istringstream iss(line);
748 iss >> key;
749 if (key == "strip") {
750 iss >> index >> value;
751 if (index >= m_timeOffsetStrip.size()) continue;
752 m_timeOffsetStrip.at(index) = value;
753 }
754 }
755 return StatusCode::SUCCESS;
756}

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_chargeAngularFactor

double MuonR4::sTgcDigitMaker::m_chargeAngularFactor {4.0}
private

◆ m_clusterParams

std::array<double, 2> MuonR4::sTgcDigitMaker::m_clusterParams {0.573, 1.092}
staticconstexprprivate

◆ m_detMgr

const MuonGMR4::MuonDetectorManager* MuonR4::sTgcDigitMaker::m_detMgr {nullptr}
private

◆ m_digitMode

digitMode MuonR4::sTgcDigitMaker::m_digitMode {digitMode::AllChType}
private

define offsets and widths of time windows for signals from wiregroups and strips.

The offsets are defined as relative time diffference with respect to the time after TOF and cable length corrections. Bunch crossing time is specified.

Definition at line 241 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/sTgcDigitizationR4/sTgcDigitMaker.h.

◆ m_doPadSharing

bool MuonR4::sTgcDigitMaker::m_doPadSharing {false}
private

◆ m_doTimeOffsetStrip

bool MuonR4::sTgcDigitMaker::m_doTimeOffsetStrip {false}
private

◆ m_gammaParameter

std::vector<GammaParameter> MuonR4::sTgcDigitMaker::m_gammaParameter
private

◆ m_idHelper

const sTgcIdHelper& MuonR4::sTgcDigitMaker::m_idHelper {m_idHelperSvc->stgcIdHelper()}
private

◆ m_idHelperSvc

const Muon::IMuonIdHelperSvc* MuonR4::sTgcDigitMaker::m_idHelperSvc {m_detMgr->idHelperSvc()}
private

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_meanGasGain

double MuonR4::sTgcDigitMaker::m_meanGasGain {5.e4}
private

Definition at line 243 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/sTgcDigitizationR4/sTgcDigitMaker.h.

243{5.e4}; // mean gain estimated from ATLAS note "ATL-MUON-PUB-2014-001"

◆ m_mostProbableArrivalTime

std::array<double, 5> MuonR4::sTgcDigitMaker::m_mostProbableArrivalTime {make_array<double, 5>(0.)}
private

Definition at line 219 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/sTgcDigitizationR4/sTgcDigitMaker.h.

constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
Definition ArrayHelper.h:10

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_posResAngular

double MuonR4::sTgcDigitMaker::m_posResAngular {0.305/m_StripResolution}
private

◆ m_posResIncident

double MuonR4::sTgcDigitMaker::m_posResIncident {1.}
private

◆ m_StripResolution

double MuonR4::sTgcDigitMaker::m_StripResolution {0.0949}
private

◆ m_theta

double MuonR4::sTgcDigitMaker::m_theta {10}
private

Definition at line 242 of file MuonPhaseII/MuonDigitization/sTgcDigitizationR4/sTgcDigitizationR4/sTgcDigitMaker.h.

242{10}; // theta=10 value best matches the PDF

◆ m_timeOffsetStrip

std::array<double, 6> MuonR4::sTgcDigitMaker::m_timeOffsetStrip {make_array<double, 6>(0.)}
private

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