Belle II Software  release-08-01-10
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 
22 namespace 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:
164  void initialize()
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 
212  int getSectorLevelSkip() const
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.
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.
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.
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.
const Array< I > & getArray() const
Getter for the array of discrete value for coordinate I.
HoughTree * getTree() const
Getter for the tree used in the search in the hough plane.
void assignArray(Array< I > array, Width< I > overlap=0)
Provide an externally constructed array by coordinate index.
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.
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.