LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArOverlapMatrix.cc
Go to the documentation of this file.
1 
9 #include "Pandora/PandoraInputTypes.h"
10 
11 #include "Pandora/PandoraInputTypes.h"
12 #include "Pandora/PandoraInternal.h"
13 #include "Pandora/StatusCodes.h"
14 
15 #include "Objects/Cluster.h"
16 
18 
21 
22 #include <algorithm>
23 
24 using namespace pandora;
25 
26 namespace lar_content
27 {
28 
29 template <typename T>
30 void 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 
62 template <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 
77 template <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();
85 }
86 
87 //------------------------------------------------------------------------------------------------------------------------------------------
88 
89 template <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 }
97 
98 //------------------------------------------------------------------------------------------------------------------------------------------
99 
100 template <typename T>
101 void 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 
123 template <typename T>
124 void 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 
141 template <typename T>
142 void OverlapMatrix<T>::RemoveCluster(const pandora::Cluster *const pCluster)
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);
152 
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 }
194 
195 //------------------------------------------------------------------------------------------------------------------------------------------
196 
197 template <typename T>
198 void 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);
203 
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)
210  {
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);
226  }
227  }
228 
229  std::sort(elementList.begin(), elementList.end());
230 }
231 
232 //------------------------------------------------------------------------------------------------------------------------------------------
233 
234 template <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 
268 template class OverlapMatrix<float>;
271 
272 } // namespace lar_content
intermediate_table::iterator iterator
intermediate_table::const_iterator const_iterator
std::vector< Element > ElementList
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
Header file for the lar overlap matrix class.
Header file for the cluster helper class.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterNavigationMap
std::unordered_map< const pandora::Cluster *, OverlapResult > OverlapList
HitType
Definition: HitType.h:12
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
std::vector< art::Ptr< recob::Cluster > > ClusterVector
Header file for the lar track two view overlap result class.
OverlapMatrix class.