CMS 3D CMS Logo

ZdcSD.cc
Go to the documentation of this file.
1 // File: ZdcSD.cc
3 // Date: 03.01
4 // Description: Sensitive Detector class for Zdc
5 // Modifications:
10 
11 #include "G4SDManager.hh"
12 #include "G4Step.hh"
13 #include "G4Track.hh"
14 #include "G4VProcess.hh"
15 #include "G4ios.hh"
16 #include "G4Cerenkov.hh"
17 #include "G4ParticleTable.hh"
18 #include "CLHEP/Units/GlobalSystemOfUnits.h"
19 #include "CLHEP/Units/GlobalPhysicalConstants.h"
20 #include "Randomize.hh"
21 #include "G4Poisson.hh"
22 
24  const SensitiveDetectorCatalog & clg,
25  edm::ParameterSet const & p,const SimTrackManager* manager) :
26  CaloSD(name, cpv, clg, p, manager){
27  edm::ParameterSet m_ZdcSD = p.getParameter<edm::ParameterSet>("ZdcSD");
28  useShowerLibrary = m_ZdcSD.getParameter<bool>("UseShowerLibrary");
29  useShowerHits = m_ZdcSD.getParameter<bool>("UseShowerHits");
30  zdcHitEnergyCut = m_ZdcSD.getParameter<double>("ZdcHitEnergyCut")*GeV;
31  thFibDir = m_ZdcSD.getParameter<double>("FiberDirection");
32  verbosity = m_ZdcSD.getParameter<int>("Verbosity");
33  int verbn = verbosity/10;
34  verbosity %= 10;
36 
37  edm::LogInfo("ForwardSim")
38  << "***************************************************\n"
39  << "* *\n"
40  << "* Constructing a ZdcSD with name " << name <<" *\n"
41  << "* *\n"
42  << "***************************************************";
43 
44  edm::LogInfo("ForwardSim")
45  << "\nUse of shower library is set to "
46  << useShowerLibrary
47  << "\nUse of Shower hits method is set to "
48  << useShowerHits;
49 
50  edm::LogInfo("ForwardSim")
51  << "\nEnergy Threshold Cut set to "
52  << zdcHitEnergyCut/GeV
53  <<" (GeV)";
54 
55  if(useShowerLibrary){
56  showerLibrary.reset(new ZdcShowerLibrary(name, cpv, p));
57  setParameterized(true);
58  } else {
59  showerLibrary.reset(nullptr);
60  }
61 }
62 
64  hits.clear();
65 }
66 
67 bool ZdcSD::getFromLibrary (const G4Step* aStep) {
68  bool ok = true;
69 
70  auto const preStepPoint = aStep->GetPreStepPoint();
71  auto const theTrack = aStep->GetTrack();
72 
73  double etrack = preStepPoint->GetKineticEnergy();
74  int primaryID = setTrackID(aStep);
75 
76  hits.clear();
77 
78  // Reset entry point for new primary
79  resetForNewPrimary(aStep);
80 
81  if (etrack >= zdcHitEnergyCut){
82  // create hits only if above threshold
83 
84  LogDebug("ForwardSim")
85  <<"----------------New track------------------------------\n"
86  <<"Incident EnergyTrack: "<<etrack<< " MeV \n"
87  <<"Zdc Cut Energy for Hits: "<<zdcHitEnergyCut<<" MeV \n"
88  << "ZdcSD::getFromLibrary " <<hits.size() <<" hits for "
89  << GetName() << " of " << primaryID << " with "
90  << theTrack->GetDefinition()->GetParticleName() << " of "
91  << etrack<< " MeV\n";
92 
93  hits.swap(showerLibrary.get()->getHits(aStep, ok));
94  }
95 
96  incidentEnergy= etrack;
97  entrancePoint = preStepPoint->GetPosition();
98  for (unsigned int i=0; i<hits.size(); i++) {
99  posGlobal = hits[i].position;
100  entranceLocal = hits[i].entryLocal;
101  double time = hits[i].time;
102  unsigned int unitID = hits[i].detID;
103  edepositHAD = hits[i].DeHad;
104  edepositEM = hits[i].DeEM;
105  currentID.setID(unitID, time, primaryID, 0);
106  processHit(aStep);
107 
108  LogDebug("ForwardSim") << "ZdcSD: Final Hit number:"<<i<<"-->"
109  <<"New HitID: "<<currentHit->getUnitID()
110  <<" New Hit trackID: "<<currentHit->getTrackID()
111  <<" New EM Energy: "<<currentHit->getEM()/GeV
112  <<" New HAD Energy: "<<currentHit->getHadr()/GeV
113  <<" New HitEntryPoint: "<<currentHit->getEntryLocal()
114  <<" New IncidentEnergy: "<<currentHit->getIncidentEnergy()/GeV
115  <<" New HitPosition: "<<posGlobal;
116  }
117  return ok;
118 }
119 
120 double ZdcSD::getEnergyDeposit(const G4Step * aStep) {
121 
122  double NCherPhot = 0.;
123 
124  // preStepPoint information
125  G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
126  G4VPhysicalVolume* currentPV = preStepPoint->GetPhysicalVolume();
127  const G4String& nameVolume = currentPV->GetName();
128 
129  const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
130  const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
131  G4double stepL = aStep->GetStepLength()/cm;
132  G4double beta = preStepPoint->GetBeta();
133  G4double charge = preStepPoint->GetCharge();
134 
135  // postStepPoint information
136  G4StepPoint* postStepPoint = aStep->GetPostStepPoint();
137  G4VPhysicalVolume* postPV = postStepPoint->GetPhysicalVolume();
138  const G4String& postnameVolume = postPV->GetName();
139 
140  // theTrack information
141  G4Track* theTrack = aStep->GetTrack();
142  G4String particleType = theTrack->GetDefinition()->GetParticleName();
143  const G4ThreeVector& vert_mom = theTrack->GetVertexMomentumDirection();
144  G4ThreeVector localPoint = theTrack->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
145 
146  // calculations
147  float costheta = vert_mom.z()/sqrt(vert_mom.x()*vert_mom.x()+
148  vert_mom.y()*vert_mom.y()+
149  vert_mom.z()*vert_mom.z());
150  float theta = std::acos(std::min(std::max(costheta,-1.f),1.f));
151  float eta = -std::log(std::tan(theta*0.5f));
152  float phi = -100.;
153  if (vert_mom.x() != 0) phi = std::atan2(vert_mom.y(),vert_mom.x());
154  if (phi < 0.) phi += twopi;
155 
156  // Get the total energy deposit
157  double stepE = aStep->GetTotalEnergyDeposit();
158  LogDebug("ForwardSim")
159  << "ZdcSD:: getEnergyDeposit: \n"
160  << " preStepPoint: " << nameVolume << "," << stepL << "," << stepE
161  << "," << beta << "," << charge << "\n"
162  << " postStepPoint: " << postnameVolume << "," << costheta << ","
163  << theta << "," << eta << "," << phi << "," << particleType << " id= "
164  << theTrack->GetTrackID() << " Etot(GeV)= " << theTrack->GetTotalEnergy()/GeV;
165 
166  const double bThreshold = 0.67;
167  if ((beta > bThreshold) && (charge != 0) && (nameVolume == "ZDC_EMFiber" || nameVolume == "ZDC_HadFiber")) {
168  LogDebug("ForwardSim") << "ZdcSD:: getEnergyDeposit: pass ";
169 
170  const float nMedium = 1.4925;
171  // float photEnSpectrDL = 10714.285714;
172  // photEnSpectrDL = (1./400.nm-1./700.nm)*10000000.cm/nm; /* cm-1 */
173 
174  const float photEnSpectrDE = 1.24;
175  // E = 2pi*(1./137.)*(eV*cm/370.)/lambda = 12.389184*(eV*cm)/lambda
176  // Emax = 12.389184*(eV*cm)/400nm*10-7cm/nm = 3.01 eV
177  // Emin = 12.389184*(eV*cm)/700nm*10-7cm/nm = 1.77 eV
178  // delE = Emax - Emin = 1.24 eV
179 
180  const float effPMTandTransport = 0.15;
181 
182  // Check these values
183  const float thFullRefl = 23.;
184  float thFullReflRad = thFullRefl*pi/180.;
185 
186  float thFibDirRad = thFibDir*pi/180.;
187 
188  // at which theta the point is located:
189  // float th1 = hitPoint.theta();
190 
191  // theta of charged particle in LabRF(hit momentum direction):
192  float costh = hit_mom.z()/sqrt(hit_mom.x()*hit_mom.x()+
193  hit_mom.y()*hit_mom.y()+
194  hit_mom.z()*hit_mom.z());
195  float th = acos(std::min(std::max(costh,-1.f),1.f));
196  // just in case (can do both standard ranges of phi):
197  if (th < 0.) th += twopi;
198 
199  // theta of cone with Cherenkov photons w.r.t.direction of charged part.:
200  float costhcher =1./(nMedium*beta);
201  float thcher = acos(std::min(std::max(costhcher,-1.f),1.f));
202 
203  // diff thetas of charged part. and quartz direction in LabRF:
204  float DelFibPart = std::abs(th - thFibDirRad);
205 
206  // define real distances:
207  float d = std::abs(std::tan(th)-std::tan(thFibDirRad));
208 
209  float a = std::tan(thFibDirRad)+std::tan(std::abs(thFibDirRad-thFullReflRad));
210  float r = std::tan(th)+std::tan(std::abs(th-thcher));
211 
212  // define losses d_qz in cone of full reflection inside quartz direction
213  float d_qz = -1;
214  float variant = -1;
215 
216  // if (d > (r+a))
217  if (DelFibPart > (thFullReflRad + thcher) ) {
218  variant = 0.; d_qz = 0.;
219  } else {
220  // if ((DelFibPart + thcher) < thFullReflRad ) [(d+r) < a]
221  if ((th + thcher) < (thFibDirRad+thFullReflRad) && (th - thcher) > (thFibDirRad-thFullReflRad) ) {
222  variant = 1.; d_qz = 1.;
223  } else {
224  // if ((thcher - DelFibPart ) > thFullReflRad ) [(r-d) > a]
225  if ((thFibDirRad + thFullReflRad) < (th + thcher) && (thFibDirRad - thFullReflRad) > (th - thcher) ) {
226  variant = 2.; d_qz = 0.;
227  } else {
228  variant = 3.; // d_qz is calculated below
229 
230  // use crossed length of circles(cone projection) - dC1/dC2 :
231  float arg_arcos = 0.;
232  float tan_arcos = 2.*a*d;
233  if (tan_arcos != 0.) arg_arcos =(r*r-a*a-d*d)/tan_arcos;
234  // std::cout.testOut << " d_qz: " << r << "," << a << "," << d << " " << tan_arcos << " " << arg_arcos;
235  arg_arcos = std::abs(arg_arcos);
236  // std::cout.testOut << "," << arg_arcos;
237  float th_arcos = acos(std::min(std::max(arg_arcos,-1.f),1.f));
238  // std::cout.testOut << " " << th_arcos;
239  d_qz = th_arcos/twopi;
240  // std::cout.testOut << " " << d_qz;
241  d_qz = std::abs(d_qz);
242  // std::cout.testOut << "," << d_qz;
243  }
244  }
245  }
246  double meanNCherPhot = 0.;
247  int poissNCherPhot = 0;
248  if (d_qz > 0) {
249  meanNCherPhot = 370.*charge*charge*( 1. - 1./(nMedium*nMedium*beta*beta) ) * photEnSpectrDE * stepL;
250 
251  poissNCherPhot = std::max((int)G4Poisson(meanNCherPhot),0);
252  NCherPhot = poissNCherPhot * effPMTandTransport * d_qz;
253  }
254 
255  LogDebug("ForwardSim")
256  << "ZdcSD:: getEnergyDeposit: gED: "
257  << stepE
258  << "," << costh
259  << "," << th
260  << "," << costhcher
261  << "," << thcher
262  << "," << DelFibPart
263  << "," << d
264  << "," << a
265  << "," << r
266  << "," << hitPoint
267  << "," << hit_mom
268  << "," << vert_mom
269  << "," << localPoint
270  << "," << charge
271  << "," << beta
272  << "," << stepL
273  << "," << d_qz
274  << "," << variant
275  << "," << meanNCherPhot
276  << "," << poissNCherPhot
277  << "," << NCherPhot;
278  // --constants-----------------
279  // << "," << photEnSpectrDE
280  // << "," << nMedium
281  // << "," << bThreshold
282  // << "," << thFibDirRad
283  // << "," << thFullReflRad
284  // << "," << effPMTandTransport
285  // --other variables-----------
286  // << "," << curprocess
287  // << "," << nameProcess
288  // << "," << name
289  // << "," << rad
290  // << "," << mat
291 
292  } else {
293  // determine failure mode: beta, charge, and/or nameVolume
294  if (beta <= bThreshold)
295  LogDebug("ForwardSim")
296  << "ZdcSD:: getEnergyDeposit: fail beta=" << beta;
297  if (charge == 0)
298  LogDebug("ForwardSim")
299  << "ZdcSD:: getEnergyDeposit: fail charge=0";
300  if ( !(nameVolume == "ZDC_EMFiber" || nameVolume == "ZDC_HadFiber") )
301  LogDebug("ForwardSim")
302  << "ZdcSD:: getEnergyDeposit: fail nv=" << nameVolume;
303  }
304 
305  return NCherPhot;
306 }
307 
308 uint32_t ZdcSD::setDetUnitId(const G4Step* aStep) {
309  return (numberingScheme.get() == nullptr ? 0 : numberingScheme.get()->getUnitID(aStep));
310 }
311 
313  if (scheme != nullptr) {
314  edm::LogInfo("ForwardSim") << "ZdcSD: updates numbering scheme for "
315  << GetName();
316  numberingScheme.reset(scheme);
317  }
318 }
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:130
void setNumberingScheme(ZdcNumberingScheme *scheme)
Definition: ZdcSD.cc:312
double thFibDir
Definition: ZdcSD.h:35
T getParameter(std::string const &) const
std::unique_ptr< ZdcNumberingScheme > numberingScheme
Definition: ZdcSD.h:39
const double GeV
Definition: MathUtil.h:16
Definition: CaloSD.h:37
int verbosity
Definition: ZdcSD.h:33
std::vector< ZdcShowerLibrary::Hit > hits
Definition: ZdcSD.h:40
Geom::Theta< T > theta() const
double getIncidentEnergy() const
Definition: CaloG4Hit.h:65
G4ThreeVector posGlobal
Definition: CaloSD.h:128
bool useShowerHits
Definition: ZdcSD.h:34
void processHit(const G4Step *step)
Definition: CaloSD.h:102
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
const Double_t pi
ZdcSD(const std::string &, const DDCompactView &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: ZdcSD.cc:23
float edepositHAD
Definition: CaloSD.h:130
T sqrt(T t)
Definition: SSEVec.h:18
void resetForNewPrimary(const G4Step *)
Definition: CaloSD.cc:447
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
CaloG4Hit * currentHit
Definition: CaloSD.h:136
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
int getTrackID() const
Definition: CaloG4Hit.h:68
CaloHitID currentID
Definition: CaloSD.h:132
void initRun() override
Definition: ZdcSD.cc:63
double getEM() const
Definition: CaloG4Hit.h:59
std::unique_ptr< ZdcShowerLibrary > showerLibrary
Definition: ZdcSD.h:38
float incidentEnergy
Definition: CaloSD.h:129
virtual int setTrackID(const G4Step *)
Definition: CaloSD.cc:621
double a
Definition: hdecay.h:121
double zdcHitEnergyCut
Definition: ZdcSD.h:36
math::XYZPoint getEntryLocal() const
Definition: CaloG4Hit.h:53
uint32_t getUnitID() const
Definition: CaloG4Hit.h:69
bool getFromLibrary(const G4Step *) override
Definition: ZdcSD.cc:67
uint32_t setDetUnitId(const G4Step *step) override
Definition: ZdcSD.cc:308
bool useShowerLibrary
Definition: ZdcSD.h:34
G4ThreeVector entrancePoint
Definition: CaloSD.h:126
G4ThreeVector entranceLocal
Definition: CaloSD.h:127
double getHadr() const
Definition: CaloG4Hit.h:62
double getEnergyDeposit(const G4Step *) override
Definition: ZdcSD.cc:120
void setParameterized(bool val)
Definition: CaloSD.h:99