Belle II Software  release-05-01-25
SectoredLinearDivision.h
1 /**************************************************************************
2 * BASF2 (Belle Analysis Framework 2) *
3 * Copyright(C) 2015 - Belle II Collaboration *
4 * *
5 * Author: The Belle II Collaboration *
6 * Contributors: Oliver Frost *
7 * *
8 * This software is provided "as is" without any warranty. *
9 **************************************************************************/
10 #pragma once
11 
12 #include <tracking/trackFindingCDC/utilities/Product.h>
13 
14 #include <framework/utilities/Utils.h>
15 
16 #include <utility>
17 #include <vector>
18 #include <cassert>
19 
20 namespace Belle2 {
25  namespace TrackFindingCDC {
26 
47  template<class ABox, std::size_t... divisions>
48  class SectoredLinearDivision {
49 
50  public:
52  static const std::size_t s_nSubBoxes = Product<divisions...>::value;
53 
54  private:
56  static constexpr std::size_t s_divisions[sizeof...(divisions)] = {divisions...};
57 
58  public:
60  explicit SectoredLinearDivision(const typename ABox::Delta& overlaps = typename ABox::Delta(),
61  int sectorLevelSkip = 0)
62  : m_overlaps(overlaps)
63  , m_sectorLevelSkip(sectorLevelSkip)
64  {
65  }
66 
67  public:
69  template <class ANode>
70  std::vector<ABox> operator()(const ANode& node)
71  {
72  const ABox& box = node;
73  if (branch_unlikely(node.getLevel() == 0)) {
74  std::vector<ABox> result = makeSubBoxes(box, std::make_index_sequence<s_nSubBoxes>());
75  // Apply further divisions sectorLevelSkip times and return all boxes.
76  for (int iSkipped = 0; iSkipped < m_sectorLevelSkip; ++iSkipped) {
77  std::vector<ABox> sectoredBoxes;
78  sectoredBoxes.reserve(result.size() * s_nSubBoxes);
79  for (const ABox& boxToDivide : result) {
80  for (const ABox& dividedBox : makeSubBoxes(boxToDivide, std::make_index_sequence<s_nSubBoxes>())) {
81  sectoredBoxes.push_back(dividedBox);
82  }
83  }
84  result = std::move(sectoredBoxes);
85  }
86 
87  return result;
88  }
89  return makeSubBoxes(box, std::make_index_sequence<s_nSubBoxes>());
90  }
91 
93  template<std::size_t... Is>
94  std::vector<ABox>
95  makeSubBoxes(const ABox& box, std::index_sequence<Is...> /*globalSubBoxIndex*/)
96  {
97  return {{ makeSubBox(box, Is, std::make_index_sequence<sizeof...(divisions)>())... }};
98  }
99 
101  template <std::size_t... Is>
102  ABox makeSubBox(const ABox& box, std::size_t globalISubBox, std::index_sequence<Is...> /*coordinatesIndex*/)
103  {
104  std::array<std::size_t, sizeof...(divisions)> indices;
105  for (size_t c_Index = 0 ; c_Index < sizeof...(divisions); ++c_Index) {
106  indices[c_Index] = globalISubBox % s_divisions[c_Index];
107  globalISubBox /= s_divisions[c_Index];
108  }
109  assert(globalISubBox == 0);
110  return ABox(box.template getDivisionBoundsWithOverlap<Is>(std::get<Is>(m_overlaps),
111  s_divisions[Is],
112  indices[Is]) ...);
113  }
114 
115  private:
117  typename ABox::Delta m_overlaps;
118 
120  int m_sectorLevelSkip;
121  };
122 
123  // Extra mention of the constexpr such that it aquires external linkage.
124  template<class ABox, std::size_t... divisions>
125  constexpr std::size_t SectoredLinearDivision<ABox, divisions...>::s_divisions[sizeof...(divisions)];
126  }
128 }
Belle2::TrackFindingCDC::SectoredLinearDivision::operator()
std::vector< ABox > operator()(const ANode &node)
Factory method to construct the subboxes with overlap from the given box.
Definition: SectoredLinearDivision.h:78
Belle2::TrackFindingCDC::SectoredLinearDivision::s_divisions
static constexpr std::size_t s_divisions[sizeof...(divisions)]
Array of the number of divisions for each dimension.
Definition: SectoredLinearDivision.h:64
Belle2::TrackFindingCDC::SectoredLinearDivision::m_sectorLevelSkip
int m_sectorLevelSkip
Number of levels to be skipped to form the finer binning at level 1.
Definition: SectoredLinearDivision.h:128
Belle2::TrackFindingCDC::SectoredLinearDivision::m_overlaps
ABox::Delta m_overlaps
Custom overlaps of the bounds at each division for each dimension.
Definition: SectoredLinearDivision.h:125
branch_unlikely
#define branch_unlikely(x)
A macro to tell the compiler that the argument x will be very likely be false.
Definition: Utils.h:148
Belle2::TrackFindingCDC::SectoredLinearDivision::makeSubBox
ABox makeSubBox(const ABox &box, std::size_t globalISubBox, std::index_sequence< Is... >)
Make the subbox with overlaps of the given box at global index.
Definition: SectoredLinearDivision.h:110
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TrackFindingCDC::SectoredLinearDivision::SectoredLinearDivision
SectoredLinearDivision(const typename ABox::Delta &overlaps=typename ABox::Delta(), int sectorLevelSkip=0)
Initialise the sub box factory with specific overlaps.
Definition: SectoredLinearDivision.h:68
Belle2::TrackFindingCDC::SectoredLinearDivision::makeSubBoxes
std::vector< ABox > makeSubBoxes(const ABox &box, std::index_sequence< Is... >)
Make all subboxs with overlap of the given box.
Definition: SectoredLinearDivision.h:103
Belle2::TrackFindingCDC::SectoredLinearDivision
Factory object that constructs sub boxes from a given box with optional overlaps.
Definition: SectoredLinearDivision.h:56
Belle2::TrackFindingCDC::SectoredLinearDivision::s_nSubBoxes
static const std::size_t s_nSubBoxes
Number of sub boxes produced by this factory facility.
Definition: SectoredLinearDivision.h:60