8 #ifndef LAR_KD_TREE_LINKER_ALGO_TEMPLATED_H 9 #define LAR_KD_TREE_LINKER_ALGO_TEMPLATED_H 21 template <
typename DATA,
unsigned DIM = 2>
22 class KDTreeLinkerAlgo
41 void build(
std::vector<KDTreeNodeInfoT<DATA, DIM> > &eltList,
const KDTreeBoxT<DIM> ®ion);
50 void search(
const KDTreeBoxT<DIM> &searchBox,
std::vector<KDTreeNodeInfoT<DATA, DIM> > &resRecHitList);
59 void findNearestNeighbour(
const KDTreeNodeInfoT<DATA, DIM> &point,
const KDTreeNodeInfoT<DATA, DIM> *&result,
float &distance);
105 KDTreeNodeT<DATA, DIM> *
recBuild(
int low,
int high,
int depth,
const KDTreeBoxT<DIM> ®ion);
113 void recSearch(
const KDTreeNodeT<DATA, DIM> *current,
const KDTreeBoxT<DIM> &trackBox);
124 void recNearestNeighbour(
unsigned depth,
const KDTreeNodeT<DATA, DIM> *current,
const KDTreeNodeInfoT<DATA, DIM> &point,
125 const KDTreeNodeT<DATA, DIM> *&best_match,
float &best_dist);
132 void addSubtree(
const KDTreeNodeT<DATA, DIM> *current);
142 float dist2(
const KDTreeNodeInfoT<DATA, DIM> &a,
const KDTreeNodeInfoT<DATA, DIM> &b)
const;
161 template <
typename DATA,
unsigned DIM>
174 template <
typename DATA,
unsigned DIM>
182 template <
typename DATA,
unsigned DIM>
201 template <
typename DATA,
unsigned DIM>
207 const int nbrElts = high - low;
208 int median = nbrElts / 2 - (1 - 1 * (nbrElts & 1));
223 const unsigned thedim = treeDepth % DIM;
236 if (j < median) l = i;
237 if (i > median) m = j;
245 template <
typename DATA,
unsigned DIM>
258 template <
typename DATA,
unsigned DIM>
266 if ((current->
left ==
nullptr) && (current->
right ==
nullptr))
270 bool isInside =
true;
272 for (
unsigned i = 0; i < DIM; ++i)
274 const auto thedim = current->
info.dims[i];
275 isInside *= thedim >= trackBox.
dimmin[i] && thedim <= trackBox.
dimmax[i];
285 bool isFullyContained =
true;
286 bool hasIntersection =
true;
288 for (
unsigned i = 0; i < DIM; ++i)
290 const auto regionmin = current->
left->region.dimmin[i];
291 const auto regionmax = current->
left->region.dimmax[i];
292 isFullyContained *= (regionmin >= trackBox.
dimmin[i] && regionmax <= trackBox.
dimmax[i]);
293 hasIntersection *= (regionmin < trackBox.
dimmax[i] && regionmax > trackBox.
dimmin[i]);
296 if (isFullyContained)
300 else if (hasIntersection)
306 isFullyContained =
true;
307 hasIntersection =
true;
309 for (
unsigned i = 0; i < DIM; ++i)
311 const auto regionmin = current->
right->region.dimmin[i];
312 const auto regionmax = current->
right->region.dimmax[i];
313 isFullyContained *= (regionmin >= trackBox.
dimmin[i] && regionmax <= trackBox.
dimmax[i]);
314 hasIntersection *= (regionmin < trackBox.
dimmax[i] && regionmax > trackBox.
dimmin[i]);
317 if (isFullyContained)
321 else if (hasIntersection)
330 template <
typename DATA,
unsigned DIM>
347 result = &(best_match->
info);
348 distance = std::sqrt(distance);
355 template <
typename DATA,
unsigned DIM>
359 const unsigned int current_dim = depth % DIM;
361 if (current->
left ==
nullptr && current->
right ==
nullptr)
363 best_match = current;
364 best_dist = this->
dist2(point, best_match->
info);
369 const float dist_to_axis = point.
dims[current_dim] - current->
info.dims[current_dim];
371 if (dist_to_axis < 0.
f)
381 const float dist_current = this->
dist2(point, current->
info);
383 if (dist_current < best_dist)
385 best_dist = dist_current;
386 best_match = current;
390 if (best_dist > dist_to_axis * dist_to_axis)
394 float check_dist = best_dist;
396 if (dist_to_axis < 0.
f)
405 if (check_dist < best_dist)
407 best_dist = check_dist;
408 best_match = check_best;
417 template <
typename DATA,
unsigned DIM >
423 if ((current->
left ==
nullptr) && (current->
right ==
nullptr))
438 template <
typename DATA,
unsigned DIM>
443 for (
unsigned i = 0 ; i < DIM; ++i)
445 const double diff = a.
dims[i] - b.
dims[i];
454 template <
typename DATA,
unsigned DIM>
466 template <
typename DATA,
unsigned DIM>
474 template <
typename DATA,
unsigned DIM>
482 template <
typename DATA,
unsigned DIM>
491 template <
typename DATA,
unsigned DIM>
505 template <
typename DATA,
unsigned DIM>
508 const int portionSize = high - low;
513 if (portionSize == 1)
528 node->
info = (*initialEltList)[medianId];
534 const unsigned thedim = depth % DIM;
535 auto medianVal = (*initialEltList)[medianId].dims[thedim];
536 leftRegion.
dimmax[thedim] = medianVal;
537 rightRegion.
dimmin[thedim] = medianVal;
543 node->
left = this->
recBuild(low, medianId, depth, leftRegion);
544 node->
right = this->
recBuild(medianId, high, depth, rightRegion);
551 #endif // LAR_KD_TREE_LINKER_ALGO_TEMPLATED_H int nodePoolPos_
The node pool position.
KDTreeNodeT< DATA, DIM > * root_
The KDTree root.
std::vector< KDTreeNodeInfoT< DATA, DIM > > * initialEltList
The initial element list.
void setAttributs(const KDTreeBoxT< DIM > ®ionBox, const KDTreeNodeInfoT< DATA, DIM > &infoToStore)
setAttributs
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
KDTreeNodeInfoT< DATA, DIM > info
Data.
int nodePoolSize_
The node pool size.
std::array< float, DIM > dims
KDTreeLinkerAlgo()
Default constructor.
int size()
Return the number of nodes + leaves in the tree (nElements should be (size() +1) / 2) ...
void clear()
Clear all allocated structures.
KDTreeNodeT< DATA, DIM > * right
Right son.
bool empty()
Whether the tree is empty.
void recNearestNeighbour(unsigned depth, const KDTreeNodeT< DATA, DIM > *current, const KDTreeNodeInfoT< DATA, DIM > &point, const KDTreeNodeT< DATA, DIM > *&best_match, float &best_dist)
Recursive nearest neighbour search. Is called by findNearestNeighbour()
void findNearestNeighbour(const KDTreeNodeInfoT< DATA, DIM > &point, const KDTreeNodeInfoT< DATA, DIM > *&result, float &distance)
findNearestNeighbour
Data stored in each KDTree node. The dim1/dim2 fields are usually the duplication of some PFRecHit va...
void clearTree()
Frees the KDTree.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
KDTreeNodeT< DATA, DIM > * left
Left son.
KDTreeNodeT< DATA, DIM > * getNextNode()
Get the next node from the node pool.
~KDTreeLinkerAlgo()
Destructor calls clear.
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
float dist2(const KDTreeNodeInfoT< DATA, DIM > &a, const KDTreeNodeInfoT< DATA, DIM > &b) const
dist2
void addSubtree(const KDTreeNodeT< DATA, DIM > *current)
Add all elements of an subtree to the closest elements. Used during the recSearch().
KDTreeNodeT< DATA, DIM > * nodePool_
Node pool allows us to do just 1 call to new for each tree building.
std::vector< KDTreeNodeInfoT< DATA, DIM > > * closestNeighbour
The closest neighbour.
std::array< float, DIM > dimmin
KDTreeNodeT< DATA, DIM > * recBuild(int low, int high, int depth, const KDTreeBoxT< DIM > ®ion)
Recursive kdtree builder. Is called by build()
std::array< float, DIM > dimmax
int medianSearch(int low, int high, int treeDepth)
Fast median search with Wirth algorithm in eltList between low and high indexes.
void recSearch(const KDTreeNodeT< DATA, DIM > *current, const KDTreeBoxT< DIM > &trackBox)
Recursive kdtree search. Is called by search()
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > ®ion)
Build the KD tree from the "eltList" in the space define by "region".