Jpp  18.0.0-rc.3
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JFrodo.cc File Reference

Fit time-slewing histogram in output of JCalibrateMuon.cc in calibration mode. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TF1.h"
#include "TMath.h"
#include "TFitResult.h"
#include "JTools/JRange.hh"
#include "JDetector/JCalibration.hh"
#include "JDetector/JPMTAnalogueSignalProcessor.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

Fit time-slewing histogram in output of JCalibrateMuon.cc in calibration mode.

Author
mdejong

Definition in file JFrodo.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 64 of file JFrodo.cc.

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:1514
debug
Definition: JMessage.hh:29
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
*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
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
#define NOTICE(A)
Definition: JMessage.hh:64
#define FATAL(A)
Definition: JMessage.hh:67
const double xmin
Definition: JQuadrature.cc:23
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
Definition: JMuonPostfit.sh:36
no fit printf nominal n $STRING awk v X
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
int debug
debug level