How to make RooAbsPdf derived class extendable

Hi, I would like to write a class called A that inherits from RooAbsPdf, and is usable inside an extended RooAddPdf. To calculate the normalization, I have another class called B that inherits from RooAbsReal. My question is: what methods need to be implemented to allow A and B to be used in an extended likelihood fit within a RooAddPdf?

Here is a minimal example of what I would like to do (add AB + GausNorm):

# Gaussian:
gaus = RooGaussian("gaus","gaus",x,m,s);
norm = RooRealVar("norm","norm",100);
# New PDF
pdfA = A()
varB = B()
# RooAddPdf
model= RooAddPdf(  

Do I need to implement expectedEvents in the RooAbsPdf? Does expectedEvents from RooAddPdf represent the number used in the fit, or does pdf.createIntegral()->getVal()? Thanks.

What I see in your code already seems to extend the PDF. When you give as many scale parameters as PDFs to RooAddPdf, it automatically treats them as extended.
The PDF that’s being used in the sum does not need to be extendable.

I tried to make this a bit more clear in the new RooAddPdf doxygen page:

Does this solve your problem?

Hi @StephanH, thanks for your response. I can fill in some more details. In the attached plot, I find a disagreement between what RooAddPdf::getVal() returns and what I expect. “Real Sum” shows the sum of [pdfA normalized to varB.getVal()] + [gaus normalized to norm]. “RooAddPdf” shows the output from model normalized to model.expectedEvents().

However, when I look at model.expectedEvents(), I find that this is equal to varB.getVal()+norm.getVal().

So my question really is: why aren’t these consistent? I think I’m missing something about what RooAddPdf is doing such that my assumption that these should be the same is not correct. Thanks very much for your help.

What you see might be the difference between getVal() and getVal(RooArgSet(x)).
For speed reasons, RooFit skips normalising PDFs when you call getVal() without any argument. You could also say that it’s not clear what should be integrated over to normalise. If you supply a set of variables to integrate over, you get the normalised value.

Does this answer the question or is there still more that we need to investigate?

Hi @StephanH, thanks very much for the help! Indeed I did a comparison between getVal() and getVal(RooArgSet) and it does seem to explain the difference. My only question now is: do I have to worry about this when doing a fit with RooAddPdf?

To illustrate, I have a comparison between getVal() and getVal(RooArgSet) plotted. It appears that the getVal() version (red line) normalizes the gaussian component differently than the getVal(RooArgSet) (black line). Is there a chance that the fit would be using the default PDF (red line) instead of the “correctly normalized” one?

Thanks for helping with this.

No, during fitting, the PDFs are always normalised. That’s why a dataset in RooFit needs to know what its variables are.

1 Like

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