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.