69 if (( numberPhotons < std::numeric_limits<double>::epsilon() )
70 || ( energy<=std::numeric_limits<double>::epsilon() ))
74 <<
"AddTrackPhotons() trying to add to iTimePDclock #" 80 <<
" MeV of energy from track ID=" 91 itr->first != iTimePDclock){
92 std::vector<sim::SDP> sdplist;
93 sdplist.emplace_back(trackID,
106 for(
auto& sdp : itr->second){
108 if (sdp.trackID != trackID )
continue;
111 double weight = sdp.numPhotons + numberPhotons;
112 sdp.x = (sdp.x * sdp.numPhotons + xyz[0]*numberPhotons)/weight;
113 sdp.y = (sdp.y * sdp.numPhotons + xyz[1]*numberPhotons)/weight;
114 sdp.z = (sdp.z * sdp.numPhotons + xyz[2]*numberPhotons)/weight;
116 sdp.energy = sdp.energy +
energy;
124 itr->second.emplace_back(trackID,
140 double numPhotons = 0.;
146 itr->first == iTimePDclock){
150 for(
auto sdp : itr->second){
151 numPhotons += sdp.numPhotons;
169 itr->first == iTimePDclock){
173 for(
auto sdp : itr->second ){
174 energy += sdp.energy;
189 if(startTimePDclock > endTimePDclock ){
190 mf::LogWarning(
"OpDetBacktrackerRecord") <<
"requested TimePDclock range is bogus: " 191 << startTimePDclock <<
" " << endTimePDclock
192 <<
" return empty vector";
196 std::map<TrackID_t, sim::SDP> idToSDP;
205 if(itr->first > endTimePDclock)
break;
208 auto const& sdplist = itr->second;
210 for(
auto const& sdp : sdplist){
211 auto itTrkSDP = idToSDP.find(sdp.trackID);
212 if( itTrkSDP != idToSDP.end() ){
214 sim::SDP& trackSDP = itTrkSDP->second;
217 double const nPh2 = sdp.numPhotons;
218 double const weight = nPh1 + nPh2;
221 trackSDP.
x = (sdp.x*nPh2 + trackSDP.
x*nPh1)/weight;
222 trackSDP.
y = (sdp.y*nPh2 + trackSDP.
y*nPh1)/weight;
223 trackSDP.
z = (sdp.z*nPh2 + trackSDP.
z*nPh1)/weight;
227 idToSDP[sdp.trackID] =
sim::SDP(sdp);
235 std::vector<sim::SDP> sdps;
236 sdps.reserve(idToSDP.size());
237 for(
auto const& itr : idToSDP){
238 sdps.push_back(itr.second);
250 std::vector<sim::TrackSDP> trackSDPs;
252 if(startTimePDclock > endTimePDclock ){
253 mf::LogWarning(
"OpDetBacktrackerRecord::TrackSDPs") <<
"requested iTimePDclock range is bogus: " 254 << startTimePDclock <<
" " << endTimePDclock
255 <<
" return empty vector";
259 double totalPhotons = 0.;
261 for (
auto const& sdp : sdps)
262 totalPhotons += sdp.numPhotons;
265 if(totalPhotons < 1.
e-5) totalPhotons = 1.;
268 for (
auto const& sdp : sdps){
270 trackSDPs.emplace_back(sdp.trackID, sdp.numPhotons/totalPhotons, sdp.numPhotons);
280 std::pair<OpDetBacktrackerRecord::TrackID_t,OpDetBacktrackerRecord::TrackID_t>
285 throw std::runtime_error(
"ERROR OpDetBacktrackerRecord Merge: Trying to merge different channels!");
292 auto iTimePDclock = itr.first;
293 auto const& sdps = itr.second;
299 std::vector<sim::SDP>* curSDPVec;
301 itrthis->first != iTimePDclock){
306 curSDPVec = &(itrthis->second);
308 for(
auto const& sdp : sdps){
309 curSDPVec->emplace_back(sdp, offset);
310 if( sdp.trackID+offset < range_trackID.first )
311 range_trackID.first = sdp.trackID+offset;
312 if( sdp.trackID+offset > range_trackID.second )
313 range_trackID.second = sdp.trackID+offset;
319 return range_trackID;
328 {
return a.first < b.first; }
332 {
return a_TimePDclock < b.first; }
336 {
return a.first < b_TimePDclock; }
343 return std::lower_bound
350 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]
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.
#define LOG_ERROR(category)
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.
void AddScintillationPhotons(TrackID_t trackID, timePDclock_t timePDclock, double numberPhotons, double const *xyz, double energy)
Add scintillation photons and energy to this OpticalDetector.
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].
std::pair< double, std::vector< sim::SDP > > timePDclockSDP_t
List of energy deposits at the same time (on this Optical Detector)
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
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.