Jpp  17.3.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JFit3D.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 #include <vector>
5 #include <algorithm>
6 
7 #include "TROOT.h"
8 #include "TFile.h"
9 #include "TKey.h"
10 #include "TH3.h"
11 #include "TProfile.h"
12 #include "TF3.h"
13 #include "TString.h"
14 #include "TRegexp.h"
15 
16 #include "JLang/JType.hh"
17 #include "JLang/JTypeList.hh"
18 #include "JLang/JToken.hh"
19 #include "JTools/JRange.hh"
20 
21 #include "JGizmo/JRootObjectID.hh"
22 #include "JGizmo/JGizmoToolkit.hh"
23 
24 #include "Jeep/JPrint.hh"
25 #include "Jeep/JParser.hh"
26 #include "Jeep/JMessage.hh"
27 
28 
29 namespace {
30 
31  using namespace JPP;
32 
33  /**
34  * Auxiliary class for ROOT fit.
35  */
36  struct JFit {
37  /**
38  * Constructor.
39  *
40  * \param object object
41  * \param fcn fcn
42  * \param option option
43  */
44  JFit(TObject& object,
45  TF2* fcn,
46  const std::string& option) :
47  object(object),
48  fcn (fcn),
49  option(option)
50  {}
51 
52 
53  /**
54  * Attempt fit for given data type.
55  *
56  * \param type data type
57  */
58  template<class T>
59  void operator()(const JType<T>& type)
60  {
61  try {
62  result = dynamic_cast<T&>(object).Fit(fcn, option.c_str(), "same");
63  }
64  catch(const std::exception&) {}
65  }
66 
67  TObject& object;
68  TF2* fcn;
69  std::string option;
70  TFitResultPtr result;
71  };
72 }
73 
74 
75 /**
76  * \file
77  * General purpose fit program for 3D ROOT objects.\n
78  * The option <tt>-f</tt> corresponds to <tt><file name>:<object name></tt>.
79  *
80  * The expressions for the fit function, start and fixed values should comply
81  * with ROOT class TFormula.
82  *
83  * In the expressions of the start and fixed values, names of member methods
84  * of corresponding class of the fit object may appear,
85  * such as TH1::GetMaximum, TH1::GetRMS, etc., e.g:
86  * <pre>
87  * -F "[0]*exp(-0.5*x*x/([1]*[1])*exp(-0.5*y*y/([2]*[2])*exp(-0.5*z*z/([3]*[3])"
88  * -@ "p0 = GetMaximum; p1 = 2*GetRMS(1); .."
89  * -= "p3 = 1"
90  * </pre>
91  * The result of the formulas for the start and fixed values will be evaluated
92  * for each histogram separately.
93  * \author mdejong
94  */
95 int main(int argc, char **argv)
96 {
97  using namespace std;
98  using namespace JPP;
99 
100  typedef JToken<';'> JToken_t;
101  typedef JRange<double> JRange_t;
102 
103  vector<JRootObjectID> inputFile;
104  string outputFile;
105  string formula;
106  vector<JToken_t> startValues;
107  vector<JToken_t> fixedValues;
108  vector<JToken_t> limitValues;
109  JRange_t X;
110  JRange_t Y;
111  JRange_t Z;
112  string option;
113  int debug;
114 
115  try {
116 
117  JParser<> zap("General purpose fit program for 2D 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['R'] = make_field(limitValues, "limit values, e.g: \"p0 = <lower limit> <upper limit>;\"") = JPARSER::initialised();
125  zap['x'] = make_field(X, "abscissa range") = JRange_t();
126  zap['y'] = make_field(Y, "abscissa range") = JRange_t();
127  zap['z'] = make_field(Z, "abscissa range") = JRange_t();
128  zap['O'] = make_field(option, "Fit option") = "";
129  zap['d'] = make_field(debug) = 1;
130 
131  zap['='] = JPARSER::initialised();
132 
133  zap(argc, argv);
134  }
135  catch(const exception &error) {
136  FATAL(error.what() << endl);
137  }
138 
139 
140  if (option.find('O') == string::npos) { option += "O"; }
141  //if (option.find('N') == string::npos) { option += "N"; }
142  if (debug == 0 && option.find('Q') == string::npos) { option += "Q"; }
143 
144 
145  TFile out(outputFile.c_str(), "recreate");
146 
147 
148  TF3* fcn = new TF3("user", formula.c_str());
149 
150  fcn->SetNpx(10000);
151 
152  if (fcn->IsZombie()) {
153  FATAL("Function: " << formula << " is zombie." << endl);
154  }
155 
156  for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
157 
158  DEBUG("Input: " << *input << endl);
159 
160  TDirectory* dir = getDirectory(*input);
161 
162  if (dir == NULL) {
163  ERROR("File: " << input->getFullFilename() << " not opened." << endl);
164  continue;
165  }
166 
167  const TRegexp regexp(input->getObjectName());
168 
169  TIter iter(dir->GetListOfKeys());
170 
171  for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
172 
173  const TString tag(key->GetName());
174 
175  DEBUG("Key: " << tag << " match = " << tag.Contains(regexp) << endl);
176 
177  // option match
178 
179  if (tag.Contains(regexp) && isTObject(key)) {
180 
181  TObject* object = key->ReadObj();
182 
183 
184  // set fit parameters
185 
186  try {
187 
188  for (vector<JToken_t>::const_iterator i = startValues.begin(); i != startValues.end(); ++i) {
189  fcn->SetParameter(getParameter(*i), getValue(*i,object));
190  }
191 
192  for (vector<JToken_t>::const_iterator i = fixedValues.begin(); i != fixedValues.end(); ++i) {
193  fcn->FixParameter(getParameter(*i), getValue(*i,object));
194  }
195 
196  for (vector<JToken_t>::const_iterator i = limitValues.begin(); i != limitValues.end(); ++i) {
197  fcn->SetParLimits(getParameter(*i), getValue(*i,0), getValue(*i,1));
198  }
199  }
200  catch(JLANG::JParseError& error) {
201  FATAL(error << endl);
202  }
203 
204  DEBUG("Start values " << object->GetName() << endl);
205 
206  for (int i = 0; i != fcn->GetNpar(); ++i) {
207  DEBUG(left << setw(12) << fcn->GetParName (i) << ' ' <<
208  SCIENTIFIC(12,5) << fcn->GetParameter(i) << endl);
209  }
210 
211  Double_t xmin = numeric_limits<Double_t>::max();
212  Double_t xmax = numeric_limits<Double_t>::lowest();
213  Double_t ymin = numeric_limits<Double_t>::max();
214  Double_t ymax = numeric_limits<Double_t>::lowest();
215  Double_t zmin = numeric_limits<Double_t>::max();
216  Double_t zmax = numeric_limits<Double_t>::lowest();
217 
218  {
219  TH3* h3 = dynamic_cast<TH3*>(object);
220 
221  if (h3 != NULL) {
222  xmin = min(xmin, h3->GetXaxis()->GetXmin());
223  xmax = max(xmax, h3->GetXaxis()->GetXmax());
224  ymin = min(ymin, h3->GetYaxis()->GetXmin());
225  ymax = max(ymax, h3->GetYaxis()->GetXmax());
226  zmin = min(zmin, h3->GetZaxis()->GetXmin());
227  zmax = max(zmax, h3->GetZaxis()->GetXmax());
228  }
229  }
230 
231  if (X != JRange_t()) {
232  xmin = X.getLowerLimit();
233  xmax = X.getUpperLimit();
234  }
235 
236  if (Y != JRange_t()) {
237  ymin = Y.getLowerLimit();
238  ymax = Y.getUpperLimit();
239  }
240 
241  if (Z != JRange_t()) {
242  zmin = Z.getLowerLimit();
243  zmax = Z.getUpperLimit();
244  }
245 
246  fcn->SetRange(xmin, ymin, zmin, xmax, ymax, zmax);
247 
248  if (option.find("R") == string::npos) {
249  option += "R";
250  }
251 
252 
253  // execute fit
254 
255  JFit fit(*object, fcn, option);
256 
257  for_each(fit, JType<TH3>());
258 
259 
260  if (fit.result != -1) {
261 
262  // output fit results
263 
264  NOTICE("Fit values " << object->GetName() << endl);
265  NOTICE("Fit formula " << formula << endl);
266 
267  for (int j = 0; j != fcn->GetNpar(); ++j) {
268  NOTICE(left << setw(12) << fcn->GetParName (j) << ' ' <<
269  SCIENTIFIC(12,5) << fcn->GetParameter(j) << " +/- " <<
270  SCIENTIFIC(12,5) << fcn->GetParError (j) << endl);
271  }
272 
273  } else {
274 
275  WARNING("Object: not compatible with ROOT Fit." << endl);
276  }
277 
278  out.cd();
279 
280  object->Write();
281  fcn ->Write();
282  }
283  }
284 
285  dir->Close();
286  }
287 
288  out.Write();
289  out.Close();
290 }
const double xmax
Definition: JQuadrature.cc:24
Utility class to parse command line options.
Definition: JParser.hh:1517
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
Definition: JScale.hh:47
int main(int argc, char *argv[])
Definition: Main.cc:15
int getParameter(const std::string &text)
Get parameter number from text string.
TFitResultPtr Fit(TH1D *h)
Definition: JNanobeacon.hh:14
Definition: JRoot.hh:19
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 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
do set_variable OUTPUT_DIRECTORY $WORKDIR T
#define NOTICE(A)
Definition: JMessage.hh:64
#define ERROR(A)
Definition: JMessage.hh:66
then awk string
General purpose messaging.
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
Auxiliary class to define a range between two values.
Utility class to parse command line options.
Wrapper class around string.
Definition: JToken.hh:23
Exception for parsing value.
Definition: JException.hh:180
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.
do set_variable MODULE getModule a $WORKDIR detector_a datx L $STRING JEditDetector a $WORKDIR detector_a datx M $MODULE setz o $WORKDIR detector_a datx JEditDetector a $WORKDIR detector_b datx M $MODULE setz o $WORKDIR detector_b datx done echo Output stored at $WORKDIR detector_a datx and $WORKDIR tripod_a txt JDrawDetector2D a $WORKDIR detector_a datx a $WORKDIR detector_b datx L BL o detector $FORMAT $BATCH JDrawDetector2D T $WORKDIR tripod_a txt T $WORKDIR tripod_b txt L BL o tripod $FORMAT $BATCH JCompareDetector a $WORKDIR detector_a datx b $WORKDIR detector_b datx o $WORKDIR abc root &dev null for KEY in X Y Z
int j
Definition: JPolint.hh:703
then echo WARNING
Definition: JTuneHV.sh:91
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:484
int debug
debug level
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
JFit()
Default constructor.