Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArOverlapMatrix.cc
Go to the documentation of this file.
1
10
13#include "Pandora/StatusCodes.h"
14
15#include "Objects/Cluster.h"
16
18
21
22#include <algorithm>
23
24using namespace pandora;
25
26namespace lar_content
27{
28
29template <typename T>
30void OverlapMatrix<T>::GetUnambiguousElements(const bool ignoreUnavailable, ElementList &elementList) const
31{
32 for (typename TheMatrix::const_iterator iter1 = this->begin(), iter1End = this->end(); iter1 != iter1End; ++iter1)
33 {
34 ElementList tempElementList;
35 ClusterList clusterList1, clusterList2;
36 this->GetConnectedElements(iter1->first, ignoreUnavailable, tempElementList, clusterList1, clusterList2);
37
38 const Cluster *pCluster1(nullptr), *pCluster2(nullptr);
39 if (!this->DefaultAmbiguityFunction(clusterList1, clusterList2, pCluster1, pCluster2))
40 continue;
41
42 // ATTN With HIT_CUSTOM definitions, it is possible to navigate from different view 1 clusters to same combination
43 if (iter1->first != pCluster1)
44 continue;
45
46 if (!pCluster1 || !pCluster2)
47 continue;
48
49 typename OverlapList::const_iterator iter2 = iter1->second.find(pCluster2);
50 if (iter1->second.end() == iter2)
51 throw StatusCodeException(STATUS_CODE_FAILURE);
52
53 Element element(pCluster1, pCluster2, iter2->second);
54 elementList.push_back(element);
55 }
56
57 std::sort(elementList.begin(), elementList.end());
58}
59
60//------------------------------------------------------------------------------------------------------------------------------------------
61
62template <typename T>
64 const ClusterList &clusterList1, const ClusterList &clusterList2, const Cluster *&pCluster1, const Cluster *&pCluster2) const
65{
66 if ((1 != clusterList1.size()) || (1 != clusterList2.size()))
67 return false;
68
69 pCluster1 = *(clusterList1.begin());
70 pCluster2 = *(clusterList2.begin());
71
72 return true;
73}
74
75//------------------------------------------------------------------------------------------------------------------------------------------
76
77template <typename T>
79 const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList, unsigned int &n1, unsigned int &n2) const
80{
81 ClusterList clusterList1, clusterList2;
82 this->GetConnectedElements(pCluster, ignoreUnavailable, elementList, clusterList1, clusterList2);
83 n1 = clusterList1.size();
84 n2 = clusterList2.size();
86
87//------------------------------------------------------------------------------------------------------------------------------------------
88
89template <typename T>
91{
92 for (typename TheMatrix::const_iterator iter1 = this->begin(), iter1End = this->end(); iter1 != iter1End; ++iter1)
93 sortedKeyClusters.push_back(iter1->first);
94
95 std::sort(sortedKeyClusters.begin(), sortedKeyClusters.end(), LArClusterHelper::SortByNHits);
96}
98//------------------------------------------------------------------------------------------------------------------------------------------
99
100template <typename T>
101void OverlapMatrix<T>::SetOverlapResult(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const OverlapResult &overlapResult)
102{
103 OverlapList &overlapList = m_overlapMatrix[pCluster1];
104 typename OverlapList::const_iterator iter = overlapList.find(pCluster2);
105
106 if (overlapList.end() != iter)
107 throw pandora::StatusCodeException(pandora::STATUS_CODE_ALREADY_PRESENT);
108
109 if (!overlapList.insert(typename OverlapList::value_type(pCluster2, overlapResult)).second)
110 throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
111
112 ClusterList &navigation12(m_clusterNavigationMap12[pCluster1]);
113 ClusterList &navigation21(m_clusterNavigationMap21[pCluster2]);
114
115 if (navigation12.end() == std::find(navigation12.begin(), navigation12.end(), pCluster2))
116 navigation12.push_back(pCluster2);
117 if (navigation21.end() == std::find(navigation21.begin(), navigation21.end(), pCluster1))
118 navigation21.push_back(pCluster1);
119}
120
121//------------------------------------------------------------------------------------------------------------------------------------------
122
123template <typename T>
124void OverlapMatrix<T>::ReplaceOverlapResult(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const OverlapResult &overlapResult)
125{
126 typename TheMatrix::iterator iter1 = m_overlapMatrix.find(pCluster1);
127
128 if (m_overlapMatrix.end() == iter1)
129 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
130
131 typename OverlapList::iterator iter2 = iter1->second.find(pCluster2);
132
133 if (iter1->second.end() == iter2)
134 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
135
136 iter2->second = overlapResult;
137}
138
139//------------------------------------------------------------------------------------------------------------------------------------------
140
141template <typename T>
143{
144 ClusterList additionalRemovals;
145
146 if (m_clusterNavigationMap12.erase(pCluster) > 0)
147 {
148 typename TheMatrix::iterator iter = m_overlapMatrix.find(pCluster);
149
150 if (m_overlapMatrix.end() != iter)
151 m_overlapMatrix.erase(iter);
153 for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMap21.begin(); navIter != m_clusterNavigationMap21.end();)
154 {
155 ClusterNavigationMap::iterator thisIter = navIter++;
156 ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
157
158 if (thisIter->second.end() != listIter)
159 thisIter->second.erase(listIter);
160
161 if (thisIter->second.empty())
162 additionalRemovals.push_back(thisIter->first);
163 }
164 }
165
166 if (m_clusterNavigationMap21.erase(pCluster) > 0)
167 {
168 for (typename TheMatrix::iterator iter1 = m_overlapMatrix.begin(), iter1End = m_overlapMatrix.end(); iter1 != iter1End; ++iter1)
169 {
170 typename OverlapList::iterator iter = iter1->second.find(pCluster);
171
172 if (iter1->second.end() != iter)
173 iter1->second.erase(iter);
174 }
175
176 for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMap12.begin(); navIter != m_clusterNavigationMap12.end();)
177 {
178 ClusterNavigationMap::iterator thisIter = navIter++;
179 ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
180
181 if (thisIter->second.end() != listIter)
182 thisIter->second.erase(listIter);
183
184 if (thisIter->second.empty())
185 additionalRemovals.push_back(thisIter->first);
186 }
187 }
188
189 additionalRemovals.sort(LArClusterHelper::SortByNHits);
190
191 for (ClusterList::const_iterator iter = additionalRemovals.begin(), iterEnd = additionalRemovals.end(); iter != iterEnd; ++iter)
192 this->RemoveCluster(*iter);
193}
195//------------------------------------------------------------------------------------------------------------------------------------------
196
197template <typename T>
198void OverlapMatrix<T>::GetConnectedElements(const Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList,
199 ClusterList &clusterList1, ClusterList &clusterList2) const
200{
201 ClusterList localClusterList1, localClusterList2;
202 this->ExploreConnections(pCluster, ignoreUnavailable, localClusterList1, localClusterList2);
204 // ATTN Now need to check that all clusters received are from fully available matrix elements
205 elementList.clear();
206 clusterList1.clear();
207 clusterList2.clear();
208
209 for (typename TheMatrix::const_iterator iter1 = this->begin(), iter1End = this->end(); iter1 != iter1End; ++iter1)
211 if (localClusterList1.end() == std::find(localClusterList1.begin(), localClusterList1.end(), iter1->first))
212 continue;
213
214 for (typename OverlapList::const_iterator iter2 = iter1->second.begin(), iter2End = iter1->second.end(); iter2 != iter2End; ++iter2)
215 {
216 if (ignoreUnavailable && (!iter1->first->IsAvailable() || !iter2->first->IsAvailable()))
217 continue;
218
219 Element element(iter1->first, iter2->first, iter2->second);
220 elementList.push_back(element);
221
222 if (clusterList1.end() == std::find(clusterList1.begin(), clusterList1.end(), iter1->first))
223 clusterList1.push_back(iter1->first);
224 if (clusterList2.end() == std::find(clusterList2.begin(), clusterList2.end(), iter2->first))
225 clusterList2.push_back(iter2->first);
227 }
228
229 std::sort(elementList.begin(), elementList.end());
230}
231
232//------------------------------------------------------------------------------------------------------------------------------------------
233
234template <typename T>
236 const Cluster *const pCluster, const bool ignoreUnavailable, ClusterList &clusterList1, ClusterList &clusterList2) const
237{
238 if (ignoreUnavailable && !pCluster->IsAvailable())
239 return;
240
241 const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
242 const bool clusterFromView1(
243 !m_clusterNavigationMap12.empty() && (LArClusterHelper::GetClusterHitType(m_clusterNavigationMap12.begin()->first) == hitType));
244 const bool clusterFromView2(
245 !m_clusterNavigationMap21.empty() && (LArClusterHelper::GetClusterHitType(m_clusterNavigationMap21.begin()->first) == hitType));
246
247 if (clusterFromView1 == clusterFromView2)
248 throw StatusCodeException(STATUS_CODE_FAILURE);
249
250 ClusterList &clusterList(clusterFromView1 ? clusterList1 : clusterList2);
251 const ClusterNavigationMap &navigationMap(clusterFromView1 ? m_clusterNavigationMap12 : m_clusterNavigationMap21);
252
253 if (clusterList.end() != std::find(clusterList.begin(), clusterList.end(), pCluster))
254 return;
255
256 clusterList.push_back(pCluster);
257 ClusterNavigationMap::const_iterator iter = navigationMap.find(pCluster);
258
259 if (navigationMap.end() == iter)
260 throw StatusCodeException(STATUS_CODE_FAILURE);
261
262 for (ClusterList::const_iterator cIter = iter->second.begin(), cIterEnd = iter->second.end(); cIter != cIterEnd; ++cIter)
263 this->ExploreConnections(*cIter, ignoreUnavailable, clusterList1, clusterList2);
264}
265
266//------------------------------------------------------------------------------------------------------------------------------------------
267
268template class OverlapMatrix<float>;
271
272} // namespace lar_content
Header file for the cluster class.
Header file for the cluster helper class.
Header file for the lar overlap matrix class.
Header file for the lar track two view overlap result class.
Header file for pandora input types and associated external typedefs exposed via the PandoraApi.
Header file defining relevant internal typedefs, sort and string conversion functions.
Header file defining status codes and relevant preprocessor macros.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position,...
bool DefaultAmbiguityFunction(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2, const pandora::Cluster *&pCluster1, const pandora::Cluster *&pCluster2) const
Default ambiguity function, checking that only one cluster from view 1 and view 2 is found.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterNavigationMap
void SetOverlapResult(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const OverlapResult &overlapResult)
Set overlap result.
std::vector< Element > ElementList
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (view 1 clusters with current implementation)
std::unordered_map< const pandora::Cluster *, OverlapResult > OverlapList
void ExploreConnections(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, pandora::ClusterList &clusterList1, pandora::ClusterList &clusterList2) const
Explore connections associated with a given cluster.
void RemoveCluster(const pandora::Cluster *const pCluster)
Remove entries from matrix corresponding to specified cluster.
void GetUnambiguousElements(const bool ignoreUnavailable, ElementList &elementList) const
Get unambiguous elements.
void ReplaceOverlapResult(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const OverlapResult &overlapResult)
SetReplace an existing overlap result.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
Cluster class.
Definition Cluster.h:31
bool IsAvailable() const
Whether the cluster is available to be added to a particle flow object.
Definition Cluster.h:582
StatusCodeException class.
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList