LArSoft  v10_06_00
Liquid Argon Software toolkit - https://larsoft.org/
DLCheatHierarchyTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 #include "Pandora/StatusCodes.h"
11 
15 
17 
19 
20 using namespace pandora;
21 using namespace lar_content;
22 
23 namespace lar_dl_content
24 {
25 
26 DLCheatHierarchyTool::DLCheatHierarchyTool() :
27  m_mcParticleListName("Input"),
28  m_neutrinoPfoListName("NeutrinoParticles3D"),
29  m_pfoListNames({"TrackParticles3D", "ShowerParticles3D"})
30 {
31 }
32 
33 //------------------------------------------------------------------------------------------------------------------------------------------
34 
35 StatusCode DLCheatHierarchyTool::Run(const PfoToMCParticleMap &pfoToMCParticleMap, const ChildToParentPfoMap &childToParentPfoMap,
36  const HierarchyPfo &parentPfo, const HierarchyPfo &childPfo, bool &isTrueLink, bool &trueParentOrientation, bool &trueChildOrientation)
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 }
61 
62 //------------------------------------------------------------------------------------------------------------------------------------------
63 
64 StatusCode DLCheatHierarchyTool::Run(const PfoToMCParticleMap &pfoToMCParticleMap, const ChildToParentPfoMap &childToParentPfoMap,
65  const ParticleFlowObject *const pNeutrinoPfo, const HierarchyPfo &childPfo, bool &isTrueLink, bool &trueChildOrientation)
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 }
83 
84 //------------------------------------------------------------------------------------------------------------------------------------------
85 
86 StatusCode DLCheatHierarchyTool::IsNeutronChild(const ParticleFlowObject *const pPfo, const PfoToMCParticleMap &pfoToMCParticleMap, bool &isNeutronChild) const
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 }
104 
105 //------------------------------------------------------------------------------------------------------------------------------------------
106 
107 bool DLCheatHierarchyTool::IsUpstreamTrueVertex(const PfoToMCParticleMap &pfoToMCParticleMap, const ParticleFlowObject *const pPfo,
108  const CartesianVector &upstreamVertex, const CartesianVector &downstreamVertex)
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 }
117 
118 //------------------------------------------------------------------------------------------------------------------------------------------
119 
121  const Algorithm *const pAlgorithm, PfoToMCParticleMap &pfoToMCParticleMap, ChildToParentPfoMap &childToParentPfoMap) const
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 }
146 
147 //------------------------------------------------------------------------------------------------------------------------------------------
148 
149 bool DLCheatHierarchyTool::GetMCParticleList(const Algorithm *const pAlgorithm, const MCParticleList *&pMCParticleList) const
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 }
159 
160 //------------------------------------------------------------------------------------------------------------------------------------------
161 
162 bool DLCheatHierarchyTool::GetNeutrinoPfo(const Algorithm *const pAlgorithm, const ParticleFlowObject *&pNeutrinoPfo) const
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 }
180 
181 //------------------------------------------------------------------------------------------------------------------------------------------
182 
183 void DLCheatHierarchyTool::MatchPFParticles(const Algorithm *const pAlgorithm, PfoToMCParticleMap &pfoToMCParticleMap) const
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 }
261 
262 //------------------------------------------------------------------------------------------------------------------------------------------
263 
264 float DLCheatHierarchyTool::GetNSpacepoints(const ParticleFlowObject *const pPfo) const
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 }
276 
277 //------------------------------------------------------------------------------------------------------------------------------------------
278 
279 bool DLCheatHierarchyTool::IsEMParticle(const MCParticle *const pMCParticle) const
280 {
281  return ((pMCParticle->GetParticleId() == 22) || (std::abs(pMCParticle->GetParticleId()) == 11));
282 }
283 
284 //------------------------------------------------------------------------------------------------------------------------------------------
285 
286 const MCParticle *DLCheatHierarchyTool::GetLeadEMParticle(const MCParticle *const pMCParticle) const
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 }
312 
313 //------------------------------------------------------------------------------------------------------------------------------------------
314 
315 float DLCheatHierarchyTool::SumEnergy(const CaloHitList &caloHitList) const
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 }
327 
328 //------------------------------------------------------------------------------------------------------------------------------------------
329 
330 void DLCheatHierarchyTool::GetVisibleMCHierarchy(const PfoToMCParticleMap &pfoToMCParticleMap, MCToMCMap &childToParentMCMap) const
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 }
367 
368 //------------------------------------------------------------------------------------------------------------------------------------------
369 
370 void DLCheatHierarchyTool::GetVisiblePfoHierarchy(const ParticleFlowObject *const pNeutrinoPfo,
371  const PfoToMCParticleMap &pfoToMCParticleMap, const MCToMCMap &childToParentMCMap, ChildToParentPfoMap &childToParentPfoMap) const
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 }
430 
431 //------------------------------------------------------------------------------------------------------------------------------------------
432 
433 void DLCheatHierarchyTool::BuildSplitHierarchy(const std::pair<const MCParticle *, PfoList> &splitPfo, ChildToParentPfoMap &childToParentPfoMap) const
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 }
480 
481 //------------------------------------------------------------------------------------------------------------------------------------------
482 
483 float DLCheatHierarchyTool::GetClosestDistance(const ParticleFlowObject *const pPfo1, const ParticleFlowObject *const pPfo2) const
484 {
485  ClusterList clusterList1, clusterList2;
486  LArPfoHelper::GetThreeDClusterList(pPfo1, clusterList1);
487  LArPfoHelper::GetThreeDClusterList(pPfo2, clusterList2);
488 
489  return LArClusterHelper::GetClosestDistance(clusterList1, clusterList2);
490 }
491 
492 //------------------------------------------------------------------------------------------------------------------------------------------
493 
494 const ParticleFlowObject *DLCheatHierarchyTool::BestParentInSplitHierarchy(const ParticleFlowObject *const pChildPfo, const PfoList &splitParticle) const
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 }
518 
519 //------------------------------------------------------------------------------------------------------------------------------------------
520 
522  const ParticleFlowObject *const pParentPfo, const int generationToFind, ChildToParentPfoMap &childToParentPfoMap) const
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 }
537 
538 //------------------------------------------------------------------------------------------------------------------------------------------
539 
540 StatusCode DLCheatHierarchyTool::ReadSettings(const TiXmlHandle xmlHandle)
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 }
554 
555 //------------------------------------------------------------------------------------------------------------------------------------------
556 
557 } // namespace lar_dl_content
std::map< const pandora::ParticleFlowObject *, std::pair< const pandora::ParticleFlowObject *, int > > ChildToParentPfoMap
pandora::StringVector m_pfoListNames
the vector of pfo list names
HierarchyPfo class.
Header file for the pfo helper class.
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)...
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
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const pandora::ParticleFlowObject * GetPfo() const
Get the pfo.
std::map< const pandora::MCParticle *, const pandora::MCParticle * > MCToMCMap
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 t...
void GetVisibleMCHierarchy(const PfoToMCParticleMap &pfoToMCParticleMap, MCToMCMap &childToParentMCMap) const
Determine the true child->parent MCParticle visible matches.
Header file for the HierarchyPfo class.
constexpr auto abs(T v)
Returns the absolute value of the argument.
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...
pandora::StatusCode Run(const PfoToMCParticleMap &pfoToMCParticleMap, const ChildToParentPfoMap &childToParentPfoMap, const HierarchyPfo &parentPfo, const HierarchyPfo &childPfo, bool &isTrueLink, bool &trueParentOrientation, bool &trueChildOrientation)
std::string m_neutrinoPfoListName
the neutrino pfo list name
void MatchPFParticles(const pandora::Algorithm *const pAlgorithm, PfoToMCParticleMap &pfoToMCParticleMap) const
Perform the pfo->MCParticle matching, folding back EM shower hierarchies.
TFile f
Definition: plotHisto.C:6
Header file for the cheat hierarchy tool.
bool IsEMParticle(const pandora::MCParticle *const pMCParticle) const
Whether a MCParticle is an electron or photon.
const ExtremalPoint & GetUpstreamPoint() const
Get the upstream extremal point.
Header file for the lar monte carlo particle helper helper class.
Header file for the cluster helper class.
const ExtremalPoint & GetDownstreamPoint() const
Get the downstream extremal point.
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.
std::string m_mcParticleListName
the MCParticle list name
const pandora::CartesianVector & GetPosition() const
Get the position.
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 GetClosestDistance(const pandora::ParticleFlowObject *const pPfo1, const pandora::ParticleFlowObject *const pPfo2) const
Determine the closest distance between two pfos.
void GetVisiblePfoHierarchy(const pandora::ParticleFlowObject *const pNeutrinoPfo, const PfoToMCParticleMap &pfoToMCParticleMap, const MCToMCMap &childToParentMCMap, ChildToParentPfoMap &childToParentPfoMap) const
Determine the true child->parent pfo visible matches.
HitType
Definition: HitType.h:12
float GetNSpacepoints(const pandora::ParticleFlowObject *const pPfo) const
Get the number of 3D hits owned by a pfo.
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...
std::map< const pandora::ParticleFlowObject *, const pandora::MCParticle * > PfoToMCParticleMap
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.
const pandora::MCParticle * GetLeadEMParticle(const pandora::MCParticle *const pMCParticle) const
Get the leading EM Particle in an EM MCParticle hierarchy.