LArOverlapTensor.h
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArObjects/LArOverlapTensor.h
3  *
4  * @brief Header file for the lar overlap tensor class.
5  *
6  * $Log: $
7  */
8 #ifndef LAR_OVERLAP_TENSOR_H
9 #define LAR_OVERLAP_TENSOR_H 1
10 
11 #include "Pandora/PandoraInternal.h"
12 
13 #include <unordered_map>
14 #include <vector>
15 
16 namespace lar_content
17 {
18 
19 /**
20  * @brief OverlapTensor class
21  */
22 template <typename T>
24 {
25 public:
26  typedef T OverlapResult;
27 
28  /**
29  * @brief Element class
30  */
31  class Element
32  {
33  public:
34  /**
35  * @brief Constructor
36  *
37  * @param pClusterU the address of the u cluster
38  * @param pClusterV the address of the v cluster
39  * @param pClusterW the address of the w cluster
40  * @param overlapResult the overlap result
41  */
42  Element(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW,
43  const OverlapResult &overlapResult);
44 
45  /**
46  * @brief Get the address of the given hit type cluster
47  *
48  * @param hitType hit type of the required cluster
49  *
50  * @return address of the required cluster
51  */
52  const pandora::Cluster *GetCluster(const pandora::HitType hitType) const;
53 
54  /**
55  * @brief Get the address of the u cluster
56  *
57  * @return address of the u cluster
58  */
59  const pandora::Cluster *GetClusterU() const;
60 
61  /**
62  * @brief Get the address of the v cluster
63  *
64  * @return address of the v cluster
65  */
66  const pandora::Cluster *GetClusterV() const;
67 
68  /**
69  * @brief Get the address of the w cluster
70  *
71  * @return address of the w cluster
72  */
73  const pandora::Cluster *GetClusterW() const;
74 
75  /**
76  * @brief Get the overlap result
77  *
78  * @return the overlap result
79  */
80  const OverlapResult &GetOverlapResult() const;
81 
82  /**
83  * @brief Element less than operator
84  *
85  * @param rhs the element for comparison
86  */
87  bool operator<(const Element &rhs) const;
88 
89  private:
90  const pandora::Cluster *m_pClusterU; ///< The address of the u cluster
91  const pandora::Cluster *m_pClusterV; ///< The address of the v cluster
92  const pandora::Cluster *m_pClusterW; ///< The address of the w cluster
93  OverlapResult m_overlapResult; ///< The overlap result
94  };
95 
96  typedef std::vector<Element> ElementList;
97 
98  /**
99  * @brief Get unambiguous elements
100  *
101  * @param ignoreUnavailable whether to ignore unavailable clusters
102  * @param elementList to receive the unambiguous element list
103  */
104  void GetUnambiguousElements(const bool ignoreUnavailable, ElementList &elementList) const;
105 
106  /**
107  * @brief Default ambiguity function, checking that only one U, V and W cluster is found
108  *
109  * @param clusterListU cluster list U
110  * @param clusterListV cluster list V
111  * @param clusterListW cluster list W
112  * @param pClusterU to receive the address of the unambiguous U cluster
113  * @param pClusterV to receive the address of the unambiguous V cluster
114  * @param pClusterW to receive the address of the unambiguous W cluster
115  *
116  * @return boolean
117  */
118  bool DefaultAmbiguityFunction(const pandora::ClusterList &clusterListU, const pandora::ClusterList &clusterListV,
119  const pandora::ClusterList &clusterListW, const pandora::Cluster *&pClusterU, const pandora::Cluster *&pClusterV,
120  const pandora::Cluster *&pClusterW) const;
121 
122  /**
123  * @brief Get the number of connections for a specified cluster
124  *
125  * @param pCluster address of a cluster
126  * @param ignoreUnavailable whether to ignore unavailable clusters
127  * @param nU to receive the number of u connections
128  * @param nV to receive the number of v connections
129  * @param nW to receive the number of w connections
130  */
131  void GetNConnections(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, unsigned int &nU, unsigned int &nV, unsigned int &nW) const;
132 
133  /**
134  * @brief Get a list of elements connected to a specified cluster
135  *
136  * @param pCluster address of a cluster
137  * @param ignoreUnavailable whether to ignore unavailable clusters
138  * @param elementList to receive the connected element list
139  */
140  void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const;
141 
142  /**
143  * @brief Get a list of elements connected to a specified cluster
144  *
145  * @param pCluster address of a cluster
146  * @param ignoreUnavailable whether to ignore unavailable clusters
147  * @param elementList to receive the connected element list
148  * @param nU to receive the number of u connections
149  * @param nV to receive the number of v connections
150  * @param nW to receive the number of w connections
151  */
152  void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList,
153  unsigned int &nU, unsigned int &nV, unsigned int &nW) const;
154 
155  typedef std::unordered_map<const pandora::Cluster *, pandora::ClusterList> ClusterNavigationMap;
156  typedef std::unordered_map<const pandora::Cluster *, OverlapResult> OverlapList;
157  typedef std::unordered_map<const pandora::Cluster *, OverlapList> OverlapMatrix;
158  typedef std::unordered_map<const pandora::Cluster *, OverlapMatrix> TheTensor;
159 
161 
162  /**
163  * @brief Returns an iterator referring to the first element in the overlap tensor
164  */
165  const_iterator begin() const;
166 
167  /**
168  * @brief Returns an iterator referring to the past-the-end element in the overlap tensor
169  */
170  const_iterator end() const;
171 
172  /**
173  * @brief Get a sorted vector of key clusters (U clusters with current implementation)
174  *
175  * @param sortedKeyClusters to receive the sorted vector of key clusters
176  */
177  void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const;
178 
179  /**
180  * @brief Get the overlap result for a specified trio of clusters
181  *
182  * @param pClusterU address of cluster u
183  * @param pClusterV address of cluster v
184  * @param pClusterW address of cluster w
185  *
186  * @return the address of the overlap result
187  */
188  const OverlapResult &GetOverlapResult(
189  const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW) const;
190 
191  /**
192  * @brief Get the overlap list for a specified pair of clusters
193  *
194  * @param pClusterU address of cluster u
195  * @param pClusterV address of cluster v
196  *
197  * @return the cluster overlap list
198  */
199  const OverlapList &GetOverlapList(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV) const;
200 
201  /**
202  * @brief Get the cluster overlap matrix for a specified cluster
203  *
204  * @param pClusterU address of cluster u
205  *
206  * @return the cluster overlap matrix
207  */
208  const OverlapMatrix &GetOverlapMatrix(const pandora::Cluster *const pClusterU) const;
209 
210  /**
211  * @brief Get the cluster navigation map U->V
212  *
213  * @return the cluster navigation map U->V
214  */
215  const ClusterNavigationMap &GetClusterNavigationMapUV() const;
216 
217  /**
218  * @brief Get the cluster navigation map V->W
219  *
220  * @return the cluster navigation map V->W
221  */
222  const ClusterNavigationMap &GetClusterNavigationMapVW() const;
223 
224  /**
225  * @brief Get the cluster navigation map W->U
226  *
227  * @return the cluster navigation map W->U
228  */
229  const ClusterNavigationMap &GetClusterNavigationMapWU() const;
230 
231  /**
232  * @brief Set overlap result
233  *
234  * @param pClusterU address of cluster u
235  * @param pClusterV address of cluster v
236  * @param pClusterW address of cluster w
237  * @param overlapResult the overlap result
238  */
239  void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV,
240  const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult);
241 
242  /**
243  * @brief SetReplace an existing overlap result
244  *
245  * @param pClusterU address of cluster u
246  * @param pClusterV address of cluster v
247  * @param pClusterW address of cluster w
248  * @param overlapResult the overlap result
249  */
250  void ReplaceOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV,
251  const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult);
252 
253  /**
254  * @brief Remove entries from tensor corresponding to specified cluster
255  *
256  * @param pCluster address of the cluster
257  */
258  void RemoveCluster(const pandora::Cluster *const pCluster);
259 
260  /**
261  * @brief Clear overlap tensor
262  */
263  void Clear();
264 
265 private:
266  /**
267  * @brief Get elements connected to a specified cluster
268  *
269  * @param pCluster address of the cluster
270  * @param elementList the element list
271  * @param clusterListU connected u clusters
272  * @param clusterListV connected v clusters
273  * @param clusterListW connected w clusters
274  */
275  void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList,
276  pandora::ClusterList &clusterListU, pandora::ClusterList &clusterListV, pandora::ClusterList &clusterListW) const;
277 
278  /**
279  * @brief Explore connections associated with a given cluster
280  *
281  * @param pCluster address of the cluster
282  * @param clusterListU connected u clusters
283  * @param clusterListV connected v clusters
284  * @param clusterListW connected w clusters
285  */
286  void ExploreConnections(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, pandora::ClusterList &clusterListU,
287  pandora::ClusterList &clusterListV, pandora::ClusterList &clusterListW) const;
288 
289  TheTensor m_overlapTensor; ///< The overlap tensor
290  ClusterNavigationMap m_clusterNavigationMapUV; ///< The cluster navigation map U->V
291  ClusterNavigationMap m_clusterNavigationMapVW; ///< The cluster navigation map V->W
292  ClusterNavigationMap m_clusterNavigationMapWU; ///< The cluster navigation map W->U
293 };
294 
295 //------------------------------------------------------------------------------------------------------------------------------------------
296 
297 template <typename T>
299  const pandora::Cluster *const pCluster, const bool ignoreUnavailable, unsigned int &nU, unsigned int &nV, unsigned int &nW) const
300 {
301  ElementList elementList;
302  this->GetConnectedElements(pCluster, ignoreUnavailable, elementList, nU, nV, nW);
303 }
304 
305 //------------------------------------------------------------------------------------------------------------------------------------------
306 
307 template <typename T>
308 inline void OverlapTensor<T>::GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
309 {
310  unsigned int nU(0), nV(0), nW(0);
311  this->GetConnectedElements(pCluster, ignoreUnavailable, elementList, nU, nV, nW);
312 }
313 
314 //------------------------------------------------------------------------------------------------------------------------------------------
315 
316 template <typename T>
318 {
319  return m_overlapTensor.begin();
320 }
321 
322 //------------------------------------------------------------------------------------------------------------------------------------------
323 
324 template <typename T>
326 {
327  return m_overlapTensor.end();
328 }
329 
330 //------------------------------------------------------------------------------------------------------------------------------------------
331 
332 template <typename T>
334  const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW) const
335 {
336  const OverlapList &overlapList(this->GetOverlapList(pClusterU, pClusterV));
337  typename OverlapList::const_iterator iter = overlapList.find(pClusterW);
338 
339  if (overlapList.end() == iter)
340  throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND);
341 
342  return iter->second;
343 }
344 
345 //------------------------------------------------------------------------------------------------------------------------------------------
346 
347 template <typename T>
349  const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV) const
350 {
351  const OverlapMatrix &overlapMatrix(this->GetOverlapMatrix(pClusterU));
352  typename OverlapMatrix::const_iterator iter = overlapMatrix.find(pClusterV);
353 
354  if (overlapMatrix.end() == iter)
355  throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND);
356 
357  return iter->second;
358 }
359 
360 //------------------------------------------------------------------------------------------------------------------------------------------
361 
362 template <typename T>
363 inline const typename OverlapTensor<T>::OverlapMatrix &OverlapTensor<T>::GetOverlapMatrix(const pandora::Cluster *const pClusterU) const
364 {
365  typename TheTensor::const_iterator iter = m_overlapTensor.find(pClusterU);
366 
367  if (m_overlapTensor.end() == iter)
368  throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND);
369 
370  return iter->second;
371 }
372 
373 //------------------------------------------------------------------------------------------------------------------------------------------
374 
375 template <typename T>
377 {
379 }
380 
381 //------------------------------------------------------------------------------------------------------------------------------------------
382 
383 template <typename T>
385 {
387 }
388 
389 //------------------------------------------------------------------------------------------------------------------------------------------
390 
391 template <typename T>
393 {
395 }
396 
397 //------------------------------------------------------------------------------------------------------------------------------------------
398 
399 template <typename T>
401 {
402  m_overlapTensor.clear();
403  m_clusterNavigationMapUV.clear();
404  m_clusterNavigationMapVW.clear();
405  m_clusterNavigationMapWU.clear();
406 }
407 
408 //------------------------------------------------------------------------------------------------------------------------------------------
409 //------------------------------------------------------------------------------------------------------------------------------------------
410 
411 template <typename T>
412 inline OverlapTensor<T>::Element::Element(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV,
413  const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult) :
414  m_pClusterU(pClusterU),
415  m_pClusterV(pClusterV),
416  m_pClusterW(pClusterW),
417  m_overlapResult(overlapResult)
418 {
419 }
420 
421 //------------------------------------------------------------------------------------------------------------------------------------------
422 
423 template <typename T>
424 inline const pandora::Cluster *OverlapTensor<T>::Element::GetClusterU() const
425 {
426  return m_pClusterU;
427 }
428 
429 //------------------------------------------------------------------------------------------------------------------------------------------
430 
431 template <typename T>
432 inline const pandora::Cluster *OverlapTensor<T>::Element::GetClusterV() const
433 {
434  return m_pClusterV;
435 }
436 
437 //------------------------------------------------------------------------------------------------------------------------------------------
438 
439 template <typename T>
440 inline const pandora::Cluster *OverlapTensor<T>::Element::GetClusterW() const
441 {
442  return m_pClusterW;
443 }
444 
445 //------------------------------------------------------------------------------------------------------------------------------------------
446 
447 template <typename T>
449 {
450  return m_overlapResult;
451 }
452 
453 //------------------------------------------------------------------------------------------------------------------------------------------
454 
455 template <typename T>
457 {
458  if (this == &rhs)
459  return false;
460 
461  return (this->GetOverlapResult() < rhs.GetOverlapResult());
462 }
463 
464 } // namespace lar_content
465 
466 #endif // #ifndef LAR_OVERLAP_TENSOR_H
OverlapResult m_overlapResult
The overlap result.
OverlapTensor class.
ClusterNavigationMap m_clusterNavigationMapVW
The cluster navigation map V->W.
const ClusterNavigationMap & GetClusterNavigationMapVW() const
Get the cluster navigation map V->W.
ClusterNavigationMap m_clusterNavigationMapUV
The cluster navigation map U->V.
const pandora::Cluster * GetClusterW() const
Get the address of the w cluster.
enum cvn::HType HitType
const_iterator begin() const
Returns an iterator referring to the first element in the overlap tensor.
void GetNConnections(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, unsigned int &nU, unsigned int &nV, unsigned int &nW) const
Get the number of connections for a specified cluster.
const pandora::Cluster * m_pClusterW
The address of the w cluster.
std::unordered_map< const pandora::Cluster *, OverlapMatrix > TheTensor
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
const ClusterNavigationMap & GetClusterNavigationMapUV() const
Get the cluster navigation map U->V.
void ExploreConnections(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, pandora::ClusterList &clusterListU, pandora::ClusterList &clusterListV, pandora::ClusterList &clusterListW) const
Explore connections associated with a given cluster.
intermediate_table::const_iterator const_iterator
void ReplaceOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
SetReplace an existing overlap result.
const pandora::Cluster * GetClusterU() const
Get the address of the u cluster.
TheTensor m_overlapTensor
The overlap tensor.
const OverlapList & GetOverlapList(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV) const
Get the overlap list for a specified pair of clusters.
const_iterator end() const
Returns an iterator referring to the past-the-end element in the overlap tensor.
void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Set overlap result.
void Clear()
Clear overlap tensor.
std::vector< Element > ElementList
void GetUnambiguousElements(const bool ignoreUnavailable, ElementList &elementList) const
Get unambiguous elements.
const OverlapMatrix & GetOverlapMatrix(const pandora::Cluster *const pClusterU) const
Get the cluster overlap matrix for a specified cluster.
TheMatrix::const_iterator const_iterator
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
Element(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Constructor.
const pandora::Cluster * GetCluster(const pandora::HitType hitType) const
Get the address of the given hit type cluster.
const pandora::Cluster * m_pClusterU
The address of the u cluster.
ClusterNavigationMap m_clusterNavigationMapWU
The cluster navigation map W->U.
const OverlapResult & GetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW) const
Get the overlap result for a specified trio of clusters.
std::unordered_map< const pandora::Cluster *, OverlapResult > OverlapList
bool operator<(const Element &rhs) const
Element less than operator.
const OverlapResult & GetOverlapResult() const
Get the overlap result.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterNavigationMap
const pandora::Cluster * m_pClusterV
The address of the v cluster.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
const pandora::Cluster * GetClusterV() const
Get the address of the v cluster.
void RemoveCluster(const pandora::Cluster *const pCluster)
Remove entries from tensor corresponding to specified cluster.
bool DefaultAmbiguityFunction(const pandora::ClusterList &clusterListU, const pandora::ClusterList &clusterListV, const pandora::ClusterList &clusterListW, const pandora::Cluster *&pClusterU, const pandora::Cluster *&pClusterV, const pandora::Cluster *&pClusterW) const
Default ambiguity function, checking that only one U, V and W cluster is found.
std::unordered_map< const pandora::Cluster *, OverlapList > OverlapMatrix
const ClusterNavigationMap & GetClusterNavigationMapWU() const
Get the cluster navigation map W->U.
TheTensor::const_iterator const_iterator