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

General purpose fit program for 1D ROOT objects. 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 for 1D 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(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 for 1D ROOT objects.");
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;\"") = JPARSER::initialised();
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(argc, argv);
131  }
132  catch(const exception &error) {
133  FATAL(error.what() << endl);
134  }
135 
136 
137  if (option.find('O') == string::npos) { option += "O"; }
138  //if (option.find('N') == string::npos) { option += "N"; }
139  if (debug == 0 && option.find('Q') == string::npos) { option += "Q"; }
140 
141  bool px = (project == 'x' || project == 'X'); // projection on x-axis
142  bool py = (project == 'y' || project == 'Y'); // projection on y-axis
143 
144  if (py) {
145  swap(Y, X); // Y becomes x-axis range and X becomes y-axis range
146  }
147 
148 
149  TFile out(outputFile.c_str(), "recreate");
150 
151 
152  TF1* fcn = new TF1("user", formula.c_str());
153 
154  fcn->SetNpx(1000);
155 
156  if (fcn->IsZombie()) {
157  FATAL("Function: " << formula << " is zombie." << endl);
158  }
159 
160  for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
161 
162  DEBUG("Input: " << *input << endl);
163 
164  TDirectory* dir = getDirectory(*input);
165 
166  if (dir == NULL) {
167  ERROR("File: " << input->getFullFilename() << " not opened." << endl);
168  continue;
169  }
170 
171  const TRegexp regexp(input->getObjectName());
172 
173  TIter iter(dir->GetListOfKeys());
174 
175  for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
176 
177  const TString tag(key->GetName());
178 
179  DEBUG("Key: " << tag << " match = " << tag.Contains(regexp) << endl);
180 
181  // option match
182 
183  if (tag.Contains(regexp) && isTObject(key)) {
184 
185  TObject* object = key->ReadObj();
186 
187  try {
188 
189  TProfile& h1 = dynamic_cast<TProfile&>(*object);
190 
191  object = h1.ProjectionX();
192  }
193  catch(exception&) {}
194 
195  try {
196 
197  TH2& h2 = dynamic_cast<TH2&>(*object);
198 
199  if (px) {
200 
201  object = h2.ProjectionX("_px",
202  h2.GetYaxis()->FindBin(Y.getLowerLimit()),
203  h2.GetYaxis()->FindBin(Y.getUpperLimit()));
204 
205  } else if (py) {
206 
207  object = h2.ProjectionY("_py",
208  h2.GetXaxis()->FindBin(Y.getLowerLimit()),
209  h2.GetXaxis()->FindBin(Y.getUpperLimit()));
210 
211  } else {
212 
213  ERROR("For 2D histograms, use option option -P for projections." << endl);
214 
215  continue;
216  }
217  }
218  catch(exception&) {}
219 
220 
221  // set fit parameters
222 
223  try {
224 
225  for (vector<JToken_t>::const_iterator j = startValues.begin(); j != startValues.end(); ++j) {
226  fcn->SetParameter(getParameter(*j), getValue(*j,object));
227  }
228 
229  for (vector<JToken_t>::const_iterator j = fixedValues.begin(); j != fixedValues.end(); ++j) {
230  fcn->FixParameter(getParameter(*j), getValue(*j,object));
231  }
232  }
233  catch(JLANG::JParseError& error) {
234  FATAL(error << endl);
235  }
236 
237  DEBUG("Start values " << object->GetName() << endl);
238 
239  for (int j = 0; j != fcn->GetNpar(); ++j) {
240  DEBUG(left << setw(12) << fcn->GetParName (j) << ' ' <<
241  SCIENTIFIC(12,5) << fcn->GetParameter(j) << endl);
242  }
243 
244  Double_t xmin = numeric_limits<Double_t>::max();
245  Double_t xmax = numeric_limits<Double_t>::lowest();
246 
247  {
248  TH1* h1 = dynamic_cast<TH1*>(object);
249 
250  if (h1 != NULL) {
251  xmin = min(xmin, h1->GetXaxis()->GetXmin());
252  xmax = max(xmax, h1->GetXaxis()->GetXmax());
253  }
254  }
255 
256  {
257  TGraph* g1 = dynamic_cast<TGraph*>(object);
258 
259  if (g1 != NULL) {
260  for (Int_t i = 0; i != g1->GetN(); ++i) {
261  xmin = min(xmin, g1->GetX()[i]);
262  xmax = max(xmax, g1->GetX()[i]);
263  }
264  }
265  }
266 
267  if (X != JRange_t()) {
268  xmin = X.getLowerLimit();
269  xmax = X.getUpperLimit();
270  }
271 
272  fcn->SetRange(xmin, xmax);
273 
274  if (option.find("R") == string::npos) {
275  option += "R";
276  }
277 
278 
279  // execute fit
280 
281  JFit fit(*object, fcn, option);
282 
284 
285 
286  if (fit.result != -1) {
287 
288  // output fit results
289 
290  NOTICE("Fit values " << object->GetName() << endl);
291  NOTICE("Fit formula " << formula << endl);
292 
293  for (int j = 0; j != fcn->GetNpar(); ++j) {
294  NOTICE(left << setw(12) << fcn->GetParName (j) << ' ' <<
295  SCIENTIFIC(12,5) << fcn->GetParameter(j) << " +/- " <<
296  SCIENTIFIC(12,5) << fcn->GetParError (j) << endl);
297  }
298 
299  } else {
300 
301  WARNING("Object: not compatible with ROOT Fit." << endl);
302  }
303 
304  out.cd();
305 
306  object->Write();
307  }
308  }
309 
310  dir->Close();
311  }
312 
313  out.Write();
314  out.Close();
315 }
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:71
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
Type definition of range.
Definition: JHead.hh:39
#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
then break fi done getCenter read X Y Z let X
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
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
Exception for parsing value.
Definition: JException.hh:180
bool isTObject(const TKey *key)
Check if given key corresponds to a TObject.
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
int j
Definition: JPolint.hh:682
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:484
Double_t g1(const Double_t x)
Function.
Definition: JQuantiles.cc:25