All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ParticleListAction.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file ParticleListAction.h
3 /// \brief Use Geant4's user "hooks" to maintain a list of particles generated by Geant4.
4 ///
5 /// \author seligman@nevis.columbia.edu
6 ////////////////////////////////////////////////////////////////////////
7 
8 /// This class implements the LArG4::UserAction interface in order to
9 /// accumulate a list of particles modeled by Geant4.
10 //
11 /// It uses multiple inheritance: it inherits from LArG4::UserAction,
12 /// in order to take advantage of Geant4's user hooks; it also
13 /// inherits from cfg::Observer, because it accesses a parameter from
14 /// an XML configuration file.
15 
16 #ifndef LArG4_ParticleListAction_h
17 #define LArG4_ParticleListAction_h
18 
19 #include "Geant4/G4Types.hh"
20 #include "TLorentzVector.h"
21 
22 #include "cetlib/exempt_ptr.h"
23 #include "larcorealg/CoreUtils/ParticleFilters.h" // util::PositionInVolumeFilter
24 #include "nug4/G4Base/UserAction.h"
25 #include "nusimdata/SimulationBase/simb.h" // simb::GeneratedParticleIndex_t
26 
27 #include <map>
28 #include <memory>
29 
30 // Forward declarations.
31 class G4Event;
32 class G4Track;
33 class G4Step;
34 
35 namespace sim {
36  class ParticleList;
37 }
38 
39 namespace simb {
40  class MCParticle;
41 }
42 
43 namespace larg4 {
44 
45  class ParticleListAction : public g4b::UserAction {
46  public:
47  using GeneratedParticleIndex_t = simb::GeneratedParticleIndex_t;
48 
49  struct ParticleInfo_t {
50 
51  cet::exempt_ptr<simb::MCParticle> particle; ///< Object representing particle.
52  bool keep = false; ///< if there was decision to keep
53  bool drop = false; ///< For EM shower daughters, whether to drop them (independently of `keep`)
54  /// Index of the particle in the original generator truth record.
55  GeneratedParticleIndex_t truthIndex = simb::NoGeneratedParticleIndex;
56 
57  /// Resets the information (does not release memory it does not own)
58  void
60  {
61  particle = nullptr;
62  keep = false;
63  drop = false;
64  truthIndex = simb::NoGeneratedParticleIndex;
65  }
66 
67  /// Returns whether there is a particle
68  bool
69  hasParticle() const
70  {
71  return !particle.empty();
72  }
73 
74  /// Returns whether there is a particle
75  bool
76  isPrimary() const
77  {
78  return simb::isGeneratedParticleIndex(truthIndex);
79  }
80 
81  /// Returns whether there is a particle known to be kept
82  bool
83  keepParticle() const
84  {
85  return hasParticle() && keep;
86  }
87 
88  /// Returns the index of the particle in the generator truth record.
91  {
92  return truthIndex;
93  }
94 
95  }; // ParticleInfo_t
96 
97  // Standard constructors and destructors;
98  ParticleListAction(double energyCut,
99  bool storeTrajectories = false,
100  bool keepEMShowerDaughters = false,
101  bool keepMCParticleList = true,
102  bool storeDroppedMCParticles = false);
103 
104  // UserActions method that we'll override, to obtain access to
105  // Geant4's particle tracks and trajectories.
106  virtual void BeginOfEventAction(const G4Event*);
107  virtual void EndOfEventAction(const G4Event*);
108  virtual void PreTrackingAction(const G4Track*);
109  virtual void PostTrackingAction(const G4Track*);
110  virtual void SteppingAction(const G4Step*);
111 
112  /// Grabs a particle filter
113  void
114  ParticleFilter(std::unique_ptr<util::PositionInVolumeFilter>&& filter)
115  {
116  fFilter = std::move(filter);
117  }
118 
119  // TrackID of the current particle, EveID if the particle is from an EM shower
120  static int
122  {
123  return fCurrentTrackID;
124  }
125  static int
127  {
128  return fCurrentOrigTrackID;
129  }
130  static int
132  {
133  return fCurrentPdgCode;
134  }
135 
136  void
138  {
139  fTrackIDOffset = 0;
140  }
141 
142  // Returns the ParticleList accumulated during the current event.
143  const sim::ParticleList* GetList() const;
144 
145  /// Returns a map of truth record information index for each of the primary
146  /// particles (by track ID).
147  std::map<int, GeneratedParticleIndex_t> const&
149  {
150  return fPrimaryTruthMap;
151  }
152 
153  /// Returns whether a particle list is being kept.
154  bool
155  hasList() const
156  {
157  return static_cast<bool>(fparticleList);
158  }
159 
160  /// Returns the index of primary truth (`sim::NoGeneratorIndex` if none).
162 
163  // Yields the ParticleList accumulated during the current event.
164  sim::ParticleList&& YieldList();
165 
166  /// Yields the (dropped) ParticleList accumulated during the current event.
167  sim::ParticleList&& YieldDroppedList();
168 
169  /// returns whether the specified particle has been marked as dropped
170  static bool isDropped(simb::MCParticle const* p);
171 
172  private:
173  // this method will loop over the fParentIDMap to get the
174  // parentage of the provided trackid
175  int GetParentage(int trackid, bool useOrigTrackIDMap = false) const;
176 
177  G4double fenergyCut; ///< The minimum energy for a particle to
178  ///< be included in the list.
179  ParticleInfo_t fCurrentParticle; ///< information about the particle currently being simulated
180  ///< for a single particle.
181  std::unique_ptr<sim::ParticleList> fparticleList; ///< The accumulated particle information for
182  ///< all particles in the event.
183  std::unique_ptr<sim::ParticleList> fdroppedParticleList; ///< The accumulated particle information for
184  ///< all dropped particles in the event.
185  G4bool fstoreTrajectories; ///< Whether to store particle trajectories with each particle.
186  std::map<int, int> fParentIDMap; ///< key is current track ID, value is parent ID
187  std::map<int, int> fParentIDMap_OrigTrackID; ///< key is current track ID, value is parent ID -- for real G4 track ID tracking only
188  static int fCurrentTrackID; ///< track ID of the current particle, set to eve ID
189  ///< for EM shower particles
190  static int fCurrentOrigTrackID; ///< g4 real track ID of the current particle (including for EM shower daughters)
191  ///< except for EM shower particles where it always shows the original track ID
192  static int fCurrentPdgCode; ///< pdg code of current particle
193  static int fTrackIDOffset; ///< offset added to track ids when running over
194  ///< multiple MCTruth objects.
195  bool fKeepEMShowerDaughters; ///< whether to keep EM shower secondaries, tertiaries, etc
196 
197  std::unique_ptr<util::PositionInVolumeFilter> fFilter; ///< filter for particles to be kept
198 
199  /// Map: particle track ID -> index of primary information in MC truth.
200  std::map<int, GeneratedParticleIndex_t> fPrimaryTruthMap;
201 
202  /// Adds a trajectory point to the current particle, and runs the filter
203  void AddPointToCurrentParticle(TLorentzVector const& pos,
204  TLorentzVector const& mom,
205  std::string const& process);
206  };
207 
208 } // namespace LArG4
209 
210 #endif // LArG4_ParticleListAction_h
ParticleListAction(double energyCut, bool storeTrajectories=false, bool keepEMShowerDaughters=false, bool keepMCParticleList=true, bool storeDroppedMCParticles=false)
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.
static int fCurrentPdgCode
pdg code of current particle
virtual void BeginOfEventAction(const G4Event *)
std::map< int, GeneratedParticleIndex_t > fPrimaryTruthMap
Map: particle track ID -&gt; index of primary information in MC truth.
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
bool keepParticle() const
Returns whether there is a particle known to be kept.
pdgs p
Definition: selectors.fcl:22
const sim::ParticleList * GetList() const
GeneratedParticleIndex_t truthInfoIndex() const
Returns the index of the particle in the generator truth record.
std::map< int, int > fParentIDMap
key is current track ID, value is parent ID
virtual void PreTrackingAction(const G4Track *)
BEGIN_PROLOG note Geant4 assumes this is in MeV keepEMShowerDaughters
void clear()
Resets the information (does not release memory it does not own)
sim::ParticleList && YieldList()
static bool isDropped(simb::MCParticle const *p)
returns whether the specified particle has been marked as dropped
bool fKeepEMShowerDaughters
whether to keep EM shower secondaries, tertiaries, etc
virtual void PostTrackingAction(const G4Track *)
simb::GeneratedParticleIndex_t GeneratedParticleIndex_t
sim::ParticleList && YieldDroppedList()
Yields the (dropped) ParticleList accumulated during the current event.
void ParticleFilter(std::unique_ptr< util::PositionInVolumeFilter > &&filter)
Grabs a particle filter.
GeneratedParticleIndex_t GetPrimaryTruthIndex(int trackId) const
Returns the index of primary truth (sim::NoGeneratorIndex if none).
std::unique_ptr< util::PositionInVolumeFilter > fFilter
filter for particles to be kept
std::unique_ptr< sim::ParticleList > fparticleList
physics filters filter
bool isPrimary() const
Returns whether there is a particle.
cet::exempt_ptr< simb::MCParticle > particle
Object representing particle.
bool hasList() const
Returns whether a particle list is being kept.
BEGIN_PROLOG note Geant4 assumes this is in MeV does not store electromagnetic shower daughter storeTrajectories
static int fCurrentOrigTrackID
except for EM shower particles where it always shows the original track ID
virtual void EndOfEventAction(const G4Event *)
bool hasParticle() const
Returns whether there is a particle.
Defines classes to filter particles based on their trajectory.
virtual void SteppingAction(const G4Step *)
std::map< int, GeneratedParticleIndex_t > const & GetPrimaryTruthMap() const
bool keep
if there was decision to keep