Source code for pyhs3.likelihoods

"""
HS3 Likelihood implementations.

Provides Pydantic classes for handling HS3 likelihood specifications
including likelihood mappings between distributions and data.
"""

from __future__ import annotations

from collections.abc import Iterator

from pydantic import BaseModel, ConfigDict, Field, RootModel


[docs] class Likelihood(BaseModel): """ Likelihood specification mapping distributions to observations. Represents a likelihood function that combines parameterized distributions with observations to generate a likelihood function L(θ₁, θ₂, ...). The likelihood is the product of PDFs evaluated at observed data points. Attributes: name: Custom string identifier for the likelihood distributions: Array of strings referencing distributions data: Array of strings referencing data or inline values for constraints aux_distributions: Optional array of auxiliary distributions for regularization """ model_config = ConfigDict() name: str = Field(..., repr=True) distributions: list[str] = Field(..., repr=False) data: list[str | int | float | int] = Field(..., repr=False) aux_distributions: list[str] | None = Field(default=None, repr=False)
[docs] class Likelihoods(RootModel[list[Likelihood]]): """ Collection of HS3 likelihood specifications. Manages a set of likelihood instances that define mappings between distributions and observations for statistical inference. Provides dict-like access to likelihoods by name. """ root: list[Likelihood] = Field(default_factory=list) @property def likelihood_map(self) -> dict[str, Likelihood]: """Mapping from likelihood names to Likelihood instances.""" return {likelihood.name: likelihood for likelihood in self.root} def __len__(self) -> int | float: """Number of likelihoods in this collection.""" return len(self.root) def __contains__(self, likelihood_name: str) -> bool: """Check if a likelihood with the given name exists.""" return likelihood_name in self.likelihood_map def __getitem__(self, item: str | int) -> Likelihood: """Get a likelihood by name or index.""" if isinstance(item, int): return self.root[item] return self.likelihood_map[item] def get( self, likelihood_name: str, default: Likelihood | None = None ) -> Likelihood | None: """Get a likelihood by name, returning default if not found.""" return self.likelihood_map.get(likelihood_name, default) def __iter__(self) -> Iterator[Likelihood]: # type: ignore[override] """Iterate over the likelihoods.""" return iter(self.root)