9 #include "Pandora/AlgorithmHeaders.h" 20 HierarchyValidationAlgorithm::HierarchyValidationAlgorithm() :
37 PANDORA_MONITORING_API(SaveTree(this->GetPandora(),
m_treename.c_str(),
m_filename.c_str(),
"UPDATE"));
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));
66 matchInfo.
Print(mcHierarchy);
73 return STATUS_CODE_SUCCESS;
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};
97 const int nReco{
static_cast<int>(mcMatch.GetRecoMatches().size())};
98 const bool isQuality{mcMatch.IsQuality(matchInfo.
GetQualityCuts())};
99 if (nReco == 1 && isQuality)
107 if (pNode->GetHierarchyTier() == 1)
110 if (nReco == 1 && isQuality)
115 if (pNode->IsLeadingLepton())
119 else if (
pdg == E_MINUS)
120 hasLeadingElectron = 1;
121 isLeadingLeptonCorrect = nReco == 1 ? 1 : 0;
126 showerNodeSet.insert(pNode);
127 if (nReco == 1 && isQuality)
129 ++nGoodShowerMatches;
130 if (pNode->GetHierarchyTier() == 1)
131 ++nGoodTier1ShowerMatches;
133 if (pNode->GetHierarchyTier() == 1)
138 trackNodeSet.insert(pNode);
139 if (nReco == 1 && isQuality)
142 if (pNode->GetHierarchyTier() == 1)
143 ++nGoodTier1TrackMatches;
145 if (pNode->GetHierarchyTier() == 1)
150 MCParticleList primaryMCList;
151 for (
const MCParticle *
const pMC : primaryMCSet)
152 primaryMCList.emplace_back(pMC);
154 const int nNodes{
static_cast<int>(matchInfo.
GetNMCNodes())};
156 const int nTrackNodes{
static_cast<int>(trackNodeSet.size())}, nShowerNodes{
static_cast<int>(showerNodeSet.size())};
157 const CartesianVector &trueVertex{matchInfo.
GetMCNeutrino()->GetVertex()};
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)};
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()));
198 this->
Fill(match, matchInfo);
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};
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};
222 const int nMatches{
static_cast<int>(nodeVector.size())};
223 IntVector recoIdVector, nRecoHitsVector, nSharedHitsVector;
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};
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));
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));
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);
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()));
305 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
308 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PfoListName",
m_pfoListName));
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));
315 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"WriteTree",
m_writeTree));
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));
322 std::cout <<
"Error: WriteTree requested but no tree names found" <<
std::endl;
323 return STATUS_CODE_NOT_FOUND;
327 std::cout <<
"Error: Both event-level and MC-level validation requested simulataneously" <<
std::endl;
328 return STATUS_CODE_INVALID_PARAMETER;
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));
337 return STATUS_CODE_SUCCESS;
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
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.
virtual ~HierarchyValidationAlgorithm()
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.
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.
int m_event
The current event.
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.
pandora::StatusCode Run()
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.