Gaussian Likelihoods
This module provides the base classes for Gaussian likelihoods in SOLikeT, including support for combining multiple likelihoods with cross-covariances.
GaussianLikelihood
The base class for all Gaussian likelihoods. Subclasses should implement
the _get_theory() method to compute the theory prediction.
- class soliket.gaussian.GaussianLikelihood(info: Mapping[str, Any] = mappingproxy({}), name: str | None = None, timing: bool | None = None, packages_path: str | None = None, initialize=True, standalone=True)[source]
Bases:
LikelihoodBase class for Gaussian likelihoods in SOLikeT.
This class provides the infrastructure for computing Gaussian log-likelihoods from SACC data files. Subclasses must implement the
_get_theory()method to compute the theory prediction for the data vector.Parameters
- namestr
Name identifier for the likelihood (default: “Gaussian”)
- datapathstr
Path to the SACC file containing data and covariance
- use_spectrastr or list
Which spectra to use. Either “all” or a list of tracer pairs like
[("tracer1", "tracer2")]- ncovsimsint, optional
Number of simulations used to estimate covariance. If provided, applies the Hartlap correction factor to the inverse covariance.
Attributes
- dataGaussianData
The assembled Gaussian data object with covariance
- sacc_datasacc.Sacc
The loaded SACC data object
- xnp.ndarray
The bin centers (ell values)
- ynp.ndarray
The data vector
- covnp.ndarray
The covariance matrix
Examples
To create a custom Gaussian likelihood:
class MyLikelihood(GaussianLikelihood): name = "my_likelihood" _allowable_tracers = ("cmb_temperature", "cmb_polarization") def _get_theory(self, **params): # Compute theory prediction return theory_vector
- logp(**params_values) float[source]
Computes and returns the log likelihood value. Takes as keyword arguments the parameter values. To get the derived parameters, pass a _derived keyword with an empty dictionary.
Alternatively you can just implement calculate() and save the log likelihood into state[‘logp’]; this may be more convenient if you also need to also calculate other quantities.
MultiGaussianLikelihood
A likelihood that combines multiple Gaussian likelihoods, optionally accounting for cross-covariances between them.
- class soliket.gaussian.MultiGaussianLikelihood(info=mappingproxy({}), **kwargs)[source]
Bases:
GaussianLikelihoodA likelihood combining multiple Gaussian likelihoods with cross-covariances.
This class enables joint analysis of multiple datasets by combining their data vectors and covariance matrices. Cross-covariances between datasets can be specified via a
CrossCovobject stored in SACC format.Parameters
- componentslist of str
List of likelihood class names to combine, e.g.,
["soliket.mflike.MFLike", "soliket.lensing.LensingLikelihood"]- optionslist of dict
Configuration options for each component likelihood. Each dict should contain at minimum
datapathand any other required parameters.- cross_cov_pathstr, optional
Path to a SACC file containing cross-covariances between components. If not provided, components are assumed independent (zero cross-covariance).
Attributes
- likelihoodslist of Likelihood
The instantiated component likelihoods
- cross_covCrossCov or None
The loaded cross-covariance container
- dataMultiGaussianData
The combined data object with joint covariance
Examples
YAML configuration:
likelihood: soliket.MultiGaussianLikelihood: components: - soliket.mflike.MFLike - soliket.lensing.LensingLikelihood options: - datapath: /path/to/mflike.fits use_spectra: all - datapath: /path/to/lensing.fits cross_cov_path: /path/to/cross_cov.fits
Python usage:
from soliket import MultiGaussianLikelihood info = { "components": ["soliket.mflike.MFLike", "soliket.lensing.LensingLikelihood"], "options": [ {"datapath": "mflike.fits", "use_spectra": "all"}, {"datapath": "lensing.fits"}, ], "cross_cov_path": "cross_cov.fits", } like = MultiGaussianLikelihood(info)
- classmethod get_defaults(return_yaml=False, yaml_expand_defaults=True, input_options=mappingproxy({}))[source]
Return defaults for this component_or_class, with syntax:
option: value [...] params: [...] # if required prior: [...] # if required
If keyword return_yaml is set to True, it returns literally that, whereas if False (default), it returns the corresponding Python dict.
Note that in external components installed as zip_safe=True packages files cannot be accessed directly. In this case using !default .yaml includes currently does not work.
Also note that if you return a dictionary it may be modified (return a deep copy if you want to keep it).
if yaml_expand_defaults then !default: file includes will be expanded
input_options may be a dictionary of input options, e.g. in case default params are dynamically dependent on an input variable
- get_helper_theories() dict[str, Theory][source]
Return dictionary of optional names and helper Theory instances that should be used in conjunction with this component. The helpers can be created here as only called once, and before any other use of helpers.
- Returns:
dictionary of names and Theory instances
- classmethod get_modified_defaults(defaults, input_options=mappingproxy({}))[source]
After defaults dictionary is loaded, you can dynamically modify them here as needed,e.g. to add or remove defaults[‘params’]. Use this when you don’t want the inheritance-recursive nature of get_defaults() or don’t only want to affect class attributes (like get_class_options() does0.
- get_requirements()[source]
Get a dictionary of requirements (or a list of requirement name, option tuples) that are always needed (e.g. must be calculated by another component or provided as input parameters).
- Returns:
dictionary or list of tuples of requirement names and options (or iterable of requirement names if no optional parameters are needed)
- initialize_with_provider(provider: Provider)[source]
Final initialization after parameters, provider and assigned requirements set. The provider is used to get the requirements of this theory using provider.get_X() and provider.get_param(‘Y’).
- Parameters:
provider – the
theory.Providerinstance that should be used by this component to get computed requirements
Usage Example
To combine multiple likelihoods (e.g., CMB TT and lensing) with cross-covariances:
likelihood:
soliket.MultiGaussianLikelihood:
components:
- soliket.mflike.MFLike
- soliket.lensing.LensingLikelihood
options:
- datapath: /path/to/mflike_data.fits
use_spectra: all
- datapath: /path/to/lensing_data.fits
cross_cov_path: /path/to/cross_covariance.fits
The cross_cov_path parameter is optional. If not provided, the likelihoods
are assumed to be independent (zero cross-covariance).
CrossCov
A container for storing cross-covariances between likelihood components. Supports saving and loading in SACC format.
- class soliket.gaussian.CrossCov(*args, **kwargs)[source]
Bases:
dictCross-covariance container for multi-component Gaussian likelihoods.
Stores cross-covariances between named components (e.g., “mflike”, “lensing”) and optionally the full covariances for each component. Supports saving and loading in SACC format for persistence.
The dictionary keys are tuples of component names, e.g., (“mflike”, “lensing”). Values are the corresponding covariance matrices.
For the full joint covariance, use:
Diagonal blocks:
(name, name)-> auto-covariance matrixOff-diagonal blocks:
(name1, name2)-> cross-covariance matrix
Examples
Mode 1: Full covariance specification
Use
add_component()for auto-covariances andadd_cross_covariance()for off-diagonal blocks:cross_cov = CrossCov() cross_cov.add_component("mflike", mflike_cov) cross_cov.add_component("lensing", lensing_cov) cross_cov.add_cross_covariance("mflike", "lensing", cross_block) cross_cov.save("cross_cov.fits")
Mode 2: Cross-covariance only
If auto-covariances will come from individual likelihoods:
cross_cov = CrossCov() cross_cov.add_cross_covariance("mflike", "lensing", cross_block) cross_cov.save("cross_cov.fits")
Loading:
cross_cov = CrossCov.load("cross_cov.fits") block = cross_cov[("mflike", "lensing")]
- add_component(name: str, cov: ndarray)[source]
Add a component with its full covariance.
Parameters
- namestr
Component name (e.g., “mflike”, “kk”)
- covnp.ndarray
Full covariance matrix for this component
- add_cross_covariance(name1: str, name2: str, cross_cov: ndarray)[source]
Add cross-covariance between two components.
Parameters
- name1str
First component name
- name2str
Second component name
- cross_covnp.ndarray
Cross-covariance matrix with shape (n1, n2)
- add_metadata(key: tuple[str], tracers: tuple[tuple[str]], data_types: tuple[str], tracer_info: dict[str, dict[str, str | int]] = None)[source]
Store metadata for cross-covariance entries (legacy method).
Parameters
- keytuple[str]
Component identifier key
- tracerstuple[tuple[str]]
Tracer pairs for each component
- data_typestuple[str]
Data types (e.g., “cl_00”, “cl_22”)
- tracer_infodict[str, dict[str, str | int]]
Dictionary mapping tracer names to their properties
- property component_names: list[str]
Get ordered list of component names.
Usage Modes
Mode 1: Full covariance specification
Use add_component() to register each component with its auto-covariance,
then add_cross_covariance() for off-diagonal blocks:
from soliket.gaussian import CrossCov
cross_cov = CrossCov()
# Add auto-covariances
cross_cov.add_component("mflike", mflike_cov)
cross_cov.add_component("lensing", lensing_cov)
# Add cross-covariance
cross_cov.add_cross_covariance("mflike", "lensing", mflike_lensing_cov)
# Save to SACC format
cross_cov.save("cross_covariance.fits")
Mode 2: Cross-covariance only
If you only want to specify the cross-covariance (using auto-covariances
from individual likelihoods), just use add_cross_covariance():
cross_cov = CrossCov()
cross_cov.add_cross_covariance("mflike", "lensing", mflike_lensing_cov)
cross_cov.save("cross_covariance.fits")
When loaded by MultiGaussianLikelihood, the auto-covariances will be
taken from each individual likelihood’s SACC file.
Loading CrossCov
To load a previously saved cross-covariance:
from soliket.gaussian import CrossCov
cross_cov = CrossCov.load("cross_covariance.fits")
# Access blocks
mflike_lensing_block = cross_cov[("mflike", "lensing")]
GaussianData
Low-level data container for named multivariate Gaussian data.
- class soliket.gaussian.GaussianData(name, x: Sequence, y: Sequence[float], cov: ndarray, ncovsims: int | None = None, indices: ndarray | None = None)[source]
Bases:
objectContainer for named multivariate Gaussian data.
Stores a data vector with its covariance matrix and provides methods for computing the Gaussian log-likelihood.
Parameters
- namestr
Name identifier for the data
- xSequence
Labels or coordinates for each data point (e.g., ell values)
- ySequence[float]
The data vector values
- covnp.ndarray
Covariance matrix with shape (n, n) where n = len(x)
- ncovsimsint, optional
Number of simulations used to estimate covariance. If provided, applies the Hartlap correction factor to the inverse covariance.
- indicesnp.ndarray, optional
Boolean array for trimming cross-covariances when scale cuts are applied
Attributes
- inv_covnp.ndarray
Inverse covariance matrix (with Hartlap correction if applicable)
- norm_constfloat
Normalization constant for the Gaussian likelihood
Raises
- ValueError
If dimensions of x, y, and cov are incompatible If covariance matrix has non-positive determinant
MultiGaussianData
Assembles multiple GaussianData objects into a joint data vector
with combined covariance matrix.
- class soliket.gaussian.MultiGaussianData(data_list: list[GaussianData], cross_covs: CrossCov | None = None)[source]
Bases:
GaussianDataCombined Gaussian data from multiple components with cross-covariances.
Assembles multiple
GaussianDataobjects into a single joint data vector with a combined covariance matrix that includes both auto-covariances and cross-covariances between components.Parameters
- data_listlist of GaussianData
Individual data objects to combine
- cross_covsCrossCov, optional
Cross-covariance container. If None, components are assumed independent. Auto-covariances can come from either the CrossCov or the individual GaussianData objects (individual data takes precedence if CrossCov doesn’t contain auto-covariance for a component).
Attributes
- data_listlist of GaussianData
The original individual data objects
- nameslist of str
Names of all components
- lengthslist of int
Data vector lengths for each component
- labelslist of str
Component name for each element in the combined data vector
Examples
Combining two datasets with cross-covariance:
data1 = GaussianData("mflike", x1, y1, cov1) data2 = GaussianData("lensing", x2, y2, cov2) cross_cov = CrossCov() cross_cov.add_cross_covariance("mflike", "lensing", cross_block) multi_data = MultiGaussianData([data1, data2], cross_cov) # Access combined properties print(multi_data.cov.shape) # (n1 + n2, n1 + n2) loglike = multi_data.loglike(theory_vector)