All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
larg4::ParticleListAction Class Reference

#include <ParticleListAction.h>

Inheritance diagram for larg4::ParticleListAction:

Classes

struct  ParticleInfo_t
 

Public Types

using GeneratedParticleIndex_t = simb::GeneratedParticleIndex_t
 

Public Member Functions

 ParticleListAction (double energyCut, bool storeTrajectories=false, bool keepEMShowerDaughters=false, bool keepMCParticleList=true, bool storeDroppedMCParticles=false)
 
virtual void BeginOfEventAction (const G4Event *)
 
virtual void EndOfEventAction (const G4Event *)
 
virtual void PreTrackingAction (const G4Track *)
 
virtual void PostTrackingAction (const G4Track *)
 
virtual void SteppingAction (const G4Step *)
 
void ParticleFilter (std::unique_ptr< util::PositionInVolumeFilter > &&filter)
 Grabs a particle filter. More...
 
void ResetTrackIDOffset ()
 
const sim::ParticleList * GetList () const
 
std::map< int,
GeneratedParticleIndex_t >
const & 
GetPrimaryTruthMap () const
 
bool hasList () const
 Returns whether a particle list is being kept. More...
 
GeneratedParticleIndex_t GetPrimaryTruthIndex (int trackId) const
 Returns the index of primary truth (sim::NoGeneratorIndex if none). More...
 
sim::ParticleList && YieldList ()
 
sim::ParticleList && YieldDroppedList ()
 Yields the (dropped) ParticleList accumulated during the current event. More...
 

Static Public Member Functions

static int GetCurrentTrackID ()
 
static int GetCurrentOrigTrackID ()
 
static int GetCurrentPdgCode ()
 
static bool isDropped (simb::MCParticle const *p)
 returns whether the specified particle has been marked as dropped More...
 

Private Member Functions

int GetParentage (int trackid, bool useOrigTrackIDMap=false) const
 
void AddPointToCurrentParticle (TLorentzVector const &pos, TLorentzVector const &mom, std::string const &process)
 Adds a trajectory point to the current particle, and runs the filter. More...
 

Private Attributes

G4double fenergyCut
 
ParticleInfo_t fCurrentParticle
 
std::unique_ptr
< sim::ParticleList > 
fparticleList
 
std::unique_ptr
< sim::ParticleList > 
fdroppedParticleList
 
G4bool fstoreTrajectories
 Whether to store particle trajectories with each particle. More...
 
std::map< int, int > fParentIDMap
 key is current track ID, value is parent ID More...
 
std::map< int, int > fParentIDMap_OrigTrackID
 key is current track ID, value is parent ID – for real G4 track ID tracking only More...
 
bool fKeepEMShowerDaughters
 whether to keep EM shower secondaries, tertiaries, etc More...
 
std::unique_ptr
< util::PositionInVolumeFilter
fFilter
 filter for particles to be kept More...
 
std::map< int,
GeneratedParticleIndex_t
fPrimaryTruthMap
 Map: particle track ID -> index of primary information in MC truth. More...
 

Static Private Attributes

static int fCurrentTrackID = sim::NoParticleId
 
static int fCurrentOrigTrackID = sim::NoParticleId
 except for EM shower particles where it always shows the original track ID More...
 
static int fCurrentPdgCode = 0
 pdg code of current particle More...
 
static int fTrackIDOffset = 0
 

Detailed Description

Definition at line 45 of file ParticleListAction.h.

Member Typedef Documentation

using larg4::ParticleListAction::GeneratedParticleIndex_t = simb::GeneratedParticleIndex_t

Definition at line 47 of file ParticleListAction.h.

Constructor & Destructor Documentation

larg4::ParticleListAction::ParticleListAction ( double  energyCut,
bool  storeTrajectories = false,
bool  keepEMShowerDaughters = false,
bool  keepMCParticleList = true,
bool  storeDroppedMCParticles = false 
)

Definition at line 58 of file ParticleListAction.cxx.

64  : fenergyCut(energyCut * CLHEP::GeV)
65  , fparticleList(keepMCParticleList ? std::make_unique<sim::ParticleList>() : nullptr)
66  , fdroppedParticleList(storeDroppedMCParticles ? std::make_unique<sim::ParticleList>() : nullptr)
69  {}
util::quantities::gigaelectronvolt GeV
G4bool fstoreTrajectories
Whether to store particle trajectories with each particle.
std::unique_ptr< sim::ParticleList > fdroppedParticleList
BEGIN_PROLOG note Geant4 assumes this is in MeV keepEMShowerDaughters
bool fKeepEMShowerDaughters
whether to keep EM shower secondaries, tertiaries, etc
std::unique_ptr< sim::ParticleList > fparticleList
BEGIN_PROLOG note Geant4 assumes this is in MeV does not store electromagnetic shower daughter storeTrajectories

Member Function Documentation

void larg4::ParticleListAction::AddPointToCurrentParticle ( TLorentzVector const &  pos,
TLorentzVector const &  mom,
std::string const &  process 
)
private

Adds a trajectory point to the current particle, and runs the filter.

Definition at line 577 of file ParticleListAction.cxx.

580  {
581 
582  // Add the first point in the trajectory.
583  fCurrentParticle.particle->AddTrajectoryPoint(pos, mom, process);
584 
585  // also see if we can decide to keep the particle
586  if (!fCurrentParticle.keep) fCurrentParticle.keep = fFilter->mustKeep(pos);
587 
588  } // ParticleListAction::AddPointToCurrentParticle()
std::unique_ptr< util::PositionInVolumeFilter > fFilter
filter for particles to be kept
cet::exempt_ptr< simb::MCParticle > particle
Object representing particle.
bool keep
if there was decision to keep
void larg4::ParticleListAction::BeginOfEventAction ( const G4Event *  )
virtual

Definition at line 74 of file ParticleListAction.cxx.

75  {
76  // Clear any previous particle information.
78  if (fparticleList) fparticleList->clear();
80  fParentIDMap.clear();
83  fCurrentPdgCode = 0;
84  }
static int fCurrentPdgCode
pdg code of current particle
std::unique_ptr< sim::ParticleList > fdroppedParticleList
std::map< int, int > fParentIDMap
key is current track ID, value is parent ID
void clear()
Resets the information (does not release memory it does not own)
static const int NoParticleId
Definition: sim.h:21
std::unique_ptr< sim::ParticleList > fparticleList
static int fCurrentOrigTrackID
except for EM shower particles where it always shows the original track ID
void larg4::ParticleListAction::EndOfEventAction ( const G4Event *  )
virtual

Definition at line 468 of file ParticleListAction.cxx.

469  {
470  if (!fparticleList) return;
471 
472  // Set up the utility class for the "for_each" algorithm. (We only
473  // need a separate set-up for the utility class because we need to
474  // give it the pointer to the particle list. We're using the STL
475  // "for_each" instead of the C++ "for loop" because it's supposed
476  // to be faster.
477  UpdateDaughterInformation updateDaughterInformation;
478  updateDaughterInformation.SetParticleList(fparticleList.get());
479 
480  // Update the daughter information for each particle in the list.
481  std::for_each(fparticleList->begin(), fparticleList->end(), updateDaughterInformation);
482  }
std::unique_ptr< sim::ParticleList > fparticleList
static int larg4::ParticleListAction::GetCurrentOrigTrackID ( )
inlinestatic

Definition at line 126 of file ParticleListAction.h.

127  {
128  return fCurrentOrigTrackID;
129  }
static int fCurrentOrigTrackID
except for EM shower particles where it always shows the original track ID
static int larg4::ParticleListAction::GetCurrentPdgCode ( )
inlinestatic

Definition at line 131 of file ParticleListAction.h.

132  {
133  return fCurrentPdgCode;
134  }
static int fCurrentPdgCode
pdg code of current particle
static int larg4::ParticleListAction::GetCurrentTrackID ( )
inlinestatic

Definition at line 121 of file ParticleListAction.h.

122  {
123  return fCurrentTrackID;
124  }
const sim::ParticleList * larg4::ParticleListAction::GetList ( ) const

Definition at line 487 of file ParticleListAction.cxx.

488  {
489  if (!fparticleList) return nullptr;
490 
491  // check if the ParticleNavigator has entries, and if
492  // so grab the highest track id value from it to
493  // add to the fTrackIDOffset
494  int highestID = 0;
495  for (auto pn = fparticleList->begin(); pn != fparticleList->end(); pn++)
496  if ((*pn).first > highestID) highestID = (*pn).first;
497 
498  // If we have stored dropped particles,
499  // include them in the offset.
500  if (fdroppedParticleList) {
501  for (auto pn = fdroppedParticleList->begin(); pn != fdroppedParticleList->end(); pn++)
502  if ((*pn).first > highestID) highestID = (*pn).first;
503  }
504 
505  //Only change the fTrackIDOffset if there is in fact a particle to add to the event
506  if ((fparticleList->size()) != 0) { fTrackIDOffset = highestID + 1; }
507 
508  return fparticleList.get();
509  }
std::unique_ptr< sim::ParticleList > fdroppedParticleList
std::unique_ptr< sim::ParticleList > fparticleList
int larg4::ParticleListAction::GetParentage ( int  trackid,
bool  useOrigTrackIDMap = false 
) const
private

Definition at line 92 of file ParticleListAction.cxx.

93  {
94  int parentid = sim::NoParticleId;
95  const std::map<int, int>* parentIDMap = useOrigTrackIDMap ? &fParentIDMap_OrigTrackID : &fParentIDMap;
96 
97  // search the fParentIDMap recursively until we have the parent id
98  // of the first EM particle that led to this one
99  std::map<int, int>::const_iterator itr = parentIDMap->find(trackid);
100  while (itr != parentIDMap->end()) {
101  MF_LOG_DEBUG("ParticleListAction") << "parentage for " << trackid << " " << (*itr).second;
102 
103  // set the parentid to the current parent ID, when the loop ends
104  // this id will be the first EM particle
105  parentid = (*itr).second;
106  itr = parentIDMap->find(parentid);
107  }
108  MF_LOG_DEBUG("ParticleListAction") << "final parent ID " << parentid;
109 
110  return parentid;
111  }
std::map< int, int > fParentIDMap_OrigTrackID
key is current track ID, value is parent ID – for real G4 track ID tracking only
std::map< int, int > fParentIDMap
key is current track ID, value is parent ID
static const int NoParticleId
Definition: sim.h:21
simb::GeneratedParticleIndex_t larg4::ParticleListAction::GetPrimaryTruthIndex ( int  trackId) const

Returns the index of primary truth (sim::NoGeneratorIndex if none).

Definition at line 513 of file ParticleListAction.cxx.

514  {
515  auto const iInfo = GetPrimaryTruthMap().find(trackId);
516  return (iInfo == GetPrimaryTruthMap().end()) ? simb::NoGeneratedParticleIndex : iInfo->second;
517  } // ParticleListAction::GetPrimaryTruthIndex()
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
std::map< int, GeneratedParticleIndex_t > const & GetPrimaryTruthMap() const
std::map<int, GeneratedParticleIndex_t> const& larg4::ParticleListAction::GetPrimaryTruthMap ( ) const
inline

Returns a map of truth record information index for each of the primary particles (by track ID).

Definition at line 148 of file ParticleListAction.h.

149  {
150  return fPrimaryTruthMap;
151  }
std::map< int, GeneratedParticleIndex_t > fPrimaryTruthMap
Map: particle track ID -&gt; index of primary information in MC truth.
bool larg4::ParticleListAction::hasList ( ) const
inline

Returns whether a particle list is being kept.

Definition at line 155 of file ParticleListAction.h.

156  {
157  return static_cast<bool>(fparticleList);
158  }
std::unique_ptr< sim::ParticleList > fparticleList
bool larg4::ParticleListAction::isDropped ( simb::MCParticle const *  p)
static

returns whether the specified particle has been marked as dropped

Definition at line 51 of file ParticleListAction.cxx.

52  {
53  return !p || p->Trajectory().empty();
54  } // ParticleListAction::isDropped()
pdgs p
Definition: selectors.fcl:22
void larg4::ParticleListAction::ParticleFilter ( std::unique_ptr< util::PositionInVolumeFilter > &&  filter)
inline

Grabs a particle filter.

Definition at line 114 of file ParticleListAction.h.

115  {
116  fFilter = std::move(filter);
117  }
std::unique_ptr< util::PositionInVolumeFilter > fFilter
filter for particles to be kept
void larg4::ParticleListAction::PostTrackingAction ( const G4Track *  aTrack)
virtual

