Jpp  19.1.0-rc.1
the software that should make you happy
Functions
JTTS.cc File Reference

Auxiliary program to model transition time distribution generator from data. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <cmath>
#include <limits>
#include "TROOT.h"
#include "TFile.h"
#include "TString.h"
#include "TRegexp.h"
#include "TGraph.h"
#include "TGraphErrors.h"
#include "TGraphSmooth.h"
#include "TF1.h"
#include "TH1D.h"
#include "TSpline.h"
#include "JROOT/JMinimizer.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Auxiliary program to model transition time distribution generator from data.

Author
mdejong

Definition in file JTTS.cc.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 33 of file JTTS.cc.

34 {
35  using namespace std;
36 
37  string inputFile;
38  string outputFile;
39  Double_t bass;
40  Double_t span;
41  Double_t xbin;
42  int numberOfBins;
43  string pdf;
44  string cdf;
45  int debug;
46 
47  try {
48 
49  JParser<> zap("Auxiliary program to model transition time distribution generator from data.");
50 
51  zap['f'] = make_field(inputFile);
52  zap['o'] = make_field(outputFile) = "";
53  zap['B'] = make_field(bass) = 0.0;
54  zap['S'] = make_field(span) = 0.0;
55  zap['x'] = make_field(xbin) = 1.0; // [ns]
56  zap['n'] = make_field(numberOfBins) = 1000;
57  zap['P'] = make_field(pdf) = "";
58  zap['C'] = make_field(cdf) = "";
59  zap['d'] = make_field(debug) = 1;
60 
61  zap(argc, argv);
62  }
63  catch(const exception &error) {
64  FATAL(error.what() << endl);
65  }
66 
67 
68  const TRegexp regexp("V[0-9]+");
69 
70  TString buffer(inputFile.c_str());
71 
72  Ssiz_t len = 0;
73  Ssiz_t pos = buffer.Index(regexp, &len);
74 
75  int version = 0;
76 
77  if (pos != -1) {
78  buffer = buffer(pos+1, len-1);
79  version = buffer.Atoi();
80  }
81 
82  NOTICE("File version " << version << endl);
83 
84 
85  typedef vector<Double_t> JVector_t;
86 
87  JVector_t X;
88  JVector_t Y;
89  JVector_t EX;
90  JVector_t EY;
91 
92  ifstream in(inputFile.c_str());
93 
94  if (version == 0) {
95 
96  for (Double_t x = 0.0, y; in >> y; x += xbin) {
97  X .push_back(x);
98  Y .push_back(y);
99  EX.push_back(0.0);
100  EY.push_back(sqrt(y));
101  }
102 
103  } else {
104 
105  in.ignore(numeric_limits<streamsize>::max(), '\n');
106 
107  for (Double_t x, y, dy, rms; in >> x >> y >> dy >> rms; ) {
108  X .push_back(x);
109  Y .push_back(y);
110  EX.push_back(0.0);
111  EY.push_back(dy);
112  }
113  }
114 
115  in.close();
116 
117 
118  int N = X.size();
119 
120  if (N < 25) {
121  FATAL("Not enough points." << endl);
122  }
123 
124  if (version != 0) {
125 
126  xbin = (X[N-1] - X[0]) / (N - 1);
127 
128  NOTICE("Bin width [ns] " << xbin << endl);
129  }
130 
131  // Histogram for log-likelihood fit
132 
133  TH1D h1("h1", NULL, N, X[0] - 0.5*xbin, X[N-1] + 0.5*xbin);
134 
135  h1.Sumw2();
136 
137  for (int i = 0; i != N; ++i) {
138  h1.SetBinContent(i+1, Y [i]);
139  h1.SetBinError (i+1, EY[i]);
140  }
141 
142 
143  // Fit function
144 
145  TF1 f1("f1", "[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2])) + [3]");
146 
147 
148  // start values
149 
150  Double_t ymax = 0.0;
151  Double_t x0 = 0.0;
152  Double_t sigma = 2.0;
153  Double_t ymin = 0.0;
154 
155  for (int i = 0; i != N; ++i) {
156  if (Y[i] > ymax) {
157  ymax = Y[i];
158  x0 = X[i];
159  }
160  }
161 
162  f1.SetParameter(0, ymax);
163  f1.SetParameter(1, x0);
164  f1.SetParameter(2, sigma);
165  f1.SetParameter(3, ymin);
166 
167 
168  h1.Fit(&f1, "LL", "same", x0 - 5 * sigma, x0 + 5 * sigma);
169 
170 
171  // center data at position of Gauss
172 
173  ymax = f1.GetParameter(0);
174  x0 = f1.GetParameter(1);
175  sigma = f1.GetParameter(2);
176  ymin = f1.GetParameter(3);
177 
178  if (version == 0) {
179 
180  for (JVector_t::iterator x = X.begin(); x != X.end(); ++x) {
181  *x -= x0;
182  }
183 
184  f1.SetParameter(1, x0 = 0);
185 
186  if (ymin <= 0.0) {
187  f1.SetParameter(3, 1e-4 * ymax); // avoid division by zero
188  }
189  }
190 
191  // count pre- and delayed pulses
192 
193  Double_t yy = 0.0;
194  Double_t yl = 0.0;
195  Double_t yr = 0.0;
196 
197  for (int i = 0; i != N; ++i) {
198 
199  const Double_t x = X[i];
200  const Double_t y = Y[i];
201 
202  yy += y;
203 
204  if (x < x0 - 5.0 * sigma)
205  yl += y;
206  else if (x > x0 + 5.0 * sigma)
207  yr += y;
208  }
209 
210  NOTICE("Number of pulses: " << yy << endl);
211  NOTICE("Pre-pulses: " << yl / yy << endl);
212  NOTICE("Delayed pulses: " << yr / yy << endl);
213 
214  if (version == 0) {
215 
216  // skip leading and trailing zeros for smoothing operation
217 
218  int n1 = 0;
219  int n2 = N - 1;
220 
221  while (n1 != N - 1 && Y[n1] == 0) ++n1;
222  while (n2 != 0 && Y[n2] == 0) --n2;
223 
224  //if (n1 != 0 ) --n1;
225  //if (n2 != N - 1) ++n2;
226 
227  if (n2 <= n1) {
228  FATAL("No non-zero data." << endl);
229  }
230 
231  X = JVector_t(X .data() + n1, X .data() + n2);
232  Y = JVector_t(Y .data() + n1, Y .data() + n2);
233  EX = JVector_t(EX.data() + n1, EX.data() + n2);
234  EY = JVector_t(EY.data() + n1, EY.data() + n2);
235 
236  N = X.size();
237  }
238 
239  TGraphErrors g0(N, X.data(), Y.data(), EX.data(), EY.data());
240 
241  g0.SetName("g0");
242 
243  TGraphErrors g1(g0); // copy
244 
245  g1.SetName("g1");
246 
247 
248  if (version == 0) {
249 
250  // divide TGraph data by TF1 fit function
251 
252  for (int i = 0; i != N; ++i) {
253 
254  const Double_t x = g1.GetX()[i];
255  const Double_t f = f1.Eval(x);
256 
257  g1.GetY() [i] /= f;
258  g1.GetEY()[i] /= f;
259  }
260 
261  // smooth TGraph
262 
263  TGraphSmooth gs("gs");
264 
265  TGraph* gout = gs.SmoothSuper(&g1, "", bass, span, false, g1.GetEY());
266 
267 
268  // copy back results
269 
270  for (int i = 0; i != N; ++i) {
271  g1.GetY()[i] = gout->GetY()[i];
272  }
273 
274 
275  // multiply TGraph data by TF1 fit function
276 
277  for (int i = 0; i != N; ++i) {
278 
279  const Double_t x = g1.GetX()[i];
280  const Double_t f = f1.Eval(x);
281 
282  g1.GetY() [i] *= f;
283  g1.GetEY()[i] *= f;
284  }
285  }
286 
287  if (pdf != "") {
288 
289  TGraph g2(g1);
290 
291  Double_t W = 0.0;
292 
293  for (int i = 0; i != N; ++i) {
294  W += g2.GetY()[i];
295  }
296 
297  W *= xbin;
298 
299  for (int i = 0; i != N; ++i) {
300  g2.GetY()[i] /= W;
301  }
302 
303  ofstream out(pdf.c_str());
304 
305  const Double_t xmin = g2.GetX()[ 0 ];
306  const Double_t xmax = g2.GetX()[N-1];
307 
308  for (Double_t x = xmin, dx = (xmax - xmin) / numberOfBins; x <= xmax + 0.5*dx; x += dx) {
309 
310  out << "\t(*this)"
311  << "["
312  << showpos << FIXED(7,2) << x
313  << "] = "
314  << noshowpos << FIXED(6,4) << g2.Eval(x)
315  << ";" << endl;
316  }
317 
318  out.close();
319  }
320 
321  if (cdf != "") {
322 
323  TGraph g2(g1);
324 
325  for (int i = 0, j = 1; j != N; ++i, ++j) {
326  g2.GetY()[j] += g2.GetY()[i];
327  }
328 
329  const Double_t ymin = g2.GetY()[ 0 ];
330  const Double_t ymax = g2.GetY()[N-1];
331 
332  for (int i = 0; i != N; ++i) {
333 
334  const Double_t x = g2.GetX()[i];
335  const Double_t y = g2.GetY()[i];
336 
337  g2.GetX()[i] = (y - ymin) / ymax;
338  g2.GetY()[i] = x + 0.5 * xbin;
339  }
340 
341  ofstream out(cdf.c_str());
342 
343  const Double_t xmin = 0.0;
344  const Double_t xmax = 1.0;
345 
346  for (Double_t x = xmin, dx = (xmax - xmin) / numberOfBins; x <= xmax + 0.5*dx; x += dx) {
347 
348  out << "\t(*this)"
349  << "["
350  << noshowpos << FIXED(6,4) << x
351  << "] = "
352  << showpos << FIXED(9,5) << g2.Eval(x)
353  << ";" << endl;
354  }
355 
356  out.close();
357  }
358 
359 
360  if (outputFile != "") {
361 
362  // copy histogram centered at peak position
363 
364  const Double_t xmin = X[ 0 ];
365  const Double_t xmax = X[N-1];
366  const Double_t dx = (xmax - xmin) / N;
367 
368  TH1D h2("pmt", NULL, N, xmin - 0.5*dx, xmax + 0.5*dx);
369 
370  h2.Sumw2();
371 
372  Double_t W = 0.0;
373 
374  for (int i = 0; i != N; ++i) {
375  W += Y[i];
376  }
377 
378  W *= dx;
379 
380  for (int i = 0; i != N; ++i) {
381 
382  h2.SetBinContent(i+1, Y [i]/W);
383  h2.SetBinError (i+1, EY[i]/W);
384 
385  g1.GetY() [i] /= W;
386  g1.GetEY()[i] /= W;
387  }
388 
389  TFile out(outputFile.c_str(), "recreate");
390 
391  h1.Write();
392  h2.Write();
393  g0.Write();
394  g1.Write();
395 
396  out.Write();
397  out.Close();
398  }
399 }
string outputFile
#define NOTICE(A)
Definition: JMessage.hh:64
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2158
Double_t g1(const Double_t x)
Function.
Definition: JQuantiles.cc:25
int numberOfBins
number of bins for average CDF integral of optical module
Definition: JSirene.cc:70
Utility class to parse command line options.
Definition: JParser.hh:1714
const double sigma[]
Definition: JQuadrature.cc:74
const JPolynome f1(1.0, 2.0, 3.0)
Function.
const double xmax
Definition: JQuadrature.cc:24
const double xmin
Definition: JQuadrature.cc:23
int j
Definition: JPolint.hh:792
Definition: JSTDTypes.hh:14
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:448