ISCalcCorrelated.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ISCalcCorrelated
3 // Plugin Type: algorithm
4 // File: ISCalcCorrelated.h and ISCalcCorrelated.cxx
5 // Description: Interface to algorithm class for a specific calculation of
6 // ionization electrons and scintillation photons, based on
7 // simple microphysics arguments to establish an anticorrelation
8 // between these two quantities.
9 // Input: 'sim::SimEnergyDeposit'
10 // Output: num of Photons and Electrons
11 // May 2020 by W Foreman
12 // Modified: Adding corrections for low electric field (LArQL model)
13 // Jun 2020 by L. Paulucci and F. Marinho
14 ////////////////////////////////////////////////////////////////////////
15 
18 
19 namespace larg4 {
20  //----------------------------------------------------------------------------
22  : fISTPC{*(lar::providerFrom<geo::Geometry>())}
23  {
24  std::cout << "IonizationAndScintillation/ISCalcCorrelated Initialize." << std::endl;
26 
27  fSCE = lar::providerFrom<spacecharge::SpaceChargeService>();
28  fLArProp = lar::providerFrom<detinfo::LArPropertiesService>();
29  fScintPreScale = fLArProp->ScintPreScale();
30 
31  //the recombination coefficient is in g/(MeVcm^2), but we report energy depositions in MeV/cm,
32  //need to divide Recombk from the LArG4Parameters service by the density of the argon we got above.
33  fRecombA = LArG4PropHandle->RecombA();
34  fRecombk = LArG4PropHandle->Recombk() / detProp.Density(detProp.Temperature());
35  fModBoxA = LArG4PropHandle->ModBoxA();
36  fModBoxB = LArG4PropHandle->ModBoxB() / detProp.Density(detProp.Temperature());
37  fUseModBoxRecomb = (bool)LArG4PropHandle->UseModBoxRecomb();
38  fUseModLarqlRecomb = (bool)LArG4PropHandle->UseModLarqlRecomb();
39  fLarqlChi0A = LArG4PropHandle->LarqlChi0A();
40  fLarqlChi0B = LArG4PropHandle->LarqlChi0B();
41  fLarqlChi0C = LArG4PropHandle->LarqlChi0C();
42  fLarqlChi0D = LArG4PropHandle->LarqlChi0D();
43  fLarqlAlpha = LArG4PropHandle->LarqlAlpha();
44  fLarqlBeta = LArG4PropHandle->LarqlBeta();
45  fGeVToElectrons = LArG4PropHandle->GeVToElectrons();
46 
47  // ionization work function
48  fWion = 1. / fGeVToElectrons * 1e3; // MeV
49 
50  // ion+excitation work function (\todo: get from LArG4Parameters or LArProperties?)
51  fWph = 19.5 * 1e-6; // MeV
52  }
53 
54  //----------------------------------------------------------------------------
57  sim::SimEnergyDeposit const& edep)
58  {
59  double const energy_deposit = edep.Energy();
60 
61  // calculate total quanta (ions + excitons)
62  double Nq = energy_deposit / fWph;
63 
64  float ds = edep.StepLength();
65  double dEdx = (ds <= 0.0) ? 0.0 : energy_deposit / ds;
66  double EFieldStep = EFieldAtStep(detProp.Efield(), edep);
67  double recomb = 0.;
68 
69  //calculate recombination survival fraction value inside, otherwise zero
70 
71  if(EFieldStep > 0) {
72  // Guard against spurious values of dE/dx. Note: assumes density of LAr
73  if (dEdx < 1.) dEdx = 1.;
74 
75  // calculate recombination survival fraction
76  if (fUseModBoxRecomb) {
77  if (ds > 0) {
78  double Xi = fModBoxB * dEdx / EFieldStep;
79  recomb = log(fModBoxA + Xi) / Xi;
80  }
81  else {
82  recomb = 0;
83  }
84  }
85  else {
86  recomb = fRecombA / (1. + dEdx * fRecombk / EFieldStep);
87  }
88 
89  }//Efield
90 
91  if(fUseModLarqlRecomb){ //Use corrections from LArQL model
92  recomb += EscapingEFraction(dEdx)*FieldCorrection(EFieldStep, dEdx); //Correction for low EF
93  }
94 
95 
96 
97 
98  // using this recombination, calculate number of ionization electrons
99  double const num_electrons = (energy_deposit / fWion) * recomb;
100 
101  // calculate scintillation photons
102  double const num_photons = (Nq - num_electrons) * fScintPreScale;
103 
104  MF_LOG_DEBUG("ISCalcCorrelated")
105  << " Electrons produced for " << energy_deposit << " MeV deposited with " << recomb
106  << " recombination: " << num_electrons << std::endl;
107  MF_LOG_DEBUG("ISCalcCorrelated") << "number photons: " << num_photons;
108 
109  return {energy_deposit, num_electrons, num_photons, GetScintYieldRatio(edep)};
110  }
111 
112  //----------------------------------------------------------------------------
113  double
115  {
116  // For ISCalcCorrelated, the ScintByParticleType option only controls
117  // the scintillation yield ratio, which is the ratio of fast light (singlet
118  // component) to the total light (singlet+triplet components).
119  //
120  // TODO: move this to ISCalc, since it is the same function used in the
121  // other ionization/scintillation calculation algs
122 
124 
125  switch (edep.PdgCode()) {
126  case 2212: return fLArProp->ProtonScintYieldRatio();
127  case 13:
128  case -13: return fLArProp->MuonScintYieldRatio();
129  case 211:
130  case -211: return fLArProp->PionScintYieldRatio();
131  case 321:
132  case -321: return fLArProp->KaonScintYieldRatio();
133  case 1000020040: return fLArProp->AlphaScintYieldRatio();
134  case 11:
135  case -11:
136  case 22: return fLArProp->ElectronScintYieldRatio();
137  default: return fLArProp->ElectronScintYieldRatio();
138  }
139  }
140 
141  //----------------------------------------------------------------------------
142  double
144  {
145  //electric field outside active volume set to zero
146  if(!fISTPC.isScintInActiveVolume(edep.MidPoint())) return 0;
147 
148  //electric field inside active volume
149  if (!fSCE->EnableSimEfieldSCE()) return efield;
150 
151  auto const eFieldOffsets = fSCE->GetEfieldOffsets(edep.MidPoint());
152  return efield * std::hypot(1 + eFieldOffsets.X(), eFieldOffsets.Y(), eFieldOffsets.Z());
153  }
154 
155 
156 
157  double ISCalcCorrelated::EscapingEFraction(double const dEdx){ //LArQL chi0 function = fraction of escaping electrons
158  return fLarqlChi0A/(fLarqlChi0B+exp(fLarqlChi0C+fLarqlChi0D*dEdx));
159  }
160 
161  double ISCalcCorrelated::FieldCorrection(double const EF, double const dEdx){ //LArQL f_corr function = correction factor for electric field dependence
162  return exp(-EF/(fLarqlAlpha*log(dEdx)+fLarqlBeta));
163  }
164 
165 } // namespace
virtual bool EnableSimEfieldSCE() const =0
virtual double ElectronScintYieldRatio() const =0
virtual double ScintYieldRatio() const =0
geo::Length_t StepLength() const
double fModBoxA
from LArG4Parameters service
double ModBoxA() const
ISCalcData CalcIonAndScint(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) override
double fRecombk
from LArG4Parameters service
double fWion
W_ion (23.6 eV) == 1/fGeVToElectrons.
double fGeVToElectrons
from LArG4Parameters service
virtual double AlphaScintYieldRatio() const =0
double LarqlChi0B() const
double fModBoxB
from LArG4Parameters service
bool fUseModLarqlRecomb
from LArG4Parameters service
double LarqlBeta() const
double LarqlAlpha() const
bool UseModBoxRecomb() const
Geant4 interface.
double LarqlChi0D() const
double EscapingEFraction(double const dEdx)
virtual double ProtonScintYieldRatio() const =0
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Definition: hypot.h:60
double Efield(unsigned int planegap=0) const
kV/cm
double fScintPreScale
scintillation pre-scaling factor from LArProperties service
virtual double PionScintYieldRatio() const =0
double EFieldAtStep(double efield, sim::SimEnergyDeposit const &edep) override
double LarqlChi0C() const
double fWph
W_ph (19.5 eV)
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
const double e
bool UseModLarqlRecomb() const
double fLarqlChi0B
from LArG4Parameters service
double fLarqlChi0D
from LArG4Parameters service
geo::Point_t MidPoint() const
bool fUseModBoxRecomb
from LArG4Parameters service
double RecombA() const
double fLarqlChi0C
from LArG4Parameters service
double LarqlChi0A() const
ISCalcCorrelated(detinfo::DetectorPropertiesData const &detProp)
double fLarqlChi0A
from LArG4Parameters service
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
double ModBoxB() const
double Recombk() const
double fLarqlBeta
from LArG4Parameters service
Energy deposition in the active material.
virtual double MuonScintYieldRatio() const =0
#define MF_LOG_DEBUG(id)
double GetScintYieldRatio(sim::SimEnergyDeposit const &edep)
double fLarqlAlpha
from LArG4Parameters service
double Energy() const
const detinfo::LArProperties * fLArProp
virtual double KaonScintYieldRatio() const =0
const spacecharge::SpaceCharge * fSCE
bool isScintInActiveVolume(geo::Point_t const &ScintPoint)
Definition: ISTPC.cxx:41
virtual bool ScintByParticleType() const =0
double fRecombA
from LArG4Parameters service
int bool
Definition: qglobal.h:345
double GeVToElectrons() const
QTextStream & endl(QTextStream &s)
double FieldCorrection(double const EF, double const dEdx)