ATLAS Offline Software
Loading...
Searching...
No Matches
widthestimators.h
Go to the documentation of this file.
1
20
21#include <utility>
22#include <vector>
23#include <numeric>
24#include <iostream>
25#include <algorithm>
26
28{
29 const double PROB_1SIGMA = 0.683;
30
31 namespace binned
32 {
34 // need to use template, and not TH1, since GetArray is implemeted for each specialization
35 // but not in TH1
36 template <typename T>
37 std::vector<double> get_cum_sum(const T &histo, bool normed = false)
38 {
39 // use double since it can be weighted
40 std::vector<double> cum_sum(histo->GetNbinsX() + 2);
41
42 std::partial_sum(
43 histo->GetArray(),
44 histo->GetArray() + histo->GetNbinsX() + 2,
45 cum_sum.begin());
46
47 if (normed)
48 {
49 const double last_value = cum_sum.back();
50 std::transform(cum_sum.begin(), cum_sum.end(), cum_sum.begin(),
51 [&last_value](auto &c) { return c / last_value; });
52 }
53
54 return cum_sum;
55 }
56
58 template <typename T>
59 std::pair<double, double> find_window(const T &histo, double prob = PROB_1SIGMA)
60 {
61 if (histo->GetNbinsX() <= 3 || histo->Integral() == 0.)
62 {
63 return std::make_pair<double>(0, 0);
64 }
65
66 std::vector<double> cum_sum = get_cum_sum(histo, true);
67 double min_width = histo->GetBinCenter(histo->GetNbinsX()) - histo->GetBinCenter(1);
68 std::pair<int, int> window_bin(0, histo->GetNbinsX() + 1);
69
70 for (int ibin = 0; ibin != histo->GetNbinsX() + 1; ++ibin)
71 {
72 const double target_prob = prob + cum_sum[ibin];
73 if (target_prob > 1)
74 break;
75
76 const auto up_it = std::upper_bound(cum_sum.begin() + ibin, cum_sum.end(), target_prob);
77 const auto end_bin = std::distance(cum_sum.begin(), up_it);
78 const double width = histo->GetBinCenter(end_bin) - histo->GetBinCenter(ibin);
79
80 if (width < min_width)
81 {
82 min_width = width;
83 window_bin.first = ibin;
84 window_bin.second = end_bin;
85 }
86 }
87 return std::make_pair<double>(histo->GetBinCenter(window_bin.first), histo->GetBinCenter(window_bin.second));
88 }
89
90 template <typename T>
91 double smallest_interval(const T &histo, double prob = PROB_1SIGMA)
92 {
93 const auto window = find_window(histo, prob);
94 return 0.5 * (window.second - window.first);
95 }
96
97 template <typename T>
98 double s68(const T &histo) { return smallest_interval(histo, PROB_1SIGMA); }
99
100 template <typename T>
101 double s90(const T &histo) { return smallest_interval(histo, 0.90); }
102
103 } // namespace binned
104} // namespace widthestimators
const double width
double s90(const T &histo)
double smallest_interval(const T &histo, double prob=PROB_1SIGMA)
double s68(const T &histo)
std::vector< double > get_cum_sum(const T &histo, bool normed=false)
cumulative sum (e.g.
std::pair< double, double > find_window(const T &histo, double prob=PROB_1SIGMA)
return smallest window (first value, second value) containing prob fraction of the events
const double PROB_1SIGMA