Skip to content

[RF] RooBinIntegreator gives wrong result for integrals that cut thought bin boundaries #22858

Description

@guitargeek

The RooBinIntegrator gives wrong results in case the integral boundaries lie within the bin boundaries of the integrand.

Reproducer:

RooRealVar x{"x", "x", 0., 10.};
x.setBins(5); // five bins of width 2: edges at 0, 2, 4, 6, 8, 10

const double heights[5] = {1.0, 3.0, 2.0, 4.0, 1.5};

RooDataHist dh{"dh", "", x};
for (int i = 0; i < 5; ++i) {
   dh.set(i, heights[i], 0.0);
}

// The sub-range [3, 7] deliberately cuts through the bins [2,4] and [6,8].
x.setRange("partial", 3.0, 7.0);

const double binWidth = 2.0;
const double expected = (heights[1] * 1.0 + heights[2] * 2.0 + heights[3] * 1.0) / binWidth; // = 5.5

RooHistPdf analytic{"analytic", "", x, dh, 0};

RooHistPdf numeric{"numeric", "", x, dh, 0};
numeric.forceNumInt(true);

std::unique_ptr<RooAbsReal> integAna{analytic.createIntegral(x, RooFit::Range("partial"))};
std::unique_ptr<RooAbsReal> integNum{numeric.createIntegral(x, RooFit::Range("partial"))};

const double valAna = integAna->getVal();
const double valNum = integNum->getVal();

std::cout << "\n=== integral over the sub-range [3, 7] ===" << std::endl;
std::cout << "  expected (by hand)      : " << expected << std::endl;
std::cout << "  analytic (RooHistPdf)   : " << valAna << std::endl;
std::cout << "  numeric  (RooBinIntegr.): " << valNum << std::endl;

Gives:

=== integral over the sub-range [3, 7] ===
  expected (by hand)      : 5.5
  analytic (RooHistPdf)   : 5.5
  numeric  (RooBinIntegr.): 2

It is expected that the RooBinIntegrator gives the correct result.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions