CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/TrackingTools/MaterialEffects/src/EnergyLossUpdator.cc

Go to the documentation of this file.
00001 #include "TrackingTools/MaterialEffects/interface/EnergyLossUpdator.h"
00002 #include "DataFormats/GeometrySurface/interface/MediumProperties.h"
00003 
00004 #include "DataFormats/Math/interface/approx_exp.h"
00005 #include "DataFormats/Math/interface/approx_log.h"
00006 
00007 
00008 
00009 void
00010 oldComputeBetheBloch (const LocalVector& localP,
00011                       const MediumProperties& materialConstants, double mass);
00012 void 
00013 oldComputeElectrons (const LocalVector& localP,
00014                      const MediumProperties& materialConstants,
00015                      const PropagationDirection propDir);
00016 
00017 //
00018 // Computation of contribution of energy loss to momentum and covariance
00019 // matrix of local parameters based on Bethe-Bloch. For electrons 
00020 // contribution of radiation acc. to Bethe & Heitler.
00021 //
00022 void EnergyLossUpdator::compute (const TrajectoryStateOnSurface& TSoS, 
00023                                  const PropagationDirection propDir, Effect & effect) const
00024 {
00025   //
00026   // Get surface
00027   //
00028   const Surface& surface = TSoS.surface();
00029   //
00030   //
00031   // Now get information on medium
00032   //
00033   if (surface.mediumProperties().isValid()) {
00034     //
00035     // Bethe-Bloch
00036     //
00037     if ( mass()>0.001 )
00038       computeBetheBloch(TSoS.localMomentum(),surface.mediumProperties(),effect);
00039     //
00040     // Special treatment for electrons (currently rather crude
00041     // distinction using mass)
00042     //
00043     else
00044       computeElectrons(TSoS.localMomentum(),surface.mediumProperties(),
00045                        propDir,effect);
00046     if (propDir != alongMomentum) effect.deltaP *= -1.;
00047   }
00048 }
00049 //
00050 // Computation of energy loss according to Bethe-Bloch
00051 //
00052 void
00053 EnergyLossUpdator::computeBetheBloch (const LocalVector& localP,
00054                                       const MediumProperties& materialConstants, Effect & effect) const {
00055   //
00056   // calculate absolute momentum and correction to path length from angle 
00057   // of incidence
00058   //
00059 
00060   typedef float Float;
00061 
00062   Float p2 = localP.mag2();
00063   Float xf = std::abs(std::sqrt(p2)/localP.z());
00064    
00065   // constants
00066   const Float m2 = mass()*mass();           // use mass hypothesis from constructor
00067 
00068   constexpr Float emass = 0.511e-3;
00069   constexpr Float poti = 16.e-9 * 10.75; // = 16 eV * Z**0.9, for Si Z=14
00070   const Float eplasma = 28.816e-9 * sqrt(2.33*0.498); // 28.816 eV * sqrt(rho*(Z/A)) for Si
00071   const Float delta0 = 2*log(eplasma/poti) - 1.;
00072 
00073   // calculate general physics things
00074   Float im2 = Float(1.)/m2;
00075   Float e2     = p2 + m2;
00076   Float e = std::sqrt(e2);
00077   Float beta2  = p2/e2;
00078   Float eta2  = p2*im2;
00079   Float ratio2 = (emass*emass)*im2;
00080   Float emax  = Float(2.)*emass*eta2/(Float(1.) + Float(2.)*emass*e*im2 + ratio2);
00081   
00082   Float xi = materialConstants.xi()*xf; xi /= beta2;
00083   
00084   Float dEdx = xi*(unsafe_logf<2>(Float(2.)*emass*emax/(poti*poti)) - Float(2.)*(beta2) - delta0);
00085   
00086   Float dEdx2 = xi*emax*(Float(1.)-Float(0.5)*beta2);
00087   Float dP    = dEdx/std::sqrt(beta2);
00088   Float sigp2 = dEdx2/(beta2*p2*p2);
00089   effect.deltaP += -dP;
00090   using namespace materialEffect;
00091   effect.deltaCov[elos] += sigp2;
00092 
00093 
00094   // std::cout << "pion new " <<  theDeltaP << " " << theDeltaCov(0,0) << std::endl;
00095   // oldComputeBetheBloch (localP, materialConstants, mass());
00096 
00097 }
00098 //
00099 // Computation of energy loss for electrons
00100 //
00101 void 
00102 EnergyLossUpdator::computeElectrons (const LocalVector& localP,
00103                                      const MediumProperties& materialConstants,
00104                                      const PropagationDirection propDir, Effect & effect) const {
00105   //
00106   // calculate absolute momentum and correction to path length from angle 
00107   // of incidence
00108   //
00109   float p2 = localP.mag2();
00110   float p = std::sqrt(p2);
00111   float normalisedPath = std::abs(p/localP.z())*materialConstants.radLen();
00112   //
00113   // Energy loss and variance according to Bethe and Heitler, see also
00114   // Comp. Phys. Comm. 79 (1994) 157. 
00115   //
00116   const float l3ol2 = std::log(3.)/std::log(2.);
00117   float z = unsafe_expf<3>(-normalisedPath);
00118   float varz = unsafe_expf<3>(-normalisedPath*l3ol2)- 
00119                 z*z;
00120                 // exp(-2*normalisedPath);
00121 
00122   if ( propDir==oppositeToMomentum ) {
00123     //
00124     // for backward propagation: delta(1/p) is linear in z=p_outside/p_inside
00125     // convert to obtain equivalent delta(p). Sign of deltaP is corrected
00126     // in method compute -> deltaP<0 at this place!!!
00127     //
00128     effect.deltaP += -p*(1.f/z-1.f);
00129     using namespace materialEffect;
00130     effect.deltaCov[elos]  += varz/p2;
00131   }
00132   else {        
00133     //
00134     // for forward propagation: calculate in p (linear in 1/z=p_inside/p_outside),
00135     // then convert sig(p) to sig(1/p). 
00136     //
00137     effect.deltaP += p*(z-1.f);
00138     //    float f = 1/p/z/z;
00139     // patch to ensure consistency between for- and backward propagation
00140     float f2 = 1.f/(p2*z*z);
00141     using namespace materialEffect;
00142     effect.deltaCov[elos] += f2*varz;
00143   }
00144 
00145 
00146   // std::cout << "electron new " <<  theDeltaP << " " << theDeltaCov(0,0) << std::endl;
00147   // oldComputeElectrons (localP, materialConstants, propDir);
00148 
00149 }
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00158 
00159 
00160 void
00161 oldComputeBetheBloch (const LocalVector& localP,
00162                       const MediumProperties& materialConstants, double mass) {
00163 
00164  double theDeltaP=0., theDeltaCov=0;
00165 
00166   //
00167   // calculate absolute momentum and correction to path length from angle 
00168   // of incidence
00169   //
00170   double p = localP.mag();
00171   double xf = fabs(p/localP.z());
00172   // constants
00173   const double m = mass;            // use mass hypothesis from constructor
00174 
00175   const double emass = 0.511e-3;
00176   const double poti = 16.e-9 * 10.75; // = 16 eV * Z**0.9, for Si Z=14
00177   const double eplasma = 28.816e-9 * sqrt(2.33*0.498); // 28.816 eV * sqrt(rho*(Z/A)) for Si
00178   const double delta0 = 2*log(eplasma/poti) - 1.;
00179 
00180   // calculate general physics things
00181   double e     = sqrt(p*p + m*m);
00182   double beta  = p/e;
00183   double gamma = e/m;
00184   double eta2  = beta*gamma; eta2 *= eta2;
00185   //  double lnEta2 = log(eta2);
00186   double ratio = emass/m;
00187   double emax  = 2.*emass*eta2/(1. + 2.*ratio*gamma + ratio*ratio);
00188   // double delta = delta0 + lnEta2;
00189 
00190   // calculate the mean and sigma of energy loss
00191   // xi = d[g/cm2] * 0.307075MeV/(g/cm2) * Z/A * 1/2
00192   double xi = materialConstants.xi()*xf; xi /= (beta*beta);
00193 
00194 //   double dEdx = xi*(log(2.*emass*eta2*emax/(poti*poti)) - 2.*(beta*beta));
00195   //double dEdx = xi*(log(2.*emass*emax/(poti*poti))+lnEta2 - 2.*(beta*beta) - delta);
00196 
00197   double dEdx = xi*(log(2.*emass*emax/(poti*poti)) - 2.*(beta*beta) - delta0);
00198   double dEdx2 = xi*emax*(1.-0.5*(beta*beta));
00199   double dP    = dEdx/beta;
00200   double sigp2 = dEdx2*e*e/(p*p*p*p*p*p);
00201   theDeltaP += -dP;
00202   theDeltaCov += sigp2;
00203 
00204   std::cout << "pion old " <<  theDeltaP << " " << theDeltaCov << std::endl;
00205 
00206 }
00207 
00208 
00209 void 
00210 oldComputeElectrons (const LocalVector& localP,
00211                      const MediumProperties& materialConstants,
00212                      const PropagationDirection propDir) {
00213 
00214   double theDeltaP=0., theDeltaCov=0;
00215 
00216   //
00217   // calculate absolute momentum and correction to path length from angle 
00218   // of incidence
00219   //
00220   double p = localP.mag();
00221   double normalisedPath = fabs(p/localP.z())*materialConstants.radLen();
00222   //
00223   // Energy loss and variance according to Bethe and Heitler, see also
00224   // Comp. Phys. Comm. 79 (1994) 157. 
00225   //
00226   double z = exp(-normalisedPath);
00227   double varz = exp(-normalisedPath*log(3.)/log(2.))- 
00228                 z*z;
00229                 // exp(-2*normalisedPath);
00230 
00231   if ( propDir==oppositeToMomentum ) {
00232     //
00233     // for backward propagation: delta(1/p) is linear in z=p_outside/p_inside
00234     // convert to obtain equivalent delta(p). Sign of deltaP is corrected
00235     // in method compute -> deltaP<0 at this place!!!
00236     //
00237     theDeltaP += -p*(1/z-1);
00238     theDeltaCov += varz/(p*p);
00239   }
00240   else {        
00241     //
00242     // for forward propagation: calculate in p (linear in 1/z=p_inside/p_outside),
00243     // then convert sig(p) to sig(1/p). 
00244     //
00245     theDeltaP += p*(z-1);
00246     //    double f = 1/p/z/z;
00247     // patch to ensure consistency between for- and backward propagation
00248     double f = 1./(p*z);
00249     theDeltaCov += f*f*varz;
00250   }
00251 
00252   std::cout << "electron old " <<  theDeltaP << " " << theDeltaCov << std::endl;
00253 
00254 
00255 }