00001
00002
00003
00004
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;
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
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
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
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
00186
00187
00188
00189
00190
00191
00192
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
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);
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);
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);
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);
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
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
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
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 }