14 #include "TFitResult.h"
37 const char*
const _F3 =
".f3";
52 const std::string& option) :
65 void operator()(
const JType<T>& type)
68 result =
dynamic_cast<T&
>(object).
Fit(fcn, option.c_str(),
"same");
70 catch(
const std::exception&) {}
101 int main(
int argc,
char **argv)
125 JParser<> zap(
"General purpose fit program for 2D ROOT objects.");
127 zap[
'f'] =
make_field(inputFile,
"<input file>:<object name>");
129 zap[
'F'] =
make_field(formula,
"fit formula, e.g: \"[0]+[1]*x\"");
130 zap[
'@'] =
make_field(startValues,
"start values, e.g: \"p0 = GetMaximum;\"");
137 zap[
'O'] =
make_field(option,
"Fit option") =
"";
138 zap[
'w'] =
make_field(writeFits,
"write fit function(s) to ROOT file " <<
"(\"<name>" << _F3 <<
"\")");
144 catch(
const exception &error) {
145 FATAL(error.what() << endl);
149 if (option.find(
'O') == string::npos) { option +=
"O"; }
150 if (option.find(
"R") == string::npos) { option +=
"R"; }
151 if (option.find(
"S") == string::npos) { option +=
"S"; }
153 if (
debug == 0 && option.find(
'Q') == string::npos) { option +=
"Q"; }
159 TF3* fcn =
new TF3(
"user", formula.c_str());
165 if (fcn->IsZombie()) {
166 FATAL(
"Function: " << formula <<
" is zombie." << endl);
171 DEBUG(
"Input: " << *input << endl);
176 ERROR(
"File: " << input->getFullFilename() <<
" not opened." << endl);
180 const TRegexp regexp(input->getObjectName());
182 TIter iter(dir->GetListOfKeys());
184 for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
186 const TString tag(key->GetName());
188 DEBUG(
"Key: " << tag <<
" match = " << tag.Contains(regexp) << endl);
192 if (tag.Contains(regexp) &&
isTObject(key)) {
194 TObject*
object = key->ReadObj();
205 for (Int_t i = 0; i != fcn->GetNpar(); ++i) {
206 fcn->SetParError (i, 0.0);
223 FATAL(error << endl);
226 DEBUG(
"Start values " << object->GetName() << endl);
228 for (
int i = 0; i != fcn->GetNpar(); ++i) {
229 DEBUG(left << setw(12) << fcn->GetParName (i) <<
' ' <<
230 SCIENTIFIC(12,5) << fcn->GetParameter(i) << endl);
233 Double_t
xmin = numeric_limits<Double_t>::max();
234 Double_t
xmax = numeric_limits<Double_t>::lowest();
235 Double_t ymin = numeric_limits<Double_t>::max();
236 Double_t ymax = numeric_limits<Double_t>::lowest();
237 Double_t zmin = numeric_limits<Double_t>::max();
238 Double_t zmax = numeric_limits<Double_t>::lowest();
241 TH3* h3 =
dynamic_cast<TH3*
>(object);
244 xmin = min(
xmin, h3->GetXaxis()->GetXmin());
245 xmax = max(
xmax, h3->GetXaxis()->GetXmax());
246 ymin = min(ymin, h3->GetYaxis()->GetXmin());
247 ymax = max(ymax, h3->GetYaxis()->GetXmax());
248 zmin = min(zmin, h3->GetZaxis()->GetXmin());
249 zmax = max(zmax, h3->GetZaxis()->GetXmax());
268 fcn->SetRange(
xmin, ymin, zmin,
xmax, ymax, zmax);
273 const chrono::steady_clock::time_point t0 = chrono::steady_clock::now();
275 JFit fit(*
object, fcn, option);
279 const chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
281 if (fit.result != -1) {
285 NOTICE(
"Fit values " << object->GetName() << endl);
286 NOTICE(
"Fit formula " << formula << endl);
287 NOTICE(
"chi2/NDF " <<
FIXED(7,3) << fit.result->Chi2() <<
'/' << fit.result->Ndf() <<
' ' << (fit.result->IsValid() ?
"" :
"failed") << endl);
288 NOTICE(
"Number of calls " << fit.result->NCalls() << endl);
289 NOTICE(
"Elapsed time [us] " << setw(8) << chrono::duration_cast<chrono::microseconds>(t1 - t0).count() << endl);
291 for (
int j = 0;
j != fcn->GetNpar(); ++
j) {
292 NOTICE(left << setw(12) << fcn->GetParName (
j) <<
' ' <<
293 SCIENTIFIC(12,5) << fcn->GetParameter(
j) <<
" +/- " <<
299 WARNING(
"Object: not compatible with ROOT Fit." << endl);
312 TH2* h2 =
dynamic_cast<TH2*
>(p);
315 for (Int_t ix = 1; ix <= h2->GetXaxis()->GetNbins(); ++ix) {
316 for (Int_t iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
317 for (Int_t iz = 1; iz <= h2->GetZaxis()->GetNbins(); ++iz) {
319 const Double_t
x = h2->GetXaxis()->GetBinCenter(ix);
320 const Double_t
y = h2->GetYaxis()->GetBinCenter(iy);
321 const Double_t z = h2->GetZaxis()->GetBinCenter(iz);
323 h2->SetBinContent(ix, iy, fcn->Eval(
x,
y,z));
324 h2->SetBinError (ix, iy, 0.0);
int main(int argc, char **argv)
General purpose messaging.
#define DEBUG(A)
Message macros.
static JMinimizer minimizer
ROOT minimizer.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
I/O formatting auxiliaries.
#define MAKE_CSTRING(A)
Make C-string.
Auxiliary class to define a range between two values.
Exception for parsing value.
Wrapper class around string.
Utility class to parse command line options.
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.
JObject_t & 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).
JRootfit_t< JF1_t > Fit(const TH1 &h1, const JF1_t &f1, const index_list &ls=index_list(), const range_type &X=range_type())
Global fit fuction.
Auxiliary data structure for floating point format specification.
Type definition of range.
JFit()
Default constructor.
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.