HierarchyValidationAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArMonitoring/HierarchyValidationAlgorithm.cc
3  *
4  * @brief Implementation of the particle visualisation algorithm.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 HierarchyValidationAlgorithm::HierarchyValidationAlgorithm() :
21  m_event{-1},
22  m_writeTree{false},
23  m_foldToPrimaries{false},
24  m_foldDynamic{false},
26  m_validateEvent{false},
27  m_validateMC{false}
28 {
29 }
30 
31 //------------------------------------------------------------------------------------------------------------------------------------------
32 
34 {
35  if (m_writeTree)
36  {
37  PANDORA_MONITORING_API(SaveTree(this->GetPandora(), m_treename.c_str(), m_filename.c_str(), "UPDATE"));
38  }
39 }
40 
41 //------------------------------------------------------------------------------------------------------------------------------------------
42 
44 {
45  ++m_event;
46  const CaloHitList *pCaloHitList(nullptr);
47  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_caloHitListName, pCaloHitList));
48  const MCParticleList *pMCParticleList(nullptr);
49  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
50  const PfoList *pPfoList(nullptr);
51  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_pfoListName, pPfoList));
52 
55  foldParameters.m_foldToTier = true;
56  else if (m_foldDynamic)
57  foldParameters.m_foldDynamic = true;
58  else if (m_foldToLeadingShowers)
59  foldParameters.m_foldToLeadingShowers = true;
61  LArHierarchyHelper::FillMCHierarchy(*pMCParticleList, *pCaloHitList, foldParameters, mcHierarchy);
63  LArHierarchyHelper::FillRecoHierarchy(*pPfoList, foldParameters, recoHierarchy);
65  LArHierarchyHelper::MatchHierarchies(mcHierarchy, recoHierarchy, matchInfo);
66  matchInfo.Print(mcHierarchy);
67 
68  if (m_validateEvent)
69  this->EventValidation(matchInfo);
70  else if (m_validateMC)
71  this->MCValidation(matchInfo);
72 
73  return STATUS_CODE_SUCCESS;
74 }
75 
76 //------------------------------------------------------------------------------------------------------------------------------------------
77 
79 {
80  if (m_writeTree)
81  {
83  MCParticleSet primaryMCSet;
84  std::set<const LArHierarchyHelper::MCHierarchy::Node *> trackNodeSet, showerNodeSet;
85  int nGoodTrackMatches{0}, nGoodShowerMatches{0};
86  int nGoodMatches{0}, nPoorMatches{0}, nUnmatched{0};
87  int nGoodTier1Matches{0}, nTier1Nodes{0};
88  int nGoodTier1TrackMatches{0}, nTier1TrackNodes{0};
89  int nGoodTier1ShowerMatches{0}, nTier1ShowerNodes{0};
90  int hasLeadingMuon{0}, hasLeadingElectron{0}, isLeadingLeptonCorrect{0};
91  // ATTN: Probably want quality cuts here for "good match" definition
92  for (const LArHierarchyHelper::MCMatches &mcMatch : matches)
93  {
94  const LArHierarchyHelper::MCHierarchy::Node *pNode{mcMatch.GetMC()};
95  const MCParticle *const pMC{pNode->GetLeadingMCParticle()};
96  primaryMCSet.insert(LArMCParticleHelper::GetPrimaryMCParticle(pMC));
97  const int nReco{static_cast<int>(mcMatch.GetRecoMatches().size())};
98  const bool isQuality{mcMatch.IsQuality(matchInfo.GetQualityCuts())};
99  if (nReco == 1 && isQuality)
100  ++nGoodMatches;
101  else if (nReco == 1)
102  ++nPoorMatches;
103  else if (nReco > 1)
104  ++nPoorMatches;
105  else
106  ++nUnmatched;
107  if (pNode->GetHierarchyTier() == 1)
108  {
109  ++nTier1Nodes;
110  if (nReco == 1 && isQuality)
111  ++nGoodTier1Matches;
112  }
113 
114  const int pdg{std::abs(pNode->GetParticleId())};
115  if (pNode->IsLeadingLepton())
116  {
117  if (pdg == MU_MINUS)
118  hasLeadingMuon = 1;
119  else if (pdg == E_MINUS)
120  hasLeadingElectron = 1;
121  isLeadingLeptonCorrect = nReco == 1 ? 1 : 0;
122  }
123 
124  if (pdg == PHOTON || pdg == E_MINUS)
125  {
126  showerNodeSet.insert(pNode);
127  if (nReco == 1 && isQuality)
128  {
129  ++nGoodShowerMatches;
130  if (pNode->GetHierarchyTier() == 1)
131  ++nGoodTier1ShowerMatches;
132  }
133  if (pNode->GetHierarchyTier() == 1)
134  ++nTier1ShowerNodes;
135  }
136  else
137  {
138  trackNodeSet.insert(pNode);
139  if (nReco == 1 && isQuality)
140  {
141  ++nGoodTrackMatches;
142  if (pNode->GetHierarchyTier() == 1)
143  ++nGoodTier1TrackMatches;
144  }
145  if (pNode->GetHierarchyTier() == 1)
146  ++nTier1TrackNodes;
147  }
148  }
149 
150  MCParticleList primaryMCList;
151  for (const MCParticle *const pMC : primaryMCSet)
152  primaryMCList.emplace_back(pMC);
153  const int interactionType{static_cast<int>(LArInteractionTypeHelper::GetInteractionType(primaryMCList))};
154  const int nNodes{static_cast<int>(matchInfo.GetNMCNodes())};
155 
156  const int nTrackNodes{static_cast<int>(trackNodeSet.size())}, nShowerNodes{static_cast<int>(showerNodeSet.size())};
157  const CartesianVector &trueVertex{matchInfo.GetMCNeutrino()->GetVertex()};
158  const CartesianVector &recoVertex{LArPfoHelper::GetVertex(matchInfo.GetRecoNeutrino())->GetPosition()};
159  const float vtxDx{recoVertex.GetX() - trueVertex.GetX()};
160  const float vtxDy{recoVertex.GetY() - trueVertex.GetY()};
161  const float vtxDz{recoVertex.GetZ() - trueVertex.GetZ()};
162  const float vtxDr{std::sqrt(vtxDx * vtxDx + vtxDy * vtxDy + vtxDz * vtxDz)};
163 
164  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "event", m_event));
165  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "interactionType", interactionType));
166  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodMatches", nGoodMatches));
167  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPoorMatches", nPoorMatches));
168  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nUnmatched", nUnmatched));
169  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nNodes", nNodes));
170  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTier1Matches", nGoodTier1Matches));
171  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTier1Nodes", nTier1Nodes));
172  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTrackMatches", nGoodTrackMatches));
173  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodShowerMatches", nGoodShowerMatches));
174  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTrackNodes", nTrackNodes));
175  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nShowerNodes", nShowerNodes));
176  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTier1TrackMatches", nGoodTier1TrackMatches));
177  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTier1TrackNodes", nTier1TrackNodes));
178  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTier1ShowerMatches", nGoodTier1ShowerMatches));
179  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTier1ShowerNodes", nTier1ShowerNodes));
180  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "hasLeadingMuon", hasLeadingMuon));
181  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "hasLeadingElectron", hasLeadingElectron));
182  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isLeadingLeptonCorrect", isLeadingLeptonCorrect));
183  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDx", vtxDx));
184  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDy", vtxDy));
185  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDz", vtxDz));
186  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDr", vtxDr));
187  PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_treename.c_str()));
188  }
189 }
190 
191 //------------------------------------------------------------------------------------------------------------------------------------------
192 
194 {
195  if (m_writeTree)
196  {
197  for (const LArHierarchyHelper::MCMatches &match : matchInfo.GetMatches())
198  this->Fill(match, matchInfo);
199  }
200 }
201 
202 //------------------------------------------------------------------------------------------------------------------------------------------
203 
205 {
206  const LArHierarchyHelper::MCHierarchy::Node *pMCNode{matches.GetMC()};
207  const int isTestBeam{pMCNode->IsTestBeamParticle() ? 1 : 0};
208  const int isCosmicRay{!isTestBeam && pMCNode->IsCosmicRay() ? 1 : 0};
209  const int isNeutrinoInt{!(isTestBeam || isCosmicRay) ? 1 : 0};
210  const int mcId{pMCNode->GetId()};
211  const int pdg{pMCNode->GetParticleId()};
212  const int tier{pMCNode->GetHierarchyTier()};
213  const int mcHits{static_cast<int>(pMCNode->GetCaloHits().size())};
214  const int isLeadingLepton{pMCNode->IsLeadingLepton() ? 1 : 0};
215 
216  const MCParticleList &parentList{pMCNode->GetLeadingMCParticle()->GetParentList()};
217  const int isElectron{std::abs(pMCNode->GetLeadingMCParticle()->GetParticleId()) == E_MINUS ? 1 : 0};
218  const int hasMuonParent{parentList.size() == 1 && std::abs(parentList.front()->GetParticleId()) == MU_MINUS ? 1 : 0};
219  const int isMichel{isElectron && hasMuonParent && LArMCParticleHelper::IsDecay(pMCNode->GetLeadingMCParticle()) ? 1 : 0};
220 
222  const int nMatches{static_cast<int>(nodeVector.size())};
223  IntVector recoIdVector, nRecoHitsVector, nSharedHitsVector;
224  FloatVector purityVector, completenessVector;
225  FloatVector purityAdcVector, completenessAdcVector;
226  FloatVector purityVectorU, purityVectorV, purityVectorW, completenessVectorU, completenessVectorV, completenessVectorW;
227  FloatVector purityAdcVectorU, purityAdcVectorV, purityAdcVectorW, completenessAdcVectorU, completenessAdcVectorV, completenessAdcVectorW;
228  const CartesianVector &trueVertex{pMCNode->GetLeadingMCParticle()->GetVertex()};
229  float vtxDx{0.f}, vtxDy{0.f}, vtxDz{0.f}, vtxDr{0.f};
230  for (const LArHierarchyHelper::RecoHierarchy::Node *pRecoNode : nodeVector)
231  {
232  recoIdVector.emplace_back(pRecoNode->GetParticleId());
233  nRecoHitsVector.emplace_back(static_cast<int>(pRecoNode->GetCaloHits().size()));
234  nSharedHitsVector.emplace_back(static_cast<int>(matches.GetSharedHits(pRecoNode)));
235  purityVector.emplace_back(matches.GetPurity(pRecoNode));
236  completenessVector.emplace_back(matches.GetCompleteness(pRecoNode));
237  purityAdcVector.emplace_back(matches.GetPurity(pRecoNode, true));
238  completenessAdcVector.emplace_back(matches.GetCompleteness(pRecoNode, true));
239  purityVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U));
240  purityVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V));
241  purityVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W));
242  completenessVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U));
243  completenessVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V));
244  completenessVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W));
245  purityAdcVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U, true));
246  purityAdcVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V, true));
247  purityAdcVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W, true));
248  completenessAdcVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U, true));
249  completenessAdcVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V, true));
250  completenessAdcVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W, true));
251  if (nMatches == 1)
252  {
253  // Only makes sense to calculate vertex delta if we have a one-to-one match
254  const CartesianVector &recoVertex{LArPfoHelper::GetVertex(matchInfo.GetRecoNeutrino())->GetPosition()};
255  vtxDx = recoVertex.GetX() - trueVertex.GetX();
256  vtxDy = recoVertex.GetY() - trueVertex.GetY();
257  vtxDz = recoVertex.GetZ() - trueVertex.GetZ();
258  vtxDr = std::sqrt(vtxDx * vtxDx + vtxDy * vtxDy + vtxDz * vtxDz);
259  }
260  }
261 
262  // Would like to add information on hierarchy matching. Needs some thought, it's extremely complicated
263 
264  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "event", m_event));
265  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcId", mcId));
266  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcPDG", pdg));
267  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcTier", tier));
268  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcNHits", mcHits));
269  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isNuInteration", isNeutrinoInt));
270  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isCosmicRay", isCosmicRay));
271  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isTestBeam", isTestBeam));
272  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isLeadingLepton", isLeadingLepton));
273  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isMichel", isMichel));
274  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nMatches", nMatches));
275  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "recoIdVector", &recoIdVector));
276  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nRecoHitsVector", &nRecoHitsVector));
277  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nSharedHitsVector", &nSharedHitsVector));
278  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVector", &purityVector));
279  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVector", &completenessVector));
280  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVector", &purityAdcVector));
281  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVector", &completenessAdcVector));
282  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVectorU", &purityVectorU));
283  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVectorV", &purityVectorV));
284  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVectorW", &purityVectorW));
285  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVectorU", &completenessVectorU));
286  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVectorV", &completenessVectorV));
287  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVectorW", &completenessVectorW));
288  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVectorU", &purityAdcVectorU));
289  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVectorV", &purityAdcVectorV));
290  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVectorW", &purityAdcVectorW));
291  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVectorU", &completenessAdcVectorU));
292  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVectorV", &completenessAdcVectorV));
293  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVectorW", &completenessAdcVectorW));
294  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDx", vtxDx));
295  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDy", vtxDy));
296  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDz", vtxDz));
297  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDr", vtxDr));
298  PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_treename.c_str()));
299 }
300 
301 //------------------------------------------------------------------------------------------------------------------------------------------
302 
303 StatusCode HierarchyValidationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
304 {
305  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CaloHitListName", m_caloHitListName));
306  if (m_caloHitListName.empty())
307  m_caloHitListName = "CaloHitList2D";
308  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PfoListName", m_pfoListName));
309  if (m_pfoListName.empty())
310  m_pfoListName = "RecreatedPfos";
311 
312  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ValidateEvent", m_validateEvent));
313  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ValidateMC", m_validateMC));
314 
315  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteTree", m_writeTree));
316  if (m_writeTree)
317  {
318  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "FileName", m_filename));
319  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "TreeName", m_treename));
320  if (!(m_validateEvent || m_validateMC))
321  {
322  std::cout << "Error: WriteTree requested but no tree names found" << std::endl;
323  return STATUS_CODE_NOT_FOUND;
324  }
325  else if (m_validateEvent && m_validateMC)
326  {
327  std::cout << "Error: Both event-level and MC-level validation requested simulataneously" << std::endl;
328  return STATUS_CODE_INVALID_PARAMETER;
329  }
330  }
331 
332  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldToPrimaries", m_foldToPrimaries));
333  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldDynamic", m_foldDynamic));
334  PANDORA_RETURN_RESULT_IF_AND_IF(
335  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldToLeadingShowers", m_foldToLeadingShowers));
336 
337  return STATUS_CODE_SUCCESS;
338 }
339 
340 } // namespace lar_content
bool m_foldToTier
Whether or not to apply folding based on particle tier.
bool m_foldToPrimaries
Whether or not to fold the hierarchy back to primary particles.
Header file for the interaction type helper class.
bool m_foldToLeadingShowers
Whether or not to fold the hierarchy back to leading shower particles.
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
static const pandora::MCParticle * GetPrimaryMCParticle(const pandora::MCParticle *const pMCParticle)
Get the primary parent mc particle.
const RecoHierarchy::NodeVector & GetRecoMatches() const
Retrieve the vector of matched reco nodes.
std::vector< int > IntVector
static void MatchHierarchies(const MCHierarchy &mcHierarchy, const RecoHierarchy &recoHierarchy, MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
void MCValidation(const LArHierarchyHelper::MatchInfo &matchInfo) const
Validate information at the level of MC nodes.
static InteractionType GetInteractionType(const pandora::MCParticleList &mcPrimaryList)
Get the interaction type of an event.
const MCHierarchy::Node * GetMC() const
Retrieve the MC node.
unsigned int GetNMCNodes() const
Retrieve the number of MC nodes available to match.
const MCMatchesVector & GetMatches() const
Retrieve the vector of matches (this will include null matches - i.e. MC nodes with no corresponding ...
void EventValidation(const LArHierarchyHelper::MatchInfo &matchInfo) const
Validate information at the level of MC nodes.
T abs(T value)
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.
void Fill(const LArHierarchyHelper::MCMatches &matches, const LArHierarchyHelper::MatchInfo &matchInfo) const
Collates variables and fills ROOT tree for MC particles with matches.
unsigned int GetSharedHits(const RecoHierarchy::Node *pReco) const
Retrieve the number of shared hits in the match.
float GetPurity(const RecoHierarchy::Node *pReco, const bool adcWeighted=false) const
Retrieve the purity of the match.
static bool IsDecay(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from a decay process.
const QualityCuts & GetQualityCuts() const
Retrieve the quality cuts for matching.
std::string m_pfoListName
Name of input PFO list.
bool m_foldDynamic
Whether or not to use process and topological information to make folding decisions.
bool m_foldDynamic
Whether or not to fold the hierarchy dynamically.
void Print(const MCHierarchy &mcHierarchy) const
Prints information about which reco nodes are matched to the MC nodes, information about hit sharing...
bool m_foldToLeadingShowers
Whether or not to fold shower children to the leading shower particle.
std::string m_caloHitListName
Name of input calo hit list.
std::vector< MCMatches > MCMatchesVector
const pandora::MCParticle * GetMCNeutrino() const
Retrieve the parent MC neutrino if it exists.
bool m_writeTree
Whether or not to output validation information to a ROOT file.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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...
std::string m_filename
The name of the ROOT file to write.
Dft::FloatVector FloatVector
float GetCompleteness(const RecoHierarchy::Node *pReco, const bool adcWeighted=false) const
Retrieve the completeness of the match.
std::string m_treename
The name of the ROOT tree to write.
bool m_validateMC
Whether to validate at the level of MC nodes.
bool IsTestBeamParticle() const
Check if this is a test beam particle.
Header file for the hierarchy validation algorithm.
const pandora::ParticleFlowObject * GetRecoNeutrino() const
Retrieve the parent reco neutrino if it exists.
QTextStream & endl(QTextStream &s)
bool m_validateEvent
Whether to validate at the level of an event.