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