103{
106
109
112 string formula;
119 string option;
122
123 try {
124
125 JParser<> zap(
"General purpose fit program for 2D ROOT objects.");
126
127 zap[
'f'] =
make_field(inputFile,
"<input file>:<object name>");
129 zap[
'F'] =
make_field(formula,
"fit formula, e.g: \"[0]+[1]*x\"");
140
142 }
143 catch(const exception &error) {
145 }
146
147
148 if (option.find('O') == string::npos) { option += "O"; }
149 if (option.find("R") == string::npos) { option += "R"; }
150 if (option.find("S") == string::npos) { option += "S"; }
151
152 if (
debug == 0 && option.find(
'Q') == string::npos) { option +=
"Q"; }
153
154
156
157
158 TF2* fcn = new TF2("user", formula.c_str());
159
160 fcn->SetNpx(1000);
161 fcn->SetNpy(1000);
162
163 if (fcn->IsZombie()) {
164 FATAL(
"Function: " << formula <<
" is zombie." <<
endl);
165 }
166
168
170
172
174 ERROR(
"File: " << input->getFullFilename() <<
" not opened." <<
endl);
175 continue;
176 }
177
179
181
183
184 const TString tag(
key->GetName());
185
187
188
189
191
193
194
195
196
197 try {
198
201 }
202
203 for (
Int_t i = 0; i != fcn->GetNpar(); ++i) {
204 fcn->SetParError(i, 0.0);
205 }
206
209 }
210
213 }
214
217 }
218 }
221 }
222
223 DEBUG(
"Start values " << object->GetName() <<
endl);
224
225 for (int i = 0; i != fcn->GetNpar(); ++i) {
226 DEBUG(left <<
setw(12) << fcn->GetParName (i) <<
' ' <<
228 }
229
234
235 {
236 TH2* h2 =
dynamic_cast<TH2*
>(object);
237
239
240 xmin = min(xmin, h2->GetXaxis()->GetXmin());
241 xmax = max(xmax, h2->GetXaxis()->GetXmax());
242 ymin = min(
ymin, h2->GetYaxis()->GetXmin());
243 ymax = max(
ymax, h2->GetYaxis()->GetXmax());
244
247 }
248 }
249
250 {
251 TGraph2D* g2 = dynamic_cast<TGraph2D*>(object);
252
254 for (
Int_t i = 0; i != g2->GetN(); ++i) {
255 xmin = min(xmin, g2->GetX()[i]);
256 xmax = max(xmax, g2->GetX()[i]);
259 }
260 }
261 }
262
266 }
267
271 }
272
273 fcn->SetRange(xmin,
ymin, xmax,
ymax);
274
275
276
277
278 const chrono::steady_clock::time_point t0 = chrono::steady_clock::now();
279
280 JFit fit(*
object, fcn, option);
281
283
284 const chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
285
286 if (fit.result != -1) {
287
288
289
290 NOTICE(
"Fit values " << object->GetName() <<
endl);
292 NOTICE(
"chi2/NDF " <<
FIXED(7,3) << fit.result->Chi2() <<
'/' << fit.result->Ndf() <<
' ' << (fit.result->IsValid() ?
"" :
"failed") <<
endl);
293 NOTICE(
"Number of calls " << fit.result->NCalls() <<
endl);
294 NOTICE(
"Elapsed time [us] " <<
setw(8) << chrono::duration_cast<chrono::microseconds>(t1 - t0).count() <<
endl);
295
296 for (
int j = 0;
j != fcn->GetNpar(); ++
j) {
297 NOTICE(left <<
setw(12) << fcn->GetParName (
j) <<
' ' <<
298 SCIENTIFIC(12,5) << fcn->GetParameter(
j) <<
" +/- " <<
300 }
301
302 } else {
303
304 WARNING(
"Object: not compatible with ROOT Fit." <<
endl);
305 }
306
307 out.cd();
308
309 object->Write();
310 fcn ->Write();
311
313
315
316 {
317 TH2* h2 =
dynamic_cast<TH2*
>(p);
318
320 for (
Int_t ix = 1;
ix <= h2->GetXaxis()->GetNbins(); ++
ix) {
321 for (
Int_t iy = 1;
iy <= h2->GetYaxis()->GetNbins(); ++
iy) {
322
323 const Double_t x = h2->GetXaxis()->GetBinCenter(
ix);
324 const Double_t y = h2->GetYaxis()->GetBinCenter(
iy);
325
326 h2->SetBinContent(
ix,
iy, fcn->Eval(x,y));
327 h2->SetBinError (
ix,
iy, 0.0);
328 }
329 }
330 }
331 }
332
333 {
334 TGraph2D* g2 = dynamic_cast<TGraph2D*>(p);
335
337 for (
Int_t i = 0; i != g2->GetN(); ++i) {
338
341
342 g2->GetZ()[i] = fcn->Eval(x,y);
343 }
344 }
345 }
346
347 {
348 TGraph2DErrors* g2 = dynamic_cast<TGraph2DErrors*>(p);
349
351 for (
Int_t i = 0; i != g2->GetN(); ++i) {
352 g2->SetPointError(i, 0.0, 0.0, 0.0);
353 }
354 }
355 }
356 }
357 }
358 }
359
360 dir->Close();
361 }
362
363 out.Write();
364 out.Close();
365}
#define DEBUG(A)
Message macros.
static JMinimizer minimizer
ROOT minimizer.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
#define MAKE_CSTRING(A)
Make C-string.
Exception for parsing value.
Wrapper class around string.
Template definition of a multi-dimensional oscillation probability interpolation table.
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
int getParameter(const std::string &text)
Get parameter number from text string.
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
bool isTObject(const TKey *key)
Check if given key corresponds to a TObject.
void for_each(JObject_t &object, JType< JTypeList< JHead_t, JTail_t > > typelist)
For each data type method.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Type definition of range.
Auxiliary class for a type holder.
Auxiliary data structure to define ROOT minimizer.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Auxiliary data structure for floating point format specification.