22#include <boost/multi_array.hpp>
45template <
typename T, std::
size_t N, std::
size_t M = 3,
typename U =
double>
47 using array_type = boost::multi_array<T, M + 1>;
48 using count_type = boost::multi_array<std::size_t, M + 1>;
61 std::array<std::pair<U, U>, M> limits)
100 void update(std::span<const U> pos, std::span<const T> value) {
101 if (pos.size() != M) {
102 throw std::invalid_argument(
"Wrong dimensions for the coordinates");
104 if (value.size() != N) {
105 throw std::invalid_argument(
"Wrong dimensions for the value");
107 if (check_limits(pos)) {
108 boost::array<array_index, M + 1> index;
109 for (std::size_t i = 0; i < M; ++i) {
112 for (
array_index i = 0; i < static_cast<array_index>(N); ++i) {
114 m_array(index) += value[
static_cast<std::size_t
>(i)];
122 auto const bin_volume = std::accumulate(
126 [bin_volume](T v) { return static_cast<T>(v / bin_volume); });
136 array_index calc_bin_index(
double value,
double offset,
double size)
const {
137 return static_cast<array_index>(std::floor((value - offset) / size));
143 std::array<U, M> calc_bin_sizes()
const {
144 std::array<U, M> bin_sizes;
145 for (std::size_t i = 0; i < M; ++i) {
156 bool check_limits(std::span<const U> pos)
const {
157 assert(pos.size() == M);
158 bool within_range =
true;
159 for (std::size_t i = 0; i < M; ++i) {
161 within_range =
false;
166 std::array<std::size_t, M + 1> m_array_dim()
const {
167 std::array<std::size_t, M + 1> dimensions;
169 dimensions.back() = N;
194template <
typename T, std::
size_t N, std::
size_t M = 3,
typename U =
double>
206 auto const min_r =
m_limits[0].first;
212 auto const r_left = min_r +
static_cast<U
>(i) * r_bin_size;
213 auto const r_right = r_left + r_bin_size;
214 auto const bin_volume = (r_right * r_right - r_left * r_left) *
215 z_bin_size * phi_bin_size / U(2);
216 auto *begin =
m_array[i].origin();
218 begin, begin +
m_array[i].num_elements(), begin,
219 [bin_volume](T v) {
return static_cast<T
>(v / bin_volume); });
Histogram in cylindrical coordinates.
void normalize() override
Histogram in Cartesian coordinates.
std::array< U, M > get_bin_sizes() const
Get the bin sizes.
std::array< std::size_t, M > m_n_bins
Number of bins for each dimension.
std::array< U, M > m_bin_sizes
Bin sizes for each dimension.
virtual void normalize()
Normalize histogram.
std::array< std::pair< U, U >, M > m_limits
Min and max values for each dimension.
virtual ~Histogram()=default
count_type m_count
Track the number of total hits per bin entry.
typename array_type::index array_index
std::array< T, N > m_ones
std::vector< std::size_t > get_tot_count() const
Get the histogram count data.
std::vector< T > get_histogram() const
Get the histogram data.
void update(std::span< const U > pos, std::span< const T > value)
Add data to the histogram.
array_type m_array
Histogram data.
std::array< std::pair< U, U >, M > get_limits() const
Get the ranges (min, max) for each dimension.
Histogram(std::array< std::size_t, M > n_bins, std::array< std::pair< U, U >, M > limits)
Histogram constructor.
std::array< std::size_t, M > get_n_bins() const
Get the number of bins for each dimension.
void update(std::span< const U > pos)
Add data to the histogram.