LArSoft  v10_06_00
Liquid Argon Software toolkit - https://larsoft.org/
sim::OpDetBacktrackerRecord Class Reference

Energy deposited on a readout Optical Detector by simulated tracks. More...

#include "OpDetBacktrackerRecord.h"

Classes

struct  CompareByTimePDclock
 

Public Types

typedef timePDclockSDP_t::first_type storedTimePDclock_t
 Type for timePDclock tick used in the internal representation. More...
 
typedef std::vector< timePDclockSDP_ttimePDclockSDPs_t
 Type of list of energy deposits for each timePDclock with signal. More...
 
typedef double timePDclock_t
 Type for iTimePDclock tick used in the interface. More...
 
typedef SDP::TrackID_t TrackID_t
 Type of track ID (the value comes from Geant4) More...
 

Public Member Functions

 OpDetBacktrackerRecord ()
 
 OpDetBacktrackerRecord (int detNum)
 Constructor: immediately sets the Optical Detector number. More...
 
 OpDetBacktrackerRecord (OBTRHelper &helper)
 
void AddScintillationPhotons (TrackID_t trackID, timePDclock_t timePDclock, double numberPhotons, double const *xyz, double energy)
 Add scintillation photons and energy to this OpticalDetector. More...
 
int OpDetNum () const
 Returns the readout Optical Detector this object describes. More...
 
std::vector< sim::SDPTrackIDsAndEnergies (timePDclock_t startTimePDclock, timePDclock_t endTimePDclock) const
 Return all the recorded energy deposition within a time interval. More...
 
timePDclockSDPs_t const & timePDclockSDPsMap () const
 Returns all the deposited energy information as stored. More...
 
double Photons (timePDclock_t iTimePDclock) const
 Returns the total number of scintillation photons on this Optical Detector in the specified timePDclock. More...
 
double Energy (timePDclock_t iTimePDclock) const
 Returns the total energy on this Optical Detector in the specified iTimePDclock [MeV]. More...
 
std::vector< sim::TrackSDPTrackSDPs (timePDclock_t startTimePDclock, timePDclock_t endTimePDclock) const
 Returns energies collected for each track within a time interval. More...
 
bool operator< (const OpDetBacktrackerRecord &other) const
 Comparison: sorts by Optical Detector ID. More...
 
bool operator== (const OpDetBacktrackerRecord &other) const
 Comparison: true if OpDetBacktrackerRecords have the same Optical Detector ID. More...
 
std::pair< TrackID_t, TrackID_tMergeOpDetBacktrackerRecord (const OpDetBacktrackerRecord &opDetNum, int offset)
 Merges the deposits from another Optical Detector into this one. More...
 
template<typename Stream >
void Dump (Stream &&out, std::string indent, std::string first_indent) const
 Dumps the full content of the OpDetBacktrackerRecord into a stream. More...
 
template<typename Stream >
void Dump (Stream &&out, std::string indent="") const
 Documentation at Dump(Stream&&, std::string, std::string) const. More...
 

Private Member Functions

timePDclockSDPs_t::iterator findClosestTimePDclockSDP (storedTimePDclock_t timePDclock)
 Return the iterator to the first timePDclockSDP not earlier than timePDclock. More...
 
timePDclockSDPs_t::const_iterator findClosestTimePDclockSDP (storedTimePDclock_t timePDclock) const
 Return the (constant) iterator to the first timePDclockSDP not earlier than timePDclock. More...
 

Private Attributes

int iOpDetNum
 OpticalDetector where the photons were detected. More...
 
timePDclockSDPs_t timePDclockSDPs
 list of energy deposits for each timePDclock with signal More...
 

Detailed Description

Energy deposited on a readout Optical Detector by simulated tracks.

This class stores a time organized list of scintillation photons detected connected to the G4 tracks they originated from. This class also tracks the energy deposited by those tracks, and what fraction of the energy deposited is realted to the photons detected by this OpDet.

