LArSoft  v10_06_00
Liquid Argon Software toolkit - https://larsoft.org/
lar_dl_content::DLCheatHierarchyTool Class Reference

DLCheatHierarchyTool to calculate variables related to the initial shower region. More...

#include "DLCheatHierarchyTool.h"

Inheritance diagram for lar_dl_content::DLCheatHierarchyTool:

Public Types

typedef std::map< const pandora::ParticleFlowObject *, const pandora::MCParticle * > PfoToMCParticleMap
 
typedef std::map< const pandora::ParticleFlowObject *, std::pair< const pandora::ParticleFlowObject *, int > > ChildToParentPfoMap
 

Public Member Functions

 DLCheatHierarchyTool ()
 Default constructor. More...
 
pandora::StatusCode Run (const PfoToMCParticleMap &pfoToMCParticleMap, const ChildToParentPfoMap &childToParentPfoMap, const HierarchyPfo &parentPfo, const HierarchyPfo &childPfo, bool &isTrueLink, bool &trueParentOrientation, bool &trueChildOrientation)
 
pandora::StatusCode Run (const PfoToMCParticleMap &pfoToMCParticleMap, const ChildToParentPfoMap &childToParentPfoMap, const pandora::ParticleFlowObject *const pNeutrinoPfo, const HierarchyPfo &childPfo, bool &isTrueLink, bool &trueChildOrientation)
 
void FillHierarchyMap (const pandora::Algorithm *const pAlgorithm, PfoToMCParticleMap &pfoToMCParticleMap, ChildToParentPfoMap &childToParentPfoMap) const
 Determine the true child -> parent pfo visible matches, filling the pfo->MCParticle matching map in the process. More...
 
pandora::StatusCode IsNeutronChild (const pandora::ParticleFlowObject *const pPfo, const PfoToMCParticleMap &pfoToMCParticleMap, bool &isNeutronChild) const
 Whether the true invisible parent of a particle is a neutron. More...
 

Private Types

typedef std::map< const pandora::MCParticle *, const pandora::MCParticle * > MCToMCMap
 

Private Member Functions

pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
bool IsUpstreamTrueVertex (const PfoToMCParticleMap &pfoToMCParticleMap, const pandora::ParticleFlowObject *const pPfo, const pandora::CartesianVector &upstreamVertex, const pandora::CartesianVector &downstreamVertex)
 Whether the true startpoint of the particle is in the upstream position (i.e. the endpoint closest to the neutrino vertex) More...
 
bool GetMCParticleList (const pandora::Algorithm *const pAlgorithm, const pandora::MCParticleList *&pMCParticleList) const
 Get the MCParticle list from Pandora. More...
 
bool GetNeutrinoPfo (const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *&pNeutrinoPfo) const
 Get the neutrino pfo. More...
 
void MatchPFParticles (const pandora::Algorithm *const pAlgorithm, PfoToMCParticleMap &pfoToMCParticleMap) const
 Perform the pfo->MCParticle matching, folding back EM shower hierarchies. More...
 
float GetNSpacepoints (const pandora::ParticleFlowObject *const pPfo) const
 Get the number of 3D hits owned by a pfo. More...
 
bool IsEMParticle (const pandora::MCParticle *const pMCParticle) const
 Whether a MCParticle is an electron or photon. More...
 
const pandora::MCParticle * GetLeadEMParticle (const pandora::MCParticle *const pMCParticle) const
 Get the leading EM Particle in an EM MCParticle hierarchy. More...
 
float SumEnergy (const pandora::CaloHitList &caloHitList) const
 Sum the 'energy' of the W hits in an input CaloHitList. More...
 
void GetVisibleMCHierarchy (const PfoToMCParticleMap &pfoToMCParticleMap, MCToMCMap &childToParentMCMap) const
 Determine the true child->parent MCParticle visible matches. More...
 
void GetVisiblePfoHierarchy (const pandora::ParticleFlowObject *const pNeutrinoPfo, const PfoToMCParticleMap &pfoToMCParticleMap, const MCToMCMap &childToParentMCMap, ChildToParentPfoMap &childToParentPfoMap) const
 Determine the true child->parent pfo visible matches. More...
 
void BuildSplitHierarchy (const std::pair< const pandora::MCParticle *, pandora::PfoList > &splitPfo, ChildToParentPfoMap &childToParentPfoMap) const
 Determine the 'internal' hierachy of reconstructed particles that match to the same MCParticle i.e. split particles. More...
 
float GetClosestDistance (const pandora::ParticleFlowObject *const pPfo1, const pandora::ParticleFlowObject *const pPfo2) const
 Determine the closest distance between two pfos. More...
 
const pandora::ParticleFlowObject * BestParentInSplitHierarchy (const pandora::ParticleFlowObject *const pChildPfo, const pandora::PfoList &splitParticle) const
 In cases in which the true parent pfo is ambiguous (because the parent particle has been split), find the best parent based on proximity. More...
 
void AssignGeneration (const pandora::ParticleFlowObject *const pParentPfo, const int generationToFind, ChildToParentPfoMap &childToParentPfoMap) const
 Find the children of an input parent pfo in the ChildToParentPfoMap, and assign their generation. More...
 

Private Attributes

std::string m_mcParticleListName
 the MCParticle list name More...
 
std::string m_neutrinoPfoListName
 the neutrino pfo list name More...
 
pandora::StringVector m_pfoListNames
 the vector of pfo list names More...
 

Detailed Description

DLCheatHierarchyTool to calculate variables related to the initial shower region.

Definition at line 25 of file DLCheatHierarchyTool.h.

Member Typedef Documentation

typedef std::map<const pandora::ParticleFlowObject *, std::pair<const pandora::ParticleFlowObject *, int> > lar_dl_content::DLCheatHierarchyTool::ChildToParentPfoMap

Definition at line 29 of file DLCheatHierarchyTool.h.

typedef std::map<const pandora::MCParticle *, const pandora::MCParticle *> lar_dl_content::DLCheatHierarchyTool::MCToMCMap
private

Definition at line 66 of file DLCheatHierarchyTool.h.

typedef std::map<const pandora::ParticleFlowObject *, const pandora::MCParticle *> lar_dl_content::DLCheatHierarchyTool::PfoToMCParticleMap

Definition at line 28 of file DLCheatHierarchyTool.h.

Constructor & Destructor Documentation

lar_dl_content::DLCheatHierarchyTool::DLCheatHierarchyTool ( )

Default constructor.

Definition at line 26 of file DLCheatHierarchyTool.cc.

26  :
27  m_mcParticleListName("Input"),
28  m_neutrinoPfoListName("NeutrinoParticles3D"),
29  m_pfoListNames({"TrackParticles3D", "ShowerParticles3D"})
30 {
31 }
pandora::StringVector m_pfoListNames
the vector of pfo list names
std::string m_neutrinoPfoListName
the neutrino pfo list name
std::string m_mcParticleListName
the MCParticle list name

Member Function Documentation

void lar_dl_content::DLCheatHierarchyTool::AssignGeneration ( const pandora::ParticleFlowObject *const  pParentPfo,
const int  generationToFind,
ChildToParentPfoMap childToParentPfoMap 
) const
private

Find the children of an input parent pfo in the ChildToParentPfoMap, and assign their generation.

Parameters
pParentPfoa pointer to the parent pfo
generationToFindthe generation to assign
childToParentPfoMapthe true child->parent pfo visible match map to modify

Definition at line 521 of file DLCheatHierarchyTool.cc.

Referenced by GetVisiblePfoHierarchy().

523 {
524  // Don't want to use a reference here
525  for (ChildToParentPfoMap::value_type &entry : childToParentPfoMap)
526  {
527  const ParticleFlowObject *const pThisPfo(entry.first);
528  const ParticleFlowObject *const pThisParent(entry.second.first);
529 
530  if (pParentPfo == pThisParent)
531  {
532  entry.second.second = generationToFind;
533  this->AssignGeneration(pThisPfo, (generationToFind + 1), childToParentPfoMap);
534  }
535  }
536 }
void AssignGeneration(const pandora::ParticleFlowObject *const pParentPfo, const int generationToFind, ChildToParentPfoMap &childToParentPfoMap) const
Find the children of an input parent pfo in the ChildToParentPfoMap, and assign their generation...
const ParticleFlowObject * lar_dl_content::DLCheatHierarchyTool::BestParentInSplitHierarchy ( const pandora::ParticleFlowObject *const  pChildPfo,
const pandora::PfoList &  splitParticle 
) const
private

In cases in which the true parent pfo is ambiguous (because the parent particle has been split), find the best parent based on proximity.

Parameters
pChildPfoa pointer to the child particle
splitParticlethe list of pfos forming the split particle
Returns
the best parent pfo

Definition at line 494 of file DLCheatHierarchyTool.cc.

References GetClosestDistance().

Referenced by GetVisiblePfoHierarchy().

495 {
496  float closestSep = std::numeric_limits<float>::max();
497  const ParticleFlowObject *pParentPfo(nullptr);
498 
499  for (const ParticleFlowObject *const pPotentialParent : splitParticle)
500  {
501  float thisSep(this->GetClosestDistance(pChildPfo, pPotentialParent));
502 
503  if (thisSep < closestSep)
504  {
505  closestSep = thisSep;
506  pParentPfo = pPotentialParent;
507  }
508  }
509 
510  if (!pParentPfo)
511  {
512  std::cout << "No closest Pfo?" << std::endl;
513  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
514  }
515 
516  return pParentPfo;
517 }
float GetClosestDistance(const pandora::ParticleFlowObject *const pPfo1, const pandora::ParticleFlowObject *const pPfo2) const
Determine the closest distance between two pfos.
void lar_dl_content::DLCheatHierarchyTool::BuildSplitHierarchy ( const std::pair< const pandora::MCParticle *, pandora::PfoList > &  splitPfo,
ChildToParentPfoMap childToParentPfoMap 
) const
private

Determine the 'internal' hierachy of reconstructed particles that match to the same MCParticle i.e. split particles.

Parameters
splitPfothe (MCParticle, list of matched pfos) pair
childToParentPfoMapthe true child->parent pfo visible match map to fill

Definition at line 433 of file DLCheatHierarchyTool.cc.

References GetClosestDistance().

Referenced by GetVisiblePfoHierarchy().

434 {
435  // Order segments wrt distance to the true vertex
436  std::vector<std::pair<const ParticleFlowObject *, float>> pfoComponents;
437 
438  for (const ParticleFlowObject *const pSplitPfo : splitPfo.second)
439  {
440  ClusterList clusterList;
441  LArPfoHelper::GetThreeDClusterList(pSplitPfo, clusterList);
442 
443  if (clusterList.empty())
444  throw StatusCodeException(STATUS_CODE_FAILURE);
445 
446  pfoComponents.emplace_back(std::make_pair(pSplitPfo, LArClusterHelper::GetClosestDistance(splitPfo.first->GetVertex(), clusterList)));
447  }
448 
449  std::sort(pfoComponents.begin(), pfoComponents.end(),
450  [](const std::pair<const ParticleFlowObject *, float> &a, const std::pair<const ParticleFlowObject *, float> &b)
451  { return a.second < b.second; });
452 
453  // Now build pfo hierarchy, assuming closest is the leading pfo
454  childToParentPfoMap[pfoComponents.at(1).first] = std::make_pair(pfoComponents.at(0).first, 0);
455 
456  for (unsigned int i = 2; i < pfoComponents.size(); ++i)
457  {
458  const ParticleFlowObject *const pChildPfo(pfoComponents.at(i).first);
459  double closestSep = std::numeric_limits<double>::max();
460  const ParticleFlowObject *pParentPfo(nullptr);
461 
462  for (unsigned int j = 0; j < i; ++j)
463  {
464  const ParticleFlowObject *const pPotentialParentPfo(pfoComponents.at(j).first);
465  const float thisSep(this->GetClosestDistance(pChildPfo, pPotentialParentPfo));
466 
467  if (thisSep < closestSep)
468  {
469  closestSep = thisSep;
470  pParentPfo = pPotentialParentPfo;
471  }
472  }
473 
474  if (!pParentPfo)
475  throw StatusCodeException(STATUS_CODE_FAILURE);
476 
477  childToParentPfoMap[pChildPfo] = std::make_pair(pParentPfo, 0); // Temporarily set generation to 0
478  }
479 }
float GetClosestDistance(const pandora::ParticleFlowObject *const pPfo1, const pandora::ParticleFlowObject *const pPfo2) const
Determine the closest distance between two pfos.
void lar_dl_content::DLCheatHierarchyTool::FillHierarchyMap ( const pandora::Algorithm *const  pAlgorithm,
PfoToMCParticleMap pfoToMCParticleMap,
ChildToParentPfoMap childToParentPfoMap 
) const

Determine the true child -> parent pfo visible matches, filling the pfo->MCParticle matching map in the process.

Parameters
pAlgorithma pointer to the pandora algorithm
pfoToMCParticleMapthe pfo->MCParticle matching map to fill
childToParentPfoMapthe pfo->(parentPfo, generation) map to fill

Definition at line 120 of file DLCheatHierarchyTool.cc.

References GetMCParticleList(), GetNeutrinoPfo(), GetVisibleMCHierarchy(), GetVisiblePfoHierarchy(), and MatchPFParticles().

Referenced by lar_dl_content::DLNeutrinoHierarchyAlgorithm::Run().

122 {
123  pfoToMCParticleMap.clear();
124  childToParentPfoMap.clear();
125 
126  // Get MCParticles
127  const MCParticleList *pMCParticleList(nullptr);
128  if (!this->GetMCParticleList(pAlgorithm, pMCParticleList))
129  return;
130 
131  // Get reconstructed neutrino
132  const ParticleFlowObject *pNeutrinoPfo(nullptr);
133  if (!this->GetNeutrinoPfo(pAlgorithm, pNeutrinoPfo))
134  return;
135 
136  // Match our PFPs to our MCParticles
137  this->MatchPFParticles(pAlgorithm, pfoToMCParticleMap);
138 
139  // Do MCParticle visible hierarchy building
140  MCToMCMap childToParentMCMap;
141  this->GetVisibleMCHierarchy(pfoToMCParticleMap, childToParentMCMap);
142 
143  // Do Pfo visible hierarchy building
144  this->GetVisiblePfoHierarchy(pNeutrinoPfo, pfoToMCParticleMap, childToParentMCMap, childToParentPfoMap);
145 }
std::map< const pandora::MCParticle *, const pandora::MCParticle * > MCToMCMap
void GetVisibleMCHierarchy(const PfoToMCParticleMap &pfoToMCParticleMap, MCToMCMap &childToParentMCMap) const
Determine the true child->parent MCParticle visible matches.
void MatchPFParticles(const pandora::Algorithm *const pAlgorithm, PfoToMCParticleMap &pfoToMCParticleMap) const
Perform the pfo->MCParticle matching, folding back EM shower hierarchies.
void GetVisiblePfoHierarchy(const pandora::ParticleFlowObject *const pNeutrinoPfo, const PfoToMCParticleMap &pfoToMCParticleMap, const MCToMCMap &childToParentMCMap, ChildToParentPfoMap &childToParentPfoMap) const
Determine the true child->parent pfo visible matches.
bool GetMCParticleList(const pandora::Algorithm *const pAlgorithm, const pandora::MCParticleList *&pMCParticleList) const
Get the MCParticle list from Pandora.
bool GetNeutrinoPfo(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *&pNeutrinoPfo) const
Get the neutrino pfo.
float lar_dl_content::DLCheatHierarchyTool::GetClosestDistance ( const pandora::ParticleFlowObject *const  pPfo1,
const pandora::ParticleFlowObject *const  pPfo2 
) const
private

Determine the closest distance between two pfos.

Parameters
pPfo1a pointer to one pfo
pPfo2a pointer to the other pfo
Returns
the closest distance between the two pfos

Definition at line 483 of file DLCheatHierarchyTool.cc.

Referenced by BestParentInSplitHierarchy(), and BuildSplitHierarchy().

484 {
485  ClusterList clusterList1, clusterList2;
486  LArPfoHelper::GetThreeDClusterList(pPfo1, clusterList1);
487  LArPfoHelper::GetThreeDClusterList(pPfo2, clusterList2);
488 
489  return LArClusterHelper::GetClosestDistance(clusterList1, clusterList2);
490 }
const MCParticle * lar_dl_content::DLCheatHierarchyTool::GetLeadEMParticle ( const pandora::MCParticle *const  pMCParticle) const
private

Get the leading EM Particle in an EM MCParticle hierarchy.

Parameters
pMCParticlea pointer to the input EM MCParticle
Returns
the leading EM Particle in the EM MCParticle hierarchy

Definition at line 286 of file DLCheatHierarchyTool.cc.

References IsEMParticle().

Referenced by MatchPFParticles().

287 {
288  if (!this->IsEMParticle(pMCParticle))
289  throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
290 
291  const MCParticle *pThisMCParticle(pMCParticle);
292  const MCParticle *pParentMCParticle(pMCParticle);
293 
294  while (this->IsEMParticle(pParentMCParticle))
295  {
296  const MCParticleList &parentList(pThisMCParticle->GetParentList());
297 
298  if (parentList.size() != 1)
299  {
300  std::cout << "EM shower has no parent?" << std::endl;
301  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
302  }
303 
304  pParentMCParticle = *parentList.begin();
305 
306  if (this->IsEMParticle(pParentMCParticle))
307  pThisMCParticle = pParentMCParticle;
308  }
309 
310  return pThisMCParticle;
311 }
bool IsEMParticle(const pandora::MCParticle *const pMCParticle) const
Whether a MCParticle is an electron or photon.
bool lar_dl_content::DLCheatHierarchyTool::GetMCParticleList ( const pandora::Algorithm *const  pAlgorithm,
const pandora::MCParticleList *&  pMCParticleList 
) const
private

Get the MCParticle list from Pandora.

Parameters
pAlgorithma pointer to the pandora algorithm
pMCParticleLista pointer to the MCParticle list
Returns
whether the MCParticle list could be set and is filled

Definition at line 149 of file DLCheatHierarchyTool.cc.

References m_mcParticleListName.

Referenced by FillHierarchyMap().

150 {
151  if (PandoraContentApi::GetList(*pAlgorithm, m_mcParticleListName, pMCParticleList) != STATUS_CODE_SUCCESS)
152  return false;
153 
154  if (!pMCParticleList || pMCParticleList->empty())
155  return false;
156 
157  return true;
158 }
std::string m_mcParticleListName
the MCParticle list name
bool lar_dl_content::DLCheatHierarchyTool::GetNeutrinoPfo ( const pandora::Algorithm *const  pAlgorithm,
const pandora::ParticleFlowObject *&  pNeutrinoPfo 
) const
private

Get the neutrino pfo.

Parameters
pAlgorithma pointer to the pandora algorithm
pNeutrinoPfoa pointer to the neutrino pfo
Returns
whether the neutrino pfo could be found

Definition at line 162 of file DLCheatHierarchyTool.cc.

References m_neutrinoPfoListName.

Referenced by FillHierarchyMap().

163 {
164  const PfoList *pPfoList = nullptr;
165 
166  PANDORA_THROW_RESULT_IF_AND_IF(
167  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*pAlgorithm, m_neutrinoPfoListName, pPfoList));
168 
169  if (!pPfoList || pPfoList->empty())
170  return false;
171 
172  // ATTN Enforces that only one pfo, of neutrino-type, be in the specified input list
173  pNeutrinoPfo = (1 == pPfoList->size()) ? *(pPfoList->begin()) : nullptr;
174 
175  if (!pNeutrinoPfo || !LArPfoHelper::IsNeutrino(pNeutrinoPfo))
176  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
177 
178  return true;
179 }
std::string m_neutrinoPfoListName
the neutrino pfo list name
float lar_dl_content::DLCheatHierarchyTool::GetNSpacepoints ( const pandora::ParticleFlowObject *const  pPfo) const
private

Get the number of 3D hits owned by a pfo.

Parameters
pPfoa pointer to the input pfo

Definition at line 264 of file DLCheatHierarchyTool.cc.

Referenced by MatchPFParticles().

265 {
266  ClusterList clusterList3D;
267  LArPfoHelper::GetThreeDClusterList(pPfo, clusterList3D);
268 
269  int total3DHits(0);
270 
271  for (const Cluster *const pCluster3D : clusterList3D)
272  total3DHits += pCluster3D->GetNCaloHits();
273 
274  return total3DHits;
275 }
void lar_dl_content::DLCheatHierarchyTool::GetVisibleMCHierarchy ( const PfoToMCParticleMap pfoToMCParticleMap,
MCToMCMap childToParentMCMap 
) const
private

Determine the true child->parent MCParticle visible matches.

Parameters
pfoToMCParticleMapthe pfo->MCParticle matching map
childToParentMCMapthe true child->parent MCParticle visible match map to fill

Definition at line 330 of file DLCheatHierarchyTool.cc.

Referenced by FillHierarchyMap().

331 {
332  MCParticleList reconstructedMCList;
333 
334  for (const auto &entry : pfoToMCParticleMap)
335  {
336  if (std::find(reconstructedMCList.begin(), reconstructedMCList.end(), entry.second) == reconstructedMCList.end())
337  reconstructedMCList.emplace_back(entry.second);
338  }
339 
340  for (const MCParticle *const pMCParticle : reconstructedMCList)
341  {
342  bool foundParent(false);
343  const MCParticle *pThisMCParticle(pMCParticle);
344  const MCParticle *pParentMCParticle(nullptr);
345 
346  while (!foundParent)
347  {
348  const MCParticleList &parentList(pThisMCParticle->GetParentList());
349 
350  if (parentList.size() != 1)
351  {
352  std::cout << "No MCParent for MCParticle" << std::endl;
353  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
354  }
355 
356  pParentMCParticle = *parentList.begin();
357 
358  foundParent = (LArMCParticleHelper::IsNeutrino(pParentMCParticle) ||
359  (std::find(reconstructedMCList.begin(), reconstructedMCList.end(), pParentMCParticle) != reconstructedMCList.end()));
360 
361  pThisMCParticle = pParentMCParticle;
362  }
363 
364  childToParentMCMap[pMCParticle] = pParentMCParticle;
365  }
366 }
void lar_dl_content::DLCheatHierarchyTool::GetVisiblePfoHierarchy ( const pandora::ParticleFlowObject *const  pNeutrinoPfo,
const PfoToMCParticleMap pfoToMCParticleMap,
const MCToMCMap childToParentMCMap,
ChildToParentPfoMap childToParentPfoMap 
) const
private

Determine the true child->parent pfo visible matches.

Parameters
pNeutrinoPfoa pointer to the neutrino pfo
pfoToMCParticleMapthe pfo->MCParticle matching map
childToParentMCMapthe true child->parent MCParticle visible match map
childToParentPfoMapthe true child->parent pfo visible match map to fill

Definition at line 370 of file DLCheatHierarchyTool.cc.

References AssignGeneration(), BestParentInSplitHierarchy(), and BuildSplitHierarchy().

Referenced by FillHierarchyMap().

372 {
373  std::map<const MCParticle *, PfoList> mcParticleToPfoListMap;
374 
375  for (const auto &entry : pfoToMCParticleMap)
376  mcParticleToPfoListMap[entry.second].emplace_back(entry.first);
377 
378  // First handle any split paricles
379  for (const auto &entry : mcParticleToPfoListMap)
380  {
381  if (entry.second.size() == 1)
382  continue;
383 
384  this->BuildSplitHierarchy(entry, childToParentPfoMap);
385  }
386 
387  // Now assign remaining
388  for (const auto &entry : mcParticleToPfoListMap)
389  {
390  const MCParticle *const pMatchedMCParticle(entry.first);
391 
392  if (childToParentMCMap.find(pMatchedMCParticle) == childToParentMCMap.end())
393  {
394  std::cout << "have found a mcparticle with no parent" << std::endl;
395  throw StatusCodeException(STATUS_CODE_FAILURE);
396  }
397 
398  const MCParticle *const pMatchedMCParent(childToParentMCMap.at(pMatchedMCParticle));
399 
400  for (const ParticleFlowObject *const pChildPfo : entry.second)
401  {
402  // If already assigned, move on
403  if (childToParentPfoMap.find(pChildPfo) != childToParentPfoMap.end())
404  continue;
405 
406  if (LArMCParticleHelper::IsNeutrino(pMatchedMCParent))
407  {
408  // If primary, great! Assign neutrino pfo
409  childToParentPfoMap[pChildPfo] = std::make_pair(pNeutrinoPfo, 0);
410  }
411  else
412  {
413  // Else, let's find the parent pfo
414  if (mcParticleToPfoListMap.find(pMatchedMCParent) == mcParticleToPfoListMap.end())
415  throw StatusCodeException(STATUS_CODE_FAILURE);
416 
417  const PfoList &parentPfoList(mcParticleToPfoListMap.at(pMatchedMCParent));
418 
419  if (parentPfoList.size() == 1)
420  childToParentPfoMap[pChildPfo] = std::make_pair(*parentPfoList.begin(), 0);
421  else
422  childToParentPfoMap[pChildPfo] = std::make_pair(this->BestParentInSplitHierarchy(pChildPfo, parentPfoList), 0);
423  }
424  }
425  }
426 
427  // Now determine each pfo's generation
428  this->AssignGeneration(pNeutrinoPfo, 2, childToParentPfoMap);
429 }
const pandora::ParticleFlowObject * BestParentInSplitHierarchy(const pandora::ParticleFlowObject *const pChildPfo, const pandora::PfoList &splitParticle) const
In cases in which the true parent pfo is ambiguous (because the parent particle has been split)...
void BuildSplitHierarchy(const std::pair< const pandora::MCParticle *, pandora::PfoList > &splitPfo, ChildToParentPfoMap &childToParentPfoMap) const
Determine the &#39;internal&#39; hierachy of reconstructed particles that match to the same MCParticle i...
void AssignGeneration(const pandora::ParticleFlowObject *const pParentPfo, const int generationToFind, ChildToParentPfoMap &childToParentPfoMap) const
Find the children of an input parent pfo in the ChildToParentPfoMap, and assign their generation...
bool lar_dl_content::DLCheatHierarchyTool::IsEMParticle ( const pandora::MCParticle *const  pMCParticle) const
private

Whether a MCParticle is an electron or photon.

Parameters
pMCParticlea pointer to the input MCParticle

Definition at line 279 of file DLCheatHierarchyTool.cc.

References util::abs().

Referenced by GetLeadEMParticle(), and MatchPFParticles().

280 {
281  return ((pMCParticle->GetParticleId() == 22) || (std::abs(pMCParticle->GetParticleId()) == 11));
282 }
constexpr auto abs(T v)
Returns the absolute value of the argument.
StatusCode lar_dl_content::DLCheatHierarchyTool::IsNeutronChild ( const pandora::ParticleFlowObject *const  pPfo,
const PfoToMCParticleMap pfoToMCParticleMap,
bool &  isNeutronChild 
) const

Whether the true invisible parent of a particle is a neutron.

Parameters
pPfoa pointer to the input pfo
pfoToMCParticleMapthe pfo->MCParticle matching map
isNeutronChildthe boolean to fill
Returns
a StatusCode detailing whether an answer could be found

Definition at line 86 of file DLCheatHierarchyTool.cc.

Referenced by lar_dl_content::DLNeutrinoHierarchyAlgorithm::BuildPandoraHierarchy().

87 {
88  // If we dont know the Pfo->MCParticle match
89  if (pfoToMCParticleMap.find(pPfo) == pfoToMCParticleMap.end())
90  return STATUS_CODE_NOT_FOUND;
91 
92  const MCParticleList &parentList(pfoToMCParticleMap.at(pPfo)->GetParentList());
93 
94  if (parentList.size() != 1)
95  {
96  std::cout << "No MCParent for MCParticle" << std::endl;
97  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
98  }
99 
100  isNeutronChild = ((*parentList.begin())->GetParticleId() == 2112);
101 
102  return STATUS_CODE_SUCCESS;
103 }
bool lar_dl_content::DLCheatHierarchyTool::IsUpstreamTrueVertex ( const PfoToMCParticleMap pfoToMCParticleMap,
const pandora::ParticleFlowObject *const  pPfo,
const pandora::CartesianVector &  upstreamVertex,
const pandora::CartesianVector &  downstreamVertex 
)
private

Whether the true startpoint of the particle is in the upstream position (i.e. the endpoint closest to the neutrino vertex)

Parameters
pfoToMCParticleMapthe pfo->MCParticle matching map
pPfoa pointer to the input pfo
upstreamVertexthe upstream endpoint
downstreamVertexthe downstream endpoint
Returns
whether the true startpoint of the particle is in the upstream position

Definition at line 107 of file DLCheatHierarchyTool.cc.

Referenced by Run().

109 {
110  const MCParticle *const pMatchedMCParticle(pfoToMCParticleMap.at(pPfo));
111 
112  const float upstreamSepSq((pMatchedMCParticle->GetVertex() - upstreamVertex).GetMagnitudeSquared());
113  const float downstreamSepSq((pMatchedMCParticle->GetVertex() - downstreamVertex).GetMagnitudeSquared());
114 
115  return (upstreamSepSq < downstreamSepSq);
116 }
void lar_dl_content::DLCheatHierarchyTool::MatchPFParticles ( const pandora::Algorithm *const  pAlgorithm,
PfoToMCParticleMap pfoToMCParticleMap 
) const
private

Perform the pfo->MCParticle matching, folding back EM shower hierarchies.

Parameters
pAlgorithma pointer to the pandora algorithm
pfoToMCParticleMapthe pfo->MCParticle matching map

Definition at line 183 of file DLCheatHierarchyTool.cc.

References f, GetLeadEMParticle(), GetNSpacepoints(), IsEMParticle(), m_pfoListNames, and SumEnergy().

Referenced by FillHierarchyMap().

184 {
185  for (const std::string &pfoListName : m_pfoListNames)
186  {
187  const PfoList *pPfoList(nullptr);
188 
189  if (PandoraContentApi::GetList(*pAlgorithm, pfoListName, pPfoList) != STATUS_CODE_SUCCESS)
190  continue;
191 
192  if (!pPfoList)
193  continue;
194 
195  for (const ParticleFlowObject *pPfo : *pPfoList)
196  {
197  // Demand that we have 3D hits
198  if (this->GetNSpacepoints(pPfo) == 0)
199  continue;
200 
201  // Fill contribution map
203 
204  for (const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
205  {
206  CaloHitList caloHitList;
207  LArPfoHelper::GetCaloHits(pPfo, hitType, caloHitList);
208 
209  for (const CaloHit *const pCaloHit : caloHitList)
210  {
211  try
212  {
213  const MCParticle *pHitMCParticle(MCParticleHelper::GetMainMCParticle(pCaloHit));
214 
215  // Sometimes we have to fold back EM shower hierarchies
216  if (this->IsEMParticle(pHitMCParticle))
217  pHitMCParticle = this->GetLeadEMParticle(pHitMCParticle);
218 
219  contributionMap[pHitMCParticle].emplace_back(pCaloHit);
220  }
221  catch (...)
222  {
223  continue;
224  }
225  }
226  }
227 
228  // Work out who the match is
229  unsigned int highestHit(0);
230  float highestEnergy(-1.f);
231  const MCParticle *pMatchedMCParticle(nullptr);
232 
233  for (const auto &entry : contributionMap)
234  {
235  if (entry.second.size() > highestHit)
236  {
237  highestHit = entry.second.size();
238  highestEnergy = this->SumEnergy(entry.second);
239  pMatchedMCParticle = entry.first;
240  }
241  else if (entry.second.size() == highestHit)
242  {
243  const float totalEnergy(this->SumEnergy(entry.second));
244 
245  if (totalEnergy > highestEnergy)
246  {
247  highestHit = entry.second.size();
248  highestEnergy = totalEnergy;
249  pMatchedMCParticle = entry.first;
250  }
251  }
252  }
253 
254  if (!pMatchedMCParticle)
255  throw StatusCodeException(STATUS_CODE_FAILURE);
256 
257  pfoToMCParticleMap[pPfo] = pMatchedMCParticle;
258  }
259  }
260 }
pandora::StringVector m_pfoListNames
the vector of pfo list names
float SumEnergy(const pandora::CaloHitList &caloHitList) const
Sum the &#39;energy&#39; of the W hits in an input CaloHitList.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
TFile f
Definition: plotHisto.C:6
bool IsEMParticle(const pandora::MCParticle *const pMCParticle) const
Whether a MCParticle is an electron or photon.
HitType
Definition: HitType.h:12
float GetNSpacepoints(const pandora::ParticleFlowObject *const pPfo) const
Get the number of 3D hits owned by a pfo.
const pandora::MCParticle * GetLeadEMParticle(const pandora::MCParticle *const pMCParticle) const
Get the leading EM Particle in an EM MCParticle hierarchy.
StatusCode lar_dl_content::DLCheatHierarchyTool::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
private

Definition at line 540 of file DLCheatHierarchyTool.cc.

References m_mcParticleListName, m_neutrinoPfoListName, and m_pfoListNames.

541 {
542 
543  PANDORA_RETURN_RESULT_IF_AND_IF(
544  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
545 
546  PANDORA_RETURN_RESULT_IF_AND_IF(
547  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NeutrinoPfoListName", m_neutrinoPfoListName));
548 
549  PANDORA_RETURN_RESULT_IF_AND_IF(
550  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "PfoListNames", m_pfoListNames));
551 
552  return STATUS_CODE_SUCCESS;
553 }
pandora::StringVector m_pfoListNames
the vector of pfo list names
std::string m_neutrinoPfoListName
the neutrino pfo list name
std::string m_mcParticleListName
the MCParticle list name
StatusCode lar_dl_content::DLCheatHierarchyTool::Run ( const PfoToMCParticleMap pfoToMCParticleMap,
const ChildToParentPfoMap childToParentPfoMap,
const HierarchyPfo parentPfo,
const HierarchyPfo childPfo,
bool &  isTrueLink,
bool &  trueParentOrientation,
bool &  trueChildOrientation 
)

Definition at line 35 of file DLCheatHierarchyTool.cc.

References lar_dl_content::HierarchyPfo::GetDownstreamPoint(), lar_dl_content::HierarchyPfo::GetPfo(), lar_dl_content::ExtremalPoint::GetPosition(), lar_dl_content::HierarchyPfo::GetUpstreamPoint(), and IsUpstreamTrueVertex().

Referenced by lar_dl_content::DLNeutrinoHierarchyAlgorithm::BuildPandoraHierarchy().

37 {
38  // If we dont know the Pfo->MCParticle match
39  if ((pfoToMCParticleMap.find(parentPfo.GetPfo()) == pfoToMCParticleMap.end()) ||
40  (pfoToMCParticleMap.find(childPfo.GetPfo()) == pfoToMCParticleMap.end()))
41  {
42  return STATUS_CODE_NOT_FOUND;
43  }
44 
45  // If we dont know the true parentPfo
46  if (childToParentPfoMap.find(childPfo.GetPfo()) == childToParentPfoMap.end())
47  return STATUS_CODE_NOT_FOUND;
48 
49  isTrueLink = (childToParentPfoMap.at(childPfo.GetPfo()).first == parentPfo.GetPfo());
50 
51  // What is the true orientation of the parent?
52  trueParentOrientation = this->IsUpstreamTrueVertex(
53  pfoToMCParticleMap, parentPfo.GetPfo(), parentPfo.GetUpstreamPoint().GetPosition(), parentPfo.GetDownstreamPoint().GetPosition());
54 
55  // What is the true orientation of the child?
56  trueChildOrientation = this->IsUpstreamTrueVertex(
57  pfoToMCParticleMap, childPfo.GetPfo(), childPfo.GetUpstreamPoint().GetPosition(), childPfo.GetDownstreamPoint().GetPosition());
58 
59  return STATUS_CODE_SUCCESS;
60 }
bool IsUpstreamTrueVertex(const PfoToMCParticleMap &pfoToMCParticleMap, const pandora::ParticleFlowObject *const pPfo, const pandora::CartesianVector &upstreamVertex, const pandora::CartesianVector &downstreamVertex)
Whether the true startpoint of the particle is in the upstream position (i.e. the endpoint closest to...
StatusCode lar_dl_content::DLCheatHierarchyTool::Run ( const PfoToMCParticleMap pfoToMCParticleMap,
const ChildToParentPfoMap childToParentPfoMap,
const pandora::ParticleFlowObject *const  pNeutrinoPfo,
const HierarchyPfo childPfo,
bool &  isTrueLink,
bool &  trueChildOrientation 
)

Definition at line 64 of file DLCheatHierarchyTool.cc.

References lar_dl_content::HierarchyPfo::GetDownstreamPoint(), lar_dl_content::HierarchyPfo::GetPfo(), lar_dl_content::ExtremalPoint::GetPosition(), lar_dl_content::HierarchyPfo::GetUpstreamPoint(), and IsUpstreamTrueVertex().

66 {
67  // If we dont know the Pfo->MCParticle match
68  if (pfoToMCParticleMap.find(childPfo.GetPfo()) == pfoToMCParticleMap.end())
69  return STATUS_CODE_NOT_FOUND;
70 
71  // If we dont know the true parentPfo
72  if (childToParentPfoMap.find(childPfo.GetPfo()) == childToParentPfoMap.end())
73  return STATUS_CODE_NOT_FOUND;
74 
75  isTrueLink = (childToParentPfoMap.at(childPfo.GetPfo()).first == pNeutrinoPfo);
76 
77  // What is the true orientation of the child?
78  trueChildOrientation = this->IsUpstreamTrueVertex(
79  pfoToMCParticleMap, childPfo.GetPfo(), childPfo.GetUpstreamPoint().GetPosition(), childPfo.GetDownstreamPoint().GetPosition());
80 
81  return STATUS_CODE_SUCCESS;
82 }
bool IsUpstreamTrueVertex(const PfoToMCParticleMap &pfoToMCParticleMap, const pandora::ParticleFlowObject *const pPfo, const pandora::CartesianVector &upstreamVertex, const pandora::CartesianVector &downstreamVertex)
Whether the true startpoint of the particle is in the upstream position (i.e. the endpoint closest to...
float lar_dl_content::DLCheatHierarchyTool::SumEnergy ( const pandora::CaloHitList &  caloHitList) const
private

Sum the 'energy' of the W hits in an input CaloHitList.

Parameters
caloHitListthe input CaloHitList
Returns
the summed energy

Definition at line 315 of file DLCheatHierarchyTool.cc.

References f.

Referenced by MatchPFParticles().

316 {
317  float totalEnergy(0.f);
318 
319  for (const CaloHit *const pCaloHit : caloHitList)
320  {
321  if (pCaloHit->GetHitType() == TPC_VIEW_W)
322  totalEnergy += pCaloHit->GetElectromagneticEnergy();
323  }
324 
325  return totalEnergy;
326 }
TFile f
Definition: plotHisto.C:6

Member Data Documentation

std::string lar_dl_content::DLCheatHierarchyTool::m_mcParticleListName
private

the MCParticle list name

Definition at line 205 of file DLCheatHierarchyTool.h.

Referenced by GetMCParticleList(), and ReadSettings().

std::string lar_dl_content::DLCheatHierarchyTool::m_neutrinoPfoListName
private

the neutrino pfo list name

Definition at line 206 of file DLCheatHierarchyTool.h.

Referenced by GetNeutrinoPfo(), and ReadSettings().

pandora::StringVector lar_dl_content::DLCheatHierarchyTool::m_pfoListNames
private

the vector of pfo list names

Definition at line 207 of file DLCheatHierarchyTool.h.

Referenced by MatchPFParticles(), and ReadSettings().


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