ISCalculationSeparate.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file ISCalcuation.cc
3 /// \brief Interface to algorithm class for calculating ionization electrons
4 /// and scintillation photons using separate algorithms for each
5 ///
6 /// Wes, 18Feb2018: this is a copy of the original, for standalone purposes
7 ///
8 ///
9 /// \version $Id: $
10 /// \author brebel@fnal.gov
11 ////////////////////////////////////////////////////////////////////////
12 
13 #include "fhiclcpp/ParameterSet.h"
15 
24 
26 
27 #include <cmath>
28 #include <ostream>
29 
30 namespace {
31  constexpr double scint_yield_factor{1.};
32 }
33 
34 namespace detsim {
35 
36  //----------------------------------------------------------------------------
38  : fRecombA{pset.get<double>("RecombA")}
39  , fRecombk{pset.get<double>("Recombk")}
40  , fModBoxA{pset.get<double>("ModBoxA")}
41  , fModBoxB{pset.get<double>("ModBoxB")}
42  , fUseModBoxRecomb{pset.get<bool>("UseModBoxRecomb")}
43  , fGeVToElectrons{pset.get<double>("GeVToElectrons")}
44  {
45  fLArProp = lar::providerFrom<detinfo::LArPropertiesService>();
46  fSCE = lar::providerFrom<spacecharge::SpaceChargeService>();
47 
48  // the recombination coefficient is in g/(MeVcm^2), but
49  // we report energy depositions in MeV/cm, need to divide
50  // Recombk from the LArG4Parameters service by the density
51  // of the argon we got above. FIXME: is this being done?
52 
53  std::cout << "fLArG4Prop->GeVToElectrons(): " << fGeVToElectrons << std::endl;
54  }
55 
56  //----------------------------------------------------------------------------
57  // fNumIonElectrons returns a value that is not corrected for life time effects
58  double
60  sim::SimEnergyDeposit const& edep) const
61  {
62  float e = edep.Energy();
63  float ds = edep.StepLength();
64  float x = edep.MidPointX();
65  float y = edep.MidPointY();
66  float z = edep.MidPointZ();
67  double recomb = 0.;
68  double dEdx = (ds <= 0.0) ? 0.0 : e / ds;
69  double EFieldStep = EFieldAtStep(detProp.Efield(), x, y, z);
70 
71  // Guard against spurious values of dE/dx. Note: assumes density of LAr
72  if (dEdx < 1.) dEdx = 1.;
73 
74  if (fUseModBoxRecomb) {
75  if (ds > 0) {
76  double Xi = fModBoxB * dEdx / EFieldStep;
77  recomb = log(fModBoxA + Xi) / Xi;
78  }
79  else
80  recomb = 0;
81  }
82  else {
83  recomb = fRecombA / (1. + dEdx * fRecombk / EFieldStep);
84  }
85 
86  // 1.e-3 converts fEnergyDeposit to GeV
87  double const numIonElectrons = fGeVToElectrons * 1.e-3 * e * recomb;
88 
89  MF_LOG_DEBUG("ISCalculationSeparate")
90  << " Electrons produced for " << edep.Energy() << " MeV deposited with " << recomb
91  << " recombination: " << numIonElectrons << std::endl;
92 
93  return numIonElectrons;
94  }
95 
96  //----------------------------------------------------------------------------
97  double
99  {
100  float const e = edep.Energy();
101  int const pdg = edep.PdgCode();
102  double scintYield = fLArProp->ScintYield(true);
103  if (fLArProp->ScintByParticleType()) {
104 
105  MF_LOG_DEBUG("ISCalculationSeparate") << "scintillating by particle type";
106 
107  switch (pdg) {
108 
109  case 2212: scintYield = fLArProp->ProtonScintYield(true); break;
110  case 13:
111  case -13: scintYield = fLArProp->MuonScintYield(true); break;
112  case 211:
113  case -211: scintYield = fLArProp->PionScintYield(true); break;
114  case 321:
115  case -321: scintYield = fLArProp->KaonScintYield(true); break;
116  case 1000020040: scintYield = fLArProp->AlphaScintYield(true); break;
117  case 11:
118  case -11:
119  case 22: scintYield = fLArProp->ElectronScintYield(true); break;
120  default: scintYield = fLArProp->ElectronScintYield(true);
121  }
122 
123  return scintYield * e;
124  }
125 
126  return scint_yield_factor * scintYield * e;
127  }
128  //----------------------------------------------------------------------------
131  detinfo::DetectorPropertiesData const& detProp,
132  sim::SimEnergyDeposit const& edep) const
133  {
134  return {edep.Energy(), CalculateIonization(detProp, edep), CalculateScintillation(edep)};
135  }
136 
137  double
138  ISCalculationSeparate::EFieldAtStep(double const efield, sim::SimEnergyDeposit const& edep) const
139  {
140  return EFieldAtStep(efield, edep.MidPointX(), edep.MidPointY(), edep.MidPointZ());
141  }
142 
143  double
145  float const x,
146  float const y,
147  float const z) const
148  {
149  if (not fSCE->EnableSimEfieldSCE()) { return efield; }
150 
151  auto const offsets = fSCE->GetEfieldOffsets(geo::Point_t{x, y, z});
152  return std::hypot(efield + efield * offsets.X(), efield * offsets.Y(), efield * offsets.Z());
153  }
154 
155 } // namespace
virtual bool EnableSimEfieldSCE() const =0
virtual double AlphaScintYield(bool prescale=false) const =0
geo::Length_t StepLength() const
const detinfo::LArProperties * fLArProp
double fGeVToElectrons
from LArG4Parameters service
Detector simulation of raw signals on wires.
double CalculateIonization(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) const
ISCalculationSeparate(fhicl::ParameterSet const &pset)
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Definition: hypot.h:60
const spacecharge::SpaceCharge * fSCE
double Efield(unsigned int planegap=0) const
kV/cm
virtual double ProtonScintYield(bool prescale=false) const =0
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
const double e
double EFieldAtStep(double efield, sim::SimEnergyDeposit const &edep) const
T get(std::string const &key) const
Definition: ParameterSet.h:271
virtual double ElectronScintYield(bool prescale=false) const =0
Data CalculateIonizationAndScintillation(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) const
virtual double PionScintYield(bool prescale=false) const =0
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:184
geo::Length_t MidPointX() const
geo::Length_t MidPointY() const
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
virtual double MuonScintYield(bool prescale=false) const =0
virtual double KaonScintYield(bool prescale=false) const =0
contains information for a single step in the detector simulation
geo::Length_t MidPointZ() const
virtual double ScintYield(bool prescale=false) const =0
Energy deposition in the active material.
#define MF_LOG_DEBUG(id)
list x
Definition: train.py:276
double Energy() const
virtual bool ScintByParticleType() const =0
QTextStream & endl(QTextStream &s)
double CalculateScintillation(sim::SimEnergyDeposit const &edep) const