The information is organized by time: it is divided by timePDclock ticks (units of ns), and each timePDclock tick where some energy was deposited appears in a separate entry, while the quiet timePDclock ticks are omitted. For each timePDclock, the information is stored as a list of energy deposits; each deposit comes from a single Geant4 track and stores the location where the ionization happened according to the simulation (see sim::SDP class).

Note that there can be multiple energy deposit records (that is sim::SDP) for a single track in a single timePDclock tick.

Definition at line 127 of file OpDetBacktrackerRecord.h.

Member Typedef Documentation

typedef timePDclockSDP_t::first_type sim::OpDetBacktrackerRecord::storedTimePDclock_t

Type for timePDclock tick used in the internal representation.

Definition at line 130 of file OpDetBacktrackerRecord.h.

Type for iTimePDclock tick used in the interface.

Definition at line 146 of file OpDetBacktrackerRecord.h.

Type of list of energy deposits for each timePDclock with signal.

Definition at line 133 of file OpDetBacktrackerRecord.h.

Type of track ID (the value comes from Geant4)

Definition at line 149 of file OpDetBacktrackerRecord.h.

Constructor & Destructor Documentation

sim::OpDetBacktrackerRecord::OpDetBacktrackerRecord ( )

Definition at line 109 of file OpDetBacktrackerRecord.cxx.

110  : iOpDetNum(
111  -1) //set an impossible channel number in the case where this is called without an opticalchannel.
112  //The reason for doing this is to follow the structure of SimChannel, which uses kBogusChannel
113  {}
int iOpDetNum
OpticalDetector where the photons were detected.
sim::OpDetBacktrackerRecord::OpDetBacktrackerRecord ( int  detNum)
explicit

Constructor: immediately sets the Optical Detector number.

Definition at line 116 of file OpDetBacktrackerRecord.cxx.

116 : iOpDetNum(detNum) {}
int iOpDetNum
OpticalDetector where the photons were detected.
sim::OpDetBacktrackerRecord::OpDetBacktrackerRecord ( OBTRHelper helper)
explicit

Definition at line 119 of file OpDetBacktrackerRecord.cxx.

References sim::OBTRHelper::fTimePDclockSDPs, and timePDclockSDPs.

119  : iOpDetNum(helper.fTrackID)
120  {
121  auto& sdp_map = helper.fTimePDclockSDPs;
122  for (auto& [channel, vec] : sdp_map) {
123 
124  // std::cout << "Moving SDP vector for channel " << channel << " with size " << vec.size() << std::endl;
125  timePDclockSDPs.emplace_back((double)channel, std::move(vec));
126  // std::cout << "Moved " << vec.size() << " " << timePDclockSDPs.back().second.size() << std::endl;
127  }
128  }
int iOpDetNum
OpticalDetector where the photons were detected.
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal

Member Function Documentation

void sim::OpDetBacktrackerRecord::AddScintillationPhotons ( TrackID_t  trackID,
timePDclock_t  timePDclock,
double  numberPhotons,
double const *  xyz,
double  energy 
)

Add scintillation photons and energy to this OpticalDetector.

Parameters
trackIDID of simulated track depositing this energy (from Geant4)
timePDclocktick when this deposit was collected (ns)
numberPhotonsdetected at the OpticalDetector at this time from this track
xyzcoordinates of original location of ionization/scintillation (3D array) [cm]
energyenergy deposited at this point by this track [MeV]

The iTimePDclock from OpFastScintillation (where OpDetBacktrackerRecords originate) is done with CLHEP::ns (units of nanoseconds).

Definition at line 131 of file OpDetBacktrackerRecord.cxx.

References util::abs(), energy, findClosestTimePDclockSDP(), MF_LOG_ERROR, timePDclockSDPs, and weight.

Referenced by phot::PDFastSimPVS::produce(), phot::PDFastSimANN::produce(), and larg4::OpFastScintillation::RecordPhotonsProduced().

136  {
140  // look at the collection to see if the current iTimePDclock already
141  // exists, if not, add it, if so, just add a new track id to the
142  // vector, or update the information if track is already present
143 
144  // no photons? no good!
145  if ((numberPhotons < std::numeric_limits<double>::epsilon()) ||
146  (energy <= std::numeric_limits<double>::epsilon())) {
147  // will throw
148  MF_LOG_ERROR("OpDetBacktrackerRecord")
149  << "AddTrackPhotons() trying to add to iTimePDclock #" << iTimePDclock << " "
150  << numberPhotons << " photons with " << energy
151  << " MeV of energy from track ID=" << trackID;
152  return;
153  } // if no photons
154 
155  // int rounded_time = std::round(iTimePDclock);
156 
157  auto itr = findClosestTimePDclockSDP(iTimePDclock);
158  // auto itr = timePDclockSDPs.lower_bound(rounded_time);
159 
160  // check if this iTimePDclock value is in the vector, it is possible that
161  // the lower bound is different from the given TimePDclock, in which case
162  // we need to add something for that TimePDclock
163  // if (itr == timePDclockSDPs.end() || timePDclockSDPs.key_comp()(rounded_time, itr->first)) {
164  // timePDclockSDPs.insert(
165  // {rounded_time,
166  // std::vector<sim::SDP>{sim::SDP(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2])}});
167  if (itr == timePDclockSDPs.end() || (abs(itr->first - iTimePDclock) > .50)) {
168  //itr->first != iTimePDclock){
169  std::vector<sim::SDP> sdplist;
170  sdplist.emplace_back(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2]);
171  timePDclockSDPs.emplace(itr, std::round(iTimePDclock), std::move(sdplist));
172  }
173  else { // we have that iTimePDclock already; itr points to it
174 
175  // loop over the SDP vector for this iTimePDclock and add the electrons
176  // to the entry with the same track id
177  for (auto& sdp : itr->second) {
178 
179  if (sdp.trackID != trackID) continue;
180 
181  // make a weighted average for the location information
182  double weight = sdp.numPhotons + numberPhotons;
183  sdp.x = (sdp.x * sdp.numPhotons + xyz[0] * numberPhotons) / weight;
184  sdp.y = (sdp.y * sdp.numPhotons + xyz[1] * numberPhotons) / weight;
185  sdp.z = (sdp.z * sdp.numPhotons + xyz[2] * numberPhotons) / weight;
186  sdp.numPhotons = weight;
187  sdp.energy = sdp.energy + energy;
188 
189  // found the track id we wanted, so return;
190  return;
191  } // for
192 
193  // if we never found the track id, then this is the first instance of
194  // the track id for this TimePDclock, so add sdp to the vector
195  itr->second.emplace_back(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2]);
196 
197  } // end of else "We have that iTimePDclock already"
198 
199  } // OpDetBacktrackerRecord::AddIonizationElectrons()
constexpr auto abs(T v)
Returns the absolute value of the argument.
#define MF_LOG_ERROR(category)
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
timePDclockSDPs_t::iterator findClosestTimePDclockSDP(storedTimePDclock_t timePDclock)
Return the iterator to the first timePDclockSDP not earlier than timePDclock.
double energy
Definition: plottest35.C:25
double weight
Definition: plottest35.C:25
template<class Stream >
void sim::OpDetBacktrackerRecord::Dump ( Stream &&  out,
std::string  indent,
std::string  first_indent 
) const

Dumps the full content of the OpDetBacktrackerRecord into a stream.

Template Parameters
Streaman ostream-like stream object
Parameters
outthe stream to send the information into
indentindentation of the lines (default: none)
first_indentindentation for the first line (default: as indent)

Definition at line 330 of file OpDetBacktrackerRecord.h.

References sim::SDP::energy, sim::SDP::numPhotons, sim::SDP::trackID, sim::SDP::x, sim::SDP::y, and sim::SDP::z.

Referenced by sim::DumpOpDetBacktrackerRecords::DumpOpDetBacktrackerRecord().

333 {
334  out << first_indent << "OpDet #" << OpDetNum() << " read " << timePDclockSDPs.size()
335  << " timePDclocks:\n";
336  double opDet_energy = 0., opDet_photons = 0.;
337  for (const auto& timePDclockinfo : timePDclockSDPs) {
338  auto const iTimePDclock = timePDclockinfo.first;
339  out << indent << " timePDclock #" << iTimePDclock << " with " << timePDclockinfo.second.size()
340  << " SDPs\n";
341  double timePDclock_energy = 0., timePDclock_photons = 0.;
342  for (const sim::SDP& sdp : timePDclockinfo.second) {
343  out << indent << " (" << sdp.x << ", " << sdp.y << ", " << sdp.z << ") " << sdp.numPhotons
344  << " photons, " << sdp.energy << "MeV (trkID=" << sdp.trackID << ")\n";
345  timePDclock_energy += sdp.energy;
346  timePDclock_photons += sdp.numPhotons;
347  } // for SDPs
348  out << indent << " => timePDclock #" << iTimePDclock << " CH #" << OpDetNum()
349  << " collected " << timePDclock_energy << " MeV and " << timePDclock_photons
350  << " photons. \n";
351  opDet_energy += timePDclock_energy;
352  opDet_photons += timePDclock_photons;
353  } // for timePDclocks
354  out << indent << " => channel #" << OpDetNum() << " collected " << opDet_photons
355  << " photons and " << opDet_energy << " MeV.\n";
356 } // sim::OpDetBacktrackerRecord::Dump<>()
float x
x position of ionization [cm]
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
int OpDetNum() const
Returns the readout Optical Detector this object describes.
TrackID_t trackID
Geant4 supplied track ID.
std::string indent(std::size_t const i)
float y
y position of ionization [cm]
float numPhotons
number of photons at the optical detector for this track ID and time
float energy
energy deposited by ionization
float z
z position of ionization [cm]
template<typename Stream >
void sim::OpDetBacktrackerRecord::Dump ( Stream &&  out,
std::string  indent = "" 
) const
inline

Documentation at Dump(Stream&&, std::string, std::string) const.

Definition at line 289 of file OpDetBacktrackerRecord.h.

References art::detail::indent().

290  {
291  Dump(std::forward<Stream>(out), indent, indent);
292  }
void Dump(Stream &&out, std::string indent, std::string first_indent) const
Dumps the full content of the OpDetBacktrackerRecord into a stream.
std::string indent(std::size_t const i)
double sim::OpDetBacktrackerRecord::Energy ( timePDclock_t  iTimePDclock) const

Returns the total energy on this Optical Detector in the specified iTimePDclock [MeV].

Definition at line 224 of file OpDetBacktrackerRecord.cxx.

References energy, findClosestTimePDclockSDP(), and timePDclockSDPs.

225  {
226  double energy = 0.;
227 
228  auto itr = findClosestTimePDclockSDP(iTimePDclock);
229  // auto itr = timePDclockSDPs.lower_bound(iTimePDclock);
230 
231  // check to see if this iTimePDclock value is in the map
232  if (itr != timePDclockSDPs.end() && itr->first == iTimePDclock) {
233 
234  // loop over the list for this iTimePDclock value and add up
235  // the total number of photons
236  for (auto sdp : itr->second) {
237  energy += sdp.energy;
238  } // end loop over sim::SDP for this TimePDclock
239 
240  } // end if this iTimePDclock is represented in the map
241 
242  return energy;
243  }
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
timePDclockSDPs_t::iterator findClosestTimePDclockSDP(storedTimePDclock_t timePDclock)
Return the iterator to the first timePDclockSDP not earlier than timePDclock.
double energy
Definition: plottest35.C:25
OpDetBacktrackerRecord::timePDclockSDPs_t::iterator sim::OpDetBacktrackerRecord::findClosestTimePDclockSDP ( storedTimePDclock_t  timePDclock)
private

Return the iterator to the first timePDclockSDP not earlier than timePDclock.

Definition at line 408 of file OpDetBacktrackerRecord.cxx.

References timePDclockSDPs.

Referenced by AddScintillationPhotons(), Energy(), MergeOpDetBacktrackerRecord(), Photons(), and TrackIDsAndEnergies().

409  {
410  return std::lower_bound(
411  timePDclockSDPs.begin(), timePDclockSDPs.end(), iTimePDclock, CompareByTimePDclock());
412  }
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
OpDetBacktrackerRecord::timePDclockSDPs_t::const_iterator sim::OpDetBacktrackerRecord::findClosestTimePDclockSDP ( storedTimePDclock_t  timePDclock) const
private

Return the (constant) iterator to the first timePDclockSDP not earlier than timePDclock.

Definition at line 415 of file OpDetBacktrackerRecord.cxx.

References timePDclockSDPs.

416  {
417  return std::lower_bound(
418  timePDclockSDPs.begin(), timePDclockSDPs.end(), TimePDclock, CompareByTimePDclock());
419  }
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
std::pair< OpDetBacktrackerRecord::TrackID_t, OpDetBacktrackerRecord::TrackID_t > sim::OpDetBacktrackerRecord::MergeOpDetBacktrackerRecord ( const OpDetBacktrackerRecord opDetNum,
int  offset 
)

Merges the deposits from another Optical Detector into this one.

Parameters
opDetNumthe sim::OpDetBacktrackerRecord holding information to be merged
offsettrack ID offset for the merge
Returns
range of the IDs of the added tracks

The information from the specified simulated opDetRecord is added to the current one. This is achieved by appending the energy deposit information (sim::SDP) at each iTimePDclock tick from the merged opDetRecord to the list of existing energy deposits for that iTimePDclock tick.

In addition, the track IDs of the merged opDetRecord are added an offset, so that they can be distinguished from the existing ones. This is useful when simulating tracks with multiple Geant4 runs. Geant4 will reuse track IDs on each run, and using the highest number of track ID from one run as the offset for the next avoids track ID collisions. Note however that this function does not perform any collision check, and it is caller's duty to ensure that the offset is properly large. The return value is a pair including the lowest and the largest track IDs added to this opDetRecord, equivalent to the lowest and the highest track IDs present in the merged opDetRecord, both augmented by the applied offset.

The opDetNum number of the merged opDetRecord is ignored.

Definition at line 345 of file OpDetBacktrackerRecord.cxx.

References findClosestTimePDclockSDP(), OpDetNum(), timePDclockSDPs, and timePDclockSDPsMap().

347  {
348  if (this->OpDetNum() != channel.OpDetNum())
349  throw std::runtime_error(
350  "ERROR OpDetBacktrackerRecord Merge: Trying to merge different channels!");
351 
352  std::pair<TrackID_t, TrackID_t> range_trackID(std::numeric_limits<int>::max(),
353  std::numeric_limits<int>::min());
354 
355  // for (auto const& [iTimePDclock, sdps] : channel.timePDclockSDPsMap()) {
356  for (auto const& itr : channel.timePDclockSDPsMap()) {
357 
358  auto iTimePDclock = itr.first;
359  auto const& sdps = itr.second;
360  // find the entry from this OpDetBacktrackerRecord corresponding to the iTimePDclock from the other
361  // auto itrthis = timePDclockSDPs.lower_bound(iTimePDclock);
362  auto itrthis = findClosestTimePDclockSDP(iTimePDclock);
363 
364  // pick which SDP list we have to fill: new one or existing one
365  std::vector<sim::SDP>* curSDPVec;
366  if (itrthis == timePDclockSDPs.end() || itrthis->first != iTimePDclock) {
367  timePDclockSDPs.emplace_back(iTimePDclock, std::vector<sim::SDP>());
368  curSDPVec = &(timePDclockSDPs.back().second);
369  // curSDPVec =
370  // &(timePDclockSDPs.insert({iTimePDclock, std::vector<sim::SDP>()}).first->second);
371  }
372  else
373  curSDPVec = &(itrthis->second);
374 
375  for (auto const& sdp : sdps) {
376  curSDPVec->emplace_back(sdp, offset);
377  if (sdp.trackID + offset < range_trackID.first) range_trackID.first = sdp.trackID + offset;
378  if (sdp.trackID + offset > range_trackID.second)
379  range_trackID.second = sdp.trackID + offset;
380  } //end loop over SDPs
381 
382  } //end loop over TimePDclockSDPMap
383 
384  return range_trackID;
385  }
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
int OpDetNum() const
Returns the readout Optical Detector this object describes.
timePDclockSDPs_t::iterator findClosestTimePDclockSDP(storedTimePDclock_t timePDclock)
Return the iterator to the first timePDclockSDP not earlier than timePDclock.
int sim::OpDetBacktrackerRecord::OpDetNum ( ) const
inline

Returns the readout Optical Detector this object describes.

Definition at line 321 of file OpDetBacktrackerRecord.h.

Referenced by larg4::OpDetPhotonTable::AddOpDetBacktrackerRecord(), phot::PDFastSimPVS::AddOpDetBTR(), phot::PDFastSimANN::AddOpDetBTR(), phot::PDFastSimPAR::AddOpDetBTR(), MergeOpDetBacktrackerRecord(), operator<(), and operator==().

322 {
323  return iOpDetNum;
324 }
int iOpDetNum
OpticalDetector where the photons were detected.
bool sim::OpDetBacktrackerRecord::operator< ( const OpDetBacktrackerRecord other) const
inline

Comparison: sorts by Optical Detector ID.

Definition at line 308 of file OpDetBacktrackerRecord.h.

References OpDetNum().

309 {
310  return iOpDetNum < other.OpDetNum();
311 }
int iOpDetNum
OpticalDetector where the photons were detected.
bool sim::OpDetBacktrackerRecord::operator== ( const OpDetBacktrackerRecord other) const
inline

Comparison: true if OpDetBacktrackerRecords have the same Optical Detector ID.

Definition at line 312 of file OpDetBacktrackerRecord.h.

References OpDetNum().

313 {
314  return iOpDetNum == other.OpDetNum();
315 }
int iOpDetNum
OpticalDetector where the photons were detected.
double sim::OpDetBacktrackerRecord::Photons ( timePDclock_t  iTimePDclock) const

Returns the total number of scintillation photons on this Optical Detector in the specified timePDclock.

Definition at line 202 of file OpDetBacktrackerRecord.cxx.

References findClosestTimePDclockSDP(), and timePDclockSDPs.

203  {
204  double numPhotons = 0.;
205 
206  auto itr = findClosestTimePDclockSDP(iTimePDclock);
207  // auto itr = timePDclockSDPs.lower_bound(iTimePDclock);
208  // check to see if this iTimePDclock value is in the map
209  if (itr != timePDclockSDPs.end() && itr->first == iTimePDclock) {
210 
211  // loop over the list for this iTimePDclock value and add up
212  // the total number of electrons
213  for (auto sdp : itr->second) {
214  numPhotons += sdp.numPhotons;
215  } // end loop over sim::SDP for this TimePDclock
216 
217  } // end if this iTimePDclock is represented in the map
218 
219  return numPhotons;
220  }
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
timePDclockSDPs_t::iterator findClosestTimePDclockSDP(storedTimePDclock_t timePDclock)
Return the iterator to the first timePDclockSDP not earlier than timePDclock.
sim::OpDetBacktrackerRecord::timePDclockSDPs_t const & sim::OpDetBacktrackerRecord::timePDclockSDPsMap ( ) const
inline

Returns all the deposited energy information as stored.

Returns
all the deposited energy information as stored in the object

The returned list is organized in pairs. Each pair contains all ionization information in a single iTimePDclock tick (collection of sim::SDP), and the number of that tick. The information is sorted by increasing timePDclock tick.

See the class description for the details of the ionization information content.

Definition at line 317 of file OpDetBacktrackerRecord.h.

Referenced by larg4::OpDetPhotonTable::AddOpDetBacktrackerRecord(), phot::PDFastSimPVS::AddOpDetBTR(), phot::PDFastSimANN::AddOpDetBTR(), phot::PDFastSimPAR::AddOpDetBTR(), and MergeOpDetBacktrackerRecord().

318 {
319  return timePDclockSDPs;
320 }
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
std::vector< sim::SDP > sim::OpDetBacktrackerRecord::TrackIDsAndEnergies ( timePDclock_t  startTimePDclock,
timePDclock_t  endTimePDclock 
) const

Return all the recorded energy deposition within a time interval.

Parameters
startTimePDclockiTimePDclock tick opening the time window
endTimePDclockiTimePDclock tick closing the time window (included in the interval)
Returns
a collection of energy deposit information from all tracks

This method returns the energy deposited on this Optical Detector by each track ID active in the specified iTimePDclock time interval.

Each entry pertains a single track ID. For each entry, all energy deposit information is merged into a single record. It includes:

  • energy and number of photons, as the integral in the time interval
  • position, as average weighted by the number of photons
  • the ID of the track depositing this energy

Entries are sorted by track ID number.

Definition at line 247 of file OpDetBacktrackerRecord.cxx.

References findClosestTimePDclockSDP(), sim::SDP::numPhotons, timePDclockSDPs, weight, sim::SDP::x, sim::SDP::y, and sim::SDP::z.

Referenced by cheat::PhotonBackTracker::ChannelToTrackSDPs(), cheat::PhotonBackTracker::OpDetToTrackSDPs(), cheat::PhotonBackTracker::OpHitToSDPs(), and TrackSDPs().

250  {
251  // make a map of track ID values to sim::SDP objects
252 
253  if (startTimePDclock > endTimePDclock) {
254  mf::LogWarning("OpDetBacktrackerRecord")
255  << "requested TimePDclock range is bogus: " << startTimePDclock << " " << endTimePDclock
256  << " return empty vector";
257  return {}; // returns an empty vector
258  }
259 
260  std::map<TrackID_t, sim::SDP> idToSDP;
261 
262  //find the lower bound for this iTimePDclock and then iterate from there
263  auto itr = findClosestTimePDclockSDP(startTimePDclock);
264  // auto itr = timePDclockSDPs.lower_bound(startTimePDclock);
265 
266  while (itr != timePDclockSDPs.end()) {
267 
268  // check the iTimePDclock value for the iterator, break the loop if we
269  // are outside the range
270  if (itr->first > endTimePDclock) break;
271 
272  // grab the vector of SDPs for this TimePDclock
273  auto const& sdplist = itr->second;
274  // now loop over them and add their content to the map
275  for (auto const& sdp : sdplist) {
276  auto itTrkSDP = idToSDP.find(sdp.trackID);
277  if (itTrkSDP != idToSDP.end()) {
278  // the SDP we are going to update:
279  sim::SDP& trackSDP = itTrkSDP->second;
280 
281  double const nPh1 = trackSDP.numPhotons;
282  double const nPh2 = sdp.numPhotons;
283  double const weight = nPh1 + nPh2;
284 
285  // make a weighted average for the location information
286  trackSDP.x = (sdp.x * nPh2 + trackSDP.x * nPh1) / weight;
287  trackSDP.y = (sdp.y * nPh2 + trackSDP.y * nPh1) / weight;
288  trackSDP.z = (sdp.z * nPh2 + trackSDP.z * nPh1) / weight;
289  trackSDP.numPhotons = weight;
290  } // end if the track id for this one is found
291  else {
292  idToSDP[sdp.trackID] = sim::SDP(sdp);
293  }
294  } // end loop over vector
295 
296  ++itr;
297  } // end loop over iTimePDclock values
298 
299  // now fill the vector with the sdps from the map
300  std::vector<sim::SDP> sdps;
301  sdps.reserve(idToSDP.size());
302  for (auto const& itr : idToSDP) {
303  sdps.push_back(itr.second);
304  }
305 
306  return sdps;
307  }
float x
x position of ionization [cm]
timePDclockSDPs_t timePDclockSDPs
list of energy deposits for each timePDclock with signal
timePDclockSDPs_t::iterator findClosestTimePDclockSDP(storedTimePDclock_t timePDclock)
Return the iterator to the first timePDclockSDP not earlier than timePDclock.
float y
y position of ionization [cm]
double weight
Definition: plottest35.C:25
float numPhotons
number of photons at the optical detector for this track ID and time
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
float z
z position of ionization [cm]
std::vector< sim::TrackSDP > sim::OpDetBacktrackerRecord::TrackSDPs ( timePDclock_t  startTimePDclock,
timePDclock_t  endTimePDclock 
) const

Returns energies collected for each track within a time interval.

Parameters
startTimePDclockiTimePDclock tick opening the time window
endTimePDclockiTimePDclock tick closing the time window (included in the interval)
Returns
a collection of energy and fraction from each track in interval
See also
TrackIDsAndEnergies()

This method returns the energy deposited on this Optical Detector by each track ID active in the specified iTimePDclock time interval.

Each entry pertains a single track ID. For each entry, all energy deposit information is merged into a single record. It includes:

  • energy of the track, as the integral in the time interval [MeV]
  • energy fraction respect to the total (see below)
  • the ID of the track depositing this energy

The energy fraction is the energy deposited by the track on this Optical Detector in the specified time interval, divided by the total of the energy deposited by all tracks on this Optical Detector in that same time interval.

Entries are sorted by track ID number.

Definition at line 311 of file OpDetBacktrackerRecord.cxx.

References e, sim::NoParticleId, and TrackIDsAndEnergies().

313  {
314 
315  std::vector<sim::TrackSDP> trackSDPs;
316 
317  if (startTimePDclock > endTimePDclock) {
318  mf::LogWarning("OpDetBacktrackerRecord::TrackSDPs")
319  << "requested iTimePDclock range is bogus: " << startTimePDclock << " " << endTimePDclock
320  << " return empty vector";
321  return trackSDPs;
322  }
323 
324  double totalPhotons = 0.;
325  std::vector<sim::SDP> const sdps = TrackIDsAndEnergies(startTimePDclock, endTimePDclock);
326  for (auto const& sdp : sdps)
327  totalPhotons += sdp.numPhotons;
328 
329  // protect against a divide by zero below
330  if (totalPhotons < 1.e-5) totalPhotons = 1.;
331 
332  // loop over the entries in the map and fill the input vectors
333  for (auto const& sdp : sdps) {
334  if (sdp.trackID == sim::NoParticleId) continue;
335  trackSDPs.emplace_back(sdp.trackID, sdp.numPhotons / totalPhotons, sdp.numPhotons);
336  }
337 
338  return trackSDPs;
339  }
static const int NoParticleId
Definition: sim.h:21
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< sim::SDP > TrackIDsAndEnergies(timePDclock_t startTimePDclock, timePDclock_t endTimePDclock) const
Return all the recorded energy deposition within a time interval.
Float_t e
Definition: plot.C:35

Member Data Documentation

int sim::OpDetBacktrackerRecord::iOpDetNum
private

OpticalDetector where the photons were detected.

Definition at line 137 of file OpDetBacktrackerRecord.h.

timePDclockSDPs_t sim::OpDetBacktrackerRecord::timePDclockSDPs
private

list of energy deposits for each timePDclock with signal

Definition at line 138 of file OpDetBacktrackerRecord.h.

Referenced by AddScintillationPhotons(), Energy(), findClosestTimePDclockSDP(), MergeOpDetBacktrackerRecord(), OpDetBacktrackerRecord(), Photons(), and TrackIDsAndEnergies().


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