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"
57 fEnergyLossBetheBloch(
true), fNoiseBetheBloch(
true),
59 fEnergyLossBrems(
true), fNoiseBrems(
true),
82 if(finstance != NULL) {
89 const std::vector<double>& pointPaths,
93 TMatrixT<Double_t>* noise,
94 const TMatrixT<Double_t>* jacobian,
95 const TVector3* directionBefore,
96 const TVector3* directionAfter){
103 for(
unsigned int i=1;i<points.size();++i){
107 TVector3
dir=points.at(i)-points.at(i-1);
108 double dist=dir.Mag();
109 double realPath = pointPaths.at(i);
120 gGeoManager->InitTrack(points.at(i-1).X(),points.at(i-1).Y(),points.at(i-1).Z(),
121 dir.X(),dir.Y(),dir.Z());
129 gGeoManager->FindNextBoundaryAndStep(dist-X);
130 fstep = gGeoManager->GetStep();
153 if (fEnergyLossBetheBloch)
154 momLoss += realPath/dist * this->energyLossBetheBloch(mom);
155 if (doNoise && fEnergyLossBetheBloch && fNoiseBetheBloch)
156 this->noiseBetheBloch(mom, noise);
159 this->noiseCoulomb(mom, noise, jacobian, directionBefore, directionAfter);
161 if (fEnergyLossBrems)
162 momLoss += realPath/dist * this->energyLossBrems(mom);
163 if (doNoise && fEnergyLossBrems && fNoiseBrems)
164 this->noiseBrems(mom, noise);
193 static const double maxPloss = .005;
195 gGeoManager->InitTrack(posx,posy,posz,dirx,diry,dirz);
209 gGeoManager->FindNextBoundaryAndStep(maxDist-X);
210 fstep = gGeoManager->GetStep();
231 if (fEnergyLossBetheBloch)
232 momLoss += this->energyLossBetheBloch(mom);
234 if (fEnergyLossBrems)
235 momLoss += this->energyLossBrems(mom);
239 if(dP + momLoss > mom*maxPloss){
240 double fraction = (mom*maxPloss-dP)/momLoss;
241 if ((fraction <= 0.) || (fraction >= 1.))
242 throw GFException(std::string(__func__) +
": invalid fraction", __LINE__, __FILE__).setFatal();
243 dP+=fraction*momLoss;
256 if (!gGeoManager->GetCurrentVolume()->GetMedium())
257 throw GFException(std::string(__func__) +
": no medium", __LINE__, __FILE__).setFatal();
258 TGeoMaterial * mat = gGeoManager->GetCurrentVolume()->GetMedium()->GetMaterial();
259 fmatDensity = mat->GetDensity();
262 fradiationLength = mat->GetRadLen();
267 fmatDensity = 1.40; fmatZ = 18.0; fmatA = 39.95; fradiationLength=13.947; fmEE=188.0;
270 TParticlePDG * part = TDatabasePDG::Instance()->GetParticle(fpdg);
271 fcharge = part->Charge()/(3.);
272 fmass = part->Mass();
277 fbeta = mom/sqrt(fmass*fmass+mom*mom);
280 fgammaSquare = 1.-fbeta*fbeta;
281 if(fgammaSquare>1.
E-10) fgammaSquare = 1./fgammaSquare;
282 else fgammaSquare = 1.E10;
283 fgamma = sqrt(fgammaSquare);
293 fdedx = 0.307075*fmatZ/fmatA*fmatDensity/(fbeta*fbeta)*fcharge*fcharge;
294 double massRatio = me/fmass;
296 double argument = fgammaSquare*fbeta*fbeta*me*1.E3*2./((1.E-6*fmEE) * sqrt(1+2*sqrt(fgammaSquare)*massRatio + massRatio*massRatio));
298 if (fmass==0.0)
return(0.0);
299 if (argument <=
exp(fbeta*fbeta))
311 fdedx *= (log(argument)-fbeta*fbeta);
313 if (fdedx<0.) fdedx = 0;
316 double DE = fstep * fdedx;
317 double momLoss = sqrt(mom*mom+2.*sqrt(mom*mom+fmass*fmass)*DE+DE*DE) - mom;
320 if(fabs(momLoss)<1.
E-11)momLoss=1.E-11;
328 TMatrixT<double>* noise)
const{
333 double zeta = 153.4E3 * fcharge*fcharge/(fbeta*fbeta) * fmatZ/fmatA * fmatDensity * fstep;
334 double Emax = 2.E9*me*fbeta*fbeta*fgammaSquare / (1. + 2.*fgamma*me/fmass + (me/fmass)*(me/fmass) );
335 double kappa = zeta/Emax;
338 sigma2E += zeta*Emax*(1.-fbeta*fbeta/2.);
341 double alpha = 0.996;
342 double sigmaalpha = 15.76;
344 double I = 16. * pow(fmatZ, 0.9);
346 if (fmatZ > 2.) f2 = 2./fmatZ;
348 double e2 = 10.*fmatZ*fmatZ;
349 double e1 = pow( (I/pow(e2,f2)), 1./f1);
351 double mbbgg2 = 2.E9*fmass*fbeta*fbeta*fgammaSquare;
352 double Sigma1 = fdedx*1.0E9 * f1/e1 * (log(mbbgg2 / e1) - fbeta*fbeta) / (log(mbbgg2 / I) - fbeta*fbeta) * 0.6;
353 double Sigma2 = fdedx*1.0E9 * f2/e2 * (log(mbbgg2 / e2) - fbeta*fbeta) / (log(mbbgg2 / I) - fbeta*fbeta) * 0.6;
354 double Sigma3 = fdedx*1.0E9 * Emax / ( I*(Emax+
I)*log((Emax+I)/
I) ) * 0.4;
356 double Nc = (Sigma1 + Sigma2 + Sigma3)*fstep;
360 double RLAMED = -0.422784 - fbeta*fbeta - log(zeta/Emax);
361 double RLAMAX = 0.60715 + 1.1934*RLAMED +(0.67794 + 0.052382*RLAMED)*
exp(0.94753+0.74442*RLAMED);
363 if(RLAMAX <= 1010.) {
364 sigmaalpha = 1.975560
365 +9.898841e-02 *RLAMAX
366 -2.828670e-04 *RLAMAX*RLAMAX
367 +5.345406e-07 *pow(RLAMAX,3.)
368 -4.942035e-10 *pow(RLAMAX,4.)
369 +1.729807e-13 *pow(RLAMAX,5.);
371 else { sigmaalpha = 1.871887E+01 + 1.296254E-02 *RLAMAX; }
373 if(sigmaalpha > 54.6) sigmaalpha=54.6;
374 sigma2E += sigmaalpha*sigmaalpha * zeta*zeta;
377 double Ealpha = I / (1.-(alpha*Emax/(Emax+
I)));
378 double meanE32 = I*(Emax+
I)/Emax * (Ealpha-I);
379 sigma2E += fstep * (Sigma1*e1*e1 + Sigma2*e2*e2 + Sigma3*meanE32);
386 (*noise)[6][6] += (mom*mom+fmass*fmass)/pow(mom,6.)*sigma2E;
391 TMatrixT<double>* noise,
392 const TMatrixT<double>* jacobian,
393 const TVector3* directionBefore,
394 const TVector3* directionAfter)
const{
398 double sigma2 = 225.E-6/(fbeta*fbeta*mom*mom) * fstep/fradiationLength * fmatZ/(fmatZ+1) * log(159.*pow(fmatZ,-1./3.))/log(287.*pow(fmatZ,-0.5));
401 TMatrixT<double> noiseBefore(7,7);
405 if (fabs((*directionBefore)[1]) < 1
E-14) {
406 if ((*directionBefore)[0] >= 0.) psi = M_PI/2.;
407 else psi = 3.*M_PI/2.;
410 if ((*directionBefore)[1] > 0.) psi = M_PI - atan((*directionBefore)[0]/(*directionBefore)[1]);
411 else psi = -atan((*directionBefore)[0]/(*directionBefore)[1]);
414 double sintheta = sqrt(1-(*directionBefore)[2]*(*directionBefore)[2]);
415 double costheta = (*directionBefore)[2];
416 double sinpsi = sin(psi);
417 double cospsi = cos(psi);
420 double noiseBefore34 = sigma2 * cospsi * sinpsi * sintheta*sintheta;
421 double noiseBefore35 = -sigma2 * costheta * sinpsi * sintheta;
422 double noiseBefore45 = sigma2 * costheta * cospsi * sintheta;
424 noiseBefore[3][3] = sigma2 * (cospsi*cospsi + costheta*costheta - costheta*costheta * cospsi*cospsi);
425 noiseBefore[4][3] = noiseBefore34;
426 noiseBefore[5][3] = noiseBefore35;
428 noiseBefore[3][4] = noiseBefore34;
429 noiseBefore[4][4] = sigma2 * (sinpsi*sinpsi + costheta*costheta * cospsi*cospsi);
430 noiseBefore[5][4] = noiseBefore45;
432 noiseBefore[3][5] = noiseBefore35;
433 noiseBefore[4][5] = noiseBefore45;
434 noiseBefore[5][5] = sigma2 * sintheta*sintheta;
436 TMatrixT<double> jacobianT(7,7);
437 jacobianT = (*jacobian);
440 noiseBefore = jacobianT*noiseBefore*(*jacobian);
443 TMatrixT<double> noiseAfter(7,7);
447 if (fabs((*directionAfter)[1]) < 1
E-14) {
448 if ((*directionAfter)[0] >= 0.) psi = M_PI/2.;
449 else psi = 3.*M_PI/2.;
452 if ((*directionAfter)[1] > 0.) psi = M_PI - atan((*directionAfter)[0]/(*directionAfter)[1]);
453 else psi = -atan((*directionAfter)[0]/(*directionAfter)[1]);
456 sintheta = sqrt(1-(*directionAfter)[2]*(*directionAfter)[2]);
457 costheta = (*directionAfter)[2];
462 double noiseAfter34 = sigma2 * cospsi * sinpsi * sintheta*sintheta;
463 double noiseAfter35 = -sigma2 * costheta * sinpsi * sintheta;
464 double noiseAfter45 = sigma2 * costheta * cospsi * sintheta;
466 noiseAfter[3][3] = sigma2 * (cospsi*cospsi + costheta*costheta - costheta*costheta * cospsi*cospsi);
467 noiseAfter[4][3] = noiseAfter34;
468 noiseAfter[5][3] = noiseAfter35;
470 noiseAfter[3][4] = noiseAfter34;
471 noiseAfter[4][4] = sigma2 * (sinpsi*sinpsi + costheta*costheta * cospsi*cospsi);
472 noiseAfter[5][4] = noiseAfter45;
474 noiseAfter[3][5] = noiseAfter35;
475 noiseAfter[4][5] = noiseAfter45;
476 noiseAfter[5][5] = sigma2 * sintheta*sintheta;
479 (*noise) += 0.5*noiseBefore + 0.5*noiseAfter;
486 if (fabs(fpdg)!=11)
return 0;
489 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};
490 static const double xi=2.51, beta=0.99, vl=0.00004;
492 #if defined(BETHE) // no MIGDAL corrections
493 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};
494 static const double xi=2.10, fbeta=1.00, vl=0.001;
499 double THIGH=100., CHIGH=50.;
505 if(BCUT>=mom) BCUT=mom;
511 if(BCUT>=THIGH) kc=CHIGH;
523 double Y=log(kc/(E*vl));
529 for (
unsigned int I=1;
I<=2; ++
I) {
531 for (
unsigned int J=1; J<=6; ++J) {
539 for (
unsigned int I=3;
I<=6; ++
I) {
541 for (
unsigned int J=1; J<=6; ++J) {
543 if(Y<=0.) S=S+C[K]*XX*YY;
544 else S=S+C[K+24]*XX*YY;
553 for (
unsigned int I=1;
I<=2; ++
I) {
555 for (
unsigned int J=1; J<=5; ++J) {
563 for (
unsigned int I=3;
I<=5; ++
I) {
565 for (
unsigned int J=1; J<=5; ++J) {
567 if(Y<=0.) SS=SS+C[K]*XX*YY;
568 else SS=SS+C[K+15]*XX*YY;
579 CORR=1./(1.+0.805485E-10*fmatDensity*fmatZ*E*E/(fmatA*kc*
kc));
582 double FAC=fmatZ*(fmatZ+xi)*E*E * pow((kc*CORR/T),beta) / (E+me);
583 if(FAC<=0.)
return 0.;
591 S=(1.-0.5*RAT+2.*RAT*RAT/9.);
593 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;
604 dedxBrems = 0.60221367*fmatDensity*dedxBrems/fmatA;
608 if (dedxBrems<0.) dedxBrems = 0;
613 static const double AA=7522100., A1=0.415, A3=0.0021, A5=0.00054;
617 double X=log(AA*mom/fmatZ*fmatZ);
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.;
634 if(E0<1.
E-8) factor=1.;
635 else factor = ETA * ( 1.-pow(1.-E0, 1./ETA) ) / E0;
639 double DE = fstep * factor*dedxBrems;
640 double momLoss = sqrt(mom*mom+2.*sqrt(mom*mom+fmass*fmass)*DE+DE*DE) - mom;
647 TMatrixT<double>* noise)
const{
649 if (fabs(fpdg)!=11)
return;
651 double LX = 1.442695*fstep/fradiationLength;
652 double S2B = mom*mom * ( 1./pow(3.,LX) - 1./pow(4.,LX) );
653 double DEDXB = pow(fabs(S2B),0.5);
655 double sigma2E = DEDXB*DEDXB;
658 (*noise)[6][6] += (mom*mom+fmass*fmass)/pow(mom,6.)*sigma2E;
668 const float MeanExcEnergy_vals[
MeanExcEnergy_NELEMENTS] = {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};
672 throw GFException(std::string(__func__) +
": unsupported Z", __LINE__, __FILE__).
setFatal();
677 if(mat->IsMixture()){
680 TGeoMixture *mix = (TGeoMixture*)mat;
681 for(
int i=0;i<mix->GetNelements();++i){
682 int index = int(floor((mix->GetZmixt())[i]));
683 logMEE += 1./(mix->GetAmixt())[i]*(mix->GetWmixt())[i]*(mix->GetZmixt())[i]*log(
MeanExcEnergy_get(index));
684 denom += (mix->GetWmixt())[i]*(mix->GetZmixt())[i]*1./(mix->GetAmixt())[i];
690 int index = int(floor(mat->GetZ()));
see a below echo or echo I(indirect symbol).'echo" If the symbol is local (non-external)
float MeanExcEnergy_get(int Z)
see a below echo S(symbol in a section other than those above)
static GFMaterialEffects * getInstance()
void noiseBrems(const double &mom, TMatrixT< double > *noise) const
calculation of energy loss straggeling
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
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
const float MeanExcEnergy_vals[MeanExcEnergy_NELEMENTS]
constexpr double kc
Speed of light in vacuum in LArSoft units [cm/ns].
double MeanExcEnergy_get(int Z)
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.
void getParameters()
contains energy loss classes
const int MeanExcEnergy_NELEMENTS
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true
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.