CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/SimG4CMS/Forward/src/ZdcShowerLibrary.cc

Go to the documentation of this file.
00001 
00002 // File: ZdcShowerLibrary.cc
00003 // Description: Shower library for the Zero Degree Calorimeter
00004 // E. Garcia June 2008
00006 
00007 #include "SimG4CMS/Forward/interface/ZdcSD.h"
00008 #include "SimG4CMS/Forward/interface/ZdcShowerLibrary.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include "FWCore/ServiceRegistry/interface/Service.h"
00011 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00012 
00013 #include "G4VPhysicalVolume.hh"
00014 #include "G4Step.hh"
00015 #include "G4Track.hh"
00016 #include "Randomize.hh"
00017 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00018 
00019 ZdcShowerLibrary::ZdcShowerLibrary(std::string & name, const DDCompactView & cpv,
00020                                  edm::ParameterSet const & p) {
00021   edm::ParameterSet m_HS   = p.getParameter<edm::ParameterSet>("ZdcShowerLibrary");
00022   verbose                  = m_HS.getUntrackedParameter<int>("Verbosity",0);
00023 
00024   npe = 9; // number of channels or fibers where the energy will be deposited
00025   hits.reserve(npe);
00026 
00027 }
00028 
00029 ZdcShowerLibrary::~ZdcShowerLibrary() {
00030 }
00031 
00032 void ZdcShowerLibrary::initRun(G4ParticleTable *theParticleTable){
00033   G4String parName;
00034   emPDG = theParticleTable->FindParticle(parName="e-")->GetPDGEncoding();
00035   epPDG = theParticleTable->FindParticle(parName="e+")->GetPDGEncoding();
00036   gammaPDG = theParticleTable->FindParticle(parName="gamma")->GetPDGEncoding();
00037   pi0PDG = theParticleTable->FindParticle(parName="pi0")->GetPDGEncoding();
00038   etaPDG = theParticleTable->FindParticle(parName="eta")->GetPDGEncoding();
00039   nuePDG = theParticleTable->FindParticle(parName="nu_e")->GetPDGEncoding();
00040   numuPDG = theParticleTable->FindParticle(parName="nu_mu")->GetPDGEncoding();
00041   nutauPDG= theParticleTable->FindParticle(parName="nu_tau")->GetPDGEncoding();
00042   anuePDG = theParticleTable->FindParticle(parName="anti_nu_e")->GetPDGEncoding();
00043   anumuPDG= theParticleTable->FindParticle(parName="anti_nu_mu")->GetPDGEncoding();
00044   anutauPDG= theParticleTable->FindParticle(parName="anti_nu_tau")->GetPDGEncoding();
00045   geantinoPDG= theParticleTable->FindParticle(parName="geantino")->GetPDGEncoding();
00046   LogDebug("ZdcShower")<< "ZdcShowerLibrary: Particle codes for e- = " << emPDG
00047                        << ", e+ = " << epPDG << ", gamma = " << gammaPDG 
00048                        << ", pi0 = " << pi0PDG << ", eta = " << etaPDG
00049                        << ", geantino = " << geantinoPDG << "\n        nu_e = "
00050                        << nuePDG << ", nu_mu = " << numuPDG << ", nu_tau = "
00051                        << nutauPDG << ", anti_nu_e = " << anuePDG
00052                        << ", anti_nu_mu = " << anumuPDG << ", anti_nu_tau = "
00053                        << anutauPDG;
00054 }
00055 
00056 std::vector<ZdcShowerLibrary::Hit> & ZdcShowerLibrary::getHits(G4Step * aStep, bool & ok) {
00057 
00058   G4StepPoint * preStepPoint  = aStep->GetPreStepPoint(); 
00059   G4StepPoint * postStepPoint = aStep->GetPostStepPoint(); 
00060   G4Track *     track    = aStep->GetTrack();
00061 
00062   const G4DynamicParticle *aParticle = track->GetDynamicParticle();
00063   G4ThreeVector momDir = aParticle->GetMomentumDirection();
00064   double energy = preStepPoint->GetKineticEnergy();
00065   G4ThreeVector hitPoint = preStepPoint->GetPosition();  
00066   G4ThreeVector hitPointOrig = preStepPoint->GetPosition();
00067   G4int parCode  = track->GetDefinition()->GetPDGEncoding();
00068 
00069   hits.clear();
00070  
00071   ok = false;
00072   if (parCode == geantinoPDG)
00073     return hits;
00074   ok = true;
00075   
00076   G4ThreeVector pos;
00077   G4ThreeVector posLocal;
00078   double tSlice = (postStepPoint->GetGlobalTime())/nanosecond;
00079 
00080   int nHit = 0;
00081   HcalZDCDetId::Section section;
00082   bool side = false;
00083   int channel = 0;
00084   double xx,yy,zz;
00085   double xxlocal, yylocal, zzlocal;
00086 
00087   ZdcShowerLibrary::Hit oneHit;
00088   side = (hitPointOrig.z() > 0.) ?  true : false;  
00089   
00090   float xWidthEM = fabs(theXChannelBoundaries[0] - theXChannelBoundaries[1]);
00091   float zWidthEM = fabs(theZSectionBoundaries[0] - theZSectionBoundaries[1]); 
00092   float zWidthHAD = fabs(theZHadChannelBoundaries[0] -theZHadChannelBoundaries[1]); 
00093 
00094   for (int i = 0; i < npe; i++) {
00095     if(i < 5){
00096       section = HcalZDCDetId::EM;
00097       channel = i+1;
00098       xxlocal = theXChannelBoundaries[i]+(xWidthEM/2.);
00099       xx = xxlocal + X0; 
00100       yy = 0.0;
00101       yylocal = yy + Y0;
00102       zzlocal = theZSectionBoundaries[0]+(zWidthEM/2.);
00103       zz = (hitPointOrig.z() > 0.) ? zzlocal + Z0 : zzlocal - Z0;
00104       pos = G4ThreeVector(xx,yy,zz);
00105       posLocal = G4ThreeVector(xxlocal,yylocal,zzlocal);
00106         }
00107     if(i > 4){
00108       section = HcalZDCDetId::HAD;
00109       channel = i - 4;
00110       xxlocal = 0.0;
00111       xx = xxlocal + X0;  
00112       yylocal = 0;
00113       yy = yylocal + Y0;
00114       zzlocal = (hitPointOrig.z() > 0.) ? 
00115         theZHadChannelBoundaries[i-5] + (zWidthHAD/2.) : theZHadChannelBoundaries[i-5] - (zWidthHAD/2.);
00116       zz = (hitPointOrig.z() > 0.) ? zzlocal +  Z0 : zzlocal -  Z0; 
00117       pos = G4ThreeVector(xx,yy,zz);
00118       posLocal = G4ThreeVector(xxlocal,yylocal,zzlocal);
00119     }
00120     
00121     oneHit.position = pos;
00122     oneHit.entryLocal = posLocal;
00123     oneHit.depth    = channel;
00124     oneHit.time     = tSlice;
00125     oneHit.detID    = HcalZDCDetId(section,side,channel);
00126 
00127 
00128     // Note: coodinates of hit are relative to center of detector (X0,Y0,Z0) 
00129     hitPoint.setX(hitPointOrig.x()-X0);
00130     hitPoint.setY(hitPointOrig.y()-Y0);
00131     double setZ= (hitPointOrig.z()> 0.) ? hitPointOrig.z()- Z0 : fabs(hitPointOrig.z()) - Z0;
00132     hitPoint.setZ(setZ);
00133 
00134     int dE = getEnergyFromLibrary(hitPoint,momDir,energy,parCode,section,side,channel);
00135 
00136     int iparCode = encodePartID(parCode);
00137     if (iparCode == 0 ) {
00138       oneHit.DeEM  = dE; 
00139       oneHit.DeHad = 0.;
00140     } else {
00141       oneHit.DeEM  = 0; 
00142       oneHit.DeHad = dE;
00143     }
00144     
00145     hits.push_back(oneHit);
00146     
00147     LogDebug("ZdcShower")
00148       //std::cout
00149       << "\nZdcShowerLibrary:Generated Hit " << nHit 
00150       <<" orig hit pos " << hitPointOrig
00151       <<" orig hit pos local coord" << hitPoint
00152       <<" new position " << (hits[nHit].position) 
00153       <<" Channel " <<(hits[nHit].depth) 
00154       <<" side "<< side  
00155       <<" Time " <<(hits[nHit].time)
00156       <<" DetectorID " << (hits[nHit].detID)
00157       <<" Had Energy " << (hits[nHit].DeHad)
00158       <<" EM Energy  " << (hits[nHit].DeEM)
00159       <<"\n";
00160       nHit++;
00161   }
00162   return hits;
00163 }
00164 
00165 
00166 int ZdcShowerLibrary::getEnergyFromLibrary(G4ThreeVector hitPoint, G4ThreeVector momDir, double energy,
00167                                            G4int parCode,HcalZDCDetId::Section section, bool side, int channel){
00168   int nphotons = -1;
00169   
00170   energy =energy/GeV;
00171 
00172   LogDebug("ZdcShower") 
00173   //std::cout
00174     <<"\n ZdcShowerLibrary::getEnergyFromLibrary input/output variables:"
00175     <<" phi: "<<59.2956*momDir.phi()
00176     <<" theta: "<<59.2956*momDir.theta()
00177     <<" xin : "<<hitPoint.x()
00178     <<" yin : "<<hitPoint.y()
00179     <<" zin : "<<hitPoint.z()
00180     <<" track en: " <<energy<< "(GeV)"
00181     <<" section: "<<section
00182     <<" side: "<<side
00183     <<" channel: "<< channel
00184     <<" partID: "<<parCode;
00185   //std::cout<<std::endl;
00186     
00187   // these varables are not used for now
00188   //float phi   = 59.2956*momDir.phi();
00189   //float theta = 59.2956*momDir.theta();
00190   //float zin = hitPoint.z();
00191   //int isection = int(section);
00192   //int iside = (side)? 1 : 2;
00193      
00194   int iparCode  = encodePartID(parCode);
00195 
00196   double eav = 0.;
00197   double esig = 0.;
00198   double edis = 0.;
00199 
00200   float xin = hitPoint.x(); 
00201   float yin = hitPoint.y(); 
00202   float fact = 0.;
00203 
00204   if(section == 1 && iparCode !=0){
00205     if(channel < 5 )
00206       if(((theXChannelBoundaries[channel-1])< (xin + X0)) && ((xin + X0)<= theXChannelBoundaries[channel]))fact= 0.18;
00207     if(channel ==5 )
00208       if(theXChannelBoundaries[channel-1]< xin + X0)fact = 0.18;
00209   }
00210 
00211   if(section == 2 && iparCode !=0){    
00212     if(channel == 1)fact = 0.34;
00213     if(channel == 2)fact = 0.24;
00214     if(channel == 3)fact = 0.17;
00215     if(channel == 4)fact = 0.07;
00216   }
00217   if(section == 1 && iparCode ==0){                                                     
00218     if(channel < 5 )
00219       if(((theXChannelBoundaries[channel-1])< (xin + X0)) && ((xin + X0)<= theXChannelBoundaries[channel]))fact= 1.;
00220     if(channel ==5 )
00221       if(theXChannelBoundaries[channel-1]< xin + X0)fact = 1.0;
00222   }
00223 
00224   //change to cm for parametrization
00225   yin = yin/cm;
00226   xin = xin/cm;
00227 
00228   if (iparCode==0){          
00229     eav = ((((((-0.0002*xin-2.0e-13)*xin+0.0022)*xin+1.0e-11)*xin-0.0217)*xin-3.0e-10)*xin+1.0028)*
00230       (((0.0001*yin + 0.0056)*yin + 0.0508)*yin + 1.0)*300.0*pow((energy/300.0),0.99); // EM
00231     esig = ((((((0.0005*xin - 1.0e-12)*xin - 0.0052)*xin + 5.0e-11)*xin + 0.032)*xin - 
00232              2.0e-10)*xin + 1.0)*(((0.0006*yin + 0.0071)*yin - 0.031)*yin + 1.0)*30.0*pow((energy/300.0),0.54);// EM
00233     edis = 1.0;
00234   }else{
00235   eav = ((((((-0.0002*xin-2.0e-13)*xin+0.0022)*xin+1.0e-11)*xin-0.0217)*xin-3.0e-10)*xin+1.0028)*
00236     (((0.0001*yin + 0.0056)*yin + 0.0508)*yin + 1.0)*300.0*pow((energy/300.0),1.12);// HD
00237   esig = ((((((0.0005*xin - 1.0e-12)*xin - 0.0052)*xin + 5.0e-11)*xin + 0.032)*xin - 
00238            2.0e-10)*xin + 1.0)*(((0.0006*yin + 0.0071)*yin - 0.031)*yin + 1.0)*54.0*pow((energy/300.0),0.93); //HD
00239   edis = 3.0;
00240   }
00241   
00242   if(eav <0. || edis <0.){
00243     LogDebug("ZdcShower") 
00244       <<" Negative everage energy from parametrization \n" 
00245       <<" xin: "<<xin<< "(cm)"
00246       <<" yin: "<<yin<< "(cm)"
00247       <<" track en: " <<energy<< "(GeV)"
00248       <<" eaverage: "<<eav/GeV << " (GeV)"
00249       <<" esigma: "<<esig/GeV << "  (GeV)"
00250       <<" edist: "<<edis  << " (GeV)"
00251      <<" dE hit: "<<nphotons/GeV<<  " (GeV)";
00252     return 0;
00253   }
00254   
00255   // Convert from GeV to MeV for the code
00256   eav = eav*GeV;
00257   esig= esig*GeV;
00258 
00259   while(nphotons == -1 || nphotons > int(eav + 5.*esig))
00260     nphotons = (int)(fact*photonFluctuation(eav, esig, edis));
00261   
00262   LogDebug("ZdcShower") 
00263     //std::cout
00264     <<" track en: " <<energy<< "(GeV)"
00265     <<" eaverage: "<<eav/GeV << " (GeV)"
00266     <<" esigma: "<<esig/GeV << "  (GeV)"
00267     <<" edist: "<<edis  << " (GeV)"
00268     <<" dE hit: "<<nphotons/GeV<<  " (GeV)";
00269   //std::cout<<std::endl;
00270   
00271   return nphotons; 
00272 }
00273 
00274 int ZdcShowerLibrary::photonFluctuation(double eav, double esig,double edis){
00275   int nphot=0;
00276   double efluct = 0.;
00277   if(edis == 1.0) efluct = eav+esig*CLHEP::RandGaussQ::shoot();
00278   if(edis == 3.0) efluct = eav+esig*CLHEP::RandLandau::shoot();
00279   nphot = int(efluct);
00280   if(nphot<0)nphot = 0;
00281   return nphot;
00282 }
00283 
00284 int ZdcShowerLibrary::encodePartID(G4int parCode){
00285   G4int iparCode = 1;
00286   if (parCode == emPDG ||
00287       parCode == epPDG ||
00288       parCode == gammaPDG) {
00289     iparCode = 0;
00290   } else { return iparCode; }
00291   return iparCode;
00292 }