55#include "SmartPointer.hh"
56#include "../Config/ACGDefines.hh"
61 enum class LabelType {
68 std::vector<double> &&bin_widths)
69 : bins_(std::move(bins)),
70 bin_widths_(std::move(bin_widths))
74 const std::vector<size_t> &getBins()
const {
return bins_; }
75 const std::vector<double> &getBinWidths()
const {
return bin_widths_; }
76 virtual double getTotalWidth()
const = 0;
78 virtual LabelType getLabelType()
const = 0;
79 virtual QString getBoundaryLabel(
size_t )
const { assert(
false);
return QString();}
80 virtual QString getBinLabel (
size_t )
const { assert(
false);
return QString();}
83 std::vector<size_t> bins_;
84 std::vector<double> bin_widths_;
88inline QString formatValue (
int val) {
89 return QString::number(val);
91inline QString formatValue (
unsigned int val) {
92 return QString::number(val);
94inline QString formatValue (
double val) {
95 return QString::number(val,
'g', 3);
103 std::vector<T> &&bin_values)
105 std::vector<double>(bin_counts.size(), 1.)),
106 bin_values_(std::move(bin_values))
109 double getTotalWidth()
const override {
return bins_.size();};
110 LabelType getLabelType()
const override {
return LabelType::PerBin; };
111 QString getBinLabel (
size_t idx)
const override {
return formatValue(bin_values_[idx]);}
113 std::vector<T> bin_values_;
122 std::vector<T> &&bin_boundaries,
123 std::vector<double> &&bin_widths
125 :
Histogram(std::move(histogram), std::move(bin_widths)),
126 bin_boundaries_(std::move(bin_boundaries))
128 if (bins_.size() != bin_widths_.size()
129 || bins_.size() + 1 != bin_boundaries_.size()) {
130 throw std::runtime_error(
"Histogram constructor sizes don't match.");
134 const std::vector<T> &getBinBoundaries()
const {
135 return bin_boundaries_;
138 double getTotalWidth()
const override
140 return bin_boundaries_.back() - bin_boundaries_.front();
143 LabelType getLabelType()
const override
145 return LabelType::PerBoundary;
148 QString getBoundaryLabel (
size_t idx)
const override
151 return formatValue(bin_boundaries_[idx]);
156 std::vector<T> bin_boundaries_;
161std::unique_ptr<Histogram> create_histogram_unbinned(
const std::map<T, size_t> &counts)
163 std::vector<T> values;
164 std::vector<size_t> histogram;
165 values.reserve(counts.size());
166 histogram.reserve(counts.size());
167 for (
const auto &entry: counts)
169 values.push_back(entry.first);
170 histogram.push_back(entry.second);
172 return ptr::make_unique<UnbinnedHistogram<T>>(std::move(histogram), std::move(values));
175template<
typename T,
typename Iterable>
176std::unique_ptr<Histogram> create_histogram_autorange(
const Iterable &range,
size_t max_bins = 50)
186 std::vector<T> bin_boundaries;
187 std::vector<size_t> bins;
188 std::vector<double> bin_widths;
190 const size_t n = std::distance(begin(range), end(range));
191 if (n == 0)
return {};
192 const auto minmax = std::minmax_element(begin(range), end(range));
193 const T min = *minmax.first;
194 const T max = *minmax.second;
196 const double min_dbl =
static_cast<double>(min);
197 const double val_range =
static_cast<double>(max) - min_dbl;
199 const size_t n_bins_max = std::min(max_bins, n);
200 bin_boundaries.reserve(n_bins_max + 1);
202 T last_boundary = min;
203 bin_boundaries.push_back(min);
204 for (
size_t i = 1; i < n_bins_max; ++i) {
212 T boundary =
static_cast<T
>(min + (i * val_range) / n_bins_max);
214 if (boundary != last_boundary || i == 0) {
215 bin_boundaries.push_back(boundary);
216 bin_widths.push_back(boundary - last_boundary);
218 last_boundary = boundary;
220 bin_boundaries.push_back(max);
221 bin_widths.push_back(max - last_boundary);
223 bin_boundaries.shrink_to_fit();
224 size_t n_bins = bin_boundaries.size() - 1;
230 std::for_each(begin(range), end(range), [&](
const T &val) {
231 auto it = std::upper_bound(bin_boundaries.begin(), bin_boundaries.end(), val);
232 if (it == bin_boundaries.end()) --it;
233 size_t idx = std::distance(bin_boundaries.begin(), it);
237 return ptr::make_unique<HistogramT<T>>(std::move(bins), std::move(bin_boundaries), std::move(bin_widths));
240template<
typename Iterable>
241std::unique_ptr<Histogram> create_histogram_auto(
const Iterable &range,
size_t max_bins = 50)
245 using T =
typename std::remove_cv<
246 typename std::remove_reference<
247 decltype(*begin(range))
250 const size_t n = std::distance(begin(range), end(range));
251 if (n == 0)
return {};
253 std::map<T, size_t> elem_counts;
254 bool too_many_unique =
false;
255 for (
const auto &v: range)
258 if (elem_counts.size() > max_bins)
260 too_many_unique =
true;
265 if (too_many_unique) {
266 return create_histogram_autorange<T>(range, max_bins);
268 return create_histogram_unbinned(elem_counts);
Namespace providing different geometric functions concerning angles.