Accessing overall fit status in RooFit

Hi all,

I’m performing a large number of toy MC fits. To evaluate them, I need to be sure the fits converged with no errors. From the previous postings I see there’s currently no easy way to access a “global” status, such as “ok” if all steps involved in fitting succeeded, “problems” otherwise. May I request this feature?

In particular, I have a fit for which a “grep STATUS” returns

FCN=-1.23972e+06 FROM MIGRAD STATUS=INITIATE 88 CALLS 89 TOTAL FCN=-1.23973e+06 FROM HESSE STATUS=OK 417 CALLS 4277 TOTAL FCN=-1.23973e+06 FROM MIGRAD STATUS=FAILED 4837 CALLS 4838 TOTAL FCN=-1.23973e+06 FROM HESSE STATUS=OK 403 CALLS 5241 TOTAL FCN=-1.23973e+06 FROM MIGRAD STATUS=INITIATE 50 CALLS 5291 TOTAL FCN=-1.23973e+06 FROM HESSE STATUS=OK 445 CALLS 6247 TOTAL FCN=-1.23973e+06 FROM MIGRAD STATUS=CONVERGED 1468 CALLS 6709 TOTAL FCN=-1.23973e+06 FROM MINOS STATUS=SUCCESSFUL 3162 CALLS 9871 TOTAL

I’m sure the fit result is bad, since the error of one paramter is ~35 lower than the expectation from the other fits in the toy series. I’d like to exclude such fits without depending on parsing of the logfile.

Any ideas?

  • Moritz

Hi Moritz,

The fit status is part of RooFitResult, which is returned by fitTo() if a Save() argument
is passed

                                         Wouter

— from RooFitResult.h —

// Accessors
inline Int_t status() const {
// Return MINUIT status code
return _status ;
}
inline Int_t covQual() const {
// Return MINUIT quality code of covariance matrix
return _covQual ;
}
inline Int_t numInvalidNLL() const {
// Return number of NLL evaluations with problems
return _numBadNLL ;
}
inline Double_t edm() const {
// Return estimated distance to minimum
return _edm ;
}
inline Double_t minNll() const {
// Return minimized -log(L) value
return _minNLL ;
}

Hi Wouter,

Yes, I know. But it only returns the status of the last fit operation. In my case, the last one succeeds, so all of the above look fine. The only hint I get from the logfile is the one failing MIGRAD step at the beginning…

  • Moritz

Hi Moritz,

If you use the RooMinuit interface directly instead of fitTo(), you
can check the status after every step.

I.e. instead of pdf->fitTo(data,…) ;

you can do

RooAbsReal* nll = pdf->createNll(data,...) ;
RooMinuit m(*nll) ;
m.migrad() ;
RooFitResult* r = m.save() ;
m.hesse() ;
RooFitResult* r2 = m.save() ;
delete nll ;

The options that control the likelihood definition in fitTo() can be passed identically
to createNll() [ e.g. Extended(),ConditionalObservables() ]

Wouter

1 Like

Ok, then I have another question:

In my example MIGRAD and HESSE are called multiple times within one call to fitTo(). What’s the algorithm behind this? If it is done inside fitTo() I would have to replace it by something like

RooAbsReal* nll = pdf->createNll(data,…) ;
RooMinuit m(*nll) ;
m.migrad() ;
m.hesse() ;
m.migrad() ;
m.hesse() ;
m.migrad() ;
m.hesse() ;
m.migrad() ;
m.minos() ;

?

This would be hard to control…

  • Moritz

Hi Moritz,

At the minuit interface level, the call sequences is

  1. MIGRAD
  2. HESSE
  3. MINOS

where step3 is optional (steered by Minos() option in fitTo()).

Occasionally HESSE may decide on its own to call MIGRAD again, e.g. when it believes that there may be another better minimum. I don’t know of any way to retrieve the status code of those internal steps, as the’re not published afaik through the TMinuit or TVirtualFitter interface.

Wouter

Mmmh, too bad.

Thanks anyway, Wouter!

  • Moritz