CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/GeneratorInterface/CosmicMuonGenerator/src/SingleParticleEvent.cc

Go to the documentation of this file.
00001 #include "GeneratorInterface/CosmicMuonGenerator/interface/SingleParticleEvent.h"
00002 
00003 void SingleParticleEvent::create(int id, double px, double py, double pz, double e, double m, double vx, double vy, double vz, double t0){
00004   ID = ID_in = id;
00005   Px = Px_in = px; Py = Py_in = py; Pz = Pz_in = pz; 
00006   E = E_in = e; M = M_in = m;
00007   Vx = Vx_in = vx; Vy = Vy_in = vy; Vz = Vz_in = vz; 
00008   T0 = T0_in = t0;
00009   HitTarget = false;
00010 }
00011 
00012 void SingleParticleEvent::propagate(double ElossScaleFac, double RadiusTarget, double Z_DistTarget, double Z_CentrTarget, bool TrackerOnly, bool MTCCHalf){
00013   MTCC=MTCCHalf; //need to know this boolean in absVzTmp()
00014   // calculated propagation direction
00015   dX = Px/absmom();
00016   dY = Py/absmom(); 
00017   dZ = Pz/absmom();
00018   // propagate with decreasing step size
00019   tmpVx = Vx;
00020   tmpVy = Vy;
00021   tmpVz = Vz;
00022   double RadiusTargetEff = RadiusTarget;
00023   double Z_DistTargetEff = Z_DistTarget;
00024   double Z_CentrTargetEff = Z_CentrTarget;
00025   if(TrackerOnly==true){
00026     RadiusTargetEff = RadiusTracker;
00027     Z_DistTargetEff = Z_DistTracker;
00028   }
00029   HitTarget = true;
00030   if (HitTarget == true){
00031     HitTarget = false;
00032     double stepSize = MinStepSize*100000.;
00033     double acceptR = RadiusTargetEff + stepSize;
00034     double acceptZ = Z_DistTargetEff + stepSize;
00035     bool continuePropagation = true;
00036     while (continuePropagation){
00037       //if (tmpVy < -acceptR) continuePropagation = false;
00038       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00039       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00040       //if (absVzTmp() < acceptZ && rVxyTmp() < acceptR){
00041       if (std::fabs(tmpVz - Z_CentrTargetEff) < acceptZ && rVxyTmp() < acceptR){
00042         HitTarget = true;
00043         continuePropagation = false;
00044       }
00045       if (continuePropagation) updateTmp(stepSize);
00046     }
00047   }
00048   if (HitTarget == true){
00049     HitTarget = false;
00050     double stepSize = MinStepSize*10000.;
00051     double acceptR = RadiusTargetEff + stepSize;
00052     double acceptZ = Z_DistTargetEff + stepSize;
00053     bool continuePropagation = true;
00054     while (continuePropagation){
00055       //if (tmpVy < -acceptR) continuePropagation = false;
00056       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00057       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00058       //if (absVzTmp() < acceptZ && rVxyTmp() < acceptR){
00059       if (std::fabs(tmpVz - Z_CentrTargetEff) < acceptZ && rVxyTmp() < acceptR){
00060         HitTarget = true;
00061         continuePropagation = false;
00062       }
00063       if (continuePropagation) updateTmp(stepSize);
00064     }
00065   }
00066   if (HitTarget == true){
00067     HitTarget = false;
00068     double stepSize = MinStepSize*1000.;
00069     double acceptR = RadiusTargetEff + stepSize;
00070     double acceptZ = Z_DistTargetEff + stepSize;
00071     bool continuePropagation = true;
00072     while (continuePropagation){
00073       //if (tmpVy < -acceptR) continuePropagation = false;
00074       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00075       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00076       //if (absVzTmp() < acceptZ && rVxyTmp() < acceptR){
00077       if (std::fabs(tmpVz - Z_CentrTargetEff) < acceptZ && rVxyTmp() < acceptR){
00078         HitTarget = true;
00079         continuePropagation = false;
00080       }
00081       if (continuePropagation) updateTmp(stepSize);
00082     }
00083   }
00084   if (HitTarget == true){
00085     HitTarget = false;
00086     double stepSize = MinStepSize*100.;
00087     double acceptR = RadiusTargetEff + stepSize;
00088     double acceptZ = Z_DistTargetEff + stepSize;
00089     bool continuePropagation = true;
00090     while (continuePropagation){
00091       //if (tmpVy < -acceptR) continuePropagation = false;
00092       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00093       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00094       //if (absVzTmp() < acceptZ && rVxyTmp() < acceptR){
00095       if (std::fabs(tmpVz - Z_CentrTargetEff) < acceptZ && rVxyTmp() < acceptR){
00096         HitTarget = true;
00097         continuePropagation = false;
00098       }
00099       if (continuePropagation) updateTmp(stepSize);
00100     }
00101   }
00102   if (HitTarget == true){
00103     HitTarget = false;
00104     double stepSize = MinStepSize*10.;
00105     double acceptR = RadiusTargetEff + stepSize;
00106     double acceptZ = Z_DistTargetEff + stepSize;
00107     bool continuePropagation = true;
00108     while (continuePropagation){
00109       //if (tmpVy < -acceptR) continuePropagation = false;
00110       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00111       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00112       //if (absVzTmp() < acceptZ && rVxyTmp() < acceptR){
00113       if (std::fabs(tmpVz - Z_CentrTargetEff) < acceptZ && rVxyTmp() < acceptR){
00114         HitTarget = true;
00115         continuePropagation = false;
00116       }
00117       if (continuePropagation) updateTmp(stepSize);
00118     }
00119   }
00120   if (HitTarget == true){
00121     HitTarget = false;
00122     double stepSize = MinStepSize*1.;
00123     double acceptR = RadiusTargetEff + stepSize;
00124     double acceptZ = Z_DistTargetEff + stepSize;
00125     bool continuePropagation = true;
00126     while (continuePropagation){
00127       //if (tmpVy < -acceptR) continuePropagation = false;
00128       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00129       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00130       //if (0 < absVzTmp()){ //only check for MTCC setup in last step of propagation, need fine stepSize
00131       if (absVzTmp() < acceptZ && rVxyTmp() < acceptR){
00132         if (std::fabs(tmpVz - Z_CentrTargetEff) < acceptZ && rVxyTmp() < acceptR){
00133           HitTarget = true;
00134           continuePropagation = false;
00135         }
00136       }
00137       if (continuePropagation) updateTmp(stepSize);
00138     }
00139   }
00140   // actual propagation + energy loss
00141   if (HitTarget == true){
00142     HitTarget = false;
00143     //int nAir = 0; int nWall = 0; int nRock = 0; int nClay = 0; int nPlug = 0;
00144     int nMat[6] = {0, 0, 0, 0, 0, 0};
00145     double stepSize = MinStepSize*1.; // actual step size
00146     double acceptR = RadiusCMS + stepSize;
00147     double acceptZ = Z_DistCMS + stepSize;
00148     if(TrackerOnly==true){
00149       acceptR = RadiusTracker + stepSize;
00150       acceptZ = Z_DistTracker + stepSize;
00151     }
00152     bool continuePropagation = true;
00153     while (continuePropagation){
00154       //if (Vy < -acceptR) continuePropagation = false;
00155       if (dY < 0. && tmpVy < -acceptR) continuePropagation = false;
00156       if (dY >= 0. && tmpVy > acceptR) continuePropagation = false;
00157       //if (absVz() < acceptZ && rVxy() < acceptR){
00158       if (std::fabs(Vz - Z_CentrTargetEff) < acceptZ && rVxy() < acceptR){
00159         HitTarget = true;
00160         continuePropagation = false;
00161       }
00162       if (continuePropagation) update(stepSize);
00163 
00164       int Mat = inMat(Vx,Vy,Vz, PlugVx, PlugVz, ClayWidth);
00165 
00166       nMat[Mat]++;
00167     }
00168 
00169     if (HitTarget){
00170       double lPlug = double(nMat[Plug])*stepSize;
00171       double lWall = double(nMat[Wall])*stepSize;
00172       double lAir = double(nMat[Air])*stepSize;
00173       double lClay = double(nMat[Clay])*stepSize;
00174       double lRock = double(nMat[Rock])*stepSize;      
00175       //double lUnknown = double(nMat[Unknown])*stepSize;
00176 
00177       double waterEquivalents = (lAir*RhoAir + lWall*RhoWall + lRock*RhoRock
00178                                  + lClay*RhoClay + lPlug*RhoPlug) *ElossScaleFac/10.; // [g cm^-2]
00179       subtractEloss(waterEquivalents);
00180       if (E < MuonMass) HitTarget = false; // muon stopped in the material around the target
00181     }
00182   }
00183   // end of propagation part
00184 }
00185 
00186 void SingleParticleEvent::update(double stepSize){
00187   Vx += stepSize*dX;
00188   Vy += stepSize*dY;
00189   Vz += stepSize*dZ;
00190 }
00191 
00192 void SingleParticleEvent::updateTmp(double stepSize){
00193   tmpVx += stepSize*dX;
00194   tmpVy += stepSize*dY;
00195   tmpVz += stepSize*dZ;
00196 }
00197 
00198 void SingleParticleEvent::subtractEloss(double waterEquivalents){
00199   double L10E = log10(E);
00200   // parameters for standard rock (PDG 2004, page 230)
00201   double A = (1.91514 + 0.254957*L10E)/1000.;                         // a [GeV g^-1 cm^2]
00202   double B = (0.379763 + 1.69516*L10E - 0.175026*L10E*L10E)/1000000.; // b [g^-1 cm^2]
00203   double EPS = A/B;                                                   // epsilon [GeV]
00204   E = (E + EPS)*exp(-B*waterEquivalents) - EPS; // updated energy
00205   double oldAbsMom = absmom();
00206   double newAbsMom = sqrt(E*E - MuonMass*MuonMass);
00207   Px = Px*newAbsMom/oldAbsMom;                  // updated px
00208   Py = Py*newAbsMom/oldAbsMom;                  // updated py
00209   Pz = Pz*newAbsMom/oldAbsMom;                  // updated pz
00210 }
00211 
00212 double SingleParticleEvent::Eloss(double waterEquivalents, double Energy){
00213   double L10E = log10(Energy);
00214   // parameters for standard rock (PDG 2004, page 230)
00215   double A = (1.91514 + 0.254957*L10E)/1000.;                         // a [GeV g^-1 cm^2]
00216   double B = (0.379763 + 1.69516*L10E - 0.175026*L10E*L10E)/1000000.; // b [g^-1 cm^2]
00217   double EPS = A/B;                                                   // epsilon [GeV]
00218   double newEnergy = (Energy + EPS)*exp(-B*waterEquivalents) - EPS; // updated energy
00219   double EnergyLoss = Energy - newEnergy;
00220   return EnergyLoss;
00221 }
00222 
00223 
00224 void SingleParticleEvent::setEug(double Eug) {
00225   E_ug = Eug;
00226 }
00227 
00228 double SingleParticleEvent::Eug(){ return E_ug; }
00229 
00230 double SingleParticleEvent::deltaEmin(double E_sf) {
00231   double dE = Eloss(waterEquivalents, E_sf);
00232   return E_ug - (E_sf-dE);
00233 }
00234 
00235 
00236 void SingleParticleEvent::SurfProj(double Vx_in, double Vy_in, double Vz_in,
00237                                    double Px_in, double Py_in, double Pz_in,
00238                                    double& Vx_up, double& Vy_up, double& Vz_up) { 
00239   //determine vertex of muon at Surface (+PlugWidth)
00240   double dy = Vy_in - (SurfaceOfEarth+PlugWidth);
00241   Vy_up = Vy_in - dy;
00242   Vx_up = Vx_in - dy*Px_in/Py_in;       
00243   Vz_up = Vz_in - dy*Pz_in/Py_in;
00244   if (Debug) std::cout << "Vx_up=" << Vx_up << " Vy_up=" 
00245                        << Vy_up << " Vz_up=" << Vz_up << std::endl;     
00246 }
00247 
00248 double SingleParticleEvent::absVzTmp(){
00249   if(MTCC==true){
00250     return tmpVz; //need sign to be sure muon hits half of CMS with MTCC setup
00251   }else{
00252     return std::fabs(tmpVz);
00253   }
00254 }
00255 
00256 double SingleParticleEvent::rVxyTmp(){
00257   return sqrt(tmpVx*tmpVx + tmpVy*tmpVy);
00258 }
00259 
00260 bool SingleParticleEvent::hitTarget(){ return HitTarget; }
00261 
00262 
00263 int    SingleParticleEvent::id_in(){ return ID_in; }
00264 
00265 double SingleParticleEvent::px_in(){ return Px_in; }
00266 
00267 double SingleParticleEvent::py_in(){ return Py_in; }
00268 
00269 double SingleParticleEvent::pz_in(){ return Pz_in; }
00270 
00271 double SingleParticleEvent::e_in(){ return E_in; }
00272 
00273 double SingleParticleEvent::m_in(){ return M_in; }
00274 
00275 double SingleParticleEvent::vx_in(){ return Vx_in; }
00276 
00277 double SingleParticleEvent::vy_in(){ return Vy_in; }
00278 
00279 double SingleParticleEvent::vz_in(){ return Vz_in; }
00280 
00281 double SingleParticleEvent::t0_in(){ return T0_in; }
00282 
00283 
00284 int    SingleParticleEvent::id(){ return ID; }
00285 
00286 double SingleParticleEvent::px(){ return Px; }
00287 
00288 double SingleParticleEvent::py(){ return Py; }
00289 
00290 double SingleParticleEvent::pz(){ return Pz; }
00291 
00292 double SingleParticleEvent::e(){ return E; }
00293 
00294 double SingleParticleEvent::m(){ return M; }
00295 
00296 double SingleParticleEvent::vx(){ return Vx; }
00297 
00298 double SingleParticleEvent::vy(){ return Vy; }
00299 
00300 double SingleParticleEvent::vz(){ return Vz; }
00301 
00302 double SingleParticleEvent::t0(){ return T0; }
00303 
00304 double SingleParticleEvent::WaterEquivalents() { return waterEquivalents; }
00305 
00306 double SingleParticleEvent::phi(){
00307   double phiXZ = atan2(Px,Pz);
00308   if (phiXZ < 0.) phiXZ = phiXZ + TwoPi;
00309   return  phiXZ;
00310 }
00311 
00312 double SingleParticleEvent::theta(){
00313   return atan2(sqrt(Px*Px+Pz*Pz),-Py);
00314 }
00315 
00316 double SingleParticleEvent::absmom(){
00317   return sqrt(Px*Px + Py*Py + Pz*Pz);
00318 }
00319 
00320 double SingleParticleEvent::absVz(){
00321   return std::fabs(Vz);
00322 }
00323 
00324 double SingleParticleEvent::rVxy(){
00325   return sqrt(Vx*Vx + Vy*Vy);
00326 }