LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
LArOverlapTensor.cc
Go to the documentation of this file.
1 
9 #include "Pandora/PandoraInputTypes.h"
10 
11 #include "Pandora/PandoraInternal.h"
12 #include "Pandora/PandoraInputTypes.h"
13 #include "Pandora/StatusCodes.h"
14 
15 #include "Objects/Cluster.h"
16 
18 
22 
23 #include <algorithm>
24 
25 using namespace pandora;
26 
27 namespace lar_content
28 {
29 
30 template <typename T>
31 void OverlapTensor<T>::GetUnambiguousElements(const bool ignoreUnavailable, ElementList &elementList) const
32 {
33  for (typename TheTensor::const_iterator iterU = this->begin(), iterUEnd = this->end(); iterU != iterUEnd; ++iterU)
34  {
35  ElementList tempElementList;
36  ClusterList clusterListU, clusterListV, clusterListW;
37  this->GetConnectedElements(iterU->first, ignoreUnavailable, tempElementList, clusterListU, clusterListV, clusterListW);
38 
39  const Cluster *pClusterU(NULL), *pClusterV(NULL), *pClusterW(NULL);
40  if (!this->DefaultAmbiguityFunction(clusterListU, clusterListV, clusterListW, pClusterU, pClusterV, pClusterW))
41  continue;
42 
43  // ATTN With HIT_CUSTOM definitions, it is possible to navigate from different U clusters to same combination
44  if (iterU->first != pClusterU)
45  continue;
46 
47  if ((NULL == pClusterU) || (NULL == pClusterV) || (NULL == pClusterW))
48  continue;
49 
50  typename OverlapMatrix::const_iterator iterV = iterU->second.find(pClusterV);
51  if (iterU->second.end() == iterV)
52  throw StatusCodeException(STATUS_CODE_FAILURE);
53 
54  typename OverlapList::const_iterator iterW = iterV->second.find(pClusterW);
55  if (iterV->second.end() == iterW)
56  throw StatusCodeException(STATUS_CODE_FAILURE);
57 
58  Element element(pClusterU, pClusterV, pClusterW, iterW->second);
59  elementList.push_back(element);
60  }
61 
62  std::sort(elementList.begin(), elementList.end());
63 }
64 
65 //------------------------------------------------------------------------------------------------------------------------------------------
66 
67 template <typename T>
68 bool OverlapTensor<T>::DefaultAmbiguityFunction(const ClusterList &clusterListU, const ClusterList &clusterListV, const ClusterList &clusterListW,
69  const Cluster *&pClusterU, const Cluster *&pClusterV, const Cluster *&pClusterW) const
70 {
71  if ((1 != clusterListU.size()) || (1 != clusterListV.size()) || (1 != clusterListW.size()))
72  return false;
73 
74  pClusterU = *(clusterListU.begin());
75  pClusterV = *(clusterListV.begin());
76  pClusterW = *(clusterListW.begin());
77 
78  return true;
79 }
80 
81 //------------------------------------------------------------------------------------------------------------------------------------------
82 
83 template <typename T>
84 void OverlapTensor<T>::GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList,
85  unsigned int &nU, unsigned int &nV, unsigned int &nW) const
86 {
87  ClusterList clusterListU, clusterListV, clusterListW;
88  this->GetConnectedElements(pCluster, ignoreUnavailable, elementList, clusterListU, clusterListV, clusterListW);
89  nU = clusterListU.size(); nV = clusterListV.size(); nW = clusterListW.size();
90 }
91 
92 //------------------------------------------------------------------------------------------------------------------------------------------
93 
94 template <typename T>
96 {
97  for (typename TheTensor::const_iterator iterU = this->begin(), iterUEnd = this->end(); iterU != iterUEnd; ++iterU)
98  sortedKeyClusters.push_back(iterU->first);
99 
100  std::sort(sortedKeyClusters.begin(), sortedKeyClusters.end(), LArClusterHelper::SortByNHits);
101 }
102 
103 //------------------------------------------------------------------------------------------------------------------------------------------
104 
105 template <typename T>
106 void OverlapTensor<T>::SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV,
107  const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
108 {
109  OverlapList &overlapList = m_overlapTensor[pClusterU][pClusterV];
110  typename OverlapList::const_iterator iter = overlapList.find(pClusterW);
111 
112  if (overlapList.end() != iter)
113  throw pandora::StatusCodeException(pandora::STATUS_CODE_ALREADY_PRESENT);
114 
115  if (!overlapList.insert(typename OverlapList::value_type(pClusterW, overlapResult)).second)
116  throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
117 
118  ClusterList &navigationUV(m_clusterNavigationMapUV[pClusterU]);
119  ClusterList &navigationVW(m_clusterNavigationMapVW[pClusterV]);
120  ClusterList &navigationWU(m_clusterNavigationMapWU[pClusterW]);
121 
122  if (navigationUV.end() == std::find(navigationUV.begin(), navigationUV.end(), pClusterV)) navigationUV.push_back(pClusterV);
123  if (navigationVW.end() == std::find(navigationVW.begin(), navigationVW.end(), pClusterW)) navigationVW.push_back(pClusterW);
124  if (navigationWU.end() == std::find(navigationWU.begin(), navigationWU.end(), pClusterU)) navigationWU.push_back(pClusterU);
125 }
126 
127 //------------------------------------------------------------------------------------------------------------------------------------------
128 
129 template <typename T>
130 void OverlapTensor<T>::ReplaceOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV,
131  const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
132 {
133  typename TheTensor::iterator iterU = m_overlapTensor.find(pClusterU);
134 
135  if (m_overlapTensor.end() == iterU)
136  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
137 
138  typename OverlapMatrix::iterator iterV = iterU->second.find(pClusterV);
139 
140  if (iterU->second.end() == iterV)
141  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
142 
143  typename OverlapList::iterator iterW = iterV->second.find(pClusterW);
144 
145  if (iterV->second.end() == iterW)
146  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
147 
148  iterW->second = overlapResult;
149 }
150 
151 //------------------------------------------------------------------------------------------------------------------------------------------
152 
153 template <typename T>
154 void OverlapTensor<T>::RemoveCluster(const pandora::Cluster *const pCluster)
155 {
156  ClusterList additionalRemovals;
157 
158  if (m_clusterNavigationMapUV.erase(pCluster) > 0)
159  {
160  typename TheTensor::iterator iter = m_overlapTensor.find(pCluster);
161 
162  if (m_overlapTensor.end() != iter)
163  m_overlapTensor.erase(iter);
164 
165  for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMapWU.begin(); navIter != m_clusterNavigationMapWU.end(); )
166  {
167  ClusterNavigationMap::iterator thisIter = navIter++;
168  ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
169 
170  if (thisIter->second.end() != listIter)
171  thisIter->second.erase(listIter);
172 
173  if (thisIter->second.empty())
174  additionalRemovals.push_back(thisIter->first);
175  }
176  }
177 
178  if (m_clusterNavigationMapVW.erase(pCluster) > 0)
179  {
180  for (typename TheTensor::iterator iterU = m_overlapTensor.begin(), iterUEnd = m_overlapTensor.end(); iterU != iterUEnd; ++iterU)
181  {
182  typename OverlapMatrix::iterator iter = iterU->second.find(pCluster);
183 
184  if (iterU->second.end() != iter)
185  iterU->second.erase(iter);
186  }
187 
188  for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMapUV.begin(); navIter != m_clusterNavigationMapUV.end(); )
189  {
190  ClusterNavigationMap::iterator thisIter = navIter++;
191  ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
192 
193  if (thisIter->second.end() != listIter)
194  thisIter->second.erase(listIter);
195 
196  if (thisIter->second.empty())
197  additionalRemovals.push_back(thisIter->first);
198  }
199  }
200 
201  if (m_clusterNavigationMapWU.erase(pCluster) > 0)
202  {
203  for (typename TheTensor::iterator iterU = m_overlapTensor.begin(), iterUEnd = m_overlapTensor.end(); iterU != iterUEnd; ++iterU)
204  {
205  for (typename OverlapMatrix::iterator iterV = iterU->second.begin(), iterVEnd = iterU->second.end(); iterV != iterVEnd; ++iterV)
206  {
207  typename OverlapList::iterator iter = iterV->second.find(pCluster);
208 
209  if (iterV->second.end() != iter)
210  iterV->second.erase(iter);
211  }
212  }
213 
214  for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMapVW.begin(); navIter != m_clusterNavigationMapVW.end(); )
215  {
216  ClusterNavigationMap::iterator thisIter = navIter++;
217  ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
218 
219  if (thisIter->second.end() != listIter)
220  thisIter->second.erase(listIter);
221 
222  if (thisIter->second.empty())
223  additionalRemovals.push_back(thisIter->first);
224  }
225  }
226 
227  additionalRemovals.sort(LArClusterHelper::SortByNHits);
228 
229  for (ClusterList::const_iterator iter = additionalRemovals.begin(), iterEnd = additionalRemovals.end(); iter != iterEnd; ++iter)
230  this->RemoveCluster(*iter);
231 }
232 
233 //------------------------------------------------------------------------------------------------------------------------------------------
234 
235 template <typename T>
236 void OverlapTensor<T>::GetConnectedElements(const Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList,
237  ClusterList &clusterListU, ClusterList &clusterListV, ClusterList &clusterListW) const
238 {
239  ClusterList localClusterListU, localClusterListV, localClusterListW;
240  this->ExploreConnections(pCluster, ignoreUnavailable, localClusterListU, localClusterListV, localClusterListW);
241 
242  // ATTN Now need to check that all clusters received are from fully available tensor elements
243  elementList.clear(); clusterListU.clear(); clusterListV.clear(); clusterListW.clear();
244 
245  for (typename TheTensor::const_iterator iterU = this->begin(), iterUEnd = this->end(); iterU != iterUEnd; ++iterU)
246  {
247  if (localClusterListU.end() == std::find(localClusterListU.begin(), localClusterListU.end(), iterU->first))
248  continue;
249 
250  for (typename OverlapMatrix::const_iterator iterV = iterU->second.begin(), iterVEnd = iterU->second.end(); iterV != iterVEnd; ++iterV)
251  {
252  for (typename OverlapList::const_iterator iterW = iterV->second.begin(), iterWEnd = iterV->second.end(); iterW != iterWEnd; ++iterW)
253  {
254  if (ignoreUnavailable && (!iterU->first->IsAvailable() || !iterV->first->IsAvailable() || !iterW->first->IsAvailable()))
255  continue;
256 
257  Element element(iterU->first, iterV->first, iterW->first, iterW->second);
258  elementList.push_back(element);
259 
260  if (clusterListU.end() == std::find(clusterListU.begin(), clusterListU.end(), iterU->first)) clusterListU.push_back(iterU->first);
261  if (clusterListV.end() == std::find(clusterListV.begin(), clusterListV.end(), iterV->first)) clusterListV.push_back(iterV->first);
262  if (clusterListW.end() == std::find(clusterListW.begin(), clusterListW.end(), iterW->first)) clusterListW.push_back(iterW->first);
263  }
264  }
265  }
266 
267  std::sort(elementList.begin(), elementList.end());
268 }
269 
270 //------------------------------------------------------------------------------------------------------------------------------------------
271 
272 template <typename T>
273 void OverlapTensor<T>::ExploreConnections(const Cluster *const pCluster, const bool ignoreUnavailable, ClusterList &clusterListU,
274  ClusterList &clusterListV, ClusterList &clusterListW) const
275 {
276  if (ignoreUnavailable && !pCluster->IsAvailable())
277  return;
278 
279  const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
280 
281  if (!((TPC_VIEW_U == hitType) || (TPC_VIEW_V == hitType) || (TPC_VIEW_W == hitType)))
282  throw StatusCodeException(STATUS_CODE_FAILURE);
283 
284  ClusterList &clusterList((TPC_VIEW_U == hitType) ? clusterListU : (TPC_VIEW_V == hitType) ? clusterListV : clusterListW);
285  const ClusterNavigationMap &navigationMap((TPC_VIEW_U == hitType) ? m_clusterNavigationMapUV : (TPC_VIEW_V == hitType) ? m_clusterNavigationMapVW : m_clusterNavigationMapWU);
286 
287  if (clusterList.end() != std::find(clusterList.begin(), clusterList.end(), pCluster))
288  return;
289 
290  clusterList.push_back(pCluster);
291  ClusterNavigationMap::const_iterator iter = navigationMap.find(pCluster);
292 
293  if (navigationMap.end() == iter)
294  throw StatusCodeException(STATUS_CODE_FAILURE);
295 
296  for (ClusterList::const_iterator cIter = iter->second.begin(), cIterEnd = iter->second.end(); cIter != cIterEnd; ++cIter)
297  this->ExploreConnections(*cIter, ignoreUnavailable, clusterListU, clusterListV, clusterListW);
298 }
299 
300 //------------------------------------------------------------------------------------------------------------------------------------------
301 
302 template class OverlapTensor<float>;
307 
308 } // namespace lar_content
OverlapTensor class.
Header file for the lar overlap tensor class.
intermediate_table::iterator iterator
std::unordered_map< const pandora::Cluster *, OverlapResult > OverlapList
std::vector< Element > ElementList
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
Header file for the lar shower overlap result class.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
Header file for the lar track overlap result class.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterNavigationMap
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)