Jpp test-rotations-old-533-g2bdbdb559
the software that should make you happy
Loading...
Searching...
No Matches
JRadiation.hh
Go to the documentation of this file.
1#ifndef __JPHYSICS__JRADIATION__
2#define __JPHYSICS__JRADIATION__
3
4#include <cmath>
5
6#include <TRandom3.h>
7
8#include "JLang/JCC.hh"
11
12/**
13 * \file
14 * Muon radiative cross sections.
15 * \author P. Kooijman
16 */
17
18namespace JPHYSICS {}
19namespace JPP { using namespace JPHYSICS; }
20
21namespace JPHYSICS {
22
23 namespace {
24 static const double LAMBDA = 0.65; // [GeV]
25 }
26
27 /**
28 * Auxiliary class for the calculation of the muon radiative cross sections.
29 * \author P. Kooijman
30 *
31 * Bremsstrahlung and pair production cross sections are taken from <a href="https://pdg.lbl.gov/index.html">Particle Data Group</a>.
32 *
33 * Gamma-nucleon cross section:
34 * Phys.\ Lett.\ B\ Vol.\ 697-3 (2011) 184-193.
35 */
36 class JRadiation {
37 public:
38
39 /**
40 * Virtual desctructor.
41 */
42 virtual ~JRadiation()
43 {}
44
45
46 /**
47 * Constructor.
48 *
49 * \param z number of protons
50 * \param a number of nucleons
51 * \param integrsteps number of integration steps
52 * \param eminBrems energy threshold Bremsstrahlung [GeV]
53 * \param eminEErad energy threshold pair production [GeV]
54 * \param eminGNrad energy threshold photo-production [GeV]
55 */
56 JRadiation(const double z,
57 const double a,
58 const int integrsteps,
59 const double eminBrems,
60 const double eminEErad,
61 const double eminGNrad) :
62 Z(z),
63 A(a),
64 Dn (1.54*pow(A,0.27)),
65 DnP (pow(Dn,(1-1/Z))),
66 steps(integrsteps),
67 EminBrems(eminBrems),
68 EminEErad(eminEErad),
69 EminGNrad(eminGNrad)
70 {}
71
72
73 /**
74 * Pair production cross section.
75 *
76 * \param E muon energy [GeV]
77 * \param eps shower energy [GeV]
78 * \return cross section [m^2/g]
79 */
80 double SigmaEErad(const double E,
81 const double eps) const
82 {
83 //routine to calculate dsigma/de in cm^2/GeV for radiating a photon of energy eps
84
85 if(eps<4.*MASS_ELECTRON)return 0.;
86 if(eps>E-0.75*exp(1.0)*pow(Z,1./3.)) return 0.;
87 double zeta;
88 if(E<35.*MASS_MUON)
89 {
90 zeta = 0.;
91 }
92 else
93 {
94 zeta = (0.073*log((E/MASS_MUON)/(1.+1.95e-5*pow(Z,2./3.)*E/MASS_MUON))-0.26);
95 if(zeta<0.)
96 {
97 zeta=0.;
98 }
99 else
100 {
101 zeta = zeta/(0.058*log((E/MASS_MUON)/(1.+5.3e-5*pow(Z,1./3.)*E/MASS_MUON))-0.14);
102 }
103 }
104 double integ = IntegralofG(E,eps);
105 //cout<< eps<<" integ "<< integ<<endl;
106 return integ*(4/(3.*M_PI))*(Z*(Z+zeta)/A)*AVOGADRO*pow((ALPHA_ELECTRO_MAGNETIC*r0()),2.)*(1-eps/E)/eps;
107 }
108
109
110 /**
111 * Pair production cross section.
112 *
113 * \param E muon energy [GeV]
114 * \return cross section [m^2/g]
115 */
116 virtual double TotalCrossSectionEErad(const double E) const
117 {
118 //cout<<" entering TotcrsecEErad"<<endl;
119 // radiation goes approx as 1/E so sample in log E
120 // calculate the total cross section as S(dsigma/de)*de
121 // start at E and go backwards for precision
122 double sum(0.);
123 double dle = log(E/EminEErad)/steps;
124 //cout << "dle "<< dle<<endl;
125 for(int i=0;i<steps+1;i++)
126 {
127 double factor = 1.0;
128 if(i==0 || i==steps)factor=0.5;
129 //cout<<"i"<<i<<endl;
130 double eps = EminEErad*exp(i*dle);sum += factor*eps*SigmaEErad( E, eps);
131 //cout<<"eps "<<eps<<" sum "<<sum<<endl;
132 }
133 return sum*dle;
134 }
135
136
137 /**
138 * Bremsstrahlung cross section.
139 *
140 * \param E muon energy [GeV]
141 * \return cross section [m^2/g]
142 */
143
144 double TotalCrossSectionBrems(const double E) const
145 {
146 // double delta = (MASS_MUON*MASS_MUON*eps)/(2*E*(E-eps));
147 double delta = (MASS_MUON*MASS_MUON)/(2*E);
148 //double v = eps/E;
149 double Phin = log((B()*pow(Z,-1./3.)*(MASS_MUON+delta*(DnP*sqrt(exp(1.0))-2.)))/(DnP*(MASS_ELECTRON+delta*sqrt(exp(1.0))*B()*pow(Z,-1./3.))));
150 if(Phin<0.)Phin=0.;
151 double Phie = log((BP()*pow(Z,-2./3.)*MASS_MUON)/((1+delta*MASS_MUON/(MASS_ELECTRON*MASS_ELECTRON*sqrt(exp(1.0))))*(MASS_ELECTRON+delta*sqrt(exp(1.0))*BP()*pow(Z,-2./3.))));
152 if(Phie<0.)Phie=0.;
153 //if(eps>E/(1+MASS_MUON*MASS_MUON/(2.*MASS_ELECTRON*E)))Phie=0.;
154 double sig = (16./3.)*ALPHA_ELECTRO_MAGNETIC*AVOGADRO*pow((MASS_ELECTRON/MASS_MUON*r0()),2.0)*Z*(Z*Phin+Phie)/(A);
155 double epsint = log((E-MASS_MUON)/EminBrems)-(E-MASS_MUON-EminBrems)/E+0.375*(pow(E-MASS_MUON,2.)-pow(EminBrems,2.0))/pow(E,2.0);
156 return epsint*sig;//"cross section" in m^2/g multiplied by density and inverted gives mean free path
157 }
158
159
160 /**
161 * Photo-nuclear cross section.
162 *
163 * \param E muon energy [GeV]
164 * \param eps shower energy [GeV]
165 * \return cross section [m^2/g]
166 */
167 virtual double SigmaGNrad(const double E, const double eps) const
168 {
169
170 //minimum radiated energy is 0.2 GeV, not very critical formulae become invalid for very much lower
171 //result is given in m^2/g GeV
172 if (eps<0.2) return 0.;
173 if (eps>E-MASS_PROTON) return 0.;
174 double Aeff;
175 if (A==1)
176 {Aeff = 1.;}
177 else
178 {Aeff = (0.22*A + 0.78 * pow(A,0.89));}
179 double sigmaGammaPofeps = (49.2 + 11.1 * log(eps) + 151.8/sqrt(eps))*pow(10,-34.);
180 double Psiofeps = ALPHA_ELECTRO_MAGNETIC/PI*Aeff*AVOGADRO/A*sigmaGammaPofeps/eps;
181 double Denom = 1+eps/LAMBDA*(1+LAMBDA/(2*MASS_PROTON)+eps/LAMBDA);
182 double epsoverE = eps/E;
183 double Numerator = E * E * (1 - epsoverE) / (MASS_MUON * MASS_MUON) * (1 + MASS_MUON * MASS_MUON * epsoverE * epsoverE / (LAMBDA * LAMBDA * (1 - epsoverE)));
184 double Factor = 1 - epsoverE + epsoverE * epsoverE / 2 * (1 + 2 * MASS_MUON * MASS_MUON / (LAMBDA * LAMBDA));
185 double PhiofEofeps = epsoverE - 1 + Factor * log (Numerator / Denom);
186 //cout<<"PhiofEofeps "<<PhiofEofeps<<" Psiofeps "<<Psiofeps<<endl;
187 return Psiofeps*PhiofEofeps;
188 }
189
190
191 /**
192 * Photo-nuclear cross section.
193 *
194 * \param E muon energy [GeV]
195 * \return cross section [m^2/g]
196 */
197 virtual double TotalCrossSectionGNrad(const double E) const
198 {
199 double epsmin = 0.2;
200 double epsmax = E-MASS_PROTON/2;
201 double sum(0.);
202 double dle = log(epsmax/epsmin)/steps;
203 for(int i=0;i<steps+1;i++)
204 {
205 float factor = 1.0;
206 if(i==0 || i==steps)factor=0.5;
207 //cout<<"i"<<i<<endl;
208 double eps = epsmin*exp(i*dle);sum += factor*eps*SigmaGNrad( E, eps);
209 //cout<<"eps "<<eps<<" sum "<<sum<<endl;
210 }
211
212 return sum*dle;
213 }
214
215
216 /**
217 * Bremsstrahlung shower energy.
218 *
219 * \param E muon energy [GeV]
220 * \return shower energy [GeV]
221 */
222 double EfromBrems(const double E) const
223 {
224 //double EminBrems(0.01);
225 //generate according to 1/k from minimum energy to E
226 double Er = 0.0;
227 for (int i = 1000; i != 0; --i) {
228 Er = EminBrems*exp(gRandom->Rndm()*log(E/EminBrems));
229 //check on the extra factor (1-v+3/4v^2)
230 if(gRandom->Rndm()<(1.-Er/E+0.75*pow(Er/E,2))) break;
231 }
232 return Er;
233 }
234
235
236 /**
237 * Get RMS of scattering angle for Bremsstrahlung.
238 *
239 * \param E muon energy [GeV]
240 * \param v energy loss fraction
241 * \return angle [rad]
242 */
243 double ThetaRMSfromBrems(const double E, const double v) const
244 {
245 using namespace std;
246
247 const double precision = 1.0e-3;
248
249 const double k1 = 0.092 * pow(E, -1.0/3.0);
250 const double k2 = 0.052 * pow(E, -1.0) * pow(Z, -1.0/4.0);
251 const double k3 = 0.220 * pow(E, -0.92);
252 const double k4 = 0.260 * pow(E, -0.91);
253
254 double rms = 0.0;
255
256 if (v <= 0.5) {
257
258 rms = max(min(k1*sqrt(v), k2), k3*v);
259
260 } else {
261
262 const double n = 0.81 * sqrt(E) / (sqrt(E) + 1.8);
263
264 double k5 = 0.0;
265
266 for (double vmin = 0.5, vmax = 1.0; ; ) {
267
268 const double v = 0.5 * (vmin + vmax);
269
270 const double y = k4 * pow(v, 1.0 + n) * pow(1.0 - v, -n);
271
272 if (abs(y - 0.2) <= precision) {
273
274 k5 = y * pow(1.0 - v, 1.0/2.0);
275
276 break;
277 }
278
279 if (y < 0.2)
280 vmin = v;
281 else
282 vmax = v;
283 }
284
285 rms = k4 * pow(v, 1.0 + n) * pow(1.0 - v, -n);
286
287 if (rms >= 0.2) {
288 rms = k5 * pow(1.0 - v, -1.0/2.0);
289 }
290 }
291
292 return rms;
293 }
294
295
296 /**
297 * Pair production shower energy.
298 *
299 * \param E muon energy [GeV]
300 * \return shower energy [GeV]
301 */
302 double EfromEErad(const double E) const
303 {
304 //generate according to 1/k from minimum energy to E
305
306 const double eps =0.2;
307 const double IntGmax = IntegralofG(E,eps)*2.0;
308
309 double Er = 0.0;
310 for (int i = 1000; i != 0; --i)
311 {
312 Er = EminEErad*exp(gRandom->Rndm()*log(E/EminEErad));
313 //check on the extra factor, (1-v) and IntofG
314 double factor = (1.-Er/E)*IntegralofG(E,Er)/IntGmax;
315 if(gRandom->Rndm()<factor) break;
316 }
317 return Er;
318 }
319
320
321 /**
322 * Get RMS of scattering angle for pair production.
323 *
324 * \param E muon energy [GeV]
325 * \param v energy loss fraction
326 * \return angle [rad]
327 */
328 double ThetaRMSfromEErad(const double E, const double v) const
329 {
330 using namespace std;
331
332 const double a = 8.9e-4;
333 const double b = 1.5e-5;
334 const double c = 0.032;
335 const double d = 1.0;
336 const double e = 0.1;
337
338 const double n = -1.0;
339
340 const double u = v - 2.0*MASS_ELECTRON/E;
341
342 if (u > 0.0)
343 return (2.3 + log(E)) * (1.0/E) * pow(1.0 - v, n) * (u*u) * (1.0/(v*v)) *
344 min(a * pow(v, 1.0/4.0) * (1.0 + b*E) + c*v/(v+d), e);
345 else
346 return 0.0;
347 }
348
349
350 /**
351 * Photo-nuclear shower energy.
352 *
353 * \param E muon energy [GeV]
354 * \return shower energy [GeV]
355 */
356 double EfromGNrad(const double E) const
357 {
358 //generate according to 1/k from minimum energy to E
359
360 double cmax = sigmaGammaPparam(EminGNrad);
361 if (cmax < sigmaGammaPparam(E))
362 cmax=sigmaGammaPparam(E);
363
364 double Pmax = PhiofEofepsparam(E,EminGNrad);
365
366 double Er = 0.0;
367 for (int i = 1000; i != 0; --i) {
368 Er = EminGNrad*exp(gRandom->Rndm()*log(E/EminGNrad));
369 const double factor = PhiofEofepsparam(E,Er)*sigmaGammaPparam(Er)/(cmax*Pmax);
370 if (gRandom->Rndm() < factor) return Er;
371 }
372
373 return Er;
374 }
375
376
377 /**
378 * Get RMS of scattering angle for photo-nuclear shower.
379 *
380 * \param E muon energy [GeV]
381 * \param v energy loss fraction
382 * \return angle [rad]
383 */
384 double ThetaRMSfromGNrad(const double E, const double v) const
385 {
386 return 0.0;
387 }
388
389
390 /**
391 * Ionization a parameter.
392 *
393 * \param E muon energy [GeV]
394 * \return ionization coefficient [GeV*m^2/g]
395 */
396 virtual double CalculateACoeff(double E) const
397 {
398 const double E2 = E*E;
399 const double beta = sqrt(E2 - MASS_MUON*MASS_MUON) / E;
400 const double beta2 = beta*beta;
401 const double gamma = E/MASS_MUON;
402 const double gamma2 = gamma*gamma;
403
404 const double p2 = E2 - MASS_MUON*MASS_MUON;
405 const double EMaxT = 2.*MASS_ELECTRON*p2 / (MASS_ELECTRON*MASS_ELECTRON + MASS_MUON*MASS_MUON + 2.*MASS_ELECTRON*E);
406 const double EMaxT2 = EMaxT*EMaxT;
407 const JSter& coeff = getSterCoefficient(Z);
408 const double I2 = coeff.I*coeff.I; // in GeV^2
409 const double X = log10(beta*gamma);
410
411 double delta = 0.0;
412
413 if (coeff.X0 < X && X < coeff.X1) {
414 delta = 4.6052*X + coeff.a*pow(coeff.X1-X,coeff.m) + coeff.C;
415 }
416
417 if (X > coeff.X1) {
418 delta = 4.6052*X + coeff.C;
419 }
420
421 double acoeff = (2*PI*AVOGADRO*ALPHA_ELECTRO_MAGNETIC*ALPHA_ELECTRO_MAGNETIC*le()*le())*Z/A*(MASS_ELECTRON/beta2)*(log(2.*MASS_ELECTRON*beta2*gamma2*EMaxT/I2)-2.*beta2+0.25*(EMaxT2/E2)-delta);
422
423 return acoeff;
424 }
425
426
427 /**
428 * Auxiliary data structure for handling member methods of class JRadiation.
429 */
431 double (JRadiation::*sigma)(const double) const; //!< total cross section method
432 double (JRadiation::*eloss)(const double) const; //!< energy loss method
433 double (JRadiation::*theta)(const double, const double) const; //!< scattering angle method
434 };
435
436
440
441 protected:
442 double GofZEvrho(const double E,
443 const double v,
444 const double r) const
445 {
446 const double ksi = MASS_MUON*MASS_MUON*v*v*(1-r*r)/(4*MASS_ELECTRON*MASS_ELECTRON*(1-v));//
447 const double b = v*v/(2*(1-v));//
448 const double Be = ((2+r*r)*(1+b)+ksi*(3+r*r))*log(1+1/ksi)+(1-r*r-b)/(1+ksi)-(3+r*r);
449 const double Bm = ((1+r*r)*(1+3*b/2)-(1+2*b)*(1-r*r)/ksi)*log(1+ksi)+ksi*(1-r*r-b)/(1+ksi)+(1+2*b)*(1-r*r);
450 const double Ye = (5-r*r+4*b*(1+r*r))/(2*(1+3*b)*log(3+1/ksi)-r*r-2*b*(2-r*r));
451 const double Ym = (4+r*r+3*b*(1+r*r))/((1+r*r)*(1.5+2*b)*log(3+ksi)+1-1.5*r*r);
452 const double Le = log((Astar()*pow(Z,-1./3.)*sqrt((1+ksi)*(1+Ye)))/
453 (1.+(2.*MASS_ELECTRON*sqrt(exp(1.))*Astar()*pow(Z,-1./3.)*(1+ksi)*(1+Ye))/(E*v*(1-r*r))));
454 const double Lm = log(((MASS_MUON/MASS_ELECTRON)*Astar()*pow(Z,-1./3.)*sqrt((1.+1./ksi)*(1.+Ym)))/
455 (1.+(2.*MASS_ELECTRON*sqrt(exp(1.))*Astar()*pow(Z,-1./3.)*(1+ksi)*(1+Ym))/(E*v*(1-r*r))));
456 double Phie = Be*Le; if(Phie<0.)Phie=0.;
457 double Phim = Bm*Lm; if(Phim<0.)Phim=0.;
458 return Phie+(MASS_ELECTRON*MASS_ELECTRON/(MASS_MUON*MASS_MUON))*Phim;
459 }
460
461 virtual double IntegralofG(const double E,
462 const double eps) const
463 {
464 const double EP = E-eps;
465 const double v = eps/E;
466 const double tmin = log((4*MASS_ELECTRON/eps+12*pow(MASS_MUON,2)/(E*EP)*(1-4*MASS_ELECTRON/eps))
467 /(1+(1-6*pow(MASS_MUON,2)/(E*EP))*sqrt(1-4*MASS_ELECTRON/eps)));
468
469 if (tmin < 0.0) {
470 const double dt = -tmin/steps;
471 double sum(0.);
472 for (int i = 0;i<steps+1;i++)
473 {
474 double fac = 1.0;if(i==0 || i==steps)fac=0.5;
475 double t = tmin+i*dt;
476 double r = 1.-exp(t);
477 sum+=fac*GofZEvrho(E,v,r)*exp(t);
478 }
479 return sum*dt;
480 } else
481 return 0.0;
482 }
483
484 static double sigmaGammaPparam(const double eps)
485 {
486 return (49.2 + 11.1 * log(eps) + 151.8/sqrt(eps));
487 }
488
489 static double PhiofEofepsparam(const double E,const double eps)
490 {
491 const double Denom = 1+eps/LAMBDA*(1+LAMBDA/(2*MASS_PROTON)+eps/LAMBDA);
492 const double epsoverE = eps/E;
493 const double Numerator = E * E * (1 - epsoverE) / (MASS_MUON * MASS_MUON) * (1 + MASS_MUON * MASS_MUON * epsoverE * epsoverE /
494 (LAMBDA * LAMBDA * (1 - epsoverE)));
495 const double Factor = 1 - epsoverE + epsoverE * epsoverE / 2 * (1 + 2 * MASS_MUON * MASS_MUON / (LAMBDA * LAMBDA));
496 return (epsoverE - 1 + Factor * log (Numerator / Denom));
497 }
498
499
500 static double le () { return 3.8616E-13;}
501 static double r0 () { return 2.817940e-15; }
502 static double Astar() { return 183.0; }
503 static double B () { return 183.0; }
504 static double BP () { return 1429.0; }
505
506 const double Z;
507 const double A;
508 const double Dn;
509 const double DnP;
510 const int steps;
511 const double EminBrems;
512 const double EminEErad;
513 const double EminGNrad;
514 };
515}
516
517#endif
518
Compiler version dependent expressions, macros, etc.
Physics constants.
Auxiliary class for the calculation of the muon radiative cross sections.
Definition JRadiation.hh:36
static double sigmaGammaPparam(const double eps)
virtual ~JRadiation()
Virtual desctructor.
Definition JRadiation.hh:42
virtual double SigmaGNrad(const double E, const double eps) const
Photo-nuclear cross section.
virtual double IntegralofG(const double E, const double eps) const
virtual double TotalCrossSectionEErad(const double E) const
Pair production cross section.
virtual double CalculateACoeff(double E) const
Ionization a parameter.
static double B()
double GofZEvrho(const double E, const double v, const double r) const
virtual double TotalCrossSectionGNrad(const double E) const
Photo-nuclear cross section.
static double BP()
double SigmaEErad(const double E, const double eps) const
Pair production cross section.
Definition JRadiation.hh:80
double EfromEErad(const double E) const
Pair production shower energy.
static constexpr radiation_type GNrad_t
double EfromGNrad(const double E) const
Photo-nuclear shower energy.
JRadiation(const double z, const double a, const int integrsteps, const double eminBrems, const double eminEErad, const double eminGNrad)
Constructor.
Definition JRadiation.hh:56
double EfromBrems(const double E) const
Bremsstrahlung shower energy.
double TotalCrossSectionBrems(const double E) const
Bremsstrahlung cross section.
const double EminBrems
const double EminEErad
static double le()
double ThetaRMSfromGNrad(const double E, const double v) const
Get RMS of scattering angle for photo-nuclear shower.
static double PhiofEofepsparam(const double E, const double eps)
static constexpr radiation_type Brems_t
static constexpr radiation_type EErad_t
static double Astar()
double ThetaRMSfromEErad(const double E, const double v) const
Get RMS of scattering angle for pair production.
const double EminGNrad
double ThetaRMSfromBrems(const double E, const double v) const
Get RMS of scattering angle for Bremsstrahlung.
static double r0()
Auxiliary methods for light properties of deep-sea water.
static const double ALPHA_ELECTRO_MAGNETIC
Electro-Magnetic coupling constant.
static const double MASS_MUON
muon mass [GeV]
static const double MASS_ELECTRON
electron mass [GeV]
static JSterCoefficient getSterCoefficient
Function object for Ster coefficients.
static const double AVOGADRO
Avogadro's number.
static const double MASS_PROTON
proton mass [GeV]
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for handling member methods of class JRadiation.
double(JRadiation::* theta)(const double, const double) const
scattering angle method
double(JRadiation::* eloss)(const double) const
energy loss method
double(JRadiation::* sigma)(const double) const
total cross section method
Struct for the Sternheimer coefficients.
double C
Correction density parameter
double m
Correction density parameter.
double I
Ionization potentian [GeV].
double X1
Correction density parameter.
double a
Correction density parameter.
double X0
Correction density parameter.
Auxiliary data structure to convert (lambda) function to printable object.
Definition JManip.hh:726