Skip to content

[RF][HS3] Support the HS3 histfactory function (deferred until HS3 #143 and the bin width discussion are settled) #23985

Open

Description

@cburgard

Feature description

HS3 #129 (merged) adds a histfactory function to the standard, next to the existing histfactory_dist:

  • It has the same components as histfactory_dist (axes, default_interpolation, samples with data and modifiers). Only the type differs.
  • It evaluates the HistFactory prediction, i.e. the expected bin yields $\lambda_i(\theta)$. histfactory_dist is now defined as $\prod_i \mathrm{Pois}(n_i \mid \lambda_i(\theta))$ on top of that prediction.
  • The constraint terms belong to the prediction: a likelihood that contains a histfactory_dist, or a distribution that depends on a histfactory function, includes the constraint terms of all its modifiers, in addition to aux_likelihood.

RooFit currently supports only histfactory_dist. A document containing a histfactory function fails to import with "no handling for type 'histfactory' implemented". For histfactory_dist, RooFit already conforms to #129: it puts the modifier constraint terms into the RooProdPdf of the channel.

Supporting the function would roughly require:

  • an importer for histfactory, sharing the sample/modifier code of the histfactory_dist importer, that produces a RooRealSumFunc of the samples;
  • an exporter that recognizes HistFactory-structured RooRealSumFuncs and writes them as histfactory;
  • adding the constraint terms of every histfactory function that a likelihood depends on when building the ModelConfig, and not repeating them in aux_distributions on export;
  • possibly an opt-in setting to export existing RooProdPdf/RooRealSumPdf HistFactory channels as a histfactory function plus a wrapper distribution.

This is deferred until two open questions are settled: what the function returns at a point x, discussed in HS3 #143, and the bin width discussion in #23301.

The spec defines the function per bin ($\lambda_i(\theta)$), but doesn't say what it returns when evaluated at a point $x$. Two readings fit the current text: the yield of the bin containing $x$ ($\lambda_i$), or the yield per unit bin volume ($\lambda_i/\lvert B_i\rvert$). They differ by exactly the bin volume. This matters as soon as the function is used in a likelihood. The standard's distributions that could consume it (bincounts_density_dist, rate_density_dist) integrate their input over $x$, $\nu_i = \int_{B_i} f(x)\,\mathrm{d}x$. So:

histfactory_dist never ran into this: it is evaluated at the count vector, never at a point x.

HS3 #143 proposes to make this explicit with a field on the function, yield_per: "bin" | "volume", and asks the community for input. The outcome determines the RooFit implementation:

  • the bin-width division inside the samples, which today is part of the RooRealSumPdf built for histfactory_dist;
  • the wrapper distribution used by the opt-in export setting;
  • whether RooFit needs a serialized bin-volume function at all.

Alternatives considered

  • Writing $1/\lvert B_i\rvert$ as a standard generic function (piecewise constant via ifelse), plus a marker in misc.ROOT_internal so that RooFit maps it back to RooBinWidthFunction.
  • Writing $1/\lvert B_i\rvert$ as a second, modifier-free histfactory function whose contents are the inverse bin volumes.
  • Fixing one reading without a field: either the yield per unit bin volume, so that bincounts_density_dist can consume the function directly; or the bin yield, together with a new HS3 distribution that consumes per-bin expected counts directly (a bin-space counterpart of bincounts_density_dist).

The first two are conformant workarounds that serialize the bin-volume conversion explicitly. The last requires a spec change and is one of the options under discussion in HS3 #143. None of them seemed worth committing to before HS3 #143 and the bin width discussion have concluded.

Additional context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions