CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/FastSimulation/MaterialEffects/src/MuonBremsstrahlungSimulator.cc

Go to the documentation of this file.
00001 
00002 //MuonBremsstrahlungSimulator
00003 // Description: Implementation of Muon bremsstrahlung using the Petrukhin model
00004 //Authors :Sandro Fonseca de Souza and Andre Sznajder (UERJ/Brazil)
00005 // Date: 23-Nov-2010
00007 #include "FastSimulation/MaterialEffects/interface/MuonBremsstrahlungSimulator.h"
00008 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "FastSimulation/MaterialEffects/interface/PetrukhinModel.h"
00011 
00012 #include <cmath>
00013 #include <string>
00014 #include <iostream>
00015 
00016 #include "TF1.h"
00017 
00018 
00019 
00020 
00022 MuonBremsstrahlungSimulator::MuonBremsstrahlungSimulator(const RandomEngine* engine,
00023                                                          double A,double Z, double density,double radLen,
00024                                                          double photonEnergyCut,double photonFractECut) : 
00025   MaterialEffectsSimulator(engine,A,Z,density,radLen) 
00026 {
00027   // Set the minimal photon energy for a Brem from mu+/-
00028   photonEnergy = photonEnergyCut;
00029   photonFractE = photonFractECut;
00030   d = 0.; //distance
00031   LogDebug("MuonBremsstrahlungSimulator")<< "Starting the MuonBremsstrahlungSimulator"<< std::endl;
00032 }
00033 
00034 
00035 
00037 void 
00038 MuonBremsstrahlungSimulator::compute(ParticlePropagator &Particle)
00039 {
00040 
00041   double NA = 6.022e+23;  //Avogadro's number
00042 
00043   if ( radLengths > 4. )  {
00044     Particle.SetXYZT(0.,0.,0.,0.);
00045     deltaPMuon.SetXYZT(0.,0.,0.,0.);
00046     brem_photon.SetXYZT(0.,0.,0.,0.);
00047   }
00048 
00049 // Hard brem probability with a photon Energy above photonEnergy.
00050   
00051   double EMuon = Particle.e();//Muon Energy
00052   if (EMuon<photonEnergy) return;
00053   xmin = std::max(photonEnergy/EMuon,photonFractE);//fraction of muon's energy transferred to the photon
00054 
00055  //  xmax = photonEnergy/Particle.e();
00056   if ( xmin >=1. || xmin <=0. ) return;
00057  
00058   xmax = 1.;
00059   npar = 3 ;//Number of parameters
00060 
00061   // create TF1 using a free C function 
00062   f1 = new TF1("f1",PetrukhinFunc,xmin,xmax,npar);
00063   //Setting parameters
00064   f1->SetParameters(EMuon,A,Z);
00066   //d = distance for several materials
00067   //X0 = radLen
00068   //d = radLengths * X0(for tracker,yoke,ECAL and HCAL)
00069   d =  radLengths * radLen ;      
00070   //Integration
00071   bremProba = density * d *(NA/A)* (f1->Integral(0.,1.));
00072       
00073      
00074   // Number of photons to be radiated.
00075   unsigned int nPhotons = poisson(bremProba);
00076   _theUpdatedState.reserve(nPhotons);
00077  
00078  
00079   if ( !nPhotons ) return;
00080  
00081   //Rotate to the lab frame
00082   double chi = Particle.theta();
00083   double psi = Particle.phi();
00084   RawParticle::RotationZ rotZ(psi);
00085   RawParticle::RotationY rotY(chi);
00086 
00087  
00088  
00089   // Energy of these photons
00090   for ( unsigned int i=0; i<nPhotons; ++i ) {
00091 
00092      // Check that there is enough energy left.
00093     if ( Particle.e() < photonEnergy ) break;
00094     LogDebug("MuonBremsstrahlungSimulator")<< "MuonBremsstrahlungSimulator parameters:"<< std::endl;
00095     LogDebug("MuonBremsstrahlungSimulator")<< "xmin-> " << xmin << std::endl; 
00096     LogDebug("MuonBremsstrahlungSimulator")<< "Atomic Weight-> " << A << std::endl;
00097     LogDebug("MuonBremsstrahlungSimulator")<< "Density-> " << density << std::endl;
00098     LogDebug("MuonBremsstrahlungSimulator")<< "Distance-> " << d << std::endl;
00099     LogDebug("MuonBremsstrahlungSimulator")<< "bremProba->" << bremProba << std::endl;    
00100     LogDebug("MuonBremsstrahlungSimulator")<< "nPhotons->" << nPhotons << std::endl;
00101     LogDebug("MuonBremsstrahlungSimulator")<< " Muon_Energy-> " <<  EMuon << std::endl;
00102     LogDebug("MuonBremsstrahlungSimulator")<< "X0-> "<< radLen << std::endl; 
00103     LogDebug("MuonBremsstrahlungSimulator")<< " radLengths-> " << radLengths << std::endl; 
00104 
00105     // Add a photon
00106     RawParticle thePhoton(22,brem(Particle));    
00107     if (thePhoton.E()>0.){
00108 
00109     thePhoton.rotate(rotY);
00110     thePhoton.rotate(rotZ);
00111     
00112     _theUpdatedState.push_back(thePhoton);
00113         
00114     // Update the original mu +/-
00115     deltaPMuon = Particle -= thePhoton.momentum();
00116     // Information of brem photon
00117     brem_photon.SetXYZT(thePhoton.Px(),thePhoton.Py(),thePhoton.Pz(),thePhoton.E());     
00118 
00119     LogDebug("MuonBremsstrahlungSimulator")<< " Muon Bremsstrahlung: photon_energy-> " << thePhoton.E() << std::endl;
00120     LogDebug("MuonBremsstrahlungSimulator")<< "photon_px->" << thePhoton.Px() << std::endl;
00121     LogDebug("MuonBremsstrahlungSimulator")<< "photon_py->" << thePhoton.Py() << std::endl;
00122     LogDebug("MuonBremsstrahlungSimulator")<< "photon_pz->" << thePhoton.Pz() << std::endl;
00123     
00124     } 
00125     
00126   }
00127 
00128 }
00130 XYZTLorentzVector 
00131 MuonBremsstrahlungSimulator::brem(ParticlePropagator& pp) const {
00132 
00133   // This is a simple version of a Muon Brem using Petrukhin model .
00134   //Ref: http://pdg.lbl.gov/2008/AtomicNuclearProperties/adndt.pdf 
00135   double mumass = 0.105658367;//mu mass  (GeV/c^2)
00136   double xp =0.;  
00137  //+++++++++++++++++++++++++++++++++++++++++++++++++++ 
00138   // Ref: Framework    
00139   //https://hypernews.cern.ch/HyperNews/CMS/get/swDevelopment/1969/1.html
00140   // http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/DQM/DTMonitorClient/src/DTResolutionTest.cc?view=markup
00142   try {
00143  
00144     xp = f1->GetRandom();
00145   } catch (...) {
00146     
00147     edm::LogInfo ("MuonBremsstrahlungSimulator") << "Exception when fitting..."; 
00148   }
00149   LogDebug("MuonBremsstrahlungSimulator")<<  "MuonBremsstrahlungSimulator: xp->" << xp << std::endl;
00150 
00151   
00152   // Have photon energy. Now generate angles with respect to the z axis 
00153   // defined by the incoming particle's momentum.
00154 
00155   // Isotropic in phi
00156   const double phi = random->flatShoot()*2*M_PI;
00157   // theta from universal distribution
00158   const double theta = gbteth(pp.e(),mumass,xp)*mumass/pp.e(); 
00159   
00160   // Make momentum components
00161   double stheta = std::sin(theta);
00162   double ctheta = std::cos(theta);
00163   double sphi   = std::sin(phi);
00164   double cphi   = std::cos(phi);
00165 
00166   return xp * pp.e() * XYZTLorentzVector(stheta*cphi,stheta*sphi,ctheta,1.);
00167  
00168 }
00170 double
00171 MuonBremsstrahlungSimulator::gbteth(const double ener,
00172                                 const double partm,
00173                                 const double efrac) const {
00174   const double alfa = 0.625;
00175 
00176   const double d = 0.13*(0.8+1.3/theZ())*(100.0+(1.0/ener))*(1.0+efrac);
00177   const double w1 = 9.0/(9.0+d);
00178   const double umax = ener*M_PI/partm;
00179   double u;
00180   
00181   do {
00182     double beta = (random->flatShoot()<=w1) ? alfa : 3.0*alfa;
00183     u = -std::log(random->flatShoot()*random->flatShoot())/beta;
00184   } while (u>=umax);
00185 
00186   return u;
00187 }
00188 
00190 unsigned int 
00191 MuonBremsstrahlungSimulator::poisson(double ymu) {
00192 
00193   unsigned int n = 0;
00194   double prob = std::exp(-ymu);
00195   double proba = prob;
00196   double x = random->flatShoot();
00197   
00198   while ( proba <= x ) {
00199     prob *= ymu / double(++n);
00200     proba += prob;
00201   }
00202   
00203   return n;                                                        
00204   
00205 }
00206