Definition at line 275 of file ParticleListAction.cxx.

276  {
277  if (!fCurrentParticle.hasParticle()) return;
278  assert(fparticleList);
279 
280  if (aTrack) {
281  fCurrentParticle.particle->SetWeight(aTrack->GetWeight());
282  G4String process =
283  aTrack->GetStep()->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName();
284  fCurrentParticle.particle->SetEndProcess(process);
285  }
286 
287  // We would keep it if it wasn't for KeepEMShowerDaughters = false
288  // It goes into fDroppedParticleList in case LArG4 is configured
289  // to keep a minimal version of it.
290  if (fCurrentParticle.drop) {
293  return;
294  }
295 
296  // if we have found no reason to keep it, drop it!
297  // (we might still need parentage information though)
298  if (!fCurrentParticle.keep) {
299  fparticleList->Archive(fCurrentParticle.particle.get());
300  // after the particle is archived, it is deleted
302  return;
303  }
304 
305  // store truth record pointer, only if it is available
306  if (fCurrentParticle.isPrimary()) {
308  }
309 
310  return;
311  }
std::map< int, GeneratedParticleIndex_t > fPrimaryTruthMap
Map: particle track ID -&gt; index of primary information in MC truth.
std::unique_ptr< sim::ParticleList > fdroppedParticleList
GeneratedParticleIndex_t truthInfoIndex() const
Returns the index of the particle in the generator truth record.
void clear()
Resets the information (does not release memory it does not own)
std::unique_ptr< sim::ParticleList > fparticleList
bool isPrimary() const
Returns whether there is a particle.
cet::exempt_ptr< simb::MCParticle > particle
Object representing particle.
bool hasParticle() const
Returns whether there is a particle.
bool keep
if there was decision to keep
void larg4::ParticleListAction::PreTrackingAction ( const G4Track *  track)
virtual

Definition at line 116 of file ParticleListAction.cxx.

