9 #include "Pandora/AlgorithmHeaders.h"
18 HierarchyMonitoringAlgorithm::HierarchyMonitoringAlgorithm() :
20 m_visualizeReco(
false),
21 m_visualizeDistinct(
false),
22 m_visualizeProcess{
false},
24 m_collectionOnly{
false},
25 m_foldToPrimaries{
false},
27 m_transparencyThresholdE{-1.f},
28 m_energyScaleThresholdE{1.f},
37 PANDORA_MONITORING_API(SaveTree(this->GetPandora(),
"processes",
"processes.root",
"UPDATE"));
44 PANDORA_MONITORING_API(
47 const CaloHitList *pCaloHitList(
nullptr);
48 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_caloHitListName, pCaloHitList));
49 const MCParticleList *pMCParticleList(
nullptr);
50 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*
this, pMCParticleList));
51 const PfoList *pPfoList(
nullptr);
52 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_pfoListName, pPfoList));
71 matchInfo.
Print(mcHierarchy);
89 return STATUS_CODE_SUCCESS;
96 const std::map<int, const std::string> keys = {{13,
"mu"}, {11,
"e"}, {22,
"gamma"}, {321,
"kaon"}, {211,
"pi"}, {2212,
"p"}};
97 const std::map<std::string, int> colors = {{
"mu", 5}, {
"e", 2}, {
"gamma", 9}, {
"kaon", 1}, {
"pi", 3}, {
"p", 4}, {
"other", 14}};
105 std::string key(
"other");
107 if (keys.find(
pdg) != keys.end())
110 CaloHitList uHits, vHits, wHits;
111 this->
FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
113 this->
Visualize(uHits,
"u_" + suffix, colors.at(key));
114 this->
Visualize(vHits,
"v_" + suffix, colors.at(key));
115 this->
Visualize(wHits,
"w_" + suffix, colors.at(key));
119 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
126 const std::map<int, const std::string> keys = {{13,
"mu"}, {11,
"e"}, {22,
"gamma"}, {321,
"kaon"}, {211,
"pi"}, {2212,
"p"}};
127 const int nColours{9};
128 const int colors[nColours] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
133 int nodeIdx{0}, colorIdx{0};
136 std::string key(
"other");
138 if (keys.find(
pdg) != keys.end())
141 CaloHitList uHits, vHits, wHits;
142 this->
FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
144 this->
Visualize(uHits,
"u_" + suffix, colors[colorIdx]);
145 this->
Visualize(vHits,
"v_" + suffix, colors[colorIdx]);
146 this->
Visualize(wHits,
"w_" + suffix, colors[colorIdx]);
147 colorIdx = (colorIdx + 1) >= nColours ? 0 : colorIdx + 1;
151 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
159 {
MC_PROC_PRIMARY,
"primary"}, {
MC_PROC_COMPT,
"compt"}, {
MC_PROC_PHOT,
"phot"}, {
MC_PROC_ANNIHIL,
"annihil"}, {
MC_PROC_E_IONI,
"ioni"},
175 const std::map<std::string, int> categoryToColorMap = {{
"invisible", 0}, {
"primary", 1}, {
"compt", 2}, {
"phot", 3}, {
"annihil", 4},
176 {
"ioni", 5}, {
"brem", 6}, {
"conv", 3}, {
"capture", 6}, {
"inelastic", 9}, {
"elastic", 8}, {
"decay", 7}, {
"coulomb", 9},
177 {
"pair_prod", 4}, {
"transport", 1}, {
"rayleigh", 9}, {
"kill", 2}, {
"nuclear", 5}, {
"background", 7}};
189 const std::string category{procToCategoryMap.at(process)};
193 CaloHitList uHits, vHits, wHits;
194 this->
FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
199 const MCParticleList &parentList{pMC->GetParentList()};
200 if (!parentList.empty())
202 const MCParticle *pParent{parentList.front()};
203 const int parentPdg{
std::abs(pParent->GetParticleId())};
208 this->
Visualize(uHits,
"U " + suffix, categoryToColorMap.at(category));
209 this->
Visualize(vHits,
"V " + suffix, categoryToColorMap.at(category));
210 this->
Visualize(wHits,
"W " + suffix, categoryToColorMap.at(category));
213 const int proc{
static_cast<int>(process)};
214 const float mom{pMC->GetMomentum().GetMagnitude()};
215 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
"processes",
"process",
proc));
216 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(),
"processes",
"momentum", mom));
217 PANDORA_MONITORING_API(FillTree(this->GetPandora(),
"processes"));
220 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
227 const int nColors{7};
228 const int colors[nColors] = {5, 2, 9, 1, 3, 4, 14};
237 CaloHitList uHits, vHits, wHits;
238 this->
FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
239 const int pdg{pNode->GetParticleId()};
240 const std::string key{
pdg == MU_MINUS ?
"T" :
pdg == E_MINUS ?
"S" :
"?"};
242 this->
Visualize(uHits,
"u_" + suffix, colors[colorIdx]);
243 this->
Visualize(vHits,
"v_" + suffix, colors[colorIdx]);
244 this->
Visualize(wHits,
"w_" + suffix, colors[colorIdx]);
245 colorIdx = (colorIdx + 1) >= nColors ? 0 : colorIdx + 1;
249 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
256 std::map<const LArHierarchyHelper::MCHierarchy::Node *, int> mcIdxMap;
259 if (mcIdxMap.find(matches.GetMC()) == mcIdxMap.end())
260 mcIdxMap[matches.GetMC()] = mcIdx++;
268 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
275 const std::map<int, const std::string> keys = {{13,
"mu"}, {11,
"e"}, {22,
"gamma"}, {321,
"kaon"}, {211,
"pi"}, {2212,
"p"}};
276 const int green{3}, gray{14};
277 const std::map<int, int> colors = {{0, 5}, {1, 2}, {2, 9}, {3, 1}, {4, 4}};
280 const int pdg{pMCNode->GetParticleId()};
282 std::string key(
"other");
283 if (keys.find(
pdg) != keys.end())
286 CaloHitList mcUHits, mcVHits, mcWHits;
287 this->
FillHitLists(pMCNode->GetCaloHits(), mcUHits, mcVHits, mcWHits);
288 std::string leading{pMCNode->IsLeadingLepton() ?
"_leading" :
""};
292 this->
Visualize(mcUHits,
"u_" + suffix, green);
293 this->
Visualize(mcVHits,
"v_" + suffix, green);
294 this->
Visualize(mcWHits,
"w_" + suffix, green);
298 std::string suffix{
std::to_string(mcIdx) +
"_" + key +
"_unmatched"};
299 this->
Visualize(mcUHits,
"u_" + suffix, gray);
300 this->
Visualize(mcVHits,
"v_" + suffix, gray);
301 this->
Visualize(mcWHits,
"w_" + suffix, gray);
308 CaloHitList recoUHits, recoVHits, recoWHits;
309 this->
FillHitLists(pRecoNode->GetCaloHits(), recoUHits, recoVHits, recoWHits);
310 const int characterisation{pRecoNode->GetParticleId()};
311 const std::string recoKey{characterisation == MU_MINUS ?
"T" : characterisation == E_MINUS ?
"S" :
"?"};
313 if (!recoUHits.empty())
315 const float purity{matches.
GetPurity(pRecoNode, TPC_VIEW_U,
true)};
316 const float completeness{matches.
GetCompleteness(pRecoNode, TPC_VIEW_U,
true)};
318 metrics.precision(2);
319 metrics << std::fixed <<
" p: " << purity <<
" c: " << completeness;
320 PANDORA_MONITORING_API(
321 VisualizeCaloHits(this->GetPandora(), &recoUHits,
"u_" + recoSuffix + metrics.str(),
static_cast<Color
>(colors.at(colorIdx))));
323 if (!recoVHits.empty())
325 const float purity{matches.
GetPurity(pRecoNode, TPC_VIEW_V,
true)};
326 const float completeness{matches.
GetCompleteness(pRecoNode, TPC_VIEW_V,
true)};
328 metrics.precision(2);
329 metrics << std::fixed <<
" p: " << purity <<
" c: " << completeness;
330 PANDORA_MONITORING_API(
331 VisualizeCaloHits(this->GetPandora(), &recoVHits,
"v_" + recoSuffix + metrics.str(),
static_cast<Color
>(colors.at(colorIdx))));
333 if (!recoWHits.empty())
335 const float purity{matches.
GetPurity(pRecoNode, TPC_VIEW_W,
true)};
336 const float completeness{matches.
GetCompleteness(pRecoNode, TPC_VIEW_W,
true)};
338 metrics.precision(2);
339 metrics << std::fixed <<
" p: " << purity <<
" c: " << completeness;
340 PANDORA_MONITORING_API(
341 VisualizeCaloHits(this->GetPandora(), &recoWHits,
"w_" + recoSuffix + metrics.str(),
static_cast<Color
>(colors.at(colorIdx))));
343 colorIdx = (colorIdx + 1) >= colors.size() ? 0 : colorIdx + 1;
354 CaloHitList uHits, vHits, wHits;
357 const std::string key{
pdg == MU_MINUS ?
"T" :
pdg == E_MINUS ?
"S" :
"?"};
358 const std::string suffix{
"unmatched_reco"};
359 this->
Visualize(uHits,
"u_" + suffix, gray);
360 this->
Visualize(vHits,
"v_" + suffix, gray);
361 this->
Visualize(wHits,
"w_" + suffix, gray);
368 if (!hits.empty() && hits.size() > 1)
372 PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &hits, label, static_cast<Color>(color)));
380 for (
const CaloHit *pCaloHit : hits)
382 const HitType view{pCaloHit->GetHitType()};
383 if (view == HitType::TPC_VIEW_U)
384 uHits.emplace_back(pCaloHit);
385 else if (view == HitType::TPC_VIEW_V)
386 vHits.emplace_back(pCaloHit);
387 else if (view == HitType::TPC_VIEW_W)
388 wHits.emplace_back(pCaloHit);
396 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
399 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PfoListName",
m_pfoListName));
402 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VisualizeMC",
m_visualizeMC));
403 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VisualizeReco",
m_visualizeReco));
404 PANDORA_RETURN_RESULT_IF_AND_IF(
405 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VisualizeDistinct",
m_visualizeDistinct));
406 PANDORA_RETURN_RESULT_IF_AND_IF(
407 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VisualizeProcess",
m_visualizeProcess));
408 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PerformMatching",
m_match));
409 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CollectionOnly",
m_collectionOnly));
410 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldToPrimaries",
m_foldToPrimaries));
411 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"FoldDynamic",
m_foldDynamic));
414 PANDORA_RETURN_RESULT_IF_AND_IF(
415 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TransparencyThresholdE",
m_transparencyThresholdE));
416 PANDORA_RETURN_RESULT_IF_AND_IF(
417 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"EnergyScaleThresholdE",
m_energyScaleThresholdE));
418 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ScalingFactor",
m_scalingFactor));
420 return STATUS_CODE_SUCCESS;
const pandora::CaloHitList & GetCaloHits() const
Retrieve the CaloHits associated with this node.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void Visualize(const pandora::CaloHitList &hits, const std::string &label, const int color) const
Visualize a calo hit list.
bool m_foldToTier
Whether or not to apply folding based on particle tier.
std::string m_pfoListName
Name of input PFO list.
bool m_visualizeMC
Whether or not to visualize the MC nodes.
void VisualizeMatchedMC(const LArHierarchyHelper::MCMatches &matches, const int mcIdx) const
Visualize the reco nodes matched to a single MC node.
std::vector< const Node * > NodeVector
MCProcess GetProcess() const
Get the process.
bool m_visualizeProcess
If true, allocate colours based on the MC process.
void VisualizeMCProcess(const LArHierarchyHelper::MCHierarchy &hierarchy) const
Visualize MC nodes based on the MC process that created them.
static int GetHierarchyTier(const pandora::MCParticle *const pMCParticle)
Determine the position in the hierarchy for the MCParticle.
float m_scalingFactor
TEve works with [cm], Pandora usually works with [mm] (but LArContent went with cm too) ...
bool m_visualizeReco
Whether or not to visualize the reco nodes.
const RecoHierarchy::NodeVector & GetRecoMatches() const
Retrieve the vector of matched reco nodes.
void GetFlattenedNodes(NodeVector &nodeVector) const
Retrieve a flat vector of the ndoes in the hierarchy.
static void MatchHierarchies(const MCHierarchy &mcHierarchy, const RecoHierarchy &recoHierarchy, MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
const MCHierarchy::Node * GetMC() const
Retrieve the MC node.
void VisualizeUnmatchedReco(const LArHierarchyHelper::RecoHierarchy::Node *pNode) const
Visualize the unmatched reco node.
const MCMatchesVector & GetMatches() const
Retrieve the vector of matches (this will include null matches - i.e. MC nodes with no corresponding ...
void VisualizeMatches(const LArHierarchyHelper::MatchInfo &matchInfo) const
Visualize reco to MC matches.
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...
bool m_foldToPrimaries
Whether or not to fold everything back to primaries.
std::vector< const Node * > NodeVector
pandora::StatusCode Run()
ReconstructabilityCriteria class.
float GetPurity(const RecoHierarchy::Node *pReco, const bool adcWeighted=false) const
Retrieve the purity of the match.
void VisualizeReco(const LArHierarchyHelper::RecoHierarchy &hierarchy) const
Visualize the reco nodes.
Header file for the particle visualisation algorithm.
void VisualizeMC(const LArHierarchyHelper::MCHierarchy &hierarchy) const
Visualize MC nodes.
std::string m_caloHitListName
Name of input calo hit list.
bool m_foldDynamic
Whether or not to use process and topological information to make folding decisions.
void FillHitLists(const pandora::CaloHitList &hits, pandora::CaloHitList &uHits, pandora::CaloHitList &vHits, pandora::CaloHitList &wHits) const
Fill per view hit lists.
const RecoHierarchy::NodeVector & GetUnmatchedReco() const
Retrieve the vector of unmatched reco nodes.
bool m_match
Whether or not to visualize the reco to MC matches.
void Print(const MCHierarchy &mcHierarchy) const
Prints information about which reco nodes are matched to the MC nodes, information about hit sharing...
void GetFlattenedNodes(NodeVector &nodeVector) const
Retrieve a flat vector of the nodes in the hierarchy.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
virtual ~HierarchyMonitoringAlgorithm()
std::string to_string(WindowPattern const &pattern)
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...
bool m_collectionOnly
Limit display to the collection plane only.
int GetParticleId() const
Retrieve the PDG code for the leading particle in this node Note, for reco objects the PDG codes repr...
void VisualizeMCDistinct(const LArHierarchyHelper::MCHierarchy &hierarchy) const
Visualize MC nodes without grouping by particle id.
float GetCompleteness(const RecoHierarchy::Node *pReco, const bool adcWeighted=false) const
Retrieve the completeness of the match.
float m_transparencyThresholdE
Cell energy for which transparency is saturated (0%, fully opaque)
bool m_foldDynamic
Whether or not to fold based on process information.
float m_energyScaleThresholdE
Cell energy for which color is at top end of continous color palette.
bool m_visualizeDistinct
If true, allocate colours without consideration of particle id.