Go to the documentation of this file.00001
00002 #include "FastSimulation/MaterialEffects/interface/BremsstrahlungSimulator.h"
00003 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00004
00005 #include <cmath>
00006
00007 BremsstrahlungSimulator::BremsstrahlungSimulator(double photonEnergyCut,
00008 double photonFractECut,
00009 const RandomEngine* engine) :
00010 MaterialEffectsSimulator(engine)
00011 {
00012
00013
00014 photonEnergy = photonEnergyCut;
00015 photonFractE = photonFractECut;
00016
00017 }
00018
00019
00020 void
00021 BremsstrahlungSimulator::compute(ParticlePropagator &Particle)
00022 {
00023
00024
00025
00026
00027
00028
00029 if ( radLengths > 4. ) Particle.SetXYZT(0.,0.,0.,0.);
00030
00031
00032 if (Particle.e()<photonEnergy) return;
00033 xmin = std::max(photonEnergy/Particle.e(),photonFractE);
00034 if ( xmin >=1. || xmin <=0. ) return;
00035
00036 double bremProba = radLengths * ( 4./3. * std::log(1./xmin)
00037 - 4./3. * (1.-xmin)
00038 + 1./2. * (1.-xmin*xmin) );
00039
00040
00041
00042 unsigned int nPhotons = poisson(bremProba);
00043 _theUpdatedState.reserve(nPhotons);
00044
00045 if ( !nPhotons ) return;
00046
00047
00048 double chi = Particle.theta();
00049 double psi = Particle.phi();
00050 RawParticle::RotationZ rotZ(psi);
00051 RawParticle::RotationY rotY(chi);
00052
00053
00054 for ( unsigned int i=0; i<nPhotons; ++i ) {
00055
00056
00057 if ( Particle.e() < photonEnergy ) break;
00058
00059
00060 RawParticle thePhoton(22,brem(Particle));
00061 thePhoton.rotate(rotY);
00062 thePhoton.rotate(rotZ);
00063 _theUpdatedState.push_back(thePhoton);
00064
00065
00066 Particle -= thePhoton.momentum();
00067
00068 }
00069 }
00070
00071 XYZTLorentzVector
00072 BremsstrahlungSimulator::brem(ParticlePropagator& pp) const {
00073
00074
00075
00076
00077 double emass = 0.0005109990615;
00078 double xp=0;
00079 double weight = 0.;
00080
00081 do {
00082 xp = xmin * std::exp ( -std::log(xmin) * random->flatShoot() );
00083 weight = 1. - xp + 3./4.*xp*xp;
00084 } while ( weight < random->flatShoot() );
00085
00086
00087
00088
00089
00090
00091 const double phi = random->flatShoot()*2*M_PI;
00092
00093 const double theta = gbteth(pp.e(),emass,xp)*emass/pp.e();
00094
00095
00096 double stheta = std::sin(theta);
00097 double ctheta = std::cos(theta);
00098 double sphi = std::sin(phi);
00099 double cphi = std::cos(phi);
00100
00101 return xp * pp.e() * XYZTLorentzVector(stheta*cphi,stheta*sphi,ctheta,1.);
00102
00103 }
00104
00105 double
00106 BremsstrahlungSimulator::gbteth(const double ener,
00107 const double partm,
00108 const double efrac) const {
00109 const double alfa = 0.625;
00110
00111 const double d = 0.13*(0.8+1.3/theZ())*(100.0+(1.0/ener))*(1.0+efrac);
00112 const double w1 = 9.0/(9.0+d);
00113 const double umax = ener*M_PI/partm;
00114 double u;
00115
00116 do {
00117 double beta = (random->flatShoot()<=w1) ? alfa : 3.0*alfa;
00118 u = -std::log(random->flatShoot()*random->flatShoot())/beta;
00119 } while (u>=umax);
00120
00121 return u;
00122 }
00123
00124
00125 unsigned int
00126 BremsstrahlungSimulator::poisson(double ymu) {
00127
00128 unsigned int n = 0;
00129 double prob = std::exp(-ymu);
00130 double proba = prob;
00131 double x = random->flatShoot();
00132
00133 while ( proba <= x ) {
00134 prob *= ymu / double(++n);
00135 proba += prob;
00136 }
00137
00138 return n;
00139
00140 }
00141