30namespace owned = ::mist::hep::owned;
36[[nodiscard]]
inline double
40 for (
int i = 0; i < g.GetN(); ++i) {
41 const double x = g.GetPointX(i);
42 if (x > tmin && x < tmax && g.GetPointY(i) > amp) amp = g.GetPointY(i);
52[[nodiscard]]
inline std::pair<double, double>
53extremum(
const TGraph& g,
bool find_min =
false,
54 double min_x = 0.0,
double max_x = 0.0)
56 const bool whole = (min_x == max_x);
57 const double sign = find_min ? -1.0 : 1.0;
58 double best_x = std::nan(
""), best_y = std::nan(
"");
59 double best = -std::numeric_limits<double>::infinity();
60 for (
int i = 0; i < g.GetN(); ++i) {
61 const double x = g.GetPointX(i);
62 if (!whole && (x < min_x || x > max_x))
continue;
63 const double v = sign * g.GetPointY(i);
64 if (v > best) { best = v; best_x = x; best_y = g.GetPointY(i); }
66 return {best_x, best_y};
75[[nodiscard]]
inline std::vector<double>
78 std::vector<double> crossings;
80 for (
int i = 0; i < g.GetN(); ++i) {
81 const double y = g.GetPointY(i);
82 if (!armed && direction * y > direction * threshold * 0.5)
continue;
84 if (direction * y < direction * threshold)
continue;
85 crossings.push_back(g.GetPointX(i));
95[[nodiscard]]
inline std::pair<double, double>
96first_above(
const TGraph& g,
double threshold,
bool negative =
false)
98 const double sign = negative ? -1.0 : 1.0;
99 for (
int i = 0; i < g.GetN(); ++i)
100 if (sign * g.GetPointY(i) > sign * threshold)
101 return {g.GetPointX(i), g.GetPointY(i)};
102 return {std::nan(
""), std::nan(
"")};
105[[nodiscard]]
inline std::pair<double, double>
106last_above(
const TGraph& g,
double threshold,
bool negative =
false)
108 const double sign = negative ? -1.0 : 1.0;
109 for (
int i = g.GetN() - 1; i >= 0; --i)
110 if (sign * g.GetPointY(i) > sign * threshold)
111 return {g.GetPointX(i), g.GetPointY(i)};
112 return {std::nan(
""), std::nan(
"")};
124 if (block_size == 0)
return out;
125 const int n = g.GetN();
126 const int step =
static_cast<int>(block_size);
127 for (
int i = 0; i < n; i += step) {
128 double best_x = g.GetPointX(i), best_y = g.GetPointY(i);
129 for (
int j = i + 1; j < std::min(i + step, n); ++j)
130 if (g.GetPointY(j) > best_y) { best_y = g.GetPointY(j); best_x = g.GetPointX(j); }
131 out->SetPoint(out->GetN(), best_x, best_y);
147 const int n = g.GetN();
148 const int w =
static_cast<int>(window);
149 if (w == 0 || w > n || sigma <= 0.0)
return out;
151 const double centre = 0.5 * (w - 1);
152 for (
int i = 0; i + w <= n; ++i) {
153 double sum_w = 0.0, sum_x = 0.0, sum_y = 0.0;
154 for (
int j = 0; j < w; ++j) {
155 const double d = (j - centre) / sigma;
156 const double weight = std::exp(-0.5 * d * d);
158 sum_x += weight * g.GetPointX(i + j);
159 sum_y += weight * g.GetPointY(i + j);
161 out->SetPoint(out->GetN(), sum_x / sum_w, sum_y / sum_w);
173[[nodiscard]]
inline double
175 int power = 1,
bool use_bin_width =
false)
177 if (g.GetN() < 2)
return 0.0;
178 const bool whole = (min_x == max_x);
179 const double dx = use_bin_width ? (g.GetPointX(1) - g.GetPointX(0)) : 1.0;
180 double integral = 0.0;
181 for (
int i = 0; i < g.GetN(); ++i) {
182 const double x = g.GetPointX(i);
183 if (!whole && (x < min_x || x > max_x))
continue;
184 integral += dx * std::pow(g.GetPointY(i), power);
205[[nodiscard]]
inline std::vector<peak>
207 int half_window = 10,
bool negative =
false)
209 std::vector<peak> peaks;
210 const int n = g.GetN();
211 if (half_window < 1) half_window = 1;
212 const double sign = negative ? -1.0 : 1.0;
214 for (
int i = 0; i < n; ++i) {
215 const double y = sign * g.GetPointY(i);
216 const int lo = std::max(0, i - half_window);
217 const int hi = std::min(n - 1, i + half_window);
218 const double y_lo = sign * g.GetPointY(lo);
219 const double y_hi = sign * g.GetPointY(hi);
220 if (y - y_lo < min_prominence)
continue;
221 if (y - y_hi < min_prominence)
continue;
222 peaks.push_back({g.GetPointX(i), g.GetPointY(i), i});
std::unique_ptr< T, root_deleter > root_ptr
Definition owned.h:60
root_ptr< T > make(Args &&... args)
Definition owned.h:67
std::pair< double, double > first_above(const TGraph &g, double threshold, bool negative=false)
Definition waveform.h:96
owned::root_ptr< TGraph > maximum_filter(const TGraph &g, std::size_t block_size)
Definition waveform.h:121
std::pair< double, double > last_above(const TGraph &g, double threshold, bool negative=false)
Definition waveform.h:106
std::vector< peak > find_peaks(const TGraph &g, double min_prominence, int half_window=10, bool negative=false)
Definition waveform.h:206
owned::root_ptr< TGraph > gaussian_filter(const TGraph &g, std::size_t window, double sigma)
Definition waveform.h:144
double integrate(const TGraph &g, double min_x, double max_x, int power=1, bool use_bin_width=false)
Definition waveform.h:174
std::pair< double, double > extremum(const TGraph &g, bool find_min=false, double min_x=0.0, double max_x=0.0)
Definition waveform.h:53
double amplitude(const TGraph &g, double tmin, double tmax)
Definition waveform.h:37
std::vector< double > threshold_crossings(const TGraph &g, double threshold, double direction=1.0)
Definition waveform.h:76
Definition waveform.h:192
double x
Definition waveform.h:193
double y
Definition waveform.h:194
int index
Definition waveform.h:195