All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimChannel.h
Go to the documentation of this file.
1 /**
2  * @file SimChannel.h
3  * @brief object containing MC truth information necessary for making
4  * RawDigits and doing back tracking
5  * @author seligman@nevis.columbia.edu
6  * @see SimChannel.cxx
7  *
8  * This class uses only LArSoft libraries that are header only.
9  */
10 
11 #ifndef LARDATAOBJ_SIMULATION_SIMCHANNEL_H
12 #define LARDATAOBJ_SIMULATION_SIMCHANNEL_H
13 
14 // LArSoftObj libraries
15 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
17 
18 // C/C++ standard libraries
19 #include <string>
20 #include <vector>
21 #include <utility> // std::pair
22 
23 namespace sim {
24 
25  /// Ionization energy from a Geant4 track
26  struct TrackIDE{
27  int trackID; ///< Geant4 supplied trackID
28  float energyFrac; ///< fraction of hit energy from the particle with this trackID
29  float energy; ///< energy from the particle with this trackID [MeV]
30  float numElectrons; ///< number of electrons from the particle detected on the wires
31  int origTrackID; ///< Geant4 supplied trackID, including no modification for shower secondaries/tertiaries
32 
33  TrackIDE() {}
34 
35 
36  TrackIDE(int id, float ef, float e, float ne, int gid = util::kBogusI) : trackID(id), energyFrac(ef), energy (e), numElectrons (ne), origTrackID(gid) {}
37 
38 
39  };
40 
41 
42  /**
43  * @brief Ionization at a point of the TPC sensitive volume
44  *
45  * This class stores information about the ionization from the simulation
46  * of a small step of a track through the TPC active volume.
47  *
48  * Ionization information consists of both energy and number of electrons.
49  * It is of paramount importance to understand what each field stores:
50  *
51  * - position: where the ionization occurred (from Geant4 simulation)
52  * - track ID: Geant4 track ID of the ionizing particle
53  * - energy: amount of energy released by ionization (from Geant4 simulation)
54  * - electrons: amount of electrons reaching the readout channel
55  *
56  * Note the different definition of the electrons respect to the rest:
57  * it describes the electrons at the anode _after_ the drifting occurred,
58  * while all the other quantities can be related to the moment the ionization
59  * happened.
60  *
61  * The number of electrons typically includes inefficiencies and physics
62  * effects that reduce and spread the electrons. In the simulation,
63  * this yields a fractional number of electrons.
64  *
65  * Each IDE is also typically associated with a time (TDC) count, that is
66  * the time at which the ionized electrons reached the readout channel, in
67  * electronic ticks, as opposed as the time when ionization occurred.
68  * The latter is not stored.
69  *
70  * At the time of writing this documentation (LArSoft 6.4.0), IDEs are
71  * computed in larg4::LArVoxelReadout.
72  * The energy and track ID come directly from Geant4 simulation.
73  * The position is the mid point of the Geant4 step that produced ionization.
74  * The electrons are
75  *
76  * 1. converted from that same energy (using a fundamental conversion factor
77  * stored in `larcoreobj/SimpleTypesAndConstants/PhysicalConstants.h`)
78  * 2. applied recombination effect by larg4::IonizationAndScintillation::Reset()
79  * 3. applied attenuation and diffusion in
80  * larg4::LArVoxelReadout::DriftIonizationElectrons()
81  *
82  * The latter also assembles the sim::IDE objects to be stored into
83  * sim::SimChannel.
84  *
85  */
86  struct IDE{
87 
88  /// Type of track ID (the value comes from Geant4)
89  typedef int TrackID_t;
90 
91  /// Default constructor (sets "bogus" values)
92  IDE();
93 
94 
95  /// Constructor: copies an IDE, and applies the specified offset to track ID
96  IDE(IDE const& ide, int offset);
97 
98  /// Constructor: sets all data members
100  float nel,
101  float e,
102  float xpos,
103  float ypos,
104  float zpos,
105  TrackID_t gid = util::kBogusI)
106  : trackID (tid)
107  , numElectrons(nel)
108  , energy (e)
109  , x (xpos)
110  , y (ypos)
111  , z (zpos)
112  , origTrackID (gid)
113  {}
114 
115 
116  TrackID_t trackID; ///< Geant4 supplied track ID
117  float numElectrons; ///< number of electrons at the readout for this track ID and time
118  float energy; ///< energy deposited by ionization by this track ID and time [MeV]
119  float x; ///< x position of ionization [cm]
120  float y; ///< y position of ionization [cm]
121  float z; ///< z position of ionization [cm]
122  TrackID_t origTrackID; ///< Geant4 supplied track ID (remains true trackID even for shower secondaries/tertiaries etc)
123  }; // struct IDE
124 
125 
126  /// List of energy deposits at the same time (on this channel)
127  typedef std::pair<unsigned short, std::vector<sim::IDE> > TDCIDE;
128 
129  /**
130  * @brief Energy deposited on a readout channel by simulated tracks
131  *
132  * This class stores the list of all energies deposited on a readout channel.
133  * The number of electrons is stored as well.
134  *
135  * The information is organized by time: it is divided by TDC ticks, and
136  * each TDC tick where some energy was deposited appears in a separate entry,
137  * while the quiet TDC ticks are omitted.
138  * For each TDC, the information is stored as a list of energy deposits;
139  * each deposit comes from a single Geant4 track and stores the location where
140  * the ionization happened according to the simulation (see `sim::IDE` class).
141  *
142  * Note that there can be multiple energy deposit records (that is `sim::IDE`)
143  * for a single track in a single TDC tick.
144  */
146  {
147  public:
148  /// Type for TDC tick used in the internal representation
149  typedef TDCIDE::first_type StoredTDC_t;
150 
151  /// Type of list of energy deposits for each TDC with signal
152  typedef std::vector<TDCIDE> TDCIDEs_t;
153 
154  private:
155  raw::ChannelID_t fChannel; ///< readout channel where electrons are collected
156  TDCIDEs_t fTDCIDEs; ///< list of energy deposits for each TDC with signal
157 
158 
159  public:
160 
161  // Default constructor
162  SimChannel();
163 
164  /// Type for TDC tick used in the interface
165  /// (different type than raw::TDCtick_t! and from internal representation!
166  /// but same meaning!)
167  typedef unsigned int TDC_t;
168 
169  /// Type of track ID (the value comes from Geant4)
171 
172 
173  /// Constructor: immediately sets the channel number
174  explicit SimChannel(raw::ChannelID_t channel);
175 
176  /**
177  * @brief Add ionization electrons and energy to this channel
178  * @param trackID ID of simulated track depositing this energy (from Geant4)
179  * @param tdc TDC tick when this deposit was collected
180  * @param numberElectrons electrons created at this point by this track
181  * @param xyz coordinates of original location of ionization (3D array) [cm]
182  * @param energy energy deposited at this point by this track [MeV]
183  *
184  * The number of electrons can be fractional because of simulated
185  * efficiency and physics effects.
186  */
187  void AddIonizationElectrons(TrackID_t trackID,
188  TDC_t tdc,
189  double numberElectrons,
190  double const* xyz,
191  double energy,
192  TrackID_t origTrackID = util::kBogusI);
193 
194  /// Returns the readout channel this object describes
195  raw::ChannelID_t Channel() const;
196 
197  /**
198  * @brief Return all the recorded energy deposition within a time interval
199  * @param startTDC TDC tick opening the time window
200  * @param endTDC TDC tick closing the time window (included in the interval)
201  * @return a collection of energy deposit information from all tracks
202  *
203  * This method returns the energy deposited on this channel by each track
204  * ID active in the specified TDC time interval.
205  *
206  * Each entry pertains a single track ID. For each entry, all energy
207  * deposit information is merged into a single record. It includes:
208  * * energy and number of electrons, as the integral in the time interval
209  * * position, as average weighted by the number of electrons
210  * * the ID of the track depositing this energy
211  *
212  * Entries are sorted by track ID number.
213  */
214  std::vector<sim::IDE> TrackIDsAndEnergies(TDC_t startTDC,
215  TDC_t endTDC) const;
216 
217  /**
218  * @brief Returns all the deposited energy information as stored
219  * @return all the deposited energy information as stored in the object
220  *
221  * The returned list is organized in pairs. Each pair contains all
222  * ionization information in a single TDC tick (collection of `sim::IDE`),
223  * and the number of that tick. The information is sorted by increasing TDC
224  * tick.
225  *
226  * See the class description for the details of the ionization information
227  * content.
228  */
229  TDCIDEs_t const& TDCIDEMap() const;
230 
231 
232  /// Returns the total number of ionization electrons on this channel in the specified TDC
233  double Charge(TDC_t tdc) const;
234 
235  /// Returns the total energy on this channel in the specified TDC [MeV]
236  double Energy(TDC_t tdc) const;
237 
238  /**
239  * @brief Returns energies collected for each track within a time interval
240  * @param startTDC TDC tick opening the time window
241  * @param endTDC TDC tick closing the time window (included in the interval)
242  * @return a collection of energy and fraction from each track in interval
243  * @see TrackIDsAndEnergies()
244  *
245  * This method returns the energy deposited on this channel by each track
246  * ID active in the specified TDC time interval.
247  *
248  * Each entry pertains a single track ID. For each entry, all energy
249  * deposit information is merged into a single record. It includes:
250  * * energy of the track, as the integral in the time interval [MeV]
251  * * energy fraction respect to the total (see below)
252  * * the ID of the track depositing this energy
253  *
254  * The energy fraction is the energy deposited by the track on this channel
255  * in the specified time interval, divided by the total of the energy
256  * deposited by all tracks on this channel in that same time interval.
257  *
258  * Entries are sorted by track ID number.
259  */
260  std::vector<sim::TrackIDE> TrackIDEs(TDC_t startTDC,
261  TDC_t endTDC) const;
262 
263  /// Comparison: sorts by channel ID
264  bool operator< (const SimChannel& other) const;
265 
266  /// Comparison: true if SimChannels have the same channel ID
267  bool operator== (const SimChannel& other) const;
268 
269  /**
270  * @brief Merges the deposits from another channel into this one
271  * @param channel the sim::SimChannel holding information to be merged
272  * @param offset track ID offset for the merge
273  * @return range of the IDs of the added tracks
274  *
275  * The information from the specified simulated channel is added to the
276  * current one.
277  * This is achieved by appending the energy deposit information (`sim::IDE`)
278  * at each TDC tick from the merged channel to the list of existing energy
279  * deposits for that TDC tick.
280  *
281  * In addition, the track IDs of the merged channel are added an offset,
282  * so that they can be distinguished from the existing ones.
283  * This is useful when simulating tracks with multiple Geant4 runs. Geant4
284  * will reuse track IDs on each run, and using the highest number of track
285  * ID from one run as the offset for the next avoids track ID collisions.
286  * Note however that this function does not perform any collision check, and
287  * it is caller's duty to ensure that the offset is properly large.
288  * The return value is a pair including the lowest and the largest track IDs
289  * added to this channel, equivalent to the lowest and the highest track IDs
290  * present in the merged channel, both augmented by the applied offset.
291  *
292  * The channel number of the merged channel is ignored.
293  */
294  std::pair<TrackID_t,TrackID_t> MergeSimChannel
295  (const SimChannel& channel, int offset);
296 
297 
298  /**
299  * @brief Dumps the full content of the SimChannel into a stream
300  * @tparam Stream an ostream-like stream object
301  * @param out the stream to send the information into
302  * @param indent indentation of the lines (default: none)
303  * @param first_indent indentation for the first line (default: as `indent`)
304  */
305  template <typename Stream>
306  void Dump(Stream&& out, std::string indent, std::string first_indent) const;
307 
308  /// Documentation at `Dump(Stream&&, std::string, std::string) const`.
309  template <typename Stream>
310  void Dump(Stream&& out, std::string indent = "") const
311  { Dump(std::forward<Stream>(out), indent, indent); }
312 
313 
314  private:
315  /// Comparison functor, sorts by increasing TDCtick value
316  struct CompareByTDC;
317 
318  /// Return the iterator to the first TDCIDE not earlier than tdc
319  TDCIDEs_t::iterator findClosestTDCIDE(StoredTDC_t tdc);
320 
321  /// Return the (constant) iterator to the first TDCIDE not earlier than tdc
322  TDCIDEs_t::const_iterator findClosestTDCIDE
323  (StoredTDC_t tdc) const;
324  /// @}
325 
326 
327  };
328 
329 } // namespace sim
330 
331 
332 inline bool sim::SimChannel::operator< (const sim::SimChannel& other) const { return fChannel < other.Channel(); }
333 inline bool sim::SimChannel::operator== (const sim::SimChannel& other) const { return fChannel == other.Channel(); }
334 inline sim::SimChannel::TDCIDEs_t const& sim::SimChannel::TDCIDEMap() const { return fTDCIDEs; }
335 inline raw::ChannelID_t sim::SimChannel::Channel() const { return fChannel; }
336 
337 
338 // -----------------------------------------------------------------------------
339 // --- template implementation
340 // ---
341 template <class Stream>
343  (Stream&& out, std::string indent, std::string first_indent) const
344 {
345  out << first_indent << "channel #" << Channel() << " read " << fTDCIDEs.size()
346  << " TDCs:\n";
347  double channel_energy = 0., channel_charge = 0.;
348  for (const auto& TDCinfo: fTDCIDEs) {
349  auto const tdc = TDCinfo.first;
350  out << indent << " TDC #" << tdc
351  << " with " << TDCinfo.second.size() << " IDEs\n";
352  double tdc_energy = 0., tdc_charge = 0.;
353  for (const sim::IDE& ide: TDCinfo.second) {
354  out << indent
355  << " (" << ide.x << ", " << ide.y << ", " << ide.z << ") "
356  << ide.numElectrons << " electrons, " << ide.energy << " MeV (trkID="
357  << ide.trackID << ")\n";
358  tdc_energy += ide.energy;
359  tdc_charge += ide.numElectrons;
360  } // for IDEs
361  out << indent << " => TDC #" << tdc << " CH #" << Channel()
362  << " collected " << tdc_charge << " electrons and " << tdc_energy
363  << " MeV\n";
364  channel_energy += tdc_energy;
365  channel_charge += tdc_charge;
366  } // for TDCs
367  out << indent << " => channel #" << Channel() << " collected "
368  << channel_charge << " electrons and " << channel_energy << " MeV\n";
369 } // sim::SimChannel::Dump<>()
370 
371 
372 #endif // LARDATAOBJ_SIMULATION_SIMCHANNEL_H
373 
374 ////////////////////////////////////////////////////////////////////////
TrackID_t trackID
Geant4 supplied track ID.
Definition: SimChannel.h:116
std::pair< TrackID_t, TrackID_t > MergeSimChannel(const SimChannel &channel, int offset)
Merges the deposits from another channel into this one.
Definition: SimChannel.cxx:285
raw::ChannelID_t fChannel
readout channel where electrons are collected
Definition: SimChannel.h:155
float z
z position of ionization [cm]
Definition: SimChannel.h:121
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
Definition: CORSIKAGen.fcl:7
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:145
std::pair< unsigned short, std::vector< sim::IDE > > TDCIDE
List of energy deposits at the same time (on this channel)
Definition: SimChannel.h:127
double Energy(TDC_t tdc) const
Returns the total energy on this channel in the specified TDC [MeV].
Definition: SimChannel.cxx:160
void Dump(Stream &&out, std::string indent, std::string first_indent) const
Dumps the full content of the SimChannel into a stream.
Definition: SimChannel.h:343
float numElectrons
number of electrons from the particle detected on the wires
Definition: SimChannel.h:30
void Dump(Stream &&out, std::string indent="") const
Documentation at Dump(Stream&amp;&amp;, std::string, std::string) const.
Definition: SimChannel.h:310
TrackID_t origTrackID
Geant4 supplied track ID (remains true trackID even for shower secondaries/tertiaries etc) ...
Definition: SimChannel.h:122
constexpr int kBogusI
obviously bogus integer value
unsigned int TDC_t
Definition: SimChannel.h:167
float energy
energy from the particle with this trackID [MeV]
Definition: SimChannel.h:29
std::vector< TDCIDE > TDCIDEs_t
Type of list of energy deposits for each TDC with signal.
Definition: SimChannel.h:152
float x
x position of ionization [cm]
Definition: SimChannel.h:119
IDE(TrackID_t tid, float nel, float e, float xpos, float ypos, float zpos, TrackID_t gid=util::kBogusI)
Constructor: sets all data members.
Definition: SimChannel.h:99
TDCIDEs_t fTDCIDEs
list of energy deposits for each TDC with signal
Definition: SimChannel.h:156
double Charge(TDC_t tdc) const
Returns the total number of ionization electrons on this channel in the specified TDC...
Definition: SimChannel.cxx:138
Ionization at a point of the TPC sensitive volume.
Definition: SimChannel.h:86
int origTrackID
Geant4 supplied trackID, including no modification for shower secondaries/tertiaries.
Definition: SimChannel.h:31
float energy
energy deposited by ionization by this track ID and time [MeV]
Definition: SimChannel.h:118
std::vector< sim::TrackIDE > TrackIDEs(TDC_t startTDC, TDC_t endTDC) const
Returns energies collected for each track within a time interval.
Definition: SimChannel.cxx:250
float energyFrac
fraction of hit energy from the particle with this trackID
Definition: SimChannel.h:28
TrackIDE(int id, float ef, float e, float ne, int gid=util::kBogusI)
Definition: SimChannel.h:36
TDCIDEs_t::iterator findClosestTDCIDE(StoredTDC_t tdc)
Return the iterator to the first TDCIDE not earlier than tdc.
Definition: SimChannel.cxx:346
float y
y position of ionization [cm]
Definition: SimChannel.h:120
bool operator==(const SimChannel &other) const
Comparison: true if SimChannels have the same channel ID.
Definition: SimChannel.h:333
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
Definition: SimChannel.h:335
int trackID
Geant4 supplied trackID.
Definition: SimChannel.h:27
bool operator<(const SimChannel &other) const
Comparison: sorts by channel ID.
Definition: SimChannel.h:332
std::vector< sim::IDE > TrackIDsAndEnergies(TDC_t startTDC, TDC_t endTDC) const
Return all the recorded energy deposition within a time interval.
Definition: SimChannel.cxx:184
IDE::TrackID_t TrackID_t
Type of track ID (the value comes from Geant4)
Definition: SimChannel.h:170
do i e
TDCIDEs_t const & TDCIDEMap() const
Returns all the deposited energy information as stored.
Definition: SimChannel.h:334
IDE()
Default constructor (sets &quot;bogus&quot; values)
Definition: SimChannel.cxx:23
void AddIonizationElectrons(TrackID_t trackID, TDC_t tdc, double numberElectrons, double const *xyz, double energy, TrackID_t origTrackID=util::kBogusI)
Add ionization electrons and energy to this channel.
Definition: SimChannel.cxx:55
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Collection of Physical constants used in LArSoft.
int TrackID_t
Type of track ID (the value comes from Geant4)
Definition: SimChannel.h:89
Ionization energy from a Geant4 track.
Definition: SimChannel.h:26
bnb BNB Stream
float numElectrons
number of electrons at the readout for this track ID and time
Definition: SimChannel.h:117
TDCIDE::first_type StoredTDC_t
Type for TDC tick used in the internal representation.
Definition: SimChannel.h:149