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

General purpose fit program for 2D ROOT objects. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include "TROOT.h"
#include "TFile.h"
#include "TKey.h"
#include "TH2.h"
#include "TGraph2D.h"
#include "TGraph2DErrors.h"
#include "TF2.h"
#include "TString.h"
#include "TRegexp.h"
#include "JLang/JType.hh"
#include "JLang/JTypeList.hh"
#include "JLang/JToken.hh"
#include "JTools/JRange.hh"
#include "JGizmo/JRootObjectID.hh"
#include "JGizmo/JGizmoToolkit.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

General purpose fit program for 2D ROOT objects.


The option -f corresponds to <file name>:<object name>.

The expressions for the fit function, start and fixed values should comply with ROOT class TFormula.

In the expressions of the start and fixed values, names of member methods of corresponding class of the fit object may appear, such as TH1::GetMaximum, TH1::GetRMS, etc., e.g:

     -F "[0]*exp(-0.5*x*x/([1]*[1])*exp(-0.5*y*y/([2]*[2])"
     -@ "p0 = GetMaximum; p1 = 2*GetRMS(1); .."
     -= "p2 = 1"

The result of the formulas for the start and fixed values will be evaluated for each histogram separately.

Author
mdejong

Definition in file JFit2D.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 96 of file JFit2D.cc.

