IAP GITLAB

Skip to content
Snippets Groups Projects
Commit d0bae245 authored by Maximilian Reininghaus's avatar Maximilian Reininghaus :vulcan:
Browse files

even better flow bin handling

parent cc183aac
No related branches found
No related tags found
No related merge requests found
...@@ -23,30 +23,34 @@ namespace corsika { ...@@ -23,30 +23,34 @@ namespace corsika {
void save_hist(boost::histogram::histogram<Axes, Storage> const& h, void save_hist(boost::histogram::histogram<Axes, Storage> const& h,
std::string const& filename) { std::string const& filename) {
int const rank = h.rank(); int const rank = h.rank();
int const size = h.size();
using value_type = typename boost::histogram::histogram<Axes, Storage>::value_type;
std::vector<size_t> axes_dims; std::vector<size_t> axes_dims;
axes_dims.reserve(rank); axes_dims.reserve(rank);
auto overflow = std::make_unique<bool[]>(rank);
auto underflow = std::make_unique<bool[]>(rank);
std::vector<char> axis_types; std::vector<char> axis_types;
axis_types.reserve(rank); axis_types.reserve(rank);
for (int i = 0; i < rank; ++i) { for (int i = 0; i < rank; ++i) {
auto const& ax = h.axis(i); auto const& ax = h.axis(i);
int const has_underflow = (ax.options() & 0x01) ? 1 : 0; unsigned const has_underflow = (ax.options() & 0x01) ? 1 : 0;
int const has_overflow = (ax.options() & 0x02) ? 1 : 0; unsigned const has_overflow = (ax.options() & 0x02) ? 1 : 0;
underflow[i] = has_underflow;
overflow[i] = has_overflow;
axes_dims.emplace_back(ax.size() + has_underflow + has_overflow); axes_dims.emplace_back(ax.size() + has_underflow + has_overflow);
if (ax.continuous()) { if (ax.continuous()) {
axis_types.push_back('c'); axis_types.push_back('c');
std::vector<double> ax_edges; std::vector<double> ax_edges;
ax_edges.reserve(ax.size()); ax_edges.reserve(ax.size() + 1);
for (int j = 0; j < ax.size(); ++j) { ax_edges.push_back(ax.bin(j).lower()); }
for (int j = 0; j < ax.size() + has_overflow; ++j) { ax_edges.push_back(ax.bin(ax.size() - 1).upper());
ax_edges.push_back(ax.bin(j).lower());
}
cnpy::npz_save(filename, std::string{"binedges_"} + std::to_string(i), cnpy::npz_save(filename, std::string{"binedges_"} + std::to_string(i),
ax_edges.data(), {ax_edges.size()}, "a"); ax_edges.data(), {ax_edges.size()}, "a");
...@@ -63,29 +67,30 @@ namespace corsika { ...@@ -63,29 +67,30 @@ namespace corsika {
cnpy::npz_save(filename, std::string{"axistypes"}, axis_types.data(), cnpy::npz_save(filename, std::string{"axistypes"}, axis_types.data(),
{axis_types.size()}, "a"); {axis_types.size()}, "a");
cnpy::npz_save(filename, std::string{"overflow"}, overflow.get(),
{axis_types.size()}, "a");
cnpy::npz_save(filename, std::string{"underflow"}, underflow.get(),
{axis_types.size()}, "a");
} }
auto const prod_axis_size = auto const prod_axis_size = std::accumulate(axes_dims.cbegin(), axes_dims.cend(),
std::accumulate(axes_dims.cbegin(), axes_dims.cend(), 1, std::multiplies<>()); unsigned{1}, std::multiplies<>());
auto temp = std::make_unique<value_type[]>(prod_axis_size); auto temp = std::make_unique<float[]>(prod_axis_size);
std::cout << "rank = " << rank << std::endl; assert(prod_axis_size == h.size());
std::cout << "size = " << size << std::endl;
std::cout << "prod_axis_size = " << prod_axis_size << std::endl;
// reduce multi-dim. to 1-dim, row-major (i.e., last axis index is contiguous in // reduce multi-dim. to 1-dim, row-major (i.e., last axis index is contiguous in
// memory) take special care of underflow bins, which have -1 as index and thus need // memory) take special care of underflow bins which have -1 as index and thus need
// to be shifted by +1 // to be shifted by +1
for (auto&& x : indexed(h, boost::histogram::coverage::all)) { for (auto&& x : indexed(h, boost::histogram::coverage::all)) {
int const offset_underflow = (h.axis(0).options() & 0x01) ? 1 : 0; int p = 0;
auto p = x.index(0) + offset_underflow; // 1-d-index
for (int axis_index = 1; axis_index < rank; ++axis_index) { for (int axis_index = 0; axis_index < rank; ++axis_index) {
int const offset_underflow = (h.axis(axis_index).options() & 0x01) ? 1 : 0; int const offset_underflow = (h.axis(axis_index).options() & 0x01) ? 1 : 0;
auto k = x.index(axis_index) + offset_underflow; auto k = x.index(axis_index) + offset_underflow;
p = k + p * axes_dims.at(axis_index); p = k + p * axes_dims.at(axis_index);
std::cout << " " << x.index(axis_index);
} }
temp[p] = *x; temp[p] = *x;
......
...@@ -11,23 +11,28 @@ ...@@ -11,23 +11,28 @@
#include <random> #include <random>
namespace bh = boost::histogram;
TEST_CASE("SaveHistogram") { TEST_CASE("SaveHistogram") {
std::mt19937 rng; std::mt19937 rng;
std::normal_distribution n1{2., 6.}; std::normal_distribution n1{2., 6.};
std::exponential_distribution e{1.}; std::exponential_distribution e{1.};
std::uniform_int_distribution u{1, 10}; std::uniform_int_distribution u{1, 10};
std::uniform_real_distribution<double> r{-3, 3};
auto h = auto h = bh::make_histogram(
boost::histogram::make_histogram(boost::histogram::axis::regular{5, 0, 10, "x"}, bh::axis::regular{5, 0, 10, "normal"}, bh::axis::regular{3, 0, 4, "exponential"},
boost::histogram::axis::regular{3, 0, 4, "y"}, bh::axis::category<int>{{2, 3, 5, 7}, "integer category"},
boost::histogram::axis::category{1, 4, 8}); bh::axis::regular<double, bh::use_default, bh::use_default,
bh::axis::option::growth_t>{10, -1, 1, "integer category"});
for (int i{0}; i < 100'000; ++i) { for (int i{0}; i < 100'000; ++i) {
auto const a = n1(rng); auto const a = n1(rng);
auto const b = e(rng); auto const b = e(rng);
auto const c = u(rng); auto const c = u(rng);
auto const d = r(rng);
h(a, b, c); h(a, b, c, d);
} }
corsika::utl::save_hist(h, "hist.npz"); corsika::utl::save_hist(h, "hist.npz");
......
...@@ -11,14 +11,16 @@ def read_hist(filename): ...@@ -11,14 +11,16 @@ def read_hist(filename):
""" """
d = np.load(filename) d = np.load(filename)
axistypes = d['axistypes'].view('c') axistypes = d['axistypes'].view('c')
overflow = d['overflow']
underflow = d['underflow']
axes = [] axes = []
for i, at in enumerate(axistypes): for i, (at, has_overflow, has_underflow) in enumerate(zip(axistypes, overflow, underflow)):
if at == b'c': if at == b'c':
axes.append(bh.axis.Variable(d[f'binedges_{i}'], overflow=True, underflow=True)) axes.append(bh.axis.Variable(d[f'binedges_{i}'], overflow=has_overflow, underflow=has_underflow))
elif at == b'd': elif at == b'd':
axes.append(bh.axis.IntCategory(d[f'binedges_{i}'])) axes.append(bh.axis.IntCategory(d[f'bins_{i}'], growth=(not has_overflow)))
h = bh.Histogram(*axes) h = bh.Histogram(*axes)
h.view(flow=True)[:] = d['data'] h.view(flow=True)[:] = d['data']
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment