Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
lar_content::LArHierarchyHelper::MCHierarchy Class Reference

MCHierarchy class. More...

#include <LArHierarchyHelper.h>

Classes

class  Node
 Node class. More...
 
class  ReconstructabilityCriteria
 ReconstructabilityCriteria class. More...
 

Public Types

typedef std::vector< const Node * > NodeVector
 
typedef std::list< const Node * > NodeList
 

Public Member Functions

 MCHierarchy ()
 Default constructor. More...
 
 MCHierarchy (const ReconstructabilityCriteria &recoCriteria)
 Construct a new MCHierarchy object using specified reconstructability criteria. More...
 
virtual ~MCHierarchy ()
 Destructor. More...
 
void FillHierarchy (const pandora::MCParticleList &mcParticleList, const pandora::CaloHitList &caloHitList, const FoldingParameters &foldParameters)
 Creates an MC hierarchy representation. Without folding this will be a mirror image of the standard MCParticle relationships. However, with folding options selected the hierarchy structure will group together MC particles into nodes based on the folding requirements. More...
 
void InterpretHierarchy (const pandora::MCParticle *const pRoot, pandora::MCParticleList &leadingParticles, pandora::MCParticleList &childParticles, const float cosAngleTolerance) const
 Interpret the hierarchy below a particular particle to determine if and how it should be folded. Folded particles are added to the leadingParticles list and child particles are added to the childParticles list. More...
 
const pandora::MCParticle * GetNeutrino () const
 Retrieve the neutrino at the root of the hierarchy if it exists. More...
 
const NodeVectorGetRootNodes () const
 Retrieve the root nodes in this hierarchy. More...
 
void GetFlattenedNodes (NodeVector &nodeVector) const
 Retrieve a flat vector of the ndoes in the hierarchy. More...
 
void RegisterNode (const Node *pNode)
 Register a node with the hierarchy. More...
 
const std::string ToString () const
 Produce a string representation of the hierarchy. More...
 
bool IsNeutrinoHierarchy () const
 Check if this is a neutrino hierarchy. More...
 
bool IsTestBeamHierarchy () const
 Check if this is a test beam hierarchy. More...
 

Private Member Functions

void CollectContinuations (const pandora::MCParticle *pRoot, pandora::MCParticleList &continuingParticles, pandora::MCParticleList &childParticles, const float cosAngleTolerance) const
 Identify downstream particles that represent continuations of the parent particle from a reconstruction perspective. More...
 
bool IsReconstructable (const pandora::MCParticle *pMCParticle) const
 Checks if an individual particle meets reconstructability criteria. More...
 
bool IsReconstructable (const pandora::CaloHitList &caloHits) const
 Checks if a set of hits meet reconstructability criteria. More...
 

Private Attributes

NodeVector m_rootNodes
 The leading nodes (e.g. primary particles, cosmic rays, ...) More...
 
ReconstructabilityCriteria m_recoCriteria
 The criteria used to determine if the node is reconstructable. More...
 
const pandora::MCParticle * m_pNeutrino
 The incident neutrino, if it exists. More...
 
std::map< const pandora::MCParticle *, pandora::CaloHitList > m_mcToHitsMap
 The map between MC particles and calo hits. More...
 
std::map< const Node *, int > m_nodeToIdMap
 A map from nodes to unique ids. More...
 
int m_nextNodeId
 The ID to use for the next node. More...
 

Detailed Description

MCHierarchy class.

Definition at line 88 of file LArHierarchyHelper.h.

Member Typedef Documentation

Definition at line 126 of file LArHierarchyHelper.h.

Definition at line 124 of file LArHierarchyHelper.h.

Constructor & Destructor Documentation

lar_content::LArHierarchyHelper::MCHierarchy::MCHierarchy ( )

Default constructor.

Definition at line 75 of file LArHierarchyHelper.cc.

75  : m_pNeutrino{nullptr}, m_nextNodeId{1}
76 {
77 }
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
int m_nextNodeId
The ID to use for the next node.
lar_content::LArHierarchyHelper::MCHierarchy::MCHierarchy ( const ReconstructabilityCriteria recoCriteria)

Construct a new MCHierarchy object using specified reconstructability criteria.

Parameters
recoCriteriaThe reconstructability criteria to be applied

Definition at line 81 of file LArHierarchyHelper.cc.

81  :
82  m_recoCriteria(recoCriteria),
83  m_pNeutrino{nullptr},
84  m_nextNodeId{1}
85 {
86 }
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
ReconstructabilityCriteria m_recoCriteria
The criteria used to determine if the node is reconstructable.
int m_nextNodeId
The ID to use for the next node.
lar_content::LArHierarchyHelper::MCHierarchy::~MCHierarchy ( )
virtual

Destructor.

Definition at line 90 of file LArHierarchyHelper.cc.

91 {
92  for (const Node *pNode : m_rootNodes)
93  delete pNode;
94  m_rootNodes.clear();
95 }
QMapNodeBase Node
Definition: qmap.cpp:41
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)

Member Function Documentation

void lar_content::LArHierarchyHelper::MCHierarchy::CollectContinuations ( const pandora::MCParticle *  pRoot,
pandora::MCParticleList &  continuingParticles,
pandora::MCParticleList &  childParticles,
const float  cosAngleTolerance 
) const
private

Identify downstream particles that represent continuations of the parent particle from a reconstruction perspective.

Parameters
pRootThe root MC particle
continuingParticlesAn output list of the particles identified as continuations
childParticlesAn output list of the particles identified as child particles given any continuations
cosAngleToleranceThe cosine of the maximum angle for which trajectories are considered continuous

Definition at line 339 of file LArHierarchyHelper.cc.

