Back to home page

EIC code displayed by LXR

 
 

    


Warning, /acts/docs/core/misc/grid_axis.md is written in an unsupported language. File is not indexed.

0001 # Grid and axis
0002 
0003 The `Grid` template class provides a generic binned `Grid` implementation in $N$ dimensions. `Grid` accepts a variadic list of `Axis` types, where the number of axes equals the number of desired dimensions of the `Grid`.
0004 
0005 ## Axis
0006 `Axis` accepts two template parameters:
0007 
0008 ```cpp
0009 template <AxisType type,
0010           AxisBoundaryType bdt = AxisBoundaryType::Open>
0011 class Axis;
0012 ```
0013 
0014 where
0015 ```cpp
0016 enum class AxisBoundaryType { Open, Bound, Closed };
0017 enum class AxisType { Equidistant, Variable };
0018 ```
0019 
0020 ### AxisType
0021 
0022 `AxisType` defines whether an axis is fully determined by $x_\text{min}$, $x_\text{max}$ and $N_\text{bins}$, or if there are variable bin boundaries $x_i = \{x_1, \ldots x_N\}$.
0023 The axis boundaries and, if necessary, the bin boundaries are provided in the constructor.
0024 
0025 
0026 If at all possible, `Equidistant` is preferable, since bin $b$ can then be calculated in constant time for given $x$ as
0027 
0028 $$b = \frac{\mathrm{floor}(x - x_\text{min})}{w} + 1$$
0029 
0030 where $b \in \{0, 1, \ldots N_\text{bins}\}$. If the type is `Variable`, a search for the correct bin is performed over the bin boundaries.
0031 
0032 ### AxisBoundaryType
0033 
0034 `AxisBoundaryType` steers how out-of-bounds lookups are handled.
0035 There are three options:
0036 
0037 ![The three different axis boundary types](figures/AxisBoundaryTypes.svg)
0038 
0039 - **Bound**: out-of-bounds lookups resolve to the closest valid bin.
0040 - **Open**: out-of-bounds lookups resolve to dedicated underflow and overflow bins.
0041 - **Closed**: out-of-bounds lookups wrap-around to the other side of the axis.
0042 
0043 ## Grid creation
0044 
0045 The types of the axes have to be known at compile-time, since they are provided to the `Grid` as template parameters.
0046 Thus, the number of dimensions $N$ of the `Grid` is also fixed at compile-time.
0047 The axes can be any combination of the aforementioned variations.
0048 
0049 ```cpp
0050 template <typename T, class... Axes> class Grid;
0051 ```
0052 
0053 where `T` is the value type that is stored in each bin. Instances of each axis are then given to the `Grid` constructor as a tuple. This Axis instances hold the number of bins and the boundary values, which are **runtime values**.
0054 
0055 The `Grid` performs a lookup by recursively visiting each axis and having it perform a lookup in the corresponding component of the input vector. The lookup methods are templated on the input vector type, which only has to support component access. Transforming in and out of the local `Grid` reference frame is not handled by the `Grid`.
0056 
0057 ## Local vs global bin indices
0058 
0059 The underlying data structure of the `Grid` is a one-dimensional `std::vector<T>`, where `T` is the template parameter determining the stored value type. The index of this vector is referred to as the **global bin index**.
0060 The logical index structure, where each global bin is addressed by an $N$-dimensional vector of integers is called **local bin indices**. The two can be converted into one another using
0061 
0062 ```cpp
0063 using index_t = std::array<size_t, N>;
0064 index_t getLocalBinIndices(size_t bin) const;
0065 size_t getGlobalBinIndex(const index_t& localBins) const;
0066 ```
0067 
0068 The local bin indices are always defined from 1 to $N_\text{bins}$ for the respective axis. Bins 0 and $N_\text{bins} + 1$ address the underflow and overflow bins, **which are always present, even if `AxisBoundaryType != Open`**.
0069 
0070 ## Finding neighbors
0071 
0072 The `Grid` can determine the number of neighbors around a given bin. This done by first converting the global bin index to local bin indices, and then varying the local bin indices in each dimension. At this stage, each Axis gets to decide, which indices are considered neighbors, which differs depending on `AxisBinningType`. `Open` considers the underflow and overflow bins, while `Bound` does not. `Closed` considers bins on the other side of the axis.
0073 The resulting neighbor combination around bin *B* might look like
0074 
0075 | b x b | 1     | 2    | 3     |
0076 |-------|-------|------|-------|
0077 | 1     | x     | 0,+1 | x     |
0078 | 2     | -1, 0 | B    | +1, 0 |
0079 | 3     | x     | 0,-1 | x     |
0080 
0081 Here, the corner combinations are still missing (also true for $N>2$). This is then turned into a hypercube which in $N=2$ results in:
0082 
0083 | b x b | 1     | 2    | 3     |
0084 |-------|-------|------|-------|
0085 | 1     | -1,+1 | 0,+1 | +1,+1 |
0086 | 2     | -1, 0 | B    | +1, 0 |
0087 | 3     | -1,-1 | 0,-1 | +1,-1 |
0088 
0089 These local bin indices are then converted into global bin indices before being returned.