sipm-characterisation 0.1.0
SiPM characterisation for ePIC — IV/DCR/gain, laser, readout, irradiation
Loading...
Searching...
No Matches
utility.h
Go to the documentation of this file.
1#pragma once
2
3namespace utility
4{
5 // Find first/lqast value above threshold
6 // --- negative_search triggers the search in negative values
7 template <bool negative_search = false>
8 std::pair<float, float>
10 {
11 auto sign = 1 - negative_search * 2;
12 for (int iPnt = 0; iPnt < gTarget->GetN(); iPnt++)
13 if (sign * gTarget->GetPointY(iPnt) > sign * threshold)
14 return {gTarget->GetPointX(iPnt), gTarget->GetPointY(iPnt)};
15 return {-1., -1.};
16 }
17 template <bool negative_search = false>
18 std::pair<float, float>
20 {
21 auto sign = 1 - negative_search * 2;
22 for (int iPnt = gTarget->GetN() - 1; iPnt >= 0; iPnt--)
23 if (sign * gTarget->GetPointY(iPnt) > sign * threshold)
24 return {gTarget->GetPointX(iPnt), gTarget->GetPointY(iPnt)};
25 return {-1., -1.};
26 }
27
28 // Fill a TProfile for the average of TGraphs
30 {
31 for (auto iPnt = 0; iPnt < gSource->GetN(); iPnt++)
32 {
33 hTarget->Fill(gSource->GetPointX(iPnt), gSource->GetPointY(iPnt));
34 }
35 }
36 // Fill a TH2F for the persistance of TGraphs
38 {
39 for (auto iPnt = 0; iPnt < gSource->GetN(); iPnt++)
40 {
41 hTarget->Fill(gSource->GetPointX(iPnt), gSource->GetPointY(iPnt));
42 }
43 }
44 // Fill a TH2F for the persistance of TGraphs
46 {
47 for (auto iBin = 1; iBin <= hTarget->GetNbinsX(); iBin++)
48 {
49 auto current_x = hTarget->GetXaxis()->GetBinCenter(iBin);
50 hTarget->Fill(current_x, fSource->Eval(current_x));
51 }
52 }
53 // Fill TH1F from all points in a given interval
54 // --- Source is a TGraph
56 {
57 for (int iPnt = 0; iPnt < gSource->GetN(); iPnt++)
58 {
59 if (gSource->GetPointX(iPnt) < min)
60 continue;
61 if (gSource->GetPointX(iPnt) > max)
62 break;
63 hTarget->Fill(gSource->GetPointY(iPnt));
64 }
65 }
66 // --- Source is a TProfile
68 {
69 for (int iBin = 1; iBin <= gSource->GetNbinsX(); iBin++)
70 {
71 if (gSource->GetBinCenter(iBin) < min)
72 continue;
73 if (gSource->GetBinCenter(iBin) > max)
74 break;
75 hTarget->Fill(gSource->GetBinContent(iBin));
76 }
77 }
78 // Get Graph max
79 template <bool negative_search = false>
80 std::pair<float, float>
81 get_graph_max(TGraph *gTarget, float min_point = -1., float max_point = -1.)
82 {
83 auto sign = 1 - negative_search * 2;
84 auto result_x = gTarget->GetY()[0];
85 auto result_y = gTarget->GetX()[0];
86 for (int iPnt = 1; iPnt < gTarget->GetN(); iPnt++)
87 {
88 auto current_x = gTarget->GetX()[iPnt];
90 continue;
91 auto current_y = gTarget->GetY()[iPnt];
92 if (sign * current_y > sign * result_y)
93 {
96 }
97 }
98 return {result_x, result_y};
99 }
100 // Moving average of a graph
101 template <int average_over_n_points = 2>
102 TGraph *
104 {
105 static_assert(average_over_n_points > 0, "averaging should be with at least one point");
106 if (average_over_n_points == 1)
107 return gTarget;
108 auto gResult = new TGraph();
109 gResult->SetName(gTarget->GetName());
110 for (int iPnt = 0; iPnt < gTarget->GetN() - average_over_n_points; ++iPnt)
111 {
112 double new_x = 0.;
113 double new_y = 0.;
114 for (int jPnt = iPnt; jPnt < iPnt + average_over_n_points; ++jPnt)
115 {
116 new_x += gTarget->GetPointX(jPnt);
117 new_y += gTarget->GetPointY(jPnt);
118 }
121 gResult->SetPoint(iPnt, new_x, new_y);
122 }
123 return gResult;
124 }
125 // Max filter of a graph
126 template <int average_over_n_points = 2>
127 TGraph *
129 {
130 static_assert(average_over_n_points > 0, "filtering should be with at least one point");
131 if (average_over_n_points == 1)
132 return gTarget;
133 auto gResult = new TGraph();
134 gResult->SetName(gTarget->GetName());
135 auto new_points = 0;
136 for (int iPnt = 0; iPnt < gTarget->GetN(); iPnt += average_over_n_points)
137 {
138 double new_x = gTarget->GetPointX(iPnt);
139 double new_y = gTarget->GetPointY(iPnt);
140 for (int jPnt = iPnt + 1; jPnt < min(iPnt + average_over_n_points,gTarget->GetN()); ++jPnt)
141 {
142 if (gTarget->GetPointY(jPnt) > new_y)
143 {
144 new_x = gTarget->GetPointX(jPnt);
145 new_y = gTarget->GetPointY(jPnt);
146 }
147 }
148 gResult->SetPoint(new_points, new_x, new_y);
149 new_points++;
150 }
151 return gResult;
152 }
153 // Gauss filter of a graph
154 template <int window_of_n_points = 2>
155 TGraph *
157 {
158 // Require the window of points to be at least 1
159 static_assert(window_of_n_points > 0, "gaus filter should be with at least one point");
160 // >>> If it is one, return target itself
161 if (window_of_n_points == 1)
162 return gTarget;
163 // Build result graph
164 auto gResult = new TGraph();
165 gResult->SetName(Form("%s_gausfilter_n%i_a%i", gTarget->GetName(), window_of_n_points));
166 //
167 for (int iPnt = 0; iPnt < gTarget->GetN() - window_of_n_points; ++iPnt)
168 {
169 double new_x = 0.;
170 double new_y = 0.;
171 for (int jPnt = iPnt; jPnt < iPnt + window_of_n_points; ++jPnt)
172 {
173 new_x += gTarget->GetPointX(jPnt);
174 new_y += gTarget->GetPointY(jPnt);
175 }
178 gResult->SetPoint(iPnt, new_x, new_y);
179 }
180 return gResult;
181 }
182 // Derivative of graph
183 TGraph *
185 {
186 auto gResult = new TGraph();
187 gResult->SetName(gTarget->GetName());
188 for (int iPnt = 0; iPnt < gTarget->GetN() - 1; ++iPnt)
189 {
190 auto current_x = gTarget->GetPointX(iPnt);
191 auto current_y = gTarget->GetPointY(iPnt);
192 auto next_x = gTarget->GetPointX(iPnt + 1);
193 auto next_y = gTarget->GetPointY(iPnt + 1);
194 gResult->SetPoint(iPnt, current_x * 0.5 + next_x * 0.5, (next_y - current_y) / (next_x - current_x));
195 }
196 return gResult;
197 }
198 // From TProfile to TGraphErrors
199 TGraph *
201 {
202 auto result = new TGraphErrors();
203 for (auto iBin = 1; iBin < gSource->GetNbinsX(); iBin++)
204 {
205 result->SetPoint(iBin - 1, gSource->GetBinCenter(iBin), gSource->GetBinContent(iBin));
206 result->SetPointError(iBin - 1, gSource->GetBinWidth(iBin) * 0.5, gSource->GetBinError(iBin));
207 }
208 return result;
209 }
210 // Measure simil-integral from waveform
211 template <int power = 1,
212 bool bin_width = false>
213 float
214 integrate(TGraph *gTarget, float min_point = -1., float max_point = -1.)
215 {
216 auto gResult = new TGraph();
217 gResult->SetName(gTarget->GetName());
218 auto bin_size = bin_width ? (gTarget->GetPointX(1) - gTarget->GetPointX(0)) : 1.;
219 auto integral = 0.;
220 for (int iPnt = 0; iPnt < gTarget->GetN() - 1; ++iPnt)
221 {
222 auto current_x = gTarget->GetX()[iPnt];
223 if (((current_x < min_point) || (current_x > max_point)) && (min_point != max_point))
224 continue;
225 integral += bin_size * pow(gTarget->GetPointY(iPnt), power);
226 }
227 return integral;
228 }
229 // Measure noisepower
230 // --- From TGraph
231 template <int n_parameter = 2,
232 int n_averaging = 10>
233 std::pair<float, float>
235 {
236 // Derivate the requeste number of time, smoothing over the given number of averging points
237 static_assert(n_parameter > 0, "n parameter must be greater than 0");
238 static_assert(n_averaging > 0, "averaging must be greater than 0");
241 for (auto iTer = 1; iTer < n_parameter; iTer++)
243 //
244 return {integrate<2>(used_derivative, -2., 2.) - 0.04 * integrate<2>(used_derivative, -10., -110.), integrate(gTarget, -5., 95.) - integrate(gTarget, -10., -110.)};
245 }
246 // --- From TProfile
247 template <int n_parameter = 2,
248 int n_averaging = 10>
249 std::pair<float, float>
254
255 // Peak finder
256 // Each element is a peak that has been found:
257 // [peak x-coordinate] [peak y-coordinate] [point n]
258 /*
259 template <int window_of_n_points = 100,
260 int average_over_n_points = 100,
261 bool negative_search = false>
262 std::vector<std::array<float, 3>>
263 find_peaks(TGraph *gTarget, float min_height = 10.)
264 {
265 // Result
266 std::vector<std::array<float, 3>> result;
267 // Check the window is at least 3
268 static_assert(window_of_n_points > 2, "peak finder should have at least 3 points window");
269 auto gNewTarget = moving_average<average_over_n_points>(gTarget);
270 for (int iPnt = 0; iPnt < gNewTarget->GetN(); iPnt++)
271 {
272 auto current_x = gNewTarget->GetPointX(iPnt);
273 auto current_y = gNewTarget->GetPointY(iPnt);
274 auto previous_y = gNewTarget->GetPointY(max(0, iPnt - window_of_n_points));
275 auto next_y = gNewTarget->GetPointY(min(gNewTarget->GetN(), iPnt + window_of_n_points));
276 if ((current_y - previous_y) < min_height)
277 continue;
278 if ((current_y - next_y) < min_height)
279 continue;
280 result.push_back({static_cast<float>(current_x), static_cast<float>(current_y), static_cast<float>(iPnt)});
281 iPnt += window_of_n_points;
282 }
283 TCanvas* c1 = new TCanvas();
284 gNewTarget->Draw("ALPE");
285 return result;
286 }
287 */
288
289 template <int window_of_n_points = 10,
290 int average_over_n_points = 20,
291 bool negative_search = false>
292 std::vector<std::array<float, 3>>
294 {
295 // Result
296 std::vector<std::array<float, 3>> result;
297 // Check the window is at least 3
298 static_assert(window_of_n_points > 2, "peak finder should have at least 3 points window");
300 for (int iPnt = 0; iPnt < gNewTarget->GetN(); iPnt++)
301 {
302 auto current_x = gNewTarget->GetPointX(iPnt);
303 auto current_y = gNewTarget->GetPointY(iPnt);
304 auto previous_y = gNewTarget->GetPointY(max(0, iPnt - window_of_n_points));
305 auto next_y = gNewTarget->GetPointY(min(gNewTarget->GetN(), iPnt + window_of_n_points));
307 continue;
308 if ((current_y - next_y) < min_height)
309 continue;
310 result.push_back({static_cast<float>(current_x), static_cast<float>(current_y), static_cast<float>(iPnt)});
312 }
313 TCanvas *c1 = new TCanvas();
314 gNewTarget->Draw("ALPE");
315 return result;
316 }
317
318} // namespace utility
TH2_Type * build_fine_tune_raw_histogram(std::vector< TString > kInputFileNames, TString kRunTag, TString kOutputFileName, bool kRecalculate)
Functions -------------------------------------------------------------------------------------------...
Definition fine_analysis.h:80
float threshold
Definition my_test_macro_for_WF_fitting.C:6
Definition general_utility.h:12
void fill_persistance(TH2F *hTarget, TGraph *gSource)
Definition utility.h:37
std::pair< float, float > find_last_above(TGraph *gTarget, float threshold)
Definition utility.h:19
std::pair< float, float > get_graph_max(TGraph *gTarget, float min_point=-1., float max_point=-1.)
Definition utility.h:81
TGraph * TProfile_to_TGraphErorrs(TProfile *gSource)
Definition utility.h:200
TGraph * gauss_filter(TGraph *gTarget, float alpha_parameter=2.5)
Definition utility.h:156
TGraph * maximum_filter(TGraph *gTarget)
Definition utility.h:128
std::vector< std::array< float, 3 > > find_peaks(TGraph *gTarget, float min_height=10.)
Definition utility.h:293
std::pair< float, float > find_first_above(TGraph *gTarget, float threshold)
Definition utility.h:9
void fill_profile(TProfile *hTarget, TGraph *gSource)
Definition utility.h:29
TGraph * moving_average(TGraph *gTarget)
Definition utility.h:103
void fill_from_interval(TH1F *hTarget, TGraph *gSource, float min, float max)
Definition utility.h:55
float integrate(TGraph *gTarget, float min_point=-1., float max_point=-1.)
Definition utility.h:214
std::pair< float, float > measure_noisepower(TGraph *gTarget)
Definition utility.h:234
TGraph * derivate(TGraph *gTarget, double sign=1.)
Definition utility.h:184