9 #include "Pandora/AlgorithmHeaders.h" 21 HierarchyValidationAlgorithm::HierarchyValidationAlgorithm() :
60 const CaloHitList *pCaloHitList(
nullptr);
61 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_caloHitListName, pCaloHitList));
62 const MCParticleList *pMCParticleList(
nullptr);
63 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*
this, pMCParticleList));
64 const PfoList *pPfoList(
nullptr);
65 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_pfoListName, pPfoList));
84 matchInfo.
Print(mcHierarchy);
88 this->EventValidation(matchInfo);
90 this->MCValidation(matchInfo);
93 return STATUS_CODE_SUCCESS;
104 MCParticleList rootMCParticles;
110 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
111 for (
const ParticleFlowObject *
const pRoot : rootPfos)
114 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
116 recoNodeToRootMap[pNode] = pRoot;
119 std::set<const pandora::ParticleFlowObject *> matchedRecoSliceRoots;
120 for (
const MCParticle *
const pRoot : rootMCParticles)
124 MCParticleList primaries;
128 if (pMCNode->GetHierarchyTier() == 1)
131 primaries.emplace_back(pLeadingMC);
135 if (primaries.size() == 0)
139 int isCC{0}, isQE{0}, isResonant{0}, isDIS{0}, isCoherent{0}, isNuMu{0}, isNuE{0}, nPiZero{0}, nPiPlus{0}, nPiMinus{0},
140 nPhotons{0}, nProtons{0};
145 isCC = descriptor.
IsCC();
146 isQE = descriptor.IsQE();
147 isResonant = descriptor.IsResonant();
148 isDIS = descriptor.IsDIS();
149 isCoherent = descriptor.IsCoherent();
150 isNuMu = descriptor.IsMuonNeutrino();
151 isNuE = descriptor.IsElectronNeutrino();
152 nPiZero =
static_cast<int>(descriptor.GetNumPiZero());
153 nPiPlus =
static_cast<int>(descriptor.GetNumPiPlus());
154 nPiMinus =
static_cast<int>(descriptor.GetNumPiMinus());
155 nPhotons =
static_cast<int>(descriptor.GetNumPhotons());
156 nProtons =
static_cast<int>(descriptor.GetNumProtons());
162 std::set<const LArHierarchyHelper::MCHierarchy::Node *> trackNodeSet, showerNodeSet;
163 int nGoodTrackMatches{0}, nGoodShowerMatches{0};
164 int nGoodMatches{0}, nPoorMatches{0}, nUnmatched{0};
165 int nGoodTier1Matches{0}, nTier1Nodes{0};
166 int nGoodTier1TrackMatches{0}, nTier1TrackNodes{0};
167 int nGoodTier1ShowerMatches{0}, nTier1ShowerNodes{0};
168 int hasLeadingMuon{0}, hasLeadingElectron{0}, isLeadingLeptonCorrect{0};
174 matchedRecoSliceRoots.insert(recoNodeToRootMap[pReco]);
176 const int nReco{
static_cast<int>(mcMatch.GetRecoMatches().size())};
177 const bool isQuality{mcMatch.IsQuality(matchInfo.
GetQualityCuts())};
178 if (nReco == 1 && isQuality)
184 if (pNode->GetHierarchyTier() == 1)
187 if (nReco == 1 && isQuality)
191 const int pdg{
std::abs(pNode->GetParticleId())};
192 if (pNode->IsLeadingLepton())
196 else if (pdg == E_MINUS)
197 hasLeadingElectron = 1;
198 isLeadingLeptonCorrect = nReco == 1 ? 1 : 0;
201 if (pdg == PHOTON || pdg == E_MINUS)
203 showerNodeSet.insert(pNode);
204 if (nReco == 1 && isQuality)
206 ++nGoodShowerMatches;
207 if (pNode->GetHierarchyTier() == 1)
208 ++nGoodTier1ShowerMatches;
210 if (pNode->GetHierarchyTier() == 1)
215 trackNodeSet.insert(pNode);
216 if (nReco == 1 && isQuality)
219 if (pNode->GetHierarchyTier() == 1)
220 ++nGoodTier1TrackMatches;
222 if (pNode->GetHierarchyTier() == 1)
227 const int nNodes{
static_cast<int>(matchInfo.
GetNMCNodes(pRoot))};
228 const int nTrackNodes{
static_cast<int>(trackNodeSet.size())}, nShowerNodes{
static_cast<int>(showerNodeSet.size())};
229 const int nRecoSlices{
static_cast<int>(matchedRecoSliceRoots.size())};
230 const CartesianVector &trueVertex{pRoot->GetVertex()};
231 const float trueVtxX{trueVertex.GetX()};
232 const float trueVtxY{trueVertex.GetY()};
233 const float trueVtxZ{trueVertex.GetZ()};
234 float recoVtxX{std::numeric_limits<float>::max()};
235 float recoVtxY{std::numeric_limits<float>::max()};
236 float recoVtxZ{std::numeric_limits<float>::max()};
237 float vtxDx{std::numeric_limits<float>::max()};
238 float vtxDy{std::numeric_limits<float>::max()};
239 float vtxDz{std::numeric_limits<float>::max()};
240 float vtxDr{std::numeric_limits<float>::max()};
243 for (
const ParticleFlowObject *pRootPfo : matchedRecoSliceRoots)
248 const float recoVertexX{recoVertex.GetX()};
249 const float recoVertexY{recoVertex.GetY()};
250 const float recoVertexZ{recoVertex.GetZ()};
251 const float dx{recoVertexX - trueVtxX};
252 const float dy{recoVertexY - trueVtxY};
253 const float dz{recoVertexZ - trueVtxZ};
254 const float dr{std::sqrt(dx * dx + dy * dy + dz * dz)};
257 recoVtxX = recoVertexX;
258 recoVtxY = recoVertexY;
259 recoVtxZ = recoVertexZ;
266 catch (StatusCodeException &)
268 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
269 std::cout <<
"HierarchyValidationAlgorithm::EventValidation could not retrieve recoVertex" << std::endl;
275 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nRecoSlices", nRecoSlices));
276 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isCC", isCC));
277 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isQE", isQE));
278 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isResonant", isResonant));
279 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isDIS", isDIS));
280 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isCoherent", isCoherent));
281 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isNuMu", isNuMu));
282 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isNuE", isNuE));
283 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nPiZero", nPiZero));
284 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nPiPlus", nPiPlus));
285 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nPiMinus", nPiMinus));
286 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nPhotons", nPhotons));
287 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nProtons", nProtons));
288 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isFiducial", isFiducial));
289 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"recoVtxX", recoVtxX));
290 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"recoVtxY", recoVtxY));
291 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"recoVtxZ", recoVtxZ));
292 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"trueVtxX", recoVtxX));
293 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"trueVtxY", recoVtxY));
294 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"trueVtxZ", recoVtxZ));
295 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"vtxDx", vtxDx));
296 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"vtxDy", vtxDy));
297 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"vtxDz", vtxDz));
298 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"vtxDr", vtxDr));
299 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nGoodMatches", nGoodMatches));
300 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nPoorMatches", nPoorMatches));
301 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nUnmatched", nUnmatched));
302 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nNodes", nNodes));
303 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nGoodTier1Matches", nGoodTier1Matches));
304 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nTier1Nodes", nTier1Nodes));
305 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nGoodTrackMatches", nGoodTrackMatches));
306 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nGoodShowerMatches", nGoodShowerMatches));
307 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nTrackNodes", nTrackNodes));
308 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nShowerNodes", nShowerNodes));
309 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nGoodTier1TrackMatches", nGoodTier1TrackMatches));
310 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nTier1TrackNodes", nTier1TrackNodes));
311 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nGoodTier1ShowerMatches", nGoodTier1ShowerMatches));
312 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"nTier1ShowerNodes", nTier1ShowerNodes));
313 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"hasLeadingMuon", hasLeadingMuon));
314 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"hasLeadingElectron", hasLeadingElectron));
315 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_eventTreeName.c_str(),
"isLeadingLeptonCorrect", isLeadingLeptonCorrect));
316 PANDORA_MONITORING_API(FillTree(this->GetPandora(),
m_eventTreeName.c_str()));
329 MCParticleList rootMCParticles;
330 const CartesianVector null(0.
f, 0.
f, 0.
f);
335 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
336 for (
const ParticleFlowObject *
const pRoot : rootPfos)
339 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
341 recoNodeToRootMap[pNode] = pRoot;
344 for (
const MCParticle *
const pRoot : rootMCParticles)
346 MCParticleList primaries;
350 if (pMCNode->GetHierarchyTier() == 1)
353 primaries.emplace_back(pLeadingMC);
357 if (primaries.size() == 0)
365 const int isTestBeam{pMCNode->IsTestBeamParticle() ? 1 : 0};
366 const int isCosmicRay{!isTestBeam && pMCNode->IsCosmicRay() ? 1 : 0};
367 const int isNeutrinoInt{!(isTestBeam || isCosmicRay) ? 1 : 0};
368 const int mcId{pMCNode->GetId()};
369 const int pdg{pMCNode->GetParticleId()};
370 const int tier{pMCNode->GetHierarchyTier()};
371 const int mcHits{
static_cast<int>(pMCNode->GetCaloHits().size())};
372 const int isLeadingLepton{pMCNode->IsLeadingLepton() ? 1 : 0};
373 const CaloHitList mcCaloHits{pMCNode->GetCaloHits()};
374 float mcTotalMipEnergy{0};
375 for (
const CaloHit *pCaloHit : mcCaloHits)
377 mcTotalMipEnergy += pCaloHit->GetMipEquivalentEnergy();
380 const MCParticle *
const pLeadingMC{pMCNode->GetLeadingMCParticle()};
381 const MCParticleList &parentList{pLeadingMC->GetParentList()};
382 const int isElectron{
std::abs(pLeadingMC->GetParticleId()) == E_MINUS ? 1 : 0};
383 const int hasMuonParent{parentList.size() == 1 &&
std::abs(parentList.front()->GetParticleId()) == MU_MINUS ? 1 : 0};
385 const CartesianVector mcMomentum{pLeadingMC->GetMomentum()};
386 const float mcMtm{mcMomentum.GetMagnitude()};
387 const float mcMtmX{mcMomentum.GetX()};
388 const float mcMtmY{mcMomentum.GetY()};
389 const float mcMtmZ{mcMomentum.GetZ()};
390 const float mcEnergy{pLeadingMC->GetEnergy()};
393 const int nMatches{
static_cast<int>(nodeVector.size())};
394 IntVector recoSliceIdVector, recoIdVector, nRecoHitsVector, nSharedHitsVector;
395 FloatVector recoTotalAdcVector;
396 FloatVector purityVector, completenessVector;
397 FloatVector purityAdcVector, completenessAdcVector;
398 FloatVector purityVectorU, purityVectorV, purityVectorW, completenessVectorU, completenessVectorV, completenessVectorW;
399 FloatVector purityAdcVectorU, purityAdcVectorV, purityAdcVectorW, completenessAdcVectorU, completenessAdcVectorV, completenessAdcVectorW;
400 const CartesianVector &trueVertex{isSignal == 1 ? pLeadingMC->GetVertex() : null};
401 const float trueVtxX{trueVertex.GetX()};
402 const float trueVtxY{trueVertex.GetY()};
403 const float trueVtxZ{trueVertex.GetZ()};
404 float recoVtxX{std::numeric_limits<float>::max()};
405 float recoVtxY{std::numeric_limits<float>::max()};
406 float recoVtxZ{std::numeric_limits<float>::max()};
407 float vtxDx{std::numeric_limits<float>::max()};
408 float vtxDy{std::numeric_limits<float>::max()};
409 float vtxDz{std::numeric_limits<float>::max()};
410 float vtxDr{std::numeric_limits<float>::max()};
412 int isCC{0}, isQE{0}, isResonant{0}, isDIS{0}, isCoherent{0}, isNuMu{0}, isNuE{0}, nPiZero{0}, nPiPlus{0}, nPiMinus{0},
413 nPhotons{0}, nProtons{0};
417 isCC = descriptor.
IsCC();
418 isQE = descriptor.IsQE();
419 isResonant = descriptor.IsResonant();
420 isDIS = descriptor.IsDIS();
421 isCoherent = descriptor.IsCoherent();
422 isNuMu = descriptor.IsMuonNeutrino();
423 isNuE = descriptor.IsElectronNeutrino();
424 nPiZero =
static_cast<int>(descriptor.GetNumPiZero());
425 nPiPlus =
static_cast<int>(descriptor.GetNumPiPlus());
426 nPiMinus =
static_cast<int>(descriptor.GetNumPiMinus());
427 nPhotons =
static_cast<int>(descriptor.GetNumPhotons());
428 nProtons =
static_cast<int>(descriptor.GetNumProtons());
436 const int sliceId{
static_cast<int>(
437 std::distance(rootPfos.begin(), std::find(rootPfos.begin(), rootPfos.end(), recoNodeToRootMap[pRecoNode])))};
438 recoSliceIdVector.emplace_back(sliceId);
439 recoIdVector.emplace_back(pRecoNode->GetParticleId());
440 nRecoHitsVector.emplace_back(static_cast<int>(matches.GetSelectedRecoHits(pRecoNode).size()));
441 const CaloHitList recoCaloHits{pRecoNode->GetCaloHits()};
442 float recoTotalMipEnergy{0};
443 for (
const CaloHit *pCaloHit : recoCaloHits)
445 recoTotalMipEnergy += pCaloHit->GetMipEquivalentEnergy();
447 recoTotalAdcVector.emplace_back(recoTotalMipEnergy);
448 nSharedHitsVector.emplace_back(static_cast<int>(matches.GetSharedHits(pRecoNode)));
449 purityVector.emplace_back(matches.GetPurity(pRecoNode));
450 completenessVector.emplace_back(matches.GetCompleteness(pRecoNode));
451 purityAdcVector.emplace_back(matches.GetPurity(pRecoNode,
true));
452 completenessAdcVector.emplace_back(matches.GetCompleteness(pRecoNode,
true));
453 purityVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U));
454 purityVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V));
455 purityVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W));
456 completenessVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U));
457 completenessVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V));
458 completenessVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W));
459 purityAdcVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U,
true));
460 purityAdcVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V,
true));
461 purityAdcVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W,
true));
462 completenessAdcVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U,
true));
463 completenessAdcVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V,
true));
464 completenessAdcVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W,
true));
469 const CartesianVector recoVertex{isSignal == 1 ?
LArPfoHelper::GetVertex(pRecoNode->GetLeadingPfo())->GetPosition() : null};
470 recoVtxX = recoVertex.GetX();
471 recoVtxY = recoVertex.GetY();
472 recoVtxZ = recoVertex.GetZ();
473 vtxDx = recoVtxX - trueVtxX;
474 vtxDy = recoVtxY - trueVtxY;
475 vtxDz = recoVtxZ - trueVtxZ;
476 vtxDr = std::sqrt(vtxDx * vtxDx + vtxDy * vtxDy + vtxDz * vtxDz);
478 catch (StatusCodeException &)
480 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
481 std::cout <<
"HierarchyValidationAlgorithm::MCValidation could not retrieve recoVertex" << std::endl;
486 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"event",
m_event));
488 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcId", mcId));
489 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcPDG", pdg));
490 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcTier", tier));
491 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcNHits", mcHits));
492 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcMtm", mcMtm));
493 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcMtmX", mcMtmX));
494 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcMtmY", mcMtmY));
495 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcMtmZ", mcMtmZ));
496 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcEnergy", mcEnergy));
497 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"recoTotalAdc", &recoTotalAdcVector));
498 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"mcTotalAdc", mcTotalMipEnergy));
499 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isSignal", isSignal));
500 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isNuInteraction", isNeutrinoInt));
501 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isCosmicRay", isCosmicRay));
502 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isTestBeam", isTestBeam));
503 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isLeadingLepton", isLeadingLepton));
504 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isMichel", isMichel));
505 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nMatches", nMatches));
506 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"recoSliceIdVector", &recoSliceIdVector));
507 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"recoIdVector", &recoIdVector));
508 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nRecoHitsVector", &nRecoHitsVector));
509 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nSharedHitsVector", &nSharedHitsVector));
510 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityVector", &purityVector));
511 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessVector", &completenessVector));
512 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityAdcVector", &purityAdcVector));
513 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessAdcVector", &completenessAdcVector));
514 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityVectorU", &purityVectorU));
515 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityVectorV", &purityVectorV));
516 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityVectorW", &purityVectorW));
517 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessVectorU", &completenessVectorU));
518 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessVectorV", &completenessVectorV));
519 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessVectorW", &completenessVectorW));
520 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityAdcVectorU", &purityAdcVectorU));
521 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityAdcVectorV", &purityAdcVectorV));
522 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"purityAdcVectorW", &purityAdcVectorW));
523 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessAdcVectorU", &completenessAdcVectorU));
524 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessAdcVectorV", &completenessAdcVectorV));
525 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"completenessAdcVectorW", &completenessAdcVectorW));
526 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"recoVtxX", recoVtxX));
527 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"recoVtxY", recoVtxY));
528 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"recoVtxZ", recoVtxZ));
529 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"trueVtxX", trueVtxX));
530 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"trueVtxY", trueVtxY));
531 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"trueVtxZ", trueVtxZ));
532 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"vtxDx", vtxDx));
533 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"vtxDy", vtxDy));
534 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"vtxDz", vtxDz));
535 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"vtxDr", vtxDr));
536 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isCC", isCC));
537 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isQE", isQE));
538 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isResonant", isResonant));
539 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isDIS", isDIS));
540 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isCoherent", isCoherent));
541 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isNuMu", isNuMu));
542 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"isNuE", isNuE));
543 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nPiZero", nPiZero));
544 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nPiPlus", nPiPlus));
545 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nPiMinus", nPiMinus));
546 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nPhotons", nPhotons));
547 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
m_MCTreeName.c_str(),
"nProtons", nProtons));
548 PANDORA_MONITORING_API(FillTree(this->GetPandora(),
m_MCTreeName.c_str()));
560 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
563 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PfoListName",
m_pfoListName));
567 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"Detector",
m_detector));
569 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ValidateEvent",
m_validateEvent));
570 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ValidateMC",
m_validateMC));
572 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"WriteEventTree",
m_writeEventTree));
575 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"EventFileName",
m_eventFileName));
576 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"EventTreeName",
m_eventTreeName));
579 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"WriteMCTree",
m_writeMCTree));
582 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MCFileName",
m_MCFileName));
583 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MCTreeName",
m_MCTreeName));
586 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldToPrimaries",
m_foldToPrimaries));
587 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldDynamic",
m_foldDynamic));
588 PANDORA_RETURN_RESULT_IF_AND_IF(
589 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldToLeadingShowers",
m_foldToLeadingShowers));
591 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinPurity",
m_minPurity));
592 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCompleteness",
m_minCompleteness));
593 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinRecoHits",
m_minRecoHits));
594 PANDORA_RETURN_RESULT_IF_AND_IF(
595 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinRecoHitsPerView",
m_minRecoHitsPerView));
596 PANDORA_RETURN_RESULT_IF_AND_IF(
597 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinRecoGoodViews",
m_minRecoGoodViews));
598 PANDORA_RETURN_RESULT_IF_AND_IF(
599 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"RemoveRecoNeutrons",
m_removeRecoNeutrons));
600 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SelectRecoHits",
m_selectRecoHits));
602 return STATUS_CODE_SUCCESS;
unsigned int m_minRecoGoodViews
Minimum number of reconstructed primary good views.
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.
unsigned int m_minRecoHits
Minimum number of reconstructed primary good hits.
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.
bool m_writeEventTree
Whether or not to output event validation information to a ROOT file.
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
bool m_writeMCTree
Whether or not to output MC validation information to a ROOT file.
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.
std::string m_MCFileName
The name of the MC ROOT file to write.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
bool m_removeRecoNeutrons
Whether to remove reconstructed neutrons and their downstream particles.
bool m_selectRecoHits
Whether to select reco hits that overlap with the MC particle hits.
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.
std::string m_eventTreeName
The name of the event ROOT tree to write.
int m_event
The current event.
ReconstructabilityCriteria class.
static const pandora::MCParticle * GetParentMCParticle(const pandora::MCParticle *const pMCParticle)
Get the parent mc particle.
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...
std::string m_MCTreeName
The name of the MC ROOT tree to write.
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
std::string m_eventFileName
The name of the event ROOT file to write.
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.
unsigned int m_minRecoHitsPerView
Minimum number of reconstructed hits for a good view.
static InteractionDescriptor GetInteractionDescriptor(const pandora::MCParticleList &mcPrimaryList)
Get the interaction descriptor of an event.
bool m_validateMC
Whether to validate at the level of MC nodes.
bool IsCC() const
Whether or not the interaction is CC.
Header file for the hierarchy validation algorithm.
static bool IsNeutrino(const pandora::MCParticle *const pMCParticle)
Whether a mc particle is a neutrino or antineutrino.
bool m_validateEvent
Whether to validate at the level of an event.