cosmocore.spectra_io module

Spectra IO and layout: SpectraManager + flat-vector conversions.

Moved from cosmocore.harmonic (2026-05). See ADR-0002 follow-up (architecture backlog #5) for the rename rationale.

The main class is:
  • SpectraManager: Manages power spectra for collections of cosmological fields

Key functions:
  • cl_to_vec, vec_to_cl: Convert between C_ℓ matrices and vectorized forms

References

Power Spectrum Conventions: .. [1] Tegmark, M. “How to measure CMB power spectra without losing information”

Phys. Rev. D 55, 5895 (1997)

Spherical Harmonic Transforms: .. [3] Reinecke, M. & Seljak, U. “Libsharp - spherical harmonic transforms revisited”

Astron. Astrophys. 554, A112 (2013)

cosmocore.spectra_io.cl_to_vec(cl, vec)

Reshape a (n_bins, n_spec) matrix into a flat spectrum-major vector.

Parameters:
  • cl (numpy.ndarray, shape (n_bins, n_spec)) – Input matrix. Caller owns the bin-axis semantics; this function does not interpret the rows as multipoles or impose a low-ℓ floor.

  • vec (numpy.ndarray, shape (n_bins * n_spec,)) – Output vector. Must be pre-allocated. Layout is spectrum-major: vec[ispec * n_bins + k] = cl[k, ispec].

Examples

>>> import numpy as np
>>> cl = np.random.random((10, 3))
>>> vec = np.zeros(30)
>>> cl_to_vec(cl, vec)
cosmocore.spectra_io.vec_to_cl(vec, cl)

Inverse of cl_to_vec(): scatter a flat spectrum-major vector into a (n_bins, n_spec) matrix.

Parameters:
  • vec (numpy.ndarray, shape (n_bins * n_spec,)) – Input vector with spectrum-major layout.

  • cl (numpy.ndarray, shape (n_bins, n_spec)) – Output matrix. Must be pre-allocated.

Examples

>>> import numpy as np
>>> vec = np.random.random(30)
>>> cl = np.zeros((10, 3))
>>> vec_to_cl(vec, cl)
class cosmocore.spectra_io.SpectraManager(fields)[source]

Bases: object

Manages power spectra for a collection of cosmological fields.

This class provides a comprehensive interface for handling power spectra calculations for collections of cosmological fields (e.g., temperature, E-mode, B-mode polarization). It automatically constructs the appropriate auto- and cross-spectra based on the field properties and manages the mapping between field pairs and spectrum labels.

The manager handles both dictionary and matrix representations of power spectra, applies normalization factors, and integrates with BeamManager for instrumental effects.

Parameters:

fields (list of BaseField) – Collection of cosmological fields for which to manage power spectra. Each field should have defined labels, spin, and lmax properties.

fields

The input collection of fields.

Type:

list of BaseField

labels

List of all spectrum labels (e.g., [‘TT’, ‘EE’, ‘BB’, ‘TE’, ‘TB’, ‘EB’]).

Type:

list of str

n_spectra

Total number of power spectra (auto + cross).

Type:

int

Examples

>>> from cosmocore import ScalarField, PolarizationField
>>> temp_field = ScalarField(['T'], spin=0, lmax=100)
>>> pol_field = PolarizationField(['E', 'B'], spin=2, lmax=100)
>>> spectra_mgr = SpectraManager([temp_field, pol_field])
>>> print(spectra_mgr.labels)  # ['TT', 'EE', 'BB', 'TE']

Notes

The class automatically determines which cross-spectra are physically meaningful based on the field types and spin properties. For example, temperature-B mode cross-spectra (TB) are typically zero in standard cosmological models and may be excluded.

__init__(fields)[source]
property labels: list[str]

Get list of all power spectrum labels.

Returns:

Copy of the spectrum labels list (e.g., [‘TT’, ‘EE’, ‘BB’, ‘TE’]). The order matches the column ordering in the power spectra matrix.

Return type:

list of str

property n_spectra: int

Get total number of power spectra.

Returns:

Total number of auto- and cross-power spectra managed by this instance.

Return type:

int

get_spectrum_label(field_i, field_j, mode=0)[source]

Get spectrum label for given field pair and mode.

Parameters:
  • field_i (int) – Index of first field in the field collection.

  • field_j (int) – Index of second field in the field collection.

  • mode (int, optional) – Mode index for fields with multiple modes (default: 0).

Returns:

Spectrum label (e.g., ‘TT’, ‘TE’, ‘EE’) if the combination exists, None otherwise.

Return type:

str or None

Examples

>>> # Get auto-spectrum label for temperature field (index 0)
>>> label = spectra_mgr.get_spectrum_label(0, 0)  # 'TT'
>>> # Get cross-spectrum label between temperature (0) and E-mode (1)
>>> label = spectra_mgr.get_spectrum_label(0, 1)  # 'TE'
set_cls(cls_data, lmax=None)[source]

Set power spectra from dictionary or matrix.

This method accepts power spectra in two formats and automatically converts between dictionary and matrix representations for internal use.

Parameters:
  • cls_data (dict[str, np.ndarray] or np.ndarray) – Power spectra data. ℓ-indexed: cls_data[label][ell] is C_ℓ. If dict, keys should be spectrum labels (e.g., ‘TT’, ‘EE’, ‘TE’) and values should be 1D arrays of length lmax + 1. If array, should have shape (lmax + 1, n_spectra) with columns corresponding to the spectrum labels in order.

  • lmax (int, optional) – Maximum multipole to use. If None, uses the field’s lmax. This allows setting Cls up to a different lmax than the field’s lmax.

Raises:

ValueError – If dictionary is missing required spectrum labels, or if array has wrong number of columns.

Examples

Return type:

None

>>> # Set from dictionary
>>> cls_dict = {'TT': tt_spectrum, 'EE': ee_spectrum, 'TE': te_spectrum}
>>> spectra_mgr.set_cls(cls_dict)
>>>
>>> # Set from matrix
>>> cls_matrix = np.column_stack([tt_spectrum, ee_spectrum, te_spectrum])
>>> spectra_mgr.set_cls(cls_matrix)
get_cls(field_i, field_j, mode=0)[source]

Get power spectrum for field pair and mode.

Parameters:
  • field_i (int) – Index of first field.

  • field_j (int) – Index of second field.

  • mode (int, optional) – Mode index (default: 0).

Returns:

ℓ-indexed power-spectrum array of length lmax + 1: index ell holds C_ℓ. Indices below the spectrum’s physical floor (ℓ < 2 for spin-0, ℓ < |s| for spin-s) are zero.

Return type:

np.ndarray

Raises:

ValueError – If no power spectrum is found for the specified field combination.

Examples

>>> # Get temperature auto-spectrum
>>> tt_spectrum = spectra_mgr.get_cls(0, 0)
>>> # Get temperature-E mode cross-spectrum
>>> te_spectrum = spectra_mgr.get_cls(0, 1)
build_inputs(*, symmetry_mode=None)[source]

Build C_ell_dict and spectra_list keyed by SpectrumKey.

Parameters:

symmetry_mode (SymmetryMode | str | None, optional) – How cross-component spin-2 × spin-2 EB-like spectra are emitted. SYMMETRIC (default) emits one combined GC per cross-pair; the companion CG entry from the underlying spectra map is filtered out. DIRECTIONAL emits both GC and CG (B_i × E_j) as separate spectra. See ADR-0011. Strings are coerced via SymmetryMode[name.upper()].

Returns:

  • C_ell_dict (dict[SpectrumKey, ndarray]) – Dictionary mapping each spectrum identifier to its C_ell array.

  • spectra_list (list[SpectrumKey]) – Ordered list of spectrum identifiers. DIRECTIONAL keeps the extra CG entries in their original positions; SYMMETRIC skips them so the spectrum count stays at the legacy 3-per-cross-pair.

compute_smoothing_factors(beam_manager, lmax=None)[source]

Compute smoothing factors for all spectrum labels.

Return type:

dict[str, ndarray]

Parameters:

beam_managerBeamManager

BeamManager instance for smoothing factors

lmaxint, optional

Maximum multipole to use. If None, uses the field’s lmax.

Returns:

: dict[str, np.ndarray]

Dictionary mapping spectrum labels to smoothing factor arrays