117  {
118  // Particle type.
119  G4ParticleDefinition* particleDefinition = track->GetDefinition();
120  G4int pdgCode = particleDefinition->GetPDGEncoding();
121 
122  // Get Geant4's ID number for this track. This will be the same
123  // ID number that we'll use in the ParticleList.
124  // It is offset by the number of tracks accumulated from the previous Geant4
125  // runs (if any)
126  G4int trackID = track->GetTrackID() + fTrackIDOffset;
127  fCurrentTrackID = trackID;
128  fCurrentOrigTrackID = trackID;
129  fCurrentPdgCode = pdgCode;
130 
131  if (!fparticleList) {
132  // the rest is about adding a new particle to the list: skip
133  return; // note that fCurrentParticle is clear()'ed
134  }
135 
136  // And the particle's parent (same offset as above):
137  G4int parentID = track->GetParentID() + fTrackIDOffset;
138 
139  std::string process_name = "unknown";
140  bool drop_shower_daughter = false;
141 
142  // Is there an MCTruth object associated with this G4Track? We
143  // have to go up a "chain" of information to find out:
144  const G4DynamicParticle* dynamicParticle = track->GetDynamicParticle();
145  const G4PrimaryParticle* primaryParticle = dynamicParticle->GetPrimaryParticle();
146  simb::GeneratedParticleIndex_t primaryIndex = simb::NoGeneratedParticleIndex;
147  if (primaryParticle != 0) {
148  const G4VUserPrimaryParticleInformation* gppi = primaryParticle->GetUserInformation();
149  const g4b::PrimaryParticleInformation* ppi =
150  dynamic_cast<const g4b::PrimaryParticleInformation*>(gppi);
151  if (ppi != 0) {
152  primaryIndex = ppi->MCParticleIndex();
153 
154  // If we've made it this far, a PrimaryParticleInformation
155  // object exists and we are using a primary particle, set the
156  // process name accordingly
157  process_name = "primary";
158 
159  // primary particles should have parentID = 0, even if there
160  // are multiple MCTruths for this event
161  parentID = 0;
162  } // end else no primary particle information
163  } // Is there a G4PrimaryParticle?
164  // If this is not a primary particle...
165  else {
166  // check if this particle was made in an EM shower, don't put it in the particle
167  // list as we don't care about secondaries, tertiaries, etc for these showers
168  // figure out what process is making this track - skip it if it is
169  // one of pair production, compton scattering, photoelectric effect
170  // bremstrahlung, annihilation, any ionization - who wants to save
171  // a buttload of electrons that arent from a CC interaction?
172  process_name = track->GetCreatorProcess()->GetProcessName();
173  drop_shower_daughter = (!fKeepEMShowerDaughters && (process_name.find("conv") != std::string::npos ||
174  process_name.find("LowEnConversion") != std::string::npos ||
175  process_name.find("Pair") != std::string::npos ||
176  process_name.find("compt") != std::string::npos ||
177  process_name.find("Compt") != std::string::npos ||
178  process_name.find("Brem") != std::string::npos ||
179  process_name.find("phot") != std::string::npos ||
180  process_name.find("Photo") != std::string::npos ||
181  process_name.find("Ion") != std::string::npos ||
182  process_name.find("annihil") != std::string::npos));
183  if (drop_shower_daughter) {
184 
185  // figure out the ultimate parentage of this particle
186  // first add this track id and its parent to the fParentIDMap
187  fParentIDMap[trackID] = parentID;
188 
189  fCurrentTrackID = -1 * this->GetParentage(trackID); // the real trackID remains stored in fCurrentOrigTrackID
190 
191  // check that fCurrentTrackID is in the particle list - it is possible
192  // that this particle's parent is a particle that did not get tracked.
193  // An example is a partent that was made due to muMinusCaptureAtRest
194  // and the daughter was made by the phot process. The parent likely
195  // isn't saved in the particle list because it is below the energy cut
196  // which will put a bogus track id value into the sim::IDE object for
197  // the sim::SimChannel if we don't check it.
199 
200  } // end if keeping EM shower daughters
201 
202  // Check the energy of the particle. If it falls below the energy
203  // cut, don't add it to our list.
204  G4double energy = track->GetKineticEnergy();
205  if (energy < fenergyCut) {
207 
208  // do add the particle to the parent id map though
209  // and set the current track id to be it's ultimate parent
210  fParentIDMap[trackID] = parentID;
211  fParentIDMap_OrigTrackID[trackID] = parentID;
212 
213  fCurrentTrackID = -1 * this->GetParentage(trackID);
214  fCurrentOrigTrackID = -1 * this->GetParentage(trackID, true);
215 
216  return;
217  }
218 
219  // check to see if the parent particle has been stored in the particle navigator
220  // if not, then see if it is possible to walk up the fParentIDMap to find the
221  // ultimate parent of this particle. Use that ID as the parent ID for this
222  // particle
223  if (!fparticleList->KnownParticle(parentID) && !(fdroppedParticleList && fdroppedParticleList->KnownParticle(parentID))) {
224  // do add the particle to the parent id map
225  // just in case it makes a daughter that we have to track as well
226  fParentIDMap[trackID] = parentID;
227  fParentIDMap_OrigTrackID[trackID] = parentID;
228  int pid = this->GetParentage(parentID);
229 
230  // if we still can't find the parent in the particle navigator,
231  // we have to give up
232  if (!fparticleList->KnownParticle(pid) && !(fdroppedParticleList && fdroppedParticleList->KnownParticle(parentID))) {
233  MF_LOG_WARNING("ParticleListAction")
234  << "can't find parent id: " << parentID << " in the particle list, or fParentIDMap."
235  << " Make " << parentID << " the mother ID for"
236  << " track ID " << fCurrentTrackID << " in the hope that it will aid debugging.";
237  }
238  else
239  parentID = pid;
240  }
241 
242  } // end if not a primary particle
243 
244  // This is probably the PDG mass, but just in case:
245  double mass = dynamicParticle->GetMass() / CLHEP::GeV;
246 
247  // Create the sim::Particle object.
250  new simb::MCParticle(trackID, pdgCode, process_name, parentID, mass);
251  fCurrentParticle.truthIndex = primaryIndex;
252 
253  // if we are not filtering, we have a decision already
254  if (!fFilter) fCurrentParticle.keep = true;
255 
256  // Polarization.
257  const G4ThreeVector& polarization = track->GetPolarization();
258  fCurrentParticle.particle->SetPolarization(
259  TVector3(polarization.x(), polarization.y(), polarization.z()));
260 
261  // if KeepEMShowerDaughters = False and we decided to drop this particle,
262  // record it before throwing it away.
263  if (drop_shower_daughter) {
264  fCurrentParticle.drop = true;
266  return;
267  }
268 
269  // Save the particle in the ParticleList.
271  }
util::quantities::gigaelectronvolt GeV
static int fCurrentPdgCode
pdg code of current particle
std::unique_ptr< sim::ParticleList > fdroppedParticleList
std::map< int, int > fParentIDMap_OrigTrackID
key is current track ID, value is parent ID – for real G4 track ID tracking only
GeneratedParticleIndex_t truthIndex
Index of the particle in the original generator truth record.
int GetParentage(int trackid, bool useOrigTrackIDMap=false) const
process_name use argoneut_mc_hitfinder track
std::map< int, int > fParentIDMap
key is current track ID, value is parent ID
void clear()
Resets the information (does not release memory it does not own)
bool fKeepEMShowerDaughters
whether to keep EM shower secondaries, tertiaries, etc
static const int NoParticleId
Definition: sim.h:21
MF_LOG_WARNING("SimWire")<< "SimWire is an example module that works for the "<< "MicroBooNE detector. Each experiment should implement "<< "its own version of this module to simulate electronics "<< "response."
std::unique_ptr< util::PositionInVolumeFilter > fFilter
filter for particles to be kept
std::unique_ptr< sim::ParticleList > fparticleList
cet::exempt_ptr< simb::MCParticle > particle
Object representing particle.
float mass
Definition: dedx.py:47
static int fCurrentOrigTrackID
except for EM shower particles where it always shows the original track ID
bool keep
if there was decision to keep
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG process_name
void larg4::ParticleListAction::ResetTrackIDOffset ( )
inline

Definition at line 137 of file ParticleListAction.h.

138  {
139  fTrackIDOffset = 0;
140  }
void larg4::ParticleListAction::SteppingAction ( const G4Step *  step)
virtual

Definition at line 316 of file ParticleListAction.cxx.

317  {
318 
319  if (!fCurrentParticle.hasParticle()) { return; }
320 
321  // Temporary fix for problem where DeltaTime on the first step
322  // of optical photon propagation is calculated incorrectly. -wforeman
323  globalTime = step->GetTrack()->GetGlobalTime();
324  velocity_G4 = step->GetTrack()->GetVelocity();
325  velocity_step = step->GetStepLength() / step->GetDeltaTime();
326  if ((step->GetTrack()->GetDefinition()->GetPDGEncoding() == 0) &&
327  fabs(velocity_G4 - velocity_step) > 0.0001) {
328  // Subtract the faulty step time from the global time,
329  // and add the correct step time based on G4 velocity.
330  step->GetPostStepPoint()->SetGlobalTime(globalTime - step->GetDeltaTime() +
331  step->GetStepLength() / velocity_G4);
332  }
333 
334  // For the most part, we just want to add the post-step
335  // information to the particle's trajectory. There's one
336  // exception: In PreTrackingAction, the correct time information
337  // is not available. So add the correct vertex information here.
338 
339  if (fCurrentParticle.particle->NumberTrajectoryPoints() == 0) {
340 
341  // Get the pre/along-step information from the G4Step.
342  const G4StepPoint* preStepPoint = step->GetPreStepPoint();
343 
344  const G4ThreeVector position = preStepPoint->GetPosition();
345  G4double time = preStepPoint->GetGlobalTime();
346 
347  // Remember that LArSoft uses cm, ns, GeV.
348  TLorentzVector fourPos(position.x() / CLHEP::cm,
349  position.y() / CLHEP::cm,
350  position.z() / CLHEP::cm,
351  time / CLHEP::ns);
352 
353  const G4ThreeVector momentum = preStepPoint->GetMomentum();
354  const G4double energy = preStepPoint->GetTotalEnergy();
355  TLorentzVector fourMom(momentum.x() / CLHEP::GeV,
356  momentum.y() / CLHEP::GeV,
357  momentum.z() / CLHEP::GeV,
358  energy / CLHEP::GeV);
359 
360  // Add the first point in the trajectory.
361  AddPointToCurrentParticle(fourPos, fourMom, "Start");
362 
363  } // end if this is the first step
364 
365  // At this point, the particle is being transported through the
366  // simulation. This method is being called for every voxel that
367  // the track passes through, but we don't want to update the
368  // trajectory information if we're just updating voxels. To check
369  // for this, look at the process name for the step, and compare it
370  // against the voxelization process name (set in PhysicsList.cxx).
371  G4String process = step->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName();
372  G4bool ignoreProcess = process.contains("LArVoxel") || process.contains("OpDetReadout");
373 
374  MF_LOG_DEBUG("ParticleListAction::SteppingAction")
375  << ": DEBUG - process='" << process << "'"
376  << " ignoreProcess=" << ignoreProcess << " fstoreTrajectories=" << fstoreTrajectories;
377 
378  // We store the initial creation point of the particle
379  // and its final position (ie where it has no more energy, or at least < 1 eV) no matter
380  // what, but whether we store the rest of the trajectory depends
381  // on the process, and on a user switch
382  if (fstoreTrajectories && !ignoreProcess) {
383  // If the particle was marked to drop (EM shower daughters),
384  // then skip unless this step is last in volume.
385  //if (fCurrentParticle.drop && !step->IsLastStepInVolume()) return;
386 
387  // Get the post-step information from the G4Step.
388  const G4StepPoint* postStepPoint = step->GetPostStepPoint();
389 
390  const G4ThreeVector position = postStepPoint->GetPosition();
391  G4double time = postStepPoint->GetGlobalTime();
392 
393  // Remember that LArSoft uses cm, ns, GeV.
394  TLorentzVector fourPos(position.x() / CLHEP::cm,
395  position.y() / CLHEP::cm,
396  position.z() / CLHEP::cm,
397  time / CLHEP::ns);
398 
399  const G4ThreeVector momentum = postStepPoint->GetMomentum();
400  const G4double energy = postStepPoint->GetTotalEnergy();
401  TLorentzVector fourMom(momentum.x() / CLHEP::GeV,
402  momentum.y() / CLHEP::GeV,
403  momentum.z() / CLHEP::GeV,
404  energy / CLHEP::GeV);
405 
406  // Add another point in the trajectory.
407  AddPointToCurrentParticle(fourPos, fourMom, std::string(process));
408  }
409  }
util::quantities::gigaelectronvolt GeV
G4bool fstoreTrajectories
Whether to store particle trajectories with each particle.
void AddPointToCurrentParticle(TLorentzVector const &pos, TLorentzVector const &mom, std::string const &process)
Adds a trajectory point to the current particle, and runs the filter.
double velocity_step
double velocity_G4
double globalTime
cet::exempt_ptr< simb::MCParticle > particle
Object representing particle.
bool hasParticle() const
Returns whether there is a particle.
sim::ParticleList && larg4::ParticleListAction::YieldDroppedList ( )

Yields the (dropped) ParticleList accumulated during the current event.

Definition at line 552 of file ParticleListAction.cxx.

553  {
554  if (!fdroppedParticleList) {
555  throw cet::exception("ParticleListAction")
556  << "ParticleListAction::YieldDroppedList(): dropped particle list not build by user request.\n";
557  }
558  // check if the ParticleNavigator has entries, and if
559  // so grab the highest track id value from it to
560  // add to the fTrackIDOffset
561  int highestID = 0;
562  for (auto pn = fparticleList->begin(); pn != fparticleList->end(); pn++)
563  if ((*pn).first > highestID) highestID = (*pn).first;
564 
565  // If we have stored dropped particles,
566  // include them in the offset.
567  for (auto pn = fdroppedParticleList->begin(); pn != fdroppedParticleList->end(); pn++)
568  if ((*pn).first > highestID) highestID = (*pn).first;
569 
570  //Only change the fTrackIDOffset if there is in fact a particle to add to the event
571  if ((fparticleList->size()) != 0) { fTrackIDOffset = highestID + 1; }
572 
573  return std::move(*fdroppedParticleList);
574  } // ParticleList&& ParticleListAction::YieldDroppedList()
std::unique_ptr< sim::ParticleList > fdroppedParticleList
std::unique_ptr< sim::ParticleList > fparticleList
sim::ParticleList && larg4::ParticleListAction::YieldList ( )

Definition at line 522 of file ParticleListAction.cxx.

523  {
524  if (!fparticleList) {
525  // check with `hasList()` before calling this method
526  throw cet::exception("ParticleListAction")
527  << "ParticleListAction::YieldList(): particle list not build by user request.\n";
528  }
529  // check if the ParticleNavigator has entries, and if
530  // so grab the highest track id value from it to
531  // add to the fTrackIDOffset
532  int highestID = 0;
533  for (auto pn = fparticleList->begin(); pn != fparticleList->end(); pn++)
534  if ((*pn).first > highestID) highestID = (*pn).first;
535 
536  // If we have stored dropped particles,
537  // include them in the offset.
538  if (fdroppedParticleList) {
539  for (auto pn = fdroppedParticleList->begin(); pn != fdroppedParticleList->end(); pn++)
540  if ((*pn).first > highestID) highestID = (*pn).first;
541  }
542 
543  //Only change the fTrackIDOffset if there is in fact a particle to add to the event
544  if ((fparticleList->size()) != 0) { fTrackIDOffset = highestID + 1; }
545 
546  return std::move(*fparticleList);
547  } // ParticleList&& ParticleListAction::YieldList()
std::unique_ptr< sim::ParticleList > fdroppedParticleList
std::unique_ptr< sim::ParticleList > fparticleList

Member Data Documentation

int larg4::ParticleListAction::fCurrentOrigTrackID = sim::NoParticleId
staticprivate

except for EM shower particles where it always shows the original track ID

g4 real track ID of the current particle (including for EM shower daughters)

Definition at line 190 of file ParticleListAction.h.

ParticleInfo_t larg4::ParticleListAction::fCurrentParticle
private

information about the particle currently being simulated for a single particle.

Definition at line 179 of file ParticleListAction.h.

int larg4::ParticleListAction::fCurrentPdgCode = 0
staticprivate

pdg code of current particle

Definition at line 192 of file ParticleListAction.h.

int larg4::ParticleListAction::fCurrentTrackID = sim::NoParticleId
staticprivate

track ID of the current particle, set to eve ID for EM shower particles

Definition at line 188 of file ParticleListAction.h.

std::unique_ptr<sim::ParticleList> larg4::ParticleListAction::fdroppedParticleList
private

The accumulated particle information for all dropped particles in the event.

Definition at line 183 of file ParticleListAction.h.

G4double larg4::ParticleListAction::fenergyCut
private

The minimum energy for a particle to be included in the list.

Definition at line 177 of file ParticleListAction.h.

std::unique_ptr<util::PositionInVolumeFilter> larg4::ParticleListAction::fFilter
private

filter for particles to be kept

Definition at line 197 of file ParticleListAction.h.

bool larg4::ParticleListAction::fKeepEMShowerDaughters
private

whether to keep EM shower secondaries, tertiaries, etc

Definition at line 195 of file ParticleListAction.h.

std::map<int, int> larg4::ParticleListAction::fParentIDMap
private

key is current track ID, value is parent ID

Definition at line 186 of file ParticleListAction.h.

std::map<int, int> larg4::ParticleListAction::fParentIDMap_OrigTrackID
private

key is current track ID, value is parent ID – for real G4 track ID tracking only

Definition at line 187 of file ParticleListAction.h.

std::unique_ptr<sim::ParticleList> larg4::ParticleListAction::fparticleList
private

The accumulated particle information for all particles in the event.

Definition at line 181 of file ParticleListAction.h.

std::map<int, GeneratedParticleIndex_t> larg4::ParticleListAction::fPrimaryTruthMap
private

Map: particle track ID -> index of primary information in MC truth.

Definition at line 200 of file ParticleListAction.h.

G4bool larg4::ParticleListAction::fstoreTrajectories
private

Whether to store particle trajectories with each particle.

Definition at line 185 of file ParticleListAction.h.

int larg4::ParticleListAction::fTrackIDOffset = 0
staticprivate

offset added to track ids when running over multiple MCTruth objects.

Definition at line 193 of file ParticleListAction.h.


The documentation for this class was generated from the following files: