54 double numberElectrons,
63 if ((numberElectrons < std::numeric_limits<double>::epsilon())
64 || (energy <= std::numeric_limits<double>::epsilon()))
68 <<
"AddIonizationElectrons() trying to add to TDC #" 74 <<
" MeV of energy from track ID=" 86 std::vector<sim::IDE> idelist;
87 idelist.emplace_back(trackID,
94 fTDCIDEs.emplace(itr, tdc, std::move(idelist) );
100 for(
auto& ide : itr->second){
102 if (ide.trackID != trackID )
continue;
105 double weight = ide.numElectrons + numberElectrons;
106 ide.x = (ide.x * ide.numElectrons + xyz[0]*numberElectrons)/weight;
107 ide.y = (ide.y * ide.numElectrons + xyz[1]*numberElectrons)/weight;
108 ide.z = (ide.z * ide.numElectrons + xyz[2]*numberElectrons)/weight;
109 ide.numElectrons =
weight;
110 ide.energy = ide.energy +
energy;
118 itr->second.emplace_back(trackID,
144 for(
auto ide : itr->second){
145 charge += ide.numElectrons;
166 for(
auto ide : itr->second ){
167 energy += ide.energy;
183 if(startTDC > endTDC ){
185 << startTDC <<
" " << endTDC
186 <<
" return empty vector";
190 std::map<TrackID_t, sim::IDE> idToIDE;
199 if(itr->first > endTDC)
break;
202 auto const& idelist = itr->second;
204 for(
auto const& ide : idelist){
205 auto itTrkIDE = idToIDE.find(ide.trackID);
206 if( itTrkIDE != idToIDE.end() ){
208 sim::IDE& trackIDE = itTrkIDE->second;
211 double const nel2 = ide.numElectrons;
212 double const en1 = trackIDE.
energy;
213 double const en2 = ide.energy;
214 double const energy = en1 + en2;
215 double const weight = nel1 + nel2;
218 trackIDE.
x = (ide.x*nel2 + trackIDE.
x*nel1)/weight;
219 trackIDE.
y = (ide.y*nel2 + trackIDE.
y*nel1)/weight;
220 trackIDE.
z = (ide.z*nel2 + trackIDE.
z*nel1)/weight;
225 idToIDE[ide.trackID] =
sim::IDE(ide);
233 std::vector<sim::IDE> ides;
234 ides.reserve(idToIDE.size());
235 for(
auto const& itr : idToIDE){
236 ides.push_back(itr.second);
248 std::vector<sim::TrackIDE> trackIDEs;
250 if(startTDC > endTDC ){
251 mf::LogWarning(
"SimChannel::TrackIDEs") <<
"requested tdc range is bogus: " 252 << startTDC <<
" " << endTDC
253 <<
" return empty vector";
259 for (
auto const& ide : ides)
260 totalE += ide.energy;
263 if(totalE < 1.
e-5) totalE = 1.;
266 for (
auto const& ide : ides){
268 trackIDEs.emplace_back(ide.trackID, ide.energy/totalE, ide.energy, ide.numElectrons);
278 std::pair<SimChannel::TrackID_t,SimChannel::TrackID_t>
283 throw std::runtime_error(
"ERROR SimChannel Merge: Trying to merge different channels!");
288 for(
auto const& itr : channel.
TDCIDEMap()){
290 auto tdc = itr.first;
291 auto const& ides = itr.second;
297 std::vector<sim::IDE>* curIDEVec;
299 itrthis->first != tdc){
300 fTDCIDEs.emplace_back(tdc, std::vector<sim::IDE>());
301 curIDEVec = &(
fTDCIDEs.back().second);
304 curIDEVec = &(itrthis->second);
306 for(
auto const& ide : ides){
307 curIDEVec->emplace_back(ide, offset);
308 if( ide.trackID+offset < range_trackID.first )
309 range_trackID.first = ide.trackID+offset;
310 if( ide.trackID+offset > range_trackID.second )
311 range_trackID.second = ide.trackID+offset;
317 return range_trackID;
326 {
return a.first < b.first; }
330 {
return a_tdc < b.first; }
334 {
return a.first < b_tdc; }
341 return std::lower_bound
348 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].
constexpr int kBogusI
obviously bogus integer value
float x
x position of ionization [cm]
#define LOG_ERROR(category)
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.
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.
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
object containing MC truth information necessary for making RawDigits and doing back tracking ...
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)
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Tools and modules for checking out the basics of the Monte Carlo.
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.