Belle II Software development
SectoredLinearDivision.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
10#include <tracking/trackFindingCDC/utilities/Product.h>
11
12#include <framework/utilities/Utils.h>
13
14#include <utility>
15#include <vector>
16#include <cassert>
17
18namespace Belle2 {
23 namespace TrackFindingCDC {
24
45 template<class ABox, std::size_t... divisions>
47
48 public:
50 static const std::size_t s_nSubBoxes = Product<divisions...>::value;
51
52 private:
54 static constexpr std::size_t s_divisions[sizeof...(divisions)] = {divisions...};
55
56 public:
58 explicit SectoredLinearDivision(const typename ABox::Delta& overlaps = typename ABox::Delta(),
59 int sectorLevelSkip = 0)
60 : m_overlaps(overlaps)
61 , m_sectorLevelSkip(sectorLevelSkip)
62 {
63 }
64
65 public:
67 template <class ANode>
68 std::vector<ABox> operator()(const ANode& node)
69 {
70 const ABox& box = node;
71 if (branch_unlikely(node.getLevel() == 0)) {
72 std::vector<ABox> result = makeSubBoxes(box, std::make_index_sequence<s_nSubBoxes>());
73 // Apply further divisions sectorLevelSkip times and return all boxes.
74 for (int iSkipped = 0; iSkipped < m_sectorLevelSkip; ++iSkipped) {
75 std::vector<ABox> sectoredBoxes;
76 sectoredBoxes.reserve(result.size() * s_nSubBoxes);
77 for (const ABox& boxToDivide : result) {
78 for (const ABox& dividedBox : makeSubBoxes(boxToDivide, std::make_index_sequence<s_nSubBoxes>())) {
79 sectoredBoxes.push_back(dividedBox);
80 }
81 }
82 result = std::move(sectoredBoxes);
83 }
84
85 return result;
86 }
87 return makeSubBoxes(box, std::make_index_sequence<s_nSubBoxes>());
88 }
89
91 template<std::size_t... Is>
92 std::vector<ABox>
93 makeSubBoxes(const ABox& box, std::index_sequence<Is...> /*globalSubBoxIndex*/)
94 {
95 return {{ makeSubBox(box, Is, std::make_index_sequence<sizeof...(divisions)>())... }};
96 }
97
99 template <std::size_t... Is>
100 ABox makeSubBox(const ABox& box, std::size_t globalISubBox, std::index_sequence<Is...> /*coordinatesIndex*/)
101 {
102 std::array<std::size_t, sizeof...(divisions)> indices;
103 for (size_t c_Index = 0 ; c_Index < sizeof...(divisions); ++c_Index) {
104 indices[c_Index] = globalISubBox % s_divisions[c_Index];
105 globalISubBox /= s_divisions[c_Index];
106 }
107 assert(globalISubBox == 0);
108 return ABox(box.template getDivisionBoundsWithOverlap<Is>(std::get<Is>(m_overlaps),
109 s_divisions[Is],
110 indices[Is]) ...);
111 }
112
113 private:
115 typename ABox::Delta m_overlaps;
116
119 };
120
121 // Extra mention of the constexpr such that it aquires external linkage.
122 template<class ABox, std::size_t... divisions>
123 constexpr std::size_t SectoredLinearDivision<ABox, divisions...>::s_divisions[sizeof...(divisions)];
124 }
126}
Factory object that constructs sub boxes from a given box with optional overlaps.
std::vector< ABox > operator()(const ANode &node)
Factory method to construct the subboxes with overlap from the given box.
int m_sectorLevelSkip
Number of levels to be skipped to form the finer binning at level 1.
static constexpr std::size_t s_divisions[sizeof...(divisions)]
Array of the number of divisions for each dimension.
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.
std::vector< ABox > makeSubBoxes(const ABox &box, std::index_sequence< Is... >)
Make all subboxs with overlap of the given box.
static const std::size_t s_nSubBoxes
Number of sub boxes produced by this factory facility.
ABox::Delta m_overlaps
Custom overlaps of the bounds at each division for each dimension.
SectoredLinearDivision(const typename ABox::Delta &overlaps=typename ABox::Delta(), int sectorLevelSkip=0)
Initialise the sub box factory with specific overlaps.
#define branch_unlikely(x)
A macro to tell the compiler that the argument x will be very likely be false.
Definition: Utils.h:134
Abstract base class for different kinds of events.
Template class for compile time computation of products.
Definition: Product.h:21