Skip to content

[RF][HS3] Don't let evauation artifacts demote top-level pdfs in the export - #23224

Merged
guitargeek merged 2 commits into
root-project:masterfrom
guitargeek:hs3-toplevel-23221
Sep 2, 2026
Merged

[RF][HS3] Don't let evauation artifacts demote top-level pdfs in the export#23224
guitargeek merged 2 commits into
root-project:masterfrom
guitargeek:hs3-toplevel-23221

Conversation

@guitargeek

Copy link
Copy Markdown
Contributor

The HS3 exporter and RooJSONFactoryWSTool::cleanWS() used !hasClients() as the criterion for "this pdf or function is a top-level object of the workspace". But RooFit also registers objects that live outside the workspace as clients: the normalization integral that RooAbsPdf caches after getVal(normSet), or the integral returned by createIntegral(). A single normalized evaluation before the export therefore silently produced a document without any distributions, domains or parameter values, while exportJSON() still returned true.

Only count clients that are actually components of the workspace, since these are the ones that make an object a sub-node of a bigger model.

Closes #23221.

🤖 Done with the help of AI

A second commit does some refactors to keep the total number of lines of code under control.

The HS3 exporter and `RooJSONFactoryWSTool::cleanWS()` used
`!hasClients()` as the criterion for "this pdf or function is a top-level
object of the workspace". But RooFit also registers objects that live
outside the workspace as clients: the normalization integral that
`RooAbsPdf` caches after `getVal(normSet)`, or the integral returned by
`createIntegral()`. A single normalized evaluation before the export
therefore silently produced a document without any distributions, domains
or parameter values, while `exportJSON()` still returned `true`.

Only count clients that are actually components of the workspace, since
these are the ones that make an object a sub-node of a bigger model.

Closes root-project#23221.

🤖 Done with the help of AI
Behaviour-preserving cleanup of roofit/hs3, motivated by keeping the line
count in check after the fix for root-project#23221:

  * Build error messages with string concatenation instead of a
    `std::stringstream` whose only purpose is to feed `error()`, and drop
    the `return`s after `error()`, which is `[[noreturn]]`.
  * Share the "find the category observable" loop between the two dataset
    export functions, and the name-index construction between "functions"
    and "distributions".
  * HistFactory: factor out the repeated modifier node creation and the
    constraint queueing loops, drop the unreachable "optionally" branch of
    `optionallyExportGammaParameters()` (`forceExport` was always true),
    merge `hasStaterror()` into `findStaterror()`, and drop a `std::map`
    presence check that `operator[]` already covers.
  * RooFitCore: `readBinning()` reimplemented `RooJSONFactoryWSTool::readAxes()`,
    the RealSumPdf/RealSumFunc importer and exporter pairs are now
    templates, `writePolynomialBody()` is inlined into its single caller,
    and the manual `push_back` loops use the existing `operator<<` for
    JSON sequences.
  * Drop unused includes and dead locals.

Verified that the exported JSON for HistFactory, RealSum, Polynomial,
Spline and ParamHistFunc models is byte-identical before and after.

🤖 Done with the help of AI
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Test Results

    23 files      23 suites   3d 18h 53m 59s ⏱️
 3 863 tests  3 862 ✅ 0 💤 1 ❌
79 591 runs  79 590 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 7053a31.

@dpiparo
dpiparo self-requested a review September 2, 2026 07:06
@guitargeek
guitargeek merged commit b34bfe6 into root-project:master Sep 2, 2026
36 of 38 checks passed
@guitargeek
guitargeek deleted the hs3-toplevel-23221 branch September 2, 2026 07:29
@guitargeek

Copy link
Copy Markdown
Contributor Author

/backport to 6.40

@root-project-bot

Copy link
Copy Markdown

Preparing to backport PR #23224 to branch 6.40 requested by guitargeek

@root-project-bot

Copy link
Copy Markdown

This PR has been backported to branch 6.40: #23229

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][HS3] RooJSONFactoryWSTool silently exports an empty document after pdf.getVal(normSet) or createIntegral

3 participants