Home | News | Documentation | Download

Trouble integrating over range


I’m trying to integrate a PDF over a range to get the fraction of the PDF within that range, but I always get 1. My script is something like

RooRealVar jpsi_m("jpsi_m","M_{J/#psi}",3036,3156, "MeV");
RooRealVar phi_m("phi_m","M_{#phi}",1005,1035, "MeV");
//1D PDF's
RooCrystalBall signal_jp_cb("signal_jp_cb", "signal_jp_cb PDF", jpsi_m, <CrystallBall parameters>);
RooBreitWigner signal_p_bw("signal_p", "signal_p PDF", phi_m, ,BreitWigner parameters>);
//2D PDF's
RooProdPdf signal_cb_bw("signal_cb_bw", "signal PDF CBxBW", signal_jp_cb, signal_p_bw);
RooUniform bg("bg", "bg PDF", RooArgSet(jpsi_m, phi_m));
RooAddPdf model_cb_bw("model_cb_bw", "model CBxBW+U", RooArgList(signal_cb_bw, bg), RooArgList(nsig, nbg));

//Get integral
jpsi_m.setRange("mass_window", 3036, 3156);
phi_m.setRange("mass_window", 1005, 1035);
RooAbsReal *integrated_model_jpsi_phi = signal_cb_bw.createIntegral(RooArgSet(jpsi_m, phi_m), NormSet(RooArgSet(jpsi_m, phi_m)), Range("mass_window"));
Double_t integral = integrated_model_jpsi_phi->getVal();

I’d expect integral to be something between 0 and 1, but it’s always 1. It seems that the integrand normalization is performed using only the range defined in the RooRealVar constructors. How can I correctly normalize the integrand (such that it is 1 only when integrated over (-inf, +inf))?

Thank you in advance,

Hi @lmeyerga ,
sorry for the high latency, we need @moneta 's help here. Let’s ping him.


I am not sure I have understood what you would like to do exactly. If you provide a normalised pdf ask its integral the result will be 1. You are maybe interested in the integral in a sub-range. Note also that the RooAddPdf requires in its definition that the pdf’s are normalised in their given range. If you want the expected events in a subrange, then the function to call is RooAbsPdf::expectedEvents.


Yes, I’m interested in the integral of the PDF in a sub-range. I wish to find the fraction of the PDF area that is within this sub-range.
My first (naive) thought was that, since PDF’s are normalized to 1, simply integrating over the sub-range would give me the ratio I want.
Is there a way to normalize a PDF such as a Gaussian such that their full integral (from -inf to +inf) is 1?


Then in this case, it is simple. Define the initial range between -inf and +inf and then a different range when creating the integral function. Here is a simple example:

RooWorkspace w;
w.factory("Gaussian::pdf(x[-inf,inf],m[0],s[1])");   // here I define x in [-inf,+inf]
auto pdf= w.pdf("pdf");
auto x = w.var("x");
auto integral = pdf->createIntegral(*x,RooFit::NormSet(*x),RooFit::Range("range"));

That worked, thanks!