26 #include "TDatabasePDG.h"
27 #include "TGeoMedium.h"
28 #include "TGeoMaterial.h"
29 #include "TGeoManager.h"
47 fEnergyLossBetheBloch(
true), fNoiseBetheBloch(
true),
49 fEnergyLossBrems(
true), fNoiseBrems(
true),
88 if (modelName == std::string(
"GEANE")) {
90 }
else if (modelName == std::string(
"Highland")) {
93 std::string errorMsg = std::string(
"There is no MSC model called \"") + modelName +
"\". Maybe it is not implemented or you misspelled the model name";
107 const double* jacobian,
108 const TVector3* directionBefore,
109 const TVector3* directionAfter)
118 unsigned int nPoints(points.size());
120 for (
unsigned int i = 1; i < nPoints; ++i) {
122 TVector3 dir(points.at(i).getPos() - points.at(i-1).getPos());
123 double dist = dir.Mag();
130 double realPath = points.at(i-1).getPath();
132 gGeoManager->InitTrack(points.at(i-1).X(), points.at(i-1).Y(), points.at(i-1).Z(),
133 dir.X(), dir.Y(), dir.Z());
139 gGeoManager->FindNextBoundaryAndStep(dist - X);
140 step = gGeoManager->GetStep();
141 fstep = fabs(step * realPath / dist);
142 if (
fstep <= 0.)
continue;
145 if (realPath < 0) stepSign = -1.;
155 this->
noiseCoulomb(mom, noise, jacobian, directionBefore, directionAfter);
174 const double& maxAngleStep,
186 static const double maxRelMomLoss = .005;
187 static const double minStep = 1.E-4;
190 if (relMomLoss > maxRelMomLoss)
return 0;
191 if (maxStep < minStep)
return minStep;
195 double relMomLossStep(0);
196 TGeoMaterial* mat(NULL);
199 gGeoManager->InitTrack(posx+minStep*dirx,
210 TGeoMedium* medium = gGeoManager->GetCurrentVolume()->GetMedium();
211 assert(medium != NULL);
212 mat = medium->GetMaterial();
213 gGeoManager->FindNextBoundaryAndStep(maxStep-X);
214 fstep = gGeoManager->GetStep();
217 std::cout<<
" gGeoManager->GetStep() = " << gGeoManager->GetStep() <<
" fstep = " <<
fstep <<
"\n";
220 if (
fstep <= 0.)
continue;
230 if (relMomLoss + relMomLossStep > maxRelMomLoss) {
231 double fraction = (maxRelMomLoss - relMomLoss) / relMomLossStep;
232 X += fraction *
fstep;
234 std::cout<<
" momLoss exceeded \n";
239 relMomLoss += relMomLossStep;
259 TParticlePDG*
part = TDatabasePDG::Instance()->GetParticle(
fpdg);
260 fcharge = part->Charge() / (3.);
261 fmass = part->Mass();
292 double momLoss = sqrt(mom * mom + 2.*sqrt(mom * mom +
fmass *
fmass) * DE + DE * DE) -
mom;
295 if (momLoss < 0.)
return 0.;
309 double kappa = zeta / Emax;
312 sigma2E += zeta * Emax * (1. -
fbeta *
fbeta / 2.);
315 double alpha = 0.996;
316 double sigmaalpha = 15.76;
318 double I = 16. * pow(
fmatZ, 0.9);
323 double e1 = pow((I / pow(e2, f2)), 1. / f1);
328 double Sigma3 =
fdedx * 1.0E9 * Emax / (I * (Emax + I) * log((Emax + I) / I)) * 0.4;
330 double Nc = (Sigma1 + Sigma2 + Sigma3) * fabs(
fstep);
334 double RLAMED = -0.422784 -
fbeta *
fbeta - log(zeta / Emax);
335 double RLAMAX = 0.60715 + 1.1934 * RLAMED + (0.67794 + 0.052382 * RLAMED) * exp(0.94753 + 0.74442 * RLAMED);
337 if (RLAMAX <= 1010.) {
338 sigmaalpha = 1.975560
339 + 9.898841e-02 * RLAMAX
340 - 2.828670e-04 * RLAMAX * RLAMAX
341 + 5.345406e-07 * pow(RLAMAX, 3.)
342 - 4.942035e-10 * pow(RLAMAX, 4.)
343 + 1.729807e-13 * pow(RLAMAX, 5.);
344 }
else { sigmaalpha = 1.871887E+01 + 1.296254E-02 * RLAMAX; }
346 if (sigmaalpha > 54.6) sigmaalpha = 54.6;
347 sigma2E += sigmaalpha * sigmaalpha * zeta * zeta;
349 double Ealpha = I / (1. - (alpha * Emax / (Emax + I)));
350 double meanE32 = I * (Emax + I) / Emax * (Ealpha - I);
351 sigma2E += fabs(
fstep) * (Sigma1 * e1 * e1 + Sigma2 * e2 * e2 + Sigma3 * meanE32);
358 noise[6*7+6] += (mom * mom +
fmass *
fmass) / pow(mom, 6.) * sigma2E;
364 const double* jacobian,
365 const TVector3* directionBefore,
366 const TVector3* directionAfter)
const
377 double logCor = (1 + 0.038 * log(stepOverRadLength));
380 assert(sigma2 > 0.0);
385 double noiseBefore[7*7];
386 memset(noiseBefore,0x00,7*7*
sizeof(
double));
390 if (fabs((*directionBefore)[1]) < 1E-14) {
391 if ((*directionBefore)[0] >= 0.) psi =
M_PI / 2.;
392 else psi = 3.*
M_PI / 2.;
394 if ((*directionBefore)[1] > 0.) psi =
M_PI - atan((*directionBefore)[0] / (*directionBefore)[1]);
395 else psi = -atan((*directionBefore)[0] / (*directionBefore)[1]);
398 double sintheta = sqrt(1 - (*directionBefore)[2] * (*directionBefore)[2]);
399 double costheta = (*directionBefore)[2];
400 double sinpsi = sin(psi);
401 double cospsi =
cos(psi);
404 const double noiseBefore33 = sigma2 * (cospsi * cospsi + costheta * costheta - costheta * costheta * cospsi * cospsi);
405 const double noiseBefore43 = sigma2 * cospsi * sinpsi * sintheta * sintheta;
406 const double noiseBefore53 = -sigma2 * costheta * sinpsi * sintheta;
407 const double noiseBefore44 = sigma2 * (sinpsi * sinpsi + costheta * costheta * cospsi * cospsi);
408 const double noiseBefore54 = sigma2 * costheta * cospsi * sintheta;
409 const double noiseBefore55 = sigma2 * sintheta * sintheta;
413 double JTM0 = jacobian[21+0] * noiseBefore33 + jacobian[28+0] * noiseBefore43 + jacobian[35+0] * noiseBefore53;
414 double JTM1 = jacobian[21+0] * noiseBefore43 + jacobian[28+0] * noiseBefore44 + jacobian[35+0] * noiseBefore54;
415 double JTM2 = jacobian[21+0] * noiseBefore53 + jacobian[28+0] * noiseBefore54 + jacobian[35+0] * noiseBefore55;
416 double JTM3 = jacobian[21+1] * noiseBefore33 + jacobian[28+1] * noiseBefore43 + jacobian[35+1] * noiseBefore53;
417 double JTM4 = jacobian[21+1] * noiseBefore43 + jacobian[28+1] * noiseBefore44 + jacobian[35+1] * noiseBefore54;
418 double JTM5 = jacobian[21+1] * noiseBefore53 + jacobian[28+1] * noiseBefore54 + jacobian[35+1] * noiseBefore55;
419 double JTM6 = jacobian[21+2] * noiseBefore33 + jacobian[28+2] * noiseBefore43 + jacobian[35+2] * noiseBefore53;
420 double JTM7 = jacobian[21+2] * noiseBefore43 + jacobian[28+2] * noiseBefore44 + jacobian[35+2] * noiseBefore54;
421 double JTM8 = jacobian[21+2] * noiseBefore53 + jacobian[28+2] * noiseBefore54 + jacobian[35+2] * noiseBefore55;
422 double JTM9 = jacobian[21+3] * noiseBefore33 + jacobian[28+3] * noiseBefore43 + jacobian[35+3] * noiseBefore53;
423 double JTM10 = jacobian[21+3] * noiseBefore43 + jacobian[28+3] * noiseBefore44 + jacobian[35+3] * noiseBefore54;
424 double JTM11 = jacobian[21+3] * noiseBefore53 + jacobian[28+3] * noiseBefore54 + jacobian[35+3] * noiseBefore55;
425 double JTM12 = jacobian[21+4] * noiseBefore33 + jacobian[28+4] * noiseBefore43 + jacobian[35+4] * noiseBefore53;
426 double JTM13 = jacobian[21+4] * noiseBefore43 + jacobian[28+4] * noiseBefore44 + jacobian[35+4] * noiseBefore54;
427 double JTM14 = jacobian[21+4] * noiseBefore53 + jacobian[28+4] * noiseBefore54 + jacobian[35+4] * noiseBefore55;
430 noiseBefore[35+5] = (jacobian[21+5] * noiseBefore33 + jacobian[28+5] * noiseBefore43 + jacobian[35+5] * noiseBefore53) * jacobian[21+5] + (jacobian[21+5] * noiseBefore43 + jacobian[28+5] * noiseBefore44 + jacobian[35+5] * noiseBefore54) * jacobian[28+5] + (jacobian[21+5] * noiseBefore53 + jacobian[28+5] * noiseBefore54 + jacobian[35+5] * noiseBefore55) * jacobian[35+5];
431 for (
int i=0; i<6; ++i) noiseBefore[i] = JTM0 * jacobian[21+i] + JTM1 * jacobian[28+i] + JTM2 * jacobian[35+i];
432 for (
int i=1; i<6; ++i) noiseBefore[7+i] = JTM3 * jacobian[21+i] + JTM4 * jacobian[28+i] + JTM5 * jacobian[35+i];
433 for (
int i=2; i<6; ++i) noiseBefore[14+i] = JTM6 * jacobian[21+i] + JTM7 * jacobian[28+i] + JTM8 * jacobian[35+i];
434 for (
int i=3; i<6; ++i) noiseBefore[21+i] = JTM9 * jacobian[21+i] + JTM10 * jacobian[28+i] + JTM11 * jacobian[35+i];
435 for (
int i=4; i<6; ++i) noiseBefore[28+i] = JTM12 * jacobian[21+i] + JTM13 * jacobian[28+i] + JTM14 * jacobian[35+i];
438 noiseBefore[7+0] = noiseBefore[1];
439 noiseBefore[14+0] = noiseBefore[2]; noiseBefore[14+1] = noiseBefore[7+2];
440 noiseBefore[21+0] = noiseBefore[3]; noiseBefore[21+1] = noiseBefore[7+3]; noiseBefore[21+2] = noiseBefore[14+3];
441 noiseBefore[28+0] = noiseBefore[4]; noiseBefore[28+1] = noiseBefore[7+4]; noiseBefore[28+2] = noiseBefore[14+4]; noiseBefore[28+3] = noiseBefore[21+4];
442 noiseBefore[35+0] = noiseBefore[5]; noiseBefore[35+1] = noiseBefore[7+5]; noiseBefore[35+2] = noiseBefore[14+5]; noiseBefore[35+3] = noiseBefore[21+5]; noiseBefore[35+4] = noiseBefore[28+5];
446 double noiseAfter[7*7];
447 memset(noiseAfter,0x00,7*7*
sizeof(
double));
451 if (fabs((*directionAfter)[1]) < 1E-14) {
452 if ((*directionAfter)[0] >= 0.) psi =
M_PI / 2.;
453 else psi = 3.*
M_PI / 2.;
455 if ((*directionAfter)[1] > 0.) psi =
M_PI - atan((*directionAfter)[0] / (*directionAfter)[1]);
456 else psi = -atan((*directionAfter)[0] / (*directionAfter)[1]);
459 sintheta = sqrt(1 - (*directionAfter)[2] * (*directionAfter)[2]);
460 costheta = (*directionAfter)[2];
465 noiseAfter[3*7+3] = sigma2 * (cospsi * cospsi + costheta * costheta - costheta * costheta * cospsi * cospsi);
466 noiseAfter[3*7+4] = sigma2 * cospsi * sinpsi * sintheta * sintheta;
467 noiseAfter[3*7+5] = -sigma2 * costheta * sinpsi * sintheta;
469 noiseAfter[4*7+3] = noiseAfter[3*7+4];
470 noiseAfter[4*7+4] = sigma2 * (sinpsi * sinpsi + costheta * costheta * cospsi * cospsi);
471 noiseAfter[4*7+5] = sigma2 * costheta * cospsi * sintheta;
473 noiseAfter[5*7+3] = noiseAfter[3*7+5];
474 noiseAfter[5*7+4] = noiseAfter[4*7+5];
475 noiseAfter[5*7+5] = sigma2 * sintheta * sintheta;
478 for (
unsigned int i=0; i<7*7; ++i){
479 noise[i] += 0.5 * (noiseBefore[i]+noiseAfter[i]);
488 if (fabs(
fpdg) != 11)
return 0;
491 static const double C[101] = { 0.0, -0.960613E-01, 0.631029E-01, -0.142819E-01, 0.150437E-02, -0.733286E-04, 0.131404E-05, 0.859343E-01, -0.529023E-01, 0.131899E-01, -0.159201E-02, 0.926958E-04, -0.208439E-05, -0.684096E+01, 0.370364E+01, -0.786752E+00, 0.822670E-01, -0.424710E-02, 0.867980E-04, -0.200856E+01, 0.129573E+01, -0.306533E+00, 0.343682E-01, -0.185931E-02, 0.392432E-04, 0.127538E+01, -0.515705E+00, 0.820644E-01, -0.641997E-02, 0.245913E-03, -0.365789E-05, 0.115792E+00, -0.463143E-01, 0.725442E-02, -0.556266E-03, 0.208049E-04, -0.300895E-06, -0.271082E-01, 0.173949E-01, -0.452531E-02, 0.569405E-03, -0.344856E-04, 0.803964E-06, 0.419855E-02, -0.277188E-02, 0.737658E-03, -0.939463E-04, 0.569748E-05, -0.131737E-06, -0.318752E-03, 0.215144E-03, -0.579787E-04, 0.737972E-05, -0.441485E-06, 0.994726E-08, 0.938233E-05, -0.651642E-05, 0.177303E-05, -0.224680E-06, 0.132080E-07, -0.288593E-09, -0.245667E-03, 0.833406E-04, -0.129217E-04, 0.915099E-06, -0.247179E-07, 0.147696E-03, -0.498793E-04, 0.402375E-05, 0.989281E-07, -0.133378E-07, -0.737702E-02, 0.333057E-02, -0.553141E-03, 0.402464E-04, -0.107977E-05, -0.641533E-02, 0.290113E-02, -0.477641E-03, 0.342008E-04, -0.900582E-06, 0.574303E-05, 0.908521E-04, -0.256900E-04, 0.239921E-05, -0.741271E-07, -0.341260E-04, 0.971711E-05, -0.172031E-06, -0.119455E-06, 0.704166E-08, 0.341740E-05, -0.775867E-06, -0.653231E-07, 0.225605E-07, -0.114860E-08, -0.119391E-06, 0.194885E-07, 0.588959E-08, -0.127589E-08, 0.608247E-10};
492 static const double xi = 2.51, beta = 0.99, vl = 0.00004;
494 #if defined(BETHE) // no MIGDAL corrections
495 static const double C[101] = { 0.0, 0.834459E-02, 0.443979E-02, -0.101420E-02, 0.963240E-04, -0.409769E-05, 0.642589E-07, 0.464473E-02, -0.290378E-02, 0.547457E-03, -0.426949E-04, 0.137760E-05, -0.131050E-07, -0.547866E-02, 0.156218E-02, -0.167352E-03, 0.101026E-04, -0.427518E-06, 0.949555E-08, -0.406862E-02, 0.208317E-02, -0.374766E-03, 0.317610E-04, -0.130533E-05, 0.211051E-07, 0.158941E-02, -0.385362E-03, 0.315564E-04, -0.734968E-06, -0.230387E-07, 0.971174E-09, 0.467219E-03, -0.154047E-03, 0.202400E-04, -0.132438E-05, 0.431474E-07, -0.559750E-09, -0.220958E-02, 0.100698E-02, -0.596464E-04, -0.124653E-04, 0.142999E-05, -0.394378E-07, 0.477447E-03, -0.184952E-03, -0.152614E-04, 0.848418E-05, -0.736136E-06, 0.190192E-07, -0.552930E-04, 0.209858E-04, 0.290001E-05, -0.133254E-05, 0.116971E-06, -0.309716E-08, 0.212117E-05, -0.103884E-05, -0.110912E-06, 0.655143E-07, -0.613013E-08, 0.169207E-09, 0.301125E-04, -0.461920E-04, 0.871485E-05, -0.622331E-06, 0.151800E-07, -0.478023E-04, 0.247530E-04, -0.381763E-05, 0.232819E-06, -0.494487E-08, -0.336230E-04, 0.223822E-04, -0.384583E-05, 0.252867E-06, -0.572599E-08, 0.105335E-04, -0.567074E-06, -0.216564E-06, 0.237268E-07, -0.658131E-09, 0.282025E-05, -0.671965E-06, 0.565858E-07, -0.193843E-08, 0.211839E-10, 0.157544E-04, -0.304104E-05, -0.624410E-06, 0.120124E-06, -0.457445E-08, -0.188222E-05, -0.407118E-06, 0.375106E-06, -0.466881E-07, 0.158312E-08, 0.945037E-07, 0.564718E-07, -0.319231E-07, 0.371926E-08, -0.123111E-09};
496 static const double xi = 2.10,
fbeta = 1.00, vl = 0.001;
499 double BCUT = 10000.;
501 double THIGH = 100., CHIGH = 50.;
502 double dedxBrems = 0.;
507 if (BCUT >= mom) BCUT =
mom;
513 if (BCUT >= THIGH) kc = CHIGH;
521 if (BCUT > T) kc =
T;
523 double X = log(T / me);
524 double Y = log(kc / (E * vl));
528 double S = 0., YY = 1.;
530 for (
unsigned int I = 1;
I <= 2; ++
I) {
532 for (
unsigned int J = 1; J <= 6; ++J) {
534 S = S + C[K] * XX * YY;
540 for (
unsigned int I = 3;
I <= 6; ++
I) {
542 for (
unsigned int J = 1; J <= 6; ++J) {
544 if (Y <= 0.) S = S + C[K] * XX * YY;
545 else S = S + C[K + 24] * XX * YY;
554 for (
unsigned int I = 1;
I <= 2; ++
I) {
556 for (
unsigned int J = 1; J <= 5; ++J) {
558 SS = SS + C[K] * XX * YY;
564 for (
unsigned int I = 3;
I <= 5; ++
I) {
566 for (
unsigned int J = 1; J <= 5; ++J) {
568 if (Y <= 0.) SS = SS + C[K] * XX * YY;
569 else SS = SS + C[K + 15] * XX * YY;
583 double FAC =
fmatZ * (
fmatZ + xi) * E * E * pow((kc * CORR / T), beta) / (E + me);
584 if (FAC <= 0.)
return 0.;
592 S = (1. - 0.5 * RAT + 2.*RAT * RAT / 9.);
594 S = S / (1. - 0.5 * RAT + 2.*RAT * RAT / 9.);
597 S = BCUT * (1. - 0.5 * RAT + 2.*RAT * RAT / 9.);
599 S = S / (kc * (1. - 0.5 * RAT + 2.*RAT * RAT / 9.));
601 dedxBrems = dedxBrems * S;
608 if (dedxBrems < 0.) dedxBrems = 0;
613 static const double AA = 7522100., A1 = 0.415, A3 = 0.0021, A5 = 0.00054;
619 if (X >= +9.) ETA = 1.;
621 double W = A1 * X + A3 * pow(X, 3.) + A5 * pow(X, 5.);
622 ETA = 0.5 + atan(W) /
M_PI;
629 if (ETA < 0.0001) factor = 1.E-10;
630 else if (ETA > 0.9999) factor = 1.;
633 if (E0 > 1.) E0 = 1.;
634 if (E0 < 1.E-8) factor = 1.;
635 else factor = ETA * (1. - pow(1. - E0, 1. / ETA)) / E0;
639 double DE = fabs(
fstep) * factor * dedxBrems;
640 double momLoss = sqrt(mom * mom + 2.*sqrt(mom * mom +
fmass *
fmass) * DE + DE * DE) -
mom;
650 if (fabs(
fpdg) != 11)
return;
653 double S2B = mom * mom * (1. / pow(3., LX) - 1. / pow(4., LX));
654 double DEDXB = pow(fabs(S2B), 0.5);
655 DEDXB = 1.2E9 * DEDXB;
656 double sigma2E = DEDXB * DEDXB;
659 noise[6*7+6] += (mom * mom +
fmass *
fmass) / pow(mom, 6.) * sigma2E;
673 const
float MeanExcEnergy_vals[] = {1.e15, 19.2, 41.8, 40.0, 63.7, 76.0, 78., 82.0, 95.0, 115.0, 137.0, 149.0, 156.0, 166.0, 173.0, 173.0, 180.0, 174.0, 188.0, 190.0, 191.0, 216.0, 233.0, 245.0, 257.0, 272.0, 286.0, 297.0, 311.0, 322.0, 330.0, 334.0, 350.0, 347.0, 348.0, 343.0, 352.0, 363.0, 366.0, 379.0, 393.0, 417.0, 424.0, 428.0, 441.0, 449.0, 470.0, 470.0, 469.0, 488.0, 488.0, 487.0, 485.0, 491.0, 482.0, 488.0, 491.0, 501.0, 523.0, 535.0, 546.0, 560.0, 574.0, 580.0, 591.0, 614.0, 628.0, 650.0, 658.0, 674.0, 684.0, 694.0, 705.0, 718.0, 727.0, 736.0, 746.0, 757.0, 790.0, 790.0, 800.0, 810.0, 823.0, 823.0, 830.0, 825.0, 794.0, 827.0, 826.0, 841.0, 847.0, 878.0, 890.0};
683 if (mat->IsMixture()) {
686 TGeoMixture* mix = (TGeoMixture*)mat;
687 for (
int i = 0; i < mix->GetNelements(); ++i) {
688 int index = int(floor((mix->GetZmixt())[i]));
689 logMEE += 1. / (mix->GetAmixt())[i] * (mix->GetWmixt())[i] * (mix->GetZmixt())[i] * log(
MeanExcEnergy_get(index));
690 denom += (mix->GetWmixt())[i] * (mix->GetZmixt())[i] * 1. / (mix->GetAmixt())[i];
695 int index = int(floor(mat->GetZ()));