Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

AIDA_Fitter.cpp

Go to the documentation of this file.
00001  /**********************************************************************
00002   *                                                                    *
00003   * Copyright (c) 2002 Lorenzo Moneta, CERN/IT                       *
00004   *                   <Lorenzo.Moneta.cern.ch>                       *
00005   *                                                                    *
00006   * This library is free software; you can redistribute it and/or      *
00007   * modify it under the terms of the GNU Lesser General Public         *
00008   * License as published by the Free Software Foundation; either       *
00009   * version 2.1 of the License, or (at your option) any later version. *
00010   *                                                                    *
00011   * This library is distributed in the hope that it will be useful,    *
00012   * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
00013   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
00014   * Lesser General Public License for more details.                    *
00015   *                                                                    *
00016   * You should have received a copy of the GNU Lesser General Public   *
00017   * License along with this library (see file COPYING); if not, write  *
00018   * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
00019   * 330, Boston, MA 02111-1307 USA, or contact the author.             *
00020   *                                                                    *
00021   **********************************************************************/
00022 
00023 // Implementation file for class AIDA_Fitter
00024 // 
00025 // Authors  : Lorenzo Moneta , Jakub Moscicki
00026 // Created  : Thu Oct  3 15:23:33 2002
00027 // 
00028 // Last update: Thu Oct  3 15:23:33 2002
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   // delete parameter settings 
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;  // time saving self-test
00090 
00091    return *this;
00092 }
00093 
00095 
00096 AIDA::IFitResult * AIDA_Fitter::fit(AIDA::IFitData & d, AIDA::IFunction & f)
00097 {
00098   // check dimensionality
00099   if (d.dimension() != f.dimension()) { 
00100     INFO_MSG("AIDA_Fitter_FML: dimension mismatch: between function and data");
00101     return 0;
00102   }
00103 
00104   // if f in native FML function we don't need the adapter
00105   Anaphe::FML::IFMLFunction *ff = dynamic_cast<Anaphe::FML::IFMLFunction*>(&f);
00106   
00107   if(ff) return fit(d,*ff);
00108   else
00109     {
00110       // well, f is a foreign implementation, we need an adapter
00111       AIDA::Dev::IDevModelFunction *dmf = dynamic_cast<AIDA::Dev::IDevModelFunction*>(&f);
00112 
00113       if(!dmf) return 0;
00114       
00115       
00116       // As suggested by Kuba 
00117       // I need to pass a function fuctory to the adapter. 
00118       // To do: function factory should be a singleton to be used 
00119       // in other classes of the package
00120 
00121       // if is an AIDA_FunctionAdapter use the factory...
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       // update annotation of AIDA::IFunction (it is a fitted function)
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   // check first the dimension 
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   // check fit type 
00158 
00159   // operations for unbinned fits 
00160  
00161   if (dd->fitType() == AIDA::Dev::IDevFitter::UNBINNED_FIT) { 
00162     if (fitMethodName() != "UnbinnedML") { 
00163     // set method 
00164       INFO_MSG( " Setting fit type to UNBINNED" );
00165       setFitMethod("UnbinnedML");
00166       m_fitter->fitConfig().setErrorUP(0.5);
00167     }
00168     // check if function is normalizable
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     // normalize
00174     f.normalize(true); 
00175 
00176     // set ranges 
00177     for (int i = 0; i < f.dimension(); ++i) { 
00178       AIDA::IRangeSet & r = dd->range(i);
00179       // dynamic cast to implementation
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       // home implementation, use a faster path
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 // foregin implementation, use adapter
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      // do volutaruy memory leak to avoid error with autopointers
00226      //AIDA_FitData * d = new AIDA_FitData();        
00227      AIDA_FitData d;
00228      if(!connect(d,h )) return 0;  
00229 
00230      // check dimensions..
00231      if (d.dimension() != f.dimension() ) { 
00232        INFO_MSG("AIDA_Fitter_FML: dimension mismatch: between function and data");
00233        return 0;
00234      }
00235 
00236      // need to copy range of function in IFitData for unbinned fits and 
00237      if (d.fitType() == AIDA::Dev::IDevFitter::UNBINNED_FIT) {
00238      // function must be of type IModelFunction
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            // loop on function ranges 
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       // to implement this you must create a parser for constraint expressions
00380       // create a Linear or NonlinearConstraint object and here you go - the rest is done.
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 // set fitter options
00428 
00429 bool AIDA_Fitter::setOptions(const std::string & options)
00430 { 
00431   if (!m_fitter) return false; 
00432 
00433   FitterOptionParser parser(options);
00434   /* 
00435   std::cout <<  " Fitter options... " << std::endl;
00436   std::cout << " printLevel " << parser.printLevel()  << std::endl;
00437   std::cout << " useMINOS " << parser.useMinos()  << std::endl;
00438   std::cout << " errorUp " << parser.errorUP() << std::endl;
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         // I should never be here
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         // I should never be here
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         // I should never be here
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 // connect of DatapointSet to data 
00527 bool AIDA_Fitter::connect(AIDA::IFitData& d , AIDA::IDataPointSet &dps)
00528 {
00529   // connect using defaults indeces (0,1,2,...) for coordinate and last one
00530   // for values 
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   }     // end of namespace Anaphe::AIDA_Fitter_FML
00543 } 

Generated on Tue May 20 14:49:01 2003 for AIDA_Fitter_FML by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002