Jpp 19.3.0-rc.3
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 protected:
427 double GofZEvrho(const double E,
428 const double v,
429 const double r) const
430 {
431 const double ksi = MASS_MUON*MASS_MUON*v*v*(1-r*r)/(4*MASS_ELECTRON*MASS_ELECTRON*(1-v));//
432 const double b = v*v/(2*(1-v));//
433 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);
434 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);
435 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));
436 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);
437 const double Le = log((Astar()*pow(Z,-1./3.)*sqrt((1+ksi)*(1+Ye)))/
438 (1.+(2.*MASS_ELECTRON*sqrt(exp(1.))*Astar()*pow(Z,-1./3.)*(1+ksi)*(1+Ye))/(E*v*(1-r*r))));
439 const double Lm = log(((MASS_MUON/MASS_ELECTRON)*Astar()*pow(Z,-1./3.)*sqrt((1.+1./ksi)*(1.+Ym)))/
440 (1.+(2.*MASS_ELECTRON*sqrt(exp(1.))*Astar()*pow(Z,-1./3.)*(1+ksi)*(1+Ym))/(E*v*(1-r*r))));
441 double Phie = Be*Le; if(Phie<0.)Phie=0.;
442 double Phim = Bm*Lm; if(Phim<0.)Phim=0.;
443 return Phie+(MASS_ELECTRON*MASS_ELECTRON/(MASS_MUON*MASS_MUON))*Phim;
444 }
445
446 virtual double IntegralofG(const double E,
447 const double eps) const
448 {
449 const double EP = E-eps;
450 const double v = eps/E;
451 const double tmin = log((4*MASS_ELECTRON/eps+12*pow(MASS_MUON,2)/(E*EP)*(1-4*MASS_ELECTRON/eps))
452 /(1+(1-6*pow(MASS_MUON,2)/(E*EP))*sqrt(1-4*MASS_ELECTRON/eps)));
453
454 if (tmin < 0.0) {
455 const double dt = -tmin/steps;
456 double sum(0.);
457 for (int i = 0;i<steps+1;i++)
458 {
459 double fac = 1.0;if(i==0 || i==steps)fac=0.5;
460 double t = tmin+i*dt;
461 double r = 1.-exp(t);
462 sum+=fac*GofZEvrho(E,v,r)*exp(t);
463 }
464 return sum*dt;
465 } else
466 return 0.0;
467 }
468
469 static double sigmaGammaPparam(const double eps)
470 {
471 return (49.2 + 11.1 * log(eps) + 151.8/sqrt(eps));
472 }
473
474 static double PhiofEofepsparam(const double E,const double eps)
475 {
476 const double Denom = 1+eps/LAMBDA*(1+LAMBDA/(2*MASS_PROTON)+eps/LAMBDA);
477 const double epsoverE = eps/E;
478 const double Numerator = E * E * (1 - epsoverE) / (MASS_MUON * MASS_MUON) * (1 + MASS_MUON * MASS_MUON * epsoverE * epsoverE /
479 (LAMBDA * LAMBDA * (1 - epsoverE)));
480 const double Factor = 1 - epsoverE + epsoverE * epsoverE / 2 * (1 + 2 * MASS_MUON * MASS_MUON / (LAMBDA * LAMBDA));
481 return (epsoverE - 1 + Factor * log (Numerator / Denom));
482 }
483
484
485 static double le () { return 3.8616E-13;}
486 static double r0 () { return 2.817940e-15; }
487 static double Astar() { return 183.0; }
488 static double B () { return 183.0; }
489 static double BP () { return 1429.0; }
490
491 const double Z;
492 const double A;
493 const double Dn;
494 const double DnP;
495 const int steps;
496 const double EminBrems;
497 const double EminEErad;
498 const double EminGNrad;
499 };
500
501
502 /**
503 * Auxiliary data structure for handling member methods of class JRadiation.
504 */
506 double (JRadiation::*sigma)(const double) const; //!< total cross section method
507 double (JRadiation::*eloss)(const double) const; //!< energy loss method
508 double (JRadiation::*theta)(const double, const double) const; //!< scattering angle method
509 };
510
511
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.
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 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 JRadiationSource_t GNrad_t
static const double MASS_MUON
muon mass [GeV]
static const JRadiationSource_t Brems_t
static const double MASS_ELECTRON
electron mass [GeV]
static JSterCoefficient getSterCoefficient
Function object for Ster coefficients.
static const JRadiationSource_t EErad_t
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::* sigma)(const double) const
total cross section method
double(JRadiation::* eloss)(const double) const
energy loss method
double(JRadiation::* theta)(const double, const double) const
scattering angle 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