Hello,
I am using ROOT Version 5.19/03
On a CentOS 5 machine.
I am having trouble changing the Objective Function for Fumili minimization.
I have checked the examples in the tutorials such as minuit2FitBench.C, but I can’t find an example of changing the objective function.
Essentially, I am trying to do what the comment says on line 133 of FumiliChi2FCN.h
"Calculates the sum of Elements squared, ie the chi-square. The user must
implement in a class which inherits from FumiliChi2FCN the member function
Elements() which will supply the Elements for the sum."
I am compiling using -lMinuit2 -lFumili and it compiles with no errors.
I have copied FumiliStandardChi2FCN.c and FumiliStandardChi2FCN.h to my working directory and renamed them to
MyFumiliStandardChi2FCN.c
MyFumiliStandardChi2FCN.h
I have copied GaussianModelFunction.h to my working directory and changed it to
MyModelFunction.h
//—CASE 1: The Following works--------------------------------
TGraphErrors* mygraph =new TGraphErrors(1000,x,y,ex,ey);
TF1 fit = new TF1(“fit”,fpeaksnumerical,fitrangelower,fitrangeupper,3+2npeaks);
//TVirtualFitter::SetDefaultFitter(“Fumili2”);
TVirtualFitter::SetDefaultFitter(“Fumili”);
TVirtualFitter::Fitter(mygraph,10+2*npeaks);
fit-> Set and Fix parameters …
…
int fitResult = mygraph->Fit(“fit”,“NBR”);
//------------------------------------------------------
//—CASE 2: The following does NOT work------------------------
#include “MyFumiliStandardChi2FCN.h”
#include “MyModelFunction.h”
…
TGraphErrors* mygraph =new TGraphErrors(1000,x,y,ex,ey);
TF1 fit = new TF1(“fit”,fpeaksnumerical,fitrangelower,fitrangeupper,3+2npeaks);
//TVirtualFitter::SetDefaultFitter(“Fumili2”);
TVirtualFitter::SetDefaultFitter(“Fumili”);
TVirtualFitter::Fitter(mygraph,10+2*npeaks);
std::vector params(9);
ROOT::Minuit2::MyModelFunction *modelfunc = new ROOT::Minuit2::MyModelFunction(params);
std::vector meas(1000);
std::vector pos(1000);
std::vector mvar(1000);
for (int i=0;i<1000;i++){
pos[i] = x[i];
meas[i] = y[i];
mvar[i] = ey[i];
}
ROOT::Minuit2::MyFumiliStandardChi2FCN *myObjective = new ROOT::Minuit2::MyFumiliStandardChi2FCN(*modelfunc,meas,pos,mvar);
TVirtualFitter::Fitter(mygraph)->SetFCN(myObjective);
TVirtualFitter::Fitter(mygraph)->SetUserFunc((TObject*)modelfunc);
//TVirtualFitter::Fitter(ourTGTwaveform)->SetUserFunc(fit);
int fitResult = mygraph->Fit(“fit”,“NBRU”);
//------------------------------------------------------
//===CASE 3: This does NOT work===============================
I found in older versions of ROOT, a function called GraphFitChisquareFumili.
I copied and pasted this into my program:
extern void GraphFitChisquareFumiliModified(Int_t &npar, Double_t * gin, Double_t &f,
Double_t *u, Int_t flag);
//______________________________________________________________________________
void GraphFitChisquareFumiliModified(Int_t &npar, Double_t * gin, Double_t &f,
Double_t *u, Int_t flag)
{
same as original
}
…
same as CASE 1, but with:
TVirtualFitter::Fitter(mygraph)->SetFCN(GraphFitChisquareFumiliModified);
and
int fitResult = mygraph->Fit(“fit”,“NBRU”);
This one compiles, but fails with Segmentation Violation at runtime:
//============================================================
Question 1:
When using SetDefaultFitter(“Fumili2”) in CASE 2 I get the following error:
Error in : FumiliMinimizer: Error : wrong FCN type. Try to use default minimizer
How can this be, since myObjective is of a class which is a copy and paste of FumiliStandardChi2FCN.
Question 2:
To test if the new objective function is called, I uncommented line 48 in MyFumiliStandardChi2FCN.c
and changed this->getModelFunction() to this->ModelFunction()
std::cout << "element " << i << " " << (*(this->ModelFunction()))(par, currentPosition) << " " << fMeasurements[i] << " " << result[i] << std::endl;
But nothing is printed to the terminal.
I used:
->SetFCN(myObjective)
and
->Fit(“fit”,“U”);
and I’ve tried the calls to
->SetUserFunc(…)
shown above.
How do I get my fitter (Fumili) to use my user specified objective function?
Thanks,
Anthony