RooFit minos errors for 2 parameters of interest


I wanted to take the minos errors for my parameter estimates that I get from my fit. I had two parameters of interest, and decided to check if I understood what it was doing correctly by seeing if the minos errors correspond to the 2.3 contour of 2*profileLL.

I made a simple model with what I believe is two degrees of freedom: two poissons multiplied together. I ran the fit and draw the RooFitResult’s errors. Then I drew the profileLL with appropriate contours. I see that the RooFitResult errors (the minos errors) correspond to the 2*profileLL = 1.0 (the case for 1 degree of freedom), but I expected for two degrees of freedom to see them correspond to the 2.3 contour.

Does somebody know if I have misunderstood the Minos option’s behaviour? Or have I made some other mistake?


   using namespace RooFit;
   RooWorkspace w;
   RooDataSet data("data","data",*w.set("obs"));

   RooAbsReal* nll = w.pdf("model")->createNLL(*"data"));
   RooAbsReal* pll = nll->createProfile(*w->set("poi"));

   RooFitResult* f = w->pdf("model")->fitTo(*w->data("data"),Minos(*w->set("poi")),Save(),Hesse(false));
   RooPlot* fr = new RooPlot(30,80,0,50);

   TH1* pllHist = pll->createHistogram("pllHist",*w.var("mean_1"),Binning(50,30,80),YVar(*w.var("mean_2"),Binning(50,0,50)),Scaling(false));

   double myContours[4] = {0.5,2.3/2,6.18/2,11.83/2};
   pllHist->Draw("CONT2 same");

As a follow up question, if I am correct in my interpretation of the Minos error method, and the errors should really be determined from the 2*profileLL=2.30 contour, is there a way to tell RooFit to do this when it does the fit and propagates the errors back to the parameters of interest? Or must I plot the profileLL myself and determine the upper and lower edges of the contour?


You can use RooMinimizer/RooMinuit to minimiser the NLL and use RooMinimizer::setErrorDef(2.3/2);
(the factor of 2 comes to the fact you are minimising the NLL and not 2 * NLL ).

Keep in mind the errors returned correspond to the lower/upper value of the contour and it is valid if you consider the two parameter at the same time. The separate 68% error on each parameter should be computed at
the 0.5 level.

You can use also the RooStats ProfileLikelihoodCalculator class who does this automatically, for the desired confidence level



Thanks. the errorlevel was what i needed, that appears to work!

I have a similar question:

I want to plot two contours at 68% and 90%.
I have a 2-parameters NLL on which I call the contour the contour function:
RooMinuit(*nll).contour(par1,par2, n1, n2)

What values do I have to set for n1 and n2 to get the proper contour?

Does it understand the errors in a gaussian sense
i.e n1=1=> 68% coverage, n2=1.64 =>90% coverage

Or does it assume that 2ΔNLL ~ Chi2 =>
we have to set n1= 2.3/2 (68%) n2=4.6/2 (90%)




RooMinuit::contour(p1,p2,n1,n2) will plot two contours one at n1-sigma and the second one at n2-sigma.
Now in my opinion in 2 dimension the sigma do not make much sense. It is better to think in term of CL.
So a CL of 68 % for a 2D contour requires a 2ΔNLL = Chi2 value of 2.278869
(value obtained from ROOT::Math::chisquared_quantile(0.68,2) ).

A 90% value of the Chi2, ROOT::Math::chisquared_quantile(0.90,2) = 4.605170

so you should do

  sqrt( ROOT::Math::chisquared_quantile(0.68,2) ),
  sqrt( ROOT::Math::chisquared_quantile(0.90,2) ) );



Just to note a small correction (although this may be obvious) that the last line in Lorenzo’s post should read

RooMinimizer minimizer( *nll );

minimizer.contour(par1, par2,
TMath::Sqrt( ROOT::Math::chisquared_quantile(0.68,2) ),
TMath::Sqrt( ROOT::Math::chisquared_quantile(0.9,2) ) );

to obtain 68% and 90% CL contours.

Thanks for the note. I took the liberty to edit the post.