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"
22 
23 namespace larg4 {
24 
25  //----------------------------------------------------------------------------
27  {
29  const detinfo::LArProperties* larp = lar::providerFrom<detinfo::LArPropertiesService>();
30  auto const detProp =
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
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
static constexpr double cm
Definition: Units.h:68
Store parameters for running LArG4.
double VoxelSizeX() const
Access to voxel dimensions and offsets.
double ModBoxA() const
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
bool UseModBoxRecomb() const
Geant4 interface.
static constexpr double MeV
Definition: Units.h:129
double fRecombA
from LArG4Parameters service
double fEfield
value of electric field from LArProperties service
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
double fNumIonElectrons
number of ionization electrons for this step
Definition: ISCalculation.h:49
double fModBoxB
from LArG4Parameters service
bool fScintByParticleType
from LArProperties service
static int max(int a, int b)
double RecombA() const
double fStepSize
maximum step to take
double fRecombk
from LArG4Parameters service
double ModBoxB() const
double Recombk() const
#define MF_LOG_DEBUG(id)
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
double GeVToElectrons() const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33