102{
105
106 typedef JToken<
';'> JToken_t;
108
111 string formula;
119 string option;
120 bool writeFits;
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\"");
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 <<
"\")");
141
142 zap(argc, argv);
143 }
144 catch(const exception &error) {
145 FATAL(error.what() << endl);
146 }
147
148
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"; }
152
153 if (
debug == 0 && option.find(
'Q') == string::npos) { option +=
"Q"; }
154
155
157
158
159 TF3* fcn = new TF3("user", formula.c_str());
160
161 fcn->SetNpx(300);
162 fcn->SetNpy(300);
163 fcn->SetNpz(300);
164
165 if (fcn->IsZombie()) {
166 FATAL(
"Function: " << formula <<
" is zombie." << endl);
167 }
168
169 for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
170
171 DEBUG(
"Input: " << *input << endl);
172
174
175 if (dir == NULL) {
176 ERROR(
"File: " << input->getFullFilename() <<
" not opened." << endl);
177 continue;
178 }
179
180 const TRegexp regexp(input->getObjectName());
181
182 TIter iter(dir->GetListOfKeys());
183
184 for (TKey* key; (
key = (TKey*) iter.Next()) != NULL; ) {
185
186 const TString tag(
key->GetName());
187
188 DEBUG(
"Key: " << tag <<
" match = " << tag.Contains(regexp) << endl);
189
190
191
192 if (tag.Contains(regexp) &&
isTObject(key)) {
193
195
196
197
198
199 try {
200
201 for (vector<JToken_t>::const_iterator i = startValues.begin(); i != startValues.end(); ++i) {
203 }
204
205 for (Int_t i = 0; i != fcn->GetNpar(); ++i) {
206 fcn->SetParError (i, 0.0);
207 }
208
209 for (vector<JToken_t>::const_iterator i = startErrors.begin(); i != startErrors.end(); ++i) {
211 }
212
213 for (vector<JToken_t>::const_iterator i = fixedValues.begin(); i != fixedValues.end(); ++i) {
215 }
216
217 for (vector<JToken_t>::const_iterator i = limitValues.begin(); i != limitValues.end(); ++i) {
219 }
220
221 }
223 FATAL(error << endl);
224 }
225
226 DEBUG(
"Start values " << object->GetName() << endl);
227
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);
231 }
232
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();
239
240 {
241 TH3* h3 = dynamic_cast<TH3*>(object);
242
243 if (h3 != NULL) {
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());
250 }
251 }
252
256 }
257
261 }
262
266 }
267
268 fcn->SetRange(xmin, ymin, zmin, xmax, ymax, zmax);
269
270
271
272
273 const chrono::steady_clock::time_point t0 = chrono::steady_clock::now();
274
275 JFit fit(*
object, fcn, option);
276
278
279 const chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
280
281 if (fit.result != -1) {
282
283
284
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);
290
291 for (
int j = 0;
j != fcn->GetNpar(); ++
j) {
292 NOTICE(left << setw(12) << fcn->GetParName (
j) <<
' ' <<
293 SCIENTIFIC(12,5) << fcn->GetParameter(
j) <<
" +/- " <<
295 }
296
297 } else {
298
299 WARNING(
"Object: not compatible with ROOT Fit." << endl);
300 }
301
302 out.cd();
303
304 object->Write();
305 fcn ->Write();
306
307 if (writeFits) {
308
310
311 {
312 TH2* h2 = dynamic_cast<TH2*>(p);
313
314 if (h2 != NULL) {
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) {
318
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);
322
323 h2->SetBinContent(ix, iy, fcn->Eval(x,y,z));
324 h2->SetBinError (ix, iy, 0.0);
325 }
326 }
327 }
328 }
329 }
330 }
331 }
332 }
333
334 dir->Close();
335 }
336
337 out.Write();
338 out.Close();
339}
#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.
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.
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.