Roofit pdf normalization integration


I believe the reason my NLL is taking so long to getVal() is that there are many numerical integrations. I have a RooAddPdf and many of the constituent Pdfs are not analytical but are constructed as a RooHistPdf.
However, many RooHistPdfs are generated from the same RooDataHist which does not change. Once the pdfs are created, they are only shifted horizontally and scaled vertically in the model, so it seems that RooFit should not have to numerically integrate many times, but instead integrate once and reference that many times since these constituent pdfs are all just A*f( x+a) with the same underlying f(x).

Is there a way to make roofit normalize this way or is there a better method than RooHistPdf that I should be using?

I don’t have a smaller, reproducible example code, but it would be pretty similar to fitting several gaussian peaks on an exponential background, but rather than gaussians, I have a high resolution histogram that represents what the shape should be

_PYROOT Version: 6.26.10
Platform: Not Provided
Compiler: Not Provided


I guess @jonas can help.

Hi @JayR!

Thanks for raising this point.

I’m not aware of any way to work around the numeric integration of RooHistPdfs when you have a shifted observable like this, at least not in the existing ROOT releases.

There is the RooLinearVar class that seems to be suitable for this usecase, but if you use it as the input of a RooHistPdf you will still see that numeric integration is happening. You can run this code to try:

    RooRealVar x{"x", "x", 0, -10, 10};
    x.setBins(10);

    RooDataHist dataHist("dataHist", "dataHist", x);
    for(int i = 0; i < x.numBins(); ++i) {
       dataHist.set(i, 10.0, 0.0);
    }

    RooRealVar shift{"shift", "shift", 2.0, -10, 10};
    RooRealVar slope{"slope", "slope", 1.0};
    RooLinearVar xShifted{"x_shifted", "x_shifted", x, slope, shift};

    RooHistPdf pdf{"pdf", "pdf", xShifted, x, dataHist};

    RooRealIntegral integ{"integ", "integ", pdf, x};
    integ.getVal(); // trigger evaluation

The good thing is that I’m about to fix this in the ROOT development branch:

You will therefore be able to do execute your fit without numeric integration with the next ROOT patch release, which is 6.28.00.

By the way, the reason why you can’t use a general RooFormulaVar but have to use the RooLinearVar is that for a general non-linear variable transformation, the integral of the function can’t be computed analytically anymore because one would have to do integration by parts which RooFit can’t do.

I hope this helps, let me know if you have more questions!

Jonas

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