97 {
98  using namespace std;
99  using namespace JPP;
100 
101  typedef JToken<';'> JToken_t;
102  typedef JRange<double> JRange_t;
103 
104  vector<JRootObjectID> inputFile;
105  string outputFile;
106  string formula;
107  vector<JToken_t> startValues;
108  vector<JToken_t> fixedValues;
109  vector<JToken_t> limitValues;
110  JRange_t X;
111  JRange_t Y;
112  string option;
113  bool writeFits;
114  int debug;
115 
116  try {
117 
118  JParser<> zap("General purpose fit program for 2D ROOT objects.");
119 
120  zap['f'] = make_field(inputFile, "<input file>:<object name>");
121  zap['o'] = make_field(outputFile, "ROOT file with fit results") = "fit.root";
122  zap['F'] = make_field(formula, "fit formula, e.g: \"[0]+[1]*x\"");
123  zap['@'] = make_field(startValues, "start values, e.g: \"p0 = GetMaximum;\"");
124  zap['='] = make_field(fixedValues, "fixed values, e.g: \"p0 = GetMaximum;\"") = JPARSER::initialised();
125  zap['R'] = make_field(limitValues, "limit values, e.g: \"p0 = <lower limit> <upper limit>;\"") = JPARSER::initialised();
126  zap['x'] = make_field(X, "abscissa range") = JRange_t();
127  zap['y'] = make_field(Y, "abscissa range") = JRange_t();
128  zap['O'] = make_field(option, "Fit option") = "";
129  zap['w'] = make_field(writeFits, "write fit results to ROOT file");
130  zap['d'] = make_field(debug) = 1;
131 
132  zap['='] = JPARSER::initialised();
133 
134  zap(argc, argv);
135  }
136  catch(const exception &error) {
137  FATAL(error.what() << endl);
138  }
139 
140 
141  if (option.find('O') == string::npos) { option += "O"; }
142  //if (option.find('N') == string::npos) { option += "N"; }
143  if (debug == 0 && option.find('Q') == string::npos) { option += "Q"; }
144 
145 
146  TFile out(outputFile.c_str(), "recreate");
147 
148 
149  TF2* fcn = new TF2("user", formula.c_str());
150 
151  fcn->SetNpx(10000);
152 
153  if (fcn->IsZombie()) {
154  FATAL("Function: " << formula << " is zombie." << endl);
155  }
156 
157  for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
158 
159  DEBUG("Input: " << *input << endl);
160 
161  TDirectory* dir = getDirectory(*input);
162 
163  if (dir == NULL) {
164  ERROR("File: " << input->getFullFilename() << " not opened." << endl);
165  continue;
166  }
167 
168  const TRegexp regexp(input->getObjectName());
169 
170  TIter iter(dir->GetListOfKeys());
171 
172  for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
173 
174  const TString tag(key->GetName());
175 
176  DEBUG("Key: " << tag << " match = " << tag.Contains(regexp) << endl);
177 
178  // option match
179 
180  if (tag.Contains(regexp) && isTObject(key)) {
181 
182  TObject* object = key->ReadObj();
183 
184 
185  // set fit parameters
186 
187  try {
188 
189  for (vector<JToken_t>::const_iterator i = startValues.begin(); i != startValues.end(); ++i) {
190  fcn->SetParameter(getParameter(*i), getValue(*i,object));
191  }
192 
193  for (vector<JToken_t>::const_iterator i = fixedValues.begin(); i != fixedValues.end(); ++i) {
194  fcn->FixParameter(getParameter(*i), getValue(*i,object));
195  }
196 
197  for (vector<JToken_t>::const_iterator i = limitValues.begin(); i != limitValues.end(); ++i) {
198  fcn->SetParLimits(getParameter(*i), getValue(*i,0), getValue(*i,1));
199  }
200  }
201  catch(JLANG::JParseError& error) {
202  FATAL(error << endl);
203  }
204 
205  DEBUG("Start values " << object->GetName() << endl);
206 
207  for (int i = 0; i != fcn->GetNpar(); ++i) {
208  DEBUG(left << setw(12) << fcn->GetParName (i) << ' ' <<
209  SCIENTIFIC(12,5) << fcn->GetParameter(i) << endl);
210  }
211 
212  Double_t xmin = numeric_limits<Double_t>::max();
213  Double_t xmax = numeric_limits<Double_t>::lowest();
214  Double_t ymin = numeric_limits<Double_t>::max();
215  Double_t ymax = numeric_limits<Double_t>::lowest();
216 
217  {
218  TH2* h2 = dynamic_cast<TH2*>(object);
219 
220  if (h2 != NULL) {
221 
222  xmin = min(xmin, h2->GetXaxis()->GetXmin());
223  xmax = max(xmax, h2->GetXaxis()->GetXmax());
224  ymin = min(ymin, h2->GetYaxis()->GetXmin());
225  ymax = max(ymax, h2->GetYaxis()->GetXmax());
226 
227  if (X != JRange_t()) { h2->GetXaxis()->SetRangeUser(X.getLowerLimit(), X.getUpperLimit()); }
228  if (Y != JRange_t()) { h2->GetYaxis()->SetRangeUser(Y.getLowerLimit(), Y.getUpperLimit()); }
229  }
230  }
231 
232  {
233  TGraph2D* g2 = dynamic_cast<TGraph2D*>(object);
234 
235  if (g2 != NULL) {
236  for (Int_t i = 0; i != g2->GetN(); ++i) {
237  xmin = min(xmin, g2->GetX()[i]);
238  xmax = max(xmax, g2->GetX()[i]);
239  ymin = min(ymin, g2->GetY()[i]);
240  ymax = max(ymax, g2->GetY()[i]);
241  }
242  }
243  }
244 
245  if (X != JRange_t()) {
246  xmin = X.getLowerLimit();
247  xmax = X.getUpperLimit();
248  }
249 
250  if (Y != JRange_t()) {
251  ymin = Y.getLowerLimit();
252  ymax = Y.getUpperLimit();
253  }
254 
255  fcn->SetRange(xmin, ymin, xmax, ymax);
256 
257  if (option.find("R") == string::npos) {
258  option += "R";
259  }
260 
261 
262  // execute fit
263 
264  JFit fit(*object, fcn, option);
265 
267 
268 
269  if (fit.result != -1) {
270 
271  // output fit results
272 
273  NOTICE("Fit values " << object->GetName() << endl);
274  NOTICE("Fit formula " << formula << endl);
275 
276  for (int j = 0; j != fcn->GetNpar(); ++j) {
277  NOTICE(left << setw(12) << fcn->GetParName (j) << ' ' <<
278  SCIENTIFIC(12,5) << fcn->GetParameter(j) << " +/- " <<
279  SCIENTIFIC(12,5) << fcn->GetParError (j) << endl);
280  }
281 
282  } else {
283 
284  WARNING("Object: not compatible with ROOT Fit." << endl);
285  }
286 
287  out.cd();
288 
289  object->Write();
290  fcn ->Write();
291 
292  if (writeFits) {
293 
294  TObject* p = object->Clone(MAKE_CSTRING(object->GetName() << ".f2"));
295 
296  {
297  TH2* h2 = dynamic_cast<TH2*>(p);
298 
299  if (h2 != NULL) {
300  for (Int_t ix = 1; ix <= h2->GetXaxis()->GetNbins(); ++ix) {
301  for (Int_t iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
302 
303  const Double_t x = h2->GetXaxis()->GetBinCenter(ix);
304  const Double_t y = h2->GetYaxis()->GetBinCenter(iy);
305 
306  h2->SetBinContent(ix, iy, fcn->Eval(x,y));
307  h2->SetBinError (ix, iy, 0.0);
308  }
309  }
310  }
311  }
312 
313  {
314  TGraph2D* g2 = dynamic_cast<TGraph2D*>(p);
315 
316  if (g2 != NULL) {
317  for (Int_t i = 0; i != g2->GetN(); ++i) {
318 
319  const Double_t x = g2->GetX()[i];
320  const Double_t y = g2->GetY()[i];
321 
322  g2->GetZ()[i] = fcn->Eval(x,y);
323  }
324  }
325  }
326 
327  {
328  TGraph2DErrors* g2 = dynamic_cast<TGraph2DErrors*>(p);
329 
330  if (g2 != NULL) {
331  for (Int_t i = 0; i != g2->GetN(); ++i) {
332  g2->SetPointError(i, 0.0, 0.0, 0.0);
333  }
334  }
335  }
336  }
337  }
338  }
339 
340  dir->Close();
341  }
342 
343  out.Write();
344  out.Close();
345 }
const double xmax
Definition: JQuadrature.cc:24
Utility class to parse command line options.
Definition: JParser.hh:1514
#define WARNING(A)
Definition: JMessage.hh:65
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
Definition: JScale.hh:47
int getParameter(const std::string &text)
Get parameter number from text string.
Definition: JRoot.hh:19
#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 class for a type holder.
Definition: JType.hh:19
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
string outputFile
Acoustic single fit.
Type list.
Definition: JTypeList.hh:22
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 ERROR(A)
Definition: JMessage.hh:66
JObject_t & for_each(JObject_t &object, JType< JTypeList< JHead_t, JTail_t > > typelist)
For each data type method.
Definition: JTypeList.hh:415
#define FATAL(A)
Definition: JMessage.hh:67
const double xmin
Definition: JQuadrature.cc:23
Wrapper class around string.
Definition: JToken.hh:23
Exception for parsing value.
Definition: JException.hh:196
bool isTObject(const TKey *key)
Check if given key corresponds to a TObject.
no fit printf nominal n $STRING awk v X
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
int j
Definition: JPolint.hh:792
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:486
int debug
debug level
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62