GFEnergyLossCoulomb.cxx
Go to the documentation of this file.
1 /* Copyright 2008-2009, Technische Universitaet Muenchen,
2  Authors: Christian Hoeppner & Sebastian Neubert
3 
4  This file is part of GENFIT.
5 
6  GENFIT is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  GENFIT is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
21 #include <string>
23 #include <math.h>
24 
26 }
27 
29  const double& mom,
30  const int& pdg,
31  const double& /* matDensity */,
32  const double& matZ,
33  const double& /* matA */,
34  const double& radiationLength,
35  const double& /* meanExcitationEnergy */,
36  const bool& doNoise,
37  TMatrixT<Double_t>* noise,
38  const TMatrixT<Double_t>* jacobian,
39  const TVector3* directionBefore,
40  const TVector3* directionAfter){
41 
42  double charge, mass;
43  getParticleParameters(pdg, charge, mass);
44 
45  const double beta = mom/sqrt(mass*mass+mom*mom);
46 
47  if (doNoise) {
48  if (!noise) throw GFException(std::string(__func__) + ": no noise given!", __LINE__, __FILE__).setFatal();
49  if (!jacobian) throw GFException(std::string(__func__) + ": no jacobian given!", __LINE__, __FILE__).setFatal();
50  if (!directionBefore) throw GFException(std::string(__func__) + ": no directionBefore given!", __LINE__, __FILE__).setFatal();
51  if (!directionAfter) throw GFException(std::string(__func__) + ": no directionAfter given!", __LINE__, __FILE__).setFatal();
52 
53  // MULTIPLE SCATTERING; calculate sigma^2
54  // PANDA report PV/01-07 eq(43); linear in step length
55  double sigma2 = 225.E-6/(beta*beta*mom*mom) * step/radiationLength * matZ/(matZ+1) * log(159.*pow(matZ,-1./3.))/log(287./sqrt(matZ)); // sigma^2 = 225E-6/mom^2 * XX0/beta^2 * Z/(Z+1) * ln(159*Z^(-1/3))/ln(287*Z^(-1/2)
56 
57 
58  // noiseBefore
59  TMatrixT<Double_t> noiseBefore(7,7);
60 
61  // calculate euler angles theta, psi (so that directionBefore' points in z' direction)
62  double psi = 0;
63  if (fabs((*directionBefore)[1]) < 1E-14) { // numerical case: arctan(+-inf)=+-PI/2
64  if ((*directionBefore)[0] >= 0.) psi = M_PI/2.;
65  else psi = 3.*M_PI/2.;
66  }
67  else {
68  if ((*directionBefore)[1] > 0.) psi = M_PI - atan((*directionBefore)[0]/(*directionBefore)[1]);
69  else psi = -atan((*directionBefore)[0]/(*directionBefore)[1]);
70  }
71  // cache sin and cos
72  double sintheta = sqrt(1-(*directionBefore)[2]*(*directionBefore)[2]); // theta = arccos(directionBefore[2])
73  double costheta = (*directionBefore)[2];
74  double sinpsi = sin(psi);
75  double cospsi = cos(psi);
76 
77  // calculate NoiseBefore Matrix R M R^T
78  double noiseBefore34 = sigma2 * cospsi * sinpsi * sintheta*sintheta; // noiseBefore_ij = noiseBefore_ji
79  double noiseBefore35 = -sigma2 * costheta * sinpsi * sintheta;
80  double noiseBefore45 = sigma2 * costheta * cospsi * sintheta;
81 
82  noiseBefore[3][3] = sigma2 * (cospsi*cospsi + costheta*costheta - costheta*costheta * cospsi*cospsi);
83  noiseBefore[4][3] = noiseBefore34;
84  noiseBefore[5][3] = noiseBefore35;
85 
86  noiseBefore[3][4] = noiseBefore34;
87  noiseBefore[4][4] = sigma2 * (sinpsi*sinpsi + costheta*costheta * cospsi*cospsi);
88  noiseBefore[5][4] = noiseBefore45;
89 
90  noiseBefore[3][5] = noiseBefore35;
91  noiseBefore[4][5] = noiseBefore45;
92  noiseBefore[5][5] = sigma2 * sintheta*sintheta;
93 
94  TMatrixT<Double_t> jacobianT(7,7);
95  jacobianT = (*jacobian);
96  jacobianT.T();
97 
98  noiseBefore = jacobianT*noiseBefore*(*jacobian); //propagate
99 
100  // noiseAfter
101  TMatrixT<Double_t> noiseAfter(7,7);
102 
103  // calculate euler angles theta, psi (so that A' points in z' direction)
104  psi = 0;
105  if (fabs((*directionAfter)[1]) < 1E-14) { // numerical case: arctan(+-inf)=+-PI/2
106  if ((*directionAfter)[0] >= 0.) psi = M_PI/2.;
107  else psi = 3.*M_PI/2.;
108  }
109  else {
110  if ((*directionAfter)[1] > 0.) psi = M_PI - atan((*directionAfter)[0]/(*directionAfter)[1]);
111  else psi = -atan((*directionAfter)[0]/(*directionAfter)[1]);
112  }
113  // cache sin and cos
114  sintheta = sqrt(1-(*directionAfter)[2]*(*directionAfter)[2]); // theta = arccos(directionAfter[2])
115  costheta = (*directionAfter)[2];
116  sinpsi = sin(psi);
117  cospsi = cos(psi);
118 
119  // calculate NoiseAfter Matrix R M R^T
120  double noiseAfter34 = sigma2 * cospsi * sinpsi * sintheta*sintheta; // noiseAfter_ij = noiseAfter_ji
121  double noiseAfter35 = -sigma2 * costheta * sinpsi * sintheta;
122  double noiseAfter45 = sigma2 * costheta * cospsi * sintheta;
123 
124  noiseAfter[3][3] = sigma2 * (cospsi*cospsi + costheta*costheta - costheta*costheta * cospsi*cospsi);
125  noiseAfter[4][3] = noiseAfter34;
126  noiseAfter[5][3] = noiseAfter35;
127 
128  noiseAfter[3][4] = noiseAfter34;
129  noiseAfter[4][4] = sigma2 * (sinpsi*sinpsi + costheta*costheta * cospsi*cospsi);
130  noiseAfter[5][4] = noiseAfter45;
131 
132  noiseAfter[3][5] = noiseAfter35;
133  noiseAfter[4][5] = noiseAfter45;
134  noiseAfter[5][5] = sigma2 * sintheta*sintheta;
135 
136  //calculate mean of noiseBefore and noiseAfter and update noise
137  (*noise) += 0.5*noiseBefore + 0.5*noiseAfter;
138  }
139 
140  return 0.;
141 }
142 
143 //ClassImp(GFEnergyLossCoulomb)
double beta(double KE, const simb::MCParticle *part)
std::string string
Definition: nybbler.cc:12
constexpr T pow(T x)
Definition: pow.h:72
double energyLoss(const double &step, const double &mom, const int &pdg, const double &matDensity, const double &matZ, const double &matA, const double &radiationLength, const double &meanExcitationEnergy, const bool &doNoise=false, TMatrixT< Double_t > *noise=NULL, const TMatrixT< Double_t > *jacobian=NULL, const TVector3 *directionBefore=NULL, const TVector3 *directionAfter=NULL)
Optional calculation of multiple scattering.
#define M_PI
Definition: includeROOT.h:54
void getParticleParameters(const int &pdg, double &charge, double &mass)
Gets particle charge and mass (in GeV)
Exception class for error handling in GENFIT (provides storage for diagnostic information) ...
Definition: GFException.h:48
GFException & setFatal(bool b=true)
set fatal flag. if this is true, the fit stops for this current track repr.
Definition: GFException.h:78