LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
MCShowerRecoAlg.cxx
Go to the documentation of this file.
1 //
3 // MCShowerRecoAlg source
4 //
5 //
7 
8 #include "MCShowerRecoAlg.h"
9 
10 #include "RtypesCore.h"
11 #include "TLorentzVector.h"
12 #include "TMath.h"
13 #include "TString.h"
14 #include "TVector3.h"
15 
18 #include "fhiclcpp/ParameterSet.h"
19 
28 
29 #include <memory>
30 #include <vector>
31 
32 namespace sim {
33 
34  //##################################################################
36  : fPartAlg(pset.get<fhicl::ParameterSet>("MCShowerRecoPart"))
37  , fDebugMode(pset.get<bool>("DebugMode"))
38  , fMinShowerEnergy(pset.get<double>("MinShowerEnergy"))
39  , fMinNumDaughters(pset.get<unsigned int>("MinNumDaughters"))
40  //##################################################################
41  {}
42 
43  std::unique_ptr<std::vector<sim::MCShower>> MCShowerRecoAlg::Reconstruct(MCRecoPart& part_v,
44  MCRecoEdep& edep_v)
45  {
46 
48 
49  auto pindex = details::createPlaneIndexMap();
50 
51  fPartAlg.ConstructShower(part_v);
52  auto result = std::make_unique<std::vector<sim::MCShower>>();
53  auto& mcshower = *result;
54  //std::vector<sim::MCShower> mcshower;
55  // Get shower info from grouped particles
56  const std::vector<unsigned int> shower_index_v = fPartAlg.ShowerMothers();
57  mcshower.reserve(shower_index_v.size());
58  std::vector<size_t> mcs_to_spart_v;
59  mcs_to_spart_v.reserve(shower_index_v.size());
60 
61  bool daughter_stored = false;
62  for (size_t shower_index = 0; shower_index < shower_index_v.size(); ++shower_index) {
63 
64  unsigned int shower_candidate = shower_index_v.at(shower_index);
65  auto const& shower_part = part_v.at(shower_candidate);
66 
67  unsigned int mother_track = part_v.MotherTrackID(shower_candidate);
68  unsigned int ancestor_track = part_v.AncestorTrackID(shower_candidate);
69 
70  if (mother_track == kINVALID_UINT || ancestor_track == kINVALID_UINT)
71 
72  throw cet::exception(__FUNCTION__) << "LOGIC ERROR: mother/ancestor track ID is invalid!";
73 
74  MCMiniPart mother_part;
75  MCMiniPart ancestor_part;
76 
77  unsigned int mother_index = part_v.TrackToParticleIndex(mother_track);
78  unsigned int ancestor_index = part_v.TrackToParticleIndex(ancestor_track);
79 
80  if (mother_index != kINVALID_UINT)
81  mother_part = part_v[mother_index];
82  else
83  mother_part._track_id = mother_track;
84 
85  if (ancestor_index != kINVALID_UINT)
86  ancestor_part = part_v[ancestor_index];
87  else
88  ancestor_part._track_id = ancestor_track;
89 
90  double shower_g4_energy = shower_part._start_mom[3];
91 
92  if (fDebugMode)
93 
94  std::cout << "Found MCShower with mother energy: " << shower_g4_energy << " MeV";
95 
96  // Skip if mother energy is less than the enery threshold
97  if (shower_g4_energy < fMinShowerEnergy) {
98  if (fDebugMode) std::cout << " ... below energy threshold: skipping!" << std::endl;
99 
100  continue;
101  }
102  else if (shower_part._daughters.size() < fMinNumDaughters) {
103  if (fDebugMode)
104  std::cout << " ... below # daughter particle count threshold: skipping!" << std::endl;
105 
106  continue;
107  }
108  else if (fDebugMode) {
109  std::cout << " ... condition matched. Storing this MCShower..." << std::endl;
110  }
111 
112  // Record this MCShower
113  mcs_to_spart_v.push_back(shower_index);
114 
115  if (fDebugMode)
116 
117  std::cout << " Storage index " << mcshower.size() << " => Shower index " << shower_index
118  << std::endl;
119 
120  ::sim::MCShower shower_prof;
121 
122  shower_prof.Origin(shower_part._origin);
123  shower_prof.PdgCode(shower_part._pdgcode);
124  shower_prof.TrackID(shower_part._track_id);
125  shower_prof.Process(shower_part._process);
126 
127  shower_prof.MotherPdgCode(mother_part._pdgcode);
128  shower_prof.MotherTrackID(mother_part._track_id);
129  shower_prof.MotherProcess(mother_part._process);
130 
131  shower_prof.AncestorPdgCode(ancestor_part._pdgcode);
132  shower_prof.AncestorTrackID(ancestor_part._track_id);
133  shower_prof.AncestorProcess(ancestor_part._process);
134 
135  shower_prof.Start(MCStep(shower_part._start_vtx, shower_part._start_mom));
136  shower_prof.End(MCStep(shower_part._end_vtx, shower_part._end_mom));
137  shower_prof.MotherStart(MCStep(mother_part._start_vtx, mother_part._start_mom));
138  shower_prof.MotherEnd(MCStep(mother_part._end_vtx, mother_part._end_mom));
139  shower_prof.AncestorStart(MCStep(ancestor_part._start_vtx, ancestor_part._start_mom));
140  shower_prof.AncestorEnd(MCStep(ancestor_part._end_vtx, ancestor_part._end_mom));
141 
142  // Daughter list
143  std::vector<unsigned int> daughter_track_id;
144  daughter_track_id.reserve(fPartAlg.ShowerDaughters(shower_index).size());
145 
146  for (auto const& index : fPartAlg.ShowerDaughters(shower_index))
147 
148  daughter_track_id.push_back(part_v.at(index)._track_id);
149 
150  shower_prof.DaughterTrackID(daughter_track_id);
151 
152  if (!daughter_stored && daughter_track_id.size() > 1) daughter_stored = true;
153 
154  mcshower.push_back(shower_prof);
155  }
156 
157  if (fDebugMode)
158  std::cout << " Found " << mcshower.size()
159  << " MCShowers. Now computing DetProfile position..." << std::endl;
160 
161  //
162  // Daughter vtx
163  //
164  std::vector<TLorentzVector> mcs_daughter_vtx_v(
165  mcshower.size(),
166  TLorentzVector(
168  std::vector<TLorentzVector> mcs_daughter_mom_v(mcshower.size(), TLorentzVector());
169 
170  std::vector<std::vector<double>> plane_charge_v(mcshower.size(), std::vector<double>(3, 0));
171  std::vector<std::vector<double>> plane_dqdx_v(mcshower.size(), std::vector<double>(3, 0));
172 
173  //For dEdx Calculation
174  std::vector<double> mcs_daughter_dedx_v(mcshower.size(), 0);
175  std::vector<double> mcs_daughter_dedxRAD_v(mcshower.size(), 0);
176  std::vector<TVector3> mcs_daughter_dir_v(mcshower.size(), TVector3());
177 
178  for (size_t mcs_index = 0; mcs_index < mcshower.size(); ++mcs_index) {
179 
180  auto& mcs_daughter_vtx = mcs_daughter_vtx_v[mcs_index];
181  auto& mcs_daughter_mom = mcs_daughter_mom_v[mcs_index];
182  auto& mcs_daughter_dedx = mcs_daughter_dedx_v[mcs_index];
183  auto& mcs_daughter_dedxRAD = mcs_daughter_dedxRAD_v[mcs_index];
184  auto& mcs_daughter_dir = mcs_daughter_dir_v[mcs_index];
185  auto& plane_charge = plane_charge_v[mcs_index];
186  auto& plane_dqdx = plane_dqdx_v[mcs_index];
187 
188  for (auto const& daughter_trk_id : mcshower[mcs_index].DaughterTrackID()) {
189 
190  auto const daughter_part_index = part_v.TrackToParticleIndex(daughter_trk_id);
191 
192  auto const& daughter_part = part_v[daughter_part_index];
193 
194  auto const daughter_edep_index = edep_v.TrackToEdepIndex(daughter_trk_id);
195 
196  if (daughter_edep_index < 0) continue;
197 
198  auto const& daughter_edep = edep_v.GetEdepArrayAt(daughter_edep_index);
199 
200  if (!(daughter_edep.size())) continue;
201 
202  // Record first daughter's vtx point
203  double min_dist = sim::kINVALID_DOUBLE;
204  for (auto const& edep : daughter_edep) {
205 
206  double dist = sqrt(pow(edep.pos._x - daughter_part._start_vtx[0], 2) +
207  pow(edep.pos._y - daughter_part._start_vtx[1], 2) +
208  pow(edep.pos._z - daughter_part._start_vtx[2], 2));
209 
210  if (dist < min_dist) {
211  min_dist = dist;
212  mcs_daughter_vtx[0] = edep.pos._x;
213  mcs_daughter_vtx[1] = edep.pos._y;
214  mcs_daughter_vtx[2] = edep.pos._z;
215  mcs_daughter_vtx[3] = (dist / 100. / 2.998e8) * 1.e9 + daughter_part._start_vtx[3];
216  }
217  }
218  if (!daughter_stored) {
219  // If daughter is not stored, and shower id energetic enough, attempt to include angle info
220  std::vector<double> shower_dir(3, 0);
221  shower_dir[0] = mcshower[mcs_index].Start().Px();
222  shower_dir[1] = mcshower[mcs_index].Start().Py();
223  shower_dir[2] = mcshower[mcs_index].Start().Pz();
224  double magnitude = 0;
225  for (size_t i = 0; i < 3; ++i)
226  magnitude += pow(shower_dir[i], 2);
227 
228  magnitude = sqrt(magnitude);
229 
230  if (magnitude > 1.e-10) {
231  // If enough momentum, include angle info
232  min_dist = sim::kINVALID_DOUBLE;
233 
234  for (auto& v : shower_dir)
235  v /= magnitude;
236 
237  for (auto const& edep : daughter_edep) {
238  std::vector<double> shower_dep_dir(3, 0);
239  shower_dep_dir[0] = edep.pos._x - mcshower[mcs_index].Start().X();
240  shower_dep_dir[1] = edep.pos._y - mcshower[mcs_index].Start().Y();
241  shower_dep_dir[2] = edep.pos._z - mcshower[mcs_index].Start().Z();
242 
243  double dist = sqrt(pow(shower_dep_dir[0], 2) + pow(shower_dep_dir[1], 2) +
244  pow(shower_dep_dir[2], 2));
245  for (auto& v : shower_dep_dir)
246  v /= dist;
247 
248  double angle =
249  acos(shower_dep_dir[0] * shower_dir[0] + shower_dep_dir[1] * shower_dir[1] +
250  shower_dep_dir[2] * shower_dir[2]) /
251  TMath::Pi() * 180.;
252 
253  if (dist < min_dist && angle < 10) {
254 
255  min_dist = dist;
256  mcs_daughter_vtx[0] = edep.pos._x;
257  mcs_daughter_vtx[1] = edep.pos._y;
258  mcs_daughter_vtx[2] = edep.pos._z;
259  mcs_daughter_vtx[3] =
260  (dist / 100. / 2.998e8) * 1.e9 + mcshower[mcs_index].Start().T();
261  }
262  }
263  }
264  }
265  break;
266  }
267  // Now take care of momentum & plane charge
268 
269  std::vector<double> mom(3, 0);
270  for (auto const& daughter_trk_id : mcshower[mcs_index].DaughterTrackID()) {
271 
272  //auto const daughter_part_index = part_v.TrackToParticleIndex(daughter_trk_id);
273 
274  // for c2: daughter_part is unused
275  //auto const& daughter_part = part_v[daughter_part_index];
276 
277  auto const daughter_edep_index = edep_v.TrackToEdepIndex(daughter_trk_id);
278 
279  if (daughter_edep_index < 0) continue;
280 
281  auto const& daughter_edep = edep_v.GetEdepArrayAt(daughter_edep_index);
282 
283  if (!(daughter_edep.size())) continue;
284 
285  //bool first=true; // unused
286  for (auto const& edep : daughter_edep) {
287 
288  // Compute unit vector to this energy deposition
289  mom[0] = edep.pos._x - mcs_daughter_vtx[0];
290  mom[1] = edep.pos._y - mcs_daughter_vtx[1];
291  mom[2] = edep.pos._z - mcs_daughter_vtx[2];
292 
293  // Weight by energy (momentum)
294  double magnitude = sqrt(pow(mom.at(0), 2) + pow(mom.at(1), 2) + pow(mom.at(2), 2));
295 
296  double energy = 0;
297  double npid = 0;
298  for (auto const& pid_energy : edep.deps) {
299  npid++;
300  energy += pid_energy.energy;
301  }
302  energy /= npid;
303  if (magnitude > 1.e-10) {
304  mom.at(0) = mom.at(0) * energy / magnitude;
305  mom.at(1) = mom.at(1) * energy / magnitude;
306  mom.at(2) = mom.at(2) * energy / magnitude;
307  mcs_daughter_mom[0] += mom.at(0);
308  mcs_daughter_mom[1] += mom.at(1);
309  mcs_daughter_mom[2] += mom.at(2);
310  }
311  //Determine the direction of the shower right at the start point
312  double E = 0;
313  double N = 0;
314  if (sqrt(pow(edep.pos._x - mcs_daughter_vtx[0], 2) +
315  pow(edep.pos._y - mcs_daughter_vtx[1], 2) +
316  pow(edep.pos._z - mcs_daughter_vtx[2], 2)) < 2.4 &&
317  magnitude > 1.e-10) {
318 
319  mcs_daughter_dir[0] += mom.at(0);
320  mcs_daughter_dir[1] += mom.at(1);
321  mcs_daughter_dir[2] += mom.at(2);
322  E += energy;
323  N += 1;
324  }
325 
326  if (E > 0) E /= N;
327  mcs_daughter_dedxRAD += E;
328 
329  mcs_daughter_mom[3] += energy;
330 
331  // Charge
332  auto const pid = edep.pid;
333  auto q_i = pindex.find(pid);
334  if (q_i != pindex.end())
335  plane_charge[pid.Plane] += (double)(edep.deps[pindex[pid]].charge);
336 
337  }
338 
339  }
340  mcs_daughter_dedxRAD /= 2.4;
341 
342  for (auto const& daughter_trk_id : mcshower[mcs_index].DaughterTrackID()) {
343 
344  //auto const daughter_part_index = part_v.TrackToParticleIndex(daughter_trk_id);
345 
346  // for c2: daughter_part is unused
347  //auto const& daughter_part = part_v[daughter_part_index];
348 
349  auto const daughter_edep_index = edep_v.TrackToEdepIndex(daughter_trk_id);
350 
351  if (daughter_edep_index < 0) continue;
352 
353  auto const& daughter_edep = edep_v.GetEdepArrayAt(daughter_edep_index);
354 
355  if (!(daughter_edep.size())) continue;
356 
357  for (auto const& edep : daughter_edep) {
358 
359  //Defining dEdx
360  //Need to define a plane through the shower start point (x_0, y_0, z_0) with a normal along the momentum vector of the shower
361  //The plane will be defined in the typical way:
362  // a*x + b*y + c*z + d = 0
363  // where, a = dir_x, b = dir_y, c = dir_z, d = - (a*x_0+b*y_0+c*z_0)
364  // then the *signed* distance of any point (x_1, y_1, z_1) from this plane is:
365  // D = (a*x_1 + b*y_1 + c*z_1 + d )/sqrt( pow(a,2) + pow(b,2) + pow(c,2))
366 
367  double p_mag = sqrt(pow(mcs_daughter_dir[0], 2) + pow(mcs_daughter_dir[1], 2) +
368  pow(mcs_daughter_dir[2], 2));
369  double a = 0, b = 0, c = 0, d = 0;
370  if (p_mag > 1.e-10) {
371  a = mcs_daughter_dir[0] / p_mag;
372  b = mcs_daughter_dir[1] / p_mag;
373  c = mcs_daughter_dir[2] / p_mag;
374  d = -1 * (a * mcs_daughter_vtx[0] + b * mcs_daughter_vtx[1] + c * mcs_daughter_vtx[2]);
375  }
376  else {
377  mcs_daughter_dedx += 0;
378  continue;
379  }
380  //Radial Distance
381  if ((a * edep.pos._x + b * edep.pos._y + c * edep.pos._z + d) /
382  sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2)) <
383  2.4 &&
384  (a * edep.pos._x + b * edep.pos._y + c * edep.pos._z + d) /
385  sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2)) >
386  0) {
387 
388  double E = 0;
389  double N = 0;
390 
391  for (auto const& pid_energy : edep.deps) {
392  N += 1;
393  E += pid_energy.energy;
394  }
395 
396  if (N > 0) { E /= N; }
397  else {
398  E = 0;
399  }
400 
401  mcs_daughter_dedx += E;
402 
403  // Charge
404  auto const pid = edep.pid;
405  auto q_i = pindex.find(pid);
406  if (q_i != pindex.end())
407  plane_dqdx[pid.Plane] += (double)(edep.deps[pindex[pid]].charge);
408  }
409  }
410  }
411  mcs_daughter_dedx /= 2.4;
412  plane_dqdx.at(0) /= 2.4;
413  plane_dqdx.at(1) /= 2.4;
414  plane_dqdx.at(2) /= 2.4;
415 
416  }
417 
418  if (fDebugMode)
419  std::cout << " Found " << mcshower.size() << " MCShowers. Now storing..." << std::endl;
420 
421  // Store plane charge & daughter momentum
422  for (size_t mcs_index = 0; mcs_index < mcshower.size(); ++mcs_index) {
423 
424  auto& daughter_vtx = mcs_daughter_vtx_v[mcs_index];
425  auto& daughter_mom = mcs_daughter_mom_v[mcs_index];
426  auto& daughter_dedx = mcs_daughter_dedx_v[mcs_index];
427  auto& daughter_dedxRAD = mcs_daughter_dedxRAD_v[mcs_index];
428  auto& daughter_dir = mcs_daughter_dir_v[mcs_index];
429  auto& plane_charge = plane_charge_v[mcs_index];
430  auto& plane_dqdx = plane_dqdx_v[mcs_index];
431 
432  double magnitude =
433  sqrt(pow(daughter_mom[0], 2) + pow(daughter_mom[1], 2) + pow(daughter_mom[2], 2));
434 
435  if (daughter_mom[3] > 1.e-10) {
436  daughter_mom[0] *= daughter_mom[3] / magnitude;
437  daughter_mom[1] *= daughter_mom[3] / magnitude;
438  daughter_mom[2] *= daughter_mom[3] / magnitude;
439  }
440  else
441  for (size_t i = 0; i < 4; ++i)
442  daughter_mom[i] = 0;
443 
444  mcshower.at(mcs_index).DetProfile(MCStep(daughter_vtx, daughter_mom));
445  mcshower.at(mcs_index).Charge(plane_charge);
446  mcshower.at(mcs_index).dQdx(plane_dqdx);
447  mcshower.at(mcs_index).dEdx(daughter_dedx);
448  mcshower.at(mcs_index).dEdxRAD(daughter_dedxRAD);
449  mcshower.at(mcs_index).StartDir(daughter_dir);
450  }
451 
452  if (fDebugMode) {
453 
454  for (auto const& prof : mcshower) {
455 
456  std::cout
457 
458  << Form(" Shower particle: PDG=%d : Track ID=%d Start @ (%g,%g,%g,%g) with Momentum "
459  "(%g,%g,%g,%g)",
460  prof.PdgCode(),
461  prof.TrackID(),
462  prof.Start().X(),
463  prof.Start().Y(),
464  prof.Start().Z(),
465  prof.Start().T(),
466  prof.Start().Px(),
467  prof.Start().Py(),
468  prof.Start().Pz(),
469  prof.Start().E())
470  << std::endl
471  << Form(" Mother particle: PDG=%d : Track ID=%d Start @ (%g,%g,%g,%g) with Momentum "
472  "(%g,%g,%g,%g)",
473  prof.MotherPdgCode(),
474  prof.MotherTrackID(),
475  prof.MotherStart().X(),
476  prof.MotherStart().Y(),
477  prof.MotherStart().Z(),
478  prof.MotherStart().T(),
479  prof.MotherStart().Px(),
480  prof.MotherStart().Py(),
481  prof.MotherStart().Pz(),
482  prof.MotherStart().E())
483  << std::endl
484  << Form(" Ancestor particle: PDG=%d : Track ID=%d Start @ (%g,%g,%g,%g) with Momentum "
485  "(%g,%g,%g,%g)",
486  prof.AncestorPdgCode(),
487  prof.AncestorTrackID(),
488  prof.AncestorStart().X(),
489  prof.AncestorStart().Y(),
490  prof.AncestorStart().Z(),
491  prof.AncestorStart().T(),
492  prof.AncestorStart().Px(),
493  prof.AncestorStart().Py(),
494  prof.AncestorStart().Pz(),
495  prof.AncestorStart().E())
496  << std::endl
497  << Form(" ... with %zu daughters: Start @ (%g,%g,%g,%g) with Momentum (%g,%g,%g,%g)",
498  prof.DaughterTrackID().size(),
499  prof.DetProfile().X(),
500  prof.DetProfile().Y(),
501  prof.DetProfile().Z(),
502  prof.DetProfile().T(),
503  prof.DetProfile().Px(),
504  prof.DetProfile().Py(),
505  prof.DetProfile().Pz(),
506  prof.DetProfile().E())
507  << std::endl
508  << " Charge per plane: ";
509  size_t const nPlanes = prof.Charge().size();
510  for (size_t i = 0; i < nPlanes; ++i) {
511 
512  std::cout << " | Plane " << i << std::flush;
513  std::cout << " ... Q = " << prof.Charge(i) << std::flush;
514  }
515  std::cout << std::endl << std::endl;
516  }
517  }
518  return result;
519  }
520 }
std::string _process
Definition: MCRecoPart.h:31
const double kINVALID_DOUBLE
Definition: MCLimits.h:10
const MCStep & End() const
Definition: MCShower.h:54
unsigned int TrackID() const
Definition: MCShower.h:51
MCShowerRecoAlg(fhicl::ParameterSet const &pset)
Default constructor with fhicl parameters.
const std::vector< unsigned int > ShowerMothers() const
MCShowerRecoPart fPartAlg
std::unique_ptr< std::vector< sim::MCShower > > Reconstruct(MCRecoPart &part_v, MCRecoEdep &edep_v)
std::map< geo::PlaneID, size_t > createPlaneIndexMap()
Definition: MCRecoEdep.cxx:26
int PdgCode() const
Definition: MCShower.h:50
unsigned int MotherTrackID(const unsigned int part_index) const
Definition: MCRecoPart.cxx:50
const std::vector< sim::MCEdep > & GetEdepArrayAt(size_t edep_index) const
Returns a vector of MCEdep object at the given index.
Definition: MCRecoEdep.cxx:47
TLorentzVector _start_vtx
Definition: MCRecoPart.h:35
Class def header for mcstep data container.
unsigned int fMinNumDaughters
TLorentzVector _start_mom
Definition: MCRecoPart.h:36
const std::vector< unsigned int > & DaughterTrackID() const
Definition: MCShower.h:70
unsigned int AncestorTrackID(const unsigned int part_index)
Definition: MCRecoPart.cxx:76
simb::Origin_t Origin() const
Definition: MCShower.h:48
int TrackToEdepIndex(unsigned int track_id) const
Converts a track ID to MCEdep array index. Returns -1 if no corresponding array found ...
Definition: MCRecoEdep.h:113
int MotherPdgCode() const
Definition: MCShower.h:56
const std::string & AncestorProcess() const
Definition: MCShower.h:64
Float_t E
Definition: plot.C:20
TLorentzVector _end_mom
Definition: MCRecoPart.h:38
parameter set interface
double energy
Definition: plottest35.C:25
Float_t d
Definition: plot.C:235
TLorentzVector _end_vtx
Definition: MCRecoPart.h:37
const MCStep & AncestorStart() const
Definition: MCShower.h:65
Double_t edep
Definition: macro.C:13
const std::string & MotherProcess() const
Definition: MCShower.h:58
Monte Carlo Simulation.
Definition of data types for geometry description.
const std::vector< unsigned int > & ShowerDaughters(const unsigned int shower_id) const
unsigned int AncestorTrackID() const
Definition: MCShower.h:63
const MCStep & AncestorEnd() const
Definition: MCShower.h:66
const MCStep & Start() const
Definition: MCShower.h:53
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
const MCStep & MotherEnd() const
Definition: MCShower.h:60
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Class def header for MCShower data container.
const unsigned int kINVALID_UINT
Definition: MCLimits.h:14
unsigned int MotherTrackID() const
Definition: MCShower.h:57
const std::string & Process() const
Definition: MCShower.h:52
const MCStep & MotherStart() const
Definition: MCShower.h:59
unsigned int _track_id
Definition: MCRecoPart.h:30
int AncestorPdgCode() const
Definition: MCShower.h:62
Float_t e
Definition: plot.C:35
Namespace collecting geometry-related classes utilities.
unsigned int TrackToParticleIndex(const unsigned int track_id) const
Definition: MCRecoPart.h:112
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void ConstructShower(const MCRecoPart &part_v)
Main function to read-in data and fill variables in this algorithm to reconstruct MC shower...