All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VisualParticleMonitoringAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArMonitoring/VisualParticleMonitoringAlgorithm.cc
3  *
4  * @brief Implementation of the particle visualisation algorithm.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
16 
17 using namespace pandora;
18 
19 namespace lar_content
20 {
21 
22 VisualParticleMonitoringAlgorithm::VisualParticleMonitoringAlgorithm() :
23  m_visualizeMC(false),
24  m_visualizePfo(false),
25  m_groupMCByPdg(false),
26  m_showPfoByPid(false),
27  m_showPfoMatchedMC(false),
28  m_isTestBeam{false},
29  m_transparencyThresholdE{-1.f},
30  m_energyScaleThresholdE{1.f},
31  m_scalingFactor{1.f}
32 {
33 }
34 
35 //------------------------------------------------------------------------------------------------------------------------------------------
36 
38 {
39 }
40 
41 //------------------------------------------------------------------------------------------------------------------------------------------
42 
44 {
45 #ifdef MONITORING
46  LArMCParticleHelper::MCContributionMap targetMCParticleToHitsMap;
48  {
49  const CaloHitList *pCaloHitList(nullptr);
50  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_caloHitListName, pCaloHitList));
51  const MCParticleList *pMCParticleList(nullptr);
52  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
53  this->MakeSelection(pMCParticleList, pCaloHitList, targetMCParticleToHitsMap);
54  }
55 
56  if (m_visualizeMC)
57  {
58  if (m_groupMCByPdg)
59  this->VisualizeMCByPdgCode(targetMCParticleToHitsMap);
60  else
61  this->VisualizeIndependentMC(targetMCParticleToHitsMap);
62  }
63  if (m_visualizePfo)
64  {
65  const PfoList *pPfoList(nullptr);
66  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_pfoListName, pPfoList));
67  if (m_showPfoByPid)
68  {
69  this->VisualizePfoByParticleId(*pPfoList);
70  }
71  else
72  {
74  this->VisualizeIndependentPfo(*pPfoList, targetMCParticleToHitsMap);
75  else
76  this->VisualizeIndependentPfo(*pPfoList);
77  }
78  }
79 #endif // MONITORING
80  return STATUS_CODE_SUCCESS;
81 }
82 
83 //------------------------------------------------------------------------------------------------------------------------------------------
84 
85 #ifdef MONITORING
86 
87 void VisualParticleMonitoringAlgorithm::VisualizeIndependentMC(const LArMCParticleHelper::MCContributionMap &mcMap) const
88 {
89  const std::map<int, const std::string> keys = {{13, "mu"}, {11, "e"}, {22, "gamma"}, {321, "kaon"}, {211, "pi"}, {2212, "p"}};
90  const std::map<int, Color> colors = {{0, RED}, {1, BLACK}, {2, BLUE}, {3, CYAN}, {4, MAGENTA}, {5, GREEN}, {6, ORANGE}, {7, GRAY}};
91  MCParticleList linearisedMC;
92  if (mcMap.empty())
93  return;
94 
95  PANDORA_MONITORING_API(
96  SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, m_transparencyThresholdE, m_energyScaleThresholdE, m_scalingFactor));
97  LArMCParticleHelper::GetBreadthFirstHierarchyRepresentation(mcMap.begin()->first, linearisedMC);
98 
99  size_t colorIdx{0};
100  int mcIdx{0};
101  for (const MCParticle *pMC : linearisedMC)
102  {
103  const auto iter{mcMap.find(pMC)};
104  if (iter == mcMap.end())
105  continue;
106  std::string key("other");
107  try
108  {
109  const int pdg{std::abs(pMC->GetParticleId())};
110  if (keys.find(pdg) != keys.end())
111  key = keys.at(pdg);
112  }
113  catch (const StatusCodeException &)
114  {
115  key = "unknown";
116  }
117 
118  CaloHitList uHits, vHits, wHits;
119  for (const CaloHit *pCaloHit : iter->second)
120  {
121  const HitType view{pCaloHit->GetHitType()};
122  if (view == HitType::TPC_VIEW_U)
123  uHits.emplace_back(pCaloHit);
124  else if (view == HitType::TPC_VIEW_V)
125  vHits.emplace_back(pCaloHit);
126  else
127  wHits.emplace_back(pCaloHit);
128  }
129  std::string suffix{std::to_string(mcIdx) + "_" + key};
130  if (!uHits.empty())
131  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHits, "u_" + suffix, colors.at(colorIdx)));
132  if (!vHits.empty())
133  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &vHits, "v_" + suffix, colors.at(colorIdx)));
134  if (!wHits.empty())
135  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &wHits, "w_" + suffix, colors.at(colorIdx)));
136  colorIdx = (colorIdx + 1) >= colors.size() ? 0 : colorIdx + 1;
137  ++mcIdx;
138  }
139 
140  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
141 }
142 
143 //------------------------------------------------------------------------------------------------------------------------------------------
144 
145 void VisualParticleMonitoringAlgorithm::VisualizeMCByPdgCode(const LArMCParticleHelper::MCContributionMap &mcMap) const
146 {
147  const std::map<int, const std::string> keys = {{13, "mu"}, {11, "e"}, {22, "gamma"}, {321, "kaon"}, {211, "pi"}, {2212, "p"}};
148  const std::map<std::string, Color> colors = {
149  {"mu", MAGENTA}, {"e", RED}, {"gamma", ORANGE}, {"kaon", BLACK}, {"pi", GREEN}, {"p", BLUE}, {"other", GRAY}};
150 
151  std::map<std::string, CaloHitList> uHits, vHits, wHits;
152  for (const auto & [key, value] : keys)
153  {
154  (void)key; // GCC 7 support, 8+ doesn't need this
155  uHits[value] = CaloHitList();
156  vHits[value] = CaloHitList();
157  wHits[value] = CaloHitList();
158  }
159  uHits["other"] = CaloHitList();
160  vHits["other"] = CaloHitList();
161  wHits["other"] = CaloHitList();
162 
163  for (const auto & [pMC, pCaloHits] : mcMap)
164  {
165  for (const CaloHit *pCaloHit : pCaloHits)
166  {
167  const HitType view{pCaloHit->GetHitType()};
168 
169  try
170  {
171  const int pdg{std::abs(pMC->GetParticleId())};
172  std::string key("other");
173  if (keys.find(pdg) != keys.end())
174  key = keys.at(pdg);
175 
176  if (view == HitType::TPC_VIEW_U)
177  uHits[key].emplace_back(pCaloHit);
178  else if (view == HitType::TPC_VIEW_V)
179  vHits[key].emplace_back(pCaloHit);
180  else
181  wHits[key].emplace_back(pCaloHit);
182  }
183  catch (const StatusCodeException &)
184  {
185  continue;
186  }
187  }
188  }
189 
190  PANDORA_MONITORING_API(
191  SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, m_transparencyThresholdE, m_energyScaleThresholdE, m_scalingFactor));
192 
193  for (const auto & [key, value] : keys)
194  {
195  (void)key; // GCC 7 support, 8+ doesn't need this
196  if (!uHits[value].empty())
197  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHits[value], "u_" + value, colors.at(value)));
198  }
199  if (!uHits["other"].empty())
200  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHits["other"], "u_other", colors.at("other")));
201 
202  for (const auto & [key, value] : keys)
203  {
204  (void)key; // GCC 7 support, 8+ doesn't need this
205  if (!vHits[value].empty())
206  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &vHits[value], "v_" + value, colors.at(value)));
207  }
208  if (!vHits["other"].empty())
209  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHits["other"], "v_other", colors.at("other")));
210 
211  for (const auto & [key, value] : keys)
212  {
213  (void)key; // GCC 7 support, 8+ doesn't need this
214  if (!wHits[value].empty())
215  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &wHits[value], "w_" + value, colors.at(value)));
216  }
217  if (!wHits["other"].empty())
218  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHits["other"], "w_other", colors.at("other")));
219 
220  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
221 }
222 
223 //------------------------------------------------------------------------------------------------------------------------------------------
224 
225 void VisualParticleMonitoringAlgorithm::VisualizeIndependentPfo(const PfoList &pfoList) const
226 {
227  // ATTN - If we aren't showing matched MC, just pass in an empty MC to hits map
229  this->VisualizeIndependentPfo(pfoList, mcMap);
230 }
231 
232 //------------------------------------------------------------------------------------------------------------------------------------------
233 
234 void VisualParticleMonitoringAlgorithm::VisualizeIndependentPfo(const PfoList &pfoList, const LArMCParticleHelper::MCContributionMap &mcMap) const
235 {
236  const std::map<int, Color> colors = {{0, RED}, {1, BLACK}, {2, BLUE}, {3, CYAN}, {4, MAGENTA}, {5, GREEN}, {6, ORANGE}, {7, GRAY}};
237  PfoList linearisedPfo;
238  if (pfoList.empty())
239  return;
240 
241  PANDORA_MONITORING_API(
242  SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, m_transparencyThresholdE, m_energyScaleThresholdE, m_scalingFactor));
243  LArPfoHelper::GetBreadthFirstHierarchyRepresentation(pfoList.front(), linearisedPfo);
244 
245  size_t colorIdx{0};
246  int pfoIdx{0};
247  for (const ParticleFlowObject *pPfo : linearisedPfo)
248  {
249  CaloHitList uHits, vHits, wHits;
250  const bool isTrack{LArPfoHelper::IsTrack(pPfo)};
251  CaloHitList caloHits;
252  for (const auto view : {HitType::TPC_VIEW_U, HitType::TPC_VIEW_V, HitType::TPC_VIEW_W})
253  {
254  LArPfoHelper::GetCaloHits(pPfo, view, caloHits);
255  LArPfoHelper::GetIsolatedCaloHits(pPfo, view, caloHits);
256  }
257  for (const CaloHit *pCaloHit : caloHits)
258  {
259  const HitType view{pCaloHit->GetHitType()};
260  if (view == HitType::TPC_VIEW_U)
261  uHits.emplace_back(pCaloHit);
262  else if (view == HitType::TPC_VIEW_V)
263  vHits.emplace_back(pCaloHit);
264  else if (view == HitType::TPC_VIEW_W)
265  wHits.emplace_back(pCaloHit);
266  }
267  std::string suffix{std::to_string(pfoIdx)};
268  suffix += isTrack ? "_T" : "_S";
269  if (!uHits.empty())
270  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHits, "u_" + suffix, colors.at(colorIdx)));
271  if (!vHits.empty())
272  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &vHits, "v_" + suffix, colors.at(colorIdx)));
273  if (!wHits.empty())
274  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &wHits, "w_" + suffix, colors.at(colorIdx)));
275  colorIdx = (colorIdx + 1) >= colors.size() ? 0 : colorIdx + 1;
276  if (m_showPfoMatchedMC)
277  {
278  try
279  {
280  const MCParticle *pMC{LArMCParticleHelper::GetMainMCParticle(pPfo)};
281  if (pMC)
282  {
283  const auto iter{mcMap.find(pMC)};
284  if (iter != mcMap.end())
285  {
286  CaloHitList uHitsMC, vHitsMC, wHitsMC;
287  for (const CaloHit *pCaloHit : iter->second)
288  {
289  const HitType view{pCaloHit->GetHitType()};
290  if (view == HitType::TPC_VIEW_U)
291  uHitsMC.emplace_back(pCaloHit);
292  else if (view == HitType::TPC_VIEW_V)
293  vHitsMC.emplace_back(pCaloHit);
294  else if (view == HitType::TPC_VIEW_W)
295  wHitsMC.emplace_back(pCaloHit);
296  }
297  std::string mcSuffix(suffix + "_MC");
298  if (!uHitsMC.empty())
299  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uHitsMC, "u_" + mcSuffix, colors.at(colorIdx)));
300  if (!vHitsMC.empty())
301  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &vHitsMC, "v_" + mcSuffix, colors.at(colorIdx)));
302  if (!wHitsMC.empty())
303  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &wHitsMC, "w_" + mcSuffix, colors.at(colorIdx)));
304  }
305  }
306  }
307  catch (const StatusCodeException &)
308  { // No matched MC, move on
309  }
310  }
311  ++pfoIdx;
312  }
313 
314  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
315 }
316 
317 //------------------------------------------------------------------------------------------------------------------------------------------
318 
319 void VisualParticleMonitoringAlgorithm::VisualizePfoByParticleId(const PfoList &pfoList) const
320 {
321  PfoList linearisedPfo;
322  if (pfoList.empty())
323  return;
324 
325  PANDORA_MONITORING_API(
326  SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, m_transparencyThresholdE, m_energyScaleThresholdE, m_scalingFactor));
327  LArPfoHelper::GetBreadthFirstHierarchyRepresentation(pfoList.front(), linearisedPfo);
328 
329  int pfoIdx{0};
330  for (const ParticleFlowObject *pPfo : linearisedPfo)
331  {
332  CaloHitList uTrackHits, vTrackHits, wTrackHits, uShowerHits, vShowerHits, wShowerHits;
333  const bool isTrack{LArPfoHelper::IsTrack(pPfo)};
334  CaloHitList caloHits;
335  for (const auto view : {HitType::TPC_VIEW_U, HitType::TPC_VIEW_V, HitType::TPC_VIEW_W})
336  {
337  LArPfoHelper::GetCaloHits(pPfo, view, caloHits);
338  LArPfoHelper::GetIsolatedCaloHits(pPfo, view, caloHits);
339  }
340  for (const CaloHit *pCaloHit : caloHits)
341  {
342  const HitType view{pCaloHit->GetHitType()};
343  if (view == HitType::TPC_VIEW_U)
344  {
345  if (isTrack)
346  uTrackHits.emplace_back(pCaloHit);
347  else
348  uShowerHits.emplace_back(pCaloHit);
349  }
350  else if (view == HitType::TPC_VIEW_V)
351  {
352  if (isTrack)
353  vTrackHits.emplace_back(pCaloHit);
354  else
355  vShowerHits.emplace_back(pCaloHit);
356  }
357  else
358  {
359  if (isTrack)
360  wTrackHits.emplace_back(pCaloHit);
361  else
362  wShowerHits.emplace_back(pCaloHit);
363  }
364  }
365  if (isTrack)
366  {
367  std::string suffix{std::to_string(pfoIdx) + "_T"};
368  if (!uTrackHits.empty())
369  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uTrackHits, "u_" + suffix, BLUE));
370  if (!vTrackHits.empty())
371  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &vTrackHits, "v_" + suffix, BLUE));
372  if (!wTrackHits.empty())
373  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &wTrackHits, "w_" + suffix, BLUE));
374  }
375  else
376  {
377  std::string suffix{std::to_string(pfoIdx) + "_S"};
378  if (!uShowerHits.empty())
379  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &uShowerHits, "u_" + suffix, RED));
380  if (!vShowerHits.empty())
381  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &vShowerHits, "v_" + suffix, RED));
382  if (!wShowerHits.empty())
383  PANDORA_MONITORING_API(VisualizeCaloHits(this->GetPandora(), &wShowerHits, "w_" + suffix, RED));
384  }
385  ++pfoIdx;
386  }
387 
388  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
389 }
390 
391 //------------------------------------------------------------------------------------------------------------------------------------------
392 
393 void VisualParticleMonitoringAlgorithm::MakeSelection(
394  const MCParticleList *pMCList, const CaloHitList *pCaloHitList, LArMCParticleHelper::MCContributionMap &mcMap) const
395 {
396  // Default reconstructability criteria are very liberal to allow for unfolded hierarchy
397  LArMCParticleHelper::PrimaryParameters parameters;
398  parameters.m_minPrimaryGoodHits = 2;
399  parameters.m_minHitsForGoodView = 1;
400  parameters.m_maxPhotonPropagation = std::numeric_limits<float>::max();
401  parameters.m_minHitSharingFraction = 0;
402  parameters.m_foldBackHierarchy = false;
403 
404  if (!m_isTestBeam)
405  {
408  }
409  else
410  {
413  }
414 }
415 #endif // MONITORING
416 
417 //------------------------------------------------------------------------------------------------------------------------------------------
418 
419 StatusCode VisualParticleMonitoringAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
420 {
421  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CaloHitListName", m_caloHitListName));
422  if (m_caloHitListName.empty())
423  m_caloHitListName = "CaloHitList2D";
424  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PfoListName", m_pfoListName));
425  if (m_pfoListName.empty())
426  m_pfoListName = "RecreatedPfos";
427  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VisualizeMC", m_visualizeMC));
428  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VisualizePFO", m_visualizePfo));
429  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "GroupMCByPDG", m_groupMCByPdg));
430  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ShowPFOByPID", m_showPfoByPid));
431  PANDORA_RETURN_RESULT_IF_AND_IF(
432  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ShowPFOMatchedMC", m_showPfoMatchedMC));
433  PANDORA_RETURN_RESULT_IF_AND_IF(
434  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "TransparencyThresholdE", m_transparencyThresholdE));
435  PANDORA_RETURN_RESULT_IF_AND_IF(
436  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "EnergyScaleThresholdE", m_energyScaleThresholdE));
437  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ScalingFactor", m_scalingFactor));
438 
439  return STATUS_CODE_SUCCESS;
440 }
441 
442 } // namespace lar_content
Header file for the pfo helper class.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
var pdg
Definition: selectors.fcl:14
Header file for the lar calo hit class.
float m_transparencyThresholdE
Cell energy for which transparency is saturated (0%, fully opaque)
float m_energyScaleThresholdE
Cell energy for which color is at top end of continous color palette.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
static const pandora::MCParticle * GetMainMCParticle(const pandora::ParticleFlowObject *const pPfo)
Find the mc particle making the largest contribution to 2D clusters in a specified pfo...
bool m_showPfoMatchedMC
Whether or not to display the best matched MC particle for a PFO.
bool m_showPfoByPid
Whether or not to colour PFOs by particle id.
T abs(T value)
static bool IsCosmicRay(const pandora::MCParticle *const pMCParticle)
Return true if passed a primary cosmic ray MCParticle.
static void SelectReconstructableMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters &parameters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles that match given criteria.
Header file for the particle visualisation algorithm.
static bool IsBeamParticle(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary beam MCParticle.
j template void())
Definition: json.hpp:3108
Header file for the lar mc particle class.
static void GetBreadthFirstHierarchyRepresentation(const pandora::ParticleFlowObject *const pPfo, pandora::PfoList &pfoList)
Retrieve a linearised representation of the PFO hierarchy in breadth first order. This iterates over ...
bool m_isTestBeam
Whether or not this is a test beam experiment.
float m_scalingFactor
TEve works with [cm], Pandora usually works with [mm] (but LArContent went with cm too) ...
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
Definition: reco_sbnd.fcl:182
std::string to_string(WindowPattern const &pattern)
static void GetIsolatedCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of isolated calo hits of a particular hit type from a list of pfos.
temporary value
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
bool m_groupMCByPdg
Whether or not to group MC particles by particle id.
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
bool empty(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:555
static bool IsBeamNeutrinoFinalState(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary neutrino final state MCParticle.
static void GetBreadthFirstHierarchyRepresentation(const pandora::MCParticle *const pMCParticle, pandora::MCParticleList &mcParticleList)
Retrieve a linearised representation of the MC particle hierarchy in breadth first order...
std::string m_caloHitListName
Name of input calo hit list.
bool m_visualizeMC
Whether or not to visualize MC particles.