00001
00002
00003
00004
00005
00007 #include "SimG4CMS/Forward/interface/ZdcSD.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "G4SDManager.hh"
00010 #include "G4Step.hh"
00011 #include "G4Track.hh"
00012 #include "G4VProcess.hh"
00013 #include "SimG4Core/Notification/interface/TrackInformation.h"
00014 #include "G4ios.hh"
00015 #include "G4Cerenkov.hh"
00016 #include "G4ParticleTable.hh"
00017 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00018 #include "Randomize.hh"
00019 #include "G4Poisson.hh"
00020
00021 ZdcSD::ZdcSD(G4String name, const DDCompactView & cpv,
00022 SensitiveDetectorCatalog & clg,
00023 edm::ParameterSet const & p,const SimTrackManager* manager) :
00024 CaloSD(name, cpv, clg, p, manager), numberingScheme(0) {
00025 edm::ParameterSet m_ZdcSD = p.getParameter<edm::ParameterSet>("ZdcSD");
00026 useShowerLibrary = m_ZdcSD.getParameter<bool>("UseShowerLibrary");
00027 useShowerHits = m_ZdcSD.getParameter<bool>("UseShowerHits");
00028 zdcHitEnergyCut = m_ZdcSD.getParameter<double>("ZdcHitEnergyCut")*GeV;
00029 verbosity = m_ZdcSD.getParameter<int>("Verbosity");
00030 int verbn = verbosity/10;
00031 verbosity %= 10;
00032 ZdcNumberingScheme* scheme;
00033 scheme = new ZdcNumberingScheme(verbn);
00034 setNumberingScheme(scheme);
00035
00036 edm::LogInfo("ForwardSim")
00037 << "***************************************************\n"
00038 << "* *\n"
00039 << "* Constructing a ZdcSD with name " << name <<" *\n"
00040 << "* *\n"
00041 << "***************************************************";
00042
00043 edm::LogInfo("ForwardSim")
00044 << "\nUse of shower library is set to "
00045 << useShowerLibrary
00046 << "\nUse of Shower hits method is set to "
00047 << useShowerHits;
00048
00049 edm::LogInfo("ForwardSim")
00050 << "\nEnergy Threshold Cut set to "
00051 << zdcHitEnergyCut/GeV
00052 <<" (GeV)";
00053
00054 if(useShowerLibrary){
00055 showerLibrary = new ZdcShowerLibrary(name, cpv, p);
00056 }
00057 }
00058
00059 ZdcSD::~ZdcSD() {
00060
00061 if(numberingScheme) delete numberingScheme;
00062 if(showerLibrary)delete showerLibrary;
00063
00064 edm::LogInfo("ForwardSim")
00065 <<"end of ZdcSD\n";
00066 }
00067
00068 void ZdcSD::initRun(){
00069 if(useShowerLibrary){
00070 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
00071 showerLibrary->initRun(theParticleTable);
00072 }
00073 hits.clear();
00074 }
00075
00076 bool ZdcSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
00077
00078 NaNTrap( aStep ) ;
00079
00080 if (aStep == NULL) {
00081 return true;
00082 } else {
00083 if(useShowerLibrary){
00084 getFromLibrary(aStep);
00085 }
00086 if(useShowerHits){
00087 if (getStepInfo(aStep)) {
00088 if (hitExists() == false && edepositEM+edepositHAD>0.)
00089 currentHit = CaloSD::createNewHit();
00090 }
00091 }
00092 }
00093 return true;
00094 }
00095
00096 void ZdcSD::getFromLibrary (G4Step* aStep) {
00097 bool ok = true;
00098
00099 preStepPoint = aStep->GetPreStepPoint();
00100 theTrack = aStep->GetTrack();
00101
00102 double etrack = preStepPoint->GetKineticEnergy();
00103 int primaryID = setTrackID(aStep);
00104
00105 hits.clear();
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 posGlobal = preStepPoint->GetPosition();
00118 resetForNewPrimary(posGlobal, etrack);
00119
00120 if (etrack >= zdcHitEnergyCut){
00121
00122
00123 LogDebug("ForwardSim")
00124
00125 <<"----------------New track------------------------------\n"
00126 <<"Incident EnergyTrack: "<<etrack<< " MeV \n"
00127 <<"Zdc Cut Energy for Hits: "<<zdcHitEnergyCut<<" MeV \n"
00128 << "ZdcSD::getFromLibrary " <<hits.size() <<" hits for "
00129 << GetName() << " of " << primaryID << " with "
00130 << theTrack->GetDefinition()->GetParticleName() << " of "
00131 << preStepPoint->GetKineticEnergy()<< " MeV\n";
00132
00133 hits.swap(showerLibrary->getHits(aStep, ok));
00134 }
00135
00136 entrancePoint = preStepPoint->GetPosition();
00137 for (unsigned int i=0; i<hits.size(); i++) {
00138 posGlobal = hits[i].position;
00139 entranceLocal = hits[i].entryLocal;
00140 double time = hits[i].time;
00141 unsigned int unitID = hits[i].detID;
00142 edepositHAD = hits[i].DeHad;
00143 edepositEM = hits[i].DeEM;
00144 currentID.setID(unitID, time, primaryID);
00145
00146
00147 if (currentID == previousID) {
00148 updateHit(currentHit);
00149 } else {
00150 currentHit = createNewHit();
00151 }
00152
00153
00154
00155
00156 currentHit->setIncidentEnergy(etrack);
00157
00158
00159 LogDebug("ForwardSim") << "ZdcSD: Final Hit number:"<<i<<"-->"
00160 <<"New HitID: "<<currentHit->getUnitID()
00161 <<" New Hit trackID: "<<currentHit->getTrackID()
00162 <<" New EM Energy: "<<currentHit->getEM()/GeV
00163 <<" New HAD Energy: "<<currentHit->getHadr()/GeV
00164 <<" New HitEntryPoint: "<<currentHit->getEntryLocal()
00165 <<" New IncidentEnergy: "<<currentHit->getIncidentEnergy()/GeV
00166 <<" New HitPosition: "<<posGlobal;
00167 }
00168
00169
00170 if (ok) {
00171 theTrack->SetTrackStatus(fStopAndKill);
00172 G4TrackVector tv = *(aStep->GetSecondary());
00173 for (unsigned int kk=0; kk<tv.size(); kk++) {
00174 if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume())
00175 tv[kk]->SetTrackStatus(fStopAndKill);
00176 }
00177 }
00178 }
00179
00180 double ZdcSD::getEnergyDeposit(G4Step * aStep, edm::ParameterSet const & p ) {
00181
00182 float NCherPhot = 0.;
00183
00184
00185 if (aStep == NULL) {
00186 LogDebug("ForwardSim") << "ZdcSD:: getEnergyDeposit: aStep is NULL!";
00187 return 0;
00188 } else {
00189
00190 G4SteppingControl stepControlFlag = aStep->GetControlFlag();
00191 G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
00192 G4VPhysicalVolume* currentPV = preStepPoint->GetPhysicalVolume();
00193 G4String nameVolume = currentPV->GetName();
00194
00195 G4ThreeVector hitPoint = preStepPoint->GetPosition();
00196 G4ThreeVector hit_mom = preStepPoint->GetMomentumDirection();
00197 G4double stepL = aStep->GetStepLength()/cm;
00198 G4double beta = preStepPoint->GetBeta();
00199 G4double charge = preStepPoint->GetCharge();
00200
00201
00202
00203
00204
00205
00206
00207
00208 G4StepPoint* postStepPoint = aStep->GetPostStepPoint();
00209 G4VPhysicalVolume* postPV = postStepPoint->GetPhysicalVolume();
00210 G4String postnameVolume = postPV->GetName();
00211
00212
00213 G4Track* theTrack = aStep->GetTrack();
00214 G4String particleType = theTrack->GetDefinition()->GetParticleName();
00215 G4int primaryID = theTrack->GetTrackID();
00216 G4double entot = theTrack->GetTotalEnergy();
00217 G4ThreeVector vert_mom = theTrack->GetVertexMomentumDirection();
00218 G4ThreeVector localPoint = theTrack->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
00219
00220
00221 float costheta = vert_mom.z()/sqrt(vert_mom.x()*vert_mom.x()+
00222 vert_mom.y()*vert_mom.y()+
00223 vert_mom.z()*vert_mom.z());
00224 float theta = acos(std::min(std::max(costheta,float(-1.)),float(1.)));
00225 float eta = -log(tan(theta/2));
00226 float phi = -100.;
00227 if (vert_mom.x() != 0) phi = atan2(vert_mom.y(),vert_mom.x());
00228 if (phi < 0.) phi += twopi;
00229
00230
00231 double stepE = aStep->GetTotalEnergyDeposit();
00232 LogDebug("ForwardSim")
00233 << "ZdcSD:: getEnergyDeposit: "
00234 <<"*****************HHHHHHHHHHHHHHHHHHHHHHHHHHLLLLLLLLLlllllllllll&&&&&&&&&&\n"
00235 << " preStepPoint: " << nameVolume << "," << stepL << "," << stepE
00236 << "," << beta << "," << charge << "\n"
00237 << " postStepPoint: " << postnameVolume << "," << costheta << ","
00238 << theta << "," << eta << "," << phi << "," << particleType << ","
00239 << primaryID;
00240
00241 float bThreshold = 0.67;
00242 if ((beta > bThreshold) && (charge != 0) && (nameVolume == "ZDC_EMFiber" || nameVolume == "ZDC_HadFiber")) {
00243 LogDebug("ForwardSim") << "ZdcSD:: getEnergyDeposit: pass ";
00244
00245 float nMedium = 1.4925;
00246
00247
00248
00249 float photEnSpectrDE = 1.24;
00250
00251
00252
00253
00254
00255 float effPMTandTransport = 0.15;
00256
00257
00258 float thFullRefl = 23.;
00259 float thFullReflRad = thFullRefl*pi/180.;
00260
00261 edm::ParameterSet m_ZdcSD = p.getParameter<edm::ParameterSet>("ZdcSD");
00262 thFibDir = m_ZdcSD.getParameter<double>("FiberDirection");
00263
00264 float thFibDirRad = thFibDir*pi/180.;
00265
00266
00267
00268
00269
00270 float costh = hit_mom.z()/sqrt(hit_mom.x()*hit_mom.x()+
00271 hit_mom.y()*hit_mom.y()+
00272 hit_mom.z()*hit_mom.z());
00273 float th = acos(std::min(std::max(costh,float(-1.)),float(1.)));
00274
00275 if (th < 0.) th += twopi;
00276
00277
00278 float costhcher =1./(nMedium*beta);
00279 float thcher = acos(std::min(std::max(costhcher,float(-1.)),float(1.)));
00280
00281
00282 float DelFibPart = fabs(th - thFibDirRad);
00283
00284
00285 float d = fabs(tan(th)-tan(thFibDirRad));
00286
00287
00288
00289 float a = tan(thFibDirRad)+tan(fabs(thFibDirRad-thFullReflRad));
00290 float r = tan(th)+tan(fabs(th-thcher));
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 float d_qz = -1;
00302 float variant = -1;
00303
00304
00305 if (DelFibPart > (thFullReflRad + thcher) ) {
00306 variant = 0.; d_qz = 0.;
00307 } else {
00308
00309 if ((th + thcher) < (thFibDirRad+thFullReflRad) && (th - thcher) > (thFibDirRad-thFullReflRad) ) {
00310 variant = 1.; d_qz = 1.;
00311 } else {
00312
00313 if ((thFibDirRad + thFullReflRad) < (th + thcher) && (thFibDirRad - thFullReflRad) > (th - thcher) ) {
00314 variant = 2.; d_qz = 0.;
00315 } else {
00316
00317 variant = 3.;
00318
00319
00320 float arg_arcos = 0.;
00321 float tan_arcos = 2.*a*d;
00322 if (tan_arcos != 0.) arg_arcos =(r*r-a*a-d*d)/tan_arcos;
00323
00324 arg_arcos = fabs(arg_arcos);
00325
00326 float th_arcos = acos(std::min(std::max(arg_arcos,float(-1.)),float(1.)));
00327
00328 d_qz = th_arcos/pi/2.;
00329
00330 d_qz = fabs(d_qz);
00331
00332 }
00333 }
00334 }
00335
00336
00337
00338 double meanNCherPhot = 0.;
00339 G4int poissNCherPhot = 0;
00340 if (d_qz > 0) {
00341 meanNCherPhot = 370.*charge*charge*( 1. - 1./(nMedium*nMedium*beta*beta) ) * photEnSpectrDE * stepL;
00342
00343
00344
00345 poissNCherPhot = (G4int) G4Poisson(meanNCherPhot);
00346
00347 if (poissNCherPhot < 0) poissNCherPhot = 0;
00348
00349
00350 NCherPhot = poissNCherPhot * effPMTandTransport * d_qz;
00351 }
00352
00353 LogDebug("ForwardSim")
00354 << "ZdcSD:: getEnergyDeposit: gED: "
00355 << stepE
00356 << "," << costh
00357 << "," << th
00358 << "," << costhcher
00359 << "," << thcher
00360 << "," << DelFibPart
00361 << "," << d
00362 << "," << a
00363 << "," << r
00364 << "," << hitPoint
00365 << "," << hit_mom
00366 << "," << stepControlFlag
00367 << "," << entot
00368 << "," << vert_mom
00369 << "," << localPoint
00370 << "," << charge
00371 << "," << beta
00372 << "," << stepL
00373 << "," << d_qz
00374 << "," << variant
00375 << "," << meanNCherPhot
00376 << "," << poissNCherPhot
00377 << "," << NCherPhot;
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 } else {
00393
00394 if (beta <= bThreshold)
00395 LogDebug("ForwardSim")
00396 << "ZdcSD:: getEnergyDeposit: fail beta=" << beta;
00397 if (charge == 0)
00398 LogDebug("ForwardSim")
00399 << "ZdcSD:: getEnergyDeposit: fail charge=0";
00400 if ( !(nameVolume == "ZDC_EMFiber" || nameVolume == "ZDC_HadFiber") )
00401 LogDebug("ForwardSim")
00402 << "ZdcSD:: getEnergyDeposit: fail nv=" << nameVolume;
00403 }
00404
00405 return NCherPhot;
00406 }
00407 }
00408
00409 uint32_t ZdcSD::setDetUnitId(G4Step* aStep) {
00410 uint32_t returnNumber = 0;
00411 if(numberingScheme != 0)returnNumber = numberingScheme->getUnitID(aStep);
00412
00413 return returnNumber;
00414 }
00415
00416 void ZdcSD::setNumberingScheme(ZdcNumberingScheme* scheme) {
00417 if (scheme != 0) {
00418 edm::LogInfo("ForwardSim") << "ZdcSD: updates numbering scheme for "
00419 << GetName();
00420 if (numberingScheme) delete numberingScheme;
00421 numberingScheme = scheme;
00422 }
00423 }
00424
00425 int ZdcSD::setTrackID (G4Step* aStep) {
00426 theTrack = aStep->GetTrack();
00427 double etrack = preStepPoint->GetKineticEnergy();
00428 TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
00429 int primaryID = trkInfo->getIDonCaloSurface();
00430 if (primaryID == 0) {
00431 #ifdef DebugLog
00432 LogDebug("ZdcSD") << "ZdcSD: Problem with primaryID **** set by force "
00433 << "to TkID **** " << theTrack->GetTrackID();
00434 #endif
00435 primaryID = theTrack->GetTrackID();
00436 }
00437 if (primaryID != previousID.trackID())
00438 resetForNewPrimary(preStepPoint->GetPosition(), etrack);
00439 return primaryID;
00440 }