CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
KDTreeLinkerAlgo< DATA, DIM > Class Template Reference

#include <KDTreeLinkerAlgo.h>

Public Member Functions

void build (std::vector< KDTreeNodeInfo< DATA, DIM > > &eltList, const KDTreeBox< DIM > &region)
 
void clear ()
 
bool empty ()
 
void search (const KDTreeBox< DIM > &searchBox, std::vector< DATA > &resRecHitList)
 
int size ()
 
 ~KDTreeLinkerAlgo ()
 

Private Member Functions

void clearTree ()
 
int medianSearch (int low, int high, int treeDepth) const
 
int recBuild (int low, int hight, int depth)
 
void recSearch (int current, const KDTreeBox< DIM > &trackBox, int depth=0) const
 

Private Attributes

std::vector< DATA > * closestNeighbour
 
std::vector< KDTreeNodeInfo< DATA, DIM > > * initialEltList
 
KDTreeNodes< DATA, DIMnodePool_
 

Detailed Description

template<typename DATA, unsigned int DIM = 2>
class KDTreeLinkerAlgo< DATA, DIM >

Definition at line 105 of file KDTreeLinkerAlgo.h.

Constructor & Destructor Documentation

◆ ~KDTreeLinkerAlgo()

template<typename DATA, unsigned int DIM = 2>
KDTreeLinkerAlgo< DATA, DIM >::~KDTreeLinkerAlgo ( )
inline

Definition at line 108 of file KDTreeLinkerAlgo.h.

108 { clear(); }

Member Function Documentation

◆ build()

template<typename DATA, unsigned int DIM>
void KDTreeLinkerAlgo< DATA, DIM >::build ( std::vector< KDTreeNodeInfo< DATA, DIM > > &  eltList,
const KDTreeBox< DIM > &  region 
)

Definition at line 150 of file KDTreeLinkerAlgo.h.

Referenced by KDTreeLinkerTrackEcal::buildTree(), KDTreeLinkerTrackHcal::buildTree(), HGCalImagingAlgo::findAndAssignClusters(), HGCalImagingAlgo::makeClusters(), and psClasses.BuildThread::run().

151  {
152  if (!eltList.empty()) {
153  initialEltList = &eltList;
154 
155  size_t size = initialEltList->size();
156  nodePool_.build(size);
157 
158  // Here we build the KDTree
159  int root = recBuild(0, size, 0);
160  assert(root == 0);
161 
162  initialEltList = nullptr;
163  }
164 }
KDTreeNodes< DATA, DIM > nodePool_
int recBuild(int low, int hight, int depth)
assert(be >=bs)
std::vector< KDTreeNodeInfo< DATA, DIM > > * initialEltList

◆ clear()

template<typename DATA, unsigned int DIM = 2>
void KDTreeLinkerAlgo< DATA, DIM >::clear ( void  )
inline

◆ clearTree()

template<typename DATA, unsigned int DIM = 2>
void KDTreeLinkerAlgo< DATA, DIM >::clearTree ( )
inlineprivate

Definition at line 144 of file KDTreeLinkerAlgo.h.

Referenced by KDTreeLinkerAlgo< reco::PFRecHit const *>::clear().

144 { nodePool_.clear(); }
KDTreeNodes< DATA, DIM > nodePool_

◆ empty()

template<typename DATA, unsigned int DIM = 2>
bool KDTreeLinkerAlgo< DATA, DIM >::empty ( )
inline

Definition at line 118 of file KDTreeLinkerAlgo.h.

118 { return nodePool_.empty(); }
KDTreeNodes< DATA, DIM > nodePool_

◆ medianSearch()

template<typename DATA , unsigned int DIM>
int KDTreeLinkerAlgo< DATA, DIM >::medianSearch ( int  low,
int  high,
int  treeDepth 
) const
private

Definition at line 168 of file KDTreeLinkerAlgo.h.

168  {
169  int nbrElts = high - low;
170  int median = (nbrElts & 1) ? nbrElts / 2 : nbrElts / 2 - 1;
171  median += low;
172 
173  int l = low;
174  int m = high - 1;
175 
176  while (l < m) {
177  KDTreeNodeInfo<DATA, DIM> elt = (*initialEltList)[median];
178  int i = l;
179  int j = m;
180 
181  do {
182  // The even depth is associated to dim1 dimension
183  // The odd one to dim2 dimension
184  const unsigned thedim = treeDepth % DIM;
185  while ((*initialEltList)[i].dims[thedim] < elt.dims[thedim])
186  ++i;
187  while ((*initialEltList)[j].dims[thedim] > elt.dims[thedim])
188  --j;
189 
190  if (i <= j) {
192  i++;
193  j--;
194  }
195  } while (i <= j);
196  if (j < median)
197  l = i;
198  if (i > median)
199  m = j;
200  }
201 
202  return median;
203 }
#define DIM(a)
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
std::array< float, DIM > dims
std::vector< KDTreeNodeInfo< DATA, DIM > > * initialEltList
T median(std::vector< T > values)
Definition: median.h:16

◆ recBuild()

template<typename DATA , unsigned int DIM>
int KDTreeLinkerAlgo< DATA, DIM >::recBuild ( int  low,
int  hight,
int  depth 
)
private

Definition at line 262 of file KDTreeLinkerAlgo.h.

262  {
263  int portionSize = high - low;
264 
265  if (portionSize == 1) { // Leaf case
266  int leaf = nodePool_.getNextNode();
267  const KDTreeNodeInfo<DATA, DIM> &info = (*initialEltList)[low];
268  nodePool_.right[leaf] = 0;
269  for (unsigned i = 0; i < DIM; ++i) {
270  nodePool_.dims[i][leaf] = info.dims[i];
271  }
272  nodePool_.data[leaf] = info.data;
273  return leaf;
274 
275  } else { // Node case
276 
277  // The even depth is associated to dim1 dimension
278  // The odd one to dim2 dimension
279  int medianId = medianSearch(low, high, depth);
280  int dimIndex = depth % DIM;
281  float medianVal = (*initialEltList)[medianId].dims[dimIndex];
282 
283  // We create the node
284  int nodeInd = nodePool_.getNextNode();
285 
286  ++depth;
287  ++medianId;
288 
289  // We recursively build the son nodes
290  int left = recBuild(low, medianId, depth);
291  assert(nodeInd + 1 == left);
292  int right = recBuild(medianId, high, depth);
293  nodePool_.right[nodeInd] = right;
294 
295  nodePool_.dims[dimIndex][nodeInd] = medianVal;
296 
297  return nodeInd;
298  }
299 }
static const TGPicture * info(bool iBackgroundIsBlack)
KDTreeNodes< DATA, DIM > nodePool_
int recBuild(int low, int hight, int depth)
#define DIM(a)
assert(be >=bs)
int medianSearch(int low, int high, int treeDepth) const

◆ recSearch()

template<typename DATA , unsigned int DIM>
void KDTreeLinkerAlgo< DATA, DIM >::recSearch ( int  current,
const KDTreeBox< DIM > &  trackBox,
int  depth = 0 
) const
private

Definition at line 215 of file KDTreeLinkerAlgo.h.

215  {
216  // Iterate until leaf is found, or there are no children in the
217  // search window. If search has to proceed on both children, proceed
218  // the search to left child via recursion. Swap search window
219  // dimension on alternate levels.
220  while (true) {
221  const int dimIndex = depth % DIM;
222  int right = nodePool_.right[current];
223  if (nodePool_.isLeaf(right)) {
224  // If point inside the rectangle/area
225  // Use intentionally bit-wise & instead of logical && for better
226  // performance. It is faster to always do all comparisons than to
227  // allow use of branches to not do some if any of the first ones
228  // is false.
229  bool isInside = true;
230  for (unsigned i = 0; i < DIM; ++i) {
231  float dimCurr = nodePool_.dims[i][current];
232  isInside &= (dimCurr >= trackBox.dimmin[i]) && (dimCurr <= trackBox.dimmax[i]);
233  }
234  if (isInside) {
235  closestNeighbour->push_back(nodePool_.data[current]);
236  }
237  break;
238  } else {
239  float median = nodePool_.dims[dimIndex][current];
240 
241  bool goLeft = (trackBox.dimmin[dimIndex] <= median);
242  bool goRight = (trackBox.dimmax[dimIndex] >= median);
243 
244  ++depth;
245  if (goLeft & goRight) {
246  int left = current + 1;
247  recSearch(left, trackBox, depth);
248  // continue with right
249  current = right;
250  } else if (goLeft) {
251  ++current;
252  } else if (goRight) {
253  current = right;
254  } else {
255  break;
256  }
257  }
258  }
259 }
KDTreeNodes< DATA, DIM > nodePool_
std::vector< DATA > * closestNeighbour
#define DIM(a)
std::array< float, DIM > dimmin
void recSearch(int current, const KDTreeBox< DIM > &trackBox, int depth=0) const
std::array< float, DIM > dimmax
T median(std::vector< T > values)
Definition: median.h:16

◆ search()

template<typename DATA, unsigned int DIM>
void KDTreeLinkerAlgo< DATA, DIM >::search ( const KDTreeBox< DIM > &  searchBox,
std::vector< DATA > &  resRecHitList 
)

Definition at line 206 of file KDTreeLinkerAlgo.h.

Referenced by HGCalImagingAlgo::calculateLocalDensity(), HGCalImagingAlgo::findAndAssignClusters(), KDTreeLinkerPSEcal::searchLinks(), KDTreeLinkerTrackEcal::searchLinks(), and KDTreeLinkerTrackHcal::searchLinks().

206  {
207  if (!empty()) {
209  recSearch(0, trackBox, 0);
210  closestNeighbour = nullptr;
211  }
212 }
std::vector< DATA > * closestNeighbour
void recSearch(int current, const KDTreeBox< DIM > &trackBox, int depth=0) const

◆ size()

template<typename DATA, unsigned int DIM = 2>
int KDTreeLinkerAlgo< DATA, DIM >::size ( void  )
inline

Definition at line 122 of file KDTreeLinkerAlgo.h.

Referenced by ntupleDataFormat._Collection::__iter__(), and ntupleDataFormat._Collection::__len__().

122 { return nodePool_.size(); }
KDTreeNodes< DATA, DIM > nodePool_

Member Data Documentation

◆ closestNeighbour

template<typename DATA, unsigned int DIM = 2>
std::vector<DATA>* KDTreeLinkerAlgo< DATA, DIM >::closestNeighbour
private

Definition at line 131 of file KDTreeLinkerAlgo.h.

◆ initialEltList

template<typename DATA, unsigned int DIM = 2>
std::vector<KDTreeNodeInfo<DATA, DIM> >* KDTreeLinkerAlgo< DATA, DIM >::initialEltList
private

Definition at line 132 of file KDTreeLinkerAlgo.h.

◆ nodePool_

template<typename DATA, unsigned int DIM = 2>
KDTreeNodes<DATA, DIM> KDTreeLinkerAlgo< DATA, DIM >::nodePool_
private