LArHierarchyHelper.h
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArHelpers/LArHierarchyHelper.h
3  *
4  * @brief Header file for the lar hierarchy helper class.
5  *
6  * $Log: $
7  */
8 #ifndef LAR_HIERARCHY_HELPER_H
9 #define LAR_HIERARCHY_HELPER_H 1
10 
11 #include "Pandora/PandoraInternal.h"
12 
13 #include "Helpers/MCParticleHelper.h"
14 
17 
18 namespace lar_content
19 {
20 
21 /**
22  * @brief LArHierarchyHelper class
23  */
25 {
26 public:
27  /**
28  * @brief FoldingParameters class
29  */
31  {
32  public:
33  /**
34  * @brief Default constructor
35  */
37 
38  /**
39  * @brief Constructor
40  *
41  * @param foldDynamic Whether or not to apply dynamic folding to the hierarchy
42  */
43  FoldingParameters(const bool foldDynamic, const float cosAngleTolerance = 0.9962f);
44 
45  /**
46  * @brief Constructor.
47  *
48  * If folding back to tier 2, any MC particle/PFO ("particles") at tier 1 will be allocated their own node. At tier 2, the
49  * particles will be allocated as the main particle for a node and all of their children will also be incorprated into the node
50  *
51  * @param foldingTier The tier at which level child particles should be folded back (> 0)
52  */
53  FoldingParameters(const int foldingTier);
54 
55  bool m_foldToLeadingShowers; ///< Whether or not to fold shower children to the leading shower particle
56  bool m_foldToTier; ///< Whether or not to apply folding based on particle tier
57  bool m_foldDynamic; ///< Whether or not to use process and topological information to make folding decisions
58  float m_cosAngleTolerance; ///< Cosine of the maximum angle at which topologies can be considered continuous
59  int m_tier; ///< If folding to a tier, the tier to be combined with its child particles
60  };
61 
62  /**
63  * @brief QualityCuts class
64  */
66  {
67  public:
68  /**
69  * @brief Default constructor
70  */
71  QualityCuts();
72 
73  /**
74  * @brief Constructor
75  *
76  * @param minPurity The minimum purity for a cut to be considered good
77  * @param minCompleteness The minimum completeness for a cut to be considered good
78  */
79  QualityCuts(const float minPurity, const float minCompleteness);
80 
81  const float m_minPurity; ///< The minimum purity for a match to be considered good
82  const float m_minCompleteness; ///< The minimum completeness for a match to be considered good
83  };
84 
85  /**
86  * @brief MCHierarchy class
87  */
89  {
90  public:
91  /**
92  * @brief ReconstructabilityCriteria class
93  */
95  {
96  public:
97  /**
98  * @brief Default constructor
99  */
101 
102  /**
103  * @brief Copy constructor
104  */
106 
107  /**
108  * @brief Constructor
109  *
110  * @param minHits The total minimum number of hits for a particle to be considered reconstructable
111  * @param minHitsForGoodView The number of hits within a view for a particle to be considered reconstructable
112  * @param minGoodViews The minimum number of good views for a particle to be considered reconstructable
113  * @param removeNeutrons Whether to remove neutrons and downstream particles from consideration
114  */
115  ReconstructabilityCriteria(const unsigned int minHits, const unsigned int minHitsForGoodView, const unsigned int minGoodViews,
116  const bool removeNeutrons);
117 
118  const unsigned int m_minHits; ///< the minimum number of primary good Hits
119  const unsigned int m_minHitsForGoodView; ///< the minimum number of Hits for a good view
120  const unsigned int m_minGoodViews; ///< the minimum number of primary good views
121  const bool m_removeNeutrons; ///< whether to remove neutrons and their downstream particles
122  };
123 
124  class Node;
125  typedef std::vector<const Node *> NodeVector;
126  typedef std::list<const Node *> NodeList;
127 
128  /**
129  * @brief Node class
130  */
131  class Node
132  {
133  public:
134  /**
135  * @brief Create a node with a primary MC particle
136  *
137  * @param hierarchy The parent hierarchy of this node
138  * @param pMCParticle The primary MC particle with which this node should be created
139  * @param tier The tier that should be assigned to this node
140  */
141  Node(MCHierarchy &hierarchy, const pandora::MCParticle *pMCParticle, const int tier = 1);
142 
143  /**
144  * @brief Create a node from a list of MC particles
145  *
146  * @param hierarchy The parent hierarchy of this node
147  * @param mcParticleList The MC particle list with which this node should be created
148  * @param caloHitList The CaloHit list with which this node should be created
149  * @param tier The tier that should be assigned to this node
150  */
151  Node(MCHierarchy &hierarchy, const pandora::MCParticleList &mcParticleList, const pandora::CaloHitList &caloHitList, const int tier = 1);
152 
153  /**
154  * @brief Destructor
155  */
156  virtual ~Node();
157 
158  /**
159  * @brief Return whether or not this node should be considered reconstructable
160  *
161  * @return true if reconstructable, false otherwise
162  */
163  bool IsReconstructable() const;
164 
165  /**
166  * @brief Recursively fill the hierarchy based on the criteria established for this MCHierarchy
167  *
168  * @param pRoot The MC particle acting as the root of the current branch of the hierarchy
169  * @param foldParameters The folding parameters
170  */
171  void FillHierarchy(const pandora::MCParticle *pRoot, const FoldingParameters &foldParameters);
172 
173  /**
174  * @brief Fill this node by folding all descendent particles to this node
175  *
176  * @param pRoot The MC particle acting as the root of the current branch of the hierarchy
177  */
178  void FillFlat(const pandora::MCParticle *pRoot);
179 
180  /**
181  * @brief Return the vector of children for this node
182  *
183  * @return The vector of children
184  */
185  const NodeVector &GetChildren() const;
186 
187  /**
188  * @brief Retrieve the unique ID of this node
189  *
190  * @return The unique ID of this node
191  */
192  int GetId() const;
193 
194  /**
195  * @brief Retrieve the leading MC particle associated with this node
196  *
197  * @return The main MC particle associated with this node
198  */
199  const pandora::MCParticle *GetLeadingMCParticle() const;
200 
201  /**
202  * @brief Retrieve the MC particles associated with this node
203  *
204  * @return The MC particles associated with this node
205  */
206  const pandora::MCParticleList &GetMCParticles() const;
207 
208  /**
209  * @brief Retrieve the CaloHits associated with this node
210  *
211  * @return The list of CaloHits associated with this node
212  */
213  const pandora::CaloHitList &GetCaloHits() const;
214 
215  /**
216  * @brief Retrieve the PDG code for the leading particle in this node
217  *
218  * @return The PDG code for the leading particle in this node
219  */
220  int GetParticleId() const;
221 
222  /**
223  * @brief Retrieve the hierarchy tier of this node
224  *
225  * @return The hierarchy tier of this node
226  */
227  int GetHierarchyTier() const;
228 
229  /**
230  * @brief Check if this is a particle induced by a neutrino interaction
231  *
232  * @return Whether or not this is neutrino induced
233  */
234  bool IsNeutrinoInduced() const;
235 
236  /**
237  * @brief Check if this is a test beam particle
238  *
239  * @return Whether or not this is a test beam particle
240  */
241  bool IsTestBeamParticle() const;
242 
243  /**
244  * @brief Check if this is a cosmic ray particle
245  *
246  * @return Whether or not this is a cosmic ray
247  */
248  bool IsCosmicRay() const;
249 
250  /**
251  * @brief Returns whether or not this particle is the leading lepton in the event
252  *
253  * @return Whether or not this is the leading lepton
254  */
255  bool IsLeadingLepton() const;
256 
257  /**
258  * @brief Produce a string representation of the hierarchy
259  *
260  * @return The string representation of the hierarchy
261  */
262  const std::string ToString(const std::string &prefix) const;
263 
264  private:
265  /**
266  * @brief Tags the particle as the leading lepton
267  */
268  void SetLeadingLepton();
269 
270  MCHierarchy &m_hierarchy; ///< The parent MC hierarchy
271  pandora::MCParticleList m_mcParticles; ///< The list of MC particles of which this node is composed
272  pandora::CaloHitList m_caloHits; ///< The list of calo hits of which this node is composed
273  NodeVector m_children; ///< The child nodes of this node
274  const pandora::MCParticle *m_mainParticle; ///< The leading MC particle for this node
275  int m_tier; ///< The hierarchy tier for this node
276  int m_pdg; ///< The PDG code of the leading MC particle for this node
277  bool m_isLeadingLepton; ///< Whether or not this node is the leading lepton
278 
279  friend class MCHierarchy;
280  };
281 
282  /**
283  * @brief Default constructor
284  */
285  MCHierarchy();
286 
287  /**
288  * @brief Construct a new MCHierarchy object using specified reconstructability criteria
289  *
290  * @param recoCriteria The reconstructability criteria to be applied
291  */
292  MCHierarchy(const ReconstructabilityCriteria &recoCriteria);
293 
294  /**
295  * @brief Destructor
296  */
297  virtual ~MCHierarchy();
298 
299  /**
300  * @brief Creates an MC hierarchy representation. Without folding this will be a mirror image of the standard MCParticle
301  * relationships. However, with folding options selected the hierarchy structure will group together MC particles into
302  * nodes based on the folding requirements.
303  *
304  * If only folding back to primaries, the hierarchy will be relatively flat, with a top-level neutrino or test beam
305  * particle, if appropriate, and then a set of leaf nodes, one for each primary particles also containing the MC particles
306  * (and corresponding hits) from daughter particles.
307  *
308  * If only folding back to leading shower particles, the hierarchy will largely mirror the standard MCParticle hierarchy,
309  * but, when a shower particle is reached (for this purpose an electron or photon), this particle and all daughter
310  * particles will be represented by a single leaf node.
311  *
312  * If folding back to both primary and leading shower particles the hierarchy will again be rather flat, but in this case,
313  * if a primary track-like particle (i.e. not an electron or photon) has a downstream shower particle then all downstream
314  * particles above the shower-like particle will be folded into the primary node, but a new, daughter leaf node will be
315  * created for the shower-like particle and all of its daughters, and a parent-child relationship will be formed between
316  * the primary node and shower node.
317  *
318  * @param mcParticleList The list of MC particles with which to fill the hierarchy
319  * @param caloHitList The list of hits with which to fill the hierarchy
320  * @param foldParameters The folding parameters to use for the hierarchy
321  */
322  void FillHierarchy(const pandora::MCParticleList &mcParticleList, const pandora::CaloHitList &caloHitList, const FoldingParameters &foldParameters);
323 
324  /**
325  * @brief Interpret the hierarchy below a particular particle to determine if and how it should be folded. Folded particles are
326  * added to the leadingParticles list and child particles are added to the childParticles list.
327  *
328  * @param pRoot The root of the hierarchy to interpret
329  * @param leadingParticles The output list of particles that should be folded into the root particle
330  * @param childParticles The output list of particles that should be considered children of the folded particle
331  * @param cosAngleTolerance The cosine of the maximum angle for which trajectories are considered continuous
332  */
333  void InterpretHierarchy(const pandora::MCParticle *const pRoot, pandora::MCParticleList &leadingParticles,
334  pandora::MCParticleList &childParticles, const float cosAngleTolerance) const;
335 
336  /**
337  * @brief Retrieve the neutrino at the root of the hierarchy if it exists
338  *
339  * @return The address of the incident neutrino (nullptr if it doesn't exist)
340  */
341  const pandora::MCParticle *GetNeutrino() const;
342 
343  /**
344  * @brief Retrieve the root nodes in this hierarchy
345  *
346  * @return The root nodes in this hierarchy
347  */
348  const NodeVector &GetRootNodes() const;
349 
350  /**
351  * @brief Retrieve a flat vector of the ndoes in the hierarchy
352  *
353  * @param nodeVector The output vector for the nodes in the hierarchy in breadth first order
354  */
355  void GetFlattenedNodes(NodeVector &nodeVector) const;
356 
357  /**
358  * @brief Register a node with the hierarchy
359  *
360  * @param pNode The node to register
361  */
362  void RegisterNode(const Node *pNode);
363 
364  /**
365  * @brief Produce a string representation of the hierarchy
366  *
367  * @return The string representation of the hierarchy
368  */
369  const std::string ToString() const;
370 
371  /**
372  * @brief Check if this is a neutrino hierarchy.
373  *
374  * @return Whether or not this is a neutrino hierarchy.
375  */
376  bool IsNeutrinoHierarchy() const;
377 
378  /**
379  * @brief Check if this is a test beam hierarchy.
380  *
381  * @return Whether or not this is a test beam hierarchy.
382  */
383  bool IsTestBeamHierarchy() const;
384 
385  private:
386  /**
387  * @brief Identify downstream particles that represent continuations of the parent particle from a reconstruction perspective
388  *
389  * @param pRoot The root MC particle
390  * @param continuingParticles An output list of the particles identified as continuations
391  * @param childParticles An output list of the particles identified as child particles given any continuations
392  * @param cosAngleTolerance The cosine of the maximum angle for which trajectories are considered continuous
393  */
394  void CollectContinuations(const pandora::MCParticle *pRoot, pandora::MCParticleList &continuingParticles,
395  pandora::MCParticleList &childParticles, const float cosAngleTolerance) const;
396 
397  /**
398  * @brief Checks if an individual particle meets reconstructability criteria
399  *
400  * @param pMCParticle The MC particle to assess
401  *
402  * @return Whether or not the MC particle meets reconstructability criteria
403  */
404  bool IsReconstructable(const pandora::MCParticle *pMCParticle) const;
405 
406  /**
407  * @brief Checks if a set of hits meet reconstructability criteria
408  *
409  * @param caloHits The calo hits to assess
410  *
411  * @return Whether or not the hits meet reconstructability criteria
412  */
413  bool IsReconstructable(const pandora::CaloHitList &caloHits) const;
414 
415  NodeVector m_rootNodes; ///< The leading nodes (e.g. primary particles, cosmic rays, ...)
416  ReconstructabilityCriteria m_recoCriteria; ///< The criteria used to determine if the node is reconstructable
417  const pandora::MCParticle *m_pNeutrino; ///< The incident neutrino, if it exists
418  std::map<const pandora::MCParticle *, pandora::CaloHitList> m_mcToHitsMap; ///< The map between MC particles and calo hits
419  std::map<const Node *, int> m_nodeToIdMap; ///< A map from nodes to unique ids
420  int m_nextNodeId; ///< The ID to use for the next node
421  };
422 
423  /**
424  * @brief RecoHierarchy class
425  */
427  {
428  public:
429  class Node;
430  typedef std::vector<const Node *> NodeVector;
431  typedef std::list<const Node *> NodeList;
432 
433  /**
434  * @brief Node class
435  */
436  class Node
437  {
438  public:
439  /**
440  * @brief Create a node with a primary PFO
441  *
442  * @param hierarchy The parent hierarchy of this node
443  * @param pPfo The primary PFO with which this node should be created
444  */
445  Node(const RecoHierarchy &hierarchy, const pandora::ParticleFlowObject *pPfo);
446 
447  /**
448  * @brief Create a node from a list of PFOs
449  *
450  * @param hierarchy The parent hierarchy of this node
451  * @param pfoList The PFO list with which this node should be created
452  * @parasm caloHitList The CaloHit list with which this node should be created
453  */
454  Node(const RecoHierarchy &hierarchy, const pandora::PfoList &pfoList, const pandora::CaloHitList &caloHitList);
455 
456  /**
457  * @brief Destructor
458  */
459  virtual ~Node();
460 
461  /**
462  * @brief Recursively fill the hierarchy based on the criteria established for this RecoHierarchy
463  *
464  * @param pRoot The PFO acting as the root of the current branch of the hierarchy
465  * @param foldParameters The folding parameters
466  */
467  void FillHierarchy(const pandora::ParticleFlowObject *pRoot, const FoldingParameters &foldParameters);
468 
469  /**
470  * @brief Fill this node by folding all descendent particles to this node
471  *
472  * @param pRoot The PFO acting as the root of the current branch of the hierarchy
473  */
474  void FillFlat(const pandora::ParticleFlowObject *pRoot);
475 
476  /**
477  * @brief Return the vector of children for this node
478  *
479  * @return The vector of children
480  */
481  const NodeVector &GetChildren() const;
482 
483  /**
484  * @brief Retrieve the PFOs associated with this node
485  *
486  * @return The PFOs associated with this node
487  */
488  const pandora::PfoList &GetRecoParticles() const;
489 
490  /**
491  * @brief Retrieve the CaloHits associated with this node
492  *
493  * @return The list of CaloHits associated with this node
494  */
495  const pandora::CaloHitList &GetCaloHits() const;
496 
497  /**
498  * @brief Retrieve the PDG code for the leading particle in this node
499  * Note, for reco objects the PDG codes represent tracks (muon PDG) and showers (electron PDG)
500  *
501  * @return The PDG code for the leading particle in this node
502  */
503  int GetParticleId() const;
504 
505  /**
506  * @brief Produce a string representation of the hierarchy
507  *
508  * @return The string representation of the hierarchy
509  */
510  const std::string ToString(const std::string &prefix) const;
511 
512  private:
513  const RecoHierarchy &m_hierarchy; ///< The parent reco hierarchy
514  pandora::PfoList m_pfos; ///< The list of PFOs of which this node is composed
515  pandora::CaloHitList m_caloHits; ///< The list of calo hits of which this node is composed
516  NodeVector m_children; ///< The child nodes of this node
517  int m_pdg; ///< The particle ID (track = muon, shower = electron)
518  };
519 
520  /**
521  * @brief Default constructor
522  */
523  RecoHierarchy();
524 
525  /**
526  * @brief Destructor
527  */
528  virtual ~RecoHierarchy();
529 
530  /**
531  * @brief Creates a reconstructed hierarchy representation. Without folding this will be a mirror image of the standard
532  * ParticleFlowObject (PFO) relationships. However, with folding options selected the hierarchy structure will group
533  * together PFOs into nodes based on the folding requirements.
534  *
535  * If only folding back to primaries, the hierarchy will be relatively flat, with a top-level neutrino or test beam
536  * particle, if appropriate, and then a set of leaf nodes, one for each primary particles also containing the PFOs (and
537  * corresponding hits) from daughter particles.
538  *
539  * If only folding back to leading shower particles, the hierarchy will largely mirror the standard PFO hierarchy, but,
540  * when a shower particle is reached (based on the track/shower characterisation), this particle and all daughter particles
541  * will be represented by a single leaf node.
542  *
543  * If folding back to both primary and leading shower particles the hierarchy will again be rather flat, but in this case,
544  * if a primary track-like particle has a downstream shower particle then all downstream particles above the shower-like
545  * particle will be folded into the primary node, but a new, daughter leaf node will be created for the shower-like
546  * particle and all of its daughters, and a parent-child relationship will be formed between the primary node and shower
547  * node.
548  *
549  * @param pfoList The list of PFOs with which to fill the hierarchy
550  * @param foldParameters The folding parameters to use for the hierarchy
551  */
552  void FillHierarchy(const pandora::PfoList &pfoList, const FoldingParameters &foldParameters);
553 
554  /**
555  * @brief Retrieve the root nodes in this hierarchy
556  *
557  * @return The root nodes in this hierarchy
558  */
559  const NodeVector &GetRootNodes() const;
560 
561  /**
562  * @brief Retrieve a flat vector of the nodes in the hierarchy
563  *
564  * @param nodeVector The output vector for the nodes in the hierarchy in breadth first order
565  */
566  void GetFlattenedNodes(NodeVector &nodeVector) const;
567 
568  /**
569  * @brief Retrieve the neutrino at the root of the hierarchy if it exists
570  *
571  * @return The address of the incident neutrino (nullptr if it doesn't exist)
572  */
573  const pandora::ParticleFlowObject *GetNeutrino() const;
574 
575  /**
576  * @brief Produce a string representation of the hierarchy
577  *
578  * @return The string representation of the hierarchy
579  */
580  const std::string ToString() const;
581 
582  private:
583  NodeVector m_rootNodes; ///< The leading nodes (e.g. primary particles, cosmic rays, ...)
584  const pandora::ParticleFlowObject *m_pNeutrino; ///< The incident neutrino, if it exists
585  };
586 
587  /**
588  * @brief MCMatches class
589  */
590  class MCMatches
591  {
592  public:
593  /**
594  * @brief Constructor
595  *
596  * @param pMCParticle The MCParticle being matched
597  */
598  MCMatches(const MCHierarchy::Node *pMCParticle);
599 
600  /**
601  * @brief Add a reconstructed node as a match for this MC node
602  *
603  * @param pReco The reconstructed node that matches this MC node
604  * @param nSharedHits The number of hits shared betweeb reco and MC nodes
605  */
606  void AddRecoMatch(const RecoHierarchy::Node *pReco, const int nSharedHits);
607 
608  /**
609  * @brief Retrieve the MC node
610  *
611  * @return The MC node
612  */
613  const MCHierarchy::Node *GetMC() const;
614 
615  /**
616  * @brief Retrieve the vector of matched reco nodes
617  *
618  * @return The vector of matched reco nodes
619  */
620  const RecoHierarchy::NodeVector &GetRecoMatches() const;
621 
622  /**
623  * @brief Retrieve the number of shared hits in the match
624  *
625  * @param pReco The reco node to consider
626  *
627  * @return The number of shared hits
628  */
629  unsigned int GetSharedHits(const RecoHierarchy::Node *pReco) const;
630 
631  /**
632  * @brief Retrieve the purity of the match
633  *
634  * @param pReco The reco node to consider
635  * @param adcWeighted Whether or not to weight purity according to the charge contribution
636  *
637  * @return The purity of the match
638  */
639  float GetPurity(const RecoHierarchy::Node *pReco, const bool adcWeighted = false) const;
640 
641  /**
642  * @brief Retrieve the purity of the match
643  *
644  * @param pReco The reco node to consider
645  * @param view The view for which purity should be calculated
646  * @param adcWeighted Whether or not to weight purity according to the charge contribution
647  *
648  * @return The purity of the match
649  */
650  float GetPurity(const RecoHierarchy::Node *pReco, const pandora::HitType view, const bool adcWeighted = false) const;
651 
652  /**
653  * @brief Retrieve the completeness of the match
654  *
655  * @param pReco The reco node to consider
656  * @param adcWeighted Whether or not to weight completeness according to the charge contribution
657  *
658  * @return The completeness of the match
659  */
660  float GetCompleteness(const RecoHierarchy::Node *pReco, const bool adcWeighted = false) const;
661 
662  /**
663  * @brief Retrieve the completeness of the match
664  *
665  * @param pReco The reco node to consider
666  * @param view The view for which purity should be calculated
667  * @param adcWeighted Whether or not to weight completeness according to the charge contribution
668  *
669  * @return The completeness of the match
670  */
671  float GetCompleteness(const RecoHierarchy::Node *pReco, const pandora::HitType view, const bool adcWeighted = false) const;
672 
673  /**
674  * @brief Get the number of reco nodes matched (both above and below quality cut thresholds) to the MC node
675  *
676  * @return The number of reco nodes matched to the MC node
677  */
678  size_t GetNRecoMatches() const;
679 
680  /**
681  * @brief Get whether this match passes quality cuts
682  *
683  * @param qualityCuts The quality cuts to pass
684  *
685  * @return Whether or not this match passes quality cuts
686  */
687  bool IsQuality(const QualityCuts &qualityCuts) const;
688 
689  private:
690  /**
691  * @brief Core purity calculation given intersecting hits and reco hits
692  *
693  * @param intersection The intersecting reco and MC hits
694  * @param recoHits The reco hits
695  * @param adcWeighted Whether or not to weight purity according to the charge contribution
696  *
697  * @return The purity of the match
698  */
699  float GetPurity(const pandora::CaloHitVector &intersection, const pandora::CaloHitList &recoHits, const bool adcWeighted) const;
700 
701  /**
702  * @brief Core completeness calculation given intersecting hits and MC hits
703  *
704  * @param intersection The intersecting reco and MC hits
705  * @param mcHits The MC hits
706  * @param adcWeighted Whether or not to weight completeness according to the charge contribution
707  *
708  * @return The completeness of the match
709  */
710  float GetCompleteness(const pandora::CaloHitVector &intersection, const pandora::CaloHitList &mcHits, const bool adcWeighted) const;
711 
712  const MCHierarchy::Node *m_pMCParticle; ///< MC node associated with any matches
713  RecoHierarchy::NodeVector m_recoNodes; ///< Matched reco nodes
714  pandora::IntVector m_sharedHits; ///< Number of shared hits for each match
715  };
716 
717  typedef std::vector<MCMatches> MCMatchesVector;
718 
719  /**
720  * @brief MatcheInfo class
721  */
722  class MatchInfo
723  {
724  public:
725  /**
726  * @brief Default constructor
727  */
728  MatchInfo();
729 
730  /**
731  * @brief Constructor
732  *
733  * @param qualityCuts The quality cuts to be applied to matched nodes
734  */
735  MatchInfo(const QualityCuts &qualityCuts);
736 
737  /**
738  * @brief Match the nodes in the MC and reco hierarchies.
739  *
740  * @param mcHierarchy The MC hierarchy
741  * @param recoHierarchy The reco hierarchy
742  */
743  void Match(const MCHierarchy &mcHierarchy, const RecoHierarchy &recoHierarchy);
744 
745  /**
746  * @brief Retrieve the vector of matches (this will include null matches - i.e. MC nodes with no corresponding reco)
747  *
748  * @return The vector of matches
749  */
750  const MCMatchesVector &GetMatches() const;
751 
752  /**
753  * @brief Retrieve the vector of unmatched reco nodes
754  */
755  const RecoHierarchy::NodeVector &GetUnmatchedReco() const;
756 
757  /**
758  * @brief Retrieve the parent MC neutrino if it exists
759  *
760  * @param The parent neutrino if it exists (nullptr otherwise)
761  */
762  const pandora::MCParticle *GetMCNeutrino() const;
763 
764  /**
765  * @brief Retrieve the parent reco neutrino if it exists
766  *
767  * @param The parent neutrino if it exists (nullptr otherwise)
768  */
769  const pandora::ParticleFlowObject *GetRecoNeutrino() const;
770 
771  /**
772  * @brief Retrieve the number of MC nodes available to match
773  *
774  * @return The number of MC nodes available to match
775  */
776  unsigned int GetNMCNodes() const;
777 
778  /**
779  * @brief Retrieve the number of neutrino interaction derived MC nodes available to match
780  *
781  * @return The number of MC nodes available to match
782  */
783  unsigned int GetNNeutrinoMCNodes() const;
784 
785  /**
786  * @brief Retrieve the number of cosmic ray derived MC nodes available to match
787  *
788  * @return The number of MC nodes available to match
789  */
790  unsigned int GetNCosmicRayMCNodes() const;
791 
792  /**
793  * @brief Retrieve the number of test beam derived MC nodes available to match
794  *
795  * @return The number of MC nodes available to match
796  */
797  unsigned int GetNTestBeamMCNodes() const;
798 
799  /**
800  * @brief Retrieve the quality cuts for matching
801  *
802  * @return The quality cuts
803  */
804  const QualityCuts &GetQualityCuts() const;
805 
806  /**
807  * @brief Prints information about which reco nodes are matched to the MC nodes, information about hit sharing, purity and
808  * completeness.
809  *
810  * @param mcHierarchy The MC hierarchy
811  */
812  void Print(const MCHierarchy &mcHierarchy) const;
813 
814  private:
815  const pandora::MCParticle *m_pMCNeutrino; ///< The parent neutrino if it exists
816  const pandora::ParticleFlowObject *m_pRecoNeutrino; ///< The parent neutrino if it exists
817 
818  MCMatchesVector m_matches; ///< The vector of good matches from MC to reco
819  MCMatchesVector m_goodMatches; ///< The vector of good matches - above threshold one reco to one MC matches
820  MCMatchesVector m_aboveThresholdMatches; ///< The vector of matches that pass quality but with multiple reco matches to the MC
821  MCMatchesVector m_subThresholdMatches; ///< The vector of matches that don't pass quality cuts
822  MCHierarchy::NodeVector m_unmatchedMC; ///< The vector of unmatched MC nodes
823  RecoHierarchy::NodeVector m_unmatchedReco; ///< The vector of unmatched reco nodes
824  QualityCuts m_qualityCuts; ///< The quality cuts to be applied to matches
825  };
826 
827  /**
828  * @brief Fill an MC hierarchy based on the specified folding criteria (see MCHierarchy::FillHierarchy for details)
829  *
830  * @param mcParticleList The MCParticle list to use to fill this hierarchy
831  * @param caloHitList The list of CaloHits to use to fill this hierarchy
832  * @param foldParameters The folding parameters to use for the hierarchy
833  * @param hierarchy The output MC hierarchy
834  */
835  static void FillMCHierarchy(const pandora::MCParticleList &mcParticleList, const pandora::CaloHitList &caloHitList,
836  const FoldingParameters &foldParameters, MCHierarchy &hierarchy);
837 
838  /**
839  * @brief Fill a reconstructed hierarchy based on the specified folding criteria (see RecoHierarchy::FillHierarchy for details)
840  *
841  * @param pfoList The ParticleFlowObject list to use to fill this hierarchy
842  * @param foldParameters The folding parameters to use for the hierarchy
843  * @param hierarchy The output reconstructed hierarchy
844  */
845  static void FillRecoHierarchy(const pandora::PfoList &pfoList, const FoldingParameters &foldParameters, RecoHierarchy &hierarchy);
846 
847  /**
848  * @brief Finds the matches between reconstructed and MC hierarchies.
849  *
850  * @param mcHierarchy The MC hiearchy
851  * @param recoHierarchy The reconstructed hierarchy
852  * @param matchInfo The output match information
853  */
854  static void MatchHierarchies(const MCHierarchy &mcHierarchy, const RecoHierarchy &recoHierarchy, MatchInfo &matchInfo);
855 
856 private:
857  typedef std::set<const pandora::MCParticle *> MCParticleSet;
858  typedef std::set<const pandora::ParticleFlowObject *> PfoSet;
859 
860  /**
861  * @brief Retrieves the primary MC particles from a list and returns the root (neutrino) for hierarchy, if it exists.
862  *
863  * @param mcParticleList The input list of MC particles
864  * @param primaries The output set of primary MC particles
865  *
866  * @return The root neutrino, if it exists, or nullptr
867  */
868  static const pandora::MCParticle *GetMCPrimaries(const pandora::MCParticleList &mcParticleList, MCParticleSet &primaries);
869 
870  /**
871  * @brief Retrieves the primary PFOs from a list and returns the root (neutrino) for hierarchy, if it exists.
872  *
873  * @param pfoList The input list of PFOs
874  * @param primaries The output set of primary PFOs
875  *
876  * @return The root neutrino, if it exists, or nullptr
877  */
878  static const pandora::ParticleFlowObject *GetRecoPrimaries(const pandora::PfoList &pfoList, PfoSet &primaries);
879 };
880 
881 //------------------------------------------------------------------------------------------------------------------------------------------
882 //------------------------------------------------------------------------------------------------------------------------------------------
883 
885 {
886  return m_children;
887 }
888 
889 //------------------------------------------------------------------------------------------------------------------------------------------
890 
891 inline const pandora::MCParticleList &LArHierarchyHelper::MCHierarchy::Node::GetMCParticles() const
892 {
893  return m_mcParticles;
894 }
895 
896 //------------------------------------------------------------------------------------------------------------------------------------------
897 
898 inline const pandora::CaloHitList &LArHierarchyHelper::MCHierarchy::Node::GetCaloHits() const
899 {
900  return m_caloHits;
901 }
902 
903 //------------------------------------------------------------------------------------------------------------------------------------------
904 
905 inline const pandora::MCParticle *LArHierarchyHelper::MCHierarchy::Node::GetLeadingMCParticle() const
906 {
907  return m_mainParticle;
908 }
909 
910 //------------------------------------------------------------------------------------------------------------------------------------------
911 
913 {
914  return m_pdg;
915 }
916 
917 //------------------------------------------------------------------------------------------------------------------------------------------
918 
920 {
921  return m_tier;
922 }
923 
924 //------------------------------------------------------------------------------------------------------------------------------------------
925 
927 {
929 }
930 
931 //------------------------------------------------------------------------------------------------------------------------------------------
932 
934 {
935  return m_isLeadingLepton;
936 }
937 
938 //------------------------------------------------------------------------------------------------------------------------------------------
939 
941 {
942  m_isLeadingLepton = true;
943 }
944 
945 //------------------------------------------------------------------------------------------------------------------------------------------
946 //------------------------------------------------------------------------------------------------------------------------------------------
947 
948 inline const pandora::MCParticle *LArHierarchyHelper::MCHierarchy::GetNeutrino() const
949 {
950  return m_pNeutrino;
951 }
952 
953 //------------------------------------------------------------------------------------------------------------------------------------------
954 
956 {
957  return m_rootNodes;
958 }
959 
960 //------------------------------------------------------------------------------------------------------------------------------------------
961 
963 {
964  return m_pNeutrino != nullptr;
965 }
966 
967 //------------------------------------------------------------------------------------------------------------------------------------------
968 
970 {
971  return m_pNeutrino == nullptr;
972 }
973 
974 //------------------------------------------------------------------------------------------------------------------------------------------
975 //------------------------------------------------------------------------------------------------------------------------------------------
976 
978 {
979  return m_children;
980 }
981 
982 //------------------------------------------------------------------------------------------------------------------------------------------
983 //------------------------------------------------------------------------------------------------------------------------------------------
984 
986 {
987  return m_rootNodes;
988 }
989 
990 //------------------------------------------------------------------------------------------------------------------------------------------
991 
992 inline const pandora::ParticleFlowObject *LArHierarchyHelper::RecoHierarchy::GetNeutrino() const
993 {
994  return m_pNeutrino;
995 }
996 
997 //------------------------------------------------------------------------------------------------------------------------------------------
998 //------------------------------------------------------------------------------------------------------------------------------------------
999 
1001 {
1002  return m_pMCParticle;
1003 }
1004 
1005 //------------------------------------------------------------------------------------------------------------------------------------------
1006 
1008 {
1009  return m_recoNodes;
1010 }
1011 
1012 //------------------------------------------------------------------------------------------------------------------------------------------
1013 
1015 {
1016  return m_recoNodes.size();
1017 }
1018 
1019 //------------------------------------------------------------------------------------------------------------------------------------------
1020 //------------------------------------------------------------------------------------------------------------------------------------------
1021 
1023 {
1024  return m_matches;
1025 }
1026 
1027 //------------------------------------------------------------------------------------------------------------------------------------------
1028 
1030 {
1031  return m_unmatchedReco;
1032 }
1033 
1034 //------------------------------------------------------------------------------------------------------------------------------------------
1035 
1036 inline const pandora::MCParticle *LArHierarchyHelper::MatchInfo::GetMCNeutrino() const
1037 {
1038  return m_pMCNeutrino;
1039 }
1040 
1041 //------------------------------------------------------------------------------------------------------------------------------------------
1042 
1043 inline const pandora::ParticleFlowObject *LArHierarchyHelper::MatchInfo::GetRecoNeutrino() const
1044 {
1045  return m_pRecoNeutrino;
1046 }
1047 
1048 //------------------------------------------------------------------------------------------------------------------------------------------
1049 
1051 {
1052  return m_qualityCuts;
1053 }
1054 
1055 } // namespace lar_content
1056 
1057 #endif // #ifndef LAR_HIERARCHY_HELPER_H
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
MCMatchesVector m_matches
The vector of good matches from MC to reco.
MCMatchesVector m_goodMatches
The vector of good matches - above threshold one reco to one MC matches.
const unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
std::set< const pandora::MCParticle * > MCParticleSet
Header file for the pfo helper class.
const MCHierarchy::Node * m_pMCParticle
MC node associated with any matches.
const NodeVector & GetChildren() const
Return the vector of children for this node.
bool m_foldToTier
Whether or not to apply folding based on particle tier.
int m_tier
If folding to a tier, the tier to be combined with its child particles.
RecoHierarchy::NodeVector m_recoNodes
Matched reco nodes.
enum cvn::HType HitType
QMapNodeBase Node
Definition: qmap.cpp:41
std::string string
Definition: nybbler.cc:12
pandora::IntVector m_sharedHits
Number of shared hits for each match.
int m_pdg
The PDG code of the leading MC particle for this node.
std::map< const pandora::MCParticle *, pandora::CaloHitList > m_mcToHitsMap
The map between MC particles and calo hits.
const RecoHierarchy & m_hierarchy
The parent reco hierarchy.
const RecoHierarchy::NodeVector & GetRecoMatches() const
Retrieve the vector of matched reco nodes.
int m_pdg
The particle ID (track = muon, shower = electron)
QualityCuts m_qualityCuts
The quality cuts to be applied to matches.
std::vector< int > IntVector
size_t GetNRecoMatches() const
Get the number of reco nodes matched (both above and below quality cut thresholds) to the MC node...
const pandora::CaloHitList & GetCaloHits() const
Retrieve the CaloHits associated with this node.
static void MatchHierarchies(const MCHierarchy &mcHierarchy, const RecoHierarchy &recoHierarchy, MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
const pandora::ParticleFlowObject * m_pNeutrino
The incident neutrino, if it exists.
bool m_isLeadingLepton
Whether or not this node is the leading lepton.
static const pandora::ParticleFlowObject * GetRecoPrimaries(const pandora::PfoList &pfoList, PfoSet &primaries)
Retrieves the primary PFOs from a list and returns the root (neutrino) for hierarchy, if it exists.
pandora::CaloHitList m_caloHits
The list of calo hits of which this node is composed.
const MCHierarchy::Node * GetMC() const
Retrieve the MC node.
const MCMatchesVector & GetMatches() const
Retrieve the vector of matches (this will include null matches - i.e. MC nodes with no corresponding ...
bool IsNeutrinoHierarchy() const
Check if this is a neutrino hierarchy.
static void FillRecoHierarchy(const pandora::PfoList &pfoList, const FoldingParameters &foldParameters, RecoHierarchy &hierarchy)
Fill a reconstructed hierarchy based on the specified folding criteria (see RecoHierarchy::FillHierar...
const pandora::MCParticle * GetLeadingMCParticle() const
Retrieve the leading MC particle associated with this node.
const NodeVector & GetRootNodes() const
Retrieve the root nodes in this hierarchy.
Header file for the lar monte carlo particle helper helper class.
const pandora::MCParticle * GetNeutrino() const
Retrieve the neutrino at the root of the hierarchy if it exists.
const float m_minPurity
The minimum purity for a match to be considered good.
NodeVector m_children
The child nodes of this node.
bool IsCosmicRay() const
Check if this is a cosmic ray particle.
int GetParticleId() const
Retrieve the PDG code for the leading particle in this node.
pandora::PfoList m_pfos
The list of PFOs of which this node is composed.
float m_cosAngleTolerance
Cosine of the maximum angle at which topologies can be considered continuous.
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)
NodeVector m_children
The child nodes of this node.
LArHierarchyHelper class.
const QualityCuts & GetQualityCuts() const
Retrieve the quality cuts for matching.
bool IsLeadingLepton() const
Returns whether or not this particle is the leading lepton in the event.
bool m_foldDynamic
Whether or not to use process and topological information to make folding decisions.
const RecoHierarchy::NodeVector & GetUnmatchedReco() const
Retrieve the vector of unmatched reco nodes.
ReconstructabilityCriteria m_recoCriteria
The criteria used to determine if the node is reconstructable.
const NodeVector & GetChildren() const
Return the vector of children for this node.
bool m_foldToLeadingShowers
Whether or not to fold shower children to the leading shower particle.
const pandora::ParticleFlowObject * GetNeutrino() const
Retrieve the neutrino at the root of the hierarchy if it exists.
MCHierarchy & m_hierarchy
The parent MC hierarchy.
const bool m_removeNeutrons
whether to remove neutrons and their downstream particles
int GetHierarchyTier() const
Retrieve the hierarchy tier of this node.
const pandora::MCParticle * m_mainParticle
The leading MC particle for this node.
std::vector< MCMatches > MCMatchesVector
const pandora::MCParticle * GetMCNeutrino() const
Retrieve the parent MC neutrino if it exists.
pandora::CaloHitList m_caloHits
The list of calo hits of which this node is composed.
MCMatchesVector m_aboveThresholdMatches
The vector of matches that pass quality but with multiple reco matches to the MC. ...
void SetLeadingLepton()
Tags the particle as the leading lepton.
static void FillMCHierarchy(const pandora::MCParticleList &mcParticleList, const pandora::CaloHitList &caloHitList, const FoldingParameters &foldParameters, MCHierarchy &hierarchy)
Fill an MC hierarchy based on the specified folding criteria (see MCHierarchy::FillHierarchy for deta...
pandora::MCParticleList m_mcParticles
The list of MC particles of which this node is composed.
MCHierarchy::NodeVector m_unmatchedMC
The vector of unmatched MC nodes.
const NodeVector & GetRootNodes() const
Retrieve the root nodes in this hierarchy.
bool IsTestBeamHierarchy() const
Check if this is a test beam hierarchy.
int m_nextNodeId
The ID to use for the next node.
const unsigned int m_minHits
the minimum number of primary good Hits
MCMatchesVector m_subThresholdMatches
The vector of matches that don&#39;t pass quality cuts.
RecoHierarchy::NodeVector m_unmatchedReco
The vector of unmatched reco nodes.
int m_tier
The hierarchy tier for this node.
const unsigned int m_minGoodViews
the minimum number of primary good views
const pandora::MCParticleList & GetMCParticles() const
Retrieve the MC particles associated with this node.
bool IsNeutrinoInduced() const
Check if this is a particle induced by a neutrino interaction.
const pandora::MCParticle * m_pMCNeutrino
The parent neutrino if it exists.
bool IsTestBeamParticle() const
Check if this is a test beam particle.
const pandora::ParticleFlowObject * GetRecoNeutrino() const
Retrieve the parent reco neutrino if it exists.
std::set< const pandora::ParticleFlowObject * > PfoSet
const pandora::ParticleFlowObject * m_pRecoNeutrino
The parent neutrino if it exists.
const float m_minCompleteness
The minimum completeness for a match to be considered good.
static const pandora::MCParticle * GetMCPrimaries(const pandora::MCParticleList &mcParticleList, MCParticleSet &primaries)
Retrieves the primary MC particles from a list and returns the root (neutrino) for hierarchy...
std::map< const Node *, int > m_nodeToIdMap
A map from nodes to unique ids.
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)