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