Jpp  17.3.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JFrodo.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 #include <vector>
5 
6 #include "TROOT.h"
7 #include "TFile.h"
8 #include "TH1D.h"
9 #include "TH2D.h"
10 #include "TF1.h"
11 #include "TMath.h"
12 #include "TFitResult.h"
13 
14 #include "JTools/JRange.hh"
17 
18 #include "Jeep/JPrint.hh"
19 #include "Jeep/JParser.hh"
20 #include "Jeep/JMessage.hh"
21 
22 namespace {
23 
24  /**
25  * Name of histogram with fit results from JCalibrateMuon.
26  */
27  const char* h2_t = "ha";
28 
29  const char* gauss_t = "Gauss"; //!< Gaussian
30  const char* emg_t = "EMG"; //!< Exponentially Modified Gaussian
31 
32 
33  using namespace JPP;
34 
36 
37  /**
38  * Fit function.
39  *
40  * \param x abscissa values
41  * \param parameters parameter values
42  * \return ordinate value
43  */
44  Double_t getRisetime(Double_t* x, Double_t* parameters)
45  {
46  const double t0 = parameters[0];
47  const double p1 = parameters[1];
48  const double t1 = parameters[2];
49 
50  const double npe = cpu.getNPE(x[0]);
51 
52  double ts = t0 + cpu.getRiseTime(npe) + t1 * (1.0 - exp(-npe*p1));
53 
54  return ts;
55  }
56 }
57 
58 
59 /**
60  * \file
61  * Fit time-slewing histogram in output of JCalibrateMuon.cc in calibration mode.
62  * \author mdejong
63  */
64 int main(int argc, char **argv)
65 {
66  using namespace std;
67  using namespace JPP;
68 
69  typedef JRange<double> JRange_t;
70 
71  vector<string> inputFile;
72  string outputFile;
73  string function;
74  JRange_t T_ns;
75  bool writeFits;
77  JRange_t X;
78  string option;
79  int debug;
80 
81  try {
82 
83  JProperties properties = parameters.getProperties();
84 
85  JParser<> zap("Program to fit time-slewing histogram in output of JCalibrateMuon.");
86 
87  zap['f'] = make_field(inputFile, "input files (output from JCalibrateMuon).");
88  zap['o'] = make_field(outputFile, "output file.") = "frodo.root";
89  zap['F'] = make_field(function, "fit function") = gauss_t, emg_t;
90  zap['T'] = make_field(T_ns, "ROOT fit range around maximum [ns].") = JRange_t(-7.5,+7.5);
91  zap['w'] = make_field(writeFits, "write fit results.");
92  zap['P'] = make_field(properties) = JPARSER::initialised();
93  zap['x'] = make_field(X, "ROOT fit range for time-over threshold") = JRange_t(0.0, 256.0);
94  zap['O'] = make_field(option, "ROOT fit option, see TH1::Fit.") = "";
95  zap['d'] = make_field(debug) = 1;
96 
97  zap(argc, argv);
98  }
99  catch(const exception &error) {
100  FATAL(error.what() << endl);
101  }
102 
103 
104  if (!T_ns.is_valid()) {
105  FATAL("Invalid fit range [ns] " << T_ns << endl);
106  }
107 
108  cpu.setPMTParameters(parameters);
109 
110  if (option.find('S') == string::npos) { option += 'S'; }
111  if (option.find('Q') == string::npos && debug < JEEP::debug_t) { option += 'Q'; }
112 
113  // rebin time-over-threshold
114 
115  const Double_t x[] = {
116  -0.5, 3.5, 6.5, 9.5, 12.5, 15.5, 18.5,
117  20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,
118  30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,
119  40.5, 42.5, 44.5, 46.5, 48.5,
120  50.5, 52.5, 54.5, 56.5, 58.5,
121  60.5, 65.5,
122  70.5, 75.5,
123  80.5, 85.5,
124  90.5, 95.5,
125  100.5, 120.5, 140.5, 160.5, 180.5, 200.5, 250.5
126  };
127 
128  const int N = sizeof(x)/sizeof(x[0]);
129 
130  TH2D* h2 = NULL;
131 
132  for (vector<string>::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
133 
134  NOTICE("Processing " << *i << endl);
135 
136  TFile in(i->c_str(), "exist");
137 
138  if (!in.IsOpen()) {
139  FATAL("File " << *i << " not opened." << endl);
140  }
141 
142  TH2D* p = dynamic_cast<TH2D*>(in.Get(h2_t));
143 
144  if (p == NULL) {
145  FATAL("File " << *i << " has no histogram <" << h2_t << ">." << endl);
146  }
147 
148  if (h2 == NULL)
149  h2 = (TH2D*) p->Clone();
150  else
151  h2->Add(p);
152 
153  h2->SetDirectory(0);
154 
155  in.Close();
156  }
157 
158  if (h2 == NULL) {
159  FATAL("No histogram <" << h2_t << ">." << endl);
160  }
161 
162  // histogram fit results
163 
164  TH1D h0("h0", NULL, N-1, x);
165 
166  TFile out(outputFile.c_str(), "recreate");
167 
168  for (int i = 1; i <= h0.GetXaxis()->GetNbins(); ++i) {
169 
170  const Int_t imin = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinLowEdge(i));
171  const Int_t imax = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinUpEdge (i));
172 
173  TH1D h1(MAKE_CSTRING(i << ".1D"), NULL, h2->GetYaxis()->GetNbins(), h2->GetYaxis()->GetXmin(), h2->GetYaxis()->GetXmax());
174 
175  // start values
176 
177  Double_t ymax = 0.0;
178  Double_t x0 = 0.0; // [ns]
179  Double_t sigma = 3.5; // [ns]
180 
181  for (int iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
182 
183  Double_t x = h1.GetBinCenter (iy);
184  Double_t y = 0.0;
185 
186  for (int ix = imin; ix != imax; ++ix) {
187  y += h2->GetBinContent(ix,iy);
188  }
189 
190  h1.SetBinContent(iy, y);
191 
192  if (y > ymax) {
193  ymax = y;
194  x0 = x;
195  }
196  }
197 
198 
199  TF1* f1 = NULL;
200 
201  if (function == gauss_t) {
202 
203  f1 = new TF1(function.c_str(), "[0]*TMath::Gaus(x,[1],[2]) + [3]");
204 
205  f1->SetParameter(0, ymax);
206  f1->SetParameter(1, x0);
207  f1->SetParameter(2, sigma);
208  f1->SetParameter(3, 0.0);
209 
210  f1->SetParLimits(3, 0.0, ymax);
211 
212  } else if (function == emg_t) {
213 
214  f1 = new TF1(function.c_str(), "[0]*TMath::Exp(0.5*[3]*(2.0*[1]+[3]*[2]*[2]-2.0*x))*TMath::Erfc(([1]+[3]*[2]*[2]-x)/(TMath::Sqrt(2.0)*[2])) +[4]");
215 
216  f1->SetParameter(0, ymax);
217  f1->SetParameter(1, x0 - 0.5*sigma);
218  f1->SetParameter(2, sigma);
219  f1->SetParameter(3, 0.04);
220  f1->SetParameter(4, 0.0);
221 
222  f1->SetParLimits(4, 0.0, ymax);
223 
224  } else {
225 
226  FATAL("Unknown fit function " << function << endl);
227  }
228 
229  // fit
230 
231  Double_t xmin = x0 + T_ns.getLowerLimit();
232  Double_t xmax = x0 + T_ns.getUpperLimit();
233 
234  if (xmin < h1.GetXaxis()->GetXmin()) { xmin = h1.GetXaxis()->GetXmin(); }
235  if (xmax > h1.GetXaxis()->GetXmax()) { xmax = h1.GetXaxis()->GetXmax(); }
236 
237  TFitResultPtr result = h1.Fit(f1, option.c_str(), "same", xmin, xmax);
238 
239  if (result.Get() == NULL) {
240  FATAL("Invalid TFitResultPtr " << h1.GetName() << endl);
241  }
242 
243  if (debug >= notice_t || !result->IsValid()) {
244  cout << "Bin: "
245  << setw(4) << i << ' '
246  << FIXED(7,3) << f1->GetParameter(1) << " +/- "
247  << FIXED(7,3) << f1->GetParError (1) << ' '
248  << FIXED(7,3) << result->Chi2() << '/'
249  << result->Ndf() << ' '
250  << (result->IsValid() ? "" : "failed") << endl;
251  }
252 
253  if (result->IsValid()) {
254  h0.SetBinContent(i, f1->GetParameter(1));
255  h0.SetBinError (i, f1->GetParError (1));
256  }
257 
258  if (writeFits) {
259  h1.Write();
260  }
261 
262  delete f1;
263  }
264 
265  // Fit
266 
267  TF1 f1("f1", getRisetime, x[0], x[N-1], 3);
268 
269  f1.SetParameter(0, 0.0);
270  f1.SetParameter(1, 2.0e-2);
271  f1.FixParameter(2, -7.0);
272 
273  TFitResultPtr result = h0.Fit(&f1, "S", "same", X.constrain(x[0]), X.constrain(x[N-1]));
274 
275  if (debug >= notice_t || !result->IsValid()) {
276  cout << "Time-slewing correction" << endl;
277  cout << FIXED(7,3) << result->Chi2() << '/'
278  << result->Ndf() << ' '
279  << (result->IsValid() ? "" : "failed") << endl;
280 
281  for (int i = 0; i != f1.GetNpar(); ++i) {
282  cout << "parameter[" << i << "] = " << FIXED(8,4) << f1.GetParameter(i) << " +/- " << FIXED(8,4) << f1.GetParError (i) << endl;
283  }
284  }
285 
286  cout << "// Produced by JFrodo.cc; to be included on JGetRiseTime.hh." << endl;
287 
288  const double t0 = f1.Eval(TIME_OVER_THRESHOLD_NS);
289 
290  for (int i = 0; i != 256; ++i) {
291  cout << "this->push_back(" << FIXED(6,2) << f1.Eval((Double_t) i) - t0 << ");" << endl;
292  }
293 
294  h0.Write();
295 
296  out.Close();
297 }
const double xmax
Definition: JQuadrature.cc:24
Utility class to parse command line options.
Definition: JParser.hh:1517
debug
Definition: JMessage.hh:29
int main(int argc, char *argv[])
Definition: Main.cc:15
TPaveText * p1
Time calibration (including definition of sign of time offset).
const double TIME_OVER_THRESHOLD_NS
Specification for time-over-threshold corresponding to a one photo-electron pulse.
notice
Definition: JMessage.hh:32
Utility class to parse parameter values.
Definition: JProperties.hh:496
then JShowerPostfit f $INPUT_FILE o $OUTPUT_FILE N
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:136
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
string outputFile
const double sigma[]
Definition: JQuadrature.cc:74
const JPolynome f1(1.0, 2.0, 3.0)
Function.
Type definition of range.
Definition: JHead.hh:41
I/O formatting auxiliaries.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1993
return result
Definition: JPolint.hh:764
#define NOTICE(A)
Definition: JMessage.hh:64
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
const double xmin
Definition: JQuadrature.cc:23
Auxiliary class to define a range between two values.
Utility class to parse command line options.
no fit printf nominal n $STRING awk v X
PMT analogue signal processor.
Data structure for PMT parameters.
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 JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable STRING $argv[2] set_array QUANTILES set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable MODULE `getModule -a $DETECTOR -L "$STRING 0"` source JAcousticsToolkit.sh typeset -A TRIPODS get_tripods $WORKDIR/tripod.txt TRIPODS XMEAN
int debug
debug level