LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
HierarchyMonitoringAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
13 using namespace pandora;
14 
15 namespace lar_content
16 {
17 
18 HierarchyMonitoringAlgorithm::HierarchyMonitoringAlgorithm() :
19  m_visualizeMC(false),
20  m_visualizeReco(false),
21  m_visualizeDistinct(false),
22  m_visualizeProcess{false},
23  m_match(false),
24  m_collectionOnly{false},
25  m_foldToPrimaries{false},
26  m_foldDynamic{true},
27  m_minPurity{0.8f},
28  m_minCompleteness{0.65f},
32  m_scalingFactor{1.f}
33 {
34 }
35 
36 //------------------------------------------------------------------------------------------------------------------------------------------
37 
39 {
40  if (!m_rootFileName.empty())
41  {
42  PANDORA_MONITORING_API(SaveTree(this->GetPandora(), "processes", m_rootFileName, "UPDATE"));
43  }
44 }
45 
46 //------------------------------------------------------------------------------------------------------------------------------------------
47 
49 {
50 #ifdef MONITORING
51  PANDORA_MONITORING_API(
52  SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, m_transparencyThresholdE, m_energyScaleThresholdE, m_scalingFactor));
53 
54  const CaloHitList *pCaloHitList(nullptr);
55  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_caloHitListName, pCaloHitList));
56  const MCParticleList *pMCParticleList(nullptr);
57  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
58 
60  LArHierarchyHelper::MCHierarchy mcHierarchy(criteria);
64  foldParameters.m_foldToTier = true;
65  else if (m_foldDynamic)
66  foldParameters.m_foldDynamic = true;
67 
68  if (m_visualizeMC || m_match)
69  {
70  LArHierarchyHelper::FillMCHierarchy(*pMCParticleList, *pCaloHitList, foldParameters, mcHierarchy);
71  std::cout << mcHierarchy.ToString() << std::endl;
72  }
73  if (m_visualizeReco || m_match)
74  {
75  const PfoList *pPfoList(nullptr);
76  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_pfoListName, pPfoList));
77  LArHierarchyHelper::FillRecoHierarchy(*pPfoList, foldParameters, recoHierarchy);
78  std::cout << recoHierarchy.ToString() << std::endl;
79  }
80  if (m_match)
81  {
83  LArHierarchyHelper::MatchInfo matchInfo(mcHierarchy, recoHierarchy, quality);
85  matchInfo.Print(mcHierarchy);
86  this->VisualizeMatches(matchInfo);
87  }
88  else
89  {
90  if (m_visualizeMC)
91  {
93  this->VisualizeMCDistinct(mcHierarchy);
94  else if (m_visualizeProcess)
95  this->VisualizeMCProcess(mcHierarchy);
96  else
97  this->VisualizeMC(mcHierarchy);
98  }
99  if (m_visualizeReco)
100  this->VisualizeReco(recoHierarchy);
101  }
102 #endif
103 
104  return STATUS_CODE_SUCCESS;
105 }
106 
107 //------------------------------------------------------------------------------------------------------------------------------------------
108 #ifdef MONITORING
109 void HierarchyMonitoringAlgorithm::VisualizeMC(const LArHierarchyHelper::MCHierarchy &hierarchy) const
110 {
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}};
113 
114  MCParticleList rootMCParticles;
115  hierarchy.GetRootMCParticles(rootMCParticles);
116  for (const MCParticle *const pRoot : rootMCParticles)
117  {
119  hierarchy.GetFlattenedNodes(pRoot, nodes);
120 
121  bool depositedHits{false};
122  int nodeIdx{0};
123  for (const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
124  {
125  std::string key("other");
126  const int pdg{std::abs(pNode->GetParticleId())};
127  if (keys.find(pdg) != keys.end())
128  key = keys.at(pdg);
129 
130  CaloHitList uHits, vHits, wHits;
131  this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
132  if (!(uHits.empty() && vHits.empty() && wHits.empty()))
133  {
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));
139  }
140  ++nodeIdx;
141  }
142  if (depositedHits)
143  {
144  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
145  }
146  }
147 }
148 
149 //------------------------------------------------------------------------------------------------------------------------------------------
150 
151 void HierarchyMonitoringAlgorithm::VisualizeMCDistinct(const LArHierarchyHelper::MCHierarchy &hierarchy) const
152 {
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};
156 
157  MCParticleList rootMCParticles;
158  hierarchy.GetRootMCParticles(rootMCParticles);
159  for (const MCParticle *const pRoot : rootMCParticles)
160  {
162  hierarchy.GetFlattenedNodes(pRoot, nodes);
163 
164  bool depositedHits{false};
165  int nodeIdx{0}, colorIdx{0};
166  for (const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
167  {
168  std::string key("other");
169  const int pdg{std::abs(pNode->GetParticleId())};
170  if (keys.find(pdg) != keys.end())
171  key = keys.at(pdg);
172 
173  CaloHitList uHits, vHits, wHits;
174  this->FillHitLists(pNode->GetCaloHits(), uHits, vHits, wHits);
175  if (!(uHits.empty() && vHits.empty() && wHits.empty()))
176  {
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;
183  }
184  ++nodeIdx;
185  }
186 
187  if (depositedHits)
188  {
189  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
190  }
191  }
192 }
193 
194 //------------------------------------------------------------------------------------------------------------------------------------------
195 
196 void HierarchyMonitoringAlgorithm::VisualizeMCProcess(const LArHierarchyHelper::MCHierarchy &hierarchy) const
197 {
198  const std::map<MCProcess, std::string> procToCategoryMap = {{MC_PROC_INCIDENT_NU, "invisible"}, {MC_PROC_UNKNOWN, "invisible"},
199  {MC_PROC_PRIMARY, "primary"}, {MC_PROC_COMPT, "compt"}, {MC_PROC_PHOT, "phot"}, {MC_PROC_ANNIHIL, "annihil"}, {MC_PROC_E_IONI, "ioni"},
200  {MC_PROC_E_BREM, "brem"}, {MC_PROC_CONV, "conv"}, {MC_PROC_MU_IONI, "ioni"}, {MC_PROC_MU_MINUS_CAPTURE_AT_REST, "capture"},
201  {MC_PROC_NEUTRON_INELASTIC, "inelastic"}, {MC_PROC_N_CAPTURE, "capture"}, {MC_PROC_HAD_ELASTIC, "elastic"}, {MC_PROC_DECAY, "decay"},
202  {MC_PROC_COULOMB_SCAT, "coulomb"}, {MC_PROC_MU_BREM, "brem"}, {MC_PROC_MU_PAIR_PROD, "pair_prod"}, {MC_PROC_PHOTON_INELASTIC, "inelastic"},
203  {MC_PROC_HAD_IONI, "ioni"}, {MC_PROC_PROTON_INELASTIC, "inelastic"}, {MC_PROC_PI_PLUS_INELASTIC, "inelastic"},
205  {MC_PROC_RAYLEIGH, "rayleigh"}, {MC_PROC_HAD_BREM, "brem"}, {MC_PROC_HAD_PAIR_PROD, "pair_prod"}, {MC_PROC_ION_IONI, "ioni"},
206  {MC_PROC_NEUTRON_KILLER, "kill"}, {MC_PROC_ION_INELASTIC, "inelastic"}, {MC_PROC_HE3_INELASTIC, "inelastic"},
207  {MC_PROC_ALPHA_INELASTIC, "inelastic"}, {MC_PROC_ANTI_HE3_INELASTIC, "inelastic"}, {MC_PROC_ANTI_ALPHA_INELASTIC, "inelastic"},
209  {MC_PROC_ANTI_NEUTRON_INELASTIC, "inelastic"}, {MC_PROC_ANTI_PROTON_INELASTIC, "inelastic"},
210  {MC_PROC_ANTI_TRITON_INELASTIC, "inelastic"}, {MC_PROC_DEUTERON_INELASTIC, "inelastic"}, {MC_PROC_ELECTRON_NUCLEAR, "nuclear"},
211  {MC_PROC_PHOTON_NUCLEAR, "nuclear"}, {MC_PROC_KAON_PLUS_INELASTIC, "inelastic"}, {MC_PROC_KAON_MINUS_INELASTIC, "inelastic"},
212  {MC_PROC_HAD_BERTINI_CAPTURE_AT_REST, "capture"}, {MC_PROC_LAMBDA_INELASTIC, "inelastic"}, {MC_PROC_MU_NUCLEAR, "nuclear"},
213  {MC_PROC_TRITON_INELASTIC, "inelastic"}, {MC_PROC_PRIMARY_BACKGROUND, "background"}};
214 
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}};
218 
219  MCParticleList rootMCParticles;
220  hierarchy.GetRootMCParticles(rootMCParticles);
221  for (const MCParticle *const pRoot : rootMCParticles)
222  {
224  hierarchy.GetFlattenedNodes(pRoot, nodes);
225 
226  int nodeIdx{0};
227  for (const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
228  {
229  const LArMCParticle *pMC{dynamic_cast<const LArMCParticle *>(pNode->GetLeadingMCParticle())};
230  if (!pMC)
231  continue;
232  const MCProcess process{pMC->GetProcess()};
233  const std::string category{procToCategoryMap.at(process)};
234  const int pdg{std::abs(pNode->GetParticleId())};
235  const int tier{LArMCParticleHelper::GetHierarchyTier(pMC)};
236 
237  CaloHitList uHits, vHits, wHits;
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)};
241  if (process == MC_PROC_DECAY)
242  {
243  const MCParticleList &parentList{pMC->GetParentList()};
244  if (!parentList.empty())
245  {
246  const MCParticle *pParent{parentList.front()};
247  const int parentPdg{std::abs(pParent->GetParticleId())};
248  suffix += " from " + std::to_string(parentPdg);
249  }
250  }
251 
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));
255  ++nodeIdx;
256 
257  const int proc{static_cast<int>(process)};
258  const float mom{pMC->GetMomentum().GetMagnitude()};
259  if (!m_rootFileName.empty())
260  {
261  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), "processes", "process", proc));
262  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), "processes", "momentum", mom));
263  PANDORA_MONITORING_API(FillTree(this->GetPandora(), "processes"));
264  }
265  }
266 
267  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
268  }
269 }
270 
271 //------------------------------------------------------------------------------------------------------------------------------------------
272 
273 void HierarchyMonitoringAlgorithm::VisualizeReco(const LArHierarchyHelper::RecoHierarchy &hierarchy) const
274 {
275  const int nColors{7};
276  const int colors[nColors] = {5, 2, 9, 1, 3, 4, 14};
277 
278  PfoList rootPfos;
279  hierarchy.GetRootPfos(rootPfos);
280  for (const ParticleFlowObject *const pRoot : rootPfos)
281  {
283  hierarchy.GetFlattenedNodes(pRoot, nodes);
284 
285  int colorIdx{0};
286  int pfoIdx{0};
287  for (const LArHierarchyHelper::RecoHierarchy::Node *pNode : nodes)
288  {
289  CaloHitList uHits, vHits, wHits;
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;
298  ++pfoIdx;
299  }
300 
301  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
302  }
303 }
304 
305 //------------------------------------------------------------------------------------------------------------------------------------------
306 
307 void HierarchyMonitoringAlgorithm::VisualizeMatches(const LArHierarchyHelper::MatchInfo &matchInfo) const
308 {
309  const int nColors{8};
310  const int colors[nColors] = {2, 3, 4, 5, 6, 7, 8, 9};
311  MCParticleList rootMCParticles;
312  matchInfo.GetRootMCParticles(rootMCParticles);
313  PfoList rootPfos;
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};
323  for (const ParticleFlowObject *const pRoot : rootPfos)
324  {
325  recoRootToSliceMap[pRoot] = sliceIdx;
327  recoHierarchy.GetFlattenedNodes(pRoot, nodes);
328  for (const LArHierarchyHelper::RecoHierarchy::Node *pNode : nodes)
329  {
330  recoNodeToColorMap[pNode] = colors[colorIdx];
331  recoNodeToIdMap[pNode] = recoIdx;
332  recoNodeToRootMap[pNode] = pRoot;
333  ++recoIdx;
334  }
335  ++sliceIdx;
336  ++colorIdx;
337  if (colorIdx >= nColors)
338  colorIdx = 0;
339  }
340  for (const MCParticle *const pRoot : rootMCParticles)
341  {
342  bool isReconstructable{false};
344  mcHierarchy.GetFlattenedNodes(pRoot, nodes);
345 
346  // Display MC
347  for (const LArHierarchyHelper::MCHierarchy::Node *pNode : nodes)
348  {
349  const MCParticle *pMC{pNode->GetLeadingMCParticle()};
350  if (!pMC)
351  continue;
352  const int pdg{std::abs(pNode->GetParticleId())};
353 
354  CaloHitList uHits, vHits, wHits;
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;
363  ++mcIdx;
364  }
365 
366  // Display reco
367  const LArHierarchyHelper::MCMatchesVector &matches{matchInfo.GetMatches(pRoot)};
368  std::map<const LArHierarchyHelper::RecoHierarchy::Node *, bool> matchedReco;
369  std::map<const ParticleFlowObject *, bool> matchedRoots;
370  for (const auto &match : matches)
371  {
372  const LArHierarchyHelper::MCHierarchy::Node *pMC{match.GetMC()};
373  for (const LArHierarchyHelper::RecoHierarchy::Node *pReco : match.GetRecoMatches())
374  {
375  CaloHitList uHits, vHits, wHits;
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)};
380 
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)
386  {
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]);
390 
391  matchedReco[pReco] = true;
392  matchedRoots[recoNodeToRootMap[pReco]] = true;
393  }
394  else
395  {
396  // Only note the reconstructed slice if the completeness passes a minimal threshold
397  if (completeness >= m_minMatchCompleteness)
398  {
399  matchedReco[pReco] = true;
400  matchedRoots[recoNodeToRootMap[pReco]] = true;
401 
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);
405  }
406  }
407  }
408  }
409 
410  // Display unmatched reco (for this true slice)
411  for (const auto [pRecoRoot, val] : matchedRoots)
412  {
413  (void)val;
415  recoHierarchy.GetFlattenedNodes(pRecoRoot, recoNodes);
416  for (const LArHierarchyHelper::RecoHierarchy::Node *pNode : recoNodes)
417  {
418  if (matchedReco.find(pNode) == matchedReco.end())
419  {
420  CaloHitList uHits, vHits, wHits;
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);
427  }
428  }
429  }
430 
431  if (isReconstructable)
432  {
433  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
434  }
435  }
436 }
437 
438 //------------------------------------------------------------------------------------------------------------------------------------------
439 
440 void HierarchyMonitoringAlgorithm::Visualize(const CaloHitList &hits, const std::string &label, const int color) const
441 {
442  if (!hits.empty())
443  {
444  if (m_collectionOnly && hits.front()->GetHitType() != TPC_VIEW_W)
445  return;
446  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &hits, label, static_cast<Color>(color)));
447  }
448 }
449 
450 //------------------------------------------------------------------------------------------------------------------------------------------
451 
452 void HierarchyMonitoringAlgorithm::FillHitLists(const CaloHitList &hits, CaloHitList &uHits, CaloHitList &vHits, CaloHitList &wHits) const
453 {
454  for (const CaloHit *pCaloHit : hits)
455  {
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);
463  }
464 }
465 #endif
466 
467 //------------------------------------------------------------------------------------------------------------------------------------------
468 
469 std::string HierarchyMonitoringAlgorithm::ToStringSF(const float val, const int sf) const
470 {
471  std::ostringstream out;
472  out.precision(sf);
473  out << std::fixed << val;
474  return out.str();
475 }
476 
477 //------------------------------------------------------------------------------------------------------------------------------------------
478 
479 StatusCode HierarchyMonitoringAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
480 {
481  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CaloHitListName", m_caloHitListName));
482  if (m_caloHitListName.empty())
483  m_caloHitListName = "CaloHitList2D";
484  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PfoListName", m_pfoListName));
485  if (m_pfoListName.empty())
486  m_pfoListName = "RecreatedPfos";
487  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "RootFileName", m_rootFileName));
488  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VisualizeMC", m_visualizeMC));
489  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VisualizeReco", m_visualizeReco));
490  PANDORA_RETURN_RESULT_IF_AND_IF(
491  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VisualizeDistinct", m_visualizeDistinct));
492  PANDORA_RETURN_RESULT_IF_AND_IF(
493  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VisualizeProcess", m_visualizeProcess));
494  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PerformMatching", m_match));
495  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CollectionOnly", m_collectionOnly));
496  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldToPrimaries", m_foldToPrimaries));
497  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldDynamic", m_foldDynamic));
498  if (m_foldToPrimaries)
499  m_foldDynamic = false;
500  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinPurity", m_minPurity));
501  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCompleteness", m_minCompleteness));
502  PANDORA_RETURN_RESULT_IF_AND_IF(
503  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchCompleteness", m_minMatchCompleteness));
504  PANDORA_RETURN_RESULT_IF_AND_IF(
505  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "TransparencyThresholdE", m_transparencyThresholdE));
506  PANDORA_RETURN_RESULT_IF_AND_IF(
507  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "EnergyScaleThresholdE", m_energyScaleThresholdE));
508  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ScalingFactor", m_scalingFactor));
509 
510  return STATUS_CODE_SUCCESS;
511 }
512 
513 } // namespace lar_content
void GetRootMCParticles(pandora::MCParticleList &rootMCParticles) const
Retrieve the root MC particles of the interaction hierarchies.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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 ...
void GetFlattenedNodes(const pandora::MCParticle *const pRoot, NodeVector &nodeVector) const
Retrieve a flat vector of the ndoes in the hierarchy.
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.
std::string m_pfoListName
Name of input PFO list.
bool m_visualizeMC
Whether or not to visualize the MC nodes.
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.
MCProcess GetProcess() const
Get the process.
bool m_visualizeProcess
If true, allocate colours based on the MC process.
constexpr auto abs(T v)
Returns the absolute value of the argument.
std::string ToStringSF(const float val, const int sf=3) const
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.
static void MatchHierarchies(MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
LAr mc particle class.
Definition: LArMCParticle.h:94
float m_minCompleteness
The minimum completeness for a match to be considered good.
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.
void hits()
Definition: readHits.C:15
float m_minPurity
The minimum purity for a match to be considered good.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::string m_rootFileName
Name of the output ROOT file (optional)
Header file for the particle visualisation algorithm.
float m_minMatchCompleteness
The minimum completeness at which to a PFO should be considered matching at all.
const QualityCuts & GetQualityCuts() const
Retrieve the quality cuts for matching.
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.
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...
std::size_t color(std::string const &procname)
const std::string ToString() const
Produce a string representation of the hierarchy.
std::vector< MCMatches > MCMatchesVector
HitType
Definition: HitType.h:12
const MCHierarchy & GetMCHierarchy() const
Retrieve the MC hierarchy used for the matching.
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...
bool m_collectionOnly
Limit display to the collection plane only.
void GetFlattenedNodes(const pandora::ParticleFlowObject *const pRoot, NodeVector &nodeVector) const
Retrieve a flat vector of the nodes in the hierarchy.
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.