101{
104
107
110 string formula;
118 string option;
120
121 try {
122
123 JParser<> zap(
"General purpose fit program for 1D ROOT objects.");
124
125 zap[
'f'] =
make_field(inputFile,
"<input file>:<object name>");
127 zap[
'F'] =
make_field(formula,
"fit formula, e.g: \"[0]+[1]*x\"");
134 zap[
'P'] =
make_field(project,
"projection") =
'\0',
'x',
'X',
'y',
'Y';
138
140 }
141 catch(const exception &error) {
143 }
144
145
146 if (option.find('O') == string::npos) { option += "O"; }
147 if (option.find("R") == string::npos) { option += "R"; }
148 if (option.find("S") == string::npos) { option += "S"; }
149
150 if (
debug == 0 && option.find(
'Q') == string::npos) { option +=
"Q"; }
151
154
156 swap(Y, X);
157 }
158
159
161
162
163 TF1* fcn = new TF1("user", formula.c_str());
164
165 fcn->SetNpx(1000);
166
167 if (fcn->IsZombie()) {
168 FATAL(
"Function: " << formula <<
" is zombie." <<
endl);
169 }
170
172
174
176
178 ERROR(
"File: " << input->getFullFilename() <<
" not opened." <<
endl);
179 continue;
180 }
181
183
185
187
188 const TString tag(
key->GetName());
189
191
192
193
195
197
198 try {
199
201
202 object = h1.ProjectionX();
203 }
204 catch(exception&) {}
205
206 try {
207
208 TH2& h2 =
dynamic_cast<TH2&
>(*object);
209
210 if (px) {
211
212 object = h2.ProjectionX("_px",
215
217
218 object = h2.ProjectionY("_py",
221
222 } else {
223
224 ERROR(
"For 2D histograms, use option option -P for projections." <<
endl);
225
226 continue;
227 }
228 }
229 catch(exception&) {}
230
231
232
233
234 try {
235
238 }
239
240 for (
Int_t i = 0; i != fcn->GetNpar(); ++i) {
241 fcn->SetParError (i, 0.0);
242 }
243
246 }
247
250 }
251
254 }
255 }
258 }
259
260 DEBUG(
"Start values " << object->GetName() <<
endl);
261
262 for (
int j = 0;
j != fcn->GetNpar(); ++
j) {
263 DEBUG(left <<
setw(12) << fcn->GetParName (
j) <<
' ' <<
265 }
266
269
270 {
271 TH1* h1 =
dynamic_cast<TH1*
>(object);
272
274 xmin = min(xmin, h1->GetXaxis()->GetXmin());
275 xmax = max(xmax, h1->GetXaxis()->GetXmax());
276 }
277 }
278
279 {
280 TGraph*
g1 =
dynamic_cast<TGraph*
>(object);
281
283 for (
Int_t i = 0; i !=
g1->GetN(); ++i) {
284 xmin = min(xmin,
g1->GetX()[i]);
285 xmax = max(xmax,
g1->GetX()[i]);
286 }
287 }
288 }
289
293 }
294
295 fcn->SetRange(xmin, xmax);
296
297
298
299
300 const chrono::steady_clock::time_point t0 = chrono::steady_clock::now();
301
302 JFit fit(*
object, fcn, option);
303
305
306 const chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
307
308 if (fit.result != -1) {
309
310
311
312 NOTICE(
"Fit values " << object->GetName() <<
endl);
314 NOTICE(
"chi2/NDF " <<
FIXED(7,3) << fit.result->Chi2() <<
'/' << fit.result->Ndf() <<
' ' << (fit.result->IsValid() ?
"" :
"failed") <<
endl);
315 NOTICE(
"Number of calls " << fit.result->NCalls() <<
endl);
316 NOTICE(
"Elapsed time [us] " <<
setw(8) << chrono::duration_cast<chrono::microseconds>(t1 - t0).count() <<
endl);
317
318 for (
int j = 0;
j != fcn->GetNpar(); ++
j) {
319 NOTICE(left <<
setw(12) << fcn->GetParName (
j) <<
' ' <<
320 SCIENTIFIC(12,5) << fcn->GetParameter(
j) <<
" +/- " <<
322 }
323
324 } else {
325
326 WARNING(
"Object: not compatible with ROOT Fit." <<
endl);
327 }
328
329 out.cd();
330
331 object->Write();
332 }
333 }
334
335 dir->Close();
336 }
337
338 out.Write();
339 out.Close();
340}
#define DEBUG(A)
Message macros.
static JMinimizer minimizer
ROOT minimizer.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Double_t g1(const Double_t x)
Function.
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.