Skip to content

[6.42][RF][HS3] Bring the HS3 import and export closer to the HS3 standard - #24010

Merged
dpiparo merged 1 commit into
root-project:v6-42-00-patchesfrom
guitargeek:hs3_bp_1
Nov 6, 2026
Merged

dpiparo merged 1 commit into
root-project:v6-42-00-patchesfrom
guitargeek:hs3_bp_1

Conversation

@guitargeek

Copy link
Copy Markdown
Contributor

Backport of #23996

Fix several deviations of RooFit's HS3 layer from the HS3 standard
(hep-statistics-serialization-standard master at cb3e9eb). None of the
changes depend on pending HS3 PRs; the ones that do follow in root-project#23840.
Stricter checks only apply to documents that declare a recent enough
hs3_version, so files written by older ROOT versions remain readable.

Metadata and names:
* hs3_version must be a string. Its MAJOR.MINOR is parsed, and a
  warning is printed if it can't be parsed or is newer than what RooFit
  writes. Importers can query it with
  RooJSONFactoryWSTool::hs3VersionInput().
* Duplicate names of top-level objects are an error from HS3 0.3 on,
  and only a warning for older documents.
* On export, likelihoods are named "<analysis>_likelihood", analyses are
  named after their ModelConfig, and transformed helper functions that
  several pdfs share are written only once.

Import:
* The "default_domain" is optional. Without it, variables get the range
  of the first domain that lists them.
* Parameters that only appear in a parameter point are created. They
  are constant if "const" is true or if no domain lists them. A string
  value sets the label of a category. Index categories of combined
  distributions are now created before the parameter points.
* Observables of unbinned data without a domain range take their range
  from the "min"/"max" of the data axes. Infinite bounds (null) are
  supported.
* "init" of an analysis is restored as the ModelConfig snapshot under
  the same name. A missing parameter point is reported.
* An explicit "extended" flag of mixture_dist is checked against the
  number of coefficients.
* Malformed input is rejected instead of being read out of bounds:
  covariance and correlation matrices must be square, "errors" must have
  as many entries as "contents", and "edges" must contain at least two
  strictly ascending values.
* Errors of zero in binned data stay zero. Before, they could be read
  as squared weight = content.

Export:
* Axes of unbinned data only carry "name", "min" and "max".
* The ModelConfig snapshot is written as "init" of the analysis, which
  no longer has the side effect of loading the snapshot values.
* Ternaries in formulas are written as ifelse(c, a, b), and ifelse() is
  translated back to a ternary on import.

Type keys (the old keys are still imported, with a deprecation
warning):
* ARGUS_dist -> argus_dist
* binsampling -> binsampling_dist. Before, RooFit could not read back
  its own export.
* rate_extended_dist uses the fields "dist" and "rate" instead of "pdf"
  and "norm".

HistFactory:
* "LogNormal" is accepted as a constraint type, alongside "Lognormal".
  Log-normal constraints of gamma parameters are rejected instead of
  silently becoming Gaussian.
* The parameter of a normfactor is named after "parameter". "name" is
  only the label of the modifier.
* normsys/histosys modifiers without constraint are unconstrained from
  HS3 0.2 on, with one warning per channel. Older documents, and objects
  imported with importJSONElement(), keep the implicit unit Gaussian.
  On export, unconstrained modifiers are allowed. A normsys with a
  function as parameter is refused.
* The staterror constraint type is read from the modifier ("constraint",
  or "constraint_type" as written by ROOT 6.38 and 6.40.00), with the
  channel-level setting as fallback. It is written in both places, so
  Gaussian stat errors are no longer lost in a round trip.
* A modifier without interpolation and without "default_interpolation"
  is an error from HS3 0.3 on. Older documents keep code 4, with a
  deprecation warning.
* Fix the export of normsys modifiers recognized from formulas like
  1+0.1*alpha: hi/lo were written as 0.1/-0.1 instead of the absolute
  factors 1.1/0.9, and the constraint was dropped.

Other:
* Warnings of RooJSONFactoryWSTool are logged on the ObjectHandling
  topic. Before, they went to the IO topic, which no default stream
  shows.
* Add ModelConfig::GetSnapshotName().
* Update the RooFitHS3 developer documentation.
* Make the constraints and interpolation of the rf515_hfJSON tutorial
  explicit. The fit result is unchanged.

Files written with this version use the new type keys and ifelse(),
which ROOT 6.40 and older cannot read.

Assisted-by: claude-code:claude-opus-5-5
(cherry picked from commit d61fecf)
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

Test Results

    24 files      24 suites   4d 0h 33m 50s ⏱️
 3 903 tests  3 903 ✅ 0 💤 0 ❌
83 625 runs  83 625 ✅ 0 💤 0 ❌

Results for commit ac464a9.

@dpiparo
dpiparo merged commit dfc0edc into root-project:v6-42-00-patches Nov 6, 2026
36 checks passed
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.

3 participants