TransverseAssociationAlgorithm.h
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArTwoDReco/LArClusterAssociation/TransverseAssociationAlgorithm.h
3  *
4  * @brief Header file for the transverse association algorithm class.
5  *
6  * $Log: $
7  */
8 #ifndef LAR_TRANSVERSE_ASSOCIATION_ALGORITHM_H
9 #define LAR_TRANSVERSE_ASSOCIATION_ALGORITHM_H 1
10 
11 #include "Pandora/Algorithm.h"
12 
14 
15 namespace lar_content
16 {
17 
18 template <typename, unsigned int>
19 class KDTreeLinkerAlgo;
20 template <typename, unsigned int>
21 class KDTreeNodeInfoT;
22 
23 //------------------------------------------------------------------------------------------------------------------------------------------
24 
25 /**
26  * @brief TransverseAssociationAlgorithm class
27  */
29 {
30 public:
31  /**
32  * @brief Default constructor
33  */
35 
36 private:
37  /**
38  * @brief LArTransverseCluster class
39  */
41  {
42  public:
43  /**
44  * @brief Constructor
45  *
46  * @param pSeedCluster
47  * @param associatedClusters
48  */
49  LArTransverseCluster(const pandora::Cluster *const pSeedCluster, const pandora::ClusterVector &associatedClusters);
50 
51  /**
52  * @brief Constructor
53  *
54  * @return the address of the seed cluster
55  */
56  const pandora::Cluster *GetSeedCluster() const;
57 
58  /**
59  * @brief Get the associated cluster vector
60  *
61  * @return the associated cluster vector
62  */
64 
65  /**
66  * @brief Get the inner vertex position
67  *
68  * @return the inner vertex position
69  */
70  const pandora::CartesianVector &GetInnerVertex() const;
71 
72  /**
73  * @brief Get the outer vertex position
74  *
75  * @return the outer vertex position
76  */
77  const pandora::CartesianVector &GetOuterVertex() const;
78 
79  /**
80  * @brief Get the direction
81  *
82  * @return the direction
83  */
84  const pandora::CartesianVector &GetDirection() const;
85 
86  private:
87  const pandora::Cluster *m_pSeedCluster;
89  pandora::CartesianVector m_innerVertex;
90  pandora::CartesianVector m_outerVertex;
91  pandora::CartesianVector m_direction;
92  };
93 
94  typedef std::vector<LArTransverseCluster *> TransverseClusterList;
95 
98  typedef std::vector<HitKDNode2D> HitKDNode2DList;
99 
100  typedef std::unordered_map<const pandora::Cluster *, pandora::ClusterSet> ClusterToClustersMap;
101  typedef std::unordered_map<const pandora::CaloHit *, const pandora::Cluster *> HitToClusterMap;
102 
103  pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle);
104  void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const;
105  void PopulateClusterAssociationMap(const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const;
106  bool IsExtremalCluster(const bool isForward, const pandora::Cluster *const pCurrentCluster, const pandora::Cluster *const pTestCluster) const;
107 
108  /**
109  * @brief Use a kd-tree to obtain details of all nearby cluster combinations
110  *
111  * @param allClusters the list of all clusters
112  * @param nearbyClusters to obtain the nearby cluster map
113  */
114  void GetNearbyClusterMap(const pandora::ClusterVector &allClusters, ClusterToClustersMap &nearbyClusters) const;
115 
116  /**
117  * @brief Separate input clusters by length
118  *
119  * @param inputClusters the input vector of clusters
120  * @param shortClusters the output vector of short clusters
121  * @param transverseMediumClusters the output vector of transverse medium clusters
122  * @param longitudinalMediumClusters the output vector of longitudinal medium clusters
123  * @param longClusters the output vector of all long clusters
124  */
125  void SortInputClusters(const pandora::ClusterVector &inputClusters, pandora::ClusterVector &shortClusters, pandora::ClusterVector &transverseMediumClusters,
126  pandora::ClusterVector &longitudinalMediumClusters, pandora::ClusterVector &longClusters) const;
127 
128  /**
129  * @brief Form a reduced set of associations between two input lists of clusters
130  *
131  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
132  * @param firstVector the first input vector of clusters
133  * @param secondVector the second input vector of clusters
134  * @param clusterAssociationMap the output map of associations between clusters
135  */
136  void FillReducedAssociationMap(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &firstVector,
137  const pandora::ClusterVector &secondVector, ClusterAssociationMap &clusterAssociationMap) const;
138 
139  /**
140  * @brief Form associations between two input lists of cluster
141  *
142  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
143  * @param firstVector the first input vector of clusters
144  * @param secondVector the second input vector of clusters
145  * @param firstAssociationMap the map of associations between first and second cluster vectors
146  * @param secondAssociationMap the reversed map of associations between first and cluster vectors
147  */
148  void FillAssociationMap(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &firstVector,
149  const pandora::ClusterVector &secondVector, ClusterAssociationMap &firstAssociationMap, ClusterAssociationMap &secondAssociationMap) const;
150 
151  /**
152  * @brief Create transverse cluster objects, these are protoclusters with a direction and inner/outer vertices
153  *
154  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
155  * @param inputClusters the input vector of clusters
156  * @param inputAssociationMap the map of associations between input clusters
157  * @param transverseClusterList the output vector of transverse cluster objects
158  */
159  void FillTransverseClusterList(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &inputClusters,
160  const ClusterAssociationMap &inputAssociationMap, TransverseClusterList &transverseClusterList) const;
161 
162  /**
163  * @brief Form associations between transverse cluster objects
164  *
165  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
166  * @param transverseClusterList the input vector of transverse cluster objects
167  * @param transverseAssociationMap the external map of associations between clusters
168  * @param clusterAssociationMap the output map of associations between clusters
169  */
170  void FillTransverseAssociationMap(const ClusterToClustersMap &nearbyClusters, const TransverseClusterList &transverseClusterList,
171  const ClusterAssociationMap &transverseAssociationMap, ClusterAssociationMap &clusterAssociationMap) const;
172 
173  /**
174  * @brief Find the clusters that are transversely associated with a target cluster
175  *
176  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
177  * @param pCluster the target cluster
178  * @param inputAssociationMap the map of associations between clusters
179  * @param outputClusters the output vector of clusters transversely associated with target cluster
180  */
181  void GetAssociatedClusters(const ClusterToClustersMap &nearbyClusters, const pandora::Cluster *const pCluster,
182  const ClusterAssociationMap &inputAssociationMap, pandora::ClusterVector &associatedClusters) const;
183 
184  /**
185  * @brief Determine whether clusters are association
186  *
187  * @param isForward whether the association is forwards or backwards
188  * @param pCluster1 the first cluster
189  * @param pCluster2 the second cluster
190  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
191  *
192  * @return boolean
193  */
194  bool IsAssociated(const bool isForward, const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2,
195  const ClusterToClustersMap &nearbyClusters) const;
196 
197  /**
198  * @brief Determine whether two clusters are within the same cluster window
199  *
200  * @param pCluster1 the first cluster
201  * @param pCluster2 the second cluster
202  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
203  *
204  * @return boolean
205  */
207  const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const ClusterToClustersMap &nearbyClusters) const;
208 
209  /**
210  * @brief Determine whether two transverse clusters are associated
211  *
212  * @param pTransverseCluster1 the first transverse cluster
213  * @param pTransverseCluster2 the second transverse cluster
214  * @param nearbyClusters the nearby cluster map, extracted via use of a kd-tree
215  *
216  * @return boolean
217  */
218  bool IsTransverseAssociated(const LArTransverseCluster *const pTransverseCluster1,
219  const LArTransverseCluster *const pTransverseCluster2, const ClusterToClustersMap &nearbyClusters) const;
220 
221  /**
222  * @brief Determine whether one transverse cluster is associated with the vertex from a second transverse cluster
223  *
224  * @param pTransverseCluster the target cluster
225  * @param theVertex the vertex position
226  *
227  * @return boolean
228  */
229  bool IsTransverseAssociated(const LArTransverseCluster *const pTransverseCluster, const pandora::CartesianVector &testPosition) const;
230 
231  /**
232  * @brief Determine whether two clusters are overlapping
233  *
234  * @param pCluster1 the first cluster
235  * @param pCluster2 the second cluster
236  *
237  * @return boolean
238  */
239  bool IsOverlapping(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2) const;
240 
241  /**
242  * @brief Calculate the overall span in X for a clusters
243  *
244  * @param pCluster the target cluster
245  */
246  float GetTransverseSpan(const pandora::Cluster *const pCluster) const;
247 
248  /**
249  * @brief Calculate the overall span in Z for a clusters
250  *
251  * @param pCluster the target cluster
252  */
253  float GetLongitudinalSpan(const pandora::Cluster *const pCluster) const;
254 
255  /**
256  * @brief Calculate the overall span in X for a set of clusters
257  *
258  * @param pCluster the target cluster
259  * @param associatedClusters the vector of associated clusters
260  */
261  float GetTransverseSpan(const pandora::Cluster *const pCluster, const pandora::ClusterVector &associatedClusters) const;
262 
263  /**
264  * @brief Get minimum and maximum X coordinates for a given cluster
265  *
266  * @param pCluster the input cluster
267  * @param minX the minimum X position
268  * @param maxX the maximum X position
269  */
270  void GetExtremalCoordinatesX(const pandora::Cluster *const pCluster, float &minX, float &maxX) const;
271 
272  /**
273  * @brief Get minimum and maximum Z coordinates for a given cluster
274  *
275  * @param pCluster the input cluster
276  * @param minZ the minimum Z position
277  * @param maxZ the maximum Z position
278  */
279  void GetExtremalCoordinatesZ(const pandora::Cluster *const pCluster, float &minZ, float &maxZ) const;
280 
281  /**
282  * @brief Get minimum and maximum X or Z coordinates for a given cluster
283  *
284  * @param pCluster the input cluster
285  * @param useX calculate extermal coordinates for X (rather than Z)
286  * @param minXZ the minimum X or Z position
287  * @param maxXZ the maximum X or Z position
288  */
289  void GetExtremalCoordinatesXZ(const pandora::Cluster *const pCluster, const bool useX, float &minXZ, float &maxXZ) const;
290 
291  /**
292  * @brief Get extremal 2D coordinates for a given cluster (ordered by X)
293  *
294  * @param pCluster the input cluster
295  * @param innerCoordinate the inner coordinate
296  * @param outerCoordinate the outer coordinate
297  */
299  const pandora::Cluster *const pCluster, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate) const;
300 
301  /**
302  * @brief Remove double-counting from association map
303  *
304  * @param inputAssociationMap the inputted association map
305  * @param outputAssociationMap the outputted association map
306  */
307  void FillReducedAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const;
308 
309  /**
310  * @brief Use one map to block associations from another map
311  *
312  * @param firstAssociationMap the first association map
313  * @param secondAssociationMap the second association map
314  * @param secondAssociationMap the second association map reversed
315  * @param clusterAssociationMap the outputted association map
316  */
317  void FillReducedAssociationMap(const ClusterAssociationMap &firstAssociationMap, const ClusterAssociationMap &secondAssociationMap,
318  const ClusterAssociationMap &secondAssociationMapSwapped, ClusterAssociationMap &clusterAssociationMap) const;
319 
320  /**
321  * @brief Symmetrise an association map
322  *
323  * @param inputAssociationMap the inputted association map
324  * @param outputAssociationMap the outputted association map
325  */
326  void FillSymmetricAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const;
327 
328  /**
329  * @brief Symmetrise and then remove double-counting from an association map
330  *
331  * @param inputAssociationMap the inputted association map
332  * @param outputAssociationMap the outputted association map
333  */
334  void FinalizeClusterAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const;
335 
336  float m_firstLengthCut; ///<
337  float m_secondLengthCut; ///<
338 
339  float m_clusterWindow; ///<
340  float m_clusterAngle; ///<
341  float m_clusterCosAngle; ///<
342  float m_clusterTanAngle; ///<
343 
347 
351 
352  float m_searchRegionX; ///< Search region, applied to x dimension, for look-up from kd-trees
353  float m_searchRegionZ; ///< Search region, applied to u/v/w dimension, for look-up from kd-trees
354 };
355 
356 //------------------------------------------------------------------------------------------------------------------------------------------
357 
359 {
360  return m_pSeedCluster;
361 }
362 
363 //------------------------------------------------------------------------------------------------------------------------------------------
364 
366 {
367  return m_associatedClusters;
368 }
369 
370 //------------------------------------------------------------------------------------------------------------------------------------------
371 
372 inline const pandora::CartesianVector &TransverseAssociationAlgorithm::LArTransverseCluster::GetInnerVertex() const
373 {
374  return m_innerVertex;
375 }
376 
377 //------------------------------------------------------------------------------------------------------------------------------------------
378 
379 inline const pandora::CartesianVector &TransverseAssociationAlgorithm::LArTransverseCluster::GetOuterVertex() const
380 {
381  return m_outerVertex;
382 }
383 
384 //------------------------------------------------------------------------------------------------------------------------------------------
385 
386 inline const pandora::CartesianVector &TransverseAssociationAlgorithm::LArTransverseCluster::GetDirection() const
387 {
388  return m_direction;
389 }
390 
391 } // namespace lar_content
392 
393 #endif // #ifndef LAR_TRANSVERSE_ASSOCIATION_ALGORITHM_H
void PopulateClusterAssociationMap(const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const
Populate the cluster association map.
const pandora::CartesianVector & GetInnerVertex() const
Get the inner vertex position.
float GetTransverseSpan(const pandora::Cluster *const pCluster) const
Calculate the overall span in X for a clusters.
void FillTransverseAssociationMap(const ClusterToClustersMap &nearbyClusters, const TransverseClusterList &transverseClusterList, const ClusterAssociationMap &transverseAssociationMap, ClusterAssociationMap &clusterAssociationMap) const
Form associations between transverse cluster objects.
void GetExtremalCoordinatesXZ(const pandora::Cluster *const pCluster, const bool useX, float &minXZ, float &maxXZ) const
Get minimum and maximum X or Z coordinates for a given cluster.
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
bool IsExtremalCluster(const bool isForward, const pandora::Cluster *const pCurrentCluster, const pandora::Cluster *const pTestCluster) const
Determine which of two clusters is extremal.
void FillSymmetricAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const
Symmetrise an association map.
bool IsTransverseAssociated(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const ClusterToClustersMap &nearbyClusters) const
Determine whether two clusters are within the same cluster window.
void FillAssociationMap(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &firstVector, const pandora::ClusterVector &secondVector, ClusterAssociationMap &firstAssociationMap, ClusterAssociationMap &secondAssociationMap) const
Form associations between two input lists of cluster.
std::vector< LArTransverseCluster * > TransverseClusterList
Data stored in each KDTree node. The dim1/dim2 fields are usually the duplication of some PFRecHit va...
bool IsOverlapping(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2) const
Determine whether two clusters are overlapping.
void GetExtremalCoordinatesX(const pandora::Cluster *const pCluster, float &minX, float &maxX) const
Get minimum and maximum X coordinates for a given cluster.
float m_searchRegionX
Search region, applied to x dimension, for look-up from kd-trees.
void SortInputClusters(const pandora::ClusterVector &inputClusters, pandora::ClusterVector &shortClusters, pandora::ClusterVector &transverseMediumClusters, pandora::ClusterVector &longitudinalMediumClusters, pandora::ClusterVector &longClusters) const
Separate input clusters by length.
KDTreeNodeInfoT< const pandora::CaloHit *, 2 > HitKDNode2D
Header file for the cluster association algorithm class.
void FillTransverseClusterList(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &inputClusters, const ClusterAssociationMap &inputAssociationMap, TransverseClusterList &transverseClusterList) const
Create transverse cluster objects, these are protoclusters with a direction and inner/outer vertices...
const pandora::CartesianVector & GetOuterVertex() const
Get the outer vertex position.
std::unordered_map< const pandora::Cluster *, pandora::ClusterSet > ClusterToClustersMap
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
void FinalizeClusterAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const
Symmetrise and then remove double-counting from an association map.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with subset of cluster list, containing clusters judged to be clean...
KDTreeLinkerAlgo< const pandora::CaloHit *, 2 > HitKDTree2D
void GetNearbyClusterMap(const pandora::ClusterVector &allClusters, ClusterToClustersMap &nearbyClusters) const
Use a kd-tree to obtain details of all nearby cluster combinations.
const pandora::CartesianVector & GetDirection() const
Get the direction.
bool IsAssociated(const bool isForward, const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const ClusterToClustersMap &nearbyClusters) const
Determine whether clusters are association.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
void FillReducedAssociationMap(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &firstVector, const pandora::ClusterVector &secondVector, ClusterAssociationMap &clusterAssociationMap) const
Form a reduced set of associations between two input lists of clusters.
float GetLongitudinalSpan(const pandora::Cluster *const pCluster) const
Calculate the overall span in Z for a clusters.
float m_searchRegionZ
Search region, applied to u/v/w dimension, for look-up from kd-trees.
const pandora::ClusterVector & GetAssociatedClusters() const
Get the associated cluster vector.
void GetExtremalCoordinatesZ(const pandora::Cluster *const pCluster, float &minZ, float &maxZ) const
Get minimum and maximum Z coordinates for a given cluster.
LArTransverseCluster(const pandora::Cluster *const pSeedCluster, const pandora::ClusterVector &associatedClusters)
Constructor.