LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DeltaRayParentAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 DeltaRayParentAlgorithm::DeltaRayParentAlgorithm() :
22  m_distanceForMatching(5.f)
23 {
24 }
25 
26 //------------------------------------------------------------------------------------------------------------------------------------------
27 
29 {
30  const PfoList *pMuonPfoList(nullptr);
31  PANDORA_THROW_RESULT_IF_AND_IF(
32  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_muonPfoListName, pMuonPfoList));
33 
34  if (!pMuonPfoList || pMuonPfoList->empty())
35  return STATUS_CODE_SUCCESS;
36 
37  const PfoList *pDeltaRayPfoList(nullptr);
38  PANDORA_THROW_RESULT_IF_AND_IF(
39  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_deltaRayPfoListName, pDeltaRayPfoList));
40 
41  if (!pDeltaRayPfoList || pDeltaRayPfoList->empty())
42  return STATUS_CODE_SUCCESS;
43 
44  PfoLengthMap pfoLengthMap;
45  this->InitialisePfoLengthMap(pMuonPfoList, pDeltaRayPfoList, pfoLengthMap);
46 
47  PfoVector deltaRayPfoVector(pDeltaRayPfoList->begin(), pDeltaRayPfoList->end());
48  std::sort(deltaRayPfoVector.begin(), deltaRayPfoVector.end(), LArPfoHelper::SortByNHits);
49 
50  for (const ParticleFlowObject *const pPfo : deltaRayPfoVector)
51  {
52  if (!pPfo->GetParentPfoList().empty())
53  continue;
54 
55  const ParticleFlowObject *pParentPfo(nullptr);
56  this->FindParentPfo(pfoLengthMap, pPfo, pParentPfo);
57 
58  if (!pParentPfo)
59  continue;
60 
61  this->AssignToParentPfo(pMuonPfoList, pDeltaRayPfoList, pPfo, pParentPfo, pfoLengthMap);
62  }
63 
64  return STATUS_CODE_SUCCESS;
65 }
66 
67 //------------------------------------------------------------------------------------------------------------------------------------------
68 
69 void DeltaRayParentAlgorithm::InitialisePfoLengthMap(const PfoList *const muonPfoList, const PfoList *const deltaRayPfoList, PfoLengthMap &pfoLengthMap) const
70 {
71  for (const ParticleFlowObject *const pPfo : *muonPfoList)
72  pfoLengthMap[pPfo] = LArPfoHelper::GetTwoDLengthSquared(pPfo);
73 
74  for (const ParticleFlowObject *const pPfo : *deltaRayPfoList)
75  pfoLengthMap[pPfo] = LArPfoHelper::GetTwoDLengthSquared(pPfo);
76 }
77 
78 //------------------------------------------------------------------------------------------------------------------------------------------
79 
80 void DeltaRayParentAlgorithm::FindParentPfo(const PfoLengthMap &pfoLengthMap, const ParticleFlowObject *const pPfo, const ParticleFlowObject *&pParentPfo) const
81 {
82  const PfoLengthMap::const_iterator currentIter(pfoLengthMap.find(pPfo));
83 
84  if (currentIter == pfoLengthMap.end())
85  throw StatusCodeException(STATUS_CODE_FAILURE);
86 
87  PfoVector allPfoVector;
88 
89  for (auto &entry : pfoLengthMap)
90  allPfoVector.push_back(entry.first);
91 
92  const float lengthSquared(currentIter->second);
93  float bestDistance(m_distanceForMatching);
94 
95  for (const ParticleFlowObject *const pTestParent : allPfoVector)
96  {
97  if (pTestParent == pPfo)
98  continue;
99 
100  const PfoLengthMap::const_iterator testIter(pfoLengthMap.find(pTestParent));
101 
102  if (testIter == pfoLengthMap.end())
103  throw StatusCodeException(STATUS_CODE_FAILURE);
104 
105  if (testIter->second < lengthSquared)
106  continue;
107 
108  float distance(std::numeric_limits<float>::max());
109 
110  if (this->GetTwoDSeparation(pPfo, pTestParent, distance) == STATUS_CODE_NOT_FOUND)
111  continue;
112 
113  if (distance < bestDistance)
114  {
115  pParentPfo = pTestParent;
116  bestDistance = distance;
117  }
118  }
119 }
120 
121 //------------------------------------------------------------------------------------------------------------------------------------------
122 
123 StatusCode DeltaRayParentAlgorithm::GetTwoDSeparation(const ParticleFlowObject *const pPfo1, const ParticleFlowObject *const pPfo2, float &separation) const
124 {
125  ClusterList clusterListU1, clusterListV1, clusterListW1;
126  ClusterList clusterListU2, clusterListV2, clusterListW2;
127 
128  LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_U, clusterListU1);
129  LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_V, clusterListV1);
130  LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_W, clusterListW1);
131 
132  LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_U, clusterListU2);
133  LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_V, clusterListV2);
134  LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_W, clusterListW2);
135 
136  float numViews(0.f), distance(0.f);
137 
138  if (!clusterListU1.empty() && !clusterListU2.empty())
139  {
140  distance += LArClusterHelper::GetClosestDistance(clusterListU1, clusterListU2);
141  numViews += 1.f;
142  }
143 
144  if (!clusterListV1.empty() && !clusterListV2.empty())
145  {
146  distance += LArClusterHelper::GetClosestDistance(clusterListV1, clusterListV2);
147  numViews += 1.f;
148  }
149 
150  if (!clusterListW1.empty() && !clusterListW2.empty())
151  {
152  distance += LArClusterHelper::GetClosestDistance(clusterListW1, clusterListW2);
153  numViews += 1.f;
154  }
155 
156  if (numViews < std::numeric_limits<float>::epsilon())
157  return STATUS_CODE_NOT_FOUND;
158 
159  separation = distance / numViews;
160 
161  return STATUS_CODE_SUCCESS;
162 }
163 
164 //------------------------------------------------------------------------------------------------------------------------------------------
165 
166 void DeltaRayParentAlgorithm::AssignToParentPfo(const PfoList *const pMuonPfoList, const PfoList *const pDeltaRayPfoList,
167  const ParticleFlowObject *const pPfo, const ParticleFlowObject *const pParentPfo, PfoLengthMap &pfoLengthMap) const
168 {
169  if (std::find(pMuonPfoList->begin(), pMuonPfoList->end(), pParentPfo) != pMuonPfoList->end())
170  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pParentPfo, pPfo));
171 
172  if (std::find(pDeltaRayPfoList->begin(), pDeltaRayPfoList->end(), pParentPfo) != pDeltaRayPfoList->end())
173  {
174  ClusterList pfoClusters;
175  LArPfoHelper::GetTwoDClusterList(pPfo, pfoClusters);
176 
177  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pPfo, m_deltaRayPfoListName));
178 
179  for (const Cluster *const pCluster : pfoClusters)
180  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pParentPfo, pCluster));
181 
182  this->UpdatePfoLengthMap({pPfo, pParentPfo}, pParentPfo, pfoLengthMap);
183  }
184 }
185 
186 //------------------------------------------------------------------------------------------------------------------------------------------
187 
188 void DeltaRayParentAlgorithm::UpdatePfoLengthMap(const PfoList &pfosToRemove, const ParticleFlowObject *const pPfoToAdd, PfoLengthMap &pfoLengthMap) const
189 {
190  for (const ParticleFlowObject *const pPfoToRemove : pfosToRemove)
191  {
192  const PfoLengthMap::const_iterator iter(pfoLengthMap.find(pPfoToRemove));
193 
194  if (iter == pfoLengthMap.end())
195  throw StatusCodeException(STATUS_CODE_FAILURE);
196 
197  pfoLengthMap.erase(iter);
198  }
199 
200  pfoLengthMap[pPfoToAdd] = LArPfoHelper::GetTwoDLengthSquared(pPfoToAdd);
201 }
202 
203 //------------------------------------------------------------------------------------------------------------------------------------------
204 
205 StatusCode DeltaRayParentAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
206 {
207  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MuonPfoListName", m_muonPfoListName));
208 
209  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "DeltaRayPfoListName", m_deltaRayPfoListName));
210 
211  PANDORA_RETURN_RESULT_IF_AND_IF(
212  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DistanceForMatching", m_distanceForMatching));
213 
214  return STATUS_CODE_SUCCESS;
215 }
216 
217 } // namespace lar_content
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
pandora::StatusCode GetTwoDSeparation(const pandora::ParticleFlowObject *const pPfo1, const pandora::ParticleFlowObject *const pPfo2, float &separation) const
Get distance between two Pfos using 2D clusters.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
intermediate_table::const_iterator const_iterator
static float GetTwoDLengthSquared(const pandora::ParticleFlowObject *const pPfo)
Calculate length of Pfo using 2D clusters.
TFile f
Definition: plotHisto.C:6
Header file for the cluster helper class.
std::string m_muonPfoListName
The list of reconstructed muon pfos.
float m_distanceForMatching
The maximum separation of a delta ray pfo from its parent.
void AssignToParentPfo(const pandora::PfoList *const muonPfoList, const pandora::PfoList *const deltaRayPfoList, const pandora::ParticleFlowObject *const pPfo, const pandora::ParticleFlowObject *const pParentPfo, PfoLengthMap &pfoLengthMap) const
Apply parent-child link (if parent is a cosmic ray create parent-child link else merge the delta ray ...
void UpdatePfoLengthMap(const pandora::PfoList &pfosToRemove, const pandora::ParticleFlowObject *const pPfoToAdd, PfoLengthMap &pfoLengthMap) const
Update the pfo length map after a parent-child delta ray merge.
void FindParentPfo(const PfoLengthMap &pfoLengthMap, const pandora::ParticleFlowObject *const pPfo, const pandora::ParticleFlowObject *&pParentPfo) const
Identify the parent pfo of a given delta ray pfo (can be either a cosmic ray or delta ray pfo) ...
std::map< const pandora::ParticleFlowObject *, float > PfoLengthMap
void InitialisePfoLengthMap(const pandora::PfoList *const muonPfoList, const pandora::PfoList *const deltaRayPfoList, PfoLengthMap &pfoLengthMap) const
Initialise the delta ray pfo length map.
std::string m_deltaRayPfoListName
The list of reconstructed delta ray pfos.
Header file for the delta ray parent class.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.