67 if ((numberPhotons < std::numeric_limits<double>::epsilon()) ||
68 (energy <= std::numeric_limits<double>::epsilon())) {
71 <<
"AddTrackPhotons() trying to add to iTimePDclock #" << iTimePDclock <<
" " 72 << numberPhotons <<
" photons with " << energy
73 <<
" MeV of energy from track ID=" << trackID;
84 std::vector<sim::SDP> sdplist;
85 sdplist.emplace_back(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2]);
86 timePDclockSDPs.emplace(itr, std::round(iTimePDclock), std::move(sdplist));
92 for (
auto& sdp : itr->second) {
94 if (sdp.trackID != trackID)
continue;
97 double weight = sdp.numPhotons + numberPhotons;
98 sdp.x = (sdp.x * sdp.numPhotons + xyz[0] * numberPhotons) / weight;
99 sdp.y = (sdp.y * sdp.numPhotons + xyz[1] * numberPhotons) / weight;
100 sdp.z = (sdp.z * sdp.numPhotons + xyz[2] * numberPhotons) / weight;
102 sdp.energy = sdp.energy +
energy;
110 itr->second.emplace_back(trackID, numberPhotons, energy, xyz[0], xyz[1], xyz[2]);
119 double numPhotons = 0.;
128 for (
auto sdp : itr->second) {
129 numPhotons += sdp.numPhotons;
150 for (
auto sdp : itr->second) {
151 energy += sdp.energy;
167 if (startTimePDclock > endTimePDclock) {
169 <<
"requested TimePDclock range is bogus: " << startTimePDclock <<
" " << endTimePDclock
170 <<
" return empty vector";
174 std::map<TrackID_t, sim::SDP> idToSDP;
183 if (itr->first > endTimePDclock)
break;
186 auto const& sdplist = itr->second;
188 for (
auto const& sdp : sdplist) {
189 auto itTrkSDP = idToSDP.find(sdp.trackID);
190 if (itTrkSDP != idToSDP.end()) {
192 sim::SDP& trackSDP = itTrkSDP->second;
195 double const nPh2 = sdp.numPhotons;
196 double const weight = nPh1 + nPh2;
199 trackSDP.
x = (sdp.x * nPh2 + trackSDP.
x * nPh1) / weight;
200 trackSDP.
y = (sdp.y * nPh2 + trackSDP.
y * nPh1) / weight;
201 trackSDP.
z = (sdp.z * nPh2 + trackSDP.
z * nPh1) / weight;
205 idToSDP[sdp.trackID] =
sim::SDP(sdp);
213 std::vector<sim::SDP> sdps;
214 sdps.reserve(idToSDP.size());
215 for (
auto const& itr : idToSDP) {
216 sdps.push_back(itr.second);
228 std::vector<sim::TrackSDP> trackSDPs;
230 if (startTimePDclock > endTimePDclock) {
232 <<
"requested iTimePDclock range is bogus: " << startTimePDclock <<
" " << endTimePDclock
233 <<
" return empty vector";
237 double totalPhotons = 0.;
239 for (
auto const& sdp : sdps)
240 totalPhotons += sdp.numPhotons;
243 if (totalPhotons < 1.
e-5) totalPhotons = 1.;
246 for (
auto const& sdp : sdps) {
248 trackSDPs.emplace_back(sdp.trackID, sdp.numPhotons / totalPhotons, sdp.numPhotons);
257 std::pair<OpDetBacktrackerRecord::TrackID_t, OpDetBacktrackerRecord::TrackID_t>
262 throw std::runtime_error(
263 "ERROR OpDetBacktrackerRecord Merge: Trying to merge different channels!");
265 std::pair<TrackID_t, TrackID_t> range_trackID(std::numeric_limits<int>::max(),
266 std::numeric_limits<int>::min());
270 auto iTimePDclock = itr.first;
271 auto const& sdps = itr.second;
277 std::vector<sim::SDP>* curSDPVec;
278 if (itrthis ==
timePDclockSDPs.end() || itrthis->first != iTimePDclock) {
283 curSDPVec = &(itrthis->second);
285 for (
auto const& sdp : sdps) {
286 curSDPVec->emplace_back(sdp, offset);
287 if (sdp.trackID + offset < range_trackID.first) range_trackID.first = sdp.trackID + offset;
288 if (sdp.trackID + offset > range_trackID.second)
289 range_trackID.second = sdp.trackID + offset;
294 return range_trackID;
302 return a.first < b.first;
307 return a_TimePDclock < b.first;
312 return a.first < b_TimePDclock;
320 return std::lower_bound(
327 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
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.