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);
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);
125 const KDTreeNodeT<DATA, DIM> *&best_match,
float &best_dist);
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;
248 template <
typename DATA,
unsigned DIM>
261 template <
typename DATA,
unsigned DIM>
269 if ((current->
left ==
nullptr) && (current->
right ==
nullptr))
273 bool isInside =
true;
275 for (
unsigned i = 0; i < DIM; ++i)
277 const auto thedim = current->
info.dims[i];
278 isInside = isInside && thedim >= trackBox.
dimmin[i] && thedim <= trackBox.
dimmax[i];
288 bool isFullyContained =
true;
289 bool hasIntersection =
true;
291 for (
unsigned i = 0; i < DIM; ++i)
293 const auto regionmin = current->
left->region.dimmin[i];
294 const auto regionmax = current->
left->region.dimmax[i];
295 isFullyContained = isFullyContained && (regionmin >= trackBox.
dimmin[i] && regionmax <= trackBox.
dimmax[i]);
296 hasIntersection = hasIntersection && (regionmin < trackBox.
dimmax[i] && regionmax > trackBox.
dimmin[i]);
299 if (isFullyContained)
303 else if (hasIntersection)
309 isFullyContained =
true;
310 hasIntersection =
true;
312 for (
unsigned i = 0; i < DIM; ++i)
314 const auto regionmin = current->
right->region.dimmin[i];
315 const auto regionmax = current->
right->region.dimmax[i];
316 isFullyContained = isFullyContained && (regionmin >= trackBox.
dimmin[i] && regionmax <= trackBox.
dimmax[i]);
317 hasIntersection = hasIntersection && (regionmin < trackBox.
dimmax[i] && regionmax > trackBox.
dimmin[i]);
320 if (isFullyContained)
324 else if (hasIntersection)
333 template <
typename DATA,
unsigned DIM>
350 result = &(best_match->
info);
351 distance = std::sqrt(distance);
358 template <
typename DATA,
unsigned DIM>
362 const unsigned int current_dim = depth % DIM;
364 if (current->
left ==
nullptr && current->
right ==
nullptr)
367 best_dist = this->
dist2(point, best_match->
info);
372 const float dist_to_axis = point.
dims[current_dim] - current->
info.dims[current_dim];
374 if (dist_to_axis < 0.
f)
384 const float dist_current = this->
dist2(point, current->
info);
386 if (dist_current < best_dist)
388 best_dist = dist_current;
393 if (best_dist > dist_to_axis * dist_to_axis)
397 float check_dist = best_dist;
399 if (dist_to_axis < 0.
f)
408 if (check_dist < best_dist)
410 best_dist = check_dist;
411 best_match = check_best;
420 template <
typename DATA,
unsigned DIM>
426 if ((current->
left ==
nullptr) && (current->
right ==
nullptr))
441 template <
typename DATA,
unsigned DIM>
446 for (
unsigned i = 0; i < DIM; ++i)
448 const double diff = a.
dims[i] - b.
dims[i];
457 template <
typename DATA,
unsigned DIM>
469 template <
typename DATA,
unsigned DIM>
477 template <
typename DATA,
unsigned DIM>
485 template <
typename DATA,
unsigned DIM>
494 template <
typename DATA,
unsigned DIM>
508 template <
typename DATA,
unsigned DIM>
511 const int portionSize = high - low;
516 if (portionSize == 1)
531 node->
info = (*initialEltList)[medianId];
537 const unsigned thedim = depth % DIM;
538 auto medianVal = (*initialEltList)[medianId].dims[thedim];
539 leftRegion.
dimmax[thedim] = medianVal;
540 rightRegion.
dimmin[thedim] = medianVal;
546 node->
left = this->
recBuild(low, medianId, depth, leftRegion);
547 node->
right = this->
recBuild(medianId, high, depth, rightRegion);
554 #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.
KDTreeNodeT< DATA, DIM > * left
Left son.
KDTreeNodeT< DATA, DIM > * getNextNode()
Get the next node from the node pool.
~KDTreeLinkerAlgo()
Destructor calls clear.
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().
void swap(Handle< T > &a, Handle< T > &b)
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".
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
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 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...
void recSearch(const KDTreeNodeT< DATA, DIM > *current, const KDTreeBoxT< DIM > &trackBox)
Recursive kdtree search. Is called by search()
double median(sqlite3 *db, std::string const &table_name, std::string const &column_name)