Unbinned Log-Likelihood fits

We are trying to implement unbinned Log-Likelihood fits on a histogram, for a function composed of an exponential decay + constant offset + Crystal Ball.
The fit should be within a lower and an upper limit, so not from -infinity to +infinity.

The code works (there’s no error message given), but the fits don’t come out right – most of the parameters are ‘nan’.

Is there something else that we should take into account when using Log-Likelihood fits?
Something to do with normalising the fit function?

Hi,

Yes the function should be normalised if you are doing an unbinned fit.
In case of a binned fit to an histogram it is not needed if you are fitting also the total number of events (extended fit)

Best Regards

Lorenzo

Do we have to manually implement the normalisation? How?

Hi,

Yes, in the current of ROOT you need to define manually the function to be normalised. In the future version it is expected to add this functionality to compute that integral automatically.

Now, if you are using a TF1 class for fitting, you would need to divide the function value by the integral of the function in the range. You would need to define something like this

struct NormalizedFunction { 
   NormalizedFunction(TF1 * f) : fFunc(f) {}
   TF1 * fFunc; 

   double operator() (double *x , double *p) { 
      double xmin,xmax; 
      fFunc->GetRange(xmin,xmax); 
      return fFunc->EvalPar(x,p)/fFunc->Integral(xmin,xmax); 
   }
};
void test() { 
   TF1 * f = new TF1("f","expo",0,5);
   f->SetParameters(1,-1);
   f->SetRange(0,5); 
   TF1 * normFunc = new TF1("normFunc",NormalizedFunction(f),0,5,0);
   std::cout << normFunc->Integral(0,5) << std::endl;
   normFunc->Draw();
}

This is probably fine for a simple fitting. In case of a complex problem is not very efficient, since the integral is calculated every time. One could eventually cache the integral value and re-compute only when the function parameter values change.

Best Regards

Lorenzo