ROOT Version: Not Provided Platform: Not Provided Compiler: Not Provided
I’m fitting some dataset of neutral pion yield with the usual parametrization. The covariance matrix is astonishingly 0 (each entry is very small in terms of machine precision), since the fit errors are not zero.
I checked my code by taking into another dataset which worked well before, then the covariance matrix is not zero. So could somebody tell me what the heck is wrong?
------------------------The following is the dataset that works----------------
I would say make the fit verbose by adding “V” to the options. Then, start reading the output of Minuit. Watch out for things like
Parameters at limit
High correlations
Wrong step sizes
Sometimes, the shape of the likelihood function is just not well behaved because of e.g. highly correlated parameters or wrong data errors. Could it be that the errors of the data points are somehow unreasonable?
Thanks. Good news: after using the verbose mode “V”, it returns to me some EXTERNAL ERROR MATRIX, which seems to be the covariance matrix that I always want (see the terminal report below).
But still the MIGRAD thing didn’t converge, I’m not sure how that happened when everything “seems” to be fine (the fit result seems to agree with my data; and it actually get some reasonable covariance matrix, and just doesn’t want to share it with me, when I print it.).
Now I’m not sure if it’s legitimate to use the EXTERNAL MATRIX as my covariance matrix after all its error-report on MIGRAD divergence.
The following is the terminal report, starting from the second last fit status report:
MINUIT terminates the minimisation because the number of function calls has been limited to 1630. There’s two possibilities:
Allowing for more calls / reducing the required precision / choosing fit strategy 2 (robustness) will let the minimisation finish.
The likelihood function has a weird shape in the minimum (weird data events, outliers, correlations between parameters, fit model that cannot describe the data), and it will infinitely err around the minimum without ever converging. This is the bad case, where I cannot help easily.
The first case can be tested, though:
EDIT I realise that the first answer was only for RooFit. I will look up how to do this in root shortly.
Own fitter ROOT style:
Foption_t fitOption;
ROOT::Fit::FitOptionsMake(ROOT::Fit::kGraph, "<options>", fitOption);
// create range and minimizer options with default values
ROOT::Fit::DataRange range(minRange, maxRange);
ROOT::Math::MinimizerOptions minOption;
minOption.SetMaxIterations(xxx);
minOption.SetMaxFunctionCalls(xxx);
minOption.SetPrecision(xxx);
minOption.SetStrategy(xxx);
auto fitResult = ROOT::Fit::FitObject(<theGraph>, <fitFunction>, fitOption , minOption, "", range);
You can check the documentation for more on minimiserOptions.
The fit options "<option>", which I left empty, are the same as the options in TGraph::Fit().
Own minimiser RooFit style:
Make your own minimiser:
RooAbsReal *nll = model.createNLL(*data);
// Minimize likelihood w.r.t all parameters before making plots
RooMinimizer minimiser(*nll);
// Run gradient descent
minimiser.migrad();
// Estimate erros:
minimiser.hesse();
and before you start migrad(), use these functions to allow for more calls: