KDTreeLinkerToolsT.h
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArUtility/KDTreeLinkerToolsT.h
3  *
4  * @brief Header file for the kd tree linker tools template class
5  *
6  * $Log: $
7  */
8 #ifndef LAR_KD_TREE_LINKER_TOOLS_TEMPLATED_H
9 #define LAR_KD_TREE_LINKER_TOOLS_TEMPLATED_H 1
10 
11 #include "Api/PandoraContentApi.h"
12 
13 #include "Objects/CaloHit.h"
14 #include "Objects/CartesianVector.h"
15 
16 #include "Pandora/PandoraInternal.h"
17 
18 #include <array>
19 #include <vector>
20 
21 namespace pandora
22 {
23 class Algorithm;
24 }
25 
26 //------------------------------------------------------------------------------------------------------------------------------------------
27 
28 namespace lar_content
29 {
30 
31 /**
32  * @brief Box structure used to define 2D field. It's used in KDTree building step to divide the detector space (ECAL, HCAL...) and
33  * in searching step to create a bounding box around the demanded point (Track collision point, PS projection...).
34  */
35 template <unsigned DIM>
37 {
38 public:
39  /**
40  * @brief Default constructor
41  */
42  KDTreeBoxT();
43 
44  /**
45  * @brief Constructor
46  *
47  * @param dimargs
48  */
49  template <typename... Ts>
50  KDTreeBoxT(Ts... dimargs);
51 
52  std::array<float, DIM> dimmin; ///<
53  std::array<float, DIM> dimmax; ///<
54 };
55 
58 
59 //------------------------------------------------------------------------------------------------------------------------------------------
60 
61 /**
62  * @brief Data stored in each KDTree node. The dim1/dim2 fields are usually the duplication of some PFRecHit values
63  * (eta/phi or x/y). But in some situations, phi field is shifted by +-2.Pi
64  */
65 template <typename DATA, unsigned DIM>
66 class KDTreeNodeInfoT
67 {
68 public:
69  /**
70  * @brief Default constructor
71  */
73 
74  /**
75  * @brief Constructor
76  *
77  * @param d
78  * @param dimargs
79  */
80  template <typename... Ts>
81  KDTreeNodeInfoT(const DATA &d, Ts... dimargs);
82 
83  DATA data; ///<
84  std::array<float, DIM> dims; ///<
85 };
86 
87 //------------------------------------------------------------------------------------------------------------------------------------------
88 
89 /**
90  * @brief KDTree node
91  */
92 template <typename DATA, unsigned DIM>
94 {
95 public:
96  /**
97  * @brief Default constructor
98  */
99  KDTreeNodeT();
100 
101  /**
102  * @brief setAttributs
103  *
104  * @param regionBox
105  * @param infoToStore
106  */
107  void setAttributs(const KDTreeBoxT<DIM> &regionBox, const KDTreeNodeInfoT<DATA, DIM> &infoToStore);
108 
109  /**
110  * @brief setAttributs
111  *
112  * @param regionBox
113  */
114  void setAttributs(const KDTreeBoxT<DIM> &regionBox);
115 
117  KDTreeNodeT<DATA, DIM> *left; ///< Left son
118  KDTreeNodeT<DATA, DIM> *right; ///< Right son
119  KDTreeBoxT<DIM> region; ///< Region bounding box.
120 };
121 
122 //------------------------------------------------------------------------------------------------------------------------------------------
123 
124 /**
125  * @brief kdtree_type_adaptor
126  */
127 template <typename T>
129 {
130 public:
131  /**
132  * @brief position
133  *
134  * @param t
135  *
136  * @return position
137  */
138  static const pandora::CartesianVector &position(const T *const t);
139 };
140 
141 //------------------------------------------------------------------------------------------------------------------------------------------
142 
143 /**
144  * @brief minmax
145  *
146  * @param a
147  * @param b
148  *
149  * @return minmax
150  */
151 std::pair<float, float> minmax(const float a, const float b);
152 
153 /**
154  * @brief fill_and_bound_2d_kd_tree
155  *
156  * @param points
157  * @param nodes
158  *
159  * @return KDTreeCube
160  */
161 template <typename T>
162 KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER<const T *> &points, std::vector<KDTreeNodeInfoT<const T *, 2>> &nodes);
163 
164 /**
165  * @brief fill_and_bound_3d_kd_tree
166  *
167  * @param points
168  * @param nodes
169  *
170  * @return KDTreeCube
171  */
172 template <typename T>
173 KDTreeCube fill_and_bound_3d_kd_tree(const MANAGED_CONTAINER<const T *> &points, std::vector<KDTreeNodeInfoT<const T *, 3>> &nodes);
174 
175 /**
176  * @brief build_2d_kd_search_region
177  *
178  * @param point
179  * @param x_span
180  * @param z_span
181  *
182  * @return KDTreeBox
183  */
184 KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span);
185 
186 /**
187  * @brief build_2d_kd_search_region
188  *
189  * @param pos
190  * @param x_span
191  * @param z_span
192  *
193  * @return KDTreeBox
194  */
195 KDTreeBox build_2d_kd_search_region(const pandora::CartesianVector &pos, const float x_span, const float z_span);
196 
197 /**
198  * @brief build_3d_kd_search_region
199  *
200  * @param point
201  * @param x_span
202  * @param y_span
203  * @param z_span
204  *
205  * @return KDTreeCube
206  */
207 KDTreeCube build_3d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float y_span, const float z_span);
208 
209 /**
210  * @brief build_3d_kd_search_region
211  *
212  * @param pos
213  * @param x_span
214  * @param y_span
215  * @param z_span
216  *
217  * @return KDTreeCube
218  */
219 KDTreeCube build_3d_kd_search_region(const pandora::CartesianVector &pos, const float x_span, const float y_span, const float z_span);
220 
221 //------------------------------------------------------------------------------------------------------------------------------------------
222 //------------------------------------------------------------------------------------------------------------------------------------------
223 
224 template <unsigned DIM>
226 {
227 }
228 
229 //------------------------------------------------------------------------------------------------------------------------------------------
230 
231 template <unsigned DIM>
232 template <typename... Ts>
233 inline KDTreeBoxT<DIM>::KDTreeBoxT(Ts... dimargs)
234 {
235  static_assert(sizeof...(dimargs) == 2 * DIM, "Constructor requires 2*DIM args");
236  std::vector<float> dims = {dimargs...};
237 
238  for (unsigned i = 0; i < DIM; ++i)
239  {
240  dimmin[i] = dims[2 * i];
241  dimmax[i] = dims[2 * i + 1];
242  }
243 }
244 
245 //------------------------------------------------------------------------------------------------------------------------------------------
246 //------------------------------------------------------------------------------------------------------------------------------------------
247 
248 template <typename DATA, unsigned DIM>
250 {
251 }
252 
253 //------------------------------------------------------------------------------------------------------------------------------------------
254 
255 template <typename DATA, unsigned DIM>
256 template <typename... Ts>
257 inline KDTreeNodeInfoT<DATA, DIM>::KDTreeNodeInfoT(const DATA &d, Ts... dimargs) : data(d), dims{{dimargs...}}
258 {
259 }
260 
261 //------------------------------------------------------------------------------------------------------------------------------------------
262 //------------------------------------------------------------------------------------------------------------------------------------------
263 
264 template <typename DATA, unsigned DIM>
265 inline KDTreeNodeT<DATA, DIM>::KDTreeNodeT() : left(nullptr), right(nullptr)
266 {
267 }
268 
269 //------------------------------------------------------------------------------------------------------------------------------------------
270 
271 template <typename DATA, unsigned DIM>
272 inline void KDTreeNodeT<DATA, DIM>::setAttributs(const KDTreeBoxT<DIM> &regionBox, const KDTreeNodeInfoT<DATA, DIM> &infoToStore)
273 {
274  info = infoToStore;
275  region = regionBox;
276 }
277 
278 //------------------------------------------------------------------------------------------------------------------------------------------
279 
280 template <typename DATA, unsigned DIM>
282 {
283  region = regionBox;
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
288 template <typename T>
289 inline const pandora::CartesianVector &kdtree_type_adaptor<T>::position(const T *const t)
290 {
291  return t->GetPosition();
292 }
293 
294 template <>
295 inline const pandora::CartesianVector &kdtree_type_adaptor<const pandora::CaloHit>::position(const pandora::CaloHit *const t)
296 {
297  return t->GetPositionVector();
298 }
299 
300 template <>
301 inline const pandora::CartesianVector &kdtree_type_adaptor<const pandora::CartesianVector>::position(const pandora::CartesianVector *const t)
302 {
303  return *t;
304 }
305 
306 //------------------------------------------------------------------------------------------------------------------------------------------
307 
308 template <typename T>
309 KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER<const T *> &points, std::vector<KDTreeNodeInfoT<const T *, 2>> &nodes)
310 {
311  std::array<float, 2> minpos{{0.f, 0.f}}, maxpos{{0.f, 0.f}};
312 
313  unsigned i = 0;
314 
315  for (const T *const point : points)
316  {
317  const pandora::CartesianVector &pos = kdtree_type_adaptor<const T>::position(point);
318  nodes.emplace_back(point, pos.GetX(), pos.GetZ());
319 
320  if (0 == i)
321  {
322  minpos[0] = pos.GetX();
323  minpos[1] = pos.GetZ();
324  maxpos[0] = pos.GetX();
325  maxpos[1] = pos.GetZ();
326  }
327  else
328  {
329  minpos[0] = std::min(pos.GetX(), minpos[0]);
330  minpos[1] = std::min(pos.GetZ(), minpos[1]);
331  maxpos[0] = std::max(pos.GetX(), maxpos[0]);
332  maxpos[1] = std::max(pos.GetZ(), maxpos[1]);
333  }
334 
335  ++i;
336  }
337 
338  return KDTreeBox(minpos[0], maxpos[0], minpos[1], maxpos[1]);
339 }
340 
341 //------------------------------------------------------------------------------------------------------------------------------------------
342 
343 template <typename T>
344 KDTreeCube fill_and_bound_3d_kd_tree(const MANAGED_CONTAINER<const T *> &points, std::vector<KDTreeNodeInfoT<const T *, 3>> &nodes)
345 {
346  std::array<float, 3> minpos{{0.f, 0.f, 0.f}}, maxpos{{0.f, 0.f, 0.f}};
347 
348  unsigned i = 0;
349 
350  for (const T *const point : points)
351  {
352  const pandora::CartesianVector &pos = kdtree_type_adaptor<const T>::position(point);
353  nodes.emplace_back(point, pos.GetX(), pos.GetY(), pos.GetZ());
354 
355  if (0 == i)
356  {
357  minpos[0] = pos.GetX();
358  minpos[1] = pos.GetY();
359  minpos[2] = pos.GetZ();
360  maxpos[0] = pos.GetX();
361  maxpos[1] = pos.GetY();
362  maxpos[2] = pos.GetZ();
363  }
364  else
365  {
366  minpos[0] = std::min(pos.GetX(), minpos[0]);
367  minpos[1] = std::min(pos.GetY(), minpos[1]);
368  minpos[2] = std::min(pos.GetZ(), minpos[2]);
369  maxpos[0] = std::max(pos.GetX(), maxpos[0]);
370  maxpos[1] = std::max(pos.GetY(), maxpos[1]);
371  maxpos[2] = std::max(pos.GetZ(), maxpos[2]);
372  }
373 
374  ++i;
375  }
376 
377  return KDTreeCube(minpos[0], maxpos[0], minpos[1], maxpos[1], minpos[2], maxpos[2]);
378 }
379 
380 } // namespace lar_content
381 
382 #endif // LAR_KD_TREE_LINKER_TOOLS_TEMPLATED_H
std::pair< float, float > minmax(const float a, const float b)
minmax
static const pandora::CartesianVector & position(const T *const t)
position
void setAttributs(const KDTreeBoxT< DIM > &regionBox, const KDTreeNodeInfoT< DATA, DIM > &infoToStore)
setAttributs
Box structure used to define 2D field. It&#39;s used in KDTree building step to divide the detector space...
KDTreeBoxT< DIM > region
Region bounding box.
KDTreeNodeInfoT< DATA, DIM > info
Data.
struct vector vector
std::array< float, DIM > dims
KDTreeNodeT< DATA, DIM > * right
Right son.
KDTreeCube build_3d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float y_span, const float z_span)
build_3d_kd_search_region
Data stored in each KDTree node. The dim1/dim2 fields are usually the duplication of some PFRecHit va...
KDTreeNodeT< DATA, DIM > * left
Left son.
#define nodes
const double a
KDTreeBoxT< 3 > KDTreeCube
static int max(int a, int b)
KDTreeNodeInfoT()
Default constructor.
std::array< float, DIM > dimmin
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
static bool * b
Definition: config.cpp:1043
KDTreeNodeT()
Default constructor.
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 >> &nodes)
fill_and_bound_2d_kd_tree
std::array< float, DIM > dimmax
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
KDTreeCube fill_and_bound_3d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 3 >> &nodes)
fill_and_bound_3d_kd_tree
KDTreeBoxT< 2 > KDTreeBox