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 int status = 0;
00243 if ((beta > bThreshold) && (charge != 0) && (nameVolume == "ZDC_EMFiber" || nameVolume == "ZDC_HadFiber")) {
00244 status = 1;
00245 LogDebug("ForwardSim") << "ZdcSD:: getEnergyDeposit: pass ";
00246
00247 float nMedium = 1.4925;
00248
00249
00250
00251 float photEnSpectrDE = 1.24;
00252
00253
00254
00255
00256
00257 float effPMTandTransport = 0.15;
00258
00259
00260 float thFullRefl = 23.;
00261 float thFullReflRad = thFullRefl*pi/180.;
00262
00263 edm::ParameterSet m_ZdcSD = p.getParameter<edm::ParameterSet>("ZdcSD");
00264 thFibDir = m_ZdcSD.getParameter<double>("FiberDirection");
00265
00266 float thFibDirRad = thFibDir*pi/180.;
00267
00268
00269
00270
00271
00272 float costh = hit_mom.z()/sqrt(hit_mom.x()*hit_mom.x()+
00273 hit_mom.y()*hit_mom.y()+
00274 hit_mom.z()*hit_mom.z());
00275 float th = acos(std::min(std::max(costh,float(-1.)),float(1.)));
00276
00277 if (th < 0.) th += twopi;
00278
00279
00280 float costhcher =1./(nMedium*beta);
00281 float thcher = acos(std::min(std::max(costhcher,float(-1.)),float(1.)));
00282
00283
00284 float DelFibPart = fabs(th - thFibDirRad);
00285
00286
00287 float d = fabs(tan(th)-tan(thFibDirRad));
00288
00289
00290
00291 float a = tan(thFibDirRad)+tan(fabs(thFibDirRad-thFullReflRad));
00292 float r = tan(th)+tan(fabs(th-thcher));
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 float d_qz = -1;
00304 float variant = -1;
00305
00306
00307 if (DelFibPart > (thFullReflRad + thcher) ) {
00308 variant = 0.; d_qz = 0.;
00309 } else {
00310
00311 if ((th + thcher) < (thFibDirRad+thFullReflRad) && (th - thcher) > (thFibDirRad-thFullReflRad) ) {
00312 variant = 1.; d_qz = 1.;
00313 } else {
00314
00315 if ((thFibDirRad + thFullReflRad) < (th + thcher) && (thFibDirRad - thFullReflRad) > (th - thcher) ) {
00316 variant = 2.; d_qz = 0.;
00317 } else {
00318
00319 variant = 3.;
00320
00321
00322 float arg_arcos = 0.;
00323 float tan_arcos = 2.*a*d;
00324 if (tan_arcos != 0.) arg_arcos =(r*r-a*a-d*d)/tan_arcos;
00325
00326 arg_arcos = fabs(arg_arcos);
00327
00328 float th_arcos = acos(std::min(std::max(arg_arcos,float(-1.)),float(1.)));
00329
00330 d_qz = th_arcos/pi/2.;
00331
00332 d_qz = fabs(d_qz);
00333
00334 }
00335 }
00336 }
00337
00338
00339
00340 double meanNCherPhot = 0.;
00341 G4int poissNCherPhot = 0;
00342 if (d_qz > 0) {
00343 meanNCherPhot = 370.*charge*charge*( 1. - 1./(nMedium*nMedium*beta*beta) ) * photEnSpectrDE * stepL;
00344
00345
00346
00347 poissNCherPhot = (G4int) G4Poisson(meanNCherPhot);
00348
00349 if (poissNCherPhot < 0) poissNCherPhot = 0;
00350
00351
00352 NCherPhot = poissNCherPhot * effPMTandTransport * d_qz;
00353 }
00354
00355 LogDebug("ForwardSim")
00356 << "ZdcSD:: getEnergyDeposit: gED: "
00357 << stepE
00358 << "," << costh
00359 << "," << th
00360 << "," << costhcher
00361 << "," << thcher
00362 << "," << DelFibPart
00363 << "," << d
00364 << "," << a
00365 << "," << r
00366 << "," << hitPoint
00367 << "," << hit_mom
00368 << "," << stepControlFlag
00369 << "," << entot
00370 << "," << vert_mom
00371 << "," << localPoint
00372 << "," << charge
00373 << "," << beta
00374 << "," << stepL
00375 << "," << d_qz
00376 << "," << variant
00377 << "," << meanNCherPhot
00378 << "," << poissNCherPhot
00379 << "," << NCherPhot;
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 } else {
00395
00396 status = 0;
00397 if (beta <= bThreshold)
00398 LogDebug("ForwardSim")
00399 << "ZdcSD:: getEnergyDeposit: fail beta=" << beta;
00400 if (charge == 0)
00401 LogDebug("ForwardSim")
00402 << "ZdcSD:: getEnergyDeposit: fail charge=0";
00403 if ( !(nameVolume == "ZDC_EMFiber" || nameVolume == "ZDC_HadFiber") )
00404 LogDebug("ForwardSim")
00405 << "ZdcSD:: getEnergyDeposit: fail nv=" << nameVolume;
00406 }
00407
00408 return NCherPhot;
00409 }
00410 }
00411
00412 uint32_t ZdcSD::setDetUnitId(G4Step* aStep) {
00413 uint32_t returnNumber = 0;
00414 if(numberingScheme != 0)returnNumber = numberingScheme->getUnitID(aStep);
00415
00416 return returnNumber;
00417 }
00418
00419 void ZdcSD::setNumberingScheme(ZdcNumberingScheme* scheme) {
00420 if (scheme != 0) {
00421 edm::LogInfo("ForwardSim") << "ZdcSD: updates numbering scheme for "
00422 << GetName();
00423 if (numberingScheme) delete numberingScheme;
00424 numberingScheme = scheme;
00425 }
00426 }
00427
00428 int ZdcSD::setTrackID (G4Step* aStep) {
00429 theTrack = aStep->GetTrack();
00430 double etrack = preStepPoint->GetKineticEnergy();
00431 TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
00432 int primaryID = trkInfo->getIDonCaloSurface();
00433 if (primaryID == 0) {
00434 #ifdef DebugLog
00435 LogDebug("ZdcSD") << "ZdcSD: Problem with primaryID **** set by force "
00436 << "to TkID **** " << theTrack->GetTrackID();
00437 #endif
00438 primaryID = theTrack->GetTrackID();
00439 }
00440 if (primaryID != previousID.trackID())
00441 resetForNewPrimary(preStepPoint->GetPosition(), etrack);
00442 return primaryID;
00443 }