Fit of unbinned data: minimizer error for Minuit/Fumili

ROOT Version: 6.18.02
Platform: ubuntu 18.04 LTS on WSL10

Dear experts,
I am trying to fit unbinned data as described in the user guide. I am not using RooFit (not that I understand at least).

I am having the following error with Minuit (note that it seems to work with Fulmili but one of the parameters diverges if left unlimited)

Error in ROOT::Math::FitResult: FitConfiguration and Minimizer result are not consistent
Number of free parameters from FitConfig = 5
Number of free parameters from Minimizer = 0

Here is some chunk of code I have been writing:
ROOT::Fit::UnBinData data(nevt, x);

TF1 *fitFunc = new TF1(“fitFunc”, myfunc, (double) (xmin), (double) (xmax), 8);

ROOT::Math::WrappedMultiTF1 fitFunction(*fitFunc, fitFunc->GetNdim() );

ROOT::Fit::Fitter fitter;

fitter.SetFunction( fitFunction, false);

//… initialisation of parameters in std::vectorROOT::Fit:ParameterSettings parset (8)
// 3 over 8 parameters are fixed, 3 used for normalization → 5 are free

fitter.Config().SetParamsSettings(parset);

fitter.Config().SetMinimizer(“Minuit”); // Fumili seems to work but seems to diverge for the last parameter. If parset.at(7) is fixed the result is ok.

fitter.Config().SetUpdateAfterFit();

fitter.LikelihoodFit(data);

→ Here comes the pb

Hi,

Looking at your message, the problem seems in the number of parameters passed to the minimiser.
Your code seems fine, but I would need the full running code, to understand what is happening

Thank you

Lorenzo

Dear Lorenzo,
thanks for the quick reply. In the mean time I found out:

  • that the fit works fine if I am passing the parameters via a fitter.Config().SetParamsSettings(8, par) and set the individual limits using fitter.Config().Parsettings(i).SetLimits(lowerlimit, upperlimit) (or Fix() for some parameters)
  • that the divergence of the last parameter with Fumili (and Minuit as well since now it is also working) was most likely due to a deficient normalization of my function (as I understand a common mistake that one can do when fitting unbinned data)

Now everything is ok on my side, except maybe that the initial problem I got is not clear to me.
Somehow in using the command fitter.Config().SetParamsSettings(parset) the minuit minimizer was missing the number of expected parameters. Does it make sense to you? Should I have indicated it somewhere explicitely?

I was using the following lines for initialising the vector of parameters parset:
parset.at(2).Set(“tof1”,par[2], 0, par[2] - 3par[3], par[2] + 3par[3]);
This worked fine as I could retrieve the parameters in printing them out:
std::vectorROOT::Fit::ParameterSettings parbid = fitter.Config().ParamsSettings(); // for debugging and display of initial parameters
printf(“Initial parameters: parbid \n”);
for ( int i=0; i<8; i++ )
printf(“Name %s initial value %f fixed? %i\n”, parbid.at(i).Name().c_str(), parbid.at(i).Value(), parbid.at(i).IsFixed());

If you need the whole code I’ll have to clean it a bit for you. I can also only send the relevant part.

A last question maybe, on the way one should do these fits. I am not familiar with RooFit/RooStats, is this supposed to replace or complement the standard ROOT::Fit minimizers, for complicated statistical problems or so? If I want to do a Smirnov Kolmogorov goodness of fit test for my function, what should I preferably use?

Thanks a lot,
Best
Pierre

Hi,
It is weird that FitConfig::SetParamsSettings did not work .Please share at least the relevant code, so I can look at it. In case I will let you know if I need to run it

For the other questions:

  • RooFit complements the standard fitting in ROOT. Actually it uses internally the Fitter class to perform the minimisation. If you are fitting a simple data set (e.g. an histogram) it is not worth using RooFit, but if you start building a complex model and fitting different datasets, then it is worth using it.
  • For using the KS test for comparing data and a function, you can use the ROOT::Math::GoFTest class, see ROOT: ROOT::Math::GoFTest Class Reference

Best

Lorenzo

Dear Lorenzo,
Here is the routine which shows the problem when a vector of parameters “parset” is passed via Fit.Config().ParamsSettings(parset)

It is fitting a double gaussian over a flat background whose value depends on whether it comes before or after the gaussians.

What I do is a standard fit of binned data to get the initial rough parameters (stored in par) and refit the data with unbinned data with the normalized pdf (constant integral close to 1), which is what is shown here.

The fit works when passing the parameters using Fit.Config().ParamsSettings(7, parn), where double parn[7] is adapted from double par[8].

Let me know if this is sufficient or if need more material.

Thanks a lot for the tips concerning RooFit/RooStats, and the KS test!

Best,
Pierre

unbinfit.c (6.5 KB)

Hi,
Thank you for the code. I see now the problem.
When you call fitter.Config().SetParamsSettings(parset) you pass a new vector of fit ParameterSettings, and those will be used in the fit. The problem is that the new parameter settings that you define they have all a step size of zero. See how you call ROOT::Fit::ParameterSettings::Set
(ROOT: ROOT::Fit::ParameterSettings Class Reference). This makes the parameter constant and they will be removed from the following fit.
Note , that when calling Fitter::SetFunction the parameter settings are already created and you need to just set maybe the initial values or limits and/or fix them.

Lorenzo

Dear Lorenzo,
Sorry for the slow feedback.
many thanks for resolving the problem, it works! it was indeed the issue.

Pierre