// @(#)root/tmva $Id$ // Author: Andraes Hoecker /********************************************************************************** * Project: TMVA - a Root-integrated toolkit for multivariate data analysis * * Package: TMVA * * Class : MinuitFitter * * Web : http://tmva.sourceforge.net * * * * Description: * * Implementation * * * * Authors (alphabetical): * * Andreas Hoecker - CERN, Switzerland * * * * Copyright (c) 2005: * * CERN, Switzerland * * MPI-K Heidelberg, Germany * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted according to the terms listed in LICENSE * * (http://tmva.sourceforge.net/LICENSE) * **********************************************************************************/ //_______________________________________________________________________ // // Fitter using MINUIT //_______________________________________________________________________ #include "TFitter.h" #include "TMVA/MinuitFitter.h" #include "TMVA/MinuitWrapper.h" #include "TMVA/Interval.h" #include "TMVA/Timer.h" ClassImp(TMVA::MinuitFitter) //_______________________________________________________________________ TMVA::MinuitFitter::MinuitFitter( IFitterTarget& target, const TString& name, std::vector& ranges, const TString& theOption ) : TMVA::FitterBase( target, name, ranges, theOption ), TMVA::IFitterTarget( ) { // constructor // default parameters settings for Simulated Annealing algorithm DeclareOptions(); ParseOptions(); Init(); // initialise the TFitter } //_______________________________________________________________________ TMVA::MinuitFitter::~MinuitFitter( ) { // destructor delete fMinWrap; } //_______________________________________________________________________ void TMVA::MinuitFitter::DeclareOptions() { // declare SA options DeclareOptionRef(fErrorLevel = 1, "ErrorLevel", "TMinuit: error level: 0.5=logL fit, 1=chi-squared fit" ); DeclareOptionRef(fPrintLevel = -1, "PrintLevel", "TMinuit: output level: -1=least, 0, +1=all garbage" ); DeclareOptionRef(fFitStrategy = 2, "FitStrategy", "TMinuit: fit strategy: 2=best" ); DeclareOptionRef(fPrintWarnings = kFALSE, "PrintWarnings", "TMinuit: suppress warnings" ); DeclareOptionRef(fUseImprove = kTRUE, "UseImprove", "TMinuit: use IMPROVE" ); DeclareOptionRef(fUseMinos = kTRUE, "UseMinos", "TMinuit: use MINOS" ); DeclareOptionRef(fBatch = kFALSE, "SetBatch", "TMinuit: use batch mode" ); DeclareOptionRef(fMaxCalls = 1000, "MaxCalls", "TMinuit: approximate maximum number of function calls" ); DeclareOptionRef(fTolerance = 0.1, "Tolerance", "TMinuit: tolerance to the function value at the minimum" ); } //_______________________________________________________________________ void TMVA::MinuitFitter::Init() { // minuit-specific settings Double_t args[10]; // Execute fitting if (!fBatch) Log() << kINFO << " Init " << Endl; // timing of MC Timer timer; // initialize first -> prepare the fitter // instantiate minuit // maximum number of fit parameters is equal to // (2xnpar as workaround for TMinuit allocation bug (taken from RooMinuit)) fMinWrap = new MinuitWrapper( fFitterTarget, 2*GetNpars() ); // output level args[0] = fPrintLevel; fMinWrap->ExecuteCommand( "SET PRINTOUT", args, 1 ); if (fBatch) fMinWrap->ExecuteCommand( "SET BAT", args, 0 ); // set fitter object, and clear fMinWrap->Clear(); // error level: 1 (2*log(L) fit args[0] = fErrorLevel; fMinWrap->ExecuteCommand( "SET ERR", args, 1 ); // print warnings ? if (!fPrintWarnings) fMinWrap->ExecuteCommand( "SET NOWARNINGS", args, 0 ); // define fit strategy args[0] = fFitStrategy; fMinWrap->ExecuteCommand( "SET STRATEGY", args, 1 ); } //_______________________________________________________________________ Double_t TMVA::MinuitFitter::Run( std::vector& pars ) { // performs the fit // minuit-specific settings Double_t args[10]; // Execute fitting if ( !fBatch ) Log() << kINFO << " Fitting, please be patient ... " << Endl; // sanity check if ((Int_t)pars.size() != GetNpars()) Log() << kFATAL << " Mismatch in number of parameters: (a)" << GetNpars() << " != " << pars.size() << Endl; // timing of MC Timer* timer = 0; if (!fBatch) timer = new Timer(); // define fit parameters for (Int_t ipar=0; iparSetParameter( ipar, Form( "Par%i",ipar ), pars[ipar], fRanges[ipar]->GetWidth()/100.0, fRanges[ipar]->GetMin(), fRanges[ipar]->GetMax() ); if (fRanges[ipar]->GetWidth() == 0.0) fMinWrap->FixParameter( ipar ); } // --------- execute the fit // continue with usual case args[0] = fMaxCalls; args[1] = fTolerance; // MIGRAD fMinWrap->ExecuteCommand( "MIGrad", args, 2 ); // IMPROVE if (fUseImprove) fMinWrap->ExecuteCommand( "IMProve", args, 0 ); // MINOS if (fUseMinos) { args[0] = 500; fMinWrap->ExecuteCommand( "MINOs", args, 1 ); } // retrieve fit result (statistics) Double_t chi2; Double_t edm; Double_t errdef; Int_t nvpar; Int_t nparx; fMinWrap->GetStats( chi2, edm, errdef, nvpar, nparx ); // sanity check if (GetNpars() != nparx) { Log() << kFATAL << " Mismatch in number of parameters: " << GetNpars() << " != " << nparx << Endl; } // retrieve parameters for (Int_t ipar=0; iparGetParameter( ipar, currVal, currErr ); pars[ipar] = currVal; fMinWrap->GetErrors( ipar, errp, errm, errsym, globcor ); } // clean up // get elapsed time if (!fBatch) { Log() << kINFO << "Elapsed time: " << timer->GetElapsedTime() << " " << Endl; delete timer; } fMinWrap->Clear(); return chi2; } //_______________________________________________________________________ Double_t TMVA::MinuitFitter::EstimatorFunction( std::vector& pars ) { // performs the fit by calliung Run(pars) return Run( pars ); }