Belle II Software development
BoxDivisionHoughTree.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9#include <tracking/trackFindingCDC/hough/trees/WeightedFastHoughTree.h>
10#include <tracking/trackFindingCDC/hough/baseelements/SectoredLinearDivision.h>
11
12#include <tracking/trackFindingCDC/numerics/LookupTable.h>
13
14#include <tracking/trackFindingCDC/utilities/TupleGenerate.h>
15
16#include <type_traits>
17#include <utility>
18#include <tuple>
19#include <array>
20#include <memory>
21
22namespace Belle2 {
27 namespace TrackFindingCDC {
28
33 template <class AItemPtr, class AHoughBox, size_t ... divisions>
35
36 public:
38 using HoughBox = AHoughBox;
39
42
45
47 template <size_t I>
48 using Type = typename HoughBox::template Type<I>;
49
51 template <class T>
52 using HasType = typename HoughBox::template HasType<T>;
53
55 template <class T>
56 using TypeIndex = typename HoughBox::template TypeIndex<T>;
57
59 template <size_t I>
60 using Width = typename HoughBox::template Width<I>;
61
63 using Node = typename HoughTree::Node;
64
65 public:
67 explicit BoxDivisionHoughTree(int maxLevel, int sectorLevelSkip = 0)
68 : m_maxLevel(maxLevel)
69 , m_sectorLevelSkip(sectorLevelSkip)
70 , m_overlaps((divisions * 0)...)
71 {
72 }
73
74 private:
76 template <size_t I>
77 using Array = typename Type<I>::Array;
78
80 using Arrays = TupleGenerateN<Array, sizeof...(divisions)>;
81
82 public:
84 size_t getDivision(size_t i) const
85 {
86 return m_divisions[i];
87 }
88
103 template <size_t I>
104 void constructArray(double lowerBound,
105 double upperBound,
106 Width<I> nBinOverlap = 0,
107 Width<I> nBinWidth = 0)
108 {
109 static_assert(std::is_integral<Width<I> >::value, "Method only applicable to discrete axes");
110 const size_t division = getDivision(I);
111 const int granularityLevel = m_maxLevel + m_sectorLevelSkip;
112 const size_t nBins = std::pow(division, granularityLevel);
113
114 if (nBinWidth == 0) {
115 nBinWidth = nBinOverlap + 1;
116 }
117
118 B2ASSERT("Width " << nBinWidth << "is not bigger than overlap " << nBinOverlap,
119 nBinOverlap < nBinWidth);
120
121 const auto nPositions = (nBinWidth - nBinOverlap) * nBins + nBinOverlap + 1;
122 std::get<I>(m_arrays) = linspace<float>(lowerBound, upperBound, nPositions);
123 std::get<I>(m_overlaps) = nBinOverlap;
124 }
125
127 template <size_t I>
128 void assignArray(Array<I> array, Width<I> overlap = 0)
129 {
130 std::get<I>(m_arrays) = std::move(array);
131 std::get<I>(m_overlaps) = overlap;
132
133 // In case of a discrete axes, check whether the size of the array is sensible
134 // such that the bin width at the highest granularity level is a whole number given the overlap.
135 if (std::is_integral<Width<I> >::value) {
136 const int division = getDivision(I);
137 const int granularityLevel = m_maxLevel + m_sectorLevelSkip;
138 const long int nBins = std::pow(division, granularityLevel);
139 const long int nPositions = std::get<I>(m_arrays).size();
140 const long int nWidthTimeNBins = nPositions - 1 + (nBins - 1) * overlap;
141
142 B2ASSERT("Not enough positions in array to cover all bins.\n"
143 "Expected: positions = " << nBins - (nBins - 1) * overlap + 1 << " at least.\n"
144 "Actual: positions = " << nPositions << " (overlap = " << overlap << ", bins = " << nBins << ")\n",
145 nWidthTimeNBins >= nBins);
146
147 B2ASSERT("Number of positions in array introduces inhomogeneous width at the highest granularity level.\n"
148 "Expected: positions = 'width * bins - (bins - 1) * overlap + 1'\n"
149 "Actual: positions = " << nPositions << " (overlap = " << overlap << ", bins = " << nBins << ")\n",
150 nWidthTimeNBins % nBins == 0);
151 }
152 }
153
155 template <class T>
156 std::enable_if_t< HasType<T>::value, void>
158 {
159 assignArray<TypeIndex<T>::value>(std::move(array), overlap);
160 }
161
162 public:
165 {
166 // Compose the hough space
167 HoughBox houghPlane = constructHoughPlane();
169 m_houghTree.reset(new HoughTree(std::move(houghPlane), std::move(boxDivision)));
170 }
171
173 template <class AItemPtrs>
174 void seed(const AItemPtrs& items)
175 {
176 if (not m_houghTree) initialize();
177 m_houghTree->seed(items);
178 }
179
181 void fell()
182 {
183 m_houghTree->fell();
184 }
185
187 void raze()
188 {
189 m_houghTree->raze();
190 }
191
192 public:
195 {
196 return m_houghTree.get();
197 }
198
200 int getMaxLevel() const
201 {
202 return m_maxLevel;
203 }
204
206 void setMaxLevel(int maxLevel)
207 {
208 m_maxLevel = maxLevel;
209 }
210
213 {
214 return m_sectorLevelSkip;
215 }
216
218 void setSectorLevelSkip(int sectorLevelSkip)
219 {
220 m_sectorLevelSkip = sectorLevelSkip;
221 }
222
224 template <size_t I>
225 const Array<I>& getArray() const
226 {
227 return std::get<I>(m_arrays);
228 }
229
230 private:
232 template <size_t... Is>
233 HoughBox constructHoughPlaneImpl(const std::index_sequence<Is...>& is __attribute__((unused)))
234 {
235 return HoughBox(Type<Is>::getRange(std::get<Is>(m_arrays))...);
236 }
237
240 {
241 return constructHoughPlaneImpl(std::make_index_sequence<sizeof...(divisions)>());
242 }
243
244 private:
247
250
252 const std::array<size_t, sizeof ...(divisions)> m_divisions = {{divisions ...}};
253
255 typename HoughBox::Delta m_overlaps;
256
259
261 std::unique_ptr<HoughTree> m_houghTree = nullptr;
262 };
263 }
265}
A fast hough algorithm with rectangular boxes, which are split linearly by a fixed number of division...
void fell()
Terminates the processing by striping all hit information from the tree.
typename Type< I >::Array Array
Type of the discrete value array to coordinate index I.
AHoughBox HoughBox
Type of the box in the hough space.
void initialize()
Initialise the algorithm by constructing the hough tree from the parameters.
void raze()
Release all memory that the tree aquired during the runs.
typename HoughTree::Node Node
Type of the nodes used in the tree for the search.
void setSectorLevelSkip(int sectorLevelSkip)
Setter for number of levels to skip in first level to form a finer sectored hough space.
Arrays m_arrays
A tuple of value arrays providing the memory for the discrete bin bounds.
HoughBox constructHoughPlaneImpl(const std::index_sequence< Is... > &is)
Construct the box of the top node of the tree. Implementation unroling the indices.
int m_sectorLevelSkip
Number of levels to skip in first level to form a finer sectored hough space.
typename HoughBox::template Type< I > Type
Type of the coordinate I.
TupleGenerateN< Array, sizeof...(divisions)> Arrays
Tuple type of the discrete value arrays.
void setMaxLevel(int maxLevel)
Setter maximal level of the hough tree.
int m_maxLevel
Number of the maximum tree level.
size_t getDivision(size_t i) const
Getter the number of divisions at each level for coordinate index I.
typename HoughBox::template TypeIndex< T > TypeIndex
Function to get the coordinate index from its type.
const Array< I > & getArray() const
Getter for the array of discrete value for coordinate I.
typename HoughBox::template HasType< T > HasType
Predicate that the given type is indeed a coordinate of the hough space.
void seed(const AItemPtrs &items)
Prepare the leave finding by filling the top node with given hits.
HoughBox::Delta m_overlaps
An tuple of division overlaps in each coordinate.
HoughBox constructHoughPlane()
Construct the box of the top node of the tree.
int getSectorLevelSkip() const
Getter for number of levels to skip in first level to form a finer sectored hough space.
typename HoughBox::template Width< I > Width
Type of the width in coordinate I.
std::unique_ptr< HoughTree > m_houghTree
Dynamic hough tree structure traversed in the leaf search.
void assignArray(Array< I > array, Width< I > overlap=0)
Provide an externally constructed array by coordinate index.
std::enable_if_t< HasType< T >::value, void > assignArray(Array< TypeIndex< T >::value > array, Width< TypeIndex< T >::value > overlap=0)
Provide an externally constructed array by coordinate type.
WeightedFastHoughTree< AItemPtr, HoughBox, BoxDivision > HoughTree
Type of the fast hough tree structure.
int getMaxLevel() const
Getter for the currently set maximal level.
const std::array< size_t, sizeof ...(divisions)> m_divisions
Array of the number of divisions at each level.
BoxDivisionHoughTree(int maxLevel, int sectorLevelSkip=0)
Constructor using the given maximal level.
void constructArray(double lowerBound, double upperBound, Width< I > nBinOverlap=0, Width< I > nBinWidth=0)
Construct the discrete value array at coordinate index I.
HoughTree * getTree() const
Getter for the tree used in the search in the hough plane.
Factory object that constructs sub boxes from a given box with optional overlaps.
Dynamic tree structure with weighted items in each node which are markable through out the tree.
typename Super::Node Node
Type of the node in the tree.
Abstract base class for different kinds of events.