All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AssociationsTruth_tool.cc
Go to the documentation of this file.
2 
4 
5 #include "fhiclcpp/ParameterSet.h"
6 #include "art/Utilities/ToolMacros.h"
7 #include "art/Framework/Services/Registry/ServiceHandle.h"
8 #include "art/Framework/Core/ModuleMacros.h"
9 #include "art/Framework/Principal/Handle.h"
10 #include "canvas/Utilities/InputTag.h"
11 #include "messagefacility/MessageLogger/MessageLogger.h"
12 #include "canvas/Persistency/Common/FindManyP.h"
13 
15 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
19 #include "nusimdata/SimulationBase/MCTruth.h"
20 #include "nusimdata/SimulationBase/MCParticle.h"
21 
22 #include "nug4/ParticleNavigation/ParticleList.h"
23 #include "nug4/ParticleNavigation/EmEveIdCalculator.h"
24 
25 #include <cmath>
26 #include <algorithm>
27 
28 namespace truth
29 {
30 ////////////////////////////////////////////////////////////////////////
31 //
32 // Class: AssociationsTruth
33 // Module Type: art tool
34 // File: AssociationsTruth.h
35 //
36 // This provides MC truth information by using output
37 // reco Hit <--> MCParticle associations
38 //
39 // Configuration parameters:
40 //
41 // TruncMeanFraction - the fraction of waveform bins to discard when
42 //
43 // Created by Tracy Usher (usher@slac.stanford.edu) on November 21, 2017
44 //
45 ////////////////////////////////////////////////////////////////////////
46 
47 class AssociationsTruth : virtual public IMCTruthMatching
48 {
49 public:
50  /**
51  * @brief Constructor
52  *
53  * @param pset
54  */
55  explicit AssociationsTruth(fhicl::ParameterSet const & pset);
56 
57  /**
58  * @brief Destructor
59  */
61 
62  // provide for initialization
63  void reconfigure(fhicl::ParameterSet const & pset) override;
64 
65  /**
66  * @brief This rebuilds the internal maps
67  */
68  void Rebuild(const art::Event& evt) override;
69 
70  /**
71  * @brief Get a reference to the ParticleList
72  */
73  const sim::ParticleList& ParticleList() const override;
74 
75  // Set the EveIdCalculator for the owned ParticleList
76 // void SetEveIdCalculator(MCTruthEveIdCalculator *ec) { fParticleList.AdoptEveIdCalculator(ec); }
77 
78  // Return a pointer to the simb::MCParticle object corresponding to
79  // the given TrackID
80  const simb::MCParticle* TrackIDToParticle(int const id) const override {return fMCTruthAssociations.TrackIDToParticle(id);}
81  const simb::MCParticle* TrackIDToMotherParticle(int const id) const override {return fMCTruthAssociations.TrackIDToMotherParticle(id);}
82 
83  // Get art::Ptr<> to simb::MCTruth and related information
84  const art::Ptr<simb::MCTruth>& TrackIDToMCTruth(int id) const override;
85  const art::Ptr<simb::MCTruth>& ParticleToMCTruth(const simb::MCParticle* p) const override;
86  std::vector<const simb::MCParticle*> MCTruthToParticles(art::Ptr<simb::MCTruth> const& mct) const override;
87  const std::vector< art::Ptr<simb::MCTruth> >& MCTruthVector() const override;
88 
89  // this method will return the Geant4 track IDs of
90  // the particles contributing ionization electrons to the identified hit
91  std::vector<sim::TrackIDE> HitToTrackID(detinfo::DetectorClocksData const&,
92  recob::Hit const& hit) const override;
93  std::vector<sim::TrackIDE> HitToTrackID(detinfo::DetectorClocksData const&,
94  art::Ptr<recob::Hit> const& hit) const override;
95 
96  // method to return a subset of allhits that are matched to a list of TrackIDs
97  std::vector<std::vector<art::Ptr<recob::Hit>>> TrackIDsToHits(detinfo::DetectorClocksData const& clockData,
98  std::vector<art::Ptr<recob::Hit>> const& allhits,
99  std::vector<int> const& tkIDs) const override;
100 
101  // method to return the EveIDs of particles contributing ionization
102  // electrons to the identified hit
103  std::vector<sim::TrackIDE> HitToEveID(detinfo::DetectorClocksData const& clockData,
104  art::Ptr<recob::Hit> const& hit) const override;
105 
106  // method to return the XYZ position of the weighted average energy deposition for a given hit
107  std::vector<double> HitToXYZ(detinfo::DetectorClocksData const&,
108  art::Ptr<recob::Hit> const& hit) const override;
109 
110  // method to return the XYZ position of a space point (unweighted average XYZ of component hits).
111  std::vector<double> SpacePointToXYZ(detinfo::DetectorClocksData const& clockData,
112  art::Ptr<recob::SpacePoint> const& spt,
113  art::Event const& evt,
114  std::string const& label) const override;
115 
116  // method to return the XYZ position of a space point (unweighted average XYZ of component hits).
117  std::vector<double> SpacePointHitsToXYZ(detinfo::DetectorClocksData const& clockData,
118  art::PtrVector<recob::Hit> const& hits) const override;
119 
120  // method to return the fraction of hits in a collection that come from the specified Geant4 track ids
122  std::set<int> const& trackIDs,
123  std::vector< art::Ptr<recob::Hit> > const& hits) const override;
124 
125  // method to return the fraction of all hits in an event from a specific set of Geant4 track IDs that are
126  // represented in a collection of hits
128  std::set<int> const& trackIDs,
129  std::vector< art::Ptr<recob::Hit> > const& hits,
130  std::vector< art::Ptr<recob::Hit> > const& allhits,
131  geo::View_t const view) const override;
132 
133  // method to return the fraction of charge in a collection that come from the specified Geant4 track ids
135  std::set<int> const& trackIDs,
136  std::vector< art::Ptr<recob::Hit> > const& hits) const override;
137 
138  // method to return the fraction of all charge in an event from a specific set of Geant4 track IDs that are
139  // represented in a collection of hits
141  std::set<int> const& trackIDs,
142  std::vector< art::Ptr<recob::Hit> > const& hits,
143  std::vector< art::Ptr<recob::Hit> > const& allhits,
144  geo::View_t const view) const override;
145 
146  // method to return all EveIDs corresponding to the current sim::ParticleList
147  std::set<int> GetSetOfEveIDs() const override;
148 
149  // method to return all TrackIDs corresponding to the current sim::ParticleList
150  std::set<int> GetSetOfTrackIDs() const override;
151 
152  // method to return all EveIDs corresponding to the given list of hits
153  std::set<int> GetSetOfEveIDs(detinfo::DetectorClocksData const& clockData,
154  std::vector< art::Ptr<recob::Hit> > const& hits) const override;
155 
156  // method to return all TrackIDs corresponding to the given list of hits
157  std::set<int> GetSetOfTrackIDs(detinfo::DetectorClocksData const&,
158  std::vector< art::Ptr<recob::Hit> > const& hits) const override;
159 
160 private:
161 
162  // Fcl parameters.
163  std::vector<art::InputTag> fAssnsProducerLabels; ///< tag for finding the tracks
164  art::InputTag fG4ProducerLabel; ///< Input tag for G4 producer (MCParticle/MCTruth)
165 
166  // The class that does all the work...
167  MCTruthAssociations fMCTruthAssociations; ///< The class that does the work
168 
169  // Hopefully we can get rid of this soon
170  sim::ParticleList fParticleList;
171 
172  // Useful services, keep copies for now (we can update during begin run periods)
173  const geo::GeometryCore* fGeometry; ///< pointer to Geometry service
174 };
175 
176 //----------------------------------------------------------------------------
177 /// Constructor.
178 ///
179 /// Arguments:
180 ///
181 /// pset - Fcl parameters.
182 ///
183 AssociationsTruth::AssociationsTruth(fhicl::ParameterSet const & pset) :
184  fMCTruthAssociations(pset.get<fhicl::ParameterSet>("MCTruthAssociations"))
185 {
186  fGeometry = lar::providerFrom<geo::Geometry>();
187 
188  reconfigure(pset);
189 
190  // Report.
191  mf::LogInfo("AssociationsTruth") << "AssociationsTruth configured\n";
192 }
193 
194 //----------------------------------------------------------------------------
195 /// Destructor.
197 {}
198 
199 //----------------------------------------------------------------------------
200 /// Reconfigure method.
201 ///
202 /// Arguments:
203 ///
204 /// pset - Fcl parameter set.
205 ///
206 void AssociationsTruth::reconfigure(fhicl::ParameterSet const & pset)
207 {
208  fAssnsProducerLabels = pset.get<std::vector<art::InputTag>>("AssnsProducerLabels");
209  fG4ProducerLabel = pset.get<art::InputTag> ("G4ProducerLabel");
210 }
211 
212 //----------------------------------------------------------------------------
213 /// Rebuild method -> rebuild the basic maps to get truth information
214 ///
215 /// Arguments:
216 ///
217 /// event - the art event used to extract all information
218 ///
219 void AssociationsTruth::Rebuild(const art::Event& evt)
220 {
221  // Create a container for testing
222  HitParticleAssociationsVec partHitAssnsVec;
223 
224  // Get a handle for the associations...
225  art::Handle<art::Assns<simb::MCParticle, recob::Hit, anab::BackTrackerHitMatchingData>> partHitAssnsHandle;
226 
227  for(const auto& assnsProducerLabel : fAssnsProducerLabels)
228  {
229  evt.getByLabel(assnsProducerLabel, partHitAssnsHandle);
230 
231  if (!partHitAssnsHandle.isValid())
232  {
233  throw cet::exception("AssociationsTruth") << "===>> NO MCParticle <--> Hit associations found for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event() << std::endl;
234  }
235 
236  partHitAssnsVec.emplace_back(&*partHitAssnsHandle);
237  }
238 
239  // Recover the associations between MCTruth and MCParticles
240  art::Handle<std::vector<simb::MCParticle>> mcParticleHandle;
241  evt.getByLabel(fG4ProducerLabel, mcParticleHandle);
242 
243  std::vector<art::Ptr<simb::MCParticle>> mcParticlePtrVec;
244  art::fill_ptr_vector(mcParticlePtrVec, mcParticleHandle);
245 
246  MCTruthAssns mcTruthAssns(mcParticleHandle, evt, fG4ProducerLabel);
247 
248  // Pass this to the truth associations code
249  fMCTruthAssociations.setup(partHitAssnsVec, mcParticlePtrVec, mcTruthAssns, *fGeometry);
250 
251  // Ugliness to follow! Basically, we need to build the "particle list" and the current implementation of
252  // that code requires a copy...
253  const MCTruthParticleList& locParticleList = fMCTruthAssociations.getParticleList();
254 
255  // Clear the current container
256  fParticleList.clear();
257 
258  // Now we add particles back in one at a time...
259  for(const auto& element : locParticleList)
260  {
261  fParticleList.Add(new simb::MCParticle(*(element.second)));
262  }
263 
264  // Just to be consistent with the backtracker...
265  fParticleList.AdoptEveIdCalculator(new sim::EmEveIdCalculator);
266 }
267 
268 //----------------------------------------------------------------------
269 const sim::ParticleList& AssociationsTruth::ParticleList() const
270 {
271  // Unfortunately, this requires special handling at the moment...
272  return fParticleList;
273 }
274 
275 //----------------------------------------------------------------------
276 const art::Ptr<simb::MCTruth>& AssociationsTruth::TrackIDToMCTruth(int const id) const
277 {
279 }
280 
281 //----------------------------------------------------------------------
282 const art::Ptr<simb::MCTruth>& AssociationsTruth::ParticleToMCTruth(const simb::MCParticle* p) const
283 {
285 }
286 
287 //----------------------------------------------------------------------
288 std::vector<const simb::MCParticle*> AssociationsTruth::MCTruthToParticles(art::Ptr<simb::MCTruth> const& mct) const
289 {
291 }
292 
293 //----------------------------------------------------------------------
294 const std::vector< art::Ptr<simb::MCTruth> >& AssociationsTruth::MCTruthVector() const
295 {
297 }
298 
299 //----------------------------------------------------------------------
301  recob::Hit const& hit) const
302 {
303  std::vector<truth::TrackIDE> locTrackIDEVec = fMCTruthAssociations.HitToTrackID(&hit);
304  std::vector<sim::TrackIDE> outputVec;
305 
306  outputVec.reserve(locTrackIDEVec.size());
307 
308  for(const auto& trackIDE : locTrackIDEVec) outputVec.emplace_back(trackIDE.trackID,trackIDE.energyFrac,trackIDE.energy,trackIDE.numElectrons);
309 
310  return outputVec;
311 }
312 
313 //----------------------------------------------------------------------
314 std::vector<sim::TrackIDE> AssociationsTruth::HitToTrackID(detinfo::DetectorClocksData const& clockData,
315  art::Ptr<recob::Hit> const& hit) const
316 {
317  return HitToTrackID(clockData, *hit);
318 }
319 
320 //----------------------------------------------------------------------
321 std::vector<std::vector<art::Ptr<recob::Hit>>> AssociationsTruth::TrackIDsToHits(detinfo::DetectorClocksData const&,
322  std::vector<art::Ptr<recob::Hit>> const& allhits,
323  std::vector<int> const& tkIDs) const
324 {
325  return fMCTruthAssociations.TrackIDsToHits(allhits,tkIDs);
326 }
327 
328 //----------------------------------------------------------------------
329 // plist is assumed to have adopted the appropriate EveIdCalculator prior to
330 // having been passed to this method. It is likely that the EmEveIdCalculator is
331 // the one you always want to use
333  art::Ptr<recob::Hit> const& hit) const
334 {
335  std::vector<truth::TrackIDE> locTrackIDEVec = fMCTruthAssociations.HitToEveID(hit);
336  std::vector<sim::TrackIDE> outputVec;
337 
338  outputVec.reserve(locTrackIDEVec.size());
339 
340  for(const auto& trackIDE : locTrackIDEVec) outputVec.emplace_back(trackIDE.trackID,trackIDE.energyFrac,trackIDE.energy,trackIDE.numElectrons);
341 
342  return outputVec;
343 }
344 
345 //----------------------------------------------------------------------
347 {
349 }
350 
351 //----------------------------------------------------------------------
353 {
355 }
356 
357 //----------------------------------------------------------------------
359  std::vector< art::Ptr<recob::Hit> > const& hits) const
360 {
362 }
363 
364 //----------------------------------------------------------------------
366  std::vector< art::Ptr<recob::Hit> > const& hits) const
367 {
369 }
370 
371 //----------------------------------------------------------------------
373  std::set<int> const& trackIDs,
374  std::vector< art::Ptr<recob::Hit> > const& hits) const
375 {
376  return fMCTruthAssociations.HitCollectionPurity(trackIDs, hits);
377 }
378 
379 //----------------------------------------------------------------------
381  std::set<int> const& trackIDs,
382  std::vector< art::Ptr<recob::Hit> > const& hits) const
383 {
384  return fMCTruthAssociations.HitChargeCollectionPurity(trackIDs, hits);
385 }
386 
387 
388 //----------------------------------------------------------------------
390  std::set<int> const& trackIDs,
391  std::vector< art::Ptr<recob::Hit> > const& hits,
392  std::vector< art::Ptr<recob::Hit> > const& allhits,
393  geo::View_t const view) const
394 {
395  return fMCTruthAssociations.HitCollectionEfficiency(trackIDs, hits, allhits, view);
396 }
397 
398 //----------------------------------------------------------------------
400  std::set<int> const& trackIDs,
401  std::vector< art::Ptr<recob::Hit> > const& hits,
402  std::vector< art::Ptr<recob::Hit> > const& allhits,
403  geo::View_t const view) const
404 {
405  return fMCTruthAssociations.HitChargeCollectionEfficiency(trackIDs, hits, allhits, view);
406 }
407 
408 //----------------------------------------------------------------------
410  art::Ptr<recob::Hit> const& hit) const
411 {
412  return fMCTruthAssociations.HitToXYZ(hit);
413 }
414 
415 //----------------------------------------------------------------------
417  art::Ptr<recob::SpacePoint> const& spt,
418  art::Event const& evt,
419  std::string const& label) const
420 {
421  // Get hits that make up this space point.
422  art::PtrVector<recob::SpacePoint> spv;
423  spv.push_back(spt);
424  art::FindManyP<recob::Hit> fmh(spv, evt, label);
425  std::vector< art::Ptr<recob::Hit> > hitv = fmh.at(0);
426 
427  // make a PtrVector
428  art::PtrVector<recob::Hit> hits;
429  for(size_t h = 0; h < hitv.size(); ++h) hits.push_back(hitv[h]);
430 
431  return this->SpacePointHitsToXYZ(clockData, hits);
432 }
433 
434 //----------------------------------------------------------------------
436  art::PtrVector<recob::Hit> const& hits) const
437 {
439 }
440 
441 //----------------------------------------------------------------------------
442 
443 DEFINE_ART_CLASS_TOOL(AssociationsTruth)
444 }
const art::Ptr< simb::MCTruth > & TrackIDToMCTruth(int id) const override
Utilities related to art service access.
double HitChargeCollectionEfficiency(std::set< int >, std::vector< art::Ptr< recob::Hit > > const &, std::vector< art::Ptr< recob::Hit > > const &, geo::View_t const &) const
double HitCollectionEfficiency(detinfo::DetectorClocksData const &, std::set< int > const &trackIDs, std::vector< art::Ptr< recob::Hit > > const &hits, std::vector< art::Ptr< recob::Hit > > const &allhits, geo::View_t const view) const override
const std::vector< std::vector< art::Ptr< recob::Hit > > > TrackIDsToHits(std::vector< art::Ptr< recob::Hit >> const &, std::vector< int > const &) const
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Declaration of signal hit object.
pdgs p
Definition: selectors.fcl:22
const simb::MCParticle * TrackIDToParticle(int const id) const override
This provides an interface which defines truth matching functions made available to downstream analys...
double HitChargeCollectionPurity(detinfo::DetectorClocksData const &, std::set< int > const &trackIDs, std::vector< art::Ptr< recob::Hit > > const &hits) const override
std::vector< TrackIDE > HitToEveID(art::Ptr< recob::Hit > const &hit) const
const geo::GeometryCore * fGeometry
pointer to Geometry service
double HitCollectionPurity(detinfo::DetectorClocksData const &, std::set< int > const &trackIDs, std::vector< art::Ptr< recob::Hit > > const &hits) const override
std::vector< std::vector< art::Ptr< recob::Hit > > > TrackIDsToHits(detinfo::DetectorClocksData const &clockData, std::vector< art::Ptr< recob::Hit >> const &allhits, std::vector< int > const &tkIDs) const override
AssociationsTruth(fhicl::ParameterSet const &pset)
Constructor.
void Rebuild(const art::Event &evt) override
This rebuilds the internal maps.
process_name hit
Definition: cheaterreco.fcl:51
MCTruthAssociations fMCTruthAssociations
The class that does the work.
art::FindOneP< simb::MCTruth > MCTruthAssns
std::vector< art::InputTag > fAssnsProducerLabels
tag for finding the tracks
const simb::MCParticle * TrackIDToMotherParticle(int const &id) const
std::vector< TrackIDE > HitToTrackID(const recob::Hit *) const
std::vector< sim::TrackIDE > HitToTrackID(detinfo::DetectorClocksData const &, recob::Hit const &hit) const override
while getopts h
const sim::ParticleList & ParticleList() const override
Get a reference to the ParticleList.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
const std::vector< art::Ptr< simb::MCTruth > > & MCTruthVector() const override
const art::Ptr< simb::MCTruth > & ParticleToMCTruth(const simb::MCParticle *p) const override
std::set< int > GetSetOfTrackIDs() const
This algorithm attempts to decode Track and Hit &lt;–&gt; MCParticle assocations.
std::set< int > GetSetOfEveIDs() const
void reconfigure(fhicl::ParameterSet const &pset) override
Obtains truth matching by using hit &lt;–&gt; MCParticle associations.
const simb::MCParticle * TrackIDToMotherParticle(int const id) const override
double HitCollectionPurity(std::set< int >, std::vector< art::Ptr< recob::Hit > > const &) const
std::vector< double > HitToXYZ(detinfo::DetectorClocksData const &, art::Ptr< recob::Hit > const &hit) const override
const art::Ptr< simb::MCTruth > & TrackIDToMCTruth(int const &id) const
std::vector< sim::TrackIDE > HitToEveID(detinfo::DetectorClocksData const &clockData, art::Ptr< recob::Hit > const &hit) const override
double HitCollectionEfficiency(std::set< int >, std::vector< art::Ptr< recob::Hit > > const &, std::vector< art::Ptr< recob::Hit > > const &, geo::View_t const &) const
double HitChargeCollectionEfficiency(detinfo::DetectorClocksData const &, std::set< int > const &trackIDs, std::vector< art::Ptr< recob::Hit > > const &hits, std::vector< art::Ptr< recob::Hit > > const &allhits, geo::View_t const view) const override
double HitChargeCollectionPurity(std::set< int >, std::vector< art::Ptr< recob::Hit > > const &) const
const simb::MCParticle * TrackIDToParticle(int const &id) const
Description of geometry of one entire detector.
const art::Ptr< simb::MCTruth > & ParticleToMCTruth(const simb::MCParticle *p) const
std::set< int > GetSetOfEveIDs() const override
const MCTruthParticleList & getParticleList() const
Contains all timing reference information for the detector.
std::set< int > GetSetOfTrackIDs() const override
std::vector< const HitParticleAssociations * > HitParticleAssociationsVec
std::vector< double > HitToXYZ(art::Ptr< recob::Hit > const &hit) const
std::vector< double > SpacePointHitsToXYZ(art::PtrVector< recob::Hit > const &hits) const
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
std::vector< double > SpacePointToXYZ(detinfo::DetectorClocksData const &clockData, art::Ptr< recob::SpacePoint > const &spt, art::Event const &evt, std::string const &label) const override
art::InputTag fG4ProducerLabel
Input tag for G4 producer (MCParticle/MCTruth)
TCEvent evt
Definition: DataStructs.cxx:8
std::vector< const simb::MCParticle * > MCTruthToParticles(art::Ptr< simb::MCTruth > const &mct) const override
std::vector< const simb::MCParticle * > MCTruthToParticles(art::Ptr< simb::MCTruth > const &mct) const
std::vector< double > SpacePointHitsToXYZ(detinfo::DetectorClocksData const &clockData, art::PtrVector< recob::Hit > const &hits) const override
void setup(const HitParticleAssociationsVec &, const MCParticleVec &, const MCTruthAssns &, const geo::GeometryCore &)
art framework interface to geometry description
const MCTruthTruthVec & MCTruthVector() const