ATLAS Offline Software
Loading...
Searching...
No Matches
MaterialInteraction.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// MaterialInteraction.cxx, (c) ATLAS Detector software
9
10#include <cmath>
12
54
55namespace {
56
57constexpr double s_me = Trk::ParticleMasses::mass[Trk::electron];
58
59//The following were repeated in the code.
60//Now moved to helpers, lets keep the same
61//semantics as before for all builds.
62
63// mean excitation energy --> I
65double
66MeanExcitationEnergy(const Trk::Material& mat) {
67 // 16 eV * Z**0.9 - bring to MeV
68 return 16.e-6 * std::pow(mat.averageZ(), 0.9);
69}
70
72double
73DensityEffect(const double zOverAtimesRho, const double eta,
74 const double gamma, const double I) {
75
76 // density effect. Done for gamma > 10 ( p > 1GeV for muons)
77 // see ATLASRECTS-3144 and ATLASRECTS-7586
78 // for possible issues
79 if (gamma > 10.) {
80 // PDG 2022 Table 34.1
81 double eplasma = 28.816e-6 * std::sqrt(1000. * zOverAtimesRho);
82 // PDG 2022 Eq. 34.6
83 //2. * std::log(eplasma / I) + std::log(eta2) - 1.
84 //applying logarithmic identities becomes
85 // 2*(log(eplasma/I) + log(eta)) = 2*log(eplasma*eta/I)
86 return 2. * std::log(eplasma*eta / I) - 1.;
87 }
88 return 0;
89}
90
92double
93KAZ(const double zOverAtimesRho) {
94 // K/A*Z = 0.5 * 30.7075MeV/(g/mm2) * Z/A * rho[g/mm3]
95 return 0.5 * 30.7075 * zOverAtimesRho;
96}
97
99double
100LandauMPV(const double kazL, const double eta2, const double I,
101 const double beta, const double delta) {
102 // PDG 2022 Eq 34.12
103 // then apply logarithmic identity
104 // log(2. * s_me * eta2 / I) + log(kazL / I) = log(2. * s_me* eta2 * kazL/(I*I))
105 return -kazL * (std::log(2. * s_me * eta2*kazL/(I*I)) + 0.2 -
106 (beta * beta) - delta);
107}
108
109} // namespace
110
118 double p, const Trk::Material& mat, Trk::ParticleHypothesis particle,
119 double& sigma, double& kazL) {
120
121 sigma = 0.;
122 kazL = 0.;
123 if (mat.averageZ() < 1) {
124 return 0.;
125 }
126 const double m = Trk::ParticleMasses::mass[particle];
127 const double mfrac = s_me / m;
128 const double E = std::sqrt(p * p + m * m);
129 const double beta = p / E;
130 const double gamma = E / m;
131 const double I = MeanExcitationEnergy(mat);
132 const double zOverAtimesRho = mat.zOverAtimesRho();
133 double kaz = KAZ(zOverAtimesRho);
134 double Ionization = 0.;
135
136 if (particle == Trk::electron) {
137 // for electrons use slightly different BetheBloch adaption
138 // see Stampfer, et al, "Track Fitting With Energy Loss", Comp. Pyhs. Comm.
139 // 79 (1994), 157-164
140 Ionization = -kaz * (2. * log(2. * s_me / I) + 3. * log(gamma) - 1.95);
141 // sigmaL --> FWHM of Landau
142 sigma = 4 * kaz;
143 } else {
144 const double eta = beta * gamma;
145 const double eta2 = eta*eta;
146 const double delta = DensityEffect(zOverAtimesRho, eta, gamma, I);
147 // tmax - cut off energy
148 const double tMax =
149 2. * eta2 * s_me / (1. + 2. * gamma * mfrac + mfrac * mfrac);
150 // divide by beta^2 for non-electrons
151 kaz /= beta * beta;
152 // PDG 2022 Eq 34.5
153 Ionization = -kaz * (std::log(2. * s_me * eta2 * tMax / (I * I)) -
154 2. * (beta * beta) - delta);
155 // The MPV is path lenght dependent, here we set pathlenght = 1 (mm)
156 // so kazL = kaz
157 const double MPV = LandauMPV(kaz, eta2, I, beta, delta);
158 constexpr double factor = (1. / 3.59524);
159 sigma = -(Ionization - MPV) * factor;
160 kazL = kaz * factor;
161 }
162 return Ionization;
163}
164
166 const Trk::MaterialProperties& mat, double beta, double gamma,
167 Trk::ParticleHypothesis particle) {
168 if (particle == Trk::undefined || particle == Trk::nonInteracting) {
169 return 0.;
170 }
171
172 if (mat.averageZ() == 0. || mat.zOverAtimesRho() == 0.) {
173 return 0.;
174 }
175 const double iPot = 16.e-6 * std::pow(mat.averageZ(), 0.9);
176 const double m = Trk::ParticleMasses::mass[particle];
177 const double zOverAtimesRho = mat.zOverAtimesRho();
178 double kaz = KAZ(mat.zOverAtimesRho());
179
180 if (particle != Trk::electron) {
181 const double eta = beta * gamma;
182 const double eta2 = eta*eta;
183 double delta = DensityEffect(zOverAtimesRho, eta, gamma, iPot);
184 // mass fraction
185 double mfrac = s_me / m;
186 // tmax - cut off energy
187 double tMax = 2. * eta2 * s_me / (1. + 2. * gamma * mfrac + mfrac * mfrac);
188 // divide by beta^2 for non-electrons
189 kaz /= beta * beta;
190 // return PDG 2022 Eq 34.5
191 return kaz * (std::log(2. * s_me * eta2 * tMax / (iPot * iPot)) -
192 2. * (beta * beta) - delta);
193 }
194 // for electrons use slightly different BetheBloch adaption
195 // see Stampfer, et al, "Track Fitting With Energy Loss", Comp. Pyhs. Comm. 79
196 // (1994), 157-164
197 return kaz * (2. * std::log(2. * s_me / iPot) + 3. * std::log(gamma) - 1.95);
198}
199
206 double p, const Trk::Material& mat, Trk::ParticleHypothesis particle,
207 double& sigma, double& kazL, double path) {
208
209 const double m = Trk::ParticleMasses::mass[particle];
210 const double E = std::sqrt(p * p + m * m);
211 const double beta = p / E;
212 const double gamma = E / m;
213 const double I = MeanExcitationEnergy(mat);
214 const double zOverAtimesRho = mat.zOverAtimesRho();
215 double kaz = KAZ(zOverAtimesRho);
216 const double eta = beta * gamma;
217 const double eta2 = eta*eta;
218 const double delta = DensityEffect(zOverAtimesRho, eta, gamma, I);
219 // divide by beta^2 for non-electrons
220 kaz /= beta * beta;
221 kazL = kaz * path;
222 const double MPV = LandauMPV(kazL, eta2, I, beta, delta);
223 sigma = 0.424 * 4. * kazL; // 0.424 FWHM to sigma
224
225 return MPV;
226}
227
230 double p, const Trk::Material& mat, Trk::ParticleHypothesis particle,
231 double& sigma) {
232 sigma = 0.;
233 if (mat.x0() == 0.)
234 return 0.;
235
236 // preparation of kinetic constants
237 const double m = Trk::ParticleMasses::mass[particle];
238 const double mfrac = s_me / m;
239 const double E = sqrt(p * p + m * m);
240
241 // Bremsstrahlung - Bethe-Heitler
242 double Radiation = -E * mfrac * mfrac;
243 // sigma the rms of steep exponential
244 sigma = -Radiation;
245
246 // Add e+e- pair production and photonuclear effect for muons at energies
247 // above 8 GeV
248 // Radiation gives mean Eloss including the long tail from 'catastrophic'
249 // Eloss sigma the rms of steep exponential
250 // For the parametrization see section 2.3 of Ref [4]
251 if ((particle == Trk::muon) && (E > 8000.)) {
252 if (E < 1.e6) {
253 Radiation += 0.5345 - 6.803e-5 * E - 2.278e-11 * E * E +
254 9.899e-18 * E * E * E; // E below 1 TeV
255 sigma += (0.1828 - 3.966e-3 * std::sqrt(E) + 2.151e-5 * E); // idem
256 } else {
257 Radiation += 2.986 - 9.253e-5 * E; // E above 1 TeV
258 sigma += 17.73 + 2.409e-5 * (E - 1000000.); // idem
259 }
260 }
261 sigma = sigma / mat.x0();
262
263 return Radiation / mat.x0();
264}
265
267 const Trk::MaterialProperties& mat, double initialE,
268 Trk::ParticleHypothesis particle) {
269 if (particle == Trk::undefined || particle == Trk::nonInteracting) {
270 return 0.;
271 }
272 double mfrac = (s_me / Trk::ParticleMasses::mass[particle]);
273 mfrac *= mfrac;
274 return initialE / mat.x0() * mfrac;
275}
276
278double Trk::MaterialInteraction::sigmaMS(double dInX0, double p, double beta) {
279
280 if (dInX0 == 0. || p == 0. || beta == 0.) {
281 return 0.;
282 }
283 // Improved (See [5] Lynch & Dahl) Highland formula
284 // projected sigma_s PDG 2022 34.16
285 return 13.6 * std::sqrt(dInX0) / (beta * p) *
286 (1. + 0.038 * std::log(dInX0 / (beta * beta)));
287}
288
Scalar eta() const
pseudorapidity method
#define I(x, y, z)
Definition MD5.cxx:116
Material with information about thickness of material.
A common object to be contained by.
Definition Material.h:117
#define ATH_ALWAYS_INLINE
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
static double dEdXBetheHeitler(const Trk::MaterialProperties &mat, double initialE, Trk::ParticleHypothesis particle)
static double dEdl_ionization(double p, const Material &mat, ParticleHypothesis particle, double &sigma, double &kazL)
dE/dl ionization energy loss per path unit
static double dEdl_radiation(double p, const Material &mat, ParticleHypothesis particle, double &sigma)
dE/dl radiation energy loss per path unit
static double dE_MPV_ionization(double p, const Trk::Material &mat, Trk::ParticleHypothesis particle, double &sigma, double &kazL, double path)
Most Propable dE ionization energly loss.
static double dEdXBetheBloch(const Trk::MaterialProperties &mat, double beta, double gamma, Trk::ParticleHypothesis particle)
dE/dl ionization energy loss per path unit
static double sigmaMS(double dInX0, double p, double beta)
multiple scattering as function of dInX0