Skip to content

[RF][RS] Unify BayesianCalculator::GetInterval() 1D and ND code paths#21994

Merged
guitargeek merged 1 commit intoroot-project:masterfrom
guitargeek:issue-17567
Apr 23, 2026
Merged

[RF][RS] Unify BayesianCalculator::GetInterval() 1D and ND code paths#21994
guitargeek merged 1 commit intoroot-project:masterfrom
guitargeek:issue-17567

Conversation

@guitargeek
Copy link
Copy Markdown
Contributor

For models with a single POI and no nuisance parameters, BayesianCalculator::GetInterval() used ComputeIntervalUsingRooFit(), which built the CDF via RooAbsPdf::createCdf() On a computation graph that contains the NLL. The createCdf() relies on cloning the integrand subtree and substituting the POI with a prime variable, but the POI dependency inside the NLL compiled for the new vectorizing CPU evaluation backend is not propagated through the clone. The CDF and therefore the calculated interval is then wrong. Users worked around this by calling SetScanOfPosterior(N) instead (see #17567).

Fortunately, there was already a code path for the n-dimensional parameter case present that doesn't use createCdf(), but the ROOT Math integrator classes directly. This commit commit suggests to also do this for the 1D POI-only case to avoid the issue with using the compiled NLL in createCdf() and simplifying the code by only providing one code path for interval caluclation with integration.

Add a gtest regression test that reproduces the issue scenario and checks the default-path upper limit matches the explicit scan reference.

Closes #17567.

For models with a single POI and no nuisance parameters,
`BayesianCalculator::GetInterval()` used `ComputeIntervalUsingRooFit()`,
which built the CDF via `RooAbsPdf::createCdf()` On a computation graph
that contains the NLL. The `createCdf()` relies on cloning the integrand
subtree and substituting the POI with a prime variable, but the POI
dependency inside the NLL compiled for the new vectorizing CPU
evaluation backend is not propagated through the clone. The CDF and
therefore the calculated interval is then wrong. Users worked around
this by calling `SetScanOfPosterior(N)` instead (see root-project#17567).

Fortunately, there was already a code path for the n-dimensional
parameter case present that doesn't use `createCdf()`, but the ROOT Math
integrator classes directly. This commit commit suggests to also do this
for the 1D POI-only case to avoid the issue with using the compiled NLL
in `createCdf()` and simplifying the code by only providing one code
path for interval caluclation with integration.

Add a gtest regression test that reproduces the issue scenario and
checks the default-path upper limit matches the explicit scan reference.

Closes root-project#17567.
@github-actions
Copy link
Copy Markdown

Test Results

    22 files      22 suites   3d 10h 11m 9s ⏱️
 3 839 tests  3 838 ✅  1 💤 0 ❌
76 682 runs  76 664 ✅ 18 💤 0 ❌

Results for commit 0538159.

Copy link
Copy Markdown
Member

@lmoneta lmoneta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
Thanks for the fix!

@guitargeek guitargeek merged commit 1eb9fb6 into root-project:master Apr 23, 2026
30 of 33 checks passed
@guitargeek guitargeek deleted the issue-17567 branch April 23, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RF] RooStats.BayesianCalculator calculates the credibility interval on prior rather than on posterior

2 participants