DeltaRayParentAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArCosmicRay/DeltaRayParentAlgorithm.cc
3  *
4  * @brief Implementation of the delta ray parent algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 DeltaRayParentAlgorithm::DeltaRayParentAlgorithm() : m_distanceForMatching(5.f)
22 {
23 }
24 
25 //------------------------------------------------------------------------------------------------------------------------------------------
26 
28 {
29  const PfoList *pMuonPfoList(nullptr);
30  PANDORA_THROW_RESULT_IF_AND_IF(
31  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_muonPfoListName, pMuonPfoList));
32 
33  if (!pMuonPfoList || pMuonPfoList->empty())
34  return STATUS_CODE_SUCCESS;
35 
36  const PfoList *pDeltaRayPfoList(nullptr);
37  PANDORA_THROW_RESULT_IF_AND_IF(
38  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_deltaRayPfoListName, pDeltaRayPfoList));
39 
40  if (!pDeltaRayPfoList || pDeltaRayPfoList->empty())
41  return STATUS_CODE_SUCCESS;
42 
43  PfoLengthMap pfoLengthMap;
44  this->InitialisePfoLengthMap(pMuonPfoList, pDeltaRayPfoList, pfoLengthMap);
45 
46  PfoVector deltaRayPfoVector(pDeltaRayPfoList->begin(), pDeltaRayPfoList->end());
47  std::sort(deltaRayPfoVector.begin(), deltaRayPfoVector.end(), LArPfoHelper::SortByNHits);
48 
49  for (const ParticleFlowObject *const pPfo : deltaRayPfoVector)
50  {
51  if (!pPfo->GetParentPfoList().empty())
52  continue;
53 
54  const ParticleFlowObject *pParentPfo(nullptr);
55  this->FindParentPfo(pfoLengthMap, pPfo, pParentPfo);
56 
57  if (!pParentPfo)
58  continue;
59 
60  this->AssignToParentPfo(pMuonPfoList, pDeltaRayPfoList, pPfo, pParentPfo, pfoLengthMap);
61  }
62 
63  return STATUS_CODE_SUCCESS;
64 }
65 
66 //------------------------------------------------------------------------------------------------------------------------------------------
67 
68 void DeltaRayParentAlgorithm::InitialisePfoLengthMap(const PfoList *const muonPfoList, const PfoList *const deltaRayPfoList, PfoLengthMap &pfoLengthMap) const
69 {
70  for (const ParticleFlowObject *const pPfo : *muonPfoList)
71  pfoLengthMap[pPfo] = LArPfoHelper::GetTwoDLengthSquared(pPfo);
72 
73  for (const ParticleFlowObject *const pPfo : *deltaRayPfoList)
74  pfoLengthMap[pPfo] = LArPfoHelper::GetTwoDLengthSquared(pPfo);
75 }
76 
77 //------------------------------------------------------------------------------------------------------------------------------------------
78 
79 void DeltaRayParentAlgorithm::FindParentPfo(const PfoLengthMap &pfoLengthMap, const ParticleFlowObject *const pPfo, const ParticleFlowObject *&pParentPfo) const
80 {
81  const PfoLengthMap::const_iterator currentIter(pfoLengthMap.find(pPfo));
82 
83  if (currentIter == pfoLengthMap.end())
84  throw StatusCodeException(STATUS_CODE_FAILURE);
85 
86  PfoVector allPfoVector;
87 
88  for (auto &entry : pfoLengthMap)
89  allPfoVector.push_back(entry.first);
90 
91  const float lengthSquared(currentIter->second);
92  float bestDistance(m_distanceForMatching);
93 
94  for (const ParticleFlowObject *const pTestParent : allPfoVector)
95  {
96  if (pTestParent == pPfo)
97  continue;
98 
99  const PfoLengthMap::const_iterator testIter(pfoLengthMap.find(pTestParent));
100 
101  if (testIter == pfoLengthMap.end())
102  throw StatusCodeException(STATUS_CODE_FAILURE);
103 
104  if (testIter->second < lengthSquared)
105  continue;
106 
108 
109  if (this->GetTwoDSeparation(pPfo, pTestParent, distance) == STATUS_CODE_NOT_FOUND)
110  continue;
111 
112  if (distance < bestDistance)
113  {
114  pParentPfo = pTestParent;
115  bestDistance = distance;
116  }
117  }
118 }
119 
120 //------------------------------------------------------------------------------------------------------------------------------------------
121 
122 StatusCode DeltaRayParentAlgorithm::GetTwoDSeparation(const ParticleFlowObject *const pPfo1, const ParticleFlowObject *const pPfo2, float &separation) const
123 {
124  ClusterList clusterListU1, clusterListV1, clusterListW1;
125  ClusterList clusterListU2, clusterListV2, clusterListW2;
126 
127  LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_U, clusterListU1);
128  LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_V, clusterListV1);
129  LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_W, clusterListW1);
130 
131  LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_U, clusterListU2);
132  LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_V, clusterListV2);
133  LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_W, clusterListW2);
134 
135  float numViews(0.f), distance(0.f);
136 
137  if (!clusterListU1.empty() && !clusterListU2.empty())
138  {
139  distance += LArClusterHelper::GetClosestDistance(clusterListU1, clusterListU2);
140  numViews += 1.f;
141  }
142 
143  if (!clusterListV1.empty() && !clusterListV2.empty())
144  {
145  distance += LArClusterHelper::GetClosestDistance(clusterListV1, clusterListV2);
146  numViews += 1.f;
147  }
148 
149  if (!clusterListW1.empty() && !clusterListW2.empty())
150  {
151  distance += LArClusterHelper::GetClosestDistance(clusterListW1, clusterListW2);
152  numViews += 1.f;
153  }
154 
155  if (numViews < std::numeric_limits<float>::epsilon())
156  return STATUS_CODE_NOT_FOUND;
157 
158  separation = distance / numViews;
159 
160  return STATUS_CODE_SUCCESS;
161 }
162 
163 //------------------------------------------------------------------------------------------------------------------------------------------
164 
165 void DeltaRayParentAlgorithm::AssignToParentPfo(const PfoList *const pMuonPfoList, const PfoList *const pDeltaRayPfoList,
166  const ParticleFlowObject *const pPfo, const ParticleFlowObject *const pParentPfo, PfoLengthMap &pfoLengthMap) const
167 {
168  if (std::find(pMuonPfoList->begin(), pMuonPfoList->end(), pParentPfo) != pMuonPfoList->end())
169  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pParentPfo, pPfo));
170 
171  if (std::find(pDeltaRayPfoList->begin(), pDeltaRayPfoList->end(), pParentPfo) != pDeltaRayPfoList->end())
172  {
173  ClusterList pfoClusters;
174  LArPfoHelper::GetTwoDClusterList(pPfo, pfoClusters);
175 
176  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pPfo, m_deltaRayPfoListName));
177 
178  for (const Cluster *const pCluster : pfoClusters)
179  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pParentPfo, pCluster));
180 
181  this->UpdatePfoLengthMap({pPfo, pParentPfo}, pParentPfo, pfoLengthMap);
182  }
183 }
184 
185 //------------------------------------------------------------------------------------------------------------------------------------------
186 
187 void DeltaRayParentAlgorithm::UpdatePfoLengthMap(const PfoList &pfosToRemove, const ParticleFlowObject *const pPfoToAdd, PfoLengthMap &pfoLengthMap) const
188 {
189  for (const ParticleFlowObject *const pPfoToRemove : pfosToRemove)
190  {
191  const PfoLengthMap::const_iterator iter(pfoLengthMap.find(pPfoToRemove));
192 
193  if (iter == pfoLengthMap.end())
194  throw StatusCodeException(STATUS_CODE_FAILURE);
195 
196  pfoLengthMap.erase(iter);
197  }
198 
199  pfoLengthMap[pPfoToAdd] = LArPfoHelper::GetTwoDLengthSquared(pPfoToAdd);
200 }
201 
202 //------------------------------------------------------------------------------------------------------------------------------------------
203 
204 StatusCode DeltaRayParentAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
205 {
206  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MuonPfoListName", m_muonPfoListName));
207 
208  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "DeltaRayPfoListName", m_deltaRayPfoListName));
209 
210  PANDORA_RETURN_RESULT_IF_AND_IF(
211  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DistanceForMatching", m_distanceForMatching));
212 
213  return STATUS_CODE_SUCCESS;
214 }
215 
216 } // 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.
QList< Entry > entry
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.
QCollection::Item first()
Definition: qglist.cpp:807
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.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
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.