41 if ((numberPhotons < std::numeric_limits<double>::epsilon()) ||
42 (energy <= std::numeric_limits<double>::epsilon())) {
45 <<
"AddTrackPhotons() trying to add to iTimePDclock #" << iTimePDclock <<
" " 46 << numberPhotons <<
" photons with " << energy
47 <<
" MeV of energy from track ID=" << trackID;
51 int rounded_time = std::round(iTimePDclock);
61 std::vector<sim::SDP>{
sim::SDP(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2])}});
67 for (
auto& sdp : itr->second) {
69 if (sdp.trackID != trackID)
continue;
72 double weight = sdp.numPhotons + numberPhotons;
73 sdp.x = (sdp.x * sdp.numPhotons + xyz[0] * numberPhotons) / weight;
74 sdp.y = (sdp.y * sdp.numPhotons + xyz[1] * numberPhotons) / weight;
75 sdp.z = (sdp.z * sdp.numPhotons + xyz[2] * numberPhotons) / weight;
77 sdp.energy = sdp.energy +
energy;
85 itr->second.emplace_back(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2]);
122 for (
auto& [channel, vec] : sdp_map) {
133 double numberPhotons,
145 if ((numberPhotons < std::numeric_limits<double>::epsilon()) ||
146 (energy <= std::numeric_limits<double>::epsilon())) {
149 <<
"AddTrackPhotons() trying to add to iTimePDclock #" << iTimePDclock <<
" " 150 << numberPhotons <<
" photons with " << energy
151 <<
" MeV of energy from track ID=" << trackID;
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));
177 for (
auto& sdp : itr->second) {
179 if (sdp.trackID != trackID)
continue;
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;
187 sdp.energy = sdp.energy +
energy;
195 itr->second.emplace_back(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2]);
204 double numPhotons = 0.;
213 for (
auto sdp : itr->second) {
214 numPhotons += sdp.numPhotons;
236 for (
auto sdp : itr->second) {
237 energy += sdp.energy;
253 if (startTimePDclock > endTimePDclock) {
255 <<
"requested TimePDclock range is bogus: " << startTimePDclock <<
" " << endTimePDclock
256 <<
" return empty vector";
260 std::map<TrackID_t, sim::SDP> idToSDP;
270 if (itr->first > endTimePDclock)
break;
273 auto const& sdplist = itr->second;
275 for (
auto const& sdp : sdplist) {
276 auto itTrkSDP = idToSDP.find(sdp.trackID);
277 if (itTrkSDP != idToSDP.end()) {
279 sim::SDP& trackSDP = itTrkSDP->second;
282 double const nPh2 = sdp.numPhotons;
283 double const weight = nPh1 + nPh2;
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;
292 idToSDP[sdp.trackID] =
sim::SDP(sdp);
300 std::vector<sim::SDP> sdps;
301 sdps.reserve(idToSDP.size());
302 for (
auto const& itr : idToSDP) {
303 sdps.push_back(itr.second);
315 std::vector<sim::TrackSDP> trackSDPs;
317 if (startTimePDclock > endTimePDclock) {
319 <<
"requested iTimePDclock range is bogus: " << startTimePDclock <<
" " << endTimePDclock
320 <<
" return empty vector";
324 double totalPhotons = 0.;
326 for (
auto const& sdp : sdps)
327 totalPhotons += sdp.numPhotons;
330 if (totalPhotons < 1.
e-5) totalPhotons = 1.;
333 for (
auto const& sdp : sdps) {
335 trackSDPs.emplace_back(sdp.trackID, sdp.numPhotons / totalPhotons, sdp.numPhotons);
344 std::pair<OpDetBacktrackerRecord::TrackID_t, OpDetBacktrackerRecord::TrackID_t>
349 throw std::runtime_error(
350 "ERROR OpDetBacktrackerRecord Merge: Trying to merge different channels!");
352 std::pair<TrackID_t, TrackID_t> range_trackID(std::numeric_limits<int>::max(),
353 std::numeric_limits<int>::min());
358 auto iTimePDclock = itr.first;
359 auto const& sdps = itr.second;
365 std::vector<sim::SDP>* curSDPVec;
366 if (itrthis ==
timePDclockSDPs.end() || itrthis->first != iTimePDclock) {
373 curSDPVec = &(itrthis->second);
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;
384 return range_trackID;
392 return a.first < b.first;
397 return a_TimePDclock < b.first;
402 return a.first < b_TimePDclock;
410 return std::lower_bound(
417 return std::lower_bound(
Namespace for general, non-LArSoft-specific utilities.
int iOpDetNum
OpticalDetector where the photons were detected.
float x
x position of ionization [cm]
std::pair< double, std::vector< sim::SDP > > timePDclockSDP_t
List of energy deposits at the same time (on this Optical Detector)
constexpr auto abs(T v)
Returns the absolute value of the argument.
#define MF_LOG_ERROR(category)
double Photons(timePDclock_t iTimePDclock) const
Returns the total number of scintillation photons on this Optical Detector in the specified timePDclo...
constexpr int kBogusI
obviously bogus integer value
std::pair< TrackID_t, TrackID_t > MergeOpDetBacktrackerRecord(const OpDetBacktrackerRecord &opDetNum, int offset)
Merges the deposits from another Optical Detector into this one.
SDP()
Default constructor (sets "bogus" values)
timePDclockSDP_t::first_type storedTimePDclock_t
Type for timePDclock tick used in the internal representation.
std::vector< sim::TrackSDP > TrackSDPs(timePDclock_t startTimePDclock, timePDclock_t endTimePDclock) const
Returns energies collected for each track within a time interval.
Energy deposited on a readout Optical Detector by simulated tracks.
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.
SDP::TrackID_t TrackID_t
Type of track ID (the value comes from Geant4)
static const int NoParticleId
timePDclockSDPs_t::iterator findClosestTimePDclockSDP(storedTimePDclock_t timePDclock)
Return the iterator to the first timePDclockSDP not earlier than timePDclock.
double timePDclock_t
Type for iTimePDclock tick used in the interface.
bool operator()(timePDclockSDP_t const &a, timePDclockSDP_t const &b) const
std::map< timePDclock_t, std::vector< sim::SDP > > fTimePDclockSDPs
void AddScintillationPhotonsToMap(TrackID_t trackID, timePDclock_t iTimePDclock, double numberPhotons, double const *xyz, double energy)
void AddScintillationPhotons(TrackID_t trackID, timePDclock_t timePDclock, double numberPhotons, double const *xyz, double energy)
Add scintillation photons and energy to this OpticalDetector.
bool operator()(storedTimePDclock_t a_TimePDclock, timePDclockSDP_t const &b) const
float y
y position of ionization [cm]
double Energy(timePDclock_t iTimePDclock) const
Returns the total energy on this Optical Detector in the specified iTimePDclock [MeV].
float numPhotons
number of photons at the optical detector for this track ID and time
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.
constexpr double kBogusD
obviously bogus double value
bool operator()(timePDclockSDP_t const &a, storedTimePDclock_t b_TimePDclock) const
Collection of Physical constants used in LArSoft.
float z
z position of ionization [cm]
Tools and modules for checking out the basics of the Monte Carlo.
timePDclockSDPs_t const & timePDclockSDPsMap() const
Returns all the deposited energy information as stored.