diff --git a/corsika/framework/utility/SaveBootHistogram.hpp b/corsika/framework/utility/SaveBootHistogram.hpp
deleted file mode 100644
index 76576406264c4d15b34273d704ea87b5c6319612..0000000000000000000000000000000000000000
--- a/corsika/framework/utility/SaveBootHistogram.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#pragma once
-
-#include <cnpy/cnpy.hpp>
-
-#include <boost/histogram.hpp>
-
-#include <functional>
-#include <memory>
-#include <numeric>
-#include <utility>
-#include <vector>
-#include <string>
-
-namespace corsika {
-
-  enum class SaveMode { overwrite, append };
-
-  /**
-   * This functions saves a boost::histogram into a numpy file. Only rather basic axis
-   * types are supported: regular, variable, integer, category<int>. Only "ordinary" bin
-   * counts (i.e. a double or int) are supported, nothing fancy like profiles.
-   *
-   * Note that this function makes a temporary, dense copy of the histogram, which could
-   * be an issue for huge sizes (e.g. for high dimensions)
-   */
-  template <class Axes, class Storage>
-  inline void save_hist(boost::histogram::histogram<Axes, Storage> const& h,
-                        std::string const& filename, SaveMode mode = SaveMode::append) {
-    unsigned const rank = h.rank();
-
-    // append vs. overwrite
-    const std::string mode_str = (mode == SaveMode::append ? "a" : "w");
-
-    std::vector<size_t> axes_dims;
-    axes_dims.reserve(rank);
-
-    auto overflow = std::make_unique<bool[]>(rank);
-    auto underflow = std::make_unique<bool[]>(rank);
-
-    std::vector<char> axis_types;
-    axis_types.reserve(rank);
-
-    for (unsigned int i = 0; i < rank; ++i) {
-      auto const& ax = h.axis(i);
-      unsigned const has_underflow = (ax.options() & 0x01) ? 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);
-
-      if (ax.continuous()) {
-        axis_types.push_back('c');
-        std::vector<double> ax_edges;
-        ax_edges.reserve(ax.size() + 1);
-
-        for (int j = 0; j < ax.size(); ++j) { ax_edges.push_back(ax.bin(j).lower()); }
-
-        ax_edges.push_back(ax.bin(ax.size() - 1).upper());
-
-        cnpy::npz_save(filename, std::string{"binedges_"} + std::to_string(i),
-                       ax_edges.data(), {ax_edges.size()}, mode_str);
-      } else {
-        axis_types.push_back('d');
-        std::vector<int64_t> bins; // we assume that discrete axes have integer bins
-        bins.reserve(ax.size());
-
-        for (int j = 0; j < ax.size(); ++j) { bins.push_back(ax.bin(j).lower()); }
-
-        cnpy::npz_save(filename, std::string{"bins_"} + std::to_string(i), bins.data(),
-                       {bins.size()}, mode_str);
-      }
-    }
-
-    cnpy::npz_save(filename, std::string{"axistypes"}, axis_types.data(), {rank},
-                   mode_str);
-    cnpy::npz_save(filename, std::string{"overflow"}, overflow.get(), {rank}, mode_str);
-    cnpy::npz_save(filename, std::string{"underflow"}, underflow.get(), {rank}, mode_str);
-
-    auto const prod_axis_size = std::accumulate(axes_dims.cbegin(), axes_dims.cend(),
-                                                unsigned{1}, std::multiplies<>());
-    auto temp = std::make_unique<float[]>(prod_axis_size);
-
-    assert(prod_axis_size == h.size());
-
-    // 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
-    // to be shifted by +1
-
-    for (auto&& x : indexed(h, boost::histogram::coverage::all)) {
-      int p = 0;
-
-      for (unsigned axis_index = 0; axis_index < rank; ++axis_index) {
-        int const offset_underflow = (h.axis(axis_index).options() & 0x01) ? 1 : 0;
-        auto k = x.index(axis_index) + offset_underflow;
-        p = k + p * axes_dims.at(axis_index);
-      }
-
-      temp[p] = *x;
-    }
-
-    cnpy::npz_save(filename, "data", temp.get(), axes_dims, mode_str);
-    // In Python this array can directly be assigned to a histogram view if that
-    // histogram has its axes correspondingly: hist.view(flow=True)[:] = file['data']
-  }
-} // namespace corsika