CMS 3D CMS Logo

DreamSD.cc
Go to the documentation of this file.
1 
8 
9 #include "G4LogicalVolumeStore.hh"
10 #include "G4LogicalVolume.hh"
11 #include "G4Step.hh"
12 #include "G4Track.hh"
13 #include "G4VProcess.hh"
14 #include "G4Poisson.hh"
15 
16 // Histogramming
19 #include <TTree.h>
20 
21 // Cherenkov
24 
25 #include "G4SystemOfUnits.hh"
26 #include "G4PhysicalConstants.hh"
27 
28 //________________________________________________________________________________________
30  const SensitiveDetectorCatalog & clg,
31  edm::ParameterSet const & p, const SimTrackManager* manager) :
32  CaloSD(name, cpv, clg, p, manager) {
33 
35  useBirk= m_EC.getParameter<bool>("UseBirkLaw");
36  doCherenkov_ = m_EC.getParameter<bool>("doCherenkov");
37  birk1 = m_EC.getParameter<double>("BirkC1")*(g/(MeV*cm2));
38  birk2 = m_EC.getParameter<double>("BirkC2");
39  birk3 = m_EC.getParameter<double>("BirkC3");
40  slopeLY= m_EC.getParameter<double>("SlopeLightYield");
41  readBothSide_ = m_EC.getUntrackedParameter<bool>("ReadBothSide", false);
42 
43  chAngleIntegrals_.reset(nullptr);
44 
45  edm::LogInfo("EcalSim") << "Constructing a DreamSD with name " << GetName() << "\n"
46  << "DreamSD:: Use of Birks law is set to "
47  << useBirk << " with three constants kB = "
48  << birk1 << ", C1 = " << birk2 << ", C2 = "
49  << birk3 << "\n"
50  << " Slope for Light yield is set to "
51  << slopeLY << "\n"
52  << " Parameterization of Cherenkov is set to "
53  << doCherenkov_ << " and readout both sides is "
54  << readBothSide_;
55 
56  initMap(name,cpv);
57 
58  // Init histogramming
60 
61  if ( !tfile.isAvailable() )
62  throw cms::Exception("BadConfig") << "TFileService unavailable: "
63  << "please add it to config file";
64 
65  ntuple_ = tfile->make<TTree>("tree","Cherenkov photons");
66  if (doCherenkov_) {
67  ntuple_->Branch("nphotons",&nphotons_,"nphotons/I");
68  ntuple_->Branch("px",px_,"px[nphotons]/F");
69  ntuple_->Branch("py",py_,"py[nphotons]/F");
70  ntuple_->Branch("pz",pz_,"pz[nphotons]/F");
71  ntuple_->Branch("x",x_,"x[nphotons]/F");
72  ntuple_->Branch("y",y_,"y[nphotons]/F");
73  ntuple_->Branch("z",z_,"z[nphotons]/F");
74  }
75 
76 }
77 
78 //________________________________________________________________________________________
79 bool DreamSD::ProcessHits(G4Step * aStep, G4TouchableHistory *) {
80 
81  if (aStep == nullptr) {
82  return true;
83  } else {
84  side = 1;
85  if (getStepInfo(aStep)) {
86  if (hitExists() == false && edepositEM+edepositHAD>0.)
88  if (readBothSide_) {
89  side = -1;
90  getStepInfo(aStep);
91  if (hitExists() == false && edepositEM+edepositHAD>0.)
93  }
94  }
95  }
96  return true;
97 }
98 
99 
100 //________________________________________________________________________________________
101 bool DreamSD::getStepInfo(G4Step* aStep) {
102 
103  preStepPoint = aStep->GetPreStepPoint();
104  theTrack = aStep->GetTrack();
105  G4String nameVolume = preStepPoint->GetPhysicalVolume()->GetName();
106 
107  // take into account light collection curve for crystals
108  double weight = 1.;
109  weight *= curve_LY(aStep, side);
110  if (useBirk) weight *= getAttenuation(aStep, birk1, birk2, birk3);
111  edepositEM = aStep->GetTotalEnergyDeposit() * weight;
112  LogDebug("EcalSim") << "DreamSD:: " << nameVolume << " Side " << side
113  <<" Light Collection Efficiency " << weight
114  << " Weighted Energy Deposit " << edepositEM/MeV
115  << " MeV";
116  // Get cherenkov contribution
117  if ( doCherenkov_ ) {
118  edepositHAD = cherenkovDeposit_( aStep );
119  } else {
120  edepositHAD = 0;
121  }
122 
123  double time = (aStep->GetPostStepPoint()->GetGlobalTime())/nanosecond;
124  unsigned int unitID= setDetUnitId(aStep);
125  if (side < 0) unitID++;
126  TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
127  int primaryID;
128 
129  if (trkInfo)
130  primaryID = trkInfo->getIDonCaloSurface();
131  else
132  primaryID = 0;
133 
134  if (primaryID == 0) {
135  edm::LogWarning("EcalSim") << "CaloSD: Problem with primaryID **** set by "
136  << "force to TkID **** "
137  << theTrack->GetTrackID() << " in Volume "
138  << preStepPoint->GetTouchable()->GetVolume(0)->GetName();
139  primaryID = theTrack->GetTrackID();
140  }
141 
142  bool flag = (unitID > 0);
143  G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
144  if (flag) {
145  currentID.setID(unitID, time, primaryID, 0);
146 
147  LogDebug("EcalSim") << "CaloSD:: GetStepInfo for"
148  << " PV " << touch->GetVolume(0)->GetName()
149  << " PVid = " << touch->GetReplicaNumber(0)
150  << " MVid = " << touch->GetReplicaNumber(1)
151  << " Unit " << currentID.unitID()
152  << " Edeposit = " << edepositEM << " " << edepositHAD;
153  } else {
154  LogDebug("EcalSim") << "CaloSD:: GetStepInfo for"
155  << " PV " << touch->GetVolume(0)->GetName()
156  << " PVid = " << touch->GetReplicaNumber(0)
157  << " MVid = " << touch->GetReplicaNumber(1)
158  << " Unit " << std::hex << unitID << std::dec
159  << " Edeposit = " << edepositEM << " " << edepositHAD;
160  }
161  return flag;
162 
163 }
164 
165 
166 //________________________________________________________________________________________
168 
169  // Get the material and set properties if needed
170  DimensionMap::const_iterator ite = xtalLMap.begin();
171  const G4LogicalVolume* lv = (ite->first);
172  G4Material* material = lv->GetMaterial();
173  edm::LogInfo("EcalSim") << "DreamSD::initRun: Initializes for material "
174  << material->GetName() << " in " << lv->GetName();
175  materialPropertiesTable = material->GetMaterialPropertiesTable();
176  if ( !materialPropertiesTable ) {
177  if ( !setPbWO2MaterialProperties_( material ) ) {
178  edm::LogWarning("EcalSim") << "Couldn't retrieve material properties table\n"
179  << " Material = " << material->GetName();
180  }
181  materialPropertiesTable = material->GetMaterialPropertiesTable();
182  }
183 }
184 
185 
186 //________________________________________________________________________________________
187 uint32_t DreamSD::setDetUnitId(const G4Step * aStep) {
188  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
189  uint32_t id = (touch->GetReplicaNumber(1))*10 + (touch->GetReplicaNumber(0));
190  LogDebug("EcalSim") << "DreamSD:: ID " << id;
191  return id;
192 }
193 
194 
195 //________________________________________________________________________________________
196 void DreamSD::initMap(const std::string& sd, const DDCompactView & cpv) {
197 
198  G4String attribute = "ReadOutName";
200  DDFilteredView fv(cpv,filter);
201  fv.firstChild();
202 
203  const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
204  std::vector<G4LogicalVolume *>::const_iterator lvcite;
205  bool dodet=true;
206  while (dodet) {
207  const DDSolid & sol = fv.logicalPart().solid();
208  std::vector<double> paras(sol.parameters());
209  G4String name = sol.name().name();
210  G4LogicalVolume* lv=nullptr;
211  for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
212  if ((*lvcite)->GetName() == name) {
213  lv = (*lvcite);
214  break;
215  }
216  LogDebug("EcalSim") << "DreamSD::initMap (for " << sd << "): Solid "
217  << name << " Shape " << sol.shape() <<" Parameter 0 = "
218  << paras[0] << " Logical Volume " << lv;
219  double length = 0, width = 0;
220  // Set length to be the largest size, width the smallest
221  std::sort( paras.begin(), paras.end() );
222  length = 2.0*paras.back();
223  width = 2.0*paras.front();
224  xtalLMap.insert( std::pair<G4LogicalVolume*,Doubles>(lv,Doubles(length,width)) );
225  dodet = fv.next();
226  }
227  LogDebug("EcalSim") << "DreamSD: Length Table for " << attribute << " = "
228  << sd << ":";
229  DimensionMap::const_iterator ite = xtalLMap.begin();
230  int i=0;
231  for (; ite != xtalLMap.end(); ite++, i++) {
232  G4String name = "Unknown";
233  if (ite->first != nullptr) name = (ite->first)->GetName();
234  LogDebug("EcalSim") << " " << i << " " << ite->first << " " << name
235  << " L = " << ite->second.first
236  << " W = " << ite->second.second;
237  }
238 }
239 
240 //________________________________________________________________________________________
241 double DreamSD::curve_LY(const G4Step* aStep, int flag) {
242 
243  const G4StepPoint* stepPoint = aStep->GetPreStepPoint();
244  G4LogicalVolume* lv = stepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
245  G4String nameVolume= lv->GetName();
246 
247  double weight = 1.;
248  G4ThreeVector localPoint = setToLocal(stepPoint->GetPosition(),
249  stepPoint->GetTouchable());
250  double crlength = crystalLength(lv);
251  double localz = localPoint.x();
252  double dapd = 0.5 * crlength - flag*localz; // Distance from closest APD
253  if (dapd >= -0.1 || dapd <= crlength+0.1) {
254  if (dapd <= 100.)
255  weight = 1.0 + slopeLY - dapd * 0.01 * slopeLY;
256  } else {
257  edm::LogWarning("EcalSim") << "DreamSD: light coll curve : wrong distance "
258  << "to APD " << dapd << " crlength = "
259  << crlength << " crystal name = " << nameVolume
260  << " z of localPoint = " << localz
261  << " take weight = " << weight;
262  }
263  LogDebug("EcalSim") << "DreamSD, light coll curve : " << dapd
264  << " crlength = " << crlength
265  << " crystal name = " << nameVolume
266  << " z of localPoint = " << localz
267  << " take weight = " << weight;
268  return weight;
269 }
270 
271 //________________________________________________________________________________________
272 const double DreamSD::crystalLength(G4LogicalVolume* lv) const {
273 
274  double length= -1.;
275  DimensionMap::const_iterator ite = xtalLMap.find(lv);
276  if (ite != xtalLMap.end()) length = ite->second.first;
277  return length;
278 
279 }
280 
281 //________________________________________________________________________________________
282 const double DreamSD::crystalWidth(G4LogicalVolume* lv) const {
283 
284  double width= -1.;
285  DimensionMap::const_iterator ite = xtalLMap.find(lv);
286  if (ite != xtalLMap.end()) width = ite->second.second;
287  return width;
288 
289 }
290 
291 
292 //________________________________________________________________________________________
293 // Calculate total cherenkov deposit
294 // Inspired by Geant4's Cherenkov implementation
295 double DreamSD::cherenkovDeposit_(const G4Step* aStep ) {
296 
297  double cherenkovEnergy = 0;
298  if (!materialPropertiesTable) return cherenkovEnergy;
299  G4Material* material = aStep->GetTrack()->GetMaterial();
300 
301  // Retrieve refractive index
302  G4MaterialPropertyVector* Rindex = materialPropertiesTable->GetProperty("RINDEX");
303  if ( Rindex == nullptr ) {
304  edm::LogWarning("EcalSim") << "Couldn't retrieve refractive index";
305  return cherenkovEnergy;
306  }
307 
308  // V.Ivanchenko - temporary close log output for 9.5
309  // Material refraction properties
310  int Rlength = Rindex->GetVectorLength() - 1;
311  double Pmin = Rindex->Energy(0);
312  double Pmax = Rindex->Energy(Rlength);
313  LogDebug("EcalSim") << "Material properties: " << "\n"
314  << " Pmin = " << Pmin
315  << " Pmax = " << Pmax;
316 
317  // Get particle properties
318  const G4StepPoint* pPreStepPoint = aStep->GetPreStepPoint();
319  const G4StepPoint* pPostStepPoint = aStep->GetPostStepPoint();
320  const G4ThreeVector& x0 = pPreStepPoint->GetPosition();
321  G4ThreeVector p0 = aStep->GetDeltaPosition().unit();
322  const G4DynamicParticle* aParticle = aStep->GetTrack()->GetDynamicParticle();
323  const double charge = aParticle->GetDefinition()->GetPDGCharge();
324  // beta is averaged over step
325  double beta = 0.5*( pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta() );
326  double BetaInverse = 1.0/beta;
327 
328  LogDebug("EcalSim") << "Particle properties: " << "\n"
329  << " charge = " << charge
330  << " beta = " << beta;
331 
332  // Now get number of photons generated in this step
333  double meanNumberOfPhotons = getAverageNumberOfPhotons_( charge, beta, material, Rindex );
334  if ( meanNumberOfPhotons <= 0.0 ) { // Don't do anything
335  LogDebug("EcalSim") << "Mean number of photons is zero: " << meanNumberOfPhotons
336  << ", stopping here";
337  return cherenkovEnergy;
338  }
339 
340  // number of photons is in unit of Geant4...
341  meanNumberOfPhotons *= aStep->GetStepLength();
342 
343  // Now get a poisson distribution
344  int numPhotons = static_cast<int>( G4Poisson(meanNumberOfPhotons) );
345  //edm::LogVerbatim("EcalSim") << "Number of photons = " << numPhotons;
346  if ( numPhotons <= 0 ) {
347  LogDebug("EcalSim") << "Poission number of photons is zero: " << numPhotons
348  << ", stopping here";
349  return cherenkovEnergy;
350  }
351 
352  // Material refraction properties
353  double dp = Pmax - Pmin;
354  double maxCos = BetaInverse / (*Rindex)[Rlength];
355  double maxSin2 = (1.0 - maxCos) * (1.0 + maxCos);
356 
357  // Finally: get contribution of each photon
358  for ( int iPhoton = 0; iPhoton<numPhotons; ++iPhoton ) {
359 
360  // Determine photon momentum
361  double randomNumber;
362  double sampledMomentum, sampledRI;
363  double cosTheta, sin2Theta;
364 
365  // sample a momentum (not sure why this is needed!)
366  do {
367  randomNumber = G4UniformRand();
368  sampledMomentum = Pmin + randomNumber * dp;
369  sampledRI = Rindex->Value(sampledMomentum);
370  cosTheta = BetaInverse / sampledRI;
371 
372  sin2Theta = (1.0 - cosTheta)*(1.0 + cosTheta);
373  randomNumber = G4UniformRand();
374 
375  } while (randomNumber*maxSin2 > sin2Theta);
376 
377  // Generate random position of photon on cone surface
378  // defined by Theta
379  randomNumber = G4UniformRand();
380 
381  double phi = twopi*randomNumber;
382  double sinPhi = sin(phi);
383  double cosPhi = cos(phi);
384 
385  // Create photon momentum direction vector
386  // The momentum direction is still w.r.t. the coordinate system where the primary
387  // particle direction is aligned with the z axis
388  double sinTheta = sqrt(sin2Theta);
389  double px = sinTheta*cosPhi;
390  double py = sinTheta*sinPhi;
391  double pz = cosTheta;
392  G4ThreeVector photonDirection(px, py, pz);
393 
394  // Rotate momentum direction back to global (crystal) reference system
395  photonDirection.rotateUz(p0);
396 
397  // Create photon position and momentum
398  randomNumber = G4UniformRand();
399  G4ThreeVector photonPosition = x0 + randomNumber * aStep->GetDeltaPosition();
400  G4ThreeVector photonMomentum = sampledMomentum*photonDirection;
401 
402  // Collect energy on APD
403  cherenkovEnergy += getPhotonEnergyDeposit_( photonMomentum, photonPosition, aStep );
404 
405  // Ntuple variables
406  nphotons_ = numPhotons;
407  px_[iPhoton] = photonMomentum.x();
408  py_[iPhoton] = photonMomentum.y();
409  pz_[iPhoton] = photonMomentum.z();
410  x_[iPhoton] = photonPosition.x();
411  y_[iPhoton] = photonPosition.y();
412  z_[iPhoton] = photonPosition.z();
413  }
414 
415  // Fill ntuple
416  ntuple_->Fill();
417 
418 
419  return cherenkovEnergy;
420 
421 }
422 
423 
424 //________________________________________________________________________________________
425 // Returns number of photons produced per GEANT-unit (millimeter) in the current medium.
426 // From G4Cerenkov.cc
428  const double beta,
429  const G4Material* aMaterial,
430  const G4MaterialPropertyVector* Rindex )
431 {
432  const G4double rFact = 369.81/(eV * cm);
433 
434  if( beta <= 0.0 ) return 0.0;
435 
436  double BetaInverse = 1./beta;
437 
438  // Vectors used in computation of Cerenkov Angle Integral:
439  // - Refraction Indices for the current material
440  // - new G4PhysicsOrderedFreeVector allocated to hold CAI's
441 
442  // Min and Max photon momenta
443  int Rlength = Rindex->GetVectorLength() - 1;
444  double Pmin = Rindex->Energy(0);
445  double Pmax = Rindex->Energy(Rlength);
446 
447  // Min and Max Refraction Indices
448  double nMin = (*Rindex)[0];
449  double nMax = (*Rindex)[Rlength];
450 
451  // Max Cerenkov Angle Integral
452  double CAImax = chAngleIntegrals_.get()->GetMaxValue();
453 
454  double dp = 0., ge = 0., CAImin = 0.;
455 
456  // If n(Pmax) < 1/Beta -- no photons generated
457  if ( nMax < BetaInverse) { }
458 
459  // otherwise if n(Pmin) >= 1/Beta -- photons generated
460  else if (nMin > BetaInverse) {
461  dp = Pmax - Pmin;
462  ge = CAImax;
463  }
464  // If n(Pmin) < 1/Beta, and n(Pmax) >= 1/Beta, then
465  // we need to find a P such that the value of n(P) == 1/Beta.
466  // Interpolation is performed by the GetPhotonEnergy() and
467  // GetProperty() methods of the G4MaterialPropertiesTable and
468  // the GetValue() method of G4PhysicsVector.
469  else {
470  Pmin = Rindex->Value(BetaInverse);
471  dp = Pmax - Pmin;
472  // need boolean for current implementation of G4PhysicsVector
473  // ==> being phased out
474  double CAImin = chAngleIntegrals_->Value(Pmin);
475  ge = CAImax - CAImin;
476 
477  }
478 
479  // Calculate number of photons
480  double numPhotons = rFact * charge/eplus * charge/eplus *
481  (dp - ge * BetaInverse*BetaInverse);
482 
483  LogDebug("EcalSim") << "@SUB=getAverageNumberOfPhotons"
484  << "CAImin = " << CAImin << "\n"
485  << "CAImax = " << CAImax << "\n"
486  << "dp = " << dp << ", ge = " << ge << "\n"
487  << "numPhotons = " << numPhotons;
488 
489 
490 
491  return numPhotons;
492 
493 }
494 
495 
496 //________________________________________________________________________________________
497 // Set lead tungstate material properties on the fly.
498 // Values from Ts42 detector construction
499 bool DreamSD::setPbWO2MaterialProperties_( G4Material* aMaterial ) {
500 
501  std::string pbWO2Name("E_PbWO4");
502  if ( pbWO2Name != aMaterial->GetName() ) { // Wrong material!
503  edm::LogWarning("EcalSim") << "This is not the right material: "
504  << "expecting " << pbWO2Name
505  << ", got " << aMaterial->GetName();
506  return false;
507  }
508 
509  G4MaterialPropertiesTable* table = new G4MaterialPropertiesTable();
510 
511  // Refractive index as a function of photon momentum
512  // FIXME: Should somehow put that in the configuration
513  const int nEntries = 14;
514  double PhotonEnergy[nEntries] = { 1.7712*eV, 1.8368*eV, 1.90745*eV, 1.98375*eV, 2.0664*eV,
515  2.15625*eV, 2.25426*eV, 2.3616*eV, 2.47968*eV, 2.61019*eV,
516  2.75521*eV, 2.91728*eV, 3.09961*eV, 3.30625*eV };
517  double RefractiveIndex[nEntries] = { 2.17728, 2.18025, 2.18357, 2.18753, 2.19285,
518  2.19813, 2.20441, 2.21337, 2.22328, 2.23619,
519  2.25203, 2.27381, 2.30282, 2.34666 };
520 
521  table->AddProperty( "RINDEX", PhotonEnergy, RefractiveIndex, nEntries );
522  aMaterial->SetMaterialPropertiesTable(table); // FIXME: could this leak? What does G4 do?
523 
524  // Calculate Cherenkov angle integrals:
525  // This is an ad-hoc solution (we hold it in the class, not in the material)
526  chAngleIntegrals_.reset(new G4PhysicsOrderedFreeVector());
527 
528  int index = 0;
529  double currentRI = RefractiveIndex[index];
530  double currentPM = PhotonEnergy[index];
531  double currentCAI = 0.0;
532  chAngleIntegrals_.get()->InsertValues(currentPM, currentCAI);
533  double prevPM = currentPM;
534  double prevCAI = currentCAI;
535  double prevRI = currentRI;
536  while ( ++index < nEntries ) {
537  currentRI = RefractiveIndex[index];
538  currentPM = PhotonEnergy[index];
539  currentCAI = 0.5*(1.0/(prevRI*prevRI) + 1.0/(currentRI*currentRI));
540  currentCAI = prevCAI + (currentPM - prevPM) * currentCAI;
541 
542  chAngleIntegrals_.get()->InsertValues(currentPM, currentCAI);
543 
544  prevPM = currentPM;
545  prevCAI = currentCAI;
546  prevRI = currentRI;
547  }
548 
549  LogDebug("EcalSim") << "Material properties set for " << aMaterial->GetName();
550 
551  return true;
552 
553 }
554 
555 
556 //________________________________________________________________________________________
557 // Calculate energy deposit of a photon on APD
558 // - simple tracing to APD position (straight line);
559 // - configurable reflection probability if not straight to APD;
560 // - APD response function
561 double DreamSD::getPhotonEnergyDeposit_( const G4ThreeVector& p,
562  const G4ThreeVector& x,
563  const G4Step* aStep )
564 {
565 
566  double energy = 0;
567 
568  // Crystal dimensions
569 
570  //edm::LogVerbatim("EcalSim") << p << x;
571 
572  // 1. Check if this photon goes straight to the APD:
573  // - assume that APD is at x=xtalLength/2.0
574  // - extrapolate from x=x0 to x=xtalLength/2.0 using momentum in x-y
575 
576  G4StepPoint* stepPoint = aStep->GetPreStepPoint();
577  G4LogicalVolume* lv = stepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
578  G4String nameVolume= lv->GetName();
579 
580  double crlength = crystalLength(lv);
581  double crwidth = crystalWidth(lv);
582  double dapd = 0.5 * crlength - x.x(); // Distance from closest APD
583  double y = p.y()/p.x()*dapd;
584 
585  LogDebug("EcalSim") << "Distance to APD: " << dapd
586  << " - y at APD: " << y;
587 
588  // Not straight: compute probability
589  if ( fabs(y)>crwidth*0.5 ) {
590 
591  }
592 
593  // 2. Retrieve efficiency for this wavelength (in nm, from MeV)
594  double waveLength = p.mag()*1.239e8;
595 
596 
597  energy = p.mag()*PMTResponse::getEfficiency(waveLength);
598 
599  LogDebug("EcalSim") << "Wavelength: " << waveLength << " - Energy: " << energy;
600 
601  return energy;
602 
603 }
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:122
const double beta
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3)
Definition: CaloSD.cc:439
const std::vector< double > & parameters(void) const
Give the parameters of the solid.
Definition: DDSolid.cc:150
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the filtered-view.
const N & name() const
Definition: DDBase.h:78
bool readBothSide_
Definition: DreamSD.h:58
int getIDonCaloSurface() const
double getPhotonEnergyDeposit_(const G4ParticleMomentum &p, const G4ThreeVector &x, const G4Step *aStep)
Returns energy deposit for a given photon.
Definition: DreamSD.cc:561
std::pair< double, double > Doubles
Definition: DreamSD.h:36
Definition: CaloSD.h:42
float y_[MAXPHOTONS]
Definition: DreamSD.h:72
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
uint32_t setDetUnitId(const G4Step *) override
Definition: DreamSD.cc:187
Definition: weight.py:1
double birk1
Definition: DreamSD.h:59
bool setPbWO2MaterialProperties_(G4Material *aMaterial)
Sets material properties at run-time...
Definition: DreamSD.cc:499
T * make(const Args &...args) const
make new ROOT object
Definition: TFileService.h:64
double birk3
Definition: DreamSD.h:59
const DDSolid & solid(void) const
Returns a reference object of the solid being the shape of this LogicalPart.
void initRun() override
Definition: DreamSD.cc:167
float px_[MAXPHOTONS]
Definition: DreamSD.h:71
type of data representation of DDCompactView
Definition: DDCompactView.h:90
TTree * ntuple_
Definition: DreamSD.h:69
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
A DDSolid represents the shape of a part.
Definition: DDSolid.h:38
const double MeV
float z_[MAXPHOTONS]
Definition: DreamSD.h:72
bool next()
set current node to the next node in the filtered tree
double cherenkovDeposit_(const G4Step *aStep)
Returns the total energy due to Cherenkov radiation.
Definition: DreamSD.cc:295
float edepositHAD
Definition: CaloSD.h:122
T sqrt(T t)
Definition: SSEVec.h:18
int nphotons_
Definition: DreamSD.h:70
float pz_[MAXPHOTONS]
Definition: DreamSD.h:71
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
int side
Definition: DreamSD.h:63
bool isAvailable() const
Definition: Service.h:46
double getAverageNumberOfPhotons_(const double charge, const double beta, const G4Material *aMaterial, const G4MaterialPropertyVector *rIndex)
Returns average number of photons created by track.
Definition: DreamSD.cc:427
DDSolidShape shape(void) const
The type of the solid.
Definition: DDSolid.cc:144
double birk2
Definition: DreamSD.h:59
CaloG4Hit * currentHit
Definition: CaloSD.h:129
G4MaterialPropertiesTable * materialPropertiesTable
Definition: DreamSD.h:67
G4Track * theTrack
Definition: CaloSD.h:119
double curve_LY(const G4Step *, int)
Definition: DreamSD.cc:241
const double crystalWidth(G4LogicalVolume *) const
Definition: DreamSD.cc:282
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
G4StepPoint * preStepPoint
Definition: CaloSD.h:121
DimensionMap xtalLMap
Definition: DreamSD.h:61
CaloHitID currentID
Definition: CaloSD.h:118
auto dp
Definition: deltaR.h:22
double sd
float x_[MAXPHOTONS]
Definition: DreamSD.h:72
std::unique_ptr< G4PhysicsOrderedFreeVector > chAngleIntegrals_
Table of Cherenkov angle integrals vs photon momentum.
Definition: DreamSD.h:66
bool doCherenkov_
Definition: DreamSD.h:58
double slopeLY
Definition: DreamSD.h:60
G4bool hitExists()
Definition: CaloSD.cc:284
DreamSD(const std::string &, const DDCompactView &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: DreamSD.cc:29
bool firstChild()
set the current node to the first child ...
float py_[MAXPHOTONS]
Definition: DreamSD.h:71
bool ProcessHits(G4Step *step, G4TouchableHistory *tHistory) override
Definition: DreamSD.cc:79
uint32_t unitID() const
Definition: CaloHitID.h:22
const double crystalLength(G4LogicalVolume *) const
Definition: DreamSD.cc:272
const std::string & name() const
Returns the name.
Definition: DDName.cc:90
void initMap(const std::string &, const DDCompactView &)
Definition: DreamSD.cc:196
static const double getEfficiency(const double &waveLengthNm)
Return efficiency for given photon wavelength (in nm)
Definition: PMTResponse.cc:6
bool useBirk
Definition: DreamSD.h:58
CaloG4Hit * createNewHit()
Definition: CaloSD.cc:337
G4bool getStepInfo(G4Step *aStep) override
Definition: DreamSD.cc:101
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *)
Definition: CaloSD.cc:270