Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JFit.cc File Reference

General purpose fit program using ROOT. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include "TROOT.h"
#include "TFile.h"
#include "TKey.h"
#include "TH1.h"
#include "TGraph.h"
#include "TProfile.h"
#include "TF1.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 using ROOT.

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(x/[1])+[2]"
     -@ "p0 = GetMaximum; p1 = 2*GetRMS"
     -= "p2 = 0"

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

Author
mdejong

Definition in file JFit.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 96 of file JFit.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  JRange_t X;
110  JRange_t Y;
111  char project;
112  string option;
113  int debug;
114 
115  try {
116 
117  JParser<> zap("General purpose fit program using ROOT.");
118 
119  zap['f'] = make_field(inputFile, "<input file>:<object name>");
120  zap['o'] = make_field(outputFile, "ROOT file with fit results") = "fit.root";
121  zap['F'] = make_field(formula, "fit formula, e.g: \"[0]+[1]*x\"");
122  zap['@'] = make_field(startValues, "start values, e.g: \"p0 = GetMaximum;\"");
123  zap['='] = make_field(fixedValues, "fixed values, e.g: \"p0 = GetMaximum;\"");
124  zap['x'] = make_field(X, "abscissa range") = JRange_t();
125  zap['y'] = make_field(Y, "ordinate range") = JRange_t();
126  zap['P'] = make_field(project, "projection") = '\0', 'x', 'X', 'y', 'Y';
127  zap['O'] = make_field(option, "Fit option") = "";
128  zap['d'] = make_field(debug) = 1;
129 
130  zap['='] = JPARSER::initialised();
131 
132  zap(argc, argv);
133  }
134  catch(const exception &error) {
135  FATAL(error.what() << endl);
136  }
137 
138 
139  if (option.find('O') == string::npos) { option += "O"; }
140  //if (option.find('N') == string::npos) { option += "N"; }
141  if (debug == 0 && option.find('Q') == string::npos) { option += "Q"; }
142 
143  bool px = (project == 'x' || project == 'X'); // projection on x-axis
144  bool py = (project == 'y' || project == 'Y'); // projection on y-axis
145 
146  if (py) {
147  swap(Y, X); // Y becomes x-axis range and X becomes y-axis range
148  }
149 
150 
151  TFile out(outputFile.c_str(), "recreate");
152 
153 
154  TF1* fcn = new TF1("user", formula.c_str());
155 
156  fcn->SetNpx(1000);
157 
158  if (fcn->IsZombie()) {
159  FATAL("Function: " << formula << " is zombie." << endl);
160  }
161 
162  for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
163 
164  DEBUG("Input: " << *input << endl);
165 
166  TDirectory* dir = getDirectory(*input);
167 
168  if (dir == NULL) {
169  ERROR("File: " << input->getFullFilename() << " not opened." << endl);
170  continue;
171  }
172 
173  const TRegexp regexp(input->getObjectName());
174 
175  TIter iter(dir->GetListOfKeys());
176 
177  for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
178 
179  const TString tag(key->GetName());
180 
181  DEBUG("Key: " << tag << " match = " << tag.Contains(regexp) << endl);
182 
183  // option match
184 
185  if (tag.Contains(regexp)) {
186 
187  TObject* object = key->ReadObj();
188 
189  try {
190 
191  TProfile& h1 = dynamic_cast<TProfile&>(*object);
192 
193  object = h1.ProjectionX();
194  }
195  catch(exception&) {}
196 
197  try {
198 
199  TH2& h2 = dynamic_cast<TH2&>(*object);
200 
201  if (px) {
202 
203  object = h2.ProjectionX("_px",
204  h2.GetYaxis()->FindBin(Y.getLowerLimit()),
205  h2.GetYaxis()->FindBin(Y.getUpperLimit()));
206 
207  } else if (py) {
208 
209  object = h2.ProjectionY("_py",
210  h2.GetXaxis()->FindBin(Y.getLowerLimit()),
211  h2.GetXaxis()->FindBin(Y.getUpperLimit()));
212 
213  } else {
214 
215  ERROR("For 2D histograms, use option option -P for projections." << endl);
216 
217  continue;
218  }
219  }
220  catch(exception&) {}
221 
222 
223  // set fit parameters
224 
225  try {
226 
227  for (vector<JToken_t>::const_iterator j = startValues.begin(); j != startValues.end(); ++j) {
228  fcn->SetParameter(getParameter(*j), getValue(*j,object));
229  }
230 
231  for (vector<JToken_t>::const_iterator j = fixedValues.begin(); j != fixedValues.end(); ++j) {
232  fcn->FixParameter(getParameter(*j), getValue(*j,object));
233  }
234  }
235  catch(JLANG::JParseError& error) {
236  FATAL(error << endl);
237  }
238 
239  DEBUG("Start values " << object->GetName() << endl);
240 
241  for (int j = 0; j != fcn->GetNpar(); ++j) {
242  DEBUG(left << setw(12) << fcn->GetParName (j) << ' ' <<
243  SCIENTIFIC(12,5) << fcn->GetParameter(j) << endl);
244  }
245 
246  Double_t xmin = numeric_limits<Double_t>::max();
247  Double_t xmax = numeric_limits<Double_t>::lowest();
248 
249  {
250  TH1* h1 = dynamic_cast<TH1*>(object);
251 
252  if (h1 != NULL) {
253  xmin = min(xmin, h1->GetXaxis()->GetXmin());
254  xmax = max(xmax, h1->GetXaxis()->GetXmax());
255  }
256  }
257 
258  {
259  TGraph* g1 = dynamic_cast<TGraph*>(object);
260 
261  if (g1 != NULL) {
262  for (Int_t i = 0; i != g1->GetN(); ++i) {
263  xmin = min(xmin, g1->GetX()[i]);
264  xmax = max(xmax, g1->GetX()[i]);
265  }
266  }
267  }
268 
269  if (X != JRange_t()) {
270  xmin = X.getLowerLimit();
271  xmax = X.getUpperLimit();
272  }
273 
274  fcn->SetRange(xmin, xmax);
275 
276  if (option.find("R") == string::npos) {
277  option += "R";
278  }
279 
280 
281  // execute fit
282 
283  JFit fit(*object, fcn, option);
284 
286 
287 
288  if (fit.result != -1) {
289 
290  // output fit results
291 
292  NOTICE("Fit values " << object->GetName() << endl);
293  NOTICE("Fit formula " << formula << endl);
294 
295  for (int j = 0; j != fcn->GetNpar(); ++j) {
296  NOTICE(left << setw(12) << fcn->GetParName (j) << ' ' <<
297  SCIENTIFIC(12,5) << fcn->GetParameter(j) << " +/- " <<
298  SCIENTIFIC(12,5) << fcn->GetParError (j) << endl);
299  }
300 
301  } else {
302 
303  WARNING("Object: not compatible with ROOT Fit." << endl);
304  }
305 
306  out.cd();
307 
308  object->Write();
309  }
310  }
311 
312  dir->Close();
313  }
314 
315  out.Write();
316  out.Close();
317 }
Utility class to parse command line options.
Definition: JParser.hh:1500
#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
then for HISTOGRAM in h0 h1
Definition: JMatrixNZ.sh:69
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:66
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
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
#define NOTICE(A)
Definition: JMessage.hh:64
#define ERROR(A)
Definition: JMessage.hh:66
int debug
debug level
Definition: JSirene.cc:63
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
Wrapper class around string.
Definition: JToken.hh:23
Exception for parsing value.
Definition: JException.hh:180
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
int j
Definition: JPolint.hh:666
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:483
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
Double_t g1(const Double_t x)
Function.
Definition: JQuantiles.cc:25