// @(#)root/minuit2:$Id$ // Author: L. Moneta 10/2005 /********************************************************************** * * * Copyright (c) 2005 ROOT Foundation, CERN/PH-SFT * * * **********************************************************************/ #include "TChi2ExtendedFCN.h" #include "TChi2ExtendedFitData.h" #include "TF1.h" #include "TVirtualFitter.h" #include //#include TChi2ExtendedFCN::TChi2ExtendedFCN( const TVirtualFitter & fitter) : fUp(1.) { // constructor : create FitData class and keep a pointer to model function fFunc = dynamic_cast ( fitter.GetUserFunc() ); assert(fFunc != 0); // default skip empty bins fData = new TChi2ExtendedFitData(fitter); // need to set the size so ROOT can calculate ndf. fFunc->SetNumberFitPoints(fData->Size()); } TChi2ExtendedFCN::~TChi2ExtendedFCN() { // this class manages the fit data class. Delete it at the end if (fData) { delete fData; } } double TChi2ExtendedFCN::operator()(const std::vector& par) const { // implement chi2 extended function: use also error on x coordinates (can be also asymmetric) assert(fData != 0); assert(fFunc != 0); // std::cout << "number of params " << par.size() << " in TF1 " << fFunc->GetNpar() << " " << fFunc->GetNumberFreeParameters() << std::endl; unsigned int n = fData->Size(); double chi2 = 0; for (unsigned int i = 0; i < n; ++ i) { const std::vector & x = fData->Coords(i); fFunc->InitArgs( &x.front(), &par.front() ); double y = fData->Value(i); //std::cout << x[0] << " " << y << " " << 1./invError << " params " << par[0] << std::endl; double functionValue = fFunc->EvalPar( &x.front(), &par.front() ); double ey = fData->ErrorY(i); double exl = fData->ErrorXLow(i); double exh = fData->ErrorXUp(i); double eux = 0; if (exh <=0 && exl <= 0) eux = 0; else // works only for 1D func eux = 0.5 * (exl + exh) * fFunc->Derivative( x[0], const_cast ( &par.front() ) ); double error2 = (ey*ey + eux*eux); if (error2 == 0) error2 = 1; double tmp = ( y -functionValue ); chi2 += tmp*tmp/error2; } return chi2; }