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 102 of file KDTreeLinkerAlgo.h.

Constructor & Destructor Documentation

◆ ~KDTreeLinkerAlgo()

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

Definition at line 105 of file KDTreeLinkerAlgo.h.

105 { 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 147 of file KDTreeLinkerAlgo.h.

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

148  {
149  if (!eltList.empty()) {
150  initialEltList = &eltList;
151 
152  size_t size = initialEltList->size();
153  nodePool_.build(size);
154 
155  // Here we build the KDTree
156  int root = recBuild(0, size, 0);
157  assert(root == 0);
158 
159  initialEltList = nullptr;
160  }
161 }
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 141 of file KDTreeLinkerAlgo.h.

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

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

◆ empty()

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

Definition at line 115 of file KDTreeLinkerAlgo.h.

115 { 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 165 of file KDTreeLinkerAlgo.h.

165  {
166  int nbrElts = high - low;
167  int median = (nbrElts & 1) ? nbrElts / 2 : nbrElts / 2 - 1;
168  median += low;
169 
170  int l = low;
171  int m = high - 1;
172 
173  while (l < m) {
174  KDTreeNodeInfo<DATA, DIM> elt = (*initialEltList)[median];
175  int i = l;
176  int j = m;
177 
178  do {
179  // The even depth is associated to dim1 dimension
180  // The odd one to dim2 dimension
181  const unsigned thedim = treeDepth % DIM;
182  while ((*initialEltList)[i].dims[thedim] < elt.dims[thedim])
183  ++i;
184  while ((*initialEltList)[j].dims[thedim] > elt.dims[thedim])
185  --j;
186 
187  if (i <= j) {
189  i++;
190  j--;
191  }
192  } while (i <= j);
193  if (j < median)
194  l = i;
195  if (i > median)
196  m = j;
197  }
198 
199  return median;
200 }
#define DIM(a)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
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 259 of file KDTreeLinkerAlgo.h.

259  {
260  int portionSize = high - low;
261 
262  if (portionSize == 1) { // Leaf case
263  int leaf = nodePool_.getNextNode();
264  const KDTreeNodeInfo<DATA, DIM> &info = (*initialEltList)[low];
265  nodePool_.right[leaf] = 0;
266  for (unsigned i = 0; i < DIM; ++i) {
267  nodePool_.dims[i][leaf] = info.dims[i];
268  }
269  nodePool_.data[leaf] = info.data;
270  return leaf;
271 
272  } else { // Node case
273 
274  // The even depth is associated to dim1 dimension
275  // The odd one to dim2 dimension
276  int medianId = medianSearch(low, high, depth);
277  int dimIndex = depth % DIM;
278  float medianVal = (*initialEltList)[medianId].dims[dimIndex];
279 
280  // We create the node
281  int nodeInd = nodePool_.getNextNode();
282 
283  ++depth;
284  ++medianId;
285 
286  // We recursively build the son nodes
287  int left = recBuild(low, medianId, depth);
288  assert(nodeInd + 1 == left);
289  int right = recBuild(medianId, high, depth);
290  nodePool_.right[nodeInd] = right;
291 
292  nodePool_.dims[dimIndex][nodeInd] = medianVal;
293 
294  return nodeInd;
295  }
296 }
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 212 of file KDTreeLinkerAlgo.h.

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

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

203  {
204  if (!empty()) {
206  recSearch(0, trackBox, 0);
207  closestNeighbour = nullptr;
208  }
209 }
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 119 of file KDTreeLinkerAlgo.h.

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

119 { 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 128 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 129 of file KDTreeLinkerAlgo.h.

◆ nodePool_

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