00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "AIDA_Fitter.h"
00032 #include "AIDA_FitParameterSettings.h"
00033 #include "AIDA_FitResult.h"
00034 #include "AIDA_FitData.h"
00035 #include "FitterOptionParser.h"
00036 #include "FMLFitDataIteratorAdapter.h"
00037 # include "IDevFitDataIteratorFMLBase.h"
00038
00039 #include "AIDA_Function_FML/FMLFunctionAdapter.h"
00040 #include "AIDA_Function_FML/AIDA_DevFunctionFactory.h"
00041 #include "AIDA_Function_FML/AIDA_FunctionCatalog.h"
00042 #include "AIDA_Function_FML/AIDA_FunctionAdapter.h"
00043 #include "AIDA_Function_FML/AIDA_RangeSet.h"
00044
00045 #include "FML/FunctionCatalogue.h"
00046 #include "FML/RangeSet.h"
00047
00048 #include "FML/Fitter.h"
00049 #include "FML/debug.h"
00050 #include "FML/util.h"
00051
00052 #include "AIDA/IBaseHistogram.h"
00053 #include "AIDA/IHistogram1D.h"
00054 #include "AIDA/IHistogram2D.h"
00055 #include "AIDA/IHistogram3D.h"
00056 #include "AIDA/IProfile1D.h"
00057 #include "AIDA/IProfile2D.h"
00058 #include "AIDA/ICloud1D.h"
00059 #include "AIDA/ICloud2D.h"
00060 #include "AIDA/ICloud3D.h"
00061 #include "AIDA/IDataPointSet.h"
00062
00063
00064 namespace Anaphe {
00065 namespace AIDA_Fitter_FML {
00066
00067
00068 AIDA_Fitter::AIDA_Fitter()
00069 {
00070 m_fitter = new FML::Fitter();
00071 }
00072
00073 AIDA_Fitter::~AIDA_Fitter()
00074 {
00075
00076 for (FitParMap::iterator itr = m_parmap.begin(); itr != m_parmap.end(); ++itr)
00077 delete itr->second;
00078
00079 m_parmap.clear();
00080 delete m_fitter;
00081 }
00082
00083 AIDA_Fitter::AIDA_Fitter(const AIDA_Fitter &)
00084 {
00085 }
00086
00087 AIDA_Fitter & AIDA_Fitter::operator = (const AIDA_Fitter &rhs)
00088 {
00089 if (this == &rhs) return *this;
00090
00091 return *this;
00092 }
00093
00095
00096 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IFitData & d, AIDA::IFunction & f)
00097 {
00098
00099 if (d.dimension() != f.dimension()) {
00100 INFO_MSG("AIDA_Fitter_FML: dimension mismatch: between function and data");
00101 return 0;
00102 }
00103
00104
00105 Anaphe::FML::IFMLFunction *ff = dynamic_cast<Anaphe::FML::IFMLFunction*>(&f);
00106
00107 if(ff) return fit(d,*ff);
00108 else
00109 {
00110
00111 AIDA::Dev::IDevModelFunction *dmf = dynamic_cast<AIDA::Dev::IDevModelFunction*>(&f);
00112
00113 if(!dmf) return 0;
00114
00115
00116
00117
00118
00119
00120
00121
00122 AIDA::Dev::IDevFunctionFactory * fun_factory = 0;
00123 Anaphe::AIDA_Function_FML::AIDA_FunctionAdapter * aida_fun = dynamic_cast<Anaphe::AIDA_Function_FML::AIDA_FunctionAdapter *>(dmf);
00124 if (aida_fun) {
00125 fun_factory = new Anaphe::AIDA_Function_FML::AIDA_DevFunctionFactory();
00126 }
00127 Anaphe::AIDA_Function_FML::FMLFunctionAdapter ff(dmf,fun_factory);
00128 AIDA::IFitResult * r = fit(d,ff);
00129 delete fun_factory;
00130
00131 AIDA_FitResult * aida_r = dynamic_cast<AIDA_FitResult * >(r);
00132 if (aida_r) aida_r->fillAnnotation(&f);
00133
00134 return r;
00135 }
00136 }
00137
00139
00140 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IFitData& d, Anaphe::FML::IFMLFunction &f)
00141 {
00142
00143
00144 if (d.dimension() != f.dimension() ) {
00145 INFO_MSG("AIDA_Fitter_FML: dimension mismatch betwwen function and data ");
00146 return 0;
00147 }
00148
00149
00150 AIDA::Dev::IDevFitData * dd = dynamic_cast<AIDA::Dev::IDevFitData *>(&d);
00151
00152 if(!dd) return 0;
00153
00154 AIDA::Dev::IDevFitDataIterator* aida_it = dd->dataIterator();
00155 if (!aida_it) return 0;
00156
00157
00158
00159
00160
00161 if (dd->fitType() == AIDA::Dev::IDevFitter::UNBINNED_FIT) {
00162 if (fitMethodName() != "UnbinnedML") {
00163
00164 INFO_MSG( " Setting fit type to UNBINNED" );
00165 setFitMethod("UnbinnedML");
00166 m_fitter->fitConfig().setErrorUP(0.5);
00167 }
00168
00169 if (!f.providesNormalization()) {
00170 INFO_MSG( " AIDA_Fitter: Error - function does not provide normalization - Cannot perform unbinned fit to not normalized functions ");
00171 return 0;
00172 }
00173
00174 f.normalize(true);
00175
00176
00177 for (int i = 0; i < f.dimension(); ++i) {
00178 AIDA::IRangeSet & r = dd->range(i);
00179
00180 Anaphe::AIDA_Function_FML::AIDA_RangeSet * r_impl = dynamic_cast< Anaphe::AIDA_Function_FML::AIDA_RangeSet *> (&r);
00181 if (r_impl != 0 ) {
00182 Anaphe::FML::RangeSet r_fml = r_impl->getFMLRangeSet();
00183 bool lret = f.setNormalizationRange(i,r_fml);
00184 if (lret) {
00185 std::string text = "";
00186 for (int j = 0; j < r_fml.size(); ++j)
00187 text = "( " + Util::to_string(r_fml.lowerBounds()[j]) + " , " + Util::to_string(r_fml.upperBounds()[j]) + " ) ";
00188
00189 INFO_MSG( " Setting Function range to " + text);
00190 }
00191 else
00192 INFO_MSG( "AIDA_Fitter: Error setting a new FML::Function range" );
00193 }
00194 else
00195 INFO_MSG(" Error: Cannot get AIDA_Function_FML::RangeSet - range cannot be set on functions ");
00196 }
00197 }
00198
00199 IDevFitDataIteratorFMLBase *base_it = dynamic_cast<IDevFitDataIteratorFMLBase*>(aida_it);
00200
00201 if(base_it)
00202 {
00203
00204
00205 std::auto_ptr<Anaphe::FML::FitResult> r(m_fitter->fit(base_it->getIFMLDataIterator(), f));
00206
00207 return new AIDA_FitResult(r);
00208
00209 }
00210 else
00211 {
00212 FMLFitDataIteratorAdapter it(aida_it);
00213
00214 std::auto_ptr<Anaphe::FML::FitResult> r(m_fitter->fit(it, f));
00215
00216 return new AIDA_FitResult(r);
00217 }
00218
00219 }
00220
00222
00223 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IBaseHistogram & h, AIDA::IFunction & f)
00224 {
00225
00226
00227 AIDA_FitData d;
00228 if(!connect(d,h )) return 0;
00229
00230
00231 if (d.dimension() != f.dimension() ) {
00232 INFO_MSG("AIDA_Fitter_FML: dimension mismatch: between function and data");
00233 return 0;
00234 }
00235
00236
00237 if (d.fitType() == AIDA::Dev::IDevFitter::UNBINNED_FIT) {
00238
00239
00240 AIDA::IModelFunction * mf = dynamic_cast<AIDA::IModelFunction * > (&f);
00241 if (mf) {
00242
00243 for (int i = 0; i < d.dimension(); ++i) {
00244 AIDA::IRangeSet & range_d = d.range(i);
00245 range_d.excludeAll();
00246 AIDA::IRangeSet & range_fun = mf->normalizationRange(i);
00247
00248 for (int j = 0; j < range_fun.size(); ++j)
00249 range_d.include(range_fun.lowerBounds()[j],range_fun.upperBounds()[j] );
00250 }
00251 }
00252 }
00253
00254
00255 return fit(d,f);
00256 }
00257
00259
00260 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IBaseHistogram & h, std::string model)
00261 {
00262 std::auto_ptr<Anaphe::FML::IFMLFunction> f(Anaphe::FML::FunctionCatalogue::loadAndCreateFunction(model));
00263 if(!f.get()) return 0;
00264
00265 AIDA_FitData d;
00266 if(!connect(d,h )) return 0;
00267
00268 return fit(d,*f.get());
00269 }
00270
00272
00273
00274 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IBaseHistogram & h, std::string model, std::vector<double> & initialParameters )
00275 {
00276 std::auto_ptr<Anaphe::FML::IFMLFunction> f(Anaphe::FML::FunctionCatalogue::loadAndCreateFunction(model));
00277 if(!f.get()) return 0;
00278
00279 f->setParameters(initialParameters);
00280
00281 AIDA_FitData d;
00282 if(!connect(d,h )) return 0;
00283
00284 return fit(d,*f.get());
00285 }
00286
00288
00289 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IDataPointSet & dps, AIDA::IFunction & f)
00290 {
00291 AIDA_FitData d;
00292 if(!connect(d,dps )) return 0;
00293
00294 return fit(d,f);
00295 }
00296
00298
00299 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IDataPointSet & dps, std::string model)
00300 {
00301
00302 std::auto_ptr<Anaphe::FML::IFMLFunction> f(Anaphe::FML::FunctionCatalogue::loadAndCreateFunction(model));
00303 if(!f.get()) return 0;
00304
00305 AIDA_FitData d;
00306 if(!connect(d,dps )) return 0;
00307
00308 return fit(d,*f.get());
00309 }
00310
00312
00313
00314 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IDataPointSet & dps, std::string model, std::vector<double> & initialParameters )
00315 {
00316 std::auto_ptr<Anaphe::FML::IFMLFunction> f(Anaphe::FML::FunctionCatalogue::loadAndCreateFunction(model));
00317
00318 if(!f.get()) return 0;
00319
00320 f->setParameters(initialParameters);
00321
00322 AIDA_FitData d;
00323 if(!connect(d,dps )) return 0;
00324
00325 return fit(d,*f.get());
00326
00327 }
00328
00329
00331
00332 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IFitData & d, std::string model )
00333 {
00334 std::auto_ptr<Anaphe::FML::IFMLFunction> f(Anaphe::FML::FunctionCatalogue::loadAndCreateFunction(model));
00335 if(!f.get()) return 0;
00336
00337 return fit(d,*f.get());
00338 }
00339
00340 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IFitData & d, std::string model, std::vector<double> & initialParameters)
00341 {
00342 std::auto_ptr<Anaphe::FML::IFMLFunction> f(Anaphe::FML::FunctionCatalogue::loadAndCreateFunction(model));
00343 if(!f.get()) return 0;
00344 f->setParameters(initialParameters);
00345
00346 return fit(d,*f.get());
00347 }
00348
00349
00350 bool AIDA_Fitter::setEngine(std::string name)
00351 {
00352 return m_fitter->fitConfig().setEngine(name);
00353 }
00354
00355 std::string AIDA_Fitter::engineName()
00356 {
00357 return m_fitter->fitConfig().engineName();
00358 }
00359
00360 AIDA::IFitParameterSettings & AIDA_Fitter::fitParameterSettings(std::string name)
00361 {
00362 AIDA_FitParameterSettings * ps = new AIDA_FitParameterSettings(&m_fitter->fitConfig().fitParameterSettings(name));
00363 m_parmap[name] = ps;
00364 return *m_parmap[name];
00365 }
00366
00367 const std::vector<std::string> & AIDA_Fitter::listParameterSettings()
00368 {
00369 return m_fitter->fitConfig().listParameterSettings();
00370 }
00371
00372 void AIDA_Fitter::resetParameterSettings()
00373 {
00374 return m_fitter->fitConfig().resetParameterSettings();
00375 }
00376
00377 bool AIDA_Fitter::setConstraint(std::string expr)
00378 {
00379
00380
00381 INFO_MSG("AIDA_Fitter::setConstraint not implemented");
00382 return false;
00383 }
00384
00385 const std::vector<std::string> & AIDA_Fitter::constraints()
00386 {
00387 return m_constr;
00388 }
00389
00390 void AIDA_Fitter::resetConstraints()
00391 {
00392 }
00393
00394 bool AIDA_Fitter::setFitMethod(std::string name)
00395 {
00396 return m_fitter->fitConfig().setFitMethod(name);
00397 }
00398
00399 std::string AIDA_Fitter::fitMethodName()
00400 {
00401 return m_fitter->fitConfig().fitMethodName();
00402 }
00403
00404 AIDA::IDataPointSet * AIDA_Fitter::createScan1D(AIDA::IFitData & d, AIDA::IFunction & f, std::string par, int npts, double pmin, double pmax)
00405 {
00406 INFO_MSG("AIDA_Fitter::createScan1D not implemented");
00407 return 0;
00408 }
00409
00410 AIDA::IDataPointSet * AIDA_Fitter::createContour(AIDA::IFitData & d, AIDA::IFitResult & r, std::string par1, std::string par2, int npts, double up)
00411 {
00412 INFO_MSG("AIDA_Fitter::createContour not implemented");
00413 return 0;
00414 }
00415
00416 void AIDA_Fitter::setUseFunctionGradient( bool useGrad )
00417 {
00418 INFO_MSG("AIDA_Fitter::setUseFunctionGradient not implemented");
00419 }
00420
00421 bool AIDA_Fitter::useFunctionGradient()
00422 {
00423 return true;
00424 }
00425
00426
00427
00428
00429 bool AIDA_Fitter::setOptions(const std::string & options)
00430 {
00431 if (!m_fitter) return false;
00432
00433 FitterOptionParser parser(options);
00434
00435
00436
00437
00438
00439
00440
00441 m_fitter->fitConfig().setPrintLevel(parser.printLevel());
00442 m_fitter->fitConfig().switchMinosErrors(parser.useMinos());
00443 m_fitter->fitConfig().setErrorUP(parser.errorUP());
00444
00445 return true;
00446 }
00447
00448
00449 bool AIDA_Fitter::connect(AIDA::IFitData& d , AIDA::IBaseHistogram &h)
00450 {
00451
00452 bool lret;
00453 int dim = h.dimension();
00454 switch(dim)
00455 {
00456 case 1:
00457 {
00458 AIDA::IHistogram1D *h1 = dynamic_cast<AIDA::IHistogram1D*>(&h);
00459 if (h1) {
00460 lret = d.create1DConnection(*h1);
00461 break;
00462 }
00463 AIDA::IProfile1D *p1 = dynamic_cast<AIDA::IProfile1D*>(&h);
00464 if (p1) {
00465 lret = d.create1DConnection(*p1);
00466 break;
00467 }
00468 AIDA::ICloud1D *c1 = dynamic_cast<AIDA::ICloud1D*>(&h);
00469 if (c1) {
00470 lret = d.create1DConnection(*c1);
00471 break;
00472 }
00473
00474 INFO_MSG("AIDA_Fitter_FML: Unknown type of AIDA::IBaseHistogram");
00475 return false;
00476 }
00477
00478 case 2:
00479 {
00480 AIDA::IHistogram2D *h2 = dynamic_cast<AIDA::IHistogram2D*>(&h);
00481 if (h2) {
00482 lret = d.create2DConnection(*h2);
00483 break;
00484 }
00485 AIDA::IProfile2D *p2 = dynamic_cast<AIDA::IProfile2D*>(&h);
00486 if (p2) {
00487 lret = d.create2DConnection(*p2);
00488 break;
00489 }
00490 AIDA::ICloud2D *c2 = dynamic_cast<AIDA::ICloud2D*>(&h);
00491 if (c2) {
00492 lret = d.create2DConnection(*c2);
00493 break;
00494 }
00495
00496 INFO_MSG("AIDA_Fitter_FML: Unknown type of AIDA::IBaseHistogram");
00497 return false;
00498 }
00499
00500 case 3:
00501 {
00502 AIDA::IHistogram3D *h3 = dynamic_cast<AIDA::IHistogram3D*>(&h);
00503 if (h3) {
00504 lret = d.create3DConnection(*h3);
00505 break;
00506 }
00507 AIDA::ICloud3D *c3 = dynamic_cast<AIDA::ICloud3D*>(&h);
00508 if (c3) {
00509 lret = d.create3DConnection(*c3);
00510 break;
00511 }
00512
00513 INFO_MSG("AIDA_Fitter_FML: Unknown type of AIDA::IBaseHistogram");
00514 return false;
00515 }
00516
00517 default:
00518 {
00519 return false;
00520 }
00521 }
00522
00523 return lret;
00524 }
00525
00526
00527 bool AIDA_Fitter::connect(AIDA::IFitData& d , AIDA::IDataPointSet &dps)
00528 {
00529
00530
00531 std::vector<int> indices;
00532 for (int i = 0; i < dps.dimension()-1; ++i)
00533 indices.push_back(i);
00534
00535 int valIndex = dps.dimension()-1;
00536
00537 return d.createConnection(dps,indices,valIndex);
00538 }
00539
00540
00541
00542 }
00543 }