Is fit validity or minimizer status more important?


ROOT Version: 6.10/04 (running on LXPLUS)
Platform: SL6 (LXPLUS)
Compiler: g++ 6.2.0 (presumably, I’m not sure how to get that from root-config)


In PyROOT I’m constructing a ROOT::Fit::Fitter and then attempting to perform a fit with MINOS uncertainties.

I am performing fits to generated toys in a loop, so to ensure that the fit to the toy is good and should be kept I have been checking the status of the FitResult

# This is happening in the loop after the fit
if fitresult.Status() != 0:
    # https://root.cern.ch/root/htmldoc/ROOT__Minuit2__Minuit2Minimizer.html#ROOT__Minuit2__Minuit2Minimizer:Minimize
    # > Return false in case the minimization did not converge. In this case a
    # > status code different than zero is set
    print('Skipping toy {} as result of bad QCD only fit'.format(toy))
    continue

For some of the fit functions I am using everything seems, however, there are some functions I am using that are returning a fit status of 1 (meaning that the “Covariance was made pos [definite]”) yet the FitResult.IsValid() is returning True. As the doc string for FitResult.IsValid contains

True if fit successful, otherwise false. A fit is considered successful if the minimizer succeeded in finding the minimum. It could happen that subsequent operations like error analysis (e.g. Minos) failed. In that case the status can be still true if the original minimization algorithm succeeded in finding the minimum. One can query in that case the minimizer return status using Status(). It is responsibility to the Minimizer class to tag a found minimum as valid or not and to produce also a status code.

then I would interpret this to mean that as long as FitResult.IsValid is True then FitResult.Status values that are not 0 can be safely ignored. Is this correct?

For some additional information, here is some verbose output on an example fit result that is demonstrating this (for context, Par_0 through Par_4 are parameter of a function meant to model a QCD distribution and Par_5 is the normalization on a MC template which was injected with norm of 1):

fitresult.Print('V')
print('\nFit validity: {}'.format(fitresult.IsValid()))
print('\nFit minimizer result status: {}\n'.format(fitresult.Status()))

producing

****************************************
Minimizer is Minuit2 / MigradImproved
MinFCN                    =      15.8384
NDf                       =            0
Edm                       =   6.7771e-07
NCalls                    =          247
Par_0                     =   -0.0636224   +/-   0.00164917   	 (limited)
Par_1                     =    -0.392449   +/-   0.00360362   	 (limited)
Par_2                     =      2.72153   +/-   0.00486751   	 (limited)
Par_3                     =     -3.62766   +/-   0.00598018   	 (limited)
Par_4                     =      1.54444   +/-   0.00507965   	 (limited)
Par_5                     =     0.849186   +/-   0.112128     	 (limited)

Covariance Matrix:

            	       Par_0       Par_1       Par_2       Par_3       Par_4       Par_5
Par_0       	  2.7198e-06  -4.651e-06 -1.2967e-06  1.3788e-06  2.1181e-06  1.4973e-05
Par_1       	  -4.651e-06  1.2986e-05 -6.8913e-06 -3.8554e-06  1.9842e-06 -1.8918e-06
Par_2       	 -1.2967e-06 -6.8913e-06  2.3693e-05 -1.0892e-05 -5.3195e-06 -4.0718e-05
Par_3       	  1.3788e-06 -3.8554e-06 -1.0892e-05  3.5763e-05 -2.2287e-05 -6.2057e-05
Par_4       	  2.1181e-06  1.9842e-06 -5.3195e-06 -2.2287e-05  2.5803e-05 -1.2412e-05
Par_5       	  1.4973e-05 -1.8918e-06 -4.0718e-05 -6.2057e-05 -1.2412e-05    0.012573

Correlation Matrix:

            	       Par_0       Par_1       Par_2       Par_3       Par_4       Par_5
Par_0       	           1     -0.7826    -0.16153     0.13981     0.25283    0.080971
Par_1       	     -0.7826           1    -0.39288     -0.1789     0.10839  -0.0046819
Par_2       	    -0.16153    -0.39288           1    -0.37418    -0.21514   -0.074604
Par_3       	     0.13981     -0.1789    -0.37418           1    -0.73367   -0.092546
Par_4       	     0.25283     0.10839    -0.21514    -0.73367           1   -0.021792
Par_5       	    0.080971  -0.0046819   -0.074604   -0.092546   -0.021792           1

Fit validity: True

Fit minimizer result status: 1

Hi,

They are both relevant. The valid flag tells you have reached a minimum, but the minimiser status returns (for some of the minimiser such as Minuit) more information.
For example using Minuit2 you have as status:

  • status = 1 : Covariance was made pos defined
  • status = 2 : Hesse is invalid
  • status = 3 : Edm is above max
  • status = 4 : Reached call limit
  • status = 5 : Covariance is not positive defined

For status=0 or 1 the fitted status will be valid, while in the other cases (status=2,3,4,5) it will not be.

Lorenzo

2 Likes

@moneta Thanks for the response. Yes, this was clear. My question pertains to the case when you have a fit that returns fitresult.IsValid() of True and fitresult.Status() of 1 (indicating that the covariance matrix had to be forced to be positive definite). So as you said that

For status=0 or 1 the fitted status will be valid

my question is should I worry too much about the fact that a valid fit had to have its covariance matrix forced ? Or as long as it is valid is that okay?

2 Likes

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