BmnRoot
Loading...
Searching...
No Matches
BmnMaterialEffects.cxx
Go to the documentation of this file.
1
7
8#include "BmnMaterialInfo.h"
9#include "FairTrackParam.h"
10#include "TDatabasePDG.h"
11#include "TParticlePDG.h"
12
13#include <cassert>
14#include <cmath>
15#include <cstdlib>
16#include <iostream>
17
18using namespace std;
19
21 : fDownstream(kTRUE)
22 , fMass(0.105)
23 , fIsElectron(kFALSE)
24 , fIsMuon(kTRUE)
25{}
26
28
29BmnStatus BmnMaterialEffects::Update(FairTrackParam* par, const BmnMaterialInfo* mat, Int_t pdg, Bool_t downstream)
30{
31 if (mat->GetLength() * mat->GetRho() < 1e-10)
32 return kBMNSUCCESS;
33
34 fDownstream = downstream;
35 TDatabasePDG* db = TDatabasePDG::Instance();
36 TParticlePDG* particle = db->GetParticle(pdg);
37 assert(particle != NULL);
38 fMass = particle->Mass();
39 // fMass *= 4; //4 for He4, 3 for He3
40 fIsElectron = (std::abs(pdg) == 11) ? kTRUE : kFALSE;
41 fIsMuon = (std::abs(pdg) == 13) ? kTRUE : kFALSE;
42
43 AddEnergyLoss(par, mat);
44
45 AddThinScatter(par, mat);
46 AddThickScatter(par, mat);
47
48 return kBMNSUCCESS;
49}
50
51void BmnMaterialEffects::AddEnergyLoss(FairTrackParam* par, const BmnMaterialInfo* mat) const
52{
53 if (fIsElectron) {
54 Float_t radLength = mat->GetLength() / mat->GetRL();
55 Float_t t;
56
57 if (!fDownstream) {
58 t = radLength;
59 } else {
60 t = -radLength;
61 }
62
63 Float_t qp = par->GetQp();
64 // cout << "QP-before = " << qp << endl;
65 qp *= std::exp(-t);
66 // cout << "QP-after = " << qp << endl;
67 par->SetQp(qp);
68
69 Float_t cov = par->GetCovariance(4, 4);
70 cov += CalcSigmaSqQpElectron(par, mat);
71 par->SetCovariance(4, 4, cov);
72 } else {
73 Float_t Eloss = EnergyLoss(par, mat);
74 par->SetQp(CalcQpAfterEloss(par->GetQp(), Eloss));
75
76 Float_t cov = par->GetCovariance(4, 4);
77 cov += CalcSigmaSqQp(par, mat);
78 par->SetCovariance(4, 4, cov);
79 }
80}
81
82void BmnMaterialEffects::AddThickScatter(FairTrackParam* par, const BmnMaterialInfo* mat) const
83{
84 if (mat->GetLength() < 1e-10) {
85 return;
86 }
87
88 Float_t tx = par->GetTx();
89 Float_t ty = par->GetTy();
90 Float_t thickness = mat->GetLength(); // cm
91 Float_t thetaSq = CalcThetaSq(par, mat);
92
93 Float_t t = 1 + tx * tx + ty * ty;
94
95 Float_t Q33 = (1 + tx * tx) * t * thetaSq;
96 Float_t Q44 = (1 + ty * ty) * t * thetaSq;
97 Float_t Q34 = tx * ty * t * thetaSq;
98
99 Float_t T23 = (thickness * thickness) / 3.0;
100 Float_t T2 = thickness / 2.0;
101
102 Float_t D = (fDownstream) ? 1. : -1.;
103
104 Double_t C[15];
105 par->CovMatrix(C);
106
107 C[0] += Q33 * T23;
108 C[1] += Q34 * T23;
109 C[2] += Q33 * D * T2;
110 C[3] += Q34 * D * T2;
111
112 C[5] += Q44 * T23;
113 C[6] += Q34 * D * T2;
114 C[7] += Q44 * D * T2;
115
116 C[9] += Q33;
117 C[10] += Q34;
118
119 C[12] += Q44;
120
121 par->SetCovMatrix(C);
122}
123
124void BmnMaterialEffects::AddThinScatter(FairTrackParam* par, const BmnMaterialInfo* mat) const
125{
126 if (mat->GetLength() < 1e-10) {
127 return;
128 }
129 Float_t tx = par->GetTx();
130 Float_t ty = par->GetTy();
131 Float_t thetaSq = CalcThetaSq(par, mat);
132
133 Float_t t = 1 + tx * tx + ty * ty;
134
135 Float_t Q33 = (1 + tx * tx) * t * thetaSq;
136 Float_t Q44 = (1 + ty * ty) * t * thetaSq;
137 Float_t Q34 = tx * ty * t * thetaSq;
138
139 Double_t C[15];
140 par->CovMatrix(C);
141 C[9] += Q33;
142 C[12] += Q44;
143 C[10] += Q34;
144 par->SetCovMatrix(C);
145}
146
147Float_t BmnMaterialEffects::CalcThetaSq(const FairTrackParam* par, const BmnMaterialInfo* mat) const
148{
149 Float_t p = std::abs(1. / par->GetQp()); // GeV
150 // p *= 2; //for He3 and He4
151 Float_t E = std::sqrt(fMass * fMass + p * p);
152 Float_t beta = p / E;
153 Float_t x = mat->GetLength(); // cm
154 Float_t X0 = mat->GetRL(); // cm
155 Float_t bcp = beta * p;
156 Float_t z = 1.;
157
158 Float_t theta = 0.0136 * (1. / bcp) * z * std::sqrt(x / X0) * (1. + 0.038 * std::log(x / X0));
159 return theta * theta;
160}
161
162Float_t BmnMaterialEffects::EnergyLoss(const FairTrackParam* par, const BmnMaterialInfo* mat) const
163{
164 Float_t length = mat->GetRho() * mat->GetLength();
165 return dEdx(par, mat) * length;
166 // return MPVEnergyLoss(par, mat);
167}
168
169Float_t BmnMaterialEffects::dEdx(const FairTrackParam* par, const BmnMaterialInfo* mat) const
170{
171 Float_t dedx = BetheBloch(par, mat);
172 // dedx += BetheHeitler(par, mat);
173 // if (fIsMuon) dedx += PairProduction(par, mat);
174 return dedx;
175}
176
177Float_t BmnMaterialEffects::BetheBloch(const FairTrackParam* par, const BmnMaterialInfo* mat) const
178{
179 Float_t K = 0.000307075; // GeV * g^-1 * cm^2
180 Float_t z = (par->GetQp() > 0.) ? 1 : -1.;
181 // z *= 2; //for He3 and He4
182 Float_t Z = mat->GetZ();
183 Float_t A = mat->GetA();
184
185 Float_t M = fMass;
186 Float_t p = std::abs(1. / par->GetQp()); // GeV
187 // p *= 2; //for He3 and He4
188 Float_t E = std::sqrt(M * M + p * p);
189 Float_t beta = p / E;
190 Float_t betaSq = beta * beta;
191 Float_t gamma = E / M;
192 Float_t gammaSq = gamma * gamma;
193
194 Float_t I = CalcI(Z) * 1e-9; // GeV
195
196 Float_t me = 0.000511; // GeV
197 Float_t ratio = me / M;
198 Float_t Tmax = (2 * me * betaSq * gammaSq) / (1 + 2 * gamma * ratio + ratio * ratio);
199
200 // density correction
201 Float_t dc = 0.;
202 if (p > 0.5) { // for particles above 1 Gev
203 Float_t rho = mat->GetRho();
204 Float_t hwp = 28.816 * std::sqrt(rho * Z / A) * 1e-9; // GeV
205 dc = std::log(hwp / I) + std::log(beta * gamma) - 0.5;
206 }
207
208 return K * z * z * (Z / A) * (1. / betaSq)
209 * (0.5 * std::log(2 * me * betaSq * gammaSq * Tmax / (I * I)) - betaSq - dc);
210}
211
212Float_t BmnMaterialEffects::BetheBlochElectron(const FairTrackParam* par, const BmnMaterialInfo* mat) const
213{
214 Float_t K = 0.000307075; // GeV * g^-1 * cm^2
215 // myf z = (par->GetQp() > 0.) ? 1 : -1.;
216 Float_t Z = mat->GetZ();
217 Float_t A = mat->GetA();
218
219 Float_t me = 0.000511; // GeV;
220 Float_t p = std::abs(1. / par->GetQp()); // GeV
221 Float_t E = std::sqrt(me * me + p * p);
222 Float_t gamma = E / me;
223
224 Float_t I = CalcI(Z) * 1e-9; // GeV
225
226 if (par->GetQp() > 0) { // electrons
227 return K * (Z / A) * (std::log(2 * me / I) + 1.5 * std::log(gamma) - 0.975);
228 } else { // positrons
229 return K * (Z / A) * (std::log(2 * me / I) + 2. * std::log(gamma) - 1.);
230 }
231}
232
233Float_t BmnMaterialEffects::CalcQpAfterEloss(Float_t qp, Float_t eloss) const
234{
235 Float_t massSq = fMass * fMass;
236 Float_t p = std::abs(1. / qp);
237 // p *= 2; //for He3 and He4
238 Float_t E = std::sqrt(p * p + massSq);
239 Float_t q = (qp > 0) ? 1. : -1.;
240 // q *= 2; //for He3 and He4
241 if (!fDownstream) {
242 eloss *= -1.0;
243 } // TODO check this
244 Float_t Enew = E - eloss;
245 Float_t pnew = (Enew > fMass) ? std::sqrt(Enew * Enew - massSq) : 0.;
246 if (pnew != 0) {
247 return q / pnew;
248 } else {
249 return 1e5;
250 }
251
252 // if (!fDownstream) eloss *= -1.0;
253 // if (p > 0.) p -= eloss;
254 // else p += eloss;
255 // return 1./p;
256}
257
258Float_t BmnMaterialEffects::CalcSigmaSqQp(const FairTrackParam* par, const BmnMaterialInfo* mat) const
259{
260 Float_t P = std::abs(1. / par->GetQp()); // GeV
261 // P *= 2; //for He3 and He4
262 Float_t XMASS = fMass; // GeV
263 Float_t E = std::sqrt(P * P + XMASS * XMASS);
264 Float_t Z = mat->GetZ();
265 Float_t A = mat->GetA();
266 Float_t RHO = mat->GetRho();
267 Float_t STEP = mat->GetLength();
268 Float_t EMASS = 0.511 * 1e-3; // GeV
269
270 Float_t BETA = P / E;
271 Float_t GAMMA = E / XMASS;
272
273 // Calculate xi factor (KeV).
274 Float_t XI = (153.5 * Z * STEP * RHO) / (A * BETA * BETA);
275
276 // Maximum energy transfer to atomic electron (KeV).
277 Float_t ETA = BETA * GAMMA;
278 Float_t ETASQ = ETA * ETA;
279 Float_t RATIO = EMASS / XMASS;
280 Float_t F1 = 2. * EMASS * ETASQ;
281 Float_t F2 = 1. + 2. * RATIO * GAMMA + RATIO * RATIO;
282 Float_t EMAX = 1e6 * F1 / F2;
283
284 Float_t DEDX2 = XI * EMAX * (1. - (BETA * BETA / 2.)) * 1e-12;
285
286 Float_t SDEDX = (E * E * DEDX2) / std::pow(P, 6);
287
288 return std::abs(SDEDX);
289}
290
291Float_t BmnMaterialEffects::CalcSigmaSqQpElectron(const FairTrackParam* par, const BmnMaterialInfo* mat) const
292{
293 Float_t x = mat->GetLength(); // cm
294 Float_t X0 = mat->GetRL(); // cm
295 return par->GetQp() * par->GetQp() * (std::exp(-x / X0 * std::log(3.0) / std::log(2.0)) - std::exp(-2.0 * x / X0));
296}
297
298Float_t BmnMaterialEffects::CalcI(Float_t Z) const
299{
300 // mean excitation energy in eV
301 if (Z > 16.) {
302 return 10 * Z;
303 } else {
304 return 16 * std::pow(Z, 0.9);
305 }
306}
307
308Float_t BmnMaterialEffects::BetheHeitler(const FairTrackParam* par, const BmnMaterialInfo* mat) const
309{
310 Float_t M = fMass; // GeV
311 Float_t p = std::abs(1. / par->GetQp()); // GeV
312 Float_t rho = mat->GetRho();
313 Float_t X0 = mat->GetRL();
314 Float_t me = 0.000511; // GeV
315 Float_t E = std::sqrt(M * M + p * p);
316 Float_t ratio = me / M;
317
318 return (E * ratio * ratio) / (X0 * rho);
319}
320
321Float_t BmnMaterialEffects::PairProduction(const FairTrackParam* par, const BmnMaterialInfo* mat) const
322{
323 Float_t p = std::abs(1. / par->GetQp()); // GeV
324 Float_t M = fMass; // GeV
325 Float_t rho = mat->GetRho();
326 Float_t X0 = mat->GetRL();
327 Float_t E = std::sqrt(M * M + p * p);
328
329 return 7e-5 * E / (X0 * rho);
330}
331
333{
334 return 0.00354 * mat->GetZ() / mat->GetA();
335}
336
337Float_t BmnMaterialEffects::MPVEnergyLoss(const FairTrackParam* par, const BmnMaterialInfo* mat) const
338{
339 Float_t M = fMass * 1e3; // MeV
340 Float_t p = std::abs(1. / par->GetQp()) * 1e3; // MeV
341
342 // myf rho = mat->GetRho();
343 Float_t Z = mat->GetZ();
344 Float_t A = mat->GetA();
345 Float_t x = mat->GetRho() * mat->GetLength();
346
347 Float_t I = CalcI(Z) * 1e-6; // MeV
348
349 Float_t K = 0.307075; // MeV g^-1 cm^2
350 Float_t j = 0.200;
351
352 Float_t E = std::sqrt(M * M + p * p);
353 Float_t beta = p / E;
354 Float_t betaSq = beta * beta;
355 Float_t gamma = E / M;
356 Float_t gammaSq = gamma * gamma;
357
358 Float_t ksi = (K / 2.) * (Z / A) * (x / betaSq); // MeV
359
360 // myf hwp = 28.816 * std::sqrt(rho*Z/A) * 1e-6 ; // MeV
361 // myf dc = std::log(hwp/I) + std::log(beta*gamma) - 0.5;
362 // dc *= 2;
363 Float_t dc = 0.;
364
365 Float_t eloss = ksi * (std::log(2 * M * betaSq * gammaSq / I) + std::log(ksi / I) + j - betaSq - dc);
366
367 return eloss * 1e-3; // GeV
368}
BmnStatus
Definition BmnEnums.h:24
@ kBMNSUCCESS
Definition BmnEnums.h:25
Float_t CalcSigmaSqQp(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t BetheBlochSimple(const BmnMaterialInfo *mat) const
void AddEnergyLoss(FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t dEdx(const FairTrackParam *par, const BmnMaterialInfo *mat) const
BmnMaterialEffects()
Constructor.
Float_t CalcQpAfterEloss(Float_t qp, Float_t eloss) const
virtual BmnStatus Update(FairTrackParam *par, const BmnMaterialInfo *mat, Int_t pdg, Bool_t downstream)
Main function to be implemented for concrete material effects calculation algorithm.
Float_t BetheHeitler(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t EnergyLoss(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t CalcSigmaSqQpElectron(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t BetheBlochElectron(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t CalcThetaSq(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t MPVEnergyLoss(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t BetheBloch(const FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t CalcI(Float_t Z) const
void AddThinScatter(FairTrackParam *par, const BmnMaterialInfo *mat) const
void AddThickScatter(FairTrackParam *par, const BmnMaterialInfo *mat) const
Float_t PairProduction(const FairTrackParam *par, const BmnMaterialInfo *mat) const
virtual ~BmnMaterialEffects()
Destructor.
Float_t GetA() const
Float_t GetZ() const
Float_t GetLength() const
Float_t GetRho() const
Float_t GetRL() const
Interface for material effects calculation algorithm.
STL namespace.