spey.backends.default_pdf.uncertainty_synthesizer.signal_uncertainty_synthesizer

spey.backends.default_pdf.uncertainty_synthesizer.signal_uncertainty_synthesizer#

spey.backends.default_pdf.uncertainty_synthesizer.signal_uncertainty_synthesizer(signal_yields: List[float], modifiers: List[Dict[str, Any]], n_signal_parameters: int = 0, domain_start: int | None = None) Dict[str, Any][source]#

Synthesize signal uncertainties from a list of modifier configuration dictionaries.

Changed in version 0.2.7: modifiers is now a list of configuration dictionaries. Each dictionary specifies the modifier type ("normalization" or "shape"), the per-bin uncertainty values, and an optional name. The old list-of-arrays format is no longer accepted.

Each modifier applies a multiplicative correction to the signal yields via log-normal morphing. Two morphing modes are supported:

Normalization modifier ("type": "normalization")

A single nuisance parameter \(\theta_k\) is shared across all bins. Suitable for uncertainties that rescale the entire distribution coherently, such as PDF variations, luminosity uncertainties, or cross-section normalisation errors.

The morphing factor is

\[f_{i,k}(\theta_k) = \exp\!\left[\theta_k \ln\!\bigl(1 + \Delta_{i,k}(\theta_k)\bigr)\right],\]

where \(\Delta_{i,k} = \sigma^{(s)}_{i,k} / n^{(s)}_i\) and the sign of \(\theta_k\) selects the up or down variation.

Shape modifier ("type": "shape")

One independent nuisance parameter \(\alpha_{i,k}\) per bin. Suitable for uncertainties whose effect differs bin-by-bin in an unknown way, such as statistical uncertainties on theory predictions or bin-by-bin scale uncertainties.

The morphing factor is

\[f_{i,k}(\alpha_{i,k}) = \exp\!\left[\alpha_{i,k} \ln\!\bigl(1 + \Delta_{i,k}(\alpha_{i,k})\bigr)\right],\]

with each \(\alpha_{i,k}\) constrained by an independent standard normal prior \(\mathcal{N}(\alpha_{i,k} \mid 0, 1)\).

For asymmetric uncertainties the variation depends on the sign of the nuisance parameter:

\[\begin{split}\Delta_{i,k}(\theta) = \begin{cases} \Delta_{i,k}^{+}, & \theta \ge 0 \\ \Delta_{i,k}^{-}, & \theta < 0 \end{cases}\end{split}\]

All nuisance parameters are constrained by standard normal priors.

Note

Symmetric uncertainties must be provided as list[float] in "uncertainties". Asymmetric uncertainties must be provided as list[tuple[float, float]], where each tuple is (up, down) giving the absolute up and down variations.

Modifier configuration dictionary

Each element of modifiers is a dict with the following keys:

Key

Required

Description

"type"

yes

Morphing mode: "normalization" (one shared nuisance) or "shape" (one nuisance per bin).

"uncertainties"

yes

Per-bin absolute uncertainties. Either a list[float] for symmetric uncertainties or a list[tuple[float, float]] for asymmetric (up, down) variations. Must have one entry per bin.

"name"

no

Human-readable label used to construct parameter names (e.g. "pdf"theta_sig_pdf). Defaults to "mod0", "mod1", … when omitted.

Parameter layout with n_signal_parameters

When the calling backend uses a callable signal_yields that accepts n_signal_parameters additional free parameters, those parameters occupy indices 1 n_signal_parameters in the full parameter vector and push the background nuisance parameters (and therefore the signal-uncertainty parameters) to higher indices:

pars = [μ, sig_par_0, …, sig_par_{n-1}, θ_bkg_1, …, θ_bkg_N, θ_sig_1, …]

Pass n_signal_parameters so that the domain indices are shifted accordingly. Alternatively, supply domain_start to override the auto-computed starting index.

Examples

Normalization modifier — a single nuisance scales the whole distribution:

>>> signal_uncertainty_synthesizer(
...     signal_yields=[3.0, 5.0],
...     modifiers=[
...         {"type": "normalization", "name": "pdf", "uncertainties": [0.6, 1.0]},
...     ],
... )
# one nuisance parameter theta_sig_pdf at domain index 3

Shape modifier — independent nuisance per bin:

>>> signal_uncertainty_synthesizer(
...     signal_yields=[3.0, 5.0],
...     modifiers=[
...         {"type": "shape", "name": "scale", "uncertainties": [0.3, 0.5]},
...     ],
... )
# two nuisance parameters theta_sig_scale_0, theta_sig_scale_1 at domain
# indices 3 and 4

Mixed modifiers — normalization + shape in one model:

>>> signal_uncertainty_synthesizer(
...     signal_yields=[3.0, 5.0],
...     modifiers=[
...         {"type": "normalization", "name": "pdf",
...          "uncertainties": [0.6, 1.0]},
...         {"type": "shape", "name": "scale",
...          "uncertainties": [(0.3, 0.4), (0.5, 0.6)]},
...     ],
... )
# 3 nuisance parameters total: theta_sig_pdf (index 3),
# theta_sig_scale_0 (index 4), theta_sig_scale_1 (index 5)
Parameters:
  • signal_yields (List[float]) – List of nominal signal yields per bin. Used to compute the fractional variation \(\Delta_{i,k}\).

  • modifiers (List[Dict[str, Any]]) – List of modifier configuration dictionaries. Each dictionary must contain "type" and "uncertainties" keys; "name" is optional. See table above.

  • n_signal_parameters (int, default 0) – Number of additional free parameters that a callable signal_yields function accepts. These parameters are placed before the background nuisance parameters in the parameter vector (immediately after \(\mu\)), so the domain indices of the signal-uncertainty parameters are shifted by this amount. Has no effect when domain_start is supplied explicitly.

  • domain_start (int, default None) – Explicit starting index in the parameter vector from which signal-uncertainty nuisance parameters are assigned. When None the index is computed automatically as 1 + n_signal_parameters + N_bins.

Raises:

InvalidUncertaintyDefinition – If a modifier has an unknown "type", if the number of bins in "uncertainties" does not match signal_yields, or if the uncertainty array has an unsupported number of dimensions.

Returns:

A dictionary with

  • "lambda" — callable (pars: np.ndarray) -> np.ndarray that computes the per-bin signal modifier \(f_i(\boldsymbol{\theta}_{\rm sig})\).

  • "constraint" — list of constraint dictionaries (one per nuisance parameter) for the constraint model.

  • "n_parameters" — total number of signal-uncertainty nuisance parameters introduced. This is 1 per normalization modifier and \(N_{\rm bins}\) per shape modifier.

  • "parameter_names" — list of parameter name strings corresponding to the signal-uncertainty nuisance parameters, in parameter-vector order.