Jpp 19.3.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JLegolas.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <fstream>
5#include <vector>
6#include <cmath>
7#include <limits>
8
9#include "TROOT.h"
10#include "TFile.h"
11#include "TGraph.h"
12#include "TGraphErrors.h"
13#include "TGraphSmooth.h"
14#include "TF1.h"
15#include "TH1D.h"
16#include "TSpline.h"
17
18#include "JROOT/JMinimizer.hh"
19
20#include "JTools/JRange.hh"
21
22#include "Jeep/JPrint.hh"
23#include "Jeep/JParser.hh"
24#include "Jeep/JMessage.hh"
25
26namespace {
27
28 const char* const h0_1 = "h0";
29}
30
31/**
32 * \file
33 *
34 * Auxiliary program to model transition time distribution generator from data (e.g.\ output of JPulsar.cc).
35 * \author mdejong
36 */
37int main(int argc, char **argv)
38{
39 using namespace std;
40 using namespace JPP;
41
42 typedef JRange<double> JRange_t;
43
44 string inputFile;
45 string outputFile;
46 Double_t bass;
47 Double_t span;
48 string pdf;
49 string cdf;
50 JRange_t T_ns;
51 int debug;
52
53 try {
54
55 JParser<> zap("Auxiliary program to model transition time distribution generator from data.");
56
57 zap['f'] = make_field(inputFile, "input file (output from JPulsar)");
58 zap['o'] = make_field(outputFile) = "";
59 zap['B'] = make_field(bass, "see TGraphSmooth") = 0.00;
60 zap['S'] = make_field(span, "see TGraphSmooth") = 0.01;
61 zap['P'] = make_field(pdf, "PDF output file; for inclusion in JPMTTransitTimeProbability.hh") = "";
62 zap['C'] = make_field(cdf, "CDF output file; for inclusion in JPMTTransitTimeGenerator.hh") = "";
63 zap['T'] = make_field(T_ns, "time range for PDF and CDF") = JRange_t(-20.0, +100.0);
64 zap['d'] = make_field(debug) = 1;
65
66 zap(argc, argv);
67 }
68 catch(const exception &error) {
69 FATAL(error.what() << endl);
70 }
71
72
73 TH1D* h1 = NULL;
74
75 TFile in(inputFile.c_str(), "exist");
76
77 if (!in.IsOpen()) {
78 FATAL("File " << inputFile << " not opened." << endl);
79 }
80
81 h1 = dynamic_cast<TH1D*>(in.Get(h0_1));
82
83 if (h1 == NULL) {
84 FATAL("No histogram <" << h0_1 << ">." << endl);
85 }
86
87
88 // Fit function
89
90 TF1 f1("f1", "[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2])) + [3]");
91
92 // start values
93
94 Double_t ymax = 0.0;
95 Double_t x0 = 0.0;
96 Double_t sigma = 2.0;
97 Double_t ymin = 0.0;
98
99 for (Int_t i = 1; i <= h1->GetNbinsX(); ++i) {
100
101 const Double_t x = h1->GetBinCenter (i);
102 const Double_t y = h1->GetBinContent(i);
103
104 if (y > ymax) {
105 ymax = y;
106 x0 = x;
107 }
108 }
109
110 f1.SetParameter(0, ymax);
111 f1.SetParameter(1, x0);
112 f1.SetParameter(2, sigma);
113 f1.SetParameter(3, ymin);
114
115 // fit
116
117 h1->Fit(&f1, "LL", "same", x0 - 5 * sigma, x0 + 5 * sigma);
118
119 // copy results
120
121 ymax = f1.GetParameter(0);
122 x0 = f1.GetParameter(1);
123 sigma = f1.GetParameter(2);
124 ymin = f1.GetParameter(3);
125
126
127 // count pre- and delayed pulses and determine background
128
129 Double_t yy = 0.0;
130 Double_t yl = 0.0;
131 Double_t yr = 0.0;
132
133 Int_t n0 = 0.0;
134 Double_t y0 = 0.0;
135
136 for (Int_t i = 1; i <= h1->GetNbinsX(); ++i) {
137
138 const Double_t x = h1->GetBinCenter (i);
139 const Double_t y = h1->GetBinContent(i);
140
141 if (T_ns(x - x0)) {
142
143 yy += y;
144
145 if (x < x0 - 5.0 * sigma)
146 yl += y;
147 else if (x > x0 + 5.0 * sigma)
148 yr += y;
149
150 } else {
151
152 n0 += 1;
153 y0 += y;
154 }
155 }
156
157 if (n0 != 0) {
158 y0 /= n0;
159 }
160
161 // subtract average background
162
163 yy -= y0;
164 yl -= y0;
165 yr -= y0;
166
167 NOTICE("Number of pulses: " << yy << endl);
168 NOTICE("Pre-pulses: " << yl / yy << endl);
169 NOTICE("Delayed pulses: " << yr / yy << endl);
170
171
172 // extract data for smoothing
173
174 typedef vector<Double_t> JVector_t;
175
176 JVector_t X;
177 JVector_t Y;
178 JVector_t EX;
179 JVector_t EY;
180
181 for (Int_t i = 1; i <= h1->GetNbinsX(); ++i) {
182
183 const Double_t x = h1->GetBinCenter (i) - x0; // zero at position of Gauss
184 const Double_t y = h1->GetBinContent(i) - y0; // subtract background
185
186 if (T_ns(x)) {
187 X .push_back(x);
188 Y .push_back(y);
189 EX.push_back(0.0);
190 EY.push_back(sqrt(y));
191 }
192 }
193
194 const int N = X.size();
195
196 if (N <= 25) {
197 FATAL("Not enough points." << endl);
198 }
199
200
201 TGraphErrors g0(N, X.data(), Y.data(), EX.data(), EY.data());
202
203 g0.SetName("g0");
204
205 TGraphErrors g1(g0); // copy
206
207 g1.SetName("g1");
208
209
210 // divide TGraph data by TF1 fit function
211
212 for (int i = 0; i != N; ++i) {
213
214 const Double_t x = g1.GetX()[i];
215 const Double_t f = f1.Eval(x + x0);
216
217 g1.GetY() [i] /= f;
218 g1.GetEY()[i] /= f;
219 }
220
221
222 // smooth TGraph
223
224 TGraphSmooth gs("gs");
225
226 TGraph* gout = gs.SmoothSuper(&g1, "", bass, span, false);
227
228
229 // copy back results
230
231 for (int i = 0; i != N; ++i) {
232 g1.GetY()[i] = gout->GetY()[i];
233 }
234
235
236 // multiply TGraph data by TF1 fit function
237
238 for (int i = 0; i != N; ++i) {
239
240 const Double_t x = g1.GetX()[i];
241 const Double_t f = f1.Eval(x + x0);
242
243 g1.GetY() [i] *= f;
244 g1.GetEY()[i] *= f;
245 }
246
247
248 if (pdf != "") {
249
250 // normalise TGraph
251
252 TGraph g2(g1); // copy
253
254 Double_t W = 0.0;
255
256 for (int i = 0; i != N; ++i) {
257 W += g2.GetY()[i];
258 }
259
260 for (int i = 0; i != N; ++i) {
261 g2.GetY()[i] /= W;
262 }
263
264 ofstream out(pdf.c_str());
265
266 out << "\t// produced by JLegolas.cc" << endl;
267
268 const Double_t xmin = T_ns.getLowerLimit();
269 const Double_t xmax = T_ns.getUpperLimit();
270 const Double_t dx = 0.25;
271
272 for (Double_t x = xmin; x <= xmax + 0.5*dx; x += dx) {
273
274 Double_t y = g2.Eval(x);
275
276 if (y < 0.0) {
277 y = 0.0;
278 }
279
280 out << "\t(*this)"
281 << "["
282 << showpos << FIXED(7,2) << x
283 << "] = "
284 << noshowpos << FIXED(8,6) << y
285 << ";" << endl;
286 }
287
288 out.close();
289 }
290
291 if (cdf != "") {
292
293 // cumulate TGraph
294
295 TGraph g2(g1); // copy
296
297 for (int i = 0; i+1 != N; ++i) {
298 g2.GetY()[i+1] += g2.GetY()[i];
299 }
300
301 {
302 const Double_t xmin = g2.GetX()[ 0 ];
303 const Double_t xmax = g2.GetX()[N-1];
304 const Double_t dx = (xmax - xmin) / N;
305
306 const Double_t ymin = g2.GetY()[ 0 ];
307 const Double_t ymax = g2.GetY()[N-1];
308
309 for (int i = 0; i != N; ++i) {
310
311 const Double_t x = g2.GetX()[i];
312 const Double_t y = g2.GetY()[i];
313
314 g2.GetX()[i] = (y - ymin) / ymax;
315 g2.GetY()[i] = x + 0.5 * dx;
316 }
317 }
318
319 ofstream out(cdf.c_str());
320
321 out << "\t// produced by JLegolas.cc" << endl;
322
323 const Double_t xmin = 0.0;
324 const Double_t xmax = 1.0;
325 const Double_t dx = 0.001;
326
327 for (Double_t x = xmin; x <= xmax + 0.5*dx; x += dx) {
328
329 out << "\t(*this)"
330 << "["
331 << noshowpos << FIXED(6,4) << x
332 << "] = "
333 << showpos << FIXED(9,5) << g2.Eval(x)
334 << ";" << endl;
335 }
336
337 out.close();
338 }
339
340
341 if (outputFile != "") {
342
343 // copy of original histogram data for overlaying with TGraph
344
345 const Double_t xmin = X[ 0 ];
346 const Double_t xmax = X[N-1];
347 const Double_t dx = (xmax - xmin) / N;
348
349 TH1D h2("pmt", NULL, N, xmin - 0.5*dx, xmax + 0.5*dx);
350
351 h2.Sumw2();
352
353 // normalise
354
355 Double_t W = 0.0;
356
357 for (int i = 0; i != N; ++i) {
358 W += Y[i];
359 }
360
361 W *= dx;
362
363 for (int i = 0; i != N; ++i) {
364
365 h2.SetBinContent(i+1, Y [i]/W);
366 h2.SetBinError (i+1, EY[i]/W);
367
368 g1.GetY() [i] /= W;
369 g1.GetEY()[i] /= W;
370 }
371
372 TFile out(outputFile.c_str(), "recreate");
373
374 h1->Write();
375 h2.Write();
376 g0.Write();
377 g1.Write();
378
379 out.Write();
380 out.Close();
381 }
382}
string outputFile
int main(int argc, char **argv)
Definition JLegolas.cc:37
General purpose messaging.
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
I/O formatting auxiliaries.
Double_t g1(const Double_t x)
Function.
Definition JQuantiles.cc:25
Auxiliary class to define a range between two values.
Utility class to parse command line options.
Definition JParser.hh:1698
Range of values.
Definition JRange.hh:42
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448