Parent Directory
|
Revision Log
import changes from math development branches for subdirectory math. List of changes in detail:
mathcore:
---------
MinimizerOptions:
new class for storing Minimizer option, with static default values that can be
changed by the user
FitConfig:
- use default values from MinimizerOption class
- rename method to create parameter settings from a function
FitUtil.cxx:
improve the derivative calculations used in the effective chi2 and in Fumili and
fix a bug for evaluation of likelihood or chi2 terms.
In EvaluatePdf() work and return the log of the pdf.
FitResult:
- improve the class by adding extra information like, num. of free parameters,
minimizer status, global correlation coefficients, information about fixed
and bound parameters.
- add method for getting fit confidence intervals
- improve print method
DataRange:
add method SetRange to distinguish from AddRange. SetRange deletes the existing
ranges.
ParamsSettings: make few methods const
FCN functions (Chi2FCN, LogLikelihoodFCN, etc..)
move some common methods and data members in base class (FitMethodFunction)
RootFinder: add template Solve() for any callable function.
mathmore:
--------
minimizer classes: fill status information
GSLNLSMinimizer: return error and covariance matrix
minuit2:
-------
Minuit2Minimizer: fill status information
DavidonErrorUpdator: check that delgam or gvg are not zero ( can happen when dg = 0)
FumiliFCNAdapter: work on the log of pdf
minuit:
-------
TLinearMinimizer: add support for robust fitting
TMinuitMinimizer: fill status information and fix a bug in filling the correlation matrix.
fumili:
------
add TFumiliMinimizer:
wrapper class for TFumili using Minimizer interface
// test fitting using also RooFit and new Fitter
#include <RooAbsPdf.h>
#include <RooRealVar.h>
#include <RooArgSet.h>
#include <RooGaussian.h>
#include "RooDataSet.h"
#include "RooRealVar.h"
#include "RooGaussian.h"
#include "RooGlobalFunc.h"
#include "RooFitResult.h"
#include "RooProdPdf.h"
#include <TF1.h>
#include <TTree.h>
#include <TRandom3.h>
#include "TStopwatch.h"
#include "Math/DistFunc.h"
#include "Fit/UnBinData.h"
#include "Fit/BinData.h"
#include "Fit/Fitter.h"
#include "WrapperRooPdf.h"
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include "MinimizerTypes.h"
#include "Math/WrappedParamFunction.h"
#include <cmath>
const int N = 1; // n must be greater than 1
const int nfit = 1;
const int nEvents = 10000;
double iniPar[2*N];
typedef ROOT::Math::IParamMultiFunction Func;
void fillTree(TTree & t2) {
double x[N];
Int_t ev;
for (int j = 0; j < N; ++j) {
std::string xname = "x_" + ROOT::Math::Util::ToString(j);
std::string xname2 = "x_" + ROOT::Math::Util::ToString(j) + "/D";
t2.Branch(xname.c_str(),&x[j],xname2.c_str());
}
t2.Branch("ev",&ev,"ev/I");
//fill the tree
TRandom3 r;
for (Int_t i=0;i<nEvents;i++) {
for (int j = 0; j < N; ++j) {
double mu = double(j)/10.;
double s = 1.0 + double(j)/10.;
x[j] = r.Gaus(mu,s);
}
ev = i;
t2.Fill();
}
}
void FillUnBinData(ROOT::Fit::UnBinData &d, TTree * tree ) {
// fill the unbin data set from a TTree
// large tree
unsigned int n = tree->GetEntries();
std::cout << "number of unbin data is " << n << " of dim " << N << std::endl;
d.Initialize(n,N);
double vx[N];
for (int j = 0; j <N; ++j) {
std::string bname = "x_" + ROOT::Math::Util::ToString(j);
TBranch * bx = tree->GetBranch(bname.c_str());
bx->SetAddress(&vx[j]);
}
std::vector<double> m(N);
for (int unsigned i = 0; i < n; ++i) {
tree->GetEntry(i);
d.Add(vx);
for (int j = 0; j < N; ++j)
m[j] += vx[j];
}
std::cout << "average values of means :\n";
for (int j = 0; j < N; ++j)
std::cout << m[j]/n << " ";
std::cout << "\n";
return;
}
// class describing product of gaussian pdf
class MultiGaussRooPdf {
public:
// create all pdf
MultiGaussRooPdf(unsigned int n) :
x(n), m(n), s(n), g(n), pdf(n)
{
//assert(n >= 2);
// create the gaussians
for (unsigned int j = 0; j < n; ++j) {
std::string xname = "x_" + ROOT::Math::Util::ToString(j);
x[j] = new RooRealVar(xname.c_str(),xname.c_str(),-10000,10000) ;
std::string mname = "m_" + ROOT::Math::Util::ToString(j);
std::string sname = "s_" + ROOT::Math::Util::ToString(j);
// m[j] = new RooRealVar(mname.c_str(),mname.c_str(),iniPar[2*j],-10000,10000) ;
// s[j] = new RooRealVar(sname.c_str(),sname.c_str(),iniPar[2*j+1],-10000,10000) ;
m[j] = new RooRealVar(mname.c_str(),mname.c_str(),iniPar[2*j],-10,10) ;
s[j] = new RooRealVar(sname.c_str(),sname.c_str(),iniPar[2*j+1],-10,10) ;
std::string gname = "g_" + ROOT::Math::Util::ToString(j);
g[j] = new RooGaussian(gname.c_str(),"gauss(x,mean,sigma)",*x[j],*m[j],*s[j]);
std::string pname = "prod_" + ROOT::Math::Util::ToString(j);
if (j == 1) {
pdf[1] = new RooProdPdf(pname.c_str(),pname.c_str(),RooArgSet(*g[1],*g[0]) );
}
else if (j > 1) {
pdf[j] = new RooProdPdf(pname.c_str(),pname.c_str(),RooArgSet(*g[j],*pdf[j-1]) );
}
else if (j == 0)
pdf[0] = g[0];
}
}
RooAbsPdf & getPdf() { return *pdf.back(); }
std::auto_ptr<RooArgSet> getVars() {
std::auto_ptr<RooArgSet> vars(new RooArgSet() );
for (unsigned int i = 0; i < x.size(); ++i)
vars->add(*x[i]);
return vars;
}
~MultiGaussRooPdf() {
// free
int n = x.size();
for (int j = 0; j < n; ++j) {
delete x[j];
delete m[j];
delete s[j];
delete g[j];
delete pdf[j];
}
}
private:
std::vector<RooRealVar *> x;
std::vector<RooRealVar *> m;
std::vector<RooRealVar *> s;
std::vector<RooAbsPdf *> g;
std::vector<RooAbsPdf *> pdf;
};
//unbinned roo fit (large tree)
int FitUsingRooFit(TTree & tree, RooAbsPdf & pdf, RooArgSet & xvars) {
int iret = 0;
std::cout << "\n************************************************************\n";
std::cout << "\tFit using RooFit (Likelihood Fit) on " << pdf.GetName() << std::endl;
TStopwatch w;
w.Start();
for (int i = 0; i < nfit; ++i) {
RooDataSet data("unbindata","unbin dataset with x",&tree,xvars) ;
#ifdef DEBUG
int level = 3;
std::cout << "num entries = " << data.numEntries() << std::endl;
bool save = true;
(pdf[N-1]->getVariables())->Print("v"); // print the parameters
std::cout << "\n\nDo the fit now \n\n";
#else
int level = 1;
bool save = false;
#endif
#ifndef _WIN32 // until a bug 30762 is fixed
RooFitResult * result = pdf.fitTo(data, RooFit::Minos(0), RooFit::Hesse(0) , RooFit::PrintLevel(level), RooFit::Save(save) );
#else
RooFitResult * result = pdf.fitTo(data );
#endif
#ifdef DEBUG
assert(result != 0);
std::cout << " Roofit status " << result->status() << std::endl;
result->Print();
#endif
iret |= (result == 0);
}
w.Stop();
RooArgSet * params = pdf.getParameters(xvars);
params->Print("v");
delete params;
std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;
std::cout << "\n************************************************************\n";
return iret;
}
// unbin fit
template <class MinType>
int DoFit(TTree * tree, Func & func, bool debug = false, bool = false ) {
ROOT::Fit::UnBinData d;
// need to have done Tree->Draw() before fit
FillUnBinData(d,tree);
//std::cout << "Fit parameter 2 " << f.Parameters()[2] << std::endl;
ROOT::Fit::Fitter fitter;
fitter.Config().MinimizerOptions().SetPrintLevel(2);
fitter.Config().SetMinimizer(MinType::name(),MinType::name2());
fitter.Config().MinimizerOptions().SetTolerance(1.); // to be consistent with RooFit
if (debug)
fitter.Config().MinimizerOptions().SetPrintLevel(3);
// create the function
fitter.SetFunction(func);
// need to fix param 0 , normalization in the unbinned fits
//fitter.Config().ParSettings(0).Fix();
bool ret = fitter.Fit(d);
if (!ret) {
std::cout << " Fit Failed " << std::endl;
return -1;
}
if (debug)
fitter.Result().Print(std::cout);
return 0;
}
template <class MinType, class FitObj>
int FitUsingNewFitter(FitObj * fitobj, Func & func, bool useGrad=false) {
std::cout << "\n************************************************************\n";
std::cout << "\tFit using new Fit::Fitter\n";
std::cout << "\tMinimizer is " << MinType::name() << " " << MinType::name2() << std::endl;
int iret = 0;
TStopwatch w; w.Start();
#ifdef DEBUG
func.SetParameters(iniPar);
iret |= DoFit<MinType>(fitobj,func,true, useGrad);
#else
for (int i = 0; i < nfit; ++i) {
func.SetParameters(iniPar);
iret = DoFit<MinType>(fitobj,func, false, useGrad);
if (iret != 0) break;
}
#endif
w.Stop();
std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;
std::cout << "\n************************************************************\n";
return iret;
}
double gausnorm(const double *x, const double *p) {
//return p[0]*TMath::Gaus(x[0],p[1],p[2]);
double invsig = 1./p[1];
double tmp = (x[0]-p[0]) * invsig;
const double sqrt_2pi = 1./std::sqrt(2.* 3.14159 );
return std::exp(-0.5 * tmp*tmp ) * sqrt_2pi * invsig;
}
int main() {
TTree tree("t","a large Tree with many gaussian variables");
fillTree(tree);
// set initial parameters
for (int i = 0; i < N; ++i) {
iniPar[2*i] = 1;
iniPar[2*i+1] = 1;
}
// start counting t he time
MultiGaussRooPdf multipdf(N);
RooAbsPdf & pdf = multipdf.getPdf();
std::auto_ptr<RooArgSet> xvars = multipdf.getVars();
WrapperRooPdf wpdf( &pdf, *xvars );
std::cout << "ndim " << wpdf.NDim() << std::endl;
std::cout << "npar " << wpdf.NPar() << std::endl;
for (unsigned int i = 0; i < wpdf.NPar(); ++i)
std::cout << " par " << i << " is " << wpdf.ParameterName(i) << " value " << wpdf.Parameters()[i] << std::endl;
FitUsingNewFitter<TMINUIT>(&tree,wpdf);
// reset pdf original values
wpdf.SetParameters(iniPar);
FitUsingRooFit(tree,pdf, *xvars);
// in case of N = 1 do also a simple gauss fit
// using TF1 gausN
if (N == 1) {
ROOT::Math::WrappedParamFunction<> gausn(&gausnorm,2,iniPar,iniPar+1);
FitUsingNewFitter<TMINUIT>(&tree,gausn);
}
}
| Subversion Admin | ViewVC Help |
| Powered by ViewVC 1.0.9 |