26 #include "TDatabasePDG.h" 27 #include "TGeoManager.h" 28 #include "TGeoMaterial.h" 29 #include "TGeoMedium.h" 30 #include "TGeoVolume.h" 32 #include "TMatrixTBase.h" 33 #include "TMatrixTUtils.h" 34 #include "TParticlePDG.h" 92 const std::vector<double>& pointPaths,
96 TMatrixT<Double_t>*
noise,
97 const TMatrixT<Double_t>* jacobian,
98 const TVector3* directionBefore,
99 const TVector3* directionAfter)
107 for (
unsigned int i = 1; i < points.size(); ++i) {
111 TVector3
dir = points.at(i) - points.at(i - 1);
112 double dist = dir.Mag();
113 double realPath = pointPaths.at(i);
124 gGeoManager->InitTrack(points.at(i - 1).X(),
125 points.at(i - 1).Y(),
126 points.at(i - 1).Z(),
137 gGeoManager->FindNextBoundaryAndStep(dist - X);
138 fstep = gGeoManager->GetStep();
166 this->
noiseCoulomb(mom, noise, jacobian, directionBefore, directionAfter);
191 static const double maxPloss = .005;
193 gGeoManager->InitTrack(posx, posy, posz, dirx, diry, dirz);
203 while (X < maxDist) {
207 gGeoManager->FindNextBoundaryAndStep(maxDist - X);
208 fstep = gGeoManager->GetStep();
234 if (dP + momLoss > mom * maxPloss) {
235 double fraction = (mom * maxPloss - dP) / momLoss;
236 if ((fraction <= 0.) || (fraction >= 1.))
237 throw GFException(std::string(__func__) +
": invalid fraction", __LINE__, __FILE__)
239 dP += fraction * momLoss;
240 X += fraction *
fstep;
253 if (!gGeoManager->GetCurrentVolume()->GetMedium())
254 throw GFException(std::string(__func__) +
": no medium", __LINE__, __FILE__).setFatal();
255 TGeoMaterial*
mat = gGeoManager->GetCurrentVolume()->GetMedium()->GetMaterial();
270 TParticlePDG*
part = TDatabasePDG::Instance()->GetParticle(
fpdg);
271 fcharge = part->Charge() / (3.);
272 fmass = part->Mass();
299 ((1.E-6 *
fmEE) * sqrt(1 + 2 * sqrt(
fgammaSquare) * massRatio + massRatio * massRatio));
301 if (
fmass == 0.0)
return (0.0);
320 sqrt(mom * mom + 2. * sqrt(mom * mom +
fmass *
fmass) * DE + DE * DE) - mom;
323 if (fabs(momLoss) < 1.
E-11) momLoss = 1.E-11;
338 double kappa = zeta / Emax;
341 sigma2E += zeta * Emax * (1. -
fbeta *
fbeta / 2.);
344 double alpha = 0.996;
345 double sigmaalpha = 15.76;
347 double I = 16. * pow(
fmatZ, 0.9);
352 double e1 = pow((I / pow(e2, f2)), 1. / f1);
355 double Sigma1 =
fdedx * 1.0E9 * f1 / e1 * (log(mbbgg2 / e1) -
fbeta *
fbeta) /
357 double Sigma2 =
fdedx * 1.0E9 * f2 / e2 * (log(mbbgg2 / e2) -
fbeta *
fbeta) /
359 double Sigma3 =
fdedx * 1.0E9 * Emax / (I * (Emax + I) * log((Emax + I) / I)) * 0.4;
361 double Nc = (Sigma1 + Sigma2 + Sigma3) *
fstep;
365 double RLAMED = -0.422784 -
fbeta *
fbeta - log(zeta / Emax);
367 0.60715 + 1.1934 * RLAMED + (0.67794 + 0.052382 * RLAMED) * exp(0.94753 + 0.74442 * RLAMED);
369 if (RLAMAX <= 1010.) {
370 sigmaalpha = 1.975560 + 9.898841e-02 * RLAMAX - 2.828670e-04 * RLAMAX * RLAMAX +
371 5.345406e-07 * pow(RLAMAX, 3.) - 4.942035e-10 * pow(RLAMAX, 4.) +
372 1.729807e-13 * pow(RLAMAX, 5.);
375 sigmaalpha = 1.871887E+01 + 1.296254E-02 * RLAMAX;
378 if (sigmaalpha > 54.6) sigmaalpha = 54.6;
379 sigma2E += sigmaalpha * sigmaalpha * zeta * zeta;
382 double Ealpha = I / (1. - (alpha * Emax / (Emax + I)));
383 double meanE32 = I * (Emax + I) / Emax * (Ealpha - I);
384 sigma2E +=
fstep * (Sigma1 * e1 * e1 + Sigma2 * e2 * e2 + Sigma3 * meanE32);
391 (*noise)[6][6] += (mom * mom +
fmass *
fmass) / pow(mom, 6.) * sigma2E;
395 TMatrixT<double>*
noise,
396 const TMatrixT<double>* jacobian,
397 const TVector3* directionBefore,
398 const TVector3* directionAfter)
const 405 log(159. * pow(
fmatZ, -1. / 3.)) /
413 TMatrixT<double> noiseBefore(7, 7);
417 if (fabs((*directionBefore)[1]) < 1
E-14) {
418 if ((*directionBefore)[0] >= 0.)
421 psi = 3. * M_PI / 2.;
424 if ((*directionBefore)[1] > 0.)
425 psi = M_PI - atan((*directionBefore)[0] / (*directionBefore)[1]);
427 psi = -atan((*directionBefore)[0] / (*directionBefore)[1]);
431 sqrt(1 - (*directionBefore)[2] * (*directionBefore)[2]);
432 double costheta = (*directionBefore)[2];
433 double sinpsi = sin(psi);
434 double cospsi = cos(psi);
437 double noiseBefore34 =
438 sigma2 * cospsi * sinpsi * sintheta * sintheta;
439 double noiseBefore35 = -sigma2 * costheta * sinpsi * sintheta;
440 double noiseBefore45 = sigma2 * costheta * cospsi * sintheta;
443 sigma2 * (cospsi * cospsi + costheta * costheta - costheta * costheta * cospsi * cospsi);
444 noiseBefore[4][3] = noiseBefore34;
445 noiseBefore[5][3] = noiseBefore35;
447 noiseBefore[3][4] = noiseBefore34;
448 noiseBefore[4][4] = sigma2 * (sinpsi * sinpsi + costheta * costheta * cospsi * cospsi);
449 noiseBefore[5][4] = noiseBefore45;
451 noiseBefore[3][5] = noiseBefore35;
452 noiseBefore[4][5] = noiseBefore45;
453 noiseBefore[5][5] = sigma2 * sintheta * sintheta;
455 TMatrixT<double> jacobianT(7, 7);
456 jacobianT = (*jacobian);
459 noiseBefore = jacobianT * noiseBefore * (*jacobian);
462 TMatrixT<double> noiseAfter(7, 7);
466 if (fabs((*directionAfter)[1]) < 1
E-14) {
467 if ((*directionAfter)[0] >= 0.)
470 psi = 3. * M_PI / 2.;
473 if ((*directionAfter)[1] > 0.)
474 psi = M_PI - atan((*directionAfter)[0] / (*directionAfter)[1]);
476 psi = -atan((*directionAfter)[0] / (*directionAfter)[1]);
480 sqrt(1 - (*directionAfter)[2] * (*directionAfter)[2]);
481 costheta = (*directionAfter)[2];
486 double noiseAfter34 =
487 sigma2 * cospsi * sinpsi * sintheta * sintheta;
488 double noiseAfter35 = -sigma2 * costheta * sinpsi * sintheta;
489 double noiseAfter45 = sigma2 * costheta * cospsi * sintheta;
492 sigma2 * (cospsi * cospsi + costheta * costheta - costheta * costheta * cospsi * cospsi);
493 noiseAfter[4][3] = noiseAfter34;
494 noiseAfter[5][3] = noiseAfter35;
496 noiseAfter[3][4] = noiseAfter34;
497 noiseAfter[4][4] = sigma2 * (sinpsi * sinpsi + costheta * costheta * cospsi * cospsi);
498 noiseAfter[5][4] = noiseAfter45;
500 noiseAfter[3][5] = noiseAfter35;
501 noiseAfter[4][5] = noiseAfter45;
502 noiseAfter[5][5] = sigma2 * sintheta * sintheta;
505 (*noise) += 0.5 * noiseBefore + 0.5 * noiseAfter;
511 if (fabs(
fpdg) != 11)
return 0;
514 static const double C[101] = {
515 0.0, -0.960613E-01, 0.631029E-01, -0.142819E-01, 0.150437E-02, -0.733286E-04,
516 0.131404E-05, 0.859343E-01, -0.529023E-01, 0.131899E-01, -0.159201E-02, 0.926958E-04,
517 -0.208439E-05, -0.684096E+01, 0.370364E+01, -0.786752E+00, 0.822670E-01, -0.424710E-02,
518 0.867980E-04, -0.200856E+01, 0.129573E+01, -0.306533E+00, 0.343682E-01, -0.185931E-02,
519 0.392432E-04, 0.127538E+01, -0.515705E+00, 0.820644E-01, -0.641997E-02, 0.245913E-03,
520 -0.365789E-05, 0.115792E+00, -0.463143E-01, 0.725442E-02, -0.556266E-03, 0.208049E-04,
521 -0.300895E-06, -0.271082E-01, 0.173949E-01, -0.452531E-02, 0.569405E-03, -0.344856E-04,
522 0.803964E-06, 0.419855E-02, -0.277188E-02, 0.737658E-03, -0.939463E-04, 0.569748E-05,
523 -0.131737E-06, -0.318752E-03, 0.215144E-03, -0.579787E-04, 0.737972E-05, -0.441485E-06,
524 0.994726E-08, 0.938233E-05, -0.651642E-05, 0.177303E-05, -0.224680E-06, 0.132080E-07,
525 -0.288593E-09, -0.245667E-03, 0.833406E-04, -0.129217E-04, 0.915099E-06, -0.247179E-07,
526 0.147696E-03, -0.498793E-04, 0.402375E-05, 0.989281E-07, -0.133378E-07, -0.737702E-02,
527 0.333057E-02, -0.553141E-03, 0.402464E-04, -0.107977E-05, -0.641533E-02, 0.290113E-02,
528 -0.477641E-03, 0.342008E-04, -0.900582E-06, 0.574303E-05, 0.908521E-04, -0.256900E-04,
529 0.239921E-05, -0.741271E-07, -0.341260E-04, 0.971711E-05, -0.172031E-06, -0.119455E-06,
530 0.704166E-08, 0.341740E-05, -0.775867E-06, -0.653231E-07, 0.225605E-07, -0.114860E-08,
531 -0.119391E-06, 0.194885E-07, 0.588959E-08, -0.127589E-08, 0.608247E-10};
532 static const double xi = 2.51, beta = 0.99, vl = 0.00004;
534 #if defined(BETHE) // no MIGDAL corrections 535 static const double C[101] = {
536 0.0, 0.834459E-02, 0.443979E-02, -0.101420E-02, 0.963240E-04, -0.409769E-05,
537 0.642589E-07, 0.464473E-02, -0.290378E-02, 0.547457E-03, -0.426949E-04, 0.137760E-05,
538 -0.131050E-07, -0.547866E-02, 0.156218E-02, -0.167352E-03, 0.101026E-04, -0.427518E-06,
539 0.949555E-08, -0.406862E-02, 0.208317E-02, -0.374766E-03, 0.317610E-04, -0.130533E-05,
540 0.211051E-07, 0.158941E-02, -0.385362E-03, 0.315564E-04, -0.734968E-06, -0.230387E-07,
541 0.971174E-09, 0.467219E-03, -0.154047E-03, 0.202400E-04, -0.132438E-05, 0.431474E-07,
542 -0.559750E-09, -0.220958E-02, 0.100698E-02, -0.596464E-04, -0.124653E-04, 0.142999E-05,
543 -0.394378E-07, 0.477447E-03, -0.184952E-03, -0.152614E-04, 0.848418E-05, -0.736136E-06,
544 0.190192E-07, -0.552930E-04, 0.209858E-04, 0.290001E-05, -0.133254E-05, 0.116971E-06,
545 -0.309716E-08, 0.212117E-05, -0.103884E-05, -0.110912E-06, 0.655143E-07, -0.613013E-08,
546 0.169207E-09, 0.301125E-04, -0.461920E-04, 0.871485E-05, -0.622331E-06, 0.151800E-07,
547 -0.478023E-04, 0.247530E-04, -0.381763E-05, 0.232819E-06, -0.494487E-08, -0.336230E-04,
548 0.223822E-04, -0.384583E-05, 0.252867E-06, -0.572599E-08, 0.105335E-04, -0.567074E-06,
549 -0.216564E-06, 0.237268E-07, -0.658131E-09, 0.282025E-05, -0.671965E-06, 0.565858E-07,
550 -0.193843E-08, 0.211839E-10, 0.157544E-04, -0.304104E-05, -0.624410E-06, 0.120124E-06,
551 -0.457445E-08, -0.188222E-05, -0.407118E-06, 0.375106E-06, -0.466881E-07, 0.158312E-08,
552 0.945037E-07, 0.564718E-07, -0.319231E-07, 0.371926E-08, -0.123111E-09};
553 static const double xi = 2.10,
fbeta = 1.00, vl = 0.001;
556 double BCUT = 10000.;
558 double THIGH = 100., CHIGH = 50.;
559 double dedxBrems = 0.;
564 if (BCUT >= mom) BCUT = mom;
581 if (BCUT > T) kc = T;
583 double X = log(T / me);
584 double Y = log(kc / (E * vl));
588 double S = 0., YY = 1.;
590 for (
unsigned int I = 1; I <= 2; ++I) {
592 for (
unsigned int J = 1; J <= 6; ++J) {
594 S = S + C[K] * XX * YY;
600 for (
unsigned int I = 3; I <= 6; ++I) {
602 for (
unsigned int J = 1; J <= 6; ++J) {
605 S = S + C[K] * XX * YY;
607 S = S + C[K + 24] * XX * YY;
616 for (
unsigned int I = 1; I <= 2; ++I) {
618 for (
unsigned int J = 1; J <= 5; ++J) {
620 SS = SS + C[K] * XX * YY;
626 for (
unsigned int I = 3; I <= 5; ++I) {
628 for (
unsigned int J = 1; J <= 5; ++J) {
631 SS = SS + C[K] * XX * YY;
633 SS = SS + C[K + 15] * XX * YY;
648 double FAC =
fmatZ * (
fmatZ + xi) * E * E * pow((kc * CORR / T), beta) / (E + me);
649 if (FAC <= 0.)
return 0.;
657 S = (1. - 0.5 * RAT + 2. * RAT * RAT / 9.);
659 S = S / (1. - 0.5 * RAT + 2. * RAT * RAT / 9.);
663 S = BCUT * (1. - 0.5 * RAT + 2. * RAT * RAT / 9.);
665 S = S / (kc * (1. - 0.5 * RAT + 2. * RAT * RAT / 9.));
667 dedxBrems = dedxBrems * S;
674 if (dedxBrems < 0.) dedxBrems = 0;
679 static const double AA = 7522100., A1 = 0.415, A3 = 0.0021, A5 = 0.00054;
688 double W = A1 * X + A3 * pow(X, 3.) + A5 * pow(X, 5.);
689 ETA = 0.5 + atan(W) / M_PI;
698 else if (ETA > 0.9999)
702 if (E0 > 1.) E0 = 1.;
706 factor = ETA * (1. - pow(1. - E0, 1. / ETA)) / E0;
710 double DE =
fstep * factor * dedxBrems;
712 sqrt(mom * mom + 2. * sqrt(mom * mom +
fmass *
fmass) * DE + DE * DE) - mom;
720 if (fabs(
fpdg) != 11)
return;
723 double S2B = mom * mom * (1. / pow(3., LX) - 1. / pow(4., LX));
724 double DEDXB = pow(fabs(S2B), 0.5);
725 DEDXB = 1.2E9 * DEDXB;
726 double sigma2E = DEDXB * DEDXB;
729 (*noise)[6][6] += (mom * mom +
fmass *
fmass) / pow(mom, 6.) * sigma2E;
739 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,
740 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,
741 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,
742 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,
743 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,
744 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,
745 830.0, 825.0, 794.0, 827.0, 826.0, 841.0, 847.0, 878.0, 890.0};
750 throw GFException(std::string(__func__) +
": unsupported Z", __LINE__, __FILE__).
setFatal();
756 if (mat->IsMixture()) {
759 TGeoMixture* mix = (TGeoMixture*)mat;
760 for (
int i = 0; i < mix->GetNelements(); ++i) {
761 int index = int(floor((mix->GetZmixt())[i]));
762 logMEE += 1. / (mix->GetAmixt())[i] * (mix->GetWmixt())[i] * (mix->GetZmixt())[i] *
764 denom += (mix->GetWmixt())[i] * (mix->GetZmixt())[i] * 1. / (mix->GetAmixt())[i];
770 int index = int(floor(mat->GetZ()));
static GFMaterialEffects * getInstance()
void noiseBrems(const double &mom, TMatrixT< double > *noise) const
calculation of energy loss straggeling
const int MeanExcEnergy_NELEMENTS
void noiseCoulomb(const double &mom, TMatrixT< double > *noise, const TMatrixT< double > *jacobian, const TVector3 *directionBefore, const TVector3 *directionAfter) const
calculation of multiple scattering
virtual ~GFMaterialEffects()
double energyLossBrems(const double &mom) const
Returns energy loss.
void noiseBetheBloch(const double &mom, TMatrixT< double > *noise) const
calculation of energy loss straggling
constexpr double kc
Speed of light in vacuum in LArSoft units [cm/ns].
double MeanExcEnergy_get(int Z)
const float MeanExcEnergy_vals[MeanExcEnergy_NELEMENTS]
static GFMaterialEffects * finstance
void calcBeta(double mom)
sets fbeta, fgamma, fgammasquare; must only be used after calling getParameters() ...
Exception class for error handling in GENFIT (provides storage for diagnostic information) ...
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
double effects(const std::vector< TVector3 > &points, const std::vector< double > &pointPaths, const double &mom, const int &pdg, const bool &doNoise=false, TMatrixT< Double_t > *noise=NULL, const TMatrixT< Double_t > *jacobian=NULL, const TVector3 *directionBefore=NULL, const TVector3 *directionAfter=NULL)
Calculates energy loss in the travelled path, optional calculation of noise matrix.
GFException & setFatal(bool b=true)
set fatal flag. if this is true, the fit stops for this current track repr.
bool fEnergyLossBetheBloch
void getParameters()
contains energy loss classes
double energyLossBetheBloch(const double &mom)
Returns energy loss.
double stepper(const double &maxDist, const double &posx, const double &posy, const double &posz, const double &dirx, const double &diry, const double &dirz, const double &mom, const int &pdg)
Returns maximum length so that a specified momentum loss will not be exceeded.