341 {
342  const MCParticleList &children{pRoot->GetDaughterList()};
343  MCParticleList foldCandidates;
344  for (const MCParticle *pMCParticle : children)
345  {
346  const LArMCParticle *pLArMCParticle{dynamic_cast<const LArMCParticle *>(pMCParticle)};
347  if (!pLArMCParticle)
348  continue;
349  // Only elastic and inelastic scattering can lead to folding
351  {
352  if (pMCParticle->GetParticleId() == pRoot->GetParticleId())
353  foldCandidates.emplace_back(pMCParticle);
354  }
355  else if (!m_recoCriteria.m_removeNeutrons || (m_recoCriteria.m_removeNeutrons && pLArMCParticle->GetProcess() != MC_PROC_N_CAPTURE))
356  {
357  // Non-scattering process particles become leading candidates unless it's neutron capture and we're removing neutrons
358  childParticles.emplace_back(pMCParticle);
359  }
360  }
361  const MCParticle *pBestFoldCandidate{nullptr};
362  float bestDp{std::numeric_limits<float>::max()};
363  for (const MCParticle *pMCParticle : foldCandidates)
364  {
365  if (foldCandidates.size() == 1)
366  {
367  // No alternative options, so this is either the best folding option by default, or a sufficiently large scatter to
368  // treat as a new particle for reconstruction purposes
369  if (LArMCParticleHelper::AreTopologicallyContinuous(pRoot, pMCParticle, cosAngleTolerance))
370  pBestFoldCandidate = pMCParticle;
371  }
372  else
373  {
374  // Assess which, if any, of the children might be a continuation of the trajectory, otherwise move to child candidates
375  if (LArMCParticleHelper::AreTopologicallyContinuous(pRoot, pMCParticle, cosAngleTolerance))
376  {
377  const float dp{pRoot->GetMomentum().GetMagnitude() - pMCParticle->GetMomentum().GetMagnitude()};
378  if (dp < bestDp)
379  {
380  pBestFoldCandidate = pMCParticle;
381  bestDp = dp;
382  }
383  }
384  }
385  }
386  if (pBestFoldCandidate)
387  {
388  continuingParticles.emplace_back(pBestFoldCandidate);
389  const MCParticleList &newLeadingParticles{pBestFoldCandidate->GetDaughterList()};
390  // We need to add the children as child particles to ensure these sub-hierarchies are explored...
391  childParticles.insert(childParticles.begin(), newLeadingParticles.begin(), newLeadingParticles.end());
392  // but this current best fold candidate may have been added to the child particles by previously, so remove it
393  const auto iter{std::find(childParticles.begin(), childParticles.end(), pBestFoldCandidate)};
394  if (iter != childParticles.end())
395  childParticles.erase(iter);
396  // Having found a particle to fold back at this level, continue to explore its downstream hierarchy for further folding
397  // opportunities and make their respective children child particles for the folded node we are creating
398  LArHierarchyHelper::MCHierarchy::CollectContinuations(pBestFoldCandidate, continuingParticles, childParticles, cosAngleTolerance);
399  }
400 }
void CollectContinuations(const pandora::MCParticle *pRoot, pandora::MCParticleList &continuingParticles, pandora::MCParticleList &childParticles, const float cosAngleTolerance) const
Identify downstream particles that represent continuations of the parent particle from a reconstructi...
static bool IsInelasticScatter(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle came from an inelastic scattering process.
static int max(int a, int b)
static bool AreTopologicallyContinuous(const pandora::MCParticle *const pMCParent, const pandora::MCParticle *const pMCChild, const float cosAngleTolerance)
Determine if two MC particles are topologically continuous within a given tolerance. If the parent does not travel any distance, a travelling parent is sought and the comparison made between this and the child. If no travelling parent can be found, the particles are treated as continuous.
ReconstructabilityCriteria m_recoCriteria
The criteria used to determine if the node is reconstructable.
const bool m_removeNeutrons
whether to remove neutrons and their downstream particles
static bool IsElasticScatter(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle came from an elastic scattering process.
void lar_content::LArHierarchyHelper::MCHierarchy::FillHierarchy ( const pandora::MCParticleList &  mcParticleList,
const pandora::CaloHitList &  caloHitList,
const FoldingParameters foldParameters 
)

Creates an MC hierarchy representation. Without folding this will be a mirror image of the standard MCParticle relationships. However, with folding options selected the hierarchy structure will group together MC particles into nodes based on the folding requirements.

If only folding back to primaries, the hierarchy will be relatively flat, with a top-level neutrino or test beam particle, if appropriate, and then a set of leaf nodes, one for each primary particles also containing the MC particles (and corresponding hits) from daughter particles.

If only folding back to leading shower particles, the hierarchy will largely mirror the standard MCParticle hierarchy, but, when a shower particle is reached (for this purpose an electron or photon), this particle and all daughter particles will be represented by a single leaf node.

If folding back to both primary and leading shower particles the hierarchy will again be rather flat, but in this case, if a primary track-like particle (i.e. not an electron or photon) has a downstream shower particle then all downstream particles above the shower-like particle will be folded into the primary node, but a new, daughter leaf node will be created for the shower-like particle and all of its daughters, and a parent-child relationship will be formed between the primary node and shower node.

Parameters
mcParticleListThe list of MC particles with which to fill the hierarchy
caloHitListThe list of hits with which to fill the hierarchy
foldParametersThe folding parameters to use for the hierarchy

Definition at line 99 of file LArHierarchyHelper.cc.

100 {
101  const auto predicate = [](const MCParticle *pMCParticle) { return std::abs(pMCParticle->GetParticleId()) == NEUTRON; };
102  m_mcToHitsMap.clear();
103  for (const CaloHit *pCaloHit : caloHitList)
104  {
105  try
106  {
107  const MCParticle *pMCParticle{MCParticleHelper::GetMainMCParticle(pCaloHit)};
108  m_mcToHitsMap[pMCParticle].emplace_back(pCaloHit);
109  }
110  catch (const StatusCodeException &)
111  {
112  }
113  }
114 
115  MCParticleSet primarySet;
116  m_pNeutrino = LArHierarchyHelper::GetMCPrimaries(mcParticleList, primarySet);
117  MCParticleList primaries(primarySet.begin(), primarySet.end());
118  primaries.sort(LArMCParticleHelper::SortByMomentum);
120  primaries.erase(std::remove_if(primaries.begin(), primaries.end(), predicate), primaries.end());
121  if (foldParameters.m_foldToTier && foldParameters.m_tier == 1)
122  {
123  for (const MCParticle *pPrimary : primaries)
124  {
125  MCParticleList allParticles{pPrimary};
127  {
128  LArMCParticleHelper::GetAllDescendentMCParticles(pPrimary, allParticles);
129  }
130  else
131  {
132  // Collect track-like and shower-like particles together, but throw out neutrons and descendents
133  MCParticleList dummy;
134  LArMCParticleHelper::GetAllDescendentMCParticles(pPrimary, allParticles, allParticles, dummy);
135  }
136  CaloHitList allHits;
137  for (const MCParticle *pMCParticle : allParticles)
138  {
139  // Not all MC particles will have hits
140  if (m_mcToHitsMap.find(pMCParticle) != m_mcToHitsMap.end())
141  {
142  const CaloHitList &caloHits(m_mcToHitsMap.at(pMCParticle));
143  allHits.insert(allHits.begin(), caloHits.begin(), caloHits.end());
144  }
145  }
146  m_rootNodes.emplace_back(new Node(*this, allParticles, allHits));
147  }
148  }
149  else if (foldParameters.m_foldToLeadingShowers)
150  {
151  for (const MCParticle *pPrimary : primaries)
152  {
153  MCParticleList allParticles{pPrimary};
154  int pdg{std::abs(pPrimary->GetParticleId())};
155  const bool isShower{pdg == E_MINUS || pdg == PHOTON};
156  const bool isNeutron{pdg == NEUTRON};
157  if (isShower || (isNeutron && !m_recoCriteria.m_removeNeutrons))
158  LArMCParticleHelper::GetAllDescendentMCParticles(pPrimary, allParticles);
159  CaloHitList allHits;
160  for (const MCParticle *pMCParticle : allParticles)
161  {
162  // ATTN - Not all MC particles will have hits
163  if (m_mcToHitsMap.find(pMCParticle) != m_mcToHitsMap.end())
164  {
165  const CaloHitList &caloHits(m_mcToHitsMap.at(pMCParticle));
166  allHits.insert(allHits.begin(), caloHits.begin(), caloHits.end());
167  }
168  }
169  Node *pNode{new Node(*this, allParticles, allHits)};
170  m_rootNodes.emplace_back(pNode);
171  if (!(isShower || isNeutron))
172  {
173  // Find the children of this particle and recursively add them to the hierarchy
174  const MCParticleList &children{pPrimary->GetDaughterList()};
175  for (const MCParticle *pChild : children)
176  pNode->FillHierarchy(pChild, foldParameters);
177  }
178  }
179  }
180  else if (foldParameters.m_foldDynamic)
181  {
182  for (const MCParticle *pPrimary : primaries)
183  {
184  MCParticleList leadingParticles, childParticles;
185  this->InterpretHierarchy(pPrimary, leadingParticles, childParticles, foldParameters.m_cosAngleTolerance);
186  CaloHitList allHits;
187  for (const MCParticle *pMCParticle : leadingParticles)
188  {
189  // ATTN - Not all MC particles will have hits
190  if (m_mcToHitsMap.find(pMCParticle) != m_mcToHitsMap.end())
191  {
192  const CaloHitList &caloHits(m_mcToHitsMap.at(pMCParticle));
193  allHits.insert(allHits.begin(), caloHits.begin(), caloHits.end());
194  }
195  }
196 
197  Node *pNode{new Node(*this, leadingParticles, allHits)};
198  m_rootNodes.emplace_back(pNode);
199  for (const MCParticle *pChild : childParticles)
200  pNode->FillHierarchy(pChild, foldParameters);
201  }
202  }
203  else
204  {
205  // Unfolded and folded to tier > 1 have the same behaviour for primaries
206  for (const MCParticle *pPrimary : primaries)
207  {
208  MCParticleList allParticles{pPrimary};
209  CaloHitList allHits;
210  for (const MCParticle *pMCParticle : allParticles)
211  {
212  // ATTN - Not all MC particles will have hits
213  if (m_mcToHitsMap.find(pMCParticle) != m_mcToHitsMap.end())
214  {
215  const CaloHitList &caloHits(m_mcToHitsMap.at(pMCParticle));
216  allHits.insert(allHits.begin(), caloHits.begin(), caloHits.end());
217  }
218  }
219  Node *pNode{new Node(*this, allParticles, allHits)};
220  m_rootNodes.emplace_back(pNode);
221  // Find the children of this particle and recursively add them to the hierarchy
222  const MCParticleList &children{pPrimary->GetDaughterList()};
223  for (const MCParticle *pChild : children)
224  pNode->FillHierarchy(pChild, foldParameters);
225  }
226  }
227 
228  Node *pLeadingLepton{nullptr};
229  float leadingLeptonEnergy{-std::numeric_limits<float>::max()};
230  for (const Node *pNode : m_rootNodes)
231  {
232  const MCParticle *pMC{pNode->GetLeadingMCParticle()};
233  if (pMC)
234  {
235  const int pdg{std::abs(pMC->GetParticleId())};
236  if ((pdg == MU_MINUS || pdg == E_MINUS || pdg == TAU_MINUS) && pMC->GetEnergy() > leadingLeptonEnergy)
237  {
238  pLeadingLepton = const_cast<Node *>(pNode);
239  leadingLeptonEnergy = pMC->GetEnergy();
240  }
241  }
242  }
243  if (pLeadingLepton)
244  pLeadingLepton->SetLeadingLepton();
245 }
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
std::set< const pandora::MCParticle * > MCParticleSet
QMapNodeBase Node
Definition: qmap.cpp:41
std::map< const pandora::MCParticle *, pandora::CaloHitList > m_mcToHitsMap
The map between MC particles and calo hits.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
T abs(T value)
void InterpretHierarchy(const pandora::MCParticle *const pRoot, pandora::MCParticleList &leadingParticles, pandora::MCParticleList &childParticles, const float cosAngleTolerance) const
Interpret the hierarchy below a particular particle to determine if and how it should be folded...
static int max(int a, int b)
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)
ReconstructabilityCriteria m_recoCriteria
The criteria used to determine if the node is reconstructable.
const bool m_removeNeutrons
whether to remove neutrons and their downstream particles
cet::LibraryManager dummy("noplugin")
static void GetAllDescendentMCParticles(const pandora::MCParticle *const pMCParticle, pandora::MCParticleList &descendentMCParticleList)
Get all descendent mc particles.
static const pandora::MCParticle * GetMCPrimaries(const pandora::MCParticleList &mcParticleList, MCParticleSet &primaries)
Retrieves the primary MC particles from a list and returns the root (neutrino) for hierarchy...
void lar_content::LArHierarchyHelper::MCHierarchy::GetFlattenedNodes ( NodeVector nodeVector) const

Retrieve a flat vector of the ndoes in the hierarchy.

Parameters
nodeVectorThe output vector for the nodes in the hierarchy in breadth first order

Definition at line 404 of file LArHierarchyHelper.cc.

405 {
406  NodeList queue;
407  for (const Node *pNode : m_rootNodes)
408  {
409  nodeVector.emplace_back(pNode);
410  queue.emplace_back(pNode);
411  }
412  while (!queue.empty())
413  {
414  const NodeVector &children{queue.front()->GetChildren()};
415  queue.pop_front();
416  for (const Node *pChild : children)
417  {
418  nodeVector.emplace_back(pChild);
419  queue.emplace_back(pChild);
420  }
421  }
422 }
QMapNodeBase Node
Definition: qmap.cpp:41
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)
const pandora::MCParticle * lar_content::LArHierarchyHelper::MCHierarchy::GetNeutrino ( ) const
inline

Retrieve the neutrino at the root of the hierarchy if it exists.

Returns
The address of the incident neutrino (nullptr if it doesn't exist)

Definition at line 948 of file LArHierarchyHelper.h.

949 {
950  return m_pNeutrino;
951 }
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
const LArHierarchyHelper::MCHierarchy::NodeVector & lar_content::LArHierarchyHelper::MCHierarchy::GetRootNodes ( ) const
inline

Retrieve the root nodes in this hierarchy.

Returns
The root nodes in this hierarchy

Definition at line 955 of file LArHierarchyHelper.h.

956 {
957  return m_rootNodes;
958 }
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)
void lar_content::LArHierarchyHelper::MCHierarchy::InterpretHierarchy ( const pandora::MCParticle *const  pRoot,
pandora::MCParticleList &  leadingParticles,
pandora::MCParticleList &  childParticles,
const float  cosAngleTolerance 
) const

Interpret the hierarchy below a particular particle to determine if and how it should be folded. Folded particles are added to the leadingParticles list and child particles are added to the childParticles list.

Parameters
pRootThe root of the hierarchy to interpret
leadingParticlesThe output list of particles that should be folded into the root particle
childParticlesThe output list of particles that should be considered children of the folded particle
cosAngleToleranceThe cosine of the maximum angle for which trajectories are considered continuous

Definition at line 249 of file LArHierarchyHelper.cc.

251 {
252  leadingParticles.emplace_back(pRoot);
253  MCParticleList foldCandidates, childCandidates;
254  const MCParticleList &children{pRoot->GetDaughterList()};
255  for (const MCParticle *pMCParticle : children)
256  {
257  const LArMCParticle *pLArMCParticle{dynamic_cast<const LArMCParticle *>(pMCParticle)};
258  if (!pLArMCParticle)
259  continue;
261  {
262  // Elastic and inelastic scattering can either lead to folding, distinct nodes or disposable hits, all other processes
263  // are either distinct nodes, or disposable
264  if (pMCParticle->GetParticleId() == pRoot->GetParticleId())
265  foldCandidates.emplace_back(pMCParticle);
266  else
267  childCandidates.emplace_back(pMCParticle);
268  }
269  else if (!m_recoCriteria.m_removeNeutrons || (m_recoCriteria.m_removeNeutrons && pLArMCParticle->GetProcess() != MC_PROC_N_CAPTURE))
270  {
271  // Non-scattering process particles become leading candidates unless it's neutron capture and we're removing neutrons
272  childCandidates.emplace_back(pMCParticle);
273  }
274  }
275  const MCParticle *pBestFoldCandidate{nullptr};
276  float bestDp{std::numeric_limits<float>::max()};
277  for (const MCParticle *pMCParticle : foldCandidates)
278  {
279  if (foldCandidates.size() == 1)
280  {
281  // No alternative options, so this is either the best folding option by default, or a sufficiently large scatter to
282  // treat as a new particle for reconstruction purposes
283  if (LArMCParticleHelper::AreTopologicallyContinuous(pRoot, pMCParticle, cosAngleTolerance))
284  pBestFoldCandidate = pMCParticle;
285  else
286  childCandidates.emplace_back(pMCParticle);
287  }
288  else
289  {
290  // Assess which, if any, of the children might be a continuation of the trajectory, otherwise move to child candidates
291  if (LArMCParticleHelper::AreTopologicallyContinuous(pRoot, pMCParticle, cosAngleTolerance))
292  {
293  const float dp{pRoot->GetMomentum().GetMagnitude() - pMCParticle->GetMomentum().GetMagnitude()};
294  if (dp < bestDp)
295  {
296  pBestFoldCandidate = pMCParticle;
297  bestDp = dp;
298  }
299  }
300  else
301  {
302  childCandidates.emplace_back(pMCParticle);
303  }
304  }
305  }
306  if (pBestFoldCandidate)
307  {
308  leadingParticles.emplace_back(pBestFoldCandidate);
309  // Having found a particle to fold back at this level, continue to explore its downstream hierarchy for further folding
310  // opportunities and make their respective children leading particles for the folded node we are creating
311  this->CollectContinuations(pBestFoldCandidate, leadingParticles, childCandidates, cosAngleTolerance);
312  }
313  for (const MCParticle *pMCParticle : childCandidates)
314  {
315  // Consider if the child particle will produce enough downstream hits to warrant inclusion
316  if (this->IsReconstructable(pMCParticle))
317  childParticles.emplace_back(pMCParticle);
318  else
319  {
320  MCParticleList localHierarchy{pMCParticle};
321  CaloHitList localHits;
322  LArMCParticleHelper::GetAllDescendentMCParticles(pMCParticle, localHierarchy);
323  for (const MCParticle *pLocalMCParticle : localHierarchy)
324  {
325  if (m_mcToHitsMap.find(pLocalMCParticle) != m_mcToHitsMap.end())
326  {
327  const CaloHitList &caloHits(m_mcToHitsMap.at(pLocalMCParticle));
328  localHits.insert(localHits.begin(), caloHits.begin(), caloHits.end());
329  }
330  }
331  if (this->IsReconstructable(localHits))
332  childParticles.emplace_back(pMCParticle);
333  }
334  }
335 }
void CollectContinuations(const pandora::MCParticle *pRoot, pandora::MCParticleList &continuingParticles, pandora::MCParticleList &childParticles, const float cosAngleTolerance) const
Identify downstream particles that represent continuations of the parent particle from a reconstructi...
std::map< const pandora::MCParticle *, pandora::CaloHitList > m_mcToHitsMap
The map between MC particles and calo hits.
static bool IsInelasticScatter(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle came from an inelastic scattering process.
static int max(int a, int b)
static bool AreTopologicallyContinuous(const pandora::MCParticle *const pMCParent, const pandora::MCParticle *const pMCChild, const float cosAngleTolerance)
Determine if two MC particles are topologically continuous within a given tolerance. If the parent does not travel any distance, a travelling parent is sought and the comparison made between this and the child. If no travelling parent can be found, the particles are treated as continuous.
ReconstructabilityCriteria m_recoCriteria
The criteria used to determine if the node is reconstructable.
const bool m_removeNeutrons
whether to remove neutrons and their downstream particles
bool IsReconstructable(const pandora::MCParticle *pMCParticle) const
Checks if an individual particle meets reconstructability criteria.
static void GetAllDescendentMCParticles(const pandora::MCParticle *const pMCParticle, pandora::MCParticleList &descendentMCParticleList)
Get all descendent mc particles.
static bool IsElasticScatter(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle came from an elastic scattering process.
bool lar_content::LArHierarchyHelper::MCHierarchy::IsNeutrinoHierarchy ( ) const
inline

Check if this is a neutrino hierarchy.

Returns
Whether or not this is a neutrino hierarchy.

Definition at line 962 of file LArHierarchyHelper.h.

963 {
964  return m_pNeutrino != nullptr;
965 }
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
bool lar_content::LArHierarchyHelper::MCHierarchy::IsReconstructable ( const pandora::MCParticle *  pMCParticle) const
private

Checks if an individual particle meets reconstructability criteria.

Parameters
pMCParticleThe MC particle to assess
Returns
Whether or not the MC particle meets reconstructability criteria

Definition at line 445 of file LArHierarchyHelper.cc.

446 {
447  if (m_mcToHitsMap.find(pMCParticle) != m_mcToHitsMap.end())
448  {
449  unsigned int nHitsU{0}, nHitsV{0}, nHitsW{0};
450  for (const CaloHit *pCaloHit : m_mcToHitsMap.at(pMCParticle))
451  {
452  const HitType view{pCaloHit->GetHitType()};
453  if (view == TPC_VIEW_U)
454  ++nHitsU;
455  else if (view == TPC_VIEW_V)
456  ++nHitsV;
457  else if (view == TPC_VIEW_W)
458  ++nHitsW;
459  }
460  const unsigned int nHits{nHitsU + nHitsV + nHitsW};
461  unsigned int nGoodViews{0};
462  nGoodViews += nHitsU >= m_recoCriteria.m_minHitsForGoodView ? 1 : 0;
463  nGoodViews += nHitsV >= m_recoCriteria.m_minHitsForGoodView ? 1 : 0;
464  nGoodViews += nHitsW >= m_recoCriteria.m_minHitsForGoodView ? 1 : 0;
465 
466  return nHits >= m_recoCriteria.m_minHits && nGoodViews >= m_recoCriteria.m_minGoodViews;
467  }
468 
469  return false;
470 }
const unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
enum cvn::HType HitType
std::map< const pandora::MCParticle *, pandora::CaloHitList > m_mcToHitsMap
The map between MC particles and calo hits.
ReconstructabilityCriteria m_recoCriteria
The criteria used to determine if the node is reconstructable.
const unsigned int m_minHits
the minimum number of primary good Hits
const unsigned int m_minGoodViews
the minimum number of primary good views
bool lar_content::LArHierarchyHelper::MCHierarchy::IsReconstructable ( const pandora::CaloHitList &  caloHits) const
private

Checks if a set of hits meet reconstructability criteria.

Parameters
caloHitsThe calo hits to assess
Returns
Whether or not the hits meet reconstructability criteria
bool lar_content::LArHierarchyHelper::MCHierarchy::IsTestBeamHierarchy ( ) const
inline

Check if this is a test beam hierarchy.

Returns
Whether or not this is a test beam hierarchy.

Definition at line 969 of file LArHierarchyHelper.h.

970 {
971  return m_pNeutrino == nullptr;
972 }
const pandora::MCParticle * m_pNeutrino
The incident neutrino, if it exists.
void lar_content::LArHierarchyHelper::MCHierarchy::RegisterNode ( const Node pNode)

Register a node with the hierarchy.

Parameters
pNodeThe node to register

Definition at line 426 of file LArHierarchyHelper.cc.

427 {
428  m_nodeToIdMap.insert(std::make_pair(pNode, m_nextNodeId));
429  ++m_nextNodeId;
430 }
int m_nextNodeId
The ID to use for the next node.
std::map< const Node *, int > m_nodeToIdMap
A map from nodes to unique ids.
const std::string lar_content::LArHierarchyHelper::MCHierarchy::ToString ( ) const

Produce a string representation of the hierarchy.

Returns
The string representation of the hierarchy

Definition at line 434 of file LArHierarchyHelper.cc.

435 {
437  for (const Node *pNode : m_rootNodes)
438  str += pNode->ToString("") + "\n";
439 
440  return str;
441 }
QMapNodeBase Node
Definition: qmap.cpp:41
std::string string
Definition: nybbler.cc:12
NodeVector m_rootNodes
The leading nodes (e.g. primary particles, cosmic rays, ...)
static QCString str

Member Data Documentation

std::map<const pandora::MCParticle *, pandora::CaloHitList> lar_content::LArHierarchyHelper::MCHierarchy::m_mcToHitsMap
private

The map between MC particles and calo hits.

Definition at line 418 of file LArHierarchyHelper.h.

int lar_content::LArHierarchyHelper::MCHierarchy::m_nextNodeId
private

The ID to use for the next node.

Definition at line 420 of file LArHierarchyHelper.h.

std::map<const Node *, int> lar_content::LArHierarchyHelper::MCHierarchy::m_nodeToIdMap
private

A map from nodes to unique ids.

Definition at line 419 of file LArHierarchyHelper.h.

const pandora::MCParticle* lar_content::LArHierarchyHelper::MCHierarchy::m_pNeutrino
private

The incident neutrino, if it exists.

Definition at line 417 of file LArHierarchyHelper.h.

ReconstructabilityCriteria lar_content::LArHierarchyHelper::MCHierarchy::m_recoCriteria
private

The criteria used to determine if the node is reconstructable.

Definition at line 416 of file LArHierarchyHelper.h.

NodeVector lar_content::LArHierarchyHelper::MCHierarchy::m_rootNodes
private

The leading nodes (e.g. primary particles, cosmic rays, ...)

Definition at line 415 of file LArHierarchyHelper.h.


The documentation for this class was generated from the following files: