26#include <mist/logger/logger.h>
32namespace owned = ::mist::hep::owned;
47 mist::logger::error(
"(histo::dimension) target is null");
50 const auto* h1 =
dynamic_cast<const TH1*
>(h);
52 mist::logger::error(
"(histo::dimension) target is not a TH1-derived histogram");
55 if (
dynamic_cast<const TH3*
>(h))
return 3;
56 if (
dynamic_cast<const TH2*
>(h))
return 2;
64template <
typename TH1Type,
typename TH2Type>
69 if (da < 0 || db < 0)
return -1;
71 mist::logger::error(
"(histo::pair_dimension) dimensions disagree");
81template <
typename TH1Type,
typename TH2Type>
85 if (a->GetNbinsX() != b->GetNbinsX())
return false;
86 if (a->GetNbinsY() != b->GetNbinsY())
return false;
87 if (a->GetNbinsZ() != b->GetNbinsZ())
return false;
88 for (
int i = 1; i <= a->GetNbinsX(); ++i)
89 if (a->GetXaxis()->GetBinLowEdge(i) != b->GetXaxis()->GetBinLowEdge(i))
91 for (
int j = 1; j <= a->GetNbinsY(); ++j)
92 if (a->GetYaxis()->GetBinLowEdge(j) != b->GetYaxis()->GetBinLowEdge(j))
94 for (
int k = 1; k <= a->GetNbinsZ(); ++k)
95 if (a->GetZaxis()->GetBinLowEdge(k) != b->GetZaxis()->GetBinLowEdge(k))
113[[nodiscard]]
inline std::vector<double>
116 std::vector<double> edges;
117 if (width <= 0.0 || high <= low) {
118 mist::logger::error(
"(histo::uniform_binning) require width > 0 and high > low");
121 int n =
static_cast<int>((high - low) / width);
122 if ((high - low) - n * width > 0.0) ++n;
123 edges.reserve(n + 1);
124 for (
int i = 0; i <= n; ++i) edges.push_back(low + i * width);
125 if (edges.back() != high)
126 mist::logger::warning(
"(histo::uniform_binning) high edge adjusted to fit width");
143[[nodiscard]]
inline std::vector<double>
146 std::vector<double> edges;
147 if (n_bins <= 0 || low <= 0.0 || high <= low) {
148 mist::logger::error(
"(histo::log_binning) require n_bins > 0 and 0 < low < high");
151 const double log_lo = std::log10(low);
152 const double log_hi = std::log10(high);
153 const double step = (log_hi - log_lo) /
static_cast<double>(n_bins);
154 edges.reserve(n_bins + 1);
155 for (
int i = 0; i <= n_bins; ++i)
156 edges.push_back(std::pow(10.0, log_lo + i * step));
188template <
typename TH1Type = TH1F,
typename T>
189 requires std::is_arithmetic_v<T>
197 const std::string name =
"histo_from_vector_" +
203 const auto max_it = *std::max_element(data.begin(), data.end());
204 const auto min_it = *std::min_element(data.begin(), data.end());
205 const double span =
static_cast<double>(max_it) -
static_cast<double>(min_it);
208 low =
static_cast<double>(min_it) - 0.2 * span +
offset;
209 high =
static_cast<double>(max_it) + 0.2 * span +
offset;
213 const std::size_t sz = data.size();
215 if (sz >=
static_cast<std::size_t
>(1e2)) n_bins =
static_cast<int>(sz / 3) + 2;
216 if (sz >=
static_cast<std::size_t
>(1e3)) n_bins =
static_cast<int>(sz / 5) + 2;
217 if (sz >=
static_cast<std::size_t
>(1e4)) n_bins = 216;
221 for (
auto v : data) h->Fill(
static_cast<double>(v) +
offset);
233template <
typename TH>
245template <
typename TH>
250 if (!out)
return out;
251 const int n_cells = out->GetNcells();
252 for (
int i = 0; i < n_cells; ++i) {
253 const double shifted = out->GetBinContent(i) + value;
254 out->SetBinContent(i,
absolute ? std::fabs(shifted) : shifted);
262template <
typename TH>
265 return offset(h, 0.0,
true);
278template <
typename TH>
280scale(
const TH* h,
double factor,
double factor_error = 0.0)
283 if (!out)
return out;
284 const int n_cells = out->GetNcells();
285 for (
int i = 0; i < n_cells; ++i) {
286 const double content = out->GetBinContent(i);
287 const double error = out->GetBinError(i);
288 const double scaled = factor * content;
289 out->SetBinContent(i, scaled);
290 if (factor_error == 0.0 || content == 0.0 || factor == 0.0) {
291 out->SetBinError(i, std::fabs(factor) * error);
294 {error / content, factor_error / factor});
295 out->SetBinError(i, std::fabs(scaled) * rel);
owned::root_ptr< TH > clone_as(const TH *h)
Definition histo.h:234
int & build_counter()
Definition histo.h:170
owned::root_ptr< TH > scale(const TH *h, double factor, double factor_error=0.0)
Definition histo.h:280
std::vector< double > uniform_binning(double width, double low, double high)
Definition histo.h:114
std::vector< double > log_binning(int n_bins, double low, double high)
Definition histo.h:144
owned::root_ptr< TH > offset(const TH *h, double value, bool absolute=false)
Definition histo.h:247
owned::root_ptr< TH > absolute(const TH *h)
Definition histo.h:263
owned::root_ptr< TH1Type > make_th1_from_vector(const std::vector< T > &data, int n_bins=-1, double offset=0.0, double low=0.0, double high=0.0)
Definition histo.h:191
bool is_consistent(const TH1Type *a, const TH2Type *b)
Definition histo.h:82
int pair_dimension(const TH1Type *a, const TH2Type *b)
Definition histo.h:65
int dimension(const TH *h)
Definition histo.h:44
root_ptr< T > clone(const T &source)
Definition owned.h:81
std::unique_ptr< T, root_deleter > root_ptr
Definition owned.h:60
root_ptr< T > make(Args &&... args)
Definition owned.h:67
double quadrature_sum(R &&xs)
Definition stats.h:36