Home | News | Documentation | Download

Value of PDF in RooFit

I’m sorry for the repeat of what is probably an oft asked question, but I keep finding different answers that don’t quite fit what I’m asking

If I define just a random PDF in RooFit, how do I access the values of the PDF? I understand that the values of the PDF at a given point are innately linked to the integral of the pdf which is left purposefully undefined, but if I wanted those values for a given integral value (unity or 1 is the obvious example), how would I go about getting the value?

I’ve seen one possible solution is plotting it, getting the curve, and then just evaluating the RooCurve at a given point, but this seems unnecessary if I’m just checking the value of a maximum or minimum. For the sake of having an example, I’ll post it here.

ForumPost.C (615 Bytes)

Thanks for the help.

@StephanH can you please take a look here?

Hi @usccaa,

It’s much easier than plotting it:

  • pdf.getVal() returns an unnormalised value. The normalisation is arbitrary, i.e. the pdf class can choose the magnitude of what is returned. However, when you evaluate for different values of the pdf’s parameters, it’s guaranteed that the relative difference between the results is correct.
  • pdf.getVal(x) returns a normalised value. It returns the value you get from getVal(), but in addition, the pdf is integrated over x, and the result is divided by that integral.
  • pdf.getVal(RooArgSet(x, y, z)) returns the above, but the pdf is integrated over x, y and z to compute the normalisation.

Example:

root [0] RooRealVar x("x", "x", -10, 10) // create an observable with a range of 20
(RooRealVar &) RooRealVar::x = 0  L(-10 - 10) 

root [1] RooUniform uni("uni", "Uniform distribution over x", x)
(RooUniform &) RooUniform::uni[ x=(x) ] = 1

root [2] uni.getVal()
(double) 1.0000000
root [3] uni.getVal(x) // shorthand notation for root[4] below
(double) 0.050000000
root [4] uni.getVal(RooArgSet(x))
(double) 0.050000000

As you can see, when normalising, the uniform distribution is integrated over x from -10, 10, so it has to be normalised with 1/20.
More about normalisation in the tutorial rf110:
https://root.cern.ch/doc/master/rf110__normintegration_8C.html

This makes good sense, and is clearly the base solution.

One further question: is it possible to normalize to a value other then unity over the specified range? Or is your option just to scale by multiplying by whatever your scale factor is after the fact?

The simple answer is no, it’s always normalised to unity. The reason is that for likelihood fits, you need probabilities. To obtain probabilities, you need to normalise to unity.
However, if you want to measure a normalisation, there’s extended likelihood, and that will look like you normalised to something else.
https://root.cern.ch/doc/master/rf202__extendedmlfit_8C.html