21 #include "messagefacility/MessageLogger/MessageLogger.h"
69 if (( numberPhotons < std::numeric_limits<double>::epsilon() )
70 || ( energy<=std::numeric_limits<double>::epsilon() ))
73 MF_LOG_ERROR(
"OpDetBacktrackerRecord")
74 <<
"AddTrackPhotons() trying to add to iTimePDclock #"
80 <<
" MeV of energy from track ID="
91 (
abs(itr->first - iTimePDclock) > .50 )){
93 std::vector<sim::SDP> sdplist;
94 sdplist.emplace_back(trackID,
101 timePDclockSDPs.emplace(itr, std::round(iTimePDclock), std::move(sdplist) );
107 for(
auto& sdp : itr->second){
109 if (sdp.trackID != trackID )
continue;
112 double weight = sdp.numPhotons + numberPhotons;
113 sdp.x = (sdp.x * sdp.numPhotons + xyz[0]*numberPhotons)/weight;
114 sdp.y = (sdp.y * sdp.numPhotons + xyz[1]*numberPhotons)/weight;
115 sdp.z = (sdp.z * sdp.numPhotons + xyz[2]*numberPhotons)/weight;
116 sdp.numPhotons = weight;
117 sdp.energy = sdp.energy + energy;
125 itr->second.emplace_back(trackID,
141 double numPhotons = 0.;
143 auto itr = findClosestTimePDclockSDP(iTimePDclock);
146 if(itr != timePDclockSDPs.end() &&
147 itr->first == iTimePDclock){
151 for(
auto sdp : itr->second){
152 numPhotons += sdp.numPhotons;
170 itr->first == iTimePDclock){
174 for(
auto sdp : itr->second ){
175 energy += sdp.energy;
190 if(startTimePDclock > endTimePDclock ){
191 mf::LogWarning(
"OpDetBacktrackerRecord") <<
"requested TimePDclock range is bogus: "
192 << startTimePDclock <<
" " << endTimePDclock
193 <<
" return empty vector";
197 std::map<TrackID_t, sim::SDP> idToSDP;
206 if(itr->first > endTimePDclock)
break;
209 auto const& sdplist = itr->second;
211 for(
auto const& sdp : sdplist){
212 auto itTrkSDP = idToSDP.find(sdp.trackID);
213 if( itTrkSDP != idToSDP.end() ){
215 sim::SDP& trackSDP = itTrkSDP->second;
218 double const nPh2 = sdp.numPhotons;
219 double const weight = nPh1 + nPh2;
222 trackSDP.
x = (sdp.x*nPh2 + trackSDP.
x*nPh1)/weight;
223 trackSDP.
y = (sdp.y*nPh2 + trackSDP.
y*nPh1)/weight;
224 trackSDP.
z = (sdp.z*nPh2 + trackSDP.
z*nPh1)/weight;
228 idToSDP[sdp.trackID] =
sim::SDP(sdp);
236 std::vector<sim::SDP> sdps;
237 sdps.reserve(idToSDP.size());
238 for(
auto const& itr : idToSDP){
239 sdps.push_back(itr.second);
251 std::vector<sim::TrackSDP> trackSDPs;
253 if(startTimePDclock > endTimePDclock ){
254 mf::LogWarning(
"OpDetBacktrackerRecord::TrackSDPs") <<
"requested iTimePDclock range is bogus: "
255 << startTimePDclock <<
" " << endTimePDclock
256 <<
" return empty vector";
260 double totalPhotons = 0.;
262 for (
auto const& sdp : sdps)
263 totalPhotons += sdp.numPhotons;
266 if(totalPhotons < 1.
e-5) totalPhotons = 1.;
269 for (
auto const& sdp : sdps){
271 trackSDPs.emplace_back(sdp.trackID, sdp.numPhotons/totalPhotons, sdp.numPhotons);
281 std::pair<OpDetBacktrackerRecord::TrackID_t,OpDetBacktrackerRecord::TrackID_t>
286 throw std::runtime_error(
"ERROR OpDetBacktrackerRecord Merge: Trying to merge different channels!");
288 std::pair<TrackID_t,TrackID_t> range_trackID(std::numeric_limits<int>::max(),
289 std::numeric_limits<int>::min());
293 auto iTimePDclock = itr.first;
294 auto const& sdps = itr.second;
300 std::vector<sim::SDP>* curSDPVec;
302 itrthis->first != iTimePDclock){
307 curSDPVec = &(itrthis->second);
309 for(
auto const& sdp : sdps){
310 curSDPVec->emplace_back(sdp, offset);
311 if( sdp.trackID+offset < range_trackID.first )
312 range_trackID.first = sdp.trackID+
offset;
313 if( sdp.trackID+offset > range_trackID.second )
314 range_trackID.second = sdp.trackID+
offset;
320 return range_trackID;
329 {
return a.first < b.first; }
333 {
return a_TimePDclock < b.first; }
337 {
return a.first < b_TimePDclock; }
344 return std::lower_bound
351 return std::lower_bound
process_name opflash particleana ie ie ie z
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
float x
x position of ionization [cm]
process_name opflash particleana ie x
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.
process_name opflash particleana ie ie y
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
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
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.