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 # include "FitFunction.h"
00031
00032 class IHistogram;
00033 class IHistogram1D;
00034 class IHistogram2D;
00035 class ICloud;
00036
00037 namespace Anaphe
00038 {
00039 class IHistogram;
00040 class IHistogram1D;
00041 class IHistogram2D;
00042 }
00043
00044 # include "VoPAdapter/VoPHist.h"
00045 # include "VoPAdapter/VoPCloud.h"
00046
00047
00048 # include "Interfaces/IVector.h"
00049 # include "Interfaces/IVectorFactory.h"
00050 # include "Interfaces/IObjectiveFunction.h"
00051
00052 # include "FML/IExtendedFitter.h"
00053 # include "FML/IMinimizer.h"
00054 # include "FML/IMinimizerResult.h"
00055
00056
00057
00058 # include <iostream>
00059
00060 FitFunction::FitFunction(const std::string & label, const std::string& type, const std::string& options) : m_model(0), m_fitter(0), m_method(options)
00061 {
00062
00063 std::auto_ptr<FML::IFitter_impl> fitter( new FML::IFitter_impl );
00064 m_fitter = fitter;
00065 assert(m_fitter.get());
00066
00067
00068
00069 m_fitter->setModel(type.c_str());
00070 assert(m_fitter->internalModelFunction());
00071
00072
00073 std::auto_ptr<Function_plain_wrapper> model(new Function_plain_wrapper(label, m_fitter->internalModelFunction()));
00074 m_model = model;
00075 assert(m_model.get());
00076
00077 m_fitter->setPrintLevel(FML::IMinimizer::minimum_printout);
00078
00079 m_version = std::string(AIDA_VERSION);
00080 }
00081
00082 FitFunction::~FitFunction()
00083 {
00084
00085
00086 }
00087
00088 FitFunction::FitFunction(const FitFunction &)
00089 {
00090 }
00091
00092 FitFunction & FitFunction::operator = (const FitFunction &rhs)
00093 {
00094 if (this == &rhs) return *this;
00095
00096 return *this;
00097 }
00098
00099 bool FitFunction::setFixed ( const std::string & name, bool state )
00100 {
00101 Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00102
00103 if(!par) return false;
00104
00105 if(state)
00106 par->setBounds(par->value(), par->value());
00107 else
00108 par->release();
00109
00110 return true;
00111 }
00112
00113 bool FitFunction::setBounds ( const std::string & name, double lower, double upper )
00114 {
00115 Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00116
00117 if(!par) return false;
00118
00119 par->setBounds(lower, upper);
00120
00121 return true;
00122 }
00123
00124 bool FitFunction::setStart ( const std::string & name, double start )
00125 {
00126 Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00127
00128 if(!par) return false;
00129
00130 par->setStart(start);
00131
00132 return true;
00133 }
00134
00135 bool FitFunction::clearBounds ( const std::string & name )
00136 {
00137 Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00138
00139 if(!par) return false;
00140
00141 par->release();
00142
00143 return true;
00144 }
00145
00146 bool FitFunction::setStepSize ( const std::string & name, double step )
00147 {
00148 Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00149
00150 if(!par) return false;
00151
00152 par->setStep(step);
00153
00154 return true;
00155 }
00156
00157 double FitFunction::error ( const std::string & name )
00158 {
00159 Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00160
00161 return par ? par->error() : 0.0;
00162
00163 return true;
00164 }
00165
00166
00167 const std::vector< double > & FitFunction::errors ( )
00168 {
00169
00170
00171 m_errors_ret.clear();
00172
00173 FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00174
00175 if(ef&&ef->minimizer())
00176 for(int i=0; i<ef->minimizer()->result().dimension(); ++i)
00177 m_errors_ret.push_back(ef->minimizer()->result().error(i));
00178
00179 return m_errors_ret;
00180 }
00181
00182
00183 double FitFunction::chiSquare ( )
00184 {
00185 FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00186
00187 if(ef&&ef->minimizer())
00188 return ef->minimizer()->result().minimumValue();
00189
00190 return 0.0;
00191 }
00192
00193
00194 double FitFunction::degreeOfFreedom ( )
00195 {
00196
00197 FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00198
00199 if(ef&&ef->minimizer())
00200 {
00201
00202 int npts = 0;
00203 if(ef->data())
00204 npts = ef->data()->nPoints();
00205
00206 int pnum = 0;
00207
00208 if(ef->modelFunction())
00209 pnum = ef->modelFunction()->numberOfParameters();
00210
00211 return npts-pnum-1;
00212 }
00213
00214 return 0.0;
00215 }
00216
00217 bool FitFunction::setErrors ( const std::vector< double > & errors )
00218 {
00219 nyi();
00220 return false;
00221 }
00222
00223 bool FitFunction::setChiSquare ( double chiSquare )
00224 {
00225 nyi();
00226 return false;
00227 }
00228
00229 bool FitFunction::setDegreeOfFreedom ( double degreeOfFreedom )
00230 {
00231 nyi();
00232 return false;
00233 }
00234
00235 bool FitFunction::hasGradient ( ) const
00236 {
00237 FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00238
00239 if(ef&&ef->minimizer()&&ef->minimizer()->objectiveFunction())
00240 return ef->minimizer()->objectiveFunction()->hasGradient();
00241
00242 return false;
00243 }
00244
00248 const std::vector< double > & FitFunction::getGradient ( const std::vector< double > & one, const std::vector< double > & orTwo )
00249 {
00250 nyi();
00251 return vector<double>();
00252 }
00253
00254 bool FitFunction::fit(const IHistogram & histogram) {
00255 return fit( histogram,0,0);
00256 }
00257
00258
00259 bool FitFunction::fit(const IHistogram & histogram, int imin, int imax)
00260 {
00261 std::auto_ptr<Anaphe::IVectorFactory> vm(createIVectorFactory());
00262 if(!vm.get()) return false;
00263
00264 std::auto_ptr<Anaphe::IVector> new_vector(vm->create());
00265
00266 m_source_data = new_vector;
00267
00268 if(!m_source_data.get()) return false;
00269
00270 Anaphe::VoPHist converter;
00271
00272 if(!converter.fromHistogram(const_cast<IHistogram*>(&histogram), m_source_data.get()))
00273 return false;
00274
00275 return m_fit(imin,imax);
00276
00277 }
00278
00279
00280 bool FitFunction::fit(const ICloud & cloud, int imin, int imax)
00281 {
00282
00283 std::auto_ptr<Anaphe::IVectorFactory> vm(createIVectorFactory());
00284 if(!vm.get()) return false;
00285
00286 std::auto_ptr<Anaphe::IVector> new_vector(vm->create());
00287
00288 m_source_data = new_vector;
00289
00290 if(!m_source_data.get()) return false;
00291
00292 Anaphe::VoPCloud converter;
00293
00294 if(!converter.fromCloud(const_cast<ICloud*>(&cloud), m_source_data.get()))
00295 return false;
00296
00297
00298 m_method = "UL";
00299
00300 return m_fit(imin,imax);
00301
00302 }
00303
00304
00305
00306
00307
00308 const std::string & FitFunction::label ( ) const
00309 {
00310 return m_model->label();
00311 }
00312
00313 double FitFunction::value ( const std::vector< double > & point ) const
00314 {
00315 return m_model->value(point);
00316 }
00317
00318 int FitFunction::dimension ( ) const
00319 {
00320 return m_model->dimension();
00321 }
00322
00323 const std::vector< std::string > & FitFunction::parameterNames ( ) const
00324 {
00325 return m_model->parameterNames();
00326 }
00327
00328 const std::vector< double > & FitFunction::parameterValues ( ) const
00329 {
00330 return m_model->parameterValues();
00331 }
00332
00333 const string & FitFunction::version ( ) const
00334 {
00335 return m_version;
00336 }
00337
00338 bool FitFunction::setParameterValue ( const std::string & name, double value )
00339 {
00340 bool ok = m_fitter->setParameter(name.c_str(), value);
00341
00342 if(!ok) return false;
00343
00344 return m_model->setParameterValue(name,value);
00345 }
00346
00347
00348 void FitFunction::nyi() const
00349 {
00350 cerr << "FitFunction:: Not yet implemented" << endl;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 bool FitFunction::m_fit(int imin, int imax)
00360 {
00361 m_fitter->setData(m_source_data.get());
00362
00363 if(imax!=0 || imin != 0) {
00364 m_fitter->excludeAll();
00365 m_fitter->includeRange(imin, imax);
00366 cout << " Fitting range : " << imin << " - " << imax << endl;
00367 }
00368
00369
00370 m_fitter->printParameters(std::cout);
00371
00372 bool ok = false;
00373 if (m_method == "L" || m_method == "ML")
00374 ok = m_fitter->poissonMLFit();
00375 else if (m_method == "UL")
00376 ok = m_fitter->unbinnedMLFit();
00377 else
00378 ok = m_fitter->chiSquareFit();
00379
00380 if(ok)
00381 {
00382
00383 m_model->setParameterValues(m_fitter->parameterValueVector());
00384 }
00385
00386
00387 m_fitter->printResult(std::cout);
00388
00389 return ok;
00390 }
00391