# How to make a 2 dimensional likelihood profile

Hi experts,

I am trying to perform a 2D likelihood profile vs 2 fitting variables.
The fit is minimizing let’s say var1, and var2, which are used and expected to correlate in some extent via Multi-Dimensional constraints applied to other variables in the fit dependent from var1,var2.

Our fitter, is creating from say N datasets, N likelihoods and then they are all summed up and External - or Multi-D gauss constraints are added to the likelihood.

The code we have looks like this :

``````//make a list of likelihoods to sum
RooArgSet _nLL;
//Create and fill ArgSet
CreateNLL(_nLL);
//Sum up the Likelihoods
//Invoke the minimizer
RooMinimizer _minimizer(_nllSimultaneous);
//Configure the Minimizer
ConfigureMinimizer(_minimizer, m_name + "_PlotContour.log");
FittingProcedure(_minimizer, &_nllSimultaneous);
``````

Let’s say i have now 2 observables ( var1,var2) ;
And i want to make a 2D likelihood profile.
Is this code executed afterwards correct?

``````    if( _nllSimultaneous.dependsOn( _var1) && _nllSimultaneous.dependsOn( _var2) ){
_var1.setRange(_var1.getVal() - _var1.getError() * 3.5, _var1.getVal() + _var1.getError() * 3.5);
_var2.setRange(_var2.getVal() - _var2.getError() * 3.5, _var2.getVal() + _var2.getError() * 3.5);
_minimizer.minos(RooArgSet(_var1, _var2));
RooPlot * _frame = _minimizer.contour(_var1, _var2, 1, 2, 3);
}
``````

I.e to make the 2D 1,2,3 sigma level contour, do i need to run Minos on both observables ?
Am i missing something basic here?
To be clear, i saw that there is now a `ProfileLikelihood` root class available, however we are not using RooStats and i am not sure if I can easily/fastly port our fitter to use RooWorkSpaces and if in the fact we keep list<1model, 1dataset> summation in our fitter, can be problematic to use that class.
Any suggestion/help is more than welcome.
Cheers
Renato

Hi ,
Minos will compute 1D intervals for the parameters you pass and not the 2D contours. To make the desired contours you need to use `RooMinimizer::contour(...)` or if you need the lower level function `minimizer.fitter().GetMinimizer().Contour(..)` after having defined the wanted level with `Minimizer::SetErrorDef(..)`

Lorenzo

Hi @moneta
I am using as reference this example here :

Minos is run over only 1 of the 2 observables, and the contour on both.
Do I understand correctly that then the call to Minos() [ if before one has run Migrad and Hesse ] is useless?
Cheers
Renato

I tried all cases, no changes. So i conclude execute Minos to get a contour beforehand is useless, except if one wants to get the asymmetric errors on the parameter of interest.
Thanks again @moneta. Just a last question, is there a way to control the speed of the `contour` method ?
I.e let’s say, if my default takes 2 hours, and i want to do a fast test, how can i control it?
I am failing to understand what `SetErrorDef` does :

``````set scale for calculating the errors
``````

, if i set to 2 is it going to be faster than 1 ?
Apologize for the dummy question.

Hi,

Minos is for 1D and it is not needed before making a contour. Internally they use the same Minuit class, MnFunctionCross, to find the profile likelihood values.

SetErrorDef affacts only the level of the function, not the speed. This can be tuned using less points for the contour, the parameter `npoints` in `Minimizer::Contour`.
However you cannot do a 2d contour with too few points. Unfortunately we don’t have yet a parallel implementation and making a contour requires several minimizations, which can take a log time in a big model

Lorenzo

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.