All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
17 
25 
26 #include "art/Framework/Services/Registry/ServiceHandle.h"
27 #include "CLHEP/Random/RandBinomial.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
29 
30 #include <iostream>
31 
32 namespace larg4 {
33  //----------------------------------------------------------------------------
35  : fISTPC{*(lar::providerFrom<geo::Geometry>())}
36  , fSCE(lar::providerFrom<spacecharge::SpaceChargeService>())
37  , fBinomialGen{CLHEP::RandBinomial(Engine)}
38  {
39  MF_LOG_INFO("ISCalcCorrelated") << "IonizationAndScintillation/ISCalcCorrelated Initialize.";
40 
41  fScintPreScale = lar::providerFrom<detinfo::LArPropertiesService>()->ScintPreScale();
42 
43  art::ServiceHandle<sim::LArG4Parameters const> LArG4PropHandle;
44 
45  // The recombination coefficient is in g/(MeVcm^2), but we report
46  // energy depositions in MeV/cm, need to divide Recombk from the
47  // LArG4Parameters service by the density of the argon we got
48  // above.
49  fRecombA = LArG4PropHandle->RecombA();
50  fRecombk = LArG4PropHandle->Recombk() / detProp.Density(detProp.Temperature());
51  fModBoxA = LArG4PropHandle->ModBoxA();
52  fModBoxB = LArG4PropHandle->ModBoxB() / detProp.Density(detProp.Temperature());
53  fUseModBoxRecomb = (bool)LArG4PropHandle->UseModBoxRecomb();
54  fUseModLarqlRecomb = (bool)LArG4PropHandle->UseModLarqlRecomb();
55  fUseBinomialFlucts = (bool)LArG4PropHandle->UseBinomialFlucts();
56  fLarqlChi0A = LArG4PropHandle->LarqlChi0A();
57  fLarqlChi0B = LArG4PropHandle->LarqlChi0B();
58  fLarqlChi0C = LArG4PropHandle->LarqlChi0C();
59  fLarqlChi0D = LArG4PropHandle->LarqlChi0D();
60  fLarqlAlpha = LArG4PropHandle->LarqlAlpha();
61  fLarqlBeta = LArG4PropHandle->LarqlBeta();
62  fGeVToElectrons = LArG4PropHandle->GeVToElectrons();
63 
64  // ionization work function
65  fWion = 1. / fGeVToElectrons * 1e3; // MeV
66 
67  // ion+excitation work function
68  fWph = LArG4PropHandle->Wph() * 1e-6; // MeV
69  }
70 
71  //----------------------------------------------------------------------------
72  ISCalcData
74  sim::SimEnergyDeposit const& edep)
75  {
76 
77  double const energy_deposit = edep.Energy();
78 
79  // calculate total quanta (ions + excitons)
80  double num_ions = energy_deposit / fWion;
81  double num_quanta = energy_deposit / fWph;
82 
83  double ds = edep.StepLength();
84  double dEdx = (ds <= 0.0) ? 0.0 : energy_deposit / ds;
85  dEdx = (dEdx < 1.) ? 1. : dEdx;
86  double EFieldStep = EFieldAtStep(detProp.Efield(), edep);
87  double recomb = 0.;
88 
89  //calculate recombination survival fraction value inside, otherwise zero
90  if(EFieldStep > 0.) {
91  // calculate recombination survival fraction
92  // ...using Modified Box model
93  if (fUseModBoxRecomb) {
94  double Xi = fModBoxB * dEdx / EFieldStep;
95  recomb = std::log(fModBoxA + Xi) / Xi;
96  }
97  // ... or using Birks/Doke
98  else {
99  recomb = fRecombA / (1. + dEdx * fRecombk / EFieldStep);
100  }
101  }
102 
103  if(fUseModLarqlRecomb){ //Use corrections from LArQL model
104  recomb += EscapingEFraction(dEdx)*FieldCorrection(EFieldStep, dEdx); //Correction for low EF
105  }
106 
107  // Guard against unphysical recombination values
108  if (recomb < 0.){
109  mf::LogWarning("ISCalcCorrelated")
110  << "Recombination survival fraction is lower than 0.: " << recomb
111  << ", fixing it to 0.";
112  recomb = 0.;
113  }
114  else if (recomb > 1.){
115  mf::LogWarning("ISCalcCorrelated")
116  << "Recombination survival fraction is higher than 1.: " << recomb
117  << ", fixing it to 1.";
118  recomb = 1.;
119  }
120 
121  // using this recombination, calculate number of ionization electrons
122  double num_electrons = (fUseBinomialFlucts) ?
123  fBinomialGen.fire(num_ions, recomb) : (num_ions * recomb);
124 
125  // calculate scintillation photons
126  double num_photons = (num_quanta - num_electrons) * fScintPreScale;
127 
128  MF_LOG_DEBUG("ISCalcCorrelated")
129  << "With " << energy_deposit << " MeV of deposited energy, "
130  << "and a recombination of " << recomb << ", \nthere are "
131  << num_electrons << " electrons, and " << num_photons << " photons.";
132 
133  return {energy_deposit, num_electrons, num_photons, GetScintYieldRatio(edep)};
134  }
135 
136  //----------------------------------------------------------------------------
137  double
139  sim::SimEnergyDeposit const& edep)
140  {
141  // electric field outside active volume set to zero
142  if(!fISTPC.isScintInActiveVolume(edep.MidPoint())) return 0.;
143 
144  // electric field inside active volume
145  if (!fSCE->EnableSimEfieldSCE()) return efield;
146 
147  auto const eFieldOffsets = fSCE->GetEfieldOffsets(edep.MidPoint());
148  return efield * std::hypot(1 + eFieldOffsets.X(), eFieldOffsets.Y(), eFieldOffsets.Z());
149  }
150 
151 
152  //----------------------------------------------------------------------------
153  // LArQL chi0 function = fraction of escaping electrons
154  double
156  {
158  }
159 
160  //----------------------------------------------------------------------------
161  // LArQL f_corr function = correction factor for electric field dependence
162  double ISCalcCorrelated::FieldCorrection(double const EF,
163  double const dEdx) const
164  {
165  return std::exp(-EF/(fLarqlAlpha*std::log(dEdx)+fLarqlBeta));
166  }
167 
168 } // namespace larg4
Store parameters for running LArG4.
double FieldCorrection(double const EF, double const dEdx) const
double EscapingEFraction(double const dEdx) const
geo::Length_t StepLength() const
double fModBoxA
from LArG4Parameters service
Utilities related to art service access.
ISCalcData CalcIonAndScint(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) override
double fRecombk
from LArG4Parameters service
stream1 stream1 can override from command line with o or output services LArPropertiesService ScintPreScale
double fWion
W_ion (23.6 eV) == 1/fGeVToElectrons.
CLHEP::RandBinomial fBinomialGen
double fModBoxB
from LArG4Parameters service
bool fUseModLarqlRecomb
from LArG4Parameters service
static constexpr bool
double Efield(unsigned int planegap=0) const
kV/cm
double fScintPreScale
scintillation pre-scaling factor from LArProperties service
double EFieldAtStep(double efield, sim::SimEnergyDeposit const &edep) override
double fWph
from LArG4Parameters service
bool fUseBinomialFlucts
from LArG4Parameters service
double fLarqlChi0B
from LArG4Parameters service
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
double fLarqlChi0D
from LArG4Parameters service
geo::Point_t MidPoint() const
bool fUseModBoxRecomb
from LArG4Parameters service
double fLarqlChi0C
from LArG4Parameters service
createEngine fGeVToElectrons
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2687
double fLarqlChi0A
from LArG4Parameters service
contains information for a single step in the detector simulation
double fLarqlBeta
from LArG4Parameters service
Energy deposition in the active material.
createEngine fUseModBoxRecomb
do i e
double fLarqlAlpha
from LArG4Parameters service
double Energy() const
const spacecharge::SpaceCharge * fSCE
bool isScintInActiveVolume(geo::Point_t const &ScintPoint)
Definition: ISTPC.cxx:43
double fRecombA
from LArG4Parameters service
double GetScintYieldRatio(sim::SimEnergyDeposit const &edep)
Definition: ISCalc.cxx:47
ISCalcCorrelated(detinfo::DetectorPropertiesData const &detProp, CLHEP::HepRandomEngine &Engine)
virtual bool EnableSimEfieldSCE() const =0
art framework interface to geometry description
auto const detProp