13 #include "CLHEP/Random/RandFlat.h" 14 #include "CLHEP/Random/RandGauss.h" 15 #include "CLHEP/Random/RandPoissonQ.h" 16 #include "CLHEP/Units/SystemOfUnits.h" 21 constexpr
double LAr_Z{18};
24 constexpr
double scint_yield{1.0 / (19.5 *
CLHEP::eV)};
25 constexpr
double resolution_scale{0.107};
33 , fSCE{lar::providerFrom<spacecharge::SpaceChargeService>()}
34 ,
fLArProp{lar::providerFrom<detinfo::LArPropertiesService>()}
36 std::cout <<
"ISCalcNESTLAr Initialize." <<
std::endl;
44 CLHEP::RandGauss GaussGen(
fEngine);
45 CLHEP::RandFlat UniformGen(
fEngine);
47 double yieldFactor = 1.0;
48 double excitationRatio =
51 double const energyDeposit = edep.
Energy();
54 return {0., 0., 0., 0.};
70 DokeBirks[0] = 0.07 *
pow((eField / 1.0e3), -0.85);
74 DokeBirks[0] = 0.0003;
83 double epsilon = 11.5 * (energyDeposit /
CLHEP::keV) *
pow(LAr_Z, (-7. / 3.));
85 if (pdgcode == 2112 || pdgcode == -2112)
87 yieldFactor = 0.23 * (1 + exp(-5 * epsilon));
88 excitationRatio = 0.69337 + 0.3065 * exp(-0.008806 *
pow(eField, 0.76313));
94 double MeanNumQuanta = scint_yield * energyDeposit;
95 double sigma = sqrt(resolution_scale * MeanNumQuanta);
96 int NumQuanta =
int(floor(GaussGen.fire(MeanNumQuanta, sigma) + 0.5));
97 double LeffVar = GaussGen.fire(yieldFactor, 0.25 * yieldFactor);
98 LeffVar = std::clamp(LeffVar, 0., 1.);
107 if (energyDeposit < 1 / scint_yield || NumQuanta < 0) { NumQuanta = 0; }
110 int NumExcitons =
BinomFluct(NumQuanta, excitationRatio / (1 + excitationRatio));
111 int NumIons = NumQuanta - NumExcitons;
121 if (pdgcode != 11 && pdgcode != -11 && pdgcode != 13 &&
131 dx = dE / (Density * LET);
134 if (
abs(pdgcode) == 2112)
143 LET = (dE / dx) * (1 / Density);
145 if (LET > 0 && dE > 0 && dx > 0) {
147 if (ratio < 0.7 && pdgcode == 11) {
154 DokeBirks[1] = DokeBirks[0] / (1 - DokeBirks[2]);
155 recombProb = (DokeBirks[0] * LET) / (1 + DokeBirks[1] * LET) +
160 recombProb = std::clamp(recombProb, 0., 1.);
165 int const NumPhotons = NumExcitons +
BinomFluct(NumIons, recombProb);
166 int const NumElectrons = NumQuanta - NumPhotons;
168 return {energyDeposit,
169 static_cast<double>(NumElectrons),
170 static_cast<double>(NumPhotons),
178 CLHEP::RandGauss GaussGen(
fEngine);
179 CLHEP::RandFlat UniformGen(
fEngine);
181 double mean = N0 * prob;
182 double sigma = sqrt(N0 * prob * (1 - prob));
184 if (prob == 0.00) {
return N1; }
185 if (prob == 1.00) {
return N0; }
188 for (
int i = 0; i < N0; i++) {
189 if (UniformGen.fire() < prob) { N1++; }
193 N1 =
int(floor(GaussGen.fire(mean, sigma) + 0.5));
195 if (N1 > N0) { N1 = N0; }
196 if (N1 < 0) { N1 = 0; }
207 LET = 116.70 - 162.97 * log10(E) + 99.361 *
pow(log10(E), 2) - 33.405 *
pow(log10(E), 3) +
208 6.5069 *
pow(log10(E), 4) - 0.69334 *
pow(log10(E), 5) + .031563 *
pow(log10(E), 6);
210 else if (E > 0 && E < 1) {
225 double EField = efield;
232 std::sqrt((efield + efield * eFieldOffsets.X()) * (efield + efield * eFieldOffsets.X()) +
233 (efield * eFieldOffsets.Y() * efield * eFieldOffsets.Y()) +
234 (efield * eFieldOffsets.Z() * efield * eFieldOffsets.Z()));
static constexpr double cm
geo::Length_t StartX() const
CLHEP::HepRandomEngine & fEngine
virtual bool EnableSimEfieldSCE() const =0
geo::Length_t EndZ() const
virtual double ElectronScintYieldRatio() const =0
ISCalcNESTLAr(CLHEP::HepRandomEngine &fEngine)
virtual double ScintYieldRatio() const =0
static constexpr double keV
geo::Length_t EndY() const
static constexpr double g
virtual double AlphaScintYieldRatio() const =0
static constexpr double cm3
const spacecharge::SpaceCharge * fSCE
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
static constexpr double MeV
virtual double ProtonScintYieldRatio() const =0
geo::Length_t StartY() const
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
double Efield(unsigned int planegap=0) const
kV/cm
virtual double PionScintYieldRatio() const =0
geo::Length_t EndX() const
const detinfo::LArProperties * fLArProp
static constexpr double eV
geo::Point_t MidPoint() const
double Density(double temperature=0.) const
Returns argon density at a given temperature.
int BinomFluct(int N0, double prob)
geo::Length_t StartZ() const
ISCalcData CalcIonAndScint(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) override
double GetScintYieldRatio(sim::SimEnergyDeposit const &edep)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
double Length_t
Type used for coordinates and distances. They are measured in centimeters.
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
double CalcElectronLET(double E)
Energy deposition in the active material.
virtual double MuonScintYieldRatio() const =0
virtual double KaonScintYieldRatio() const =0
virtual bool ScintByParticleType() const =0
double EFieldAtStep(double efield, sim::SimEnergyDeposit const &edep) override
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
QTextStream & endl(QTextStream &s)