ISCalculationCorrelated.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // \file ISCalculationCorrelated.cxx
3 // \brief Interface to algorithm class for calculating ionization electrons
4 // and scintillation photon based on simple microphysics arguments
5 // to establish anticorrelation between these two quantities.
6 //
7 // To enable this in simulation, change LArG4Parameters variable
8 // in your fhicl file:
9 //
10 // services.LArG4Parameters.IonAndScintCalculator: "Correlated"
11 //
12 // TO DO:
13 // [ ] Add fluctuations from Fano factor
14 // [ ] Get W_ph = 19.5 eV from somewhere more centralized instead
15 // of hard-coding it into this algorithm
16 //
17 // \author W. Foreman, May 2020
18 // Modified: Adding corrections for low electric field (LArQL model)
19 // Mar 2021 by L. Paulucci and F. Marinho
20 ////////////////////////////////////////////////////////////////////////
21 
22 #include "Geant4/G4EmSaturation.hh"
23 #include "Geant4/G4LossTableManager.hh"
24 #include "Geant4/G4ParticleTypes.hh"
25 
32 
33 #include "cetlib_except/exception.h"
35 
36 namespace larg4 {
37 
38  //----------------------------------------------------------------------------
40  {
41  std::cout << "LegacyLArG4/ISCalculationCorrelated Initialize." << std::endl;
43  const detinfo::LArProperties* larp = lar::providerFrom<detinfo::LArPropertiesService>();
44 
45  double density = detProp.Density(detProp.Temperature());
46  fEfield = detProp.Efield();
47  fScintPreScale = larp->ScintPreScale();
48 
49  // ionization work function
50  fWion = 1. / lgpHandle->GeVToElectrons() * 1e3; // MeV
51 
52  // ion+excitation work function (\todo: get from LArG4Parameters or LArProperties?)
53  fWph = 19.5 * 1e-6; // MeV
54 
55  // the recombination coefficient is in g/(MeVcm^2), but
56  // we report energy depositions in MeV/cm, need to divide
57  // Recombk from the LArG4Parameters service by the density
58  // of the argon we got above.
59  fRecombA = lgpHandle->RecombA();
60  fRecombk = lgpHandle->Recombk() / density;
61  fModBoxA = lgpHandle->ModBoxA();
62  fModBoxB = lgpHandle->ModBoxB() / density;
63  fLarqlChi0A = lgpHandle->LarqlChi0A();
64  fLarqlChi0B = lgpHandle->LarqlChi0B();
65  fLarqlChi0C = lgpHandle->LarqlChi0C();
66  fLarqlChi0D = lgpHandle->LarqlChi0D();
67  fLarqlAlpha = lgpHandle->LarqlAlpha();
68  fLarqlBeta = lgpHandle->LarqlBeta();
69  fUseModBoxRecomb = lgpHandle->UseModBoxRecomb();
71 
72  // determine the step size using the voxel sizes
74  double maxsize =
75  std::max(lvc->VoxelSizeX(), std::max(lvc->VoxelSizeY(), lvc->VoxelSizeZ())) * CLHEP::cm;
76 
77  fStepSize = 0.1 * maxsize;
78  }
79 
80  //----------------------------------------------------------------------------
81  // fNumIonElectrons returns a value that is not corrected for life time effects
82  void
84  {
85  fEnergyDeposit = 0.;
86  fNumScintPhotons = 0.;
87  fNumIonElectrons = 0.;
88 
89  return;
90  }
91 
92  //----------------------------------------------------------------------------
93  // fNumIonElectrons returns a value that is not corrected for life time effects
94  void
96  {
97  fEnergyDeposit = step->GetTotalEnergyDeposit() / CLHEP::MeV;
98 
99  // calculate total quanta (ions + excitons)
100  double Nq = fEnergyDeposit / fWph;
101 
102  // Get the recombination factor for this voxel - Nucl.Instrum.Meth.A523:275-286,2004
103  // R = A/(1 + (dE/dx)*k)
104  // dE/dx is given by the voxel energy deposition, but have to convert it to MeV/cm
105  // from GeV/voxel width
106  // A = 0.800 +/- 0.003
107  // k = (0.097+/-0.001) g/(MeVcm^2)
108  // the dx depends on the trajectory of the step
109  // k should be divided by the density as our dE/dx is in MeV/cm,
110  // the division is handled in the constructor when we set fRecombk
111  // B.Baller: Add Modified Box recombination - ArgoNeuT result submitted to JINST
112 
113  G4ThreeVector totstep = step->GetPostStepPoint()->GetPosition();
114  totstep -= step->GetPreStepPoint()->GetPosition();
115  double dx = totstep.mag() / CLHEP::cm;
116  double dEdx = (dx == 0.0) ? 0.0 : fEnergyDeposit / dx;
117  double EFieldStep = EFieldAtStep(fEfield, step);
118 
119  // Guard against spurious values of dE/dx. Note: assumes density of LAr
120  if (dEdx < 1.) dEdx = 1.;
121 
122  // calculate the recombination survival fraction
123  double recomb = 0.;
124  if (fUseModBoxRecomb) {
125  if (dx) {
126  double Xi = fModBoxB * dEdx / EFieldStep;
127  recomb = log(fModBoxA + Xi) / Xi;
128  }
129  else
130  recomb = 0;
131  }
132  else {
133  recomb = fRecombA / (1. + dEdx * fRecombk / EFieldStep);
134  }
135 
136  if(fUseModLarqlRecomb){ //Use corrections from LArQL model
137  recomb += EscapingEFraction(dEdx)*FieldCorrection(EFieldStep, dEdx); //Correction for low EF
138  }
139 
140  // using this recombination, calculate number of ionization electrons
141  fNumIonElectrons = (fEnergyDeposit / fWion) * recomb;
142 
143  // calculate scintillation photons
145 
146  // apply the scintillation pre-scaling (normally this is already folded into
147  // the particle-specific scintillation yields)
149 
150  MF_LOG_DEBUG("ISCalculationCorrelated")
151  << " Electrons produced for " << fEnergyDeposit << " MeV deposited with " << recomb
152  << " recombination: " << fNumIonElectrons;
153  MF_LOG_DEBUG("ISCalculationCorrelated") << "number photons: " << fNumScintPhotons;
154 
155  return;
156  }
157 
158  double ISCalculationCorrelated::EscapingEFraction(double const dEdx){ //LArQL chi0 function = fraction of escaping electrons
159  return fLarqlChi0A/(fLarqlChi0B+exp(fLarqlChi0C+fLarqlChi0D*dEdx));
160  }
161 
162  double ISCalculationCorrelated::FieldCorrection(double const EF, double const dEdx){ //LArQL f_corr function = correction factor for electric field dependence
163  return exp(-EF/(fLarqlAlpha*log(dEdx)+fLarqlBeta));
164  }
165 
166 } // namespace
static constexpr double cm
Definition: Units.h:68
Store parameters for running LArG4.
double fWion
W_ion (23.6 eV) == 1/fGeVToElectrons.
double VoxelSizeX() const
Access to voxel dimensions and offsets.
double ModBoxA() const
double fModBoxA
from LArG4Parameters service
double fLarqlChi0D
from LArG4Parameters service
Encapsulates calculation of LArVoxelID and LArVoxel parameters.
double EFieldAtStep(double fEfield, const G4Step *step) const
double fLarqlChi0B
from LArG4Parameters service
double LarqlChi0B() const
double Temperature() const
In kelvin.
double LarqlBeta() const
double LarqlAlpha() const
bool UseModBoxRecomb() const
Geant4 interface.
double fLarqlAlpha
from LArG4Parameters service
static constexpr double MeV
Definition: Units.h:129
double LarqlChi0D() const
bool fUseModLarqlRecomb
from LArG4Parameters service
double Efield(unsigned int planegap=0) const
kV/cm
double LarqlChi0C() const
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
const double e
double fLarqlChi0C
from LArG4Parameters service
bool UseModLarqlRecomb() const
double fNumIonElectrons
number of ionization electrons for this step
Definition: ISCalculation.h:49
bool fUseModBoxRecomb
from LArG4Parameters service
double Density(double temperature=0.) const
Returns argon density at a given temperature.
virtual double ScintPreScale(bool prescale=true) const =0
static int max(int a, int b)
double RecombA() const
double LarqlChi0A() const
ISCalculationCorrelated(detinfo::DetectorPropertiesData const &detProp)
double fStepSize
maximum step to take
double fScintPreScale
scintillation pre-scale from LArProperties service
double ModBoxB() const
double EscapingEFraction(double const dEdx)
double Recombk() const
#define MF_LOG_DEBUG(id)
double fNumScintPhotons
number of scintillation photons for this step
Definition: ISCalculation.h:50
double fRecombA
from LArG4Parameters service
double fLarqlChi0A
from LArG4Parameters service
double fEnergyDeposit
total energy deposited in the step
Definition: ISCalculation.h:48
void CalculateIonizationAndScintillation(const G4Step *step)
double fRecombk
from LArG4Parameters service
double FieldCorrection(double const EF, double const dEdx)
double fEfield
value of electric field from LArProperties service
double GeVToElectrons() const
QTextStream & endl(QTextStream &s)
double fModBoxB
from LArG4Parameters service
double fLarqlBeta
from LArG4Parameters service