9 #include "Pandora/AlgorithmHeaders.h" 21 HierarchyValidationAlgorithm::HierarchyValidationAlgorithm() :
41 PANDORA_MONITORING_API(SaveTree(this->GetPandora(),
m_treename.c_str(),
m_filename.c_str(),
"UPDATE"));
50 const CaloHitList *pCaloHitList(
nullptr);
51 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_caloHitListName, pCaloHitList));
52 const MCParticleList *pMCParticleList(
nullptr);
53 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*
this, pMCParticleList));
54 const PfoList *pPfoList(
nullptr);
55 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_pfoListName, pPfoList));
71 matchInfo.
Print(mcHierarchy);
75 this->EventValidation(matchInfo);
77 this->MCValidation(matchInfo);
80 return STATUS_CODE_SUCCESS;
91 MCParticleList rootMCParticles;
97 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
98 for (
const ParticleFlowObject *
const pRoot : rootPfos)
101 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
103 recoNodeToRootMap[pNode] = pRoot;
106 std::set<const pandora::ParticleFlowObject *> matchedRecoSliceRoots;
107 for (
const MCParticle *
const pRoot : rootMCParticles)
111 MCParticleList primaries;
115 if (pMCNode->GetHierarchyTier() == 1)
118 primaries.emplace_back(pLeadingMC);
124 const int isCC{descriptor.
IsCC()};
125 const int isQE{descriptor.IsQE()};
126 const int isResonant{descriptor.IsResonant()};
127 const int isDIS{descriptor.IsDIS()};
128 const int isCoherent{descriptor.IsCoherent()};
129 const int isNuMu{descriptor.IsMuonNeutrino()};
130 const int isNuE{descriptor.IsElectronNeutrino()};
131 const int nPiZero{
static_cast<int>(descriptor.GetNumPiZero())};
132 const int nPiPlus{
static_cast<int>(descriptor.GetNumPiPlus())};
133 const int nPiMinus{
static_cast<int>(descriptor.GetNumPiMinus())};
134 const int nPhotons{
static_cast<int>(descriptor.GetNumPhotons())};
135 const int nProtons{
static_cast<int>(descriptor.GetNumProtons())};
137 std::set<const LArHierarchyHelper::MCHierarchy::Node *> trackNodeSet, showerNodeSet;
138 int nGoodTrackMatches{0}, nGoodShowerMatches{0};
139 int nGoodMatches{0}, nPoorMatches{0}, nUnmatched{0};
140 int nGoodTier1Matches{0}, nTier1Nodes{0};
141 int nGoodTier1TrackMatches{0}, nTier1TrackNodes{0};
142 int nGoodTier1ShowerMatches{0}, nTier1ShowerNodes{0};
143 int hasLeadingMuon{0}, hasLeadingElectron{0}, isLeadingLeptonCorrect{0};
149 matchedRecoSliceRoots.insert(recoNodeToRootMap[pReco]);
151 const int nReco{
static_cast<int>(mcMatch.GetRecoMatches().size())};
152 const bool isQuality{mcMatch.IsQuality(matchInfo.
GetQualityCuts())};
153 if (nReco == 1 && isQuality)
159 if (pNode->GetHierarchyTier() == 1)
162 if (nReco == 1 && isQuality)
166 const int pdg{
std::abs(pNode->GetParticleId())};
167 if (pNode->IsLeadingLepton())
171 else if (pdg == E_MINUS)
172 hasLeadingElectron = 1;
173 isLeadingLeptonCorrect = nReco == 1 ? 1 : 0;
176 if (pdg == PHOTON || pdg == E_MINUS)
178 showerNodeSet.insert(pNode);
179 if (nReco == 1 && isQuality)
181 ++nGoodShowerMatches;
182 if (pNode->GetHierarchyTier() == 1)
183 ++nGoodTier1ShowerMatches;
185 if (pNode->GetHierarchyTier() == 1)
190 trackNodeSet.insert(pNode);
191 if (nReco == 1 && isQuality)
194 if (pNode->GetHierarchyTier() == 1)
195 ++nGoodTier1TrackMatches;
197 if (pNode->GetHierarchyTier() == 1)
202 const int nNodes{
static_cast<int>(matchInfo.
GetNMCNodes(pRoot))};
203 const int nTrackNodes{
static_cast<int>(trackNodeSet.size())}, nShowerNodes{
static_cast<int>(showerNodeSet.size())};
204 const int nRecoSlices{
static_cast<int>(matchedRecoSliceRoots.size())};
205 const CartesianVector &trueVertex{pRoot->GetVertex()};
206 float vtxDx{std::numeric_limits<float>::max()};
207 float vtxDy{std::numeric_limits<float>::max()};
208 float vtxDz{std::numeric_limits<float>::max()};
209 float vtxDr{std::numeric_limits<float>::max()};
212 for (
const ParticleFlowObject *pRootPfo : matchedRecoSliceRoots)
215 const float dx{recoVertex.GetX() - trueVertex.GetX()};
216 const float dy{recoVertex.GetY() - trueVertex.GetY()};
217 const float dz{recoVertex.GetZ() - trueVertex.GetZ()};
218 const float dr{std::sqrt(dx * dx + dy * dy + dz * dz)};
228 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"event",
m_event));
229 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"interaction",
interaction));
230 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nRecoSlices", nRecoSlices));
231 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isCC", isCC));
232 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isQE", isQE));
233 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isResonant", isResonant));
234 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isDIS", isDIS));
235 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isCoherent", isCoherent));
236 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isNuMu", isNuMu));
237 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isNuE", isNuE));
238 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPiZero", nPiZero));
239 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPiPlus", nPiPlus));
240 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPiMinus", nPiMinus));
241 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPhotons", nPhotons));
242 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nProtons", nProtons));
243 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isFiducial", isFiducial));
244 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDx", vtxDx));
245 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDy", vtxDy));
246 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDz", vtxDz));
247 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDr", vtxDr));
248 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nGoodMatches", nGoodMatches));
249 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPoorMatches", nPoorMatches));
250 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nUnmatched", nUnmatched));
251 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nNodes", nNodes));
252 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nGoodTier1Matches", nGoodTier1Matches));
253 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nTier1Nodes", nTier1Nodes));
254 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nGoodTrackMatches", nGoodTrackMatches));
255 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nGoodShowerMatches", nGoodShowerMatches));
256 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nTrackNodes", nTrackNodes));
257 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nShowerNodes", nShowerNodes));
258 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nGoodTier1TrackMatches", nGoodTier1TrackMatches));
259 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nTier1TrackNodes", nTier1TrackNodes));
260 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nGoodTier1ShowerMatches", nGoodTier1ShowerMatches));
261 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nTier1ShowerNodes", nTier1ShowerNodes));
262 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"hasLeadingMuon", hasLeadingMuon));
263 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"hasLeadingElectron", hasLeadingElectron));
264 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isLeadingLeptonCorrect", isLeadingLeptonCorrect));
265 PANDORA_MONITORING_API(FillTree(this->GetPandora(),
m_treename.c_str()));
278 MCParticleList rootMCParticles;
283 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
284 for (
const ParticleFlowObject *
const pRoot : rootPfos)
287 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
289 recoNodeToRootMap[pNode] = pRoot;
292 for (
const MCParticle *
const pRoot : rootMCParticles)
294 MCParticleList primaries;
298 if (pMCNode->GetHierarchyTier() == 1)
301 primaries.emplace_back(pLeadingMC);
311 const int isCosmicRay{!isTestBeam && pMCNode->IsCosmicRay() ? 1 : 0};
312 const int isNeutrinoInt{!(isTestBeam || isCosmicRay) ? 1 : 0};
313 const int mcId{pMCNode->GetId()};
314 const int pdg{pMCNode->GetParticleId()};
315 const int tier{pMCNode->GetHierarchyTier()};
316 const int mcHits{
static_cast<int>(pMCNode->GetCaloHits().size())};
317 const int isLeadingLepton{pMCNode->IsLeadingLepton() ? 1 : 0};
319 const MCParticle *
const pLeadingMC{pMCNode->GetLeadingMCParticle()};
320 const MCParticleList &parentList{pLeadingMC->GetParentList()};
321 const int isElectron{
std::abs(pLeadingMC->GetParticleId()) == E_MINUS ? 1 : 0};
322 const int hasMuonParent{parentList.size() == 1 &&
std::abs(parentList.front()->GetParticleId()) == MU_MINUS ? 1 : 0};
324 const float mcMomentum{pLeadingMC->GetMomentum().GetMagnitude()};
327 const int nMatches{
static_cast<int>(nodeVector.size())};
328 IntVector recoSliceIdVector, recoIdVector, nRecoHitsVector, nSharedHitsVector;
329 FloatVector purityVector, completenessVector;
330 FloatVector purityAdcVector, completenessAdcVector;
331 FloatVector purityVectorU, purityVectorV, purityVectorW, completenessVectorU, completenessVectorV, completenessVectorW;
332 FloatVector purityAdcVectorU, purityAdcVectorV, purityAdcVectorW, completenessAdcVectorU, completenessAdcVectorV, completenessAdcVectorW;
333 const CartesianVector &trueVertex{pLeadingMC->GetVertex()};
334 float vtxDx{0.f}, vtxDy{0.f}, vtxDz{0.f}, vtxDr{0.f};
336 const int isCC{descriptor.IsCC()};
337 const int isQE{descriptor.IsQE()};
338 const int isResonant{descriptor.IsResonant()};
339 const int isDIS{descriptor.IsDIS()};
340 const int isCoherent{descriptor.IsCoherent()};
341 const int isNuMu{descriptor.IsMuonNeutrino()};
342 const int isNuE{descriptor.IsElectronNeutrino()};
343 const int nPiZero{
static_cast<int>(descriptor.GetNumPiZero())};
344 const int nPiPlus{
static_cast<int>(descriptor.GetNumPiPlus())};
345 const int nPiMinus{
static_cast<int>(descriptor.GetNumPiMinus())};
346 const int nPhotons{
static_cast<int>(descriptor.GetNumPhotons())};
347 const int nProtons{
static_cast<int>(descriptor.GetNumProtons())};
351 const int sliceId{
static_cast<int>(
352 std::distance(rootPfos.begin(), std::find(rootPfos.begin(), rootPfos.end(), recoNodeToRootMap[pRecoNode])))};
353 recoSliceIdVector.emplace_back(sliceId);
354 recoIdVector.emplace_back(pRecoNode->GetParticleId());
355 nRecoHitsVector.emplace_back(static_cast<int>(pRecoNode->GetCaloHits().size()));
356 nSharedHitsVector.emplace_back(static_cast<int>(matches.GetSharedHits(pRecoNode)));
357 purityVector.emplace_back(matches.GetPurity(pRecoNode));
358 completenessVector.emplace_back(matches.GetCompleteness(pRecoNode));
359 purityAdcVector.emplace_back(matches.GetPurity(pRecoNode,
true));
360 completenessAdcVector.emplace_back(matches.GetCompleteness(pRecoNode,
true));
361 purityVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U));
362 purityVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V));
363 purityVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W));
364 completenessVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U));
365 completenessVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V));
366 completenessVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W));
367 purityAdcVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U,
true));
368 purityAdcVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V,
true));
369 purityAdcVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W,
true));
370 completenessAdcVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U,
true));
371 completenessAdcVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V,
true));
372 completenessAdcVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W,
true));
376 vtxDx = recoVertex.GetX() - trueVertex.GetX();
377 vtxDy = recoVertex.GetY() - trueVertex.GetY();
378 vtxDz = recoVertex.GetZ() - trueVertex.GetZ();
379 vtxDr = std::sqrt(vtxDx * vtxDx + vtxDy * vtxDy + vtxDz * vtxDz);
383 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"event",
m_event));
384 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"interaction",
interaction));
385 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"mcId", mcId));
386 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"mcPDG", pdg));
387 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"mcTier", tier));
388 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"mcNHits", mcHits));
389 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"mcMomentum", mcMomentum));
390 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isNuInteration", isNeutrinoInt));
391 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isCosmicRay", isCosmicRay));
392 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isTestBeam", isTestBeam));
393 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isLeadingLepton", isLeadingLepton));
394 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isMichel", isMichel));
395 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nMatches", nMatches));
396 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"recoSliceIdVector", &recoSliceIdVector));
397 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"recoIdVector", &recoIdVector));
398 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nRecoHitsVector", &nRecoHitsVector));
399 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nSharedHitsVector", &nSharedHitsVector));
400 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityVector", &purityVector));
401 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessVector", &completenessVector));
402 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityAdcVector", &purityAdcVector));
403 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessAdcVector", &completenessAdcVector));
404 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityVectorU", &purityVectorU));
405 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityVectorV", &purityVectorV));
406 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityVectorW", &purityVectorW));
407 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessVectorU", &completenessVectorU));
408 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessVectorV", &completenessVectorV));
409 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessVectorW", &completenessVectorW));
410 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityAdcVectorU", &purityAdcVectorU));
411 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityAdcVectorV", &purityAdcVectorV));
412 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"purityAdcVectorW", &purityAdcVectorW));
413 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessAdcVectorU", &completenessAdcVectorU));
414 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessAdcVectorV", &completenessAdcVectorV));
415 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"completenessAdcVectorW", &completenessAdcVectorW));
416 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDx", vtxDx));
417 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDy", vtxDy));
418 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDz", vtxDz));
419 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"vtxDr", vtxDr));
420 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isCC", isCC));
421 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isQE", isQE));
422 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isResonant", isResonant));
423 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isDIS", isDIS));
424 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isCoherent", isCoherent));
425 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isNuMu", isNuMu));
426 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"isNuE", isNuE));
427 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPiZero", nPiZero));
428 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPiPlus", nPiPlus));
429 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPiMinus", nPiMinus));
430 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nPhotons", nPhotons));
431 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_treename.c_str(),
"nProtons", nProtons));
432 PANDORA_MONITORING_API(FillTree(this->GetPandora(),
m_treename.c_str()));
444 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
447 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PfoListName",
m_pfoListName));
451 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"Detector",
m_detector));
453 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ValidateEvent",
m_validateEvent));
454 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ValidateMC",
m_validateMC));
456 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"WriteTree",
m_writeTree));
459 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"FileName",
m_filename));
460 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"TreeName",
m_treename));
463 std::cout <<
"Error: WriteTree requested but no tree names found" << std::endl;
464 return STATUS_CODE_NOT_FOUND;
468 std::cout <<
"Error: Both event-level and MC-level validation requested simulataneously" << std::endl;
469 return STATUS_CODE_INVALID_PARAMETER;
473 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldToPrimaries",
m_foldToPrimaries));
474 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldDynamic",
m_foldDynamic));
475 PANDORA_RETURN_RESULT_IF_AND_IF(
476 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldToLeadingShowers",
m_foldToLeadingShowers));
478 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinPurity",
m_minPurity));
479 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCompleteness",
m_minCompleteness));
481 return STATUS_CODE_SUCCESS;
const MCMatchesVector & GetMatches(const pandora::MCParticle *const pRoot) const
Retrieve the vector of matches (this will include null matches - i.e. MC nodes with no corresponding ...
const RecoHierarchy & GetRecoHierarchy() const
Retrieve the reco hierarchy used for the matching.
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.
std::vector< const Node * > NodeVector
std::string m_detector
Name of the detector.
void GetRootMCParticles(pandora::MCParticleList &rootMCParticles) const
Retrieve the root MC particles of the interaction hierarchies.
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.
constexpr auto abs(T v)
Returns the absolute value of the argument.
virtual ~HierarchyValidationAlgorithm()
std::vector< int > IntVector
static void MatchHierarchies(MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
float m_minPurity
Minimum purity to tag a node as being of good quality.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
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.
int m_event
The current event.
float m_minCompleteness
Minimum completeness to tag a node as being of good quality.
pandora::StatusCode Run()
static bool IsInFiducialVolume(const pandora::Pandora &pandora, const pandora::CartesianVector &vertex, const std::string &detector)
Determine if a vertex is within a detector's fiducial volume. This throws a STATUS_CODE_INVALID_PARAM...
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.
Header file for the vertex helper class.
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
bool m_writeTree
Whether or not to output validation information to a ROOT file.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void GetRootPfos(pandora::PfoList &rootPfos) const
Retrieve the root particle flow objects of the interaction hierarchies.
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...
unsigned int GetNMCNodes(const pandora::MCParticle *const pRoot) const
Retrieve the number of MC nodes available to match.
std::string m_filename
The name of the ROOT file to write.
static InteractionDescriptor GetInteractionDescriptor(const pandora::MCParticleList &mcPrimaryList)
Get the interaction descriptor of an event.
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 IsCC() const
Whether or not the interaction is CC.
bool IsTestBeamParticle() const
Check if this is a test beam particle.
Header file for the hierarchy validation algorithm.
bool m_validateEvent
Whether to validate at the level of an event.