ConsolidatedPFParticleAnalysisTemplate_module.cc
Go to the documentation of this file.
1 /**
2  * @file larpandora/LArPandoraAnalysis/ConsolidatedPFParticleAnalysisTemplate_module.cc
3  *
4  * @brief A template analysis module for using the Pandora consolidated output
5  */
6 
9 
13 
14 #include <string>
15 
16 //------------------------------------------------------------------------------------------------------------------------------------------
17 
18 namespace lar_pandora
19 {
20 
21 /**
22  * @brief ConsolidatedPFParticleAnalysisTemplate class
23  */
25 {
26 public:
28  typedef std::map< size_t, art::Ptr<recob::PFParticle> > PFParticleIdMap;
29  typedef std::vector< art::Ptr<recob::PFParticle> > PFParticleVector;
30  typedef std::vector< art::Ptr<recob::Track> > TrackVector;
31  typedef std::vector< art::Ptr<recob::Shower> > ShowerVector;
32 
33  /**
34  * @brief Constructor
35  *
36  * @param pset the set of input fhicl parameters
37  */
39 
40  /**
41  * @brief Configure memeber variables using FHiCL parameters
42  *
43  * @param pset the set of input fhicl parameters
44  */
45  void reconfigure(fhicl::ParameterSet const &pset);
46 
47  /**
48  * @brief Analyze an event!
49  *
50  * @param evt the art event to analyze
51  */
52  void analyze(const art::Event &evt);
53 
54 private:
55  /**
56  * @brief Produce a mapping from PFParticle ID to the art ptr to the PFParticle itself for fast navigation
57  *
58  * @param pfParticleHandle the handle for the PFParticle collection
59  * @param pfParticleMap the mapping from ID to PFParticle
60  */
61  void GetPFParticleIdMap(const PFParticleHandle &pfParticleHandle, PFParticleIdMap &pfParticleMap);
62 
63  /**
64  * @brief Print out scores in PFParticleMetadata
65  *
66  * @param evt the art event to analyze
67  * @param pfParticleHandle the handle for the PFParticle collection
68  */
69  void PrintOutScores(const art::Event &evt, const PFParticleHandle &pfParticleHandle) const;
70 
71  /**
72  * @brief Produce a mapping from PFParticle ID to the art ptr to the PFParticle itself for fast navigation
73  *
74  * @param pfParticleMap the mapping from ID to PFParticle
75  * @param crParticles a vector to hold the top-level PFParticles reconstructed under the cosmic hypothesis
76  * @param nuParticles a vector to hold the final-states of the reconstruced neutrino
77  */
78  void GetFinalStatePFParticleVectors(const PFParticleIdMap &pfParticleMap, PFParticleVector &crParticles, PFParticleVector &nuParticles);
79 
80  /**
81  * @brief Collect associated tracks and showers to particles in an input particle vector
82  *
83  * @param particles a vector holding PFParticles from which to find the associated tracks and showers
84  * @param pfParticleHandle the handle for the PFParticle collection
85  * @param evt the art event to analyze
86  * @param tracks a vector to hold the associated tracks
87  * @param showers a vector to hold the associated showers
88  */
89  void CollectTracksAndShowers(const PFParticleVector &particles, const PFParticleHandle &pfParticleHandle, const art::Event &evt, TrackVector &tracks, ShowerVector &showers);
90 
91  std::string m_pandoraLabel; ///< The label for the pandora producer
92  std::string m_trackLabel; ///< The label for the track producer from PFParticles
93  std::string m_showerLabel; ///< The label for the shower producer from PFParticles
94  bool m_printOutScores; ///< Option to investigate the associations to scores for PFParticles
95 };
96 
98 
99 } // namespace lar_pandora
100 
101 //------------------------------------------------------------------------------------------------------------------------------------------
102 // implementation follows
103 
105 #include "fhiclcpp/ParameterSet.h"
108 #include "art_root_io/TFileService.h"
109 #include "art_root_io/TFileDirectory.h"
110 #include "canvas/Persistency/Common/FindManyP.h"
112 
114 
115 #include "Pandora/PdgTable.h"
116 
117 #include <iostream>
118 
119 namespace lar_pandora
120 {
121 
123 {
124  this->reconfigure(pset);
125 }
126 
127 //------------------------------------------------------------------------------------------------------------------------------------------
128 
130 {
131  m_pandoraLabel = pset.get<std::string>("PandoraLabel");
132  m_trackLabel = pset.get<std::string>("TrackLabel");
133  m_showerLabel = pset.get<std::string>("ShowerLabel");
134  m_printOutScores = pset.get<bool>("PrintOutScores",true);
135 }
136 
137 //------------------------------------------------------------------------------------------------------------------------------------------
138 
140 {
141  // Collect the PFParticles from the event
142  PFParticleHandle pfParticleHandle;
143  evt.getByLabel(m_pandoraLabel, pfParticleHandle);
144 
145  if (!pfParticleHandle.isValid())
146  {
147  mf::LogDebug("ConsolidatedPFParticleAnalysisTemplate") << " Failed to find the PFParticles." << std::endl;
148  return;
149  }
150 
151  // Produce a map of the PFParticle IDs for fast navigation through the hierarchy
152  PFParticleIdMap pfParticleMap;
153  this->GetPFParticleIdMap(pfParticleHandle, pfParticleMap);
154 
155  /// Investigate scores associated as larpandoraobject::metadata for the PFParticles
156  if (m_printOutScores)
157  this->PrintOutScores(evt, pfParticleHandle);
158 
159  // Produce two PFParticle vectors containing final-state particles:
160  // 1. Particles identified as cosmic-rays - recontructed under cosmic-hypothesis
161  // 2. Daughters of the neutrino PFParticle - reconstructed under the neutrino hypothesis
162  std::vector< art::Ptr<recob::PFParticle> > crParticles;
163  std::vector< art::Ptr<recob::PFParticle> > nuParticles;
164  this->GetFinalStatePFParticleVectors(pfParticleMap, crParticles, nuParticles);
165 
166  // Use as required!
167  // -----------------------------
168  // What follows is an example showing how one might access the reconstructed neutrino final-state tracks and showers
169 
170  // These are the vectors to hold the tracks and showers for the final-states of the reconstructed neutrino
171  std::vector< art::Ptr<recob::Track> > tracks;
172  std::vector< art::Ptr<recob::Shower> > showers;
173  this->CollectTracksAndShowers(nuParticles, pfParticleHandle, evt, tracks, showers);
174 
175  // Print a summary of the consolidated event
176  std::cout << "Consolidated event summary:" << std::endl;
177  std::cout << " - Number of primary cosmic-ray PFParticles : " << crParticles.size() << std::endl;
178  std::cout << " - Number of neutrino final-state PFParticles : " << nuParticles.size() << std::endl;
179  std::cout << " ... of which are track-like : " << tracks.size() << std::endl;
180  std::cout << " ... of which are showers-like : " << showers.size() << std::endl;
181 }
182 
183 //------------------------------------------------------------------------------------------------------------------------------------------
184 
186 {
187  for (unsigned int i = 0; i < pfParticleHandle->size(); ++i)
188  {
189  const art::Ptr<recob::PFParticle> pParticle(pfParticleHandle, i);
190  if (!pfParticleMap.insert(PFParticleIdMap::value_type(pParticle->Self(), pParticle)).second)
191  {
192  throw cet::exception("ConsolidatedPFParticleAnalysisTemplate") << " Unable to get PFParticle ID map, the input PFParticle collection has repeat IDs!";
193  }
194  }
195 }
196 
197 //------------------------------------------------------------------------------------------------------------------------------------------
198 
200 {
201  // Get the associations between PFParticles and larpandoraobj::PFParticleMetadata
202  art::FindManyP< larpandoraobj::PFParticleMetadata > pfPartToMetadataAssoc(pfParticleHandle, evt, m_pandoraLabel);
203 
204  for (unsigned int i = 0; i < pfParticleHandle->size(); ++i)
205  {
206  const std::vector< art::Ptr<larpandoraobj::PFParticleMetadata> > &pfParticleMetadataList(pfPartToMetadataAssoc.at(i));
207  if (!pfParticleMetadataList.empty())
208  {
209  const art::Ptr<recob::PFParticle> pParticle(pfParticleHandle, i);
210  for (unsigned int j=0; j<pfParticleMetadataList.size(); ++j)
211  {
212  const art::Ptr<larpandoraobj::PFParticleMetadata> &pfParticleMetadata(pfParticleMetadataList.at(j));
213  const larpandoraobj::PFParticleMetadata::PropertiesMap &pfParticlePropertiesMap(pfParticleMetadata->GetPropertiesMap());
214  if (!pfParticlePropertiesMap.empty())
215  std::cout << " Found PFParticle " << pParticle->Self() << " with: " << std::endl;
216  for (larpandoraobj::PFParticleMetadata::PropertiesMap::const_iterator it = pfParticlePropertiesMap.begin(); it != pfParticlePropertiesMap.end(); ++it)
217  std::cout << " - " << it->first << " = " << it->second << std::endl;
218  }
219  }
220  }
221 }
222 
223 //------------------------------------------------------------------------------------------------------------------------------------------
224 
226 {
227  for (PFParticleIdMap::const_iterator it = pfParticleMap.begin(); it != pfParticleMap.end(); ++it)
228  {
229  const art::Ptr<recob::PFParticle> pParticle(it->second);
230 
231  // Only look for primary particles
232  if (!pParticle->IsPrimary()) continue;
233 
234  // Check if this particle is identified as the neutrino
235  const int pdg(pParticle->PdgCode());
236  const bool isNeutrino(std::abs(pdg) == pandora::NU_E || std::abs(pdg) == pandora::NU_MU || std::abs(pdg) == pandora::NU_TAU);
237 
238  // All non-neutrino primary particles are reconstructed under the cosmic hypothesis
239  if (!isNeutrino)
240  {
241  crParticles.push_back(pParticle);
242  continue;
243  }
244 
245  // ATTN. We are filling nuParticles under the assumption that there is only one reconstructed neutrino identified per event.
246  // If this is not the case please handle accordingly
247  if (!nuParticles.empty())
248  {
249  throw cet::exception("ConsolidatedPFParticleAnalysisTemplate") << " This event contains multiple reconstructed neutrinos!";
250  }
251 
252  // Add the daughters of the neutrino PFParticle to the nuPFParticles vector
253  for (const size_t daughterId : pParticle->Daughters())
254  {
255  if (pfParticleMap.find(daughterId) == pfParticleMap.end())
256  throw cet::exception("ConsolidatedPFParticleAnalysisTemplate") << " Invalid PFParticle collection!";
257 
258  nuParticles.push_back(pfParticleMap.at(daughterId));
259  }
260  }
261 }
262 
263 //------------------------------------------------------------------------------------------------------------------------------------------
264 
266 {
267  // Get the associations between PFParticles and tracks/showers from the event
268  art::FindManyP< recob::Track > pfPartToTrackAssoc(pfParticleHandle, evt, m_trackLabel);
269  art::FindManyP< recob::Shower > pfPartToShowerAssoc(pfParticleHandle, evt, m_showerLabel);
270 
271  for (const art::Ptr<recob::PFParticle> &pParticle : particles)
272  {
273  const std::vector< art::Ptr<recob::Track> > associatedTracks(pfPartToTrackAssoc.at(pParticle.key()));
274  const std::vector< art::Ptr<recob::Shower> > associatedShowers(pfPartToShowerAssoc.at(pParticle.key()));
275  const unsigned int nTracks(associatedTracks.size());
276  const unsigned int nShowers(associatedShowers.size());
277 
278  // Check if the PFParticle has no associated tracks or showers
279  if (nTracks == 0 && nShowers == 0)
280  {
281  mf::LogDebug("ConsolidatedPFParticleAnalysisTemplate") << " No tracks or showers were associated to PFParticle " << pParticle->Self() << std::endl;
282  continue;
283  }
284 
285  // Check if there is an associated track
286  if (nTracks == 1 && nShowers == 0)
287  {
288  tracks.push_back(associatedTracks.front());
289  continue;
290  }
291 
292  // Check if there is an associated shower
293  if (nTracks == 0 && nShowers == 1)
294  {
295  showers.push_back(associatedShowers.front());
296  continue;
297  }
298 
299  throw cet::exception("ConsolidatedPFParticleAnalysisTemplate") << " There were " << nTracks << " tracks and " << nShowers << " showers associated with PFParticle " << pParticle->Self();
300  }
301 }
302 
303 } //namespace lar_pandora
void CollectTracksAndShowers(const PFParticleVector &particles, const PFParticleHandle &pfParticleHandle, const art::Event &evt, TrackVector &tracks, ShowerVector &showers)
Collect associated tracks and showers to particles in an input particle vector.
const std::vector< size_t > & Daughters() const
Returns the collection of daughter particles.
Definition: PFParticle.h:114
size_t Self() const
Returns the index of this particle.
Definition: PFParticle.h:92
std::string string
Definition: nybbler.cc:12
void reconfigure(fhicl::ParameterSet const &pset)
Configure memeber variables using FHiCL parameters.
int PdgCode() const
Return the type of particle as a PDG ID.
Definition: PFParticle.h:83
std::map< std::string, float > PropertiesMap
intermediate_table::const_iterator const_iterator
std::string m_showerLabel
The label for the shower producer from PFParticles.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
ConsolidatedPFParticleAnalysisTemplate(fhicl::ParameterSet const &pset)
Constructor.
bool isValid() const noexcept
Definition: Handle.h:191
T abs(T value)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::string m_trackLabel
The label for the track producer from PFParticles.
bool IsPrimary() const
Returns whether the particle is the root of the flow.
Definition: PFParticle.h:86
bool m_printOutScores
Option to investigate the associations to scores for PFParticles.
Definition: tracks.py:1
void PrintOutScores(const art::Event &evt, const PFParticleHandle &pfParticleHandle) const
Print out scores in PFParticleMetadata.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void GetFinalStatePFParticleVectors(const PFParticleIdMap &pfParticleMap, PFParticleVector &crParticles, PFParticleVector &nuParticles)
Produce a mapping from PFParticle ID to the art ptr to the PFParticle itself for fast navigation...
Provides recob::Track data product.
void GetPFParticleIdMap(const PFParticleHandle &pfParticleHandle, PFParticleIdMap &pfParticleMap)
Produce a mapping from PFParticle ID to the art ptr to the PFParticle itself for fast navigation...
TCEvent evt
Definition: DataStructs.cxx:7
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)