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);
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>
167 closestNeighbour(nullptr),
168 initialEltList(nullptr)
174 template <
typename DATA,
unsigned DIM>
182 template <
typename DATA,
unsigned DIM>
187 initialEltList = &eltList;
188 const size_t mysize = initialEltList->size();
190 nodePoolSize_ = mysize * 2 - 1;
194 root_ = this->recBuild(0, mysize, 0, region);
195 initialEltList =
nullptr;
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;
224 while ((*initialEltList)[i].dims[thedim] < elt.
dims[thedim])
226 while ((*initialEltList)[j].dims[thedim] > elt.
dims[thedim])
231 std::swap((*initialEltList)[i], (*initialEltList)[j]);
248 template <
typename DATA,
unsigned DIM>
253 closestNeighbour = &recHits;
254 this->recSearch(root_, trackBox);
255 closestNeighbour =
nullptr;
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];
282 closestNeighbour->push_back(current->
info);
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)
301 this->addSubtree(current->
left);
303 else if (hasIntersection)
305 this->recSearch(current->
left, trackBox);
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)
322 this->addSubtree(current->
right);
324 else if (hasIntersection)
326 this->recSearch(current->
right, trackBox);
333 template <
typename DATA,
unsigned DIM>
337 if (
nullptr != result || distance != std::numeric_limits<float>::max())
340 distance = std::numeric_limits<float>::max();
346 this->recNearestNeighbour(0, root_, point, best_match, distance);
348 if (distance != std::numeric_limits<float>::max())
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)
366 best_match = current;
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)
376 this->recNearestNeighbour(depth + 1, current->
left, point, best_match, best_dist);
380 this->recNearestNeighbour(depth + 1, current->
right, point, best_match, best_dist);
384 const float dist_current = this->dist2(point, current->
info);
386 if (dist_current < best_dist)
388 best_dist = dist_current;
389 best_match = current;
393 if (best_dist > dist_to_axis * dist_to_axis)
397 float check_dist = best_dist;
399 if (dist_to_axis < 0.f)
401 this->recNearestNeighbour(depth + 1, current->
right, point, check_best, check_dist);
405 this->recNearestNeighbour(depth + 1, current->
left, point, check_best, check_dist);
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))
429 closestNeighbour->push_back(current->
info);
434 this->addSubtree(current->
left);
435 this->addSubtree(current->
right);
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>
472 return (nodePoolPos_ == -1);
477 template <
typename DATA,
unsigned DIM>
480 return (nodePoolPos_ + 1);
485 template <
typename DATA,
unsigned DIM>
494 template <
typename DATA,
unsigned DIM>
503 return &(nodePool_[nodePoolPos_]);
508 template <
typename DATA,
unsigned DIM>
511 const int portionSize = high -
low;
516 if (portionSize == 1)
526 int medianId = this->medianSearch(low, high, depth);
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
std::vector< KDTreeNodeInfoT< DATA, DIM > > * initialEltList
The initial element list.
std::vector< KDTreeNodeInfoT< DATA, DIM > > * closestNeighbour
The closest neighbour.
int nodePoolSize_
The node pool size.
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.
KDTreeLinkerAlgo()
Default constructor.
int size()
Return the number of nodes + leaves in the tree (nElements should be (size() +1) / 2) ...
KDTreeNodeT< DATA, DIM > * root_
The KDTree root.
void clear()
Clear all allocated structures.
int nodePoolPos_
The node pool position.
KDTreeNodeT< DATA, DIM > * right
Right son.
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
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()
standard_dbscan3dalg useful for diagnostics hits not in a line will not be clustered on on only for track like only for track like on on the smaller the less shower like tracks low
void findNearestNeighbour(const KDTreeNodeInfoT< DATA, DIM > &point, const KDTreeNodeInfoT< DATA, DIM > *&result, float &distance)
findNearestNeighbour
void clearTree()
Frees the KDTree.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
KDTreeNodeT< DATA, DIM > * nodePool_
Node pool allows us to do just 1 call to new for each tree building.
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
std::array< float, DIM > dims
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void addSubtree(const KDTreeNodeT< DATA, DIM > *current)
Add all elements of an subtree to the closest elements. Used during the recSearch().
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".
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()