LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
MergeSimSources.cxx
Go to the documentation of this file.
1 
12 #include <algorithm>
13 #include <sstream>
14 #include <stdexcept>
15 
16 #include "MergeSimSources.h"
17 
19  : fG4TrackIDOffsets(offsets)
20 {
21  Reset();
22 }
23 
25 {
26  fG4TrackIDRanges.clear();
27  fG4TrackIDRanges.resize(
28  fG4TrackIDOffsets.size(),
29  std::make_pair(std::numeric_limits<int>::max(), std::numeric_limits<int>::min()));
30  fMCParticleListMap.clear();
31  fMCParticleListMap.resize(fG4TrackIDOffsets.size(), std::vector<size_t>());
32 }
33 
35  std::vector<simb::MCParticle>& merged_vector,
36  const std::vector<simb::MCParticle>& input_vector,
37  size_t source_index)
38 {
39 
40  if (source_index >= fG4TrackIDOffsets.size())
41  std::runtime_error("ERROR in MergeSimSourcesUtility: Source index out of range!");
42 
43  fMCParticleListMap[source_index].resize(input_vector.size());
44  merged_vector.reserve(merged_vector.size() + input_vector.size());
45 
46  std::pair<int, int> range_trackID(std::numeric_limits<int>::max(),
47  std::numeric_limits<int>::min());
48 
49  for (size_t i_p = 0; i_p < input_vector.size(); i_p++) {
50  merged_vector.emplace_back(input_vector[i_p], fG4TrackIDOffsets[source_index]);
51 
52  fMCParticleListMap[source_index][i_p] = merged_vector.size() - 1;
53 
54  if (std::abs(merged_vector.back().TrackId()) < range_trackID.first)
55  range_trackID.first = std::abs(merged_vector.back().TrackId());
56  if (std::abs(merged_vector.back().TrackId()) > range_trackID.second)
57  range_trackID.second = std::abs(merged_vector.back().TrackId());
58  }
59 
60  UpdateG4TrackIDRange(range_trackID, source_index);
61 }
62 
63 void sim::MergeSimSourcesUtility::MergeSimChannels(std::vector<sim::SimChannel>& merged_vector,
64  const std::vector<sim::SimChannel>& input_vector,
65  size_t source_index)
66 {
67  if (source_index >= fG4TrackIDOffsets.size())
68  std::runtime_error("ERROR in MergeSimSourcesUtility: Source index out of range!");
69 
70  merged_vector.reserve(merged_vector.size() + input_vector.size());
71 
72  std::pair<int, int> range_trackID(std::numeric_limits<int>::max(),
73  std::numeric_limits<int>::min());
74 
75  for (auto const& simchannel : input_vector) {
77  std::find(merged_vector.begin(), merged_vector.end(), simchannel);
78 
79  if (it == merged_vector.end()) {
80  merged_vector.emplace_back(simchannel.Channel());
81  it = merged_vector.end() - 1;
82  }
83 
84  std::pair<int, int> thisrange =
85  it->MergeSimChannel(simchannel, fG4TrackIDOffsets[source_index]);
86  if (std::abs(thisrange.first) < std::abs(range_trackID.first))
87  range_trackID.first = std::abs(thisrange.first);
88  if (std::abs(thisrange.second) > std::abs(range_trackID.second))
89  range_trackID.second = std::abs(thisrange.second);
90  }
91 
92  UpdateG4TrackIDRange(range_trackID, source_index);
93 }
94 
96  std::vector<sim::AuxDetSimChannel>& merged_vector,
97  const std::vector<sim::AuxDetSimChannel>& input_vector,
98  size_t source_index)
99 {
100  if (source_index >= fG4TrackIDOffsets.size())
101  std::runtime_error("ERROR in MergeSimSourcesUtility: Source index out of range!");
102 
103  merged_vector.reserve(merged_vector.size() + input_vector.size());
104 
105  std::pair<int, int> range_trackID(std::numeric_limits<int>::max(),
106  std::numeric_limits<int>::min());
107 
108  for (auto const& simchannel : input_vector) {
110  std::find(merged_vector.begin(), merged_vector.end(), simchannel);
111 
112  if (it == merged_vector.end()) {
113  merged_vector.emplace_back(simchannel.AuxDetID(), simchannel.AuxDetSensitiveID());
114  it = merged_vector.end() - 1;
115  }
116 
117  // re-make the AuxDetSimChannel with both pairs of AuxDetIDEs
118  int offset = fG4TrackIDOffsets[source_index];
119  std::vector<sim::AuxDetIDE> all_ides = it->AuxDetIDEs();
120  for (const sim::AuxDetIDE& ide : simchannel.AuxDetIDEs()) {
121  all_ides.emplace_back(ide, offset);
122 
123  auto tid = std::abs(ide.trackID) + offset;
124 
125  if (tid < range_trackID.first) range_trackID.first = tid;
126  if (tid > range_trackID.second) range_trackID.second = tid;
127  }
128 
129  *it = sim::AuxDetSimChannel(
130  simchannel.AuxDetID(), std::move(all_ides), simchannel.AuxDetSensitiveID());
131  }
132 
133  UpdateG4TrackIDRange(range_trackID, source_index);
134 }
135 
136 void sim::MergeSimSourcesUtility::MergeSimPhotons(std::vector<sim::SimPhotons>& merged_vector,
137  const std::vector<sim::SimPhotons>& input_vector)
138 {
139 
140  merged_vector.reserve(merged_vector.size() + input_vector.size());
141 
142  for (auto const& simphotons : input_vector) {
144  std::find(merged_vector.begin(), merged_vector.end(), simphotons);
145 
146  if (it == merged_vector.end()) {
147  merged_vector.emplace_back(simphotons.OpChannel());
148  it = merged_vector.end() - 1;
149  }
150 
151  *it += simphotons;
152  }
153 }
154 
156  std::vector<sim::SimPhotonsLite>& merged_vector,
157  const std::vector<sim::SimPhotonsLite>& input_vector)
158 {
159 
160  merged_vector.reserve(merged_vector.size() + input_vector.size());
161 
162  for (auto const& simphotons : input_vector) {
164  std::find(merged_vector.begin(), merged_vector.end(), simphotons);
165 
166  if (it == merged_vector.end()) {
167  merged_vector.emplace_back(simphotons.OpChannel);
168  it = merged_vector.end() - 1;
169  }
170 
171  *it += simphotons;
172  }
173 }
174 
176  std::vector<sim::SimEnergyDeposit>& dest,
177  const std::vector<sim::SimEnergyDeposit>& src,
178  std::size_t source_index) const
179 {
180 
181  int const offset = fG4TrackIDOffsets.at(source_index);
182  auto const offsetEDepID = [offset](sim::SimEnergyDeposit const& edep) {
184  };
185 
186  dest.reserve(dest.size() + src.size());
187  std::transform(begin(src), end(src), back_inserter(dest), offsetEDepID);
188 }
189 
190 void sim::MergeSimSourcesUtility::MergeAuxDetHits(std::vector<sim::AuxDetHit>& dest,
191  const std::vector<sim::AuxDetHit>& src,
192  std::size_t source_index) const
193 {
194 
195  int const offset = fG4TrackIDOffsets.at(source_index);
196  auto const offsetAuxDetHitID = [offset](sim::AuxDetHit const& adh) {
198  };
199 
200  dest.reserve(dest.size() + src.size());
201  std::transform(begin(src), end(src), back_inserter(dest), offsetAuxDetHitID);
202 }
203 
205  std::vector<sim::ParticleAncestryMap>& dest,
206  const sim::ParticleAncestryMap& src,
207  std::size_t source_index) const
208 {
209  const int offset = fG4TrackIDOffsets.at(source_index);
210 
211  dest.reserve(dest.size() + 1);
212  dest.push_back(offsetParticleAncestryMapTrackID(src, offset));
213 }
214 
215 void sim::MergeSimSourcesUtility::UpdateG4TrackIDRange(std::pair<int, int> newrange,
216  size_t source_index)
217 {
218  if (source_index >= fG4TrackIDOffsets.size())
219  std::runtime_error("ERROR in MergeSimSourcesUtility: Source index out of range!");
220 
221  if (newrange.first >= fG4TrackIDRanges[source_index].first &&
222  newrange.second <= fG4TrackIDRanges[source_index].second)
223  return;
224 
225  for (size_t i = 0; i < fG4TrackIDRanges.size(); i++) {
226  if (i == source_index) continue;
227 
228  if ((newrange.first >= fG4TrackIDRanges[i].first &&
229  newrange.first <= fG4TrackIDRanges[i].second) ||
230  (newrange.second >= fG4TrackIDRanges[i].first &&
231  newrange.second <= fG4TrackIDRanges[i].second)) {
232  std::stringstream ss;
233  ss << "ERROR in MergeSimSourcesUtility: Source trackIDs overlap!"
234  << "\n\t" << i << "\t" << fG4TrackIDRanges[i].first << " " << fG4TrackIDRanges[i].second
235  << "\n\t"
236  << "n\t" << newrange.first << " " << newrange.second;
237  throw std::runtime_error(ss.str());
238  }
239  }
240 
241  if (newrange.first < fG4TrackIDRanges[source_index].first)
242  fG4TrackIDRanges[source_index].first = newrange.first;
243  if (newrange.second > fG4TrackIDRanges[source_index].second)
244  fG4TrackIDRanges[source_index].second = newrange.second;
245 }
246 
249  int offset)
250 {
251 
252  auto tid = (edep.TrackID() >= 0) ? (edep.TrackID() + offset) : (edep.TrackID() - offset);
253  auto orig_tid =
254  (edep.OrigTrackID() >= 0) ? (edep.OrigTrackID() + offset) : (edep.OrigTrackID() - offset);
255 
256  return sim::SimEnergyDeposit{
257  edep.NumPhotons(), // np
258  edep.NumElectrons(), // ne
259  edep.ScintYieldRatio(), // sy
260  edep.Energy(), // e
261  edep.Start(), // start
262  edep.End(), // end
263  edep.T0(), // t0
264  edep.T1(), // t1
265  tid, // id
266  edep.PdgCode(), // pdg
267  orig_tid // orig id
268  };
269 } // sim::MergeSimSourcesUtility::offsetTrackID()
270 
272  int offset)
273 {
274 
275  auto tid = (adh.GetTrackID() >= 0) ? (adh.GetTrackID() + offset) : (adh.GetTrackID() - offset);
276 
277  return sim::AuxDetHit{
278  adh.GetID(), // copy number
279  tid, // g4 track id
280  adh.GetEnergyDeposited(),
281  adh.GetEntryX(),
282  adh.GetEntryY(),
283  adh.GetEntryZ(),
284  adh.GetEntryT(),
285  adh.GetExitX(),
286  adh.GetExitY(),
287  adh.GetExitZ(),
288  adh.GetExitT(),
289  adh.GetExitMomentumX(),
290  adh.GetExitMomentumY(),
291  adh.GetExitMomentumZ(),
292  };
293 } // sim::MergeSimSourcesUtility::offsetAuxDetHitTrackID()
294 
296  sim::ParticleAncestryMap const& pam,
297  int offset)
298 {
299  std::map<int, std::set<int>> newMap;
300 
301  for (auto const& [ancestor, descendants] : pam.GetMap()) {
302  const int newAnc = (ancestor >= 0) ? ancestor + offset : ancestor - offset;
303 
304  for (auto const& descendant : descendants) {
305  const int newDesc = (descendant >= 0) ? descendant + offset : descendant - offset;
306  newMap[newAnc].insert(newDesc);
307  }
308  }
309 
310  return sim::ParticleAncestryMap(newMap);
311 }
intermediate_table::iterator iterator
unsigned int GetTrackID() const
Definition: AuxDetHit.h:119
void MergeSimPhotonsLite(std::vector< sim::SimPhotonsLite > &, const std::vector< sim::SimPhotonsLite > &)
std::vector< std::pair< int, int > > fG4TrackIDRanges
void MergeSimChannels(std::vector< sim::SimChannel > &, const std::vector< sim::SimChannel > &, size_t)
void UpdateG4TrackIDRange(std::pair< int, int >, size_t)
float GetExitX() const
Definition: AuxDetHit.h:95
static sim::ParticleAncestryMap offsetParticleAncestryMapTrackID(sim::ParticleAncestryMap const &, int)
MergeSimSourcesUtility(std::vector< int > const &)
void MergeSimPhotons(std::vector< sim::SimPhotons > &, const std::vector< sim::SimPhotons > &)
constexpr auto abs(T v)
Returns the absolute value of the argument.
static sim::SimEnergyDeposit offsetSimEnergyDepositTrackID(sim::SimEnergyDeposit const &, int)
void MergeAuxDetSimChannels(std::vector< sim::AuxDetSimChannel > &, const std::vector< sim::AuxDetSimChannel > &, size_t)
float GetExitMomentumY() const
Definition: AuxDetHit.h:75
void MergeAuxDetHits(std::vector< sim::AuxDetHit > &, const std::vector< sim::AuxDetHit > &, size_t) const
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
Collection of particles crossing one auxiliary detector cell.
geo::Point_t Start() const
geo::Point_t End() const
std::vector< int > fG4TrackIDOffsets
float GetEntryX() const
Definition: AuxDetHit.h:111
float GetExitT() const
Definition: AuxDetHit.h:83
float GetEntryT() const
Definition: AuxDetHit.h:99
float GetEnergyDeposited() const
Definition: AuxDetHit.h:115
Double_t edep
Definition: macro.C:13
void MergeParticleAncestryMaps(std::vector< sim::ParticleAncestryMap > &, const sim::ParticleAncestryMap &, size_t) const
unsigned int GetID() const
Definition: AuxDetHit.h:123
float GetExitY() const
Definition: AuxDetHit.h:91
void MergeMCParticles(std::vector< simb::MCParticle > &, const std::vector< simb::MCParticle > &, size_t)
float GetExitMomentumX() const
Definition: AuxDetHit.h:79
float GetEntryZ() const
Definition: AuxDetHit.h:103
float GetExitZ() const
Definition: AuxDetHit.h:87
MC truth information to make RawDigits and do back tracking.
static sim::AuxDetHit offsetAuxDetHitTrackID(sim::AuxDetHit const &, int)
Energy deposition in the active material.
void MergeSimEnergyDeposits(std::vector< sim::SimEnergyDeposit > &, const std::vector< sim::SimEnergyDeposit > &, size_t) const
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
double Energy() const
float GetExitMomentumZ() const
Definition: AuxDetHit.h:71
double ScintYieldRatio() const
std::map< int, std::set< int > > const & GetMap() const
std::vector< std::vector< size_t > > fMCParticleListMap
float GetEntryY() const
Definition: AuxDetHit.h:107