56 double numberElectrons,
65 if ((numberElectrons < std::numeric_limits<double>::epsilon())
66 || (energy <= std::numeric_limits<double>::epsilon()))
70 <<
"AddIonizationElectrons() trying to add to TDC #" 76 <<
" MeV of energy from track ID=" 88 std::vector<sim::IDE> idelist;
89 idelist.emplace_back(trackID,
102 for(
auto& ide : itr->second){
104 if (ide.trackID != trackID )
continue;
107 double weight = ide.numElectrons + numberElectrons;
108 ide.x = (ide.x * ide.numElectrons + xyz[0]*numberElectrons)/weight;
109 ide.y = (ide.y * ide.numElectrons + xyz[1]*numberElectrons)/weight;
110 ide.z = (ide.z * ide.numElectrons + xyz[2]*numberElectrons)/weight;
111 ide.numElectrons =
weight;
112 ide.energy = ide.energy +
energy;
120 itr->second.emplace_back(trackID,
146 for(
auto ide : itr->second){
147 charge += ide.numElectrons;
168 for(
auto ide : itr->second ){
169 energy += ide.energy;
185 if(startTDC > endTDC ){
187 << startTDC <<
" " << endTDC
188 <<
" return empty vector";
192 std::map<TrackID_t, sim::IDE> idToIDE;
201 if(itr->first > endTDC)
break;
204 auto const& idelist = itr->second;
206 for(
auto const& ide : idelist){
207 auto itTrkIDE = idToIDE.find(ide.trackID);
208 if( itTrkIDE != idToIDE.end() ){
210 sim::IDE& trackIDE = itTrkIDE->second;
213 double const nel2 = ide.numElectrons;
214 double const en1 = trackIDE.
energy;
215 double const en2 = ide.energy;
216 double const energy = en1 + en2;
217 double const weight = nel1 + nel2;
220 trackIDE.
x = (ide.x*nel2 + trackIDE.
x*nel1)/weight;
221 trackIDE.
y = (ide.y*nel2 + trackIDE.
y*nel1)/weight;
222 trackIDE.
z = (ide.z*nel2 + trackIDE.
z*nel1)/weight;
227 idToIDE[ide.trackID] =
sim::IDE(ide);
235 std::vector<sim::IDE> ides;
236 ides.reserve(idToIDE.size());
237 for(
auto const& itr : idToIDE){
238 ides.push_back(itr.second);
250 std::vector<sim::TrackIDE> trackIDEs;
252 if(startTDC > endTDC ){
253 mf::LogWarning(
"SimChannel::TrackIDEs") <<
"requested tdc range is bogus: " 254 << startTDC <<
" " << endTDC
255 <<
" return empty vector";
261 for (
auto const& ide : ides)
262 totalE += ide.energy;
265 if(totalE < 1.
e-5) totalE = 1.;
268 for (
auto const& ide : ides){
270 trackIDEs.emplace_back(ide.trackID, ide.energy/totalE, ide.energy, ide.numElectrons);
280 std::pair<SimChannel::TrackID_t,SimChannel::TrackID_t>
285 throw std::runtime_error(
"ERROR SimChannel Merge: Trying to merge different channels!");
290 for(
auto const& itr : channel.
TDCIDEMap()){
292 auto tdc = itr.first;
293 auto const& ides = itr.second;
299 std::vector<sim::IDE>* curIDEVec;
301 itrthis->first != tdc){
302 fTDCIDEs.emplace_back(tdc, std::vector<sim::IDE>());
303 curIDEVec = &(
fTDCIDEs.back().second);
306 curIDEVec = &(itrthis->second);
308 for(
auto const& ide : ides){
309 curIDEVec->emplace_back(ide, offset);
310 auto tid =
std::abs(ide.trackID)+offset;
311 if( tid < range_trackID.first )
312 range_trackID.first = tid;
313 if( tid > range_trackID.second )
314 range_trackID.second = tid;
320 return range_trackID;
329 {
return a.first <
b.first; }
333 {
return a_tdc <
b.first; }
337 {
return a.first < b_tdc; }
344 return std::lower_bound
351 return std::lower_bound
TrackID_t trackID
Geant4 supplied track ID.
std::pair< TrackID_t, TrackID_t > MergeSimChannel(const SimChannel &channel, int offset)
Merges the deposits from another channel into this one.
raw::ChannelID_t fChannel
readout channel where electrons are collected
float z
z position of ionization [cm]
Namespace for general, non-LArSoft-specific utilities.
Energy deposited on a readout channel by simulated tracks.
std::pair< unsigned short, std::vector< sim::IDE > > TDCIDE
List of energy deposits at the same time (on this channel)
double Energy(TDC_t tdc) const
Returns the total energy on this channel in the specified TDC [MeV].
#define MF_LOG_ERROR(category)
constexpr int kBogusI
obviously bogus integer value
float x
x position of ionization [cm]
TDCIDEs_t fTDCIDEs
list of energy deposits for each TDC with signal
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
double Charge(TDC_t tdc) const
Returns the total number of ionization electrons on this channel in the specified TDC...
Ionization at a point of the TPC sensitive volume.
static const int NoParticleId
float energy
energy deposited by ionization by this track ID and time [MeV]
std::vector< sim::TrackIDE > TrackIDEs(TDC_t startTDC, TDC_t endTDC) const
Returns energies collected for each track within a time interval.
static int max(int a, int b)
Code to link reconstructed objects back to the MC truth information.
TDCIDEs_t::iterator findClosestTDCIDE(StoredTDC_t tdc)
Return the iterator to the first TDCIDE not earlier than tdc.
float y
y position of ionization [cm]
void AddIonizationElectrons(TrackID_t trackID, TDC_t tdc, double numberElectrons, double const *xyz, double energy)
Add ionization electrons and energy to this channel.
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
std::vector< sim::IDE > TrackIDsAndEnergies(TDC_t startTDC, TDC_t endTDC) const
Return all the recorded energy deposition within a time interval.
IDE::TrackID_t TrackID_t
Type of track ID (the value comes from Geant4)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TDCIDEs_t const & TDCIDEMap() const
Returns all the deposited energy information as stored.
constexpr double kBogusD
obviously bogus double value
IDE()
Default constructor (sets "bogus" values)
Tools and modules for checking out the basics of the Monte Carlo.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Collection of Physical constants used in LArSoft.
float numElectrons
number of electrons at the readout for this track ID and time
TDCIDE::first_type StoredTDC_t
Type for TDC tick used in the internal representation.