LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
SimEnergyDeposit.h
Go to the documentation of this file.
1 #ifndef LARDATAOBJ_SIMULATION_SIMENERGYDEPOSIT_H
8 #define LARDATAOBJ_SIMULATION_SIMENERGYDEPOSIT_H
9 
10 // LArSoft includes
11 // Define the LArSoft standard geometry types and methods.
13 
14 // C++ includes
15 #include <vector>
16 
17 namespace sim {
41  public:
42  // Define the types for the private members below.
43  using Length_t = float;
45 
46  // Since we're using LArSoft geometry types, the typical way to
47  // construct a SimEnergyDeposit might be:
48  // sim::SimEnergyDeposit sed(numPhotons,
49  // numElectrons,
50  // stepEnergy,
51  // { startX, startY, startZ },
52  // { endX, endY, endZ },
53  // startTime,
54  // endTime,
55  // trackID,
56  // pdgCode);
57 
58  SimEnergyDeposit(int np = 0,
59  // int nfp = 0,
60  // int nsp = 0,
61  int ne = 0,
62  double sy = 0,
63  double e = 0.,
64  geo::Point_t start = {0., 0., 0.},
65  geo::Point_t end = {0., 0., 0.},
66  double t0 = 0.,
67  double t1 = 0.,
68  int id = 0,
69  int pdg = 0,
70  int origTrackID = 0)
71  : numPhotons(np)
72  // , numFPhotons(nfp)
73  // , numSPhotons(nsp)
74  , numElectrons(ne)
75  , scintYieldRatio(sy)
76  , edep(e)
77  , startPos(start)
78  , endPos(end)
79  , startTime(t0)
80  , endTime(t1)
81  , trackID(id)
82  , pdgCode(pdg)
83  , origTrackID(origTrackID)
84  {}
85 
86  // Note that even if we store a value as float, we return
87  // it as double so the user doesn't have to think about
88  // precision issues.
89 
90  int NumPhotons() const { return numPhotons; }
91  int NumFPhotons() const { return round(numPhotons * scintYieldRatio); }
92  int NumSPhotons() const { return round(numPhotons * (1.0 - scintYieldRatio)); }
93  int NumElectrons() const { return numElectrons; }
94  double ScintYieldRatio() const { return scintYieldRatio; }
95  double Energy() const { return edep; }
96  geo::Point_t Start() const { return {startPos.X(), startPos.Y(), startPos.Z()}; }
97  geo::Point_t End() const { return {endPos.X(), endPos.Y(), endPos.Z()}; }
98  double Time() const { return (startTime + endTime) / 2.; }
99  int TrackID() const { return trackID; }
100  int OrigTrackID() const { return origTrackID; }
101  void setTrackID(int id) { trackID = id; }
102  int PdgCode() const { return pdgCode; }
103 
104  // While it's clear how a SimEnergyDeposit will be created by its
105  // constructor, it's not clear how users will want to access its
106  // data. So give them as many different kinds of accessors as I
107  // can think of.
108  geo::Length_t StartX() const { return startPos.X(); }
109  geo::Length_t StartY() const { return startPos.Y(); }
110  geo::Length_t StartZ() const { return startPos.Z(); }
111  double StartT() const { return startTime; }
112  geo::Length_t EndX() const { return endPos.X(); }
113  geo::Length_t EndY() const { return endPos.Y(); }
114  geo::Length_t EndZ() const { return endPos.Z(); }
115  double EndT() const { return endTime; }
116 
117  // Step mid-point.
119  {
120  return {(startPos.X() + endPos.X()) / 2.,
121  (startPos.Y() + endPos.Y()) / 2.,
122  (startPos.Z() + endPos.Z()) / 2.};
123  }
124  geo::Length_t MidPointX() const { return (startPos.X() + endPos.X()) / 2.; }
125  geo::Length_t MidPointY() const { return (startPos.Y() + endPos.Y()) / 2.; }
126  geo::Length_t MidPointZ() const { return (startPos.Z() + endPos.Z()) / 2.; }
127  geo::Length_t X() const { return (startPos.X() + endPos.X()) / 2.; }
128  geo::Length_t Y() const { return (startPos.Y() + endPos.Y()) / 2.; }
129  geo::Length_t Z() const { return (startPos.Z() + endPos.Z()) / 2.; }
130  double T() const { return (startTime + endTime) / 2.; }
131  double T0() const { return startTime; }
132  double T1() const { return endTime; }
133  double E() const { return edep; }
134 
135  // Step length. (Recall that the difference between two
136  // geo::Point_t objects is a geo::Vector_t; we get the length from
137  // spherical coordinates.
138  geo::Length_t StepLength() const { return (endPos - startPos).R(); }
139 
140  // Just in case someone wants to store sim::SimEnergyDeposit
141  // objects in a sorted container, define a sort function. Note
142  // that the ideal sort order is dependent of the analysis you're
143  // trying to perform; for example, if you're dealing with cosmic
144  // rays coming along the y-axis, sorting first by z may cause some
145  // tasks like insertions to take a very long time.
146 
147  bool operator<(const SimEnergyDeposit& rhs) const
148  {
149  return trackID < rhs.trackID && startTime < rhs.startTime &&
150  startPos.Z() < rhs.startPos.Z() && startPos.Y() < rhs.startPos.Y() &&
151  startPos.X() < rhs.startPos.X() && edep > rhs.edep; // sort by _decreasing_ energy
152  }
153 
154  private:
155  // While the accessors above return all values in double
156  // precision, store whatever we can in single precision to save
157  // memory and disk space.
158 
159  // There are roughly 7 digits of decimal precision in a float.
160  // This will suffice for energy. A float (as opposed to a double)
161  // can hold a little more than 7 digits of decimal precision. The
162  // smallest position resolution in the simulation is about 0.1mm,
163  // or 10^-4m. With seven digits of precision, that means a float
164  // can be accurate to up to the range of 10^3m. That's why the
165  // definition of our local Point_t (see above) is based on float,
166  // while geo::Point_t is based on double.
167 
168  // If the above reasoning is wrong, just change the definition of
169  // Length_t near the top of this file. Of course, also edit these
170  // comments if you do, because you're a good and responsible
171  // programmer.
172 
173  // For time, it's possible for long-lived particles like neutrons
174  // to deposit energy after billions of ns. Chances are time cuts
175  // will take care of that, but let's make sure that any overlay studies
176  // won't suffer due to lack of precision.
177 
179  // int numFPhotons; ///< of fast scintillation photons
180  // int numSPhotons; ///< of slow scintillation photons
183  float edep;
186  double startTime;
187  double endTime;
188  int trackID;
189  int pdgCode;
190  int
192  };
193  /*
194  // Class utility functions.
195 
196  // The format of the sim::SimEnergyDeposit output. I'm using a
197  // template for the ostream type, since LArSoft may have some
198  // special classes for its output streams.
199  template <typename Stream>
200  Stream& operator<<(Stream&& os, const sim::SimEnergyDeposit& sed)
201  {
202  // Note that the geo::Point_t type (returned by Start() and End())
203  // has an ostream operator defined for it.
204  os << "trackID " << sed.TrackID()
205  << " pdgCode=" << sed.PdgCode()
206  << " start=" << sed.Start()
207  << " t0=" << sed.T0()
208  << " end=" << sed.End()
209  << " t1=" << sed.T1() << " [cm,ns]"
210  << " E=" << sed.E() << "[GeV]"
211  << " #photons=" << sed.NumPhotons();
212  return os;
213  }
214 
215  // It can be more memory efficient to sort objects by pointers;
216  // e.g., if you've got an unsorted
217  // std::vector<sim::SimEnergyDeposit>, create a
218  // std::set<sim::SimEnergyDeposit*,sim::CompareSED> so you're not
219  // duplicating the objects in memory. The following definition
220  // covers sorting the pointers.
221  bool compareSED(const SimEnergyDeposit* const lhs, const SimEnergyDeposit* const rhs)
222  {
223  return (*lhs) < (*rhs);
224  }
225  */
226  typedef std::vector<SimEnergyDeposit> SimEnergyDepositCollection;
227 } // namespace sim
228 #endif // LARDATAOBJ_SIMULATION_SIMENERGYDEPOSIT_H
geo::Length_t StartX() const
code to link reconstructed objects back to the MC truth information
geo::Length_t EndZ() const
geo::Length_t StepLength() const
geo::Length_t EndY() const
TTree * t1
Definition: plottest35.C:26
double Length_t
Type used for coordinates and distances. They are measured in centimeters.
Definition: geo_vectors.h:133
geo::Length_t Y() const
int numElectrons
of ionization electrons
int origTrackID
complementary simulation track id, kept true to G4 even for shower secondaries/tertiaries etc...
SimEnergyDeposit(int np=0, int ne=0, double sy=0, double e=0., geo::Point_t start={0., 0., 0.}, geo::Point_t end={0., 0., 0.}, double t0=0., double t1=0., int id=0, int pdg=0, int origTrackID=0)
geo::Length_t StartY() const
double StartT() const
geo::Point_t startPos
positions in (cm)
int numPhotons
of scintillation photons
geo::Length_t Z() const
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
int pdgCode
pdg code of particle to avoid lookup by particle type later
geo::Length_t EndX() const
geo::Point_t Start() const
geo::Point_t End() const
Definitions of geometry vector data types.
int trackID
simulation track id
double Time() const
geo::Point_t MidPoint() const
geo::Length_t StartZ() const
Monte Carlo Simulation.
geo::Length_t MidPointX() const
geo::Length_t MidPointY() const
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
std::vector< SimEnergyDeposit > SimEnergyDepositCollection
float scintYieldRatio
scintillation yield of LAr
bool operator<(const SimEnergyDeposit &rhs) const
geo::Length_t MidPointZ() const
Energy deposition in the active material.
double Energy() const
Float_t e
Definition: plot.C:35
geo::Length_t X() const
double ScintYieldRatio() const
float edep
energy deposition (MeV)