MergeG4Collections_module.cc
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 // \file MergeG4Collections.cxx
3 // \brief
4 // \authors janow@fnal.gov jmusser@indiana.edu
5 ///////////////////////////////////////////////////////////////////////////
6 #include <math.h>
7 #include <string>
8 
16 #include "fhiclcpp/ParameterSet.h"
18 
19 #include "DAQChannelMap/DAQChannelMap.h"
23 
24 #include "Simulation/FLSHit.h"
25 #include "Simulation/FLSHitList.h"
26 #include "Simulation/Particle.h"
27 #include "Simulation/TrueEnergy.h"
28 #include "Utilities/AssociationUtil.h"
29 
30 
31 ///group hits according to time and space
33 {
35  public:
36 
37  explicit MergeG4Collections(fhicl::ParameterSet const &pset);
38  virtual ~MergeG4Collections();
39 
40  void produce(art::Event& evt);
41 
42  protected:
43 
44  // configuration settings
45  std::string fFirstGenCollection; /// MCTruth main collection label
46  std::string fFirstGenProcessLabel; /// MCTruth process main collection label
47  std::string fFirstG4Collection; /// Geant4 main collection label
49 
50  std::string fMixedGenCollection; /// MCTruth mixed collection label
52 
53  std::string fSecondCollection; /// Label for the mixing module
54 
55  bool ParticleIsInMCTruth(simb::MCParticle part, art::Ptr<simb::MCTruth> mct);
56  bool SameMCTruth(art::Ptr<simb::MCTruth> mct1, art::Ptr<simb::MCTruth> mct2);
57  };
58 
59 
60  //----------------------------------------------------------------------
62  fFirstGenCollection (pset.get< std::string >("FirstGenCollection")),
63  fFirstGenProcessLabel (pset.get< std::string >("FirstGenProcessLabel")),
64  fFirstG4Collection (pset.get< std::string >("FirstG4Collection")),
65  fIsFirstCollectionCosmic(pset.get< bool >("IsFirstCollectionCosmic")),
66  fMixedGenCollection (pset.get< std::string >("ThirdGenCollection")),
67  fMixerProcessLabel (pset.get< std::string >("ThirdCollection")),
68  fSecondCollection (pset.get< std::string >("SecondCollection"))
69  {
70  produces< std::vector<sim::FLSHitList > >();
71  produces< std::vector<sim::Particle> >();
72  produces< std::vector<sim::TrueEnergy> >();
73  produces< art::Assns <sim::Particle , simb::MCTruth> >();
74  produces< art::Assns <sim::TrueEnergy, sim::Particle> >();
75 
76  /*
77  if( fFirstGenCollection == "" ||
78  fFirstGenProcessLabel == "" ||
79  fFirstG4Collection == "" ){
80  std::cerr << "MergeG4Collections: "
81  << "First Collection labels not completely specified. Abort"
82  << std::endl;
83  std::abort();
84  }
85  */
86  if( fMixedGenCollection == "" ||
87  fMixerProcessLabel == "" ){
88  std::cerr << "MergeG4Collections: "
89  << "Mixed Gen Collection labels not completely specified. Abort"
90  << std::endl;
91  std::abort();
92  }
93  }
94 
95  //----------------------------------------------------------------------
96  MergeG4Collections::~MergeG4Collections()
97  {
98  }
99 
100  //----------------------------------------------------------------------
101  void MergeG4Collections::produce(art::Event& evt)
102  {
103 
104  std::unique_ptr< std::vector<sim::FLSHitList> > outFLSHitLists (new std::vector<sim::FLSHitList>);
105  std::unique_ptr< std::vector<sim::Particle > > tempParticles (new std::vector<sim::Particle >);
106  std::unique_ptr< std::vector<sim::Particle > > outParticles (new std::vector<sim::Particle >);
107  std::unique_ptr< std::vector<sim::TrueEnergy> > tempTrueEnergy (new std::vector<sim::TrueEnergy>);
108  std::unique_ptr< std::vector<sim::TrueEnergy> > outTrueEnergy (new std::vector<sim::TrueEnergy>);
109 
110  std::unique_ptr< art::Assns <sim::Particle , simb::MCTruth> > outMCTruthPartAssn(new art::Assns<sim::Particle , simb::MCTruth>);
111  std::unique_ptr< art::Assns <sim::TrueEnergy, sim::Particle> > outTrueEnPartAssn (new art::Assns<sim::TrueEnergy, sim::Particle>);
112 
113  // Push particles from primary collection onto merged collection.
114  // Find largest TrackId that will be used to seed trackID offsets in
115  // secondary file collections.
116  // Particles are pushed onto outParticles, which will hold
117  // combination of primary and secondary streams
118  int IdOffset = 0;
119  int MCListIndex = -1;
120 
121 
122  //// ***** Mixed Collection *****
123  //
124  art::InputTag mixedGenTag(fMixedGenCollection,"",fMixerProcessLabel);
126  evt.getByLabel(mixedGenTag, mixedMCTruths);
127 
128 
129  //// ***** First (primary) Collection *****
130  //
131  if( fFirstGenCollection != "" &&
132  fFirstGenProcessLabel != "" &&
133  fFirstG4Collection != "" ){
134 
135  art::InputTag firstGenTag(fFirstGenCollection,"",fFirstGenProcessLabel);
137  evt.getByLabel(firstGenTag, firstMCTruths);
139  evt.getByLabel(fFirstG4Collection, firstFLSHitLists);
141  evt.getByLabel(fFirstG4Collection, firstParticles);
142 
143  art::FindOneP<simb::MCTruth> MCTruthForParticle( firstParticles, evt,
144  fFirstG4Collection );
145 
146  // sim::TrueEnergy.
147  art::Handle< std::vector<sim::TrueEnergy> > firstTrueEnergies;
148  evt.getByLabel(fFirstG4Collection, firstTrueEnergies);
149  art::FindManyP<sim::TrueEnergy> TrueEnergyAssn(firstParticles, evt, fFirstG4Collection );
150 
151  // For each first-collection particle,
152  for(unsigned int i = 0; i < firstParticles->size(); ++i){
153  sim::Particle part ((*firstParticles)[i]);
154  outParticles->push_back(part);
155  int parTrId = part.TrackId();
156  bool match_truep = false;
157  for(size_t te = 0; te < TrueEnergyAssn.at(i).size(); ++te){
158  if (parTrId == TrueEnergyAssn.at(i)[te]->TrackId()) {
159  match_truep = true;
160  outTrueEnergy->push_back(*TrueEnergyAssn.at(i)[te]);
161  }
162  }
163  if (!match_truep) {
164  for(size_t par2 = 0; par2 < firstParticles->size(); ++par2){
165  for(size_t te = 0; te < TrueEnergyAssn.at(par2).size(); ++te){
166  if (parTrId == TrueEnergyAssn.at(par2)[te]->TrackId()) {
167  match_truep = true;
168  outTrueEnergy->push_back(*TrueEnergyAssn.at(par2)[te]);
169  }
170  if (match_truep) break;
171  }
172  if (match_truep) break;
173  }
174  //AS IN PREVIOUS VERSION, NEED AN ASSN SO STORE A JUNK VALUE FOR THAT PARTICLE.
175  if(!match_truep){
176  outTrueEnergy->push_back( sim::TrueEnergy(parTrId, -5, -5, -5, -5) );
177  }
178  }
179 
180  util::CreateAssn( *this, evt, *outTrueEnPartAssn, *outTrueEnergy, *outParticles, i, (outParticles->size()-1) );
181 
182  // motherID==0 means new MCTruth
183  if(part.Mother() == 0)
184  MCListIndex++;
185 
186  // incriment TrackId offset
187  if(part.TrackId() > IdOffset) IdOffset = part.TrackId();
188  for(int d = 0; d < part.NumberDaughters(); d++)
189  if(part.Daughter(d) > IdOffset)
190  IdOffset = part.Daughter(d);
191 
192  // Find the MCTruth to associate with this particle.
193  // Since the primary file particle list still has an intact MCTruth
194  // association, we can use a simple check on equality of
195  // a set of member variables to find this same MCTruth on the merged
196  // collection (mixedMCTruths)
197 
198  art::Ptr<simb::MCTruth> mct = MCTruthForParticle.at(i);
199 
200 
201  if(fIsFirstCollectionCosmic){
202  // Assume 1 MCTruth per Particle
203  art::Ptr<simb::MCTruth> mcptr(mixedMCTruths,MCListIndex);
204  util::CreateAssn(*this, evt, *outParticles, mcptr ,
205  *outMCTruthPartAssn, outParticles->size() - 1);
206  } else {
207  // Otherwise assume a neutrino
208 
209  bool foundMCT = false;
210  for(unsigned int imc = 0; imc < mixedMCTruths->size(); imc++){
211  art::Ptr<simb::MCTruth> mixed_mct(mixedMCTruths, imc);
212 
213  if( SameMCTruth(mct,mixed_mct) ){
214  // Check that original particle is in this equivalent MCTruth
215  if(part.Mother() == 0 && !ParticleIsInMCTruth(part,mixed_mct))
216  mf::LogWarning("MergeG4Collection")
217  << " !!! possible primary list particle and MCTruth position mismatch !!!";
218 
219  util::CreateAssn(*this, evt, *outParticles, mixed_mct, *outMCTruthPartAssn, outParticles->size() - 1);
220  foundMCT = true;
221  break;
222  }
223  }
224  if(!foundMCT)
225  mf::LogWarning("MergeG4Collection")
226  << "MCTruth to primary collection particle not found";
227  }
228  } // firstParticles loop
229 
230  //Set initial MCListIndex for secondary files
231  if(firstMCTruths->size() > 0) MCListIndex = firstMCTruths->size() - 1;
232 
233 
234  // Save FLSHit list for each MCTruth
235  if(firstMCTruths->size() != firstFLSHitLists->size())
236  mf::LogWarning("MergeG4Collections")
237  << " MC/FLSHitList size mismatch in first collection";
238  for(unsigned int i = 0; i < firstMCTruths->size(); ++i)
239  if(i < firstFLSHitLists->size())
240  outFLSHitLists->push_back((*firstFLSHitLists)[i]);
241 
242  }
243  //
244  //// *** If first collection specified ***
245 
246 
247 
248  //// ***** Secondary Collections *****
249  //
250  if( fSecondCollection!="" ){ // Optionally ignore second collection
251  // (for Data in a Data-MC merge)
252 
253  art::Handle< std::vector<simb::MCTruth> > SecFileMCTruthlistCol;
254  evt.getByLabel(fSecondCollection, SecFileMCTruthlistCol);
255 
256  art::Handle< std::vector<sim::FLSHitList> > SecFileFLSHitlistCol;
257  evt.getByLabel(fSecondCollection, SecFileFLSHitlistCol);
258 
259  if(SecFileMCTruthlistCol->size() != SecFileFLSHitlistCol->size())
260  mf::LogWarning("MergeG4Collections")
261  << " MC/FLSHitList size mismatch in second collection";
262 
263  art::Handle< std::vector<sim::Particle> > SecFileParticlelistCol;
264  evt.getByLabel(fSecondCollection, SecFileParticlelistCol);
265 
266  // sim::TrueEnergy.
267  art::Handle< std::vector<sim::TrueEnergy> > SecFileTrueEnergies;
268  evt.getByLabel(fSecondCollection, SecFileTrueEnergies);
269 
270  int nParticle = 0;
271  int trackIDList[100000]; // used as check of FLSHitList TrackID consistency
272  int LastPartId = 0;
273  int *Offset = new int[1000]; // holds trackID offsets, one/MCTruth
274  int OffsetIndex = 1;
275 
276  for(int i = 0; i < 1000; i++){
277  Offset[i] = 0;
278  }
279  Offset[0] = IdOffset; // TrackID offset for first secondary MCTruth is the largest trackID from primary
280 
281  int MCindex = MCListIndex;
282  if(MCindex < 0) MCindex = 0;
283  bool first = true;
284 
285  // Loop over all secondary file particles, finding the event boundaries.
286  // The MCTruth/Particle matching algorithm is based on looking for a
287  // particle in the MCTruth particle list at the same vertex location
288  // as the particle from SecFileParticlelistCol. If we don't find one,
289  // and the particle's motherID==0 we move to the next MCTruth entry.
290  for(unsigned int i = 0; i < SecFileParticlelistCol->size(); ++i){
291  sim::Particle part ((*SecFileParticlelistCol)[i]); // local copy of this particle
292  art::Ptr<simb::MCTruth> mcptr(mixedMCTruths, MCindex); // grab MCTruth at current index
293  bool partInMCT = ParticleIsInMCTruth(part,mcptr);
294 
295  if((LastPartId >= part.TrackId()) || (part.Mother()==0 && !partInMCT ) ){ // make check on MCTruth/Particle consistency
296  if(!first){
297  Offset[OffsetIndex] = Offset[OffsetIndex-1] + LastPartId; //if here, new particle must be start of next event
298  OffsetIndex++;
299  }
300  if(MCindex+1 < (int)mixedMCTruths->size()) MCindex++;
301  }
302  first = false;
303  LastPartId = part.TrackId();
304 
305  // Construct new particle with offset trackID and add to particle
306  // collection. We must also offset daughters, and motherID
307  // (if motherID is not zero)
308 
309  int partmother = 0;
310  if(part.Mother() != 0)partmother = part.Mother() + Offset[OffsetIndex-1];
311 
312  sim::Particle gpart(part.TrackId() + Offset[OffsetIndex-1],
313  part.PdgCode(),
314  part.Process(),
315  partmother,
316  part.Mass(),
317  part.StatusCode());
318 
319  gpart.SetGvtx(part.Gvx(), part.Gvy(),part.Gvz(),part.Gvt());
320  gpart.SetPolarization(part.Polarization());
321  gpart.SetWeight(part.Weight());
322  gpart.SetRescatter(part.Rescatter());
323  for(int d = 0; d < part.NumberDaughters(); d++){
324  gpart.AddDaughter(part.Daughter(d) + Offset[OffsetIndex-1]);
325  }
326  for(unsigned int t = 0; t < part.NumberTrajectoryPoints(); t++){
327  gpart.AddTrajectoryPoint(part.Position(t), part.Momentum(t));
328  }
329  tempParticles->push_back(gpart);
330 
331  // sim::TrueEnergy
332  sim::TrueEnergy TrueEn = ((*SecFileTrueEnergies)[i]);
333 
334  if (part.TrackId() != TrueEn.TrackId()) {
335  std::cout << "sim::TrueEnergy TrackId doesn't match... Part TrackId" << part.TrackId() << ", TrueEn TrackId " << TrueEn.TrackId()
336  << ". Need an assn, so going to store a junk TrueEn for this particle." << std::endl;
337  tempTrueEnergy->push_back( sim::TrueEnergy(TrueEn.TrackId() + Offset[OffsetIndex-1], -5, -5, -5, -5) );
338  } else {
339  sim::TrueEnergy gTrueEn( TrueEn.TrackId() + Offset[OffsetIndex-1],
340  TrueEn.EnteringEnergy(),
341  TrueEn.EscapingEnergy(),
342  TrueEn.TotalDepEnergy(),
343  TrueEn.TotalEscEnergy() );
344  tempTrueEnergy->push_back(gTrueEn);
345  }
346 
347  // this array is used just to check consistency of results for FLSHit matching later
348  trackIDList[nParticle] = part.TrackId() + Offset[OffsetIndex-1];
349 
350  nParticle++;
351  } // secondary Particles loop
352 
353  // Loop over secondary MCTruth list; has same size as FLSHitList
354  for(unsigned int i = 0; i < SecFileMCTruthlistCol->size(); ++i){
355  if(i < SecFileFLSHitlistCol->size()){
356 
357  sim::FLSHitList mcfls ((*SecFileFLSHitlistCol)[i]);
358  sim::FLSHitList tmcfls;
359  sim::FLSHit fHit;
360 
361  // add flshits to final list offsetting trackIDs
362  const std::vector<sim::FLSHit>& hits = mcfls.fHits;
363  for (unsigned int j = 0; j < hits.size(); ++j){
364  fHit.Clear();
365  fHit = hits[j];
366  fHit.SetTrackId(hits[j].GetTrackID() + Offset[i]);
367  tmcfls.fHits.push_back(fHit);
368 
369  // Ccheck that this FLSHit trackID is on the particle trackID list
370  // failure just results in warning message being printed
371  bool foundpart=false;
372  for(int ip = 0; ip < nParticle; ip++){
373  if(hits[j].GetTrackID() + Offset[i] == trackIDList[ip]){
374  foundpart = true;
375  break;
376  }
377  }
378  if(!foundpart){
379  mf::LogWarning("MergeG4Collections") << " !!!FLSHit problem "
380  << i << " "
381  << j << " "
382  << hits[j].GetTrackID() << " "
383  << Offset[i];
384  }
385  }
386  outFLSHitLists->push_back(tmcfls);
387  }
388  else mf::LogWarning("MergeG4Collections") << "FLSHitList length - MCList length mismatch!" << std::endl;
389  } // secondary MCTruths
390 
391  // Create Particlelist:MCTruth association
392 
393  LastPartId = 0;
394  int partcount = 0;
395  first = true;
396  // set MCList index to first secondary event location
397  if(MCListIndex + 1 < (int)mixedMCTruths->size())
398  MCListIndex++;
399  else
400  mf::LogWarning("MergeG4Collections")
401  << "!!! Caught MCListIndex MCTruth size mismatch !!! ";
402 
403 
404  //repeat loop over particle list
405  for(unsigned int j = 0; j < tempParticles->size(); ++j){
406  sim::Particle part ((*tempParticles)[j]);
407  sim::Particle oldpart ((*SecFileParticlelistCol)[j]);
408 
409  art::Ptr<simb::MCTruth> mcptr(mixedMCTruths, MCListIndex); //grab MCTruth at index location
410 
411  // Check that the particle can be found on this MCTruth particle list.
412  // If not increment MCTruth index
413  bool partInMCT = ParticleIsInMCTruth(part,mcptr);
414 
415  //check whether to increment MCTruth
416  if((LastPartId >= oldpart.TrackId()) || (part.Mother() == 0 && !partInMCT && !first )){
417 
418  if(MCListIndex +1 < (int)mixedMCTruths->size())
419  MCListIndex++;
420  else
421  mf::LogWarning("MergeG4Collections")
422  << "!!! caught MCListIndex MCTruth size mismatch !!!";
423 
424  partcount = 0;
425  }
426 
427  // Check position of mother=0 with updated list index.
428  // Should always find a match - this is just a check
429  art::Ptr<simb::MCTruth> mcptr2(mixedMCTruths, MCListIndex);
430  bool partInMCT2 = ParticleIsInMCTruth(part,mcptr2);
431 
432  if(part.Mother() == 0 && !partInMCT2 )
433  mf::LogWarning("MergeG4Collections")
434  << "!!! Secondary particle and MCTruth particle list mismatch !!!";
435  first = false;
436  LastPartId = oldpart.TrackId();
437 
438  outParticles->push_back(part); //push this particle onto final particle list and make association
439  util::CreateAssn(*this, evt, *outParticles, mcptr2 , *outMCTruthPartAssn, outParticles->size()-1);
440 
441  // sim::TrueEnergy
442  sim::TrueEnergy TrueEn = ((*tempTrueEnergy)[j]);
443  outTrueEnergy->push_back( TrueEn );
444  util::CreateAssn( *this, evt, *outTrueEnPartAssn, *outTrueEnergy, *outParticles, j, (outParticles->size()-1) );
445 
446  partcount ++;
447  } // tempParticles loop
448 
449  delete [] Offset ;
450 
451  } // If secondary labels are specified
452 
453 
454  // put the collections in the event
455  evt.put(std::move(outFLSHitLists));
456  evt.put(std::move(outParticles ));
457  evt.put(std::move(outTrueEnergy ));
458  evt.put(std::move(outMCTruthPartAssn));
459  evt.put(std::move(outTrueEnPartAssn ));
460  }
461 
462 
463  //----------------------------------------------------------------------
464  bool MergeG4Collections::ParticleIsInMCTruth( simb::MCParticle part,
466  {
467  // check for particle in mct with same start position as part
468  for(int i = 0; i < mct->NParticles(); i++){
469  simb::MCParticle mct_part = mct->GetParticle(i);
470  float vpartsep = sqrt((part.Vx()-mct_part.Vx())*(part.Vx()-mct_part.Vx())+
471  (part.Vy()-mct_part.Vy())*(part.Vy()-mct_part.Vy())+
472  (part.Vz()-mct_part.Vz())*(part.Vz()-mct_part.Vz()));
473  if(vpartsep < 0.01) return true;
474  }
475  return false;
476  }
477 
478 
479  //----------------------------------------------------------------------
480  bool MergeG4Collections::SameMCTruth( art::Ptr<simb::MCTruth> mct1,
482  {
483  // neutrino vertex and bjorken x & y are enough to constitute equality
484  return ( (mct1->GetNeutrino().X() == mct2->GetNeutrino().X()) &&
485  (mct1->GetNeutrino().Y() == mct2->GetNeutrino().Y()) &&
486  (mct1->GetNeutrino().Nu().Vx() == mct2->GetNeutrino().Nu().Vx()) &&
487  (mct1->GetNeutrino().Nu().Vy() == mct2->GetNeutrino().Nu().Vy()) &&
488  (mct1->GetNeutrino().Nu().Vz() == mct2->GetNeutrino().Nu().Vz()) );
489  }
490 
492 
493 } //end namespace merge
494 ////////////////////////////////////////////////////////////////////////////
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:217
const TVector3 & Polarization() const
Definition: MCParticle.h:213
void SetTrackId(const int trackid)
Definition: FLSHit.h:101
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:218
static bool CreateAssn(art::EDProducer const &prod, art::Event &evt, std::vector< T > &a, art::Ptr< U > b, art::Assns< T, U > &assn, size_t indx=UINT_MAX, std::string const &instance=std::string())
Create a 1 to 1 association between a new product and one already in the event.
int PdgCode() const
Definition: MCParticle.h:211
int TrackId() const
Definition: TrueEnergy.h:36
std::vector< sim::FLSHit > fHits
Definition: FLSHitList.h:21
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:76
double Gvz() const
Definition: MCParticle.h:247
double Weight() const
Definition: MCParticle.h:253
int Mother() const
Definition: MCParticle.h:212
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
T sqrt(T number)
Definition: d0nt_math.hpp:156
double Mass() const
Definition: MCParticle.h:238
std::string fMixerProcessLabel
MCTruth mixed collection label.
std::string fFirstG4Collection
MCTruth process main collection label.
OStream cerr
Definition: OStream.cxx:7
int StatusCode() const
Definition: MCParticle.h:210
TString ip
Definition: loadincs.C:5
double Gvx() const
Definition: MCParticle.h:245
A single unit of energy deposition in the liquid scintillator.
Definition: FLSHit.h:19
int NParticles() const
Definition: MCTruth.h:74
DEFINE_ART_MODULE(TestTMapFile)
double Gvy() const
Definition: MCParticle.h:246
std::string Process() const
Definition: MCParticle.h:214
float EscapingEnergy() const
Definition: TrueEnergy.h:38
int NumberDaughters() const
Definition: MCParticle.h:216
float TotalEscEnergy() const
Definition: TrueEnergy.h:40
object containing MC flux information
float EnteringEnergy() const
Definition: TrueEnergy.h:37
int TrackId() const
Definition: MCParticle.h:209
int Daughter(const int i) const
Definition: MCParticle.cxx:112
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
TString part[npart]
Definition: Style.C:32
void hits()
Definition: readHits.C:15
double Y() const
Definition: MCNeutrino.h:156
Float_t d
Definition: plot.C:236
double X() const
Definition: MCNeutrino.h:155
const double j
Definition: BetheBloch.cxx:29
std::string fFirstGenProcessLabel
MCTruth main collection label.
OStream cout
Definition: OStream.cxx:6
const simb::MCParticle & GetParticle(int i) const
Definition: MCTruth.h:75
double Vx(const int i=0) const
Definition: MCParticle.h:220
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
void SetGvtx(double *v)
Definition: MCParticle.cxx:120
group hits according to time and space
A vector of FLSHit from single neutrino interaction.
Definition: FLSHitList.h:13
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
double Gvt() const
Definition: MCParticle.h:248
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:219
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void Clear()
Clear the FLS hit.
Definition: FLSHit.cxx:39
int Rescatter() const
Definition: MCParticle.h:251
double Vz(const int i=0) const
Definition: MCParticle.h:222
float TotalDepEnergy() const
Definition: TrueEnergy.h:39
bool fIsFirstCollectionCosmic
Geant4 main collection label.
double Vy(const int i=0) const
Definition: MCParticle.h:221