All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ISCalculationSeparate.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file ISCalculationSeparate.cxx
3 /// \brief Interface to algorithm class for calculating ionization electrons
4 /// and scintillation photons using separate algorithms for each
5 ///
6 /// \author brebel@fnal.gov
7 ////////////////////////////////////////////////////////////////////////
8 
9 #include "Geant4/G4EmSaturation.hh"
10 #include "Geant4/G4LossTableManager.hh"
11 #include "Geant4/G4ParticleTypes.hh"
12 
19 
20 #include "cetlib_except/exception.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
22 
23 namespace larg4 {
24 
25  //----------------------------------------------------------------------------
27  {
28  art::ServiceHandle<sim::LArG4Parameters const> lgpHandle;
29  const detinfo::LArProperties* larp = lar::providerFrom<detinfo::LArPropertiesService>();
30  auto const detProp =
31  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
32 
33  double density = detProp.Density(detProp.Temperature());
34  fEfield = detProp.Efield();
36  fGeVToElectrons = lgpHandle->GeVToElectrons();
37 
38  // \todo get scintillation yield from LArG4Parameters or LArProperties
39  fScintYieldFactor = 1.;
40 
41  // the recombination coefficient is in g/(MeVcm^2), but
42  // we report energy depositions in MeV/cm, need to divide
43  // Recombk from the LArG4Parameters service by the density
44  // of the argon we got above.
45  fRecombA = lgpHandle->RecombA();
46  fRecombk = lgpHandle->Recombk() / density;
47  fModBoxA = lgpHandle->ModBoxA();
48  fModBoxB = lgpHandle->ModBoxB() / density;
49  fUseModBoxRecomb = lgpHandle->UseModBoxRecomb();
50 
51  // Use Birks Correction in the Scintillation process
52  fEMSaturation = G4LossTableManager::Instance()->EmSaturation();
53 
54  // determine the step size using the voxel sizes
55  art::ServiceHandle<sim::LArVoxelCalculator const> lvc;
56  double maxsize =
57  std::max(lvc->VoxelSizeX(), std::max(lvc->VoxelSizeY(), lvc->VoxelSizeZ())) * CLHEP::cm;
58 
59  fStepSize = 0.1 * maxsize;
60  }
61 
62  //----------------------------------------------------------------------------
63  // fNumIonElectrons returns a value that is not corrected for life time effects
64  void
66  {
67  fEnergyDeposit = 0.;
68  fNumScintPhotons = 0.;
69  fNumIonElectrons = 0.;
70  }
71 
72  //----------------------------------------------------------------------------
73  // fNumIonElectrons returns a value that is not corrected for life time effects
74  void
76  {
77  fEnergyDeposit = step->GetTotalEnergyDeposit() / CLHEP::MeV;
78 
79  // Get the recombination factor for this voxel - Nucl.Instrum.Meth.A523:275-286,2004
80  // R = A/(1 + (dE/dx)*k)
81  // dE/dx is given by the voxel energy deposition, but have to convert it to MeV/cm
82  // from GeV/voxel width
83  // A = 0.800 +/- 0.003
84  // k = (0.097+/-0.001) g/(MeVcm^2)
85  // the dx depends on the trajectory of the step
86  // k should be divided by the density as our dE/dx is in MeV/cm,
87  // the division is handled in the constructor when we set fRecombk
88  // B.Baller: Add Modified Box recombination - ArgoNeuT result submitted to JINST
89 
90  G4ThreeVector totstep = step->GetPostStepPoint()->GetPosition();
91  totstep -= step->GetPreStepPoint()->GetPosition();
92 
93  double dx = totstep.mag() / CLHEP::cm;
94  double recomb = 0.;
95  double dEdx = (dx == 0.0) ? 0.0 : fEnergyDeposit / dx;
96  double EFieldStep = EFieldAtStep(fEfield, step);
97 
98  // Guard against spurious values of dE/dx. Note: assumes density of LAr
99  if (dEdx < 1.) dEdx = 1.;
100 
101  if (fUseModBoxRecomb) {
102  if (dx) {
103  double Xi = fModBoxB * dEdx / EFieldStep;
104  recomb = log(fModBoxA + Xi) / Xi;
105  }
106  else
107  recomb = 0;
108  }
109  else {
110  recomb = fRecombA / (1. + dEdx * fRecombk / EFieldStep);
111  }
112 
113  // 1.e-3 converts fEnergyDeposit to GeV
114  fNumIonElectrons = fGeVToElectrons * 1.e-3 * fEnergyDeposit * recomb;
115 
116  MF_LOG_DEBUG("ISCalculationSeparate")
117  << " Electrons produced for " << fEnergyDeposit << " MeV deposited with " << recomb
118  << " recombination: " << fNumIonElectrons;
119 
120  // Now do the scintillation
121  G4MaterialPropertiesTable* mpt = step->GetTrack()->GetMaterial()->GetMaterialPropertiesTable();
122  if (!mpt)
123  throw cet::exception("ISCalculationSeparate")
124  << "Cannot find materials property table"
125  << " for this step! " << step->GetTrack()->GetMaterial() << "\n";
126 
127  // if not doing the scintillation by particle type, use the saturation
128  double scintYield = mpt->GetConstProperty("SCINTILLATIONYIELD");
129 
130  if (fScintByParticleType) {
131 
132  MF_LOG_DEBUG("ISCalculationSeparate") << "scintillating by particle type";
133 
134  // Get the definition of the current particle
135  G4ParticleDefinition* pDef = step->GetTrack()->GetDynamicParticle()->GetDefinition();
136 
137  // Obtain the G4MaterialPropertyVectory containing the
138  // scintillation light yield as a function of the deposited
139  // energy for the current particle type
140 
141  // Protons
142  if (pDef == G4Proton::ProtonDefinition()) {
143  scintYield = mpt->GetConstProperty("PROTONSCINTILLATIONYIELD");
144  }
145  // Muons
146  else if (pDef == G4MuonPlus::MuonPlusDefinition() ||
147  pDef == G4MuonMinus::MuonMinusDefinition()) {
148  scintYield = mpt->GetConstProperty("MUONSCINTILLATIONYIELD");
149  }
150  // Pions
151  else if (pDef == G4PionPlus::PionPlusDefinition() ||
152  pDef == G4PionMinus::PionMinusDefinition()) {
153  scintYield = mpt->GetConstProperty("PIONSCINTILLATIONYIELD");
154  }
155  // Kaons
156  else if (pDef == G4KaonPlus::KaonPlusDefinition() ||
157  pDef == G4KaonMinus::KaonMinusDefinition()) {
158  scintYield = mpt->GetConstProperty("KAONSCINTILLATIONYIELD");
159  }
160  // Alphas
161  else if (pDef == G4Alpha::AlphaDefinition()) {
162  scintYield = mpt->GetConstProperty("ALPHASCINTILLATIONYIELD");
163  }
164  // Electrons (must also account for shell-binding energy
165  // attributed to gamma from standard PhotoElectricEffect)
166  else if (pDef == G4Electron::ElectronDefinition() || pDef == G4Gamma::GammaDefinition()) {
167  scintYield = mpt->GetConstProperty("ELECTRONSCINTILLATIONYIELD");
168  }
169  // Default for particles not enumerated/listed above
170  else {
171  scintYield = mpt->GetConstProperty("ELECTRONSCINTILLATIONYIELD");
172  }
173 
174  // If the user has not specified yields for (p,d,t,a,carbon)
175  // then these unspecified particles will default to the
176  // electron's scintillation yield
177 
178  // Throw an exception if no scintillation yield is found
179  if (!scintYield)
180  throw cet::exception("ISCalculationSeparate")
181  << "Request for scintillation yield for energy "
182  << "deposit and particle type without correct "
183  << "entry in MaterialPropertiesTable\n"
184  << "ScintillationByParticleType requires at "
185  << "minimum that ELECTRONSCINTILLATIONYIELD is "
186  << "set by the user\n";
187 
188  fNumScintPhotons = scintYield * fEnergyDeposit;
189  }
190  else if (fEMSaturation) {
191  // The default linear scintillation process
192  fVisibleEnergyDeposition = fEMSaturation->VisibleEnergyDepositionAtAStep(step);
194  }
195  else {
197  }
198 
199  MF_LOG_DEBUG("ISCalculationSeparate")
200  << "number photons: " << fNumScintPhotons << " energy: " << fEnergyDeposit / CLHEP::MeV
201  << " saturation: " << fEMSaturation->VisibleEnergyDepositionAtAStep(step)
202  << " step length: " << step->GetStepLength() / CLHEP::cm;
203  }
204 
205 } // namespace
Store parameters for running LArG4.
Utilities related to art service access.
bool fUseModBoxRecomb
from LArG4Parameters service
G4EmSaturation * fEMSaturation
pointer to EM saturation
double fScintYieldFactor
scintillation yield factor
Encapsulates calculation of LArVoxelID and LArVoxel parameters.
double EFieldAtStep(double fEfield, const G4Step *step) const
void CalculateIonizationAndScintillation(const G4Step *step) override
double fGeVToElectrons
conversion factor from LArProperties service
double fRecombA
from LArG4Parameters service
util::quantities::megaelectronvolt MeV
double fEfield
value of electric field from LArProperties service
double fNumIonElectrons
number of ionization electrons for this step
Definition: ISCalculation.h:49
double fModBoxB
from LArG4Parameters service
bool fScintByParticleType
from LArProperties service
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2687
double fRecombk
from LArG4Parameters service
double fNumScintPhotons
number of scintillation photons for this step
Definition: ISCalculation.h:50
double fVisibleEnergyDeposition
Definition: ISCalculation.h:51
double fModBoxA
from LArG4Parameters service
double fEnergyDeposit
total energy deposited in the step
Definition: ISCalculation.h:48
virtual bool ScintByParticleType() const =0
auto const detProp