Source code for pytyche.calibrate.artifact

"""Calibration artifact — the v0.2 minimal contract.

Consumed by ``posterior.apply_calibration(calibration)``.  This module owns
only the minimal frozen shape: the layered correction payload plus the
regime metadata it was fitted on.  The ``from_sweep(name_or_path)``
registry constructor and the shipped artifacts are the calibration
track's scope, NOT part of this module.  There is no "skip" constructor:
the no-calibration choice is spelled ``None`` wherever a calibration is
accepted.
"""

from __future__ import annotations

import dataclasses
from typing import TYPE_CHECKING, Literal

from pytyche.calibrate.layered import LayeredCalibrationCorrection

if TYPE_CHECKING:
    from pytyche.contracts import ObservedExperimentData


[docs] @dataclasses.dataclass(frozen=True) class Calibration: """SBC-fitted calibration correction plus the regime it applies to. Level: cross-cutting (sweep × experiment). Fields: correction: The layered R(p) + scale-family correction payload fitted on an SBC sweep. metric: Canonical metric name the sweep was fitted on (e.g. ``"revenue_per_visitor"``). n_treatments: The K of the fitted sweep — variant count INCLUDING control. pooling: Pooling mode of the fitted sweep. NOT checked by :meth:`applies_to` (observed data carries no pooling); ``apply_calibration`` checks it against hurdle posteriors' ``pooling`` field (binary/continuous have no pooling concept). """ correction: LayeredCalibrationCorrection metric: str n_treatments: int pooling: Literal["joint", "independent"]
[docs] def applies_to(self, observed: ObservedExperimentData) -> bool: """Whether this artifact's fitted regime matches ``observed``. ``True`` iff ``observed.metric`` equals :attr:`metric` and ``len(observed.variants)`` equals :attr:`n_treatments`. """ return ( observed.metric == self.metric and len(observed.variants) == self.n_treatments )