LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
larg4::ISCalcNESTLAr Class Reference

#include "ISCalcNESTLAr.h"

Inheritance diagram for larg4::ISCalcNESTLAr:
larg4::ISCalc

Public Member Functions

 ISCalcNESTLAr (CLHEP::HepRandomEngine &fEngine)
 
double EFieldAtStep (double efield, sim::SimEnergyDeposit const &edep) override
 
ISCalcData CalcIonAndScint (detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) override
 
double GetScintYield (sim::SimEnergyDeposit const &edep, bool prescale)
 
double GetScintYieldRatio (sim::SimEnergyDeposit const &edep)
 

Private Member Functions

int BinomFluct (int N0, double prob)
 
double CalcElectronLET (double E)
 

Private Attributes

CLHEP::HepRandomEngine & fEngine
 
const spacecharge::SpaceChargefSCE
 

Detailed Description

Definition at line 23 of file ISCalcNESTLAr.h.

Constructor & Destructor Documentation

larg4::ISCalcNESTLAr::ISCalcNESTLAr ( CLHEP::HepRandomEngine &  fEngine)
explicit

Definition at line 33 of file ISCalcNESTLAr.cxx.

34  : fEngine(Engine), fSCE{lar::providerFrom<spacecharge::SpaceChargeService>()}
35  {
36  std::cout << "ISCalcNESTLAr Initialize." << std::endl;
37  }
CLHEP::HepRandomEngine & fEngine
Definition: ISCalcNESTLAr.h:34
const spacecharge::SpaceCharge * fSCE
Definition: ISCalcNESTLAr.h:35

Member Function Documentation

int larg4::ISCalcNESTLAr::BinomFluct ( int  N0,
double  prob 
)
private

Definition at line 174 of file ISCalcNESTLAr.cxx.

References fEngine, and pmtana::mean().

Referenced by CalcIonAndScint().

175  {
176  CLHEP::RandGauss GaussGen(fEngine);
177  CLHEP::RandFlat UniformGen(fEngine);
178 
179  double mean = N0 * prob;
180  double sigma = sqrt(N0 * prob * (1 - prob));
181  int N1 = 0;
182  if (prob == 0.00) { return N1; }
183  if (prob == 1.00) { return N0; }
184 
185  if (N0 < 10) {
186  for (int i = 0; i < N0; i++) {
187  if (UniformGen.fire() < prob) { N1++; }
188  }
189  }
190  else {
191  N1 = int(floor(GaussGen.fire(mean, sigma) + 0.5));
192  }
193  if (N1 > N0) { N1 = N0; }
194  if (N1 < 0) { N1 = 0; }
195  return N1;
196  }
CLHEP::HepRandomEngine & fEngine
Definition: ISCalcNESTLAr.h:34
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:13
double larg4::ISCalcNESTLAr::CalcElectronLET ( double  E)
private

Definition at line 199 of file ISCalcNESTLAr.cxx.

Referenced by CalcIonAndScint().

200  {
201  double LET;
202 
203  if (E >= 1) {
204  LET = 116.70 - 162.97 * log10(E) + 99.361 * pow(log10(E), 2) - 33.405 * pow(log10(E), 3) +
205  6.5069 * pow(log10(E), 4) - 0.69334 * pow(log10(E), 5) + .031563 * pow(log10(E), 6);
206  }
207  else if (E > 0 && E < 1) {
208  LET = 100;
209  }
210  else {
211  LET = 0;
212  }
213 
214  return LET;
215  }
Float_t E
Definition: plot.C:20
ISCalcData larg4::ISCalcNESTLAr::CalcIonAndScint ( detinfo::DetectorPropertiesData const &  detProp,
sim::SimEnergyDeposit const &  edep 
)
overridevirtual

Implements larg4::ISCalc.

Definition at line 40 of file ISCalcNESTLAr.cxx.

References util::abs(), BinomFluct(), CalcElectronLET(), detinfo::DetectorPropertiesData::Density(), Density_LAr, edep, detinfo::DetectorPropertiesData::Efield(), EFieldAtStep(), sim::SimEnergyDeposit::EndX(), sim::SimEnergyDeposit::EndY(), sim::SimEnergyDeposit::EndZ(), sim::SimEnergyDeposit::Energy(), fEngine, larg4::ISCalc::GetScintYieldRatio(), sim::SimEnergyDeposit::PdgCode(), sim::SimEnergyDeposit::StartX(), sim::SimEnergyDeposit::StartY(), and sim::SimEnergyDeposit::StartZ().

42  {
43  CLHEP::RandGauss GaussGen(fEngine);
44  CLHEP::RandFlat UniformGen(fEngine);
45 
46  double yieldFactor = 1.0; // default quenching factor, for electronic recoils
47  double excitationRatio =
48  0.21; // ratio for light particle in LAr, such as e-, mu-, Aprile et. al book
49 
50  double const energyDeposit = edep.Energy();
51  if (energyDeposit < 1 * CLHEP::eV) // too small energy deposition
52  {
53  return {0., 0., 0., 0.};
54  }
55 
56  int pdgcode = edep.PdgCode();
57 
58  geo::Length_t startx = edep.StartX();
59  geo::Length_t starty = edep.StartY();
60  geo::Length_t startz = edep.StartZ();
61  geo::Length_t endx = edep.EndX();
62  geo::Length_t endy = edep.EndY();
63  geo::Length_t endz = edep.EndZ();
64 
65  double DokeBirks[3];
66 
67  double eField = EFieldAtStep(detProp.Efield(), edep);
68  if (eField) {
69  DokeBirks[0] = 0.07 * pow((eField / 1.0e3), -0.85);
70  DokeBirks[2] = 0.00;
71  }
72  else {
73  DokeBirks[0] = 0.0003;
74  DokeBirks[2] = 0.75;
75  }
76 
77  double Density = detProp.Density() /
78  (CLHEP::g / CLHEP::cm3); // argon density at the temperature from Temperature()
79 
80  // nuclear recoil quenching "L" factor: total yield is
81  // reduced for nuclear recoil as per Lindhard theory
82  double epsilon = 11.5 * (energyDeposit / CLHEP::keV) * pow(LAr_Z, (-7. / 3.));
83 
84  if (pdgcode == 2112 || pdgcode == -2112) //nuclear recoil
85  {
86  yieldFactor = 0.23 * (1 + exp(-5 * epsilon)); //liquid argon L_eff
87  excitationRatio = 0.69337 + 0.3065 * exp(-0.008806 * pow(eField, 0.76313));
88  }
89 
90  // determine ultimate number of quanta from current E-deposition (ph+e-) total mean number of exc/ions
91  //the total number of either quanta produced is equal to product of the
92  //work function, the energy deposited, and yield reduction, for NR
93  double MeanNumQuanta = scint_yield * energyDeposit;
94  double sigma = sqrt(resolution_scale * MeanNumQuanta); //Fano
95  int NumQuanta = int(floor(GaussGen.fire(MeanNumQuanta, sigma) + 0.5));
96  double LeffVar = GaussGen.fire(yieldFactor, 0.25 * yieldFactor);
97  LeffVar = std::clamp(LeffVar, 0., 1.);
98 
99  if (yieldFactor < 1) //nuclear reocils
100  {
101  NumQuanta = BinomFluct(NumQuanta, LeffVar);
102  }
103 
104  //if Edep below work function, can't make any quanta, and if NumQuanta
105  //less than zero because Gaussian fluctuated low, update to zero
106  if (energyDeposit < 1 / scint_yield || NumQuanta < 0) { NumQuanta = 0; }
107 
108  // next section binomially assigns quanta to excitons and ions
109  int NumExcitons = BinomFluct(NumQuanta, excitationRatio / (1 + excitationRatio));
110  int NumIons = NumQuanta - NumExcitons;
111 
112  // this section calculates recombination following the modified Birks'Law of Doke, deposition by deposition,
113  // may be overridden later in code if a low enough energy necessitates switching to the
114  // Thomas-Imel box model for recombination instead (determined by site)
115  double dE = energyDeposit / CLHEP::MeV;
116  double dx = 0.0;
117  double LET = 0.0;
118  double recombProb;
119 
120  if (pdgcode != 11 && pdgcode != -11 && pdgcode != 13 &&
121  pdgcode != -13) //e-: 11, e+: -11, mu-: 13, mu+: -13
122  {
123  //in other words, if it's a gamma,ion,proton,alpha,pion,et al. do not
124  //use the step length provided by Geant4 because it's not relevant,
125  //instead calculate an estimated LET and range of the electrons that
126  //would have been produced if Geant4 could track them
127  LET = CalcElectronLET(1000 * dE);
128 
129  if (LET) {
130  dx = dE / (Density * LET); //find the range based on the LET
131  }
132 
133  if (abs(pdgcode) == 2112) //nuclear recoils
134  {
135  dx = 0;
136  }
137  }
138  else //normal case of an e-/+ energy deposition recorded by Geant
139  {
140  dx = std::hypot(startx - endx, starty - endy, startz - endz) / CLHEP::cm;
141  if (dx) {
142  LET = (dE / dx) * (1 / Density); //lin. energy xfer (prop. to dE/dx)
143  }
144  if (LET > 0 && dE > 0 && dx > 0) {
145  double ratio = CalcElectronLET(dE * 1e3) / LET;
146  if (ratio < 0.7 && pdgcode == 11) {
147  dx /= ratio;
148  LET *= ratio;
149  }
150  }
151  }
152 
153  DokeBirks[1] = DokeBirks[0] / (1 - DokeBirks[2]); //B=A/(1-C) (see paper) r
154  recombProb = (DokeBirks[0] * LET) / (1 + DokeBirks[1] * LET) +
155  DokeBirks[2]; //Doke/Birks' Law as spelled out in the NEST pape
156  recombProb *= (Density / Density_LAr);
157 
158  //check against unphysicality resulting from rounding errors
159  recombProb = std::clamp(recombProb, 0., 1.);
160 
161  //use binomial distribution to assign photons, electrons, where photons
162  //are excitons plus recombined ionization electrons, while final
163  //collected electrons are the "escape" (non-recombined) electrons
164  int const NumPhotons = NumExcitons + BinomFluct(NumIons, recombProb);
165  int const NumElectrons = NumQuanta - NumPhotons;
166 
167  return {energyDeposit,
168  static_cast<double>(NumElectrons),
169  static_cast<double>(NumPhotons),
171  }
CLHEP::HepRandomEngine & fEngine
Definition: ISCalcNESTLAr.h:34
#define Density_LAr
Definition: NestAlg.cxx:26
double Length_t
Type used for coordinates and distances. They are measured in centimeters.
Definition: geo_vectors.h:133
constexpr auto abs(T v)
Returns the absolute value of the argument.
int BinomFluct(int N0, double prob)
Double_t edep
Definition: macro.C:13
double CalcElectronLET(double E)
double GetScintYieldRatio(sim::SimEnergyDeposit const &edep)
Definition: ISCalc.cxx:41
double EFieldAtStep(double efield, sim::SimEnergyDeposit const &edep) override
double larg4::ISCalcNESTLAr::EFieldAtStep ( double  efield,
sim::SimEnergyDeposit const &  edep 
)
overridevirtual

Implements larg4::ISCalc.

Definition at line 218 of file ISCalcNESTLAr.cxx.

References spacecharge::SpaceCharge::EnableSimEfieldSCE(), fSCE, spacecharge::SpaceCharge::GetEfieldOffsets(), and sim::SimEnergyDeposit::MidPoint().

Referenced by CalcIonAndScint().

219  {
220  geo::Point_t pos = edep.MidPoint();
221  double EField = efield;
222  geo::Vector_t eFieldOffsets;
223  if (fSCE->EnableSimEfieldSCE()) {
224  eFieldOffsets = fSCE->GetEfieldOffsets(pos);
225  EField =
226  std::sqrt((efield + efield * eFieldOffsets.X()) * (efield + efield * eFieldOffsets.X()) +
227  (efield * eFieldOffsets.Y() * efield * eFieldOffsets.Y()) +
228  (efield * eFieldOffsets.Z() * efield * eFieldOffsets.Z()));
229  }
230  return EField;
231  }
virtual bool EnableSimEfieldSCE() const =0
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
const spacecharge::SpaceCharge * fSCE
Definition: ISCalcNESTLAr.h:35
Double_t edep
Definition: macro.C:13
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
double larg4::ISCalc::GetScintYield ( sim::SimEnergyDeposit const &  edep,
bool  prescale 
)
inherited

Definition at line 21 of file ISCalc.cxx.

References detinfo::LArProperties::AlphaScintYield(), detinfo::LArProperties::ElectronScintYield(), larg4::ISCalc::fLArProp, detinfo::LArProperties::KaonScintYield(), detinfo::LArProperties::MuonScintYield(), sim::SimEnergyDeposit::PdgCode(), detinfo::LArProperties::PionScintYield(), detinfo::LArProperties::ProtonScintYield(), detinfo::LArProperties::ScintByParticleType(), and detinfo::LArProperties::ScintYield().

Referenced by larg4::ISCalcSeparate::CalcScint().

22  {
23  if (!fLArProp->ScintByParticleType()) return fLArProp->ScintYield(true);
24  switch (edep.PdgCode()) {
25  case 2212: return fLArProp->ProtonScintYield(true);
26  case 13:
27  case -13: return fLArProp->MuonScintYield(true);
28  case 211:
29  case -211: return fLArProp->PionScintYield(true);
30  case 321:
31  case -321: return fLArProp->KaonScintYield(true);
32  case 1000020040: return fLArProp->AlphaScintYield(true);
33  case 11:
34  case -11:
35  case 22: return fLArProp->ElectronScintYield(true);
36  default: return fLArProp->ElectronScintYield(true);
37  }
38  }
virtual double AlphaScintYield(bool prescale=false) const =0
virtual double ProtonScintYield(bool prescale=false) const =0
const detinfo::LArProperties * fLArProp
Definition: ISCalc.h:33
virtual double ElectronScintYield(bool prescale=false) const =0
virtual double PionScintYield(bool prescale=false) const =0
Double_t edep
Definition: macro.C:13
virtual double MuonScintYield(bool prescale=false) const =0
virtual double KaonScintYield(bool prescale=false) const =0
virtual double ScintYield(bool prescale=false) const =0
virtual bool ScintByParticleType() const =0
double larg4::ISCalc::GetScintYieldRatio ( sim::SimEnergyDeposit const &  edep)
inherited

Definition at line 41 of file ISCalc.cxx.

References detinfo::LArProperties::AlphaScintYieldRatio(), detinfo::LArProperties::ElectronScintYieldRatio(), larg4::ISCalc::fLArProp, detinfo::LArProperties::KaonScintYieldRatio(), detinfo::LArProperties::MuonScintYieldRatio(), sim::SimEnergyDeposit::PdgCode(), detinfo::LArProperties::PionScintYieldRatio(), detinfo::LArProperties::ProtonScintYieldRatio(), detinfo::LArProperties::ScintByParticleType(), and detinfo::LArProperties::ScintYieldRatio().

Referenced by CalcIonAndScint(), larg4::ISCalcCorrelated::CalcIonAndScint(), and larg4::ISCalcSeparate::CalcScint().

42  {
43  // ScintByParticleType option only controls the scintillation
44  // yield ratio, which is the ratio of fast light (singlet
45  // component) to the total light (singlet+triplet components).
46 
48 
49  switch (edep.PdgCode()) {
50  case 2212: return fLArProp->ProtonScintYieldRatio();
51  case 13:
52  case -13: return fLArProp->MuonScintYieldRatio();
53  case 211:
54  case -211: return fLArProp->PionScintYieldRatio();
55  case 321:
56  case -321: return fLArProp->KaonScintYieldRatio();
57  case 1000020040: return fLArProp->AlphaScintYieldRatio();
58  case 11:
59  case -11:
60  case 22: return fLArProp->ElectronScintYieldRatio();
61  default: return fLArProp->ElectronScintYieldRatio();
62  }
63  }
virtual double ElectronScintYieldRatio() const =0
virtual double ScintYieldRatio() const =0
virtual double AlphaScintYieldRatio() const =0
virtual double ProtonScintYieldRatio() const =0
virtual double PionScintYieldRatio() const =0
const detinfo::LArProperties * fLArProp
Definition: ISCalc.h:33
Double_t edep
Definition: macro.C:13
virtual double MuonScintYieldRatio() const =0
virtual double KaonScintYieldRatio() const =0
virtual bool ScintByParticleType() const =0

Member Data Documentation

CLHEP::HepRandomEngine& larg4::ISCalcNESTLAr::fEngine
private

Definition at line 34 of file ISCalcNESTLAr.h.

Referenced by BinomFluct(), and CalcIonAndScint().

const spacecharge::SpaceCharge* larg4::ISCalcNESTLAr::fSCE
private

Definition at line 35 of file ISCalcNESTLAr.h.

Referenced by EFieldAtStep().


The documentation for this class was generated from the following files: