9 #include <nlohmann/json.hpp> 
   14 #if DISMEC_STATS_SUPPORT_HISTOGRAM 
   15 using namespace boost::histogram;
 
   18 namespace axis = boost::histogram::axis;
 
   20 using log_axis_t = axis::regular<real_t, axis::transform::log>;
 
   21 using lin_axis_t = axis::regular<real_t>;
 
   25     void combine_histograms(T& target, 
const T& source) {
 
   26         auto index_s = indexed(source, coverage::all);
 
   27         auto index_t = indexed(target, coverage::all);
 
   29         auto s_it = begin(index_s);
 
   30         auto t_it = begin(index_t);
 
   31         auto end_it = end(index_s);
 
   32         while(s_it != end_it) {
 
   39     template<
class T, 
class U>
 
   40     void combine_histograms(T& target, 
const U& source) {
 
   41         throw std::logic_error(
"Trying to combine histograms of different type");
 
   44     template<
class... Args>
 
   51         for(
auto&& b : indexed(hist, coverage::all)) {
 
   52             lower_bounds.push_back(b.bin(0).lower());
 
   53             upper_bounds.push_back(b.bin(0).upper());
 
   54             counts.push_back(
long(*b));
 
   57         result[
"Lower"] = std::move(lower_bounds);
 
   58         result[
"Upper"] = std::move(upper_bounds);
 
   59         result[
"Count"] = std::move(counts);
 
   64     std::string get_type();
 
   67     std::string get_type<lin_axis_t>() {
 
   71     std::string get_type<log_axis_t>() {
 
   82         return std::abs(value);
 
   88 HistogramStat<Axis>::HistogramStat(
int bins, 
real_t min, 
real_t max) :
 
   89     m_Histogram(make_histogram(Axis(bins, min, max))),
 
   90     m_Bins(bins), m_Min(min), m_Max(max) {
 
   95 void HistogramStat<Axis>::record_int(
long value) {
 
   96     record_real(
real_t(value));
 
  100 void HistogramStat<Axis>::record_real(
real_t value) {
 
  106     for(
int i = 0; i < vector.size(); ++i) {
 
  107         m_Histogram(transform<Axis>(vector.coeff(i)));
 
  112 std::unique_ptr<Statistics> HistogramStat<Axis>::clone()
 const {
 
  113     return std::make_unique<HistogramStat<Axis>>(m_Bins, m_Min, m_Max);
 
  116 void HistogramStat<Axis>::merge_imp(
const HistogramStat<Axis>& other) {
 
  117     combine_histograms(m_Histogram,  other.m_Histogram);
 
  122     auto temp = ::to_json(m_Histogram);
 
  123     temp[
"Type"] = get_type<Axis>();
 
  128     return std::make_unique<HistogramStat<lin_axis_t>>(bins, min, max);
 
  132     return std::make_unique<HistogramStat<log_axis_t>>(bins, min, max);
 
  136 TaggedHistogramStat<Axis>::TaggedHistogramStat(std::string tag, 
int max_tag, 
int bins, 
real_t min, 
real_t max) :
 
  137     m_Bins(bins), m_MaxTag(max_tag), m_Min(min), m_Max(max), m_Tag(
TagContainer::create_empty_container(std::move(tag))) {
 
  142 void TaggedHistogramStat<Axis>::record_int(
long value) {
 
  143     record_real(
real_t(value));
 
  147 auto TaggedHistogramStat<Axis>::get_active_hist() -> histogram_t& {
 
  148     int tag = m_Tag.get_value();
 
  150         throw std::logic_error(
"Missing tag!");
 
  154     while(tag >= 
ssize(m_Histograms)) {
 
  155         m_Histograms.push_back(make_histogram(Axis(m_Bins, m_Min, m_Max)));
 
  157     return m_Histograms[tag];
 
  161 void TaggedHistogramStat<Axis>::record_real(
real_t value) {
 
  162     get_active_hist()(value);
 
  166 void TaggedHistogramStat<Axis>::record_vec(
const DenseRealVector& vector) {
 
  167     auto& hist = get_active_hist();
 
  168     for(
int i = 0; i < vector.size(); ++i) {
 
  169         hist(transform<Axis>(vector.coeff(i)));
 
  174 std::unique_ptr<Statistics> TaggedHistogramStat<Axis>::clone()
 const {
 
  175     return std::make_unique<TaggedHistogramStat<Axis>>(m_Tag.get_name(), m_MaxTag, m_Bins, m_Min, m_Max);
 
  179 void TaggedHistogramStat<Axis>::merge_imp(
const TaggedHistogramStat<Axis>& other) {
 
  180     m_Histograms.reserve(other.m_Histograms.size());
 
  181     while(other.m_Histograms.size() > m_Histograms.size()) {
 
  182         m_Histograms.emplace_back(make_histogram(Axis(m_Bins, m_Min, m_Max)));
 
  185     for(
int i = 0; i < 
ssize(other.m_Histograms); ++i) {
 
  186         combine_histograms(m_Histograms[i], other.m_Histograms[i]);
 
  193     for(
int i = 0; i < 
ssize(m_Histograms); ++i) {
 
  194         auto temp = ::to_json(m_Histograms[i]);
 
  195         result[
"Counts"].push_back(temp[
"Count"]);
 
  197             result[
"Lower"] = std::move(temp[
"Lower"]);
 
  198             result[
"Upper"] = std::move(temp[
"Upper"]);
 
  201     result[
"Type"] = 
"Tagged" + get_type<Axis>();
 
  211     return std::make_unique<TaggedHistogramStat<lin_axis_t>>(std::move(tag), max_tag, bins, min, max);
 
  215     return std::make_unique<TaggedHistogramStat<log_axis_t>>(std::move(tag), max_tag, bins, min, max);
 
  219     throw std::runtime_error(
"Histogram statistics not supported in this binary");
 
  223     throw std::runtime_error(
"Histogram statistics not supported in this binary");
 
  226     throw std::runtime_error(
"Histogram statistics not supported in this binary");
 
  230     throw std::runtime_error(
"Histogram statistics not supported in this binary");
 
This class manages a collection of named Statistics objects.
TagContainer get_tag_by_name(const std::string &name) const
Gets the tag with the given name.
A tag container combines a name with a shared pointer, which points to the tag value.
std::unique_ptr< Statistics > make_linear_histogram(int bins, real_t min, real_t max)
std::unique_ptr< Statistics > make_logarithmic_histogram(int bins, real_t min, real_t max)
Main namespace in which all types, classes, and functions are defined.
constexpr auto ssize(const C &c) -> std::common_type_t< std::ptrdiff_t, std::make_signed_t< decltype(c.size())>>
signed size free function. Taken from https://en.cppreference.com/w/cpp/iterator/size
types::DenseVector< real_t > DenseRealVector
Any dense, real values vector.
float real_t
The default type for floating point values.