LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ParticleListAction_service.h
Go to the documentation of this file.
1 //
8 // accumulate a list of particles modeled by Geant4.
9 //
10 
11 // Include guard
12 #ifndef PARTICLELISTACTION_SERVICE_H
13 #define PARTICLELISTACTION_SERVICE_H
14 
17 
20 
24 
26 
29 #include "nusimdata/SimulationBase/simb.h" // simb::GeneratedParticleIndex_t
30 
33 
36 
40 
41 namespace art {
42  class EDProductGetter;
43 }
44 
46 
47 #include "Geant4/globals.hh"
48 
49 class G4Event;
50 class G4Track;
51 class G4Step;
52 
53 class TLorentzVector;
54 
55 #include <map>
56 #include <memory>
57 #include <set>
58 #include <string>
59 #include <unordered_map>
60 #include <utility>
61 #include <vector>
62 
63 namespace larg4 {
64 
68  public:
69  // Standard constructors and destructors;
71 
72  // UserActions method that we'll override, to obtain access to
73  // Geant4's particle tracks and trajectories.
74  void preUserTrackingAction(const G4Track*) override;
75  void postUserTrackingAction(const G4Track*) override;
76  void userSteppingAction(const G4Step*) override;
77 
79  simb::GeneratedParticleIndex_t GetPrimaryTruthIndex(int trackId) const;
80 
81  // Called at the beginning of each event (note that this is after the
82  // primaries have been generated and sent to the event manager)
83  void beginOfEventAction(const G4Event*) override;
84 
85  // Called at the end of each event, right before GEANT's state switches
86  // out of event processing and into closed geometry (last chance to access
87  // the current event).
88  void endOfEventAction(const G4Event*) override;
89 
90  // Set/get the current Art event
91  void setInputCollections(std::vector<art::Handle<std::vector<simb::MCTruth>>> const& mclists)
92  {
93  fMCLists = &mclists;
94  }
95 
96  void setPtrInfo(art::ProductID pid, art::EDProductGetter const* productGetter)
97  {
98  pid_ = pid;
99  productGetter_ = productGetter;
100  }
101 
102  std::unique_ptr<std::vector<simb::MCParticle>> ParticleCollection()
103  {
104  return std::move(partCol_);
105  }
106  std::unique_ptr<std::vector<simb::MCParticle>> DroppedParticleCollection()
107  {
108  return std::move(droppedPartCol_);
109  }
110  std::unique_ptr<sim::ParticleAncestryMap> DroppedTracksCollection()
111  {
112  return std::move(droppedCol_);
113  }
114 
115  std::unique_ptr<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>
117  {
118  return std::move(tpassn_);
119  }
120 
121  std::map<int, int> GetTargetIDMap() { return fTargetIDMap; }
122 
124  void CreateParticleFilter(std::vector<std::string> keepParticlesInVolumes,
125  std::unique_ptr<util::PositionInVolumeFilter>& filter)
126  {
127  // if we don't have favourite volumes, don't even bother creating a filter
128  std::set<std::string> vol_names(keepParticlesInVolumes.begin(), keepParticlesInVolumes.end());
129 
130  if (empty(vol_names)) filter = {};
131 
132  auto const& geom = *art::ServiceHandle<geo::Geometry const>();
133 
134  std::vector<std::vector<TGeoNode const*>> node_paths = geom.FindAllVolumePaths(vol_names);
135 
136  // collection of interesting volumes
138  GeoVolumePairs.reserve(node_paths.size()); // because we are obsessed
139 
140  //for each interesting volume, follow the node path and collect
141  //total rotations and translations
142  for (size_t iVolume = 0; iVolume < node_paths.size(); ++iVolume) {
143  std::vector<TGeoNode const*> path = node_paths[iVolume];
144 
145  auto pTransl = new TGeoTranslation(0., 0., 0.);
146  auto pRot = new TGeoRotation();
147  for (TGeoNode const* node : path) {
148  TGeoTranslation thistranslate(*node->GetMatrix());
149  TGeoRotation thisrotate(*node->GetMatrix());
150  pTransl->Add(&thistranslate);
151  *pRot = *pRot * thisrotate;
152  }
153 
154  // for some reason, pRot and pTransl don't have tr and rot bits set
155  // correctly make new translations and rotations so bits are set correctly
156  auto pTransl2 = new TGeoTranslation(
157  pTransl->GetTranslation()[0], pTransl->GetTranslation()[1], pTransl->GetTranslation()[2]);
158  double phi = 0., theta = 0., psi = 0.;
159  pRot->GetAngles(phi, theta, psi);
160  auto pRot2 = new TGeoRotation();
161  pRot2->SetAngles(phi, theta, psi);
162 
163  auto pTransf = new TGeoCombiTrans(*pTransl2, *pRot2);
164  GeoVolumePairs.emplace_back(node_paths[iVolume].back()->GetVolume(), pTransf);
165  }
166 
167  filter = std::make_unique<util::PositionInVolumeFilter>(std::move(GeoVolumePairs));
168  }
169  void ParticleFilter() { CreateParticleFilter(fKeepParticlesInVolumes, fFilter); }
171  {
172  CreateParticleFilter(fKeepDroppedParticlesInVolumes, fDroppedFilter);
173  }
175  bool storeDropped() const { return fStoreDroppedMCParticles; }
176 
177  private:
178  struct ParticleInfo_t {
179  simb::MCParticle* particle = nullptr;
180  bool keepFullTrajectory = false;
181  bool isInVolume = false;
182  bool isDropped = false;
183 
186 
188  void clear()
189  {
190  particle = nullptr;
191  keepFullTrajectory = false;
192  isInVolume = false;
193  isDropped = false;
194  truthIndex = simb::NoGeneratedParticleIndex;
195  }
196 
198  bool hasParticle() const { return particle; }
199 
201  bool isPrimary() const { return simb::isGeneratedParticleIndex(truthIndex); }
202 
204  simb::GeneratedParticleIndex_t truthInfoIndex() const { return truthIndex; }
205 
207  void print()
208  {
209  std::cout << "ParticleInfo_t: " << std::endl;
210  std::cout << " particle: " << particle << std::endl;
211  std::cout << " keepFullTrajectory: " << keepFullTrajectory << std::endl;
212  std::cout << " isInVolume: " << isInVolume << std::endl;
213  std::cout << " isDropped: " << isDropped << std::endl;
214  std::cout << " truthIndex: " << truthIndex << std::endl;
215  }
216 
217  }; // ParticleInfo_t
218 
219  // Returns whether the particle was dropped
220  bool isDropped(simb::MCParticle const* p);
221 
222  // Yields the ParticleList accumulated during the current event.
223  sim::ParticleList&& YieldList();
224 
225  // Yields the (dropped) ParticleList accumulated during the current event.
226  sim::ParticleList&& YieldDroppedList();
227 
228  // this method will loop over the fParentIDMap to get the
229  // parentage of the provided trackid
230  int GetParentage(int trackid) const;
231 
232  G4double fenergyCut;
233  ParticleInfo_t fCurrentParticle;
235  sim::ParticleList fParticleList;
237  G4bool fstoreTrajectories;
239  std::vector<std::string>
241  std::map<int, int> fParentIDMap;
246  std::map<int, int>
249  mutable int fTrackIDOffset;
251  bool fKeepEMShowerDaughters;
253  std::vector<std::string> fNotStoredPhysics;
255  bool fSparsifyTrajectories;
260 
261  std::vector<std::string>
263 
264  std::vector<std::string> fKeepDroppedParticlesInVolumes;
265  bool
268 
269  std::unique_ptr<sim::ParticleList>
271  std::vector<art::Handle<std::vector<simb::MCTruth>>> const*
274 
276  std::map<int, simb::GeneratedParticleIndex_t> fPrimaryTruthMap;
277 
279  std::map<int, size_t> fMCTIndexMap;
280 
282  std::map<int, bool> fMCTPrimProcessKeepMap;
283 
285  std::map<size_t, std::pair<std::string, G4bool>> fMCTIndexToGeneratorMap;
286 
288  std::unordered_map<std::string, int> fNotStoredCounterUMap;
289 
291  std::map<int, std::set<int>> fdroppedTracksMap;
292 
293  std::unique_ptr<std::vector<simb::MCParticle>> partCol_;
295  std::unique_ptr<std::vector<simb::MCParticle>> droppedPartCol_;
296  std::unique_ptr<sim::ParticleAncestryMap> droppedCol_;
297  std::unique_ptr<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>
300  art::EDProductGetter const* productGetter_{nullptr};
301  std::unique_ptr<util::PositionInVolumeFilter> fFilter;
302  std::unique_ptr<util::PositionInVolumeFilter>
304  void AddPointToCurrentParticle(TLorentzVector const& pos,
306  TLorentzVector const& mom,
307  std::string const& process);
308  };
309 
310 } // namespace larg4
311 
313 
314 #endif // PARTICLELISTACTION_SERVICE_H
std::map< int, std::set< int > > fdroppedTracksMap
map <ParentID, set: list of track ids for which no MCParticle was created>
std::unique_ptr< sim::ParticleList > fdroppedParticleList
bool fKeepSecondToLast
tell whether or not to force keeping the second to last point
std::unique_ptr< art::Assns< simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo > > tpassn_
std::vector< VolumeInfo_t > AllVolumeInfo_t
std::unique_ptr< util::PositionInVolumeFilter > fFilter
filter for particles to be kept
Geant4 interface.
void CreateParticleFilter(std::vector< std::string > keepParticlesInVolumes, std::unique_ptr< util::PositionInVolumeFilter > &filter)
Grabs a particle filter.
double fSparsifyMargin
set the sparsification margin
Contains data associated to particles from detector simulation.
std::unique_ptr< std::vector< simb::MCParticle > > ParticleCollection()
Particle class.
Framework includes.
bool fKeepTransportation
tell whether or not to keep the transportation process
std::unique_ptr< art::Assns< simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo > > AssnsMCTruthToMCParticle()
std::unique_ptr< std::vector< simb::MCParticle > > partCol_
std::map< int, size_t > fMCTIndexMap
Map: particle track ID -> index of primary parent in std::vector<simb::MCTruth> object.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
std::vector< std::string > fKeepParticlesInVolumes
Only write particles that have trajectories through these volumes.
constexpr GeneratedParticleIndex_t NoGeneratedParticleIndex
Constant representing the absence of generator truth information.
Definition: simb.h:34
std::unique_ptr< std::vector< simb::MCParticle > > DroppedParticleCollection()
void setInputCollections(std::vector< art::Handle< std::vector< simb::MCTruth >>> const &mclists)
#define DECLARE_ART_SERVICE(svc, scope)
std::map< size_t, std::pair< std::string, G4bool > > fMCTIndexToGeneratorMap
Map: MCTruthIndex -> generator, input label of generator and keepGenerator decision.
std::unordered_map< std::string, int > fNotStoredCounterUMap
Map: not stored process and counter.
bool fStoreDroppedMCParticles
Whether to keep a sim::MCParticle list of dropped particles.
std::unique_ptr< sim::ParticleAncestryMap > DroppedTracksCollection()
std::unique_ptr< sim::ParticleAncestryMap > droppedCol_
bool storeDropped() const
Return whether dropped particles are stored.
std::map< int, int > fTargetIDMap
key is original track ID, value is ID to assign for downstream objs (e.g. SimEdeps) ...
std::unique_ptr< std::vector< simb::MCParticle > > droppedPartCol_
This collection will hold the MCParticleLite objects created from dropped particles.
bool isGeneratedParticleIndex(GeneratedParticleIndex_t index)
Returns whether the specified one is an acceptable generator index.
Definition: simb.h:37
std::vector< std::string > fKeepDroppedParticlesInVolumes
std::unique_ptr< util::PositionInVolumeFilter > fDroppedFilter
bool isPrimary() const
Returns whether there is a particle.
std::vector< std::string > fNotStoredPhysics
Physics processes that will not be stored.
simb::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::vector< std::string > fkeepGenTrajectories
std::map< int, bool > fMCTPrimProcessKeepMap
Map: particle trakc ID -> boolean decision to keep or not full trajectory points. ...
bool hasParticle() const
Returns whether there is a particle.
static constexpr ProductID invalid() noexcept
Definition: ProductID.h:26
std::map< int, simb::GeneratedParticleIndex_t > fPrimaryTruthMap
Map: particle track ID -> index of primary information in MC truth.
Definition: MVAAlg.h:12
Defines classes to filter particles based on their trajectory.
Particle list in DetSim contains Monte Carlo particle information.
std::vector< art::Handle< std::vector< simb::MCTruth > > > const * fMCLists
MCTruthCollection input lists.
void setPtrInfo(art::ProductID pid, art::EDProductGetter const *productGetter)
Common type definitions for data products (and a bit beyond).
art framework interface to geometry description
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
std::size_t GeneratedParticleIndex_t
Type of particle index in the generator truth record (simb::MCTruth).
Definition: simb.h:30