20 m_visualizeReco(false),
21 m_visualizeDistinct(false),
22 m_visualizeProcess{false},
24 m_collectionOnly{false},
25 m_foldToPrimaries{false},
28 m_minCompleteness{0.65f},
29 m_minMatchCompleteness{0.1f},
30 m_transparencyThresholdE{-1.f},
31 m_energyScaleThresholdE{1.f},
71 std::cout << mcHierarchy.
ToString() << std::endl;
75 const PfoList *pPfoList(
nullptr);
78 std::cout << recoHierarchy.
ToString() << std::endl;
85 matchInfo.
Print(mcHierarchy);
86 this->VisualizeMatches(matchInfo);
93 this->VisualizeMCDistinct(mcHierarchy);
95 this->VisualizeMCProcess(mcHierarchy);
97 this->VisualizeMC(mcHierarchy);
100 this->VisualizeReco(recoHierarchy);
104 return STATUS_CODE_SUCCESS;
111 const std::map<int, const std::string> keys = {{13,
"mu"}, {11,
"e"}, {22,
"gamma"}, {321,
"kaon"}, {211,
"pi"}, {2212,
"p"}};
112 const std::map<std::string, int> colors = {{
"mu", 5}, {
"e", 2}, {
"gamma", 9}, {
"kaon", 1}, {
"pi", 3}, {
"p", 4}, {
"other", 14}};
116 for (
const MCParticle *
const pRoot : rootMCParticles)
121 bool depositedHits{
false};
123 for (
const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
125 std::string key(
"other");
126 const int pdg{std::abs(pNode->GetParticleId())};
127 if (keys.find(pdg) != keys.end())
131 this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
132 if (!(uHits.empty() && vHits.empty() && wHits.empty()))
134 depositedHits =
true;
135 std::string suffix{std::to_string(nodeIdx) +
"_" + key};
136 this->Visualize(uHits,
"u_" + suffix, colors.at(key));
137 this->Visualize(vHits,
"v_" + suffix, colors.at(key));
138 this->Visualize(wHits,
"w_" + suffix, colors.at(key));
151void HierarchyMonitoringAlgorithm::VisualizeMCDistinct(
const LArHierarchyHelper::MCHierarchy &hierarchy)
const
153 const std::map<int, const std::string> keys = {{13,
"mu"}, {11,
"e"}, {22,
"gamma"}, {321,
"kaon"}, {211,
"pi"}, {2212,
"p"}};
154 const int nColours{9};
155 const int colors[nColours] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
158 hierarchy.GetRootMCParticles(rootMCParticles);
159 for (
const MCParticle *
const pRoot : rootMCParticles)
162 hierarchy.GetFlattenedNodes(pRoot, nodes);
164 bool depositedHits{
false};
165 int nodeIdx{0}, colorIdx{0};
166 for (
const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
168 std::string key(
"other");
169 const int pdg{std::abs(pNode->GetParticleId())};
170 if (keys.find(pdg) != keys.end())
174 this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
175 if (!(uHits.empty() && vHits.empty() && wHits.empty()))
177 depositedHits =
true;
178 std::string suffix{std::to_string(nodeIdx) +
"_" + key};
179 this->Visualize(uHits,
"u_" + suffix, colors[colorIdx]);
180 this->Visualize(vHits,
"v_" + suffix, colors[colorIdx]);
181 this->Visualize(wHits,
"w_" + suffix, colors[colorIdx]);
182 colorIdx = (colorIdx + 1) >= nColours ? 0 : colorIdx + 1;
196void HierarchyMonitoringAlgorithm::VisualizeMCProcess(
const LArHierarchyHelper::MCHierarchy &hierarchy)
const
199 {
MC_PROC_PRIMARY,
"primary"}, {
MC_PROC_COMPT,
"compt"}, {
MC_PROC_PHOT,
"phot"}, {
MC_PROC_ANNIHIL,
"annihil"}, {
MC_PROC_E_IONI,
"ioni"},
215 const std::map<std::string, int> categoryToColorMap = {{
"invisible", 0}, {
"primary", 1}, {
"compt", 2}, {
"phot", 3}, {
"annihil", 4},
216 {
"ioni", 5}, {
"brem", 6}, {
"conv", 3}, {
"capture", 6}, {
"inelastic", 9}, {
"elastic", 8}, {
"decay", 7}, {
"coulomb", 9},
217 {
"pair_prod", 4}, {
"transport", 1}, {
"rayleigh", 9}, {
"kill", 2}, {
"nuclear", 5}, {
"background", 7}};
220 hierarchy.GetRootMCParticles(rootMCParticles);
221 for (
const MCParticle *
const pRoot : rootMCParticles)
224 hierarchy.GetFlattenedNodes(pRoot, nodes);
227 for (
const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
229 const LArMCParticle *pMC{
dynamic_cast<const LArMCParticle *
>(pNode->GetLeadingMCParticle())};
232 const MCProcess process{pMC->GetProcess()};
233 const std::string category{procToCategoryMap.at(process)};
234 const int pdg{std::abs(pNode->GetParticleId())};
238 this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
239 std::string suffix{std::to_string(nodeIdx) +
" (" + std::to_string(tier) +
") " + std::to_string(pdg) +
" " + category +
" " +
240 std::to_string(process)};
244 if (!parentList.empty())
246 const MCParticle *pParent{parentList.front()};
247 const int parentPdg{std::abs(pParent->GetParticleId())};
248 suffix +=
" from " + std::to_string(parentPdg);
252 this->Visualize(uHits,
"U " + suffix, categoryToColorMap.at(category));
253 this->Visualize(vHits,
"V " + suffix, categoryToColorMap.at(category));
254 this->Visualize(wHits,
"W " + suffix, categoryToColorMap.at(category));
257 const int proc{
static_cast<int>(process)};
258 const float mom{pMC->GetMomentum().GetMagnitude()};
273void HierarchyMonitoringAlgorithm::VisualizeReco(
const LArHierarchyHelper::RecoHierarchy &hierarchy)
const
275 const int nColors{7};
276 const int colors[nColors] = {5, 2, 9, 1, 3, 4, 14};
279 hierarchy.GetRootPfos(rootPfos);
283 hierarchy.GetFlattenedNodes(pRoot, nodes);
287 for (
const LArHierarchyHelper::RecoHierarchy::Node *pNode : nodes)
290 this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
291 const int pdg{pNode->GetParticleId()};
292 const std::string key{pdg == MU_MINUS ?
"T" : pdg == E_MINUS ?
"S" :
"?"};
293 const std::string suffix{std::to_string(pfoIdx) +
"_" + key};
294 this->Visualize(uHits,
"u_" + suffix, colors[colorIdx]);
295 this->Visualize(vHits,
"v_" + suffix, colors[colorIdx]);
296 this->Visualize(wHits,
"w_" + suffix, colors[colorIdx]);
297 colorIdx = (colorIdx + 1) >= nColors ? 0 : colorIdx + 1;
307void HierarchyMonitoringAlgorithm::VisualizeMatches(
const LArHierarchyHelper::MatchInfo &matchInfo)
const
309 const int nColors{8};
310 const int colors[nColors] = {2, 3, 4, 5, 6, 7, 8, 9};
312 matchInfo.GetRootMCParticles(rootMCParticles);
314 const LArHierarchyHelper::MCHierarchy &mcHierarchy{matchInfo.GetMCHierarchy()};
315 const LArHierarchyHelper::RecoHierarchy &recoHierarchy{matchInfo.GetRecoHierarchy()};
316 recoHierarchy.GetRootPfos(rootPfos);
317 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, int> recoNodeToColorMap;
318 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, int> recoNodeToIdMap;
319 std::map<const ParticleFlowObject *, int> recoRootToSliceMap;
320 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
321 std::map<const LArHierarchyHelper::MCHierarchy::Node *, int> mcNodeToIdMap;
322 int colorIdx{0}, recoIdx{0}, sliceIdx{0}, mcIdx{0};
325 recoRootToSliceMap[pRoot] = sliceIdx;
327 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
328 for (
const LArHierarchyHelper::RecoHierarchy::Node *pNode : nodes)
330 recoNodeToColorMap[pNode] = colors[colorIdx];
331 recoNodeToIdMap[pNode] = recoIdx;
332 recoNodeToRootMap[pNode] = pRoot;
337 if (colorIdx >= nColors)
340 for (
const MCParticle *
const pRoot : rootMCParticles)
342 bool isReconstructable{
false};
344 mcHierarchy.GetFlattenedNodes(pRoot, nodes);
347 for (
const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
349 const MCParticle *pMC{pNode->GetLeadingMCParticle()};
352 const int pdg{std::abs(pNode->GetParticleId())};
355 this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
356 std::string suffix{
"MC - ID: " + std::to_string(mcIdx) +
" PDG: " + std::to_string(pdg)};
357 this->Visualize(uHits,
"U " + suffix, 1);
358 this->Visualize(vHits,
"V " + suffix, 1);
359 this->Visualize(wHits,
"W " + suffix, 1);
360 if (!(uHits.empty() && vHits.empty() && wHits.empty()))
361 isReconstructable =
true;
362 mcNodeToIdMap[pNode] = mcIdx;
368 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, bool> matchedReco;
369 std::map<const ParticleFlowObject *, bool> matchedRoots;
370 for (
const auto &match : matches)
372 const LArHierarchyHelper::MCHierarchy::Node *pMC{match.GetMC()};
373 for (
const LArHierarchyHelper::RecoHierarchy::Node *pReco : match.GetRecoMatches())
376 const float purity{match.GetPurity(pReco,
true)};
377 const float completeness{match.GetCompleteness(pReco,
true)};
378 const std::string purityStr{this->
ToStringSF(purity)};
379 const std::string completenessStr{this->
ToStringSF(completeness)};
381 this->FillHitLists(pReco->GetCaloHits(), uHits, vHits, wHits);
382 const std::string suffix{
"Reco - Slice " + std::to_string(recoRootToSliceMap[recoNodeToRootMap[pReco]]) +
" ID " +
383 std::to_string(recoNodeToIdMap[pReco]) +
" -> " + std::to_string(mcNodeToIdMap[pMC])};
384 const LArHierarchyHelper::QualityCuts &quality{matchInfo.GetQualityCuts()};
385 if (purity >= quality.m_minPurity && completeness >= quality.m_minCompleteness)
387 this->Visualize(uHits,
"U " + suffix +
"(" + purityStr +
"," + completenessStr +
")", recoNodeToColorMap[pReco]);
388 this->Visualize(vHits,
"V " + suffix +
"(" + purityStr +
"," + completenessStr +
")", recoNodeToColorMap[pReco]);
389 this->Visualize(wHits,
"W " + suffix +
"(" + purityStr +
"," + completenessStr +
")", recoNodeToColorMap[pReco]);
391 matchedReco[pReco] =
true;
392 matchedRoots[recoNodeToRootMap[pReco]] =
true;
399 matchedReco[pReco] =
true;
400 matchedRoots[recoNodeToRootMap[pReco]] =
true;
402 this->Visualize(uHits,
"U " + suffix +
"(" + purityStr +
"," + completenessStr +
")", 14);
403 this->Visualize(vHits,
"V " + suffix +
"(" + purityStr +
"," + completenessStr +
")", 14);
404 this->Visualize(wHits,
"W " + suffix +
"(" + purityStr +
"," + completenessStr +
")", 14);
411 for (
const auto [pRecoRoot, val] : matchedRoots)
415 recoHierarchy.GetFlattenedNodes(pRecoRoot, recoNodes);
416 for (
const LArHierarchyHelper::RecoHierarchy::Node *pNode : recoNodes)
418 if (matchedReco.find(pNode) == matchedReco.end())
421 this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
422 const std::string suffix{
"Reco - Slice " + std::to_string(recoRootToSliceMap[recoNodeToRootMap[pNode]]) +
" ID " +
423 std::to_string(recoNodeToIdMap[pNode]) +
" -> #"};
424 this->Visualize(uHits,
"U " + suffix, 14);
425 this->Visualize(vHits,
"V " + suffix, 14);
426 this->Visualize(wHits,
"W " + suffix, 14);
431 if (isReconstructable)
440void HierarchyMonitoringAlgorithm::Visualize(
const CaloHitList &hits,
const std::string &label,
const int color)
const
454 for (
const CaloHit *pCaloHit : hits)
456 const HitType view{pCaloHit->GetHitType()};
457 if (view == HitType::TPC_VIEW_U)
458 uHits.emplace_back(pCaloHit);
459 else if (view == HitType::TPC_VIEW_V)
460 vHits.emplace_back(pCaloHit);
461 else if (view == HitType::TPC_VIEW_W)
462 wHits.emplace_back(pCaloHit);
471 std::ostringstream out;
473 out << std::fixed << val;
510 return STATUS_CODE_SUCCESS;
Header file for the particle visualisation algorithm.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
static pandora::StatusCode GetCurrentList(const pandora::Algorithm &algorithm, const T *&pT)
Get the current list.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
HierarchyMonitoringAlgorithm()
Default constructor.
bool m_visualizeMC
Whether or not to visualize the MC nodes.
std::string ToStringSF(const float val, const int sf=3) const
bool m_foldDynamic
Whether or not to fold based on process information.
bool m_match
Whether or not to visualize the reco to MC matches.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
float m_energyScaleThresholdE
Cell energy for which color is at top end of continous color palette.
virtual ~HierarchyMonitoringAlgorithm()
bool m_visualizeReco
Whether or not to visualize the reco nodes.
pandora::StatusCode Run()
Run the algorithm.
bool m_visualizeDistinct
If true, allocate colours without consideration of particle id.
float m_minPurity
The minimum purity for a match to be considered good.
float m_minMatchCompleteness
The minimum completeness at which to a PFO should be considered matching at all.
float m_scalingFactor
TEve works with [cm], Pandora usually works with [mm] (but LArContent went with cm too)
std::string m_rootFileName
Name of the output ROOT file (optional)
std::string m_pfoListName
Name of input PFO list.
bool m_collectionOnly
Limit display to the collection plane only.
bool m_visualizeProcess
If true, allocate colours based on the MC process.
bool m_foldToPrimaries
Whether or not to fold everything back to primaries.
float m_transparencyThresholdE
Cell energy for which transparency is saturated (0%, fully opaque)
std::string m_caloHitListName
Name of input calo hit list.
float m_minCompleteness
The minimum completeness for a match to be considered good.
bool m_foldToTier
Whether or not to apply folding based on particle tier.
bool m_foldDynamic
Whether or not to use process and topological information to make folding decisions.
ReconstructabilityCriteria class.
void GetFlattenedNodes(const pandora::MCParticle *const pRoot, NodeVector &nodeVector) const
Retrieve a flat vector of the ndoes in the hierarchy.
const std::string ToString() const
Produce a string representation of the hierarchy.
void GetRootMCParticles(pandora::MCParticleList &rootMCParticles) const
Retrieve the root MC particles of the interaction hierarchies.
std::vector< const Node * > NodeVector
void Print(const MCHierarchy &mcHierarchy) const
Prints information about which reco nodes are matched to the MC nodes, information about hit sharing,...
std::vector< const Node * > NodeVector
const std::string ToString() const
Produce a string representation of the hierarchy.
static void MatchHierarchies(MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
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...
std::vector< MCMatches > MCMatchesVector
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...
static int GetHierarchyTier(const pandora::MCParticle *const pMCParticle)
Determine the position in the hierarchy for the MCParticle.
ParticleFlowObject class.
const Pandora & GetPandora() const
Get the associated pandora instance.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
@ MC_PROC_HAD_BERTINI_CAPTURE_AT_REST
@ MC_PROC_NEUTRON_INELASTIC
@ MC_PROC_ALPHA_INELASTIC
@ MC_PROC_DEUTERON_INELASTIC
@ MC_PROC_TRITON_INELASTIC
@ MC_PROC_ANTI_DEUTERON_INELASTIC
@ MC_PROC_PI_PLUS_INELASTIC
@ MC_PROC_ANTI_NEUTRON_INELASTIC
@ MC_PROC_ANTI_ALPHA_INELASTIC
@ MC_PROC_CHIPS_NUCLEAR_CAPTURE_AT_REST
@ MC_PROC_PRIMARY_BACKGROUND
@ MC_PROC_ANTI_TRITON_INELASTIC
@ MC_PROC_ELECTRON_NUCLEAR
@ MC_PROC_ANTI_PROTON_INELASTIC
@ MC_PROC_PI_MINUS_INELASTIC
@ MC_PROC_PROTON_INELASTIC
@ MC_PROC_PHOTON_INELASTIC
@ MC_PROC_MU_MINUS_CAPTURE_AT_REST
@ MC_PROC_HAD_FRITIOF_CAPTURE_AT_REST
@ MC_PROC_KAON_PLUS_INELASTIC
@ MC_PROC_LAMBDA_INELASTIC
@ MC_PROC_ANTI_HE3_INELASTIC
@ MC_PROC_KAON_MINUS_INELASTIC
HitType
Calorimeter hit type enum.
MANAGED_CONTAINER< const MCParticle * > MCParticleList
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList