Skip to content

Commit ff91fc0

Browse files
committed
[RF] Forbid integration of a RooAbsRealLValue
Integrating a RooAbsRealLValue like a RooRealVar doesn't work in RooFit, which one can check with this code: ```C++ RooRealVar x{"x", "x", 2.0, -5.0, 5.0}; std::unique_ptr<RooAbsReal> xint{x.createIntegral(x)}; xint->Print(); ``` The integral of x from -5 to 5 should be zero, but the integral object only returns the current value of the variable. Some users expect the integral to work, and give the same result as this, which correctly prints out zero: ```C++ RooRealVar x{"x", "x", 2.0, -5.0, 5.0}; RooProduct xId{"xId", "xId", RooArgList{x}}; std::unique_ptr<RooAbsReal> xint{xId.createIntegral(x)}; xint->Print(); ``` This is assumed in two RooFit unit tests: * [testRooWrapperPdf](https://github.com/root-project/root/blob/master/roofit/roofitcore/test/testRooWrapperPdf.cxx#L27) * [testNestedPDFs](https://github.com/guitargeek/roottest/blob/master/root/roofitstats/vectorisedPDFs/testNestedPDFs.cxx#L45) in roottest Both tests **work only by chance** because the stored x value is the same as its integral! As soon as the x value or limits would change, the results don't make sense anymore. As the integration of RooAbsRealLValues never worked correctly and was not used anywhere outside artificial unit tests, this commit suggests so prohibit the integration of RooAbsRealLValues by throwing an exception if `RooAbsRealLValue::createIntegral()` is called.
1 parent 0de46d4 commit ff91fc0

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

roofit/roofitcore/inc/RooAbsRealLValue.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ class RooAbsRealLValue : public RooAbsReal, public RooAbsLValue {
153153
static TH1* createHistogram(const char *name, RooArgList &vars, const char *tAxisLabel, double* xlo, double* xhi, Int_t* nBins) ;
154154
static TH1* createHistogram(const char *name, RooArgList &vars, const char *tAxisLabel, const RooAbsBinning** bins) ;
155155

156+
RooAbsReal* createIntegral(const RooArgSet& iset, const RooArgSet* nset=nullptr, const RooNumIntConfig* cfg=nullptr, const char* rangeName=nullptr) const override;
157+
156158
protected:
157159

158160
virtual void setValFast(double value) { setVal(value) ; }

roofit/roofitcore/src/RooAbsRealLValue.cxx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,3 +1030,14 @@ bool RooAbsRealLValue::isJacobianOK(const RooArgSet&) const
10301030
// always returns true (i.e. jacobian is constant)
10311031
return true ;
10321032
}
1033+
1034+
1035+
RooAbsReal* RooAbsRealLValue::createIntegral(const RooArgSet&, const RooArgSet*, const RooNumIntConfig*, const char*) const
1036+
{
1037+
std::stringstream errStream;
1038+
errStream << "Attempting to integrate the " << ClassName() << " \"" << GetName()
1039+
<< "\", but integrating a RooAbsRealLValue is not allowed!";
1040+
const std::string errString = errStream.str();
1041+
coutE(InputArguments) << errString << std::endl;
1042+
throw std::runtime_error(errString);
1043+
}

roofit/roofitcore/test/testRooWrapperPdf.cxx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ TEST(RooWrapperPdf, Basics)
2222
RooRealVar a0("a0", "a0", 0.1, 0.1, 10.);
2323
RooRealVar a1("a1", "a1", -0.01, -2.1, 0.);
2424
RooRealVar a2("a2", "a2", 0.01, 0.01, 5.);
25+
RooProduct xId("xId", "x", RooArgList(x));
2526
RooProduct xSq("xSq", "x^2", RooArgList(x, x));
2627
RooConstVar one("one", "one", 1.);
27-
RooRealSumFunc pol("pol", "pol", RooArgList(one, x, xSq), RooArgList(a0, a1, a2));
28+
RooRealSumFunc pol("pol", "pol", RooArgList(one, xId, xSq), RooArgList(a0, a1, a2));
2829

2930
RooWrapperPdf polPdf("polPdf", "polynomial PDF", pol);
3031

@@ -52,15 +53,16 @@ TEST(RooWrapperPdf, GenerateAndFit) {
5253
RooRealVar a0("a0", "a0", 0.1);
5354
RooRealVar a1("a1", "a1", -0.01);
5455
RooRealVar a2("a2", "a2", 0.01, 0.001, 5.);
56+
RooProduct xId("xId", "x", RooArgList(x));
5557
RooProduct xSq("xSq", "x^2", RooArgList(x, x));
5658
RooConstVar one("one", "one", 1.);
57-
RooRealSumFunc pol("pol", "pol", RooArgList(one, x, xSq), RooArgList(a0, a1, a2));
59+
RooRealSumFunc pol("pol", "pol", RooArgList(one, xId, xSq), RooArgList(a0, a1, a2));
5860

5961
RooWrapperPdf polPdf("polPdf", "polynomial PDF", pol);
6062

6163
auto data = polPdf.generate(x, 50000);
6264
a2.setVal(0.02);
63-
auto result = polPdf.fitTo(*data, RooFit::Save());
65+
auto result = polPdf.fitTo(*data, RooFit::Save(), RooFit::PrintLevel(-1));
6466

6567
EXPECT_EQ(result->status(), 0) << "Fit converged.";
6668
EXPECT_LT(fabs(a2.getVal()-0.01), a2.getError());

0 commit comments

Comments
 (0)