1 #ifndef KDTreeLinkerAlgoTemplated_h
2 #define KDTreeLinkerAlgoTemplated_h
13 template <
unsigned DIM = 2>
17 template <
typename... Ts>
19 static_assert(
sizeof...(dimargs) == 2 *
DIM,
"Constructor requires 2*DIM args");
20 std::vector<float> dims = {dimargs...};
21 for (
unsigned i = 0;
i <
DIM; ++
i) {
33 template <
typename DATA,
unsigned DIM = 2>
36 std::array<float, DIM>
dims;
41 template <
typename... Ts>
43 template <
typename... Ts>
49 template <
typename DATA,
unsigned DIM = 2>
64 for (
auto &dim :
dims) {
80 for (
auto &dim :
dims) {
101 template <
typename DATA,
unsigned int DIM = 2>
132 int medianSearch(
int low,
int high,
int treeDepth)
const;
146 template <
typename DATA,
unsigned int DIM>
149 if (!eltList.empty()) {
150 initialEltList = &eltList;
152 size_t size = initialEltList->size();
153 nodePool_.build(size);
156 int root = recBuild(0, size, 0);
159 initialEltList =
nullptr;
164 template <
typename DATA,
unsigned int DIM>
166 int nbrElts = high - low;
167 int median = (nbrElts & 1) ? nbrElts / 2 : nbrElts / 2 - 1;
181 const unsigned thedim = treeDepth %
DIM;
182 while ((*initialEltList)[
i].dims[thedim] < elt.
dims[thedim])
184 while ((*initialEltList)[
j].dims[thedim] > elt.
dims[thedim])
188 std::swap((*initialEltList)[i], (*initialEltList)[j]);
202 template <
typename DATA,
unsigned int DIM>
206 recSearch(0, trackBox, 0);
207 closestNeighbour =
nullptr;
211 template <
typename DATA,
unsigned int DIM>
218 const int dimIndex = depth %
DIM;
219 int right = nodePool_.right[current];
220 if (nodePool_.isLeaf(right)) {
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]);
232 closestNeighbour->push_back(nodePool_.data[current]);
236 float median = nodePool_.dims[dimIndex][current];
242 if (goLeft & goRight) {
243 int left = current + 1;
244 recSearch(left, trackBox, depth);
249 }
else if (goRight) {
258 template <
typename DATA,
unsigned int DIM>
260 int portionSize = high - low;
262 if (portionSize == 1) {
263 int leaf = nodePool_.getNextNode();
265 nodePool_.right[leaf] = 0;
266 for (
unsigned i = 0;
i <
DIM; ++
i) {
267 nodePool_.dims[
i][leaf] = info.
dims[
i];
269 nodePool_.data[leaf] = info.
data;
276 int medianId = medianSearch(low, high, depth);
277 int dimIndex = depth %
DIM;
278 float medianVal = (*initialEltList)[medianId].dims[dimIndex];
281 int nodeInd = nodePool_.getNextNode();
287 int left = recBuild(low, medianId, depth);
288 assert(nodeInd + 1 == left);
289 int right = recBuild(medianId, high, depth);
290 nodePool_.right[nodeInd] = right;
292 nodePool_.dims[dimIndex][nodeInd] = medianVal;
KDTreeNodes< DATA, DIM > nodePool_
int medianSearch(int low, int high, int treeDepth) const
void search(const KDTreeBox< DIM > &searchBox, std::vector< DATA > &resRecHitList)
std::array< std::vector< float >, DIM > dims
int recBuild(int low, int hight, int depth)
std::vector< DATA > * closestNeighbour
std::array< float, DIM > dimmin
bool operator>(DTCELinkId const &lhs, DTCELinkId const &rhs)
KDTreeNodeInfo(const DATA &d, Ts...dimargs)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
constexpr bool isLeaf(int right) const
bool isLeafIndex(int index) const
std::array< float, DIM > dims
void build(std::vector< KDTreeNodeInfo< DATA, DIM > > &eltList, const KDTreeBox< DIM > ®ion)
std::vector< KDTreeNodeInfo< DATA, DIM > > * initialEltList
std::array< float, DIM > dimmax
void recSearch(int current, const KDTreeBox< DIM > &trackBox, int depth=0) const
tuple size
Write out results.