sp_validation.sacc_io¶
SACC_IO.
- Name:
sacc_io.py
- Description:
Read/write the standard SACC data-product layout for the weak-lensing validation package. One file describes each catalogue version:
{version}.sacc— NZ tracers, reporting-grid ξ±, pseudo-Cℓ (EE/BB/EB) with bandpower windows, COSEBIs, pure E/B, ρ/τ PSF diagnostics, and the fine ξ± integration input for COSEBIs / pure-EB (grid='integration'tagged points). The covariance is assembled block-diagonally from the per-statistic covariances (zero cross-blocks, never materialized): the analysis blocks first, then a dense per-pair integration-ξ block (the analytic integration-binning covariance when it exists — it feeds derived-statistic error propagation — or the TreeCorrvarxip/varximdiagonal as degraded fallback).assemble_covariancehands sacc a list of blocks, which stores aBlockDiagonalCovariance(one FITS table per block, Σ block² on disk rather than a dense N²) — cost scales with the integration grid’s size, a parameter set by the caller, not baked into the layout.
Insertion order is load-bearing. A Sacc is a flat list of data points in the order
add_data_pointwas called, and row/columniof the covariance refers to thei-th inserted point — there is no other linkage between a point and its covariance entry. SACC preserves that order bitwise through FITS save/load, so writers define the covariance layout by their insertion sequence. Writers below insert in the canonical order — ξ+ then ξ−, Cℓ (ee, bb, eb), COSEBIs (all Eₙ then all Bₙ), pure E/B (xip_E, xim_E, xip_B, xim_B, xip_amb, xim_amb — matchingb_modes._EB_KEYS), ρ, then τ — but readers never assume global order: they resolve indices throughSacc.indices(dtype, tracers, **tags).Tag filters are plain keyword arguments to
indices/get_data_points/get_tag; thetags={...}form silently selects nothing and must never be used.Tomographic ξ ordering: each
add_xicall inserts one tracer pair as[xip; xim], so a multi-pair vector is pair-major —[pair_0 xip; pair_0 xim; pair_1 xip; …]— not type-major ([all xip; all xim]). A tomographic ξ covariance with cross-pair correlations is therefore supplied toassemble_covarianceas ONE contiguous block spanning the consecutiveadd_xicalls, ordered pair-by-pair to match insertion. Writers must calladd_xiin the same pair order the covariance was built in. Converters that need a type-major layout (e.g. the DES 2pt-FITS convention) permute explicitly vias.indicesrather than assuming global order.
- Optionality: a file’s contents are flexible about which components of
a statistic it actually has.
add_pseudo_clrequires EE (the bandpower window’s reference series) but BB and EB are optional — an analysis that never computed EB simply omits it.add_cosebisrequires Eₙ but Bₙ is optional.add_pure_ebrequires xip_E/xim_E but the B and ambiguous-mode blocks are each optional, independently (B and amb are unrelated computations). Everything else a writer takes — θ/ℓ grids, tracer/bin identifiers, the value array for a component you ARE adding — is structurally necessary and has no default; supplying it partially would desynchronise the covariance layout, so it is refused rather than degraded. Readers mirror this split: a composite reader (get_pseudo_cl,get_cosebis,get_pure_eb) returnsNone(or omits the key) for a component the file doesn’t carry, but a selection naming that component explicitly (s.indices,_mean,extract) still fails loud on no match — silence is reserved for “this file doesn’t have that optional piece”, never for “you asked for something specific and it isn’t there”.Converters. The tail of this module holds converters between the SACC layout above and external analysis-tool file formats — the CosmoSIS “2pt FITS” (
sacc_to_twopoint_fits) and OneCovariance’s redshift / covariance files (write_nz,nz_config_stanza,read_nz,covariance_blocks). The 2pt-FITS converter reproduces today’s hand-assembled product fromcosmo_inference/scripts/cosmosis_fitting.pyHDU-for-HDU and byte-for-byte (verified against that writer), and is single-bin only today — it fails fast on a multi-bin SACC (tomographic emission lands with the tomographic round). The OneCovariance converters are coupled to SACC by file format only; OneCovariance itself is not a dependency.
- source_name(i)[source]¶
SACC tracer name for source redshift bin
i(0-based).Kept as the single definition of the
source_{i}naming contract — external consumers address tracers through it rather than the f-string.
- new_sacc(nz, metadata=None)[source]¶
Create a Sacc with the survey’s NZ (and PSF) tracers.
- Parameters:
- Returns:
Sacc holding the
source_{i}NZ tracers and thepsf_starsMisc tracer (needed by ρ/τ diagnostics).- Return type:
sacc.Sacc
- _pair(bins)[source]¶
Resolve a
(i, j)bin pair to the(source_i, source_j)names.The pair is normalised to
i <= j: shear-shear statistics are symmetric in the tracer pair, and SACC stores each pair under one ordering, so(1, 0)must address the same points as(0, 1). Kept as a helper: everyadd_*/get_*function relies on this normalisation.
- _check_ascending(name, values)[source]¶
Require
valuesto be strictly ascending; else raise ValueError.Insertion order is the covariance (and bandpower-window) order, and readers return points in insertion order, so an out-of-order grid would silently desynchronise a data vector from its covariance. Enforce monotonicity at write time instead.
- _add_theta_series(s, dtype, tracers, theta, values, **tags)[source]¶
Insert one theta-tagged series, one point per (theta, value) pair.
- add_xi(s, bins, theta, xip, xim, *, grid, theta_nom=None, npairs=None, weight=None)[source]¶
Add a real-space shear 2PCF (ξ+ then ξ−) for one tracer pair.
- Parameters:
s (sacc.Sacc) – Target, mutated in place.
theta (array_like) – Angular separations (arcmin) — TreeCorr
meanr.xip (array_like) – ξ+ and ξ− at
theta.xim (array_like) – ξ+ and ξ− at
theta.grid ({'reporting', 'integration'}) – Stored as the
gridtag on every point. The reporting (analysis) ξ± and the fine COSEBIs/pure-EB integration input share the same data type and tracer pair, so this tag is the only thing that disambiguates them in the file.theta_nom (array_like, optional) – Nominal bin centres — TreeCorr
rnom— stored astheta_nom.npairs (array_like, optional) – TreeCorr pair counts and weights, stored per point.
weight (array_like, optional) – TreeCorr pair counts and weights, stored per point.
- add_pseudo_cl(s, bins, ell_eff, cl_ee, cl_bb=None, cl_eb=None, *, window_ells, window_weights, grid='reporting')[source]¶
Add pseudo-Cℓ EE (required) plus whichever of BB/EB were computed.
- Parameters:
s (sacc.Sacc) – Target, mutated in place.
ell_eff (array_like) – Effective multipole of each bandpower.
cl_ee (array_like) – EE bandpowers at
ell_eff.cl_bb (array_like, optional) – BB and/or EB bandpowers at
ell_eff. Each defaults toNoneand is then simply not written — EB in particular is often not computed at all.cl_eb (array_like, optional) – BB and/or EB bandpowers at
ell_eff. Each defaults toNoneand is then simply not written — EB in particular is often not computed at all.window_ells (array_like) – Multipoles spanned by the bandpower window matrix (shape
(nell,)).window_weights (array_like) – Window matrix
Wof shape(nell, nbp)— one column per bandpower — from NaMasterget_bandpower_windows. Onesacc.BandpowerWindowis built and shared across every component written.grid (str, optional) – Stored as the
gridtag on every point (default'reporting'), joiningmerge’s ℓ-consistency group; variant ℓ binnings belong under different tag values.
- add_cosebis(s, bins, En, scale_cut, Bn=None)[source]¶
Add COSEBIs Eₙ (required) and Bₙ (optional) for one scale cut.
- Parameters:
s (sacc.Sacc) – Target, mutated in place.
En (array_like) – E-mode COSEBI amplitudes, one per logarithmic mode
n(1-based).scale_cut (tuple of float) –
(theta_min, theta_max)in arcmin, stored on every point as thetheta_min/theta_maxtags; multiple cuts coexist in one file, told apart by these tags.Bn (array_like, optional) – B-mode COSEBI amplitudes at the same
n. Defaults toNoneand is then simply not written. The[En; Bn]layout, when both are present, matches the COSEBI covariance.
- add_pure_eb(s, bins, theta, xip_E, xim_E, xip_B=None, xim_B=None, xip_amb=None, xim_amb=None, *, grid='reporting')[source]¶
Add pure E-mode (required) plus whichever of B/ambiguous were computed.
Blocks are inserted in
PURE_KEYSorder (xip_E, xim_E, xip_B, xim_B, xip_amb, xim_amb), matchingb_modes._EB_KEYSand the pure-EB covariance layout — whichever subset is present.- Parameters:
s (sacc.Sacc) – Target, mutated in place.
theta (array_like) – Angular separations (arcmin), shared by every block written.
xip_E (array_like) – The pure E-mode correlation functions at
theta.xim_E (array_like) – The pure E-mode correlation functions at
theta.xip_B (array_like, optional) – The pure B-mode correlation functions. Both default to
None; the pair is written together or not at all — supply both or neither.xim_B (array_like, optional) – The pure B-mode correlation functions. Both default to
None; the pair is written together or not at all — supply both or neither.xip_amb (array_like, optional) – The ambiguous-mode correlation functions. Both default to
None; same both-or-neither rule as B.xim_amb (array_like, optional) – The ambiguous-mode correlation functions. Both default to
None; same both-or-neither rule as B.grid (str, optional) – Stored as the
gridtag on every point (default'reporting'), joining ξ’s theta-consistency group inmerge’s guard.
- add_rho(s, k, theta, rho_p, rho_m, *, grid='reporting')[source]¶
Add a ρ_k PSF statistic (ρ+ then ρ−) on the
psf_starstracer.- Parameters:
s (sacc.Sacc) – Target, mutated in place.
k (int) – ρ index (0…5).
theta (array_like) – Angular separations (arcmin).
rho_p (array_like) – ρ_k+ and ρ_k− at
theta.rho_m (array_like) – ρ_k+ and ρ_k− at
theta.grid (str, optional) – Stored as the
gridtag on every point (default'reporting'), joining ξ’s theta-consistency group inmerge’s guard.
- add_tau(s, bins, k, theta, tau_p, tau_m, *, grid='reporting')[source]¶
Add a τ_k PSF-leakage statistic (τ+ then τ−).
- Parameters:
s (sacc.Sacc) – Target, mutated in place.
bins (tuple of int) – Source bin
iand PSF; the τ tracers are(source_i, psf_stars). Onlybins[0]is used.k (int) – τ index (0, 2 or 5).
theta (array_like) – Angular separations (arcmin).
tau_p (array_like) – τ_k+ and τ_k− at
theta.tau_m (array_like) – τ_k+ and τ_k− at
theta.grid (str, optional) – Stored as the
gridtag on every point (default'reporting'), joining ξ’s theta-consistency group inmerge’s guard.
- assemble_covariance(s, blocks)[source]¶
Assemble a
BlockDiagonalCovariancefrom per-statistic blocks.Each block is validated against the current insertion order: its indices must be contiguous and ascending, the blocks must tile
0…len(s.mean)exactly (no gap, no overlap), and each block must be square with a size matching its index span. Any violation raisesValueErrornaming the mismatch. Cross-blocks are zero and implicit — never materialized — because the blocks are passed toadd_covarianceas a list, whichsacc.BaseCovariance.maketurns into aBlockDiagonalCovariance(one FITS table per block, Σ block² on disk rather than a dense N² file).- Parameters:
s (sacc.Sacc) – Target, mutated in place via
add_covariance.blocks (sequence) – Ordered
(selector, cov)pairs (or a mapping of the same). Eachselectoris either an index array, or a(data_type, tracers)/(data_type, tracers, tags)tuple resolved throughs.indices;covis the block’s dense covariance.
- Returns:
s, with the assembledBlockDiagonalCovarianceattached.- Return type:
sacc.Sacc
- add_diagonal_covariance(s, variances)[source]¶
Attach a
DiagonalCovariancefrom a 1-D variance array.The 1-D array is passed straight to
add_covariance(nevernp.diag), which is what makes SACC store aDiagonalCovariance.- Parameters:
s (sacc.Sacc) – Target, mutated in place.
variances (array_like) – Per-point variances,
len == len(s.mean).
- Returns:
s, with theDiagonalCovarianceattached.- Return type:
sacc.Sacc
- _get_pm(s, dtype_p, dtype_m, tracers, **tags)[source]¶
Return
(theta, plus, minus)for a +/− data-type pair.
- get_pseudo_cl(s, bins)[source]¶
Return
(ell_eff, cl_ee, cl_bb, cl_eb, window)for one tracer pair.cl_bb/cl_ebcome backNoneif the file doesn’t carry that component (add_pseudo_clmakes both optional).windowis the sharedsacc.BandpowerWindowrecovered viaget_bandpower_windows; its columns are in the same insertion order as the returnedell_eff/clarrays, so window columnjcorresponds toell_eff[j].
- get_cosebis(s, bins, scale_cut=None)[source]¶
Return
(n, En, Bn)for one tracer pair.Bncomes backNoneif the file doesn’t carry it (add_cosebismakes it optional).
- get_pure_eb(s, bins)[source]¶
Return
(theta, {key: array})for whichever pure-EB blocks exist.xip_E/xim_E are always present (
add_pure_ebrequires them); the dict holds whichever of the B and ambiguous-mode keys (out ofPURE_KEYS: xip_E, xim_E, xip_B, xim_B, xip_amb, xim_amb) the file actually carries — a key absent from the file is simply absent from the dict, not mapped toNone.
- _indices(s, data_type, tracers, **tag_filters)[source]¶
Sacc.indicesthat fails loud instead of selecting nothing.Sacc.indicesreturns an empty array (warning only) when a selection matches no point — e.g. a typo’d tag value, or a float tag filter that is not bitwise-identical to the stored one. Every reader here funnels through this guard so an unmatched selection raises instead of propagating empty arrays downstream.
- _mean(s, data_type, tracers, **tag_filters)[source]¶
Mean values for a selection, in
s.indices(insertion) order.Never re-sort: insertion order is the covariance and bandpower-window order, so returning in
s.indicesorder keeps every reader aligned with the covariance for any file (and ascending for canonically-written files, which the writers enforce).
- _tag(s, data_type, tracers, tag, **tag_filters)[source]¶
Values of
tagfor a selection, in insertion order.
- _mean_optional(s, data_type, tracers, **tag_filters)[source]¶
Mean values for a selection, or
Noneif the file has none.Used by composite readers (
get_pseudo_cl,get_cosebis,get_pure_eb) for the components a writer made optional (BB/EB, COSEBI Bₙ, pure B/ambiguous): absence is a legitimate “this file doesn’t have that piece”, not a typo to fail loud on — unlike_mean/_indices, used for selections that name a component explicitly.
- extract(s, data_type=None, tracers=None, **tag_filters)[source]¶
Extract a sub-Sacc (points + aligned covariance sub-block).
A copy is made and everything not matching the selection is removed, so the covariance sub-block comes out correctly aligned and the original is untouched.
- Parameters:
s (sacc.Sacc) – Source, left unmodified.
data_type (str, optional) – Data type to keep.
tracers (tuple, optional) – Tracer pair to keep, as SACC tracer names (e.g.
("source_0", "source_0")or("source_0", "psf_stars")) — not integer bin indices. This differs deliberately from theadd_*/get_*interface, whosebinsargument takes integer pairs:extractis the generic selection escape hatch, mirroringSacc.keep_selectionand addressing non-source tracers uniformly.**tag_filters – Tag filters (plain kwargs, e.g.
grid='integration').
- Returns:
New Sacc holding only the selected points.
- Return type:
sacc.Sacc
- merge(saccs)[source]¶
Merge several per-statistic Sacc objects into one file’s worth.
A thin wrapper around
sacc.concatenate_data_sets: data points concatenate in input order, tracers shared by several inputs (thesource_iNZ tracers,psf_stars) are stored once, and the covariance combines block-diagonally in the same order — the library requires either all inputs to carry a covariance or none, and raises otherwise (cross-statistic covariance assembly beyond block-diagonal is out of scope here; seeassemble_covariance).Metadata must be consistent: keys present in several inputs must carry equal values (a
type: datafile cannot merge with atype: mockfile), and the union lands on the result. This deliberately replaces the library’s clash behaviour, which mangles clashing keys by appending labels.Grid consistency follows tagging semantics: the
gridtag declares which binning a set of points lives on, so all same-length theta (or ell) arrays under one tag value must be bitwise identical — sacc itself never validates angles across data types/tracers, and a grid that differs only at floating-point level chokes CosmoSIS downstream instead of failing loud here. Different lengths within a tag group pass (scale-cut subsets are legitimate); grids under different tag values are unconstrained (reportingvsintegrationdiffer by design); θ and ℓ are separate domains, each checked against itself only. ℓ series sharing a bitwise-equal grid must also share the bandpower window (series without windows skip that check).- Parameters:
saccs (sequence of sacc.Sacc) – The per-statistic data sets, in the insertion order the merged file should have. Inputs are left unmodified.
- Returns:
The merged data set.
- Return type:
sacc.Sacc
- Raises:
ValueError – If metadata conflicts, a shared tracer differs across inputs, two same-length theta or ell arrays under the same
gridtag value are not bitwise identical, or two ℓ series sharing a grid carry different bandpower windows.
- _grid_groups(s, angle)[source]¶
Nested map
grid-tag-value -> (data_type, tracers) -> point indices.One entry per
(data_type, tracers)series carrying anangle('theta'or'ell') tag, in each series’ own insertion order (never re-sorted), nested under thegridtag value it lives on (Nonefor untagged series) — the shapemerge’s consistency guard checks within each tag value. Indices (not angle values) are kept so the ℓ check can also recover each series’ bandpower window.
- _check_grid_consistency(s, angle)[source]¶
Raise unless same-length
anglearrays under onegridtag match.Consistency follows tagging semantics: the
gridtag declares which binning a series lives on, so all same-length theta (or ell) arrays sharing a tag value must be bitwise identical — sacc never validates angles across data types/tracers, and a grid diverging at floating-point level chokes CosmoSIS downstream instead of failing loud here. Different lengths within a tag value pass (scale-cut subsets are legitimate); series under different tag values are unconstrained (reportingvsintegrationdiffer by design). θ and ℓ are separate domains, each checked against itself only. For ℓ, two series on a bitwise-equal grid must also share the bandpower window (equal window ells and weight matrix); series without windows (foreign files) skip the window check.
- update_statistic(s, sub)[source]¶
Overwrite the values of
s’s points that matchsub’s, in place.The merge-back half of the extract → conceal → merge blinding flow (PRD #241 §4): each point of
subis matched to exactly one point ofsby(data_type, tracers, tags), and that point’s value is replaced. Nothing else changes — insertion order, tags, windows and the covariance are untouched (blinding shifts the mean only), sosub’s own covariance (e.g. the sub-blockextractattaches) is deliberately not consulted. Asubpoint with no match, or with several, raisesValueError.- Parameters:
s (sacc.Sacc) – Target, mutated in place.
sub (sacc.Sacc) – The replacement block, e.g.
extract(s, ...)after concealment.
- save(s, path, *, type)[source]¶
Write
stopath(FITS), overwriting any existing file.- Parameters:
s (sacc.Sacc) – Data set to write; its metadata is stamped in place.
type ({'data', 'mock'}) – Provenance of the underlying catalogue, stored as the required
typemetadata tag (PRD #241 §4, “Mocks vs data”). The caller — the pipeline computing the data vector — knows whether its input catalogue is a mock; there is deliberately no default.loadrefusestype='data'files that are not blinded.
- load(path, *, allow_unblinded=False)[source]¶
Load a Sacc from
path(FITS), failing closed on unblinded data.Every sacc_io file carries a
type: data|mockmetadata tag (stamped bysave); blinded files are additionally stampedconcealed=Trueby Smokescreen. Atype='data'file without that stamp is real, unblinded data, and loading it raises — skipping the blind can never silently expose the measured vector (PRD #241 §4). Mocks load freely, blinded or not.- Parameters:
path (str) – File to load.
allow_unblinded (bool, optional) – Escape hatch for the two legitimate consumers of unblinded data: the blinding step itself (which must read the true vector to conceal it) and the unblinding/verification tooling. Nothing else — no analysis, plotting or inference code — may pass
True.
- Returns:
The loaded data set.
- Return type:
sacc.Sacc
- _twopoint_hdu(name, values, ang, *, ang_unit=None)[source]¶
Build one 2pt BinTableHDU (BIN1/BIN2/ANGBIN/VALUE/ANG).
Reproduces
cosmosis_fitting.py._create_2pt_hdu/cl_to_fitsexactly: same column order and formats, the2PTDATAmarker, the QUANT pair forname, and NZ_SOURCE kernels.ang_unitstampsTUNITon the ANG column (“arcmin” for real-space ξ/τ; unset for Cℓ, whose ANG is ℓ).
- _nz_hdu(s, n_bins)[source]¶
Build the NZDATA HDU from the SACC
source_iNZ tracers.Reproduces
cosmosis_fitting.py.nz_to_fits: Z_MID from the tracerzgrid (assumed uniform), Z_LOW/Z_HIGH as ± half a step, oneBIN{i+1}column per source bin, and the NZDATA/NBIN/NZ header cards. All source bins are required to share thezgrid — the singleZ_MIDaxis of the DES NZDATA table.
- _cov_hdu(matrix, block_names, block_starts, extname='COVMAT', name_in_ctor=False)[source]¶
Build a covariance ImageHDU with
NAME_i/STRT_iblock headers.Reproduces the two covariance builders in
cosmosis_fitting.pycard for card. The blocked ξ/τcovdat_to_fitsbuildsImageHDU(cov)unnamed and stampsCOVDATAthenEXTNAMEfrom a dict; thecov_cl_to_fitsCELL covariance buildsImageHDU(cov, name="COVMAT_CELL")(so the EXTNAME card is created early, with astropy’s standard comment) before re-stamping.name_in_ctorselects the second form so the card order matches exactly.
- _type_major_xi(s, bins)[source]¶
Return
(theta, xip, xim)for one bin pair from the SACC reporting grid.get_xialready returns each statistic in insertion (= ascending θ) order; the type-major split (all ξ+, then all ξ−) is exactly the two arrays it hands back, so no further permutation is needed for a single pair.
- _require_single_bin(s, n_bins)[source]¶
Fail fast unless the SACC is a valid single-bin ξ product.
The converter emits the single-bin 2pt-FITS today’s CosmoSIS pipeline reads (BIN1/BIN2 all 1, one NZ column). A tomographic SACC would otherwise slip through silently —
n_binsalone drives the NZDATA column count while the ξ/covariance are read from bin(0, 0)only, so a 2-bin file would emit aNBIN=2n(z) beside a data vector holding just the(0, 0)pair. Guards both the empty-ξ case and the single-bin contract; tomographic emission lands with the tomographic round.
- sacc_to_twopoint_fits(s, path, *, rho_stats_hdu=None, tau_stats_hdu=None, n_bins=1)[source]¶
Convert an analysis SACC to a CosmoSIS 2pt-FITS file.
The assembled
HDUListmatches today’scosmosis_fitting.pyproduct for the configuration the SACC describes: PRIMARY, NZ_SOURCE, COVMAT, then (if present) COVMAT_CELL, XI_PLUS, XI_MINUS, (if present) CELL_EE / CELL_BB, and (if the rho/tau sidecars are supplied) TAU_0_PLUS, TAU_2_PLUS, RHO_STATS. The data vector and its covariance are laid out type-major (all ξ+, then all ξ−, then the τ blocks), which is the DEStwopointconvention CosmoSIS reads.- Parameters:
s (sacc.Sacc) – Analysis SACC (reporting ξ±, optional pseudo-Cℓ, covariance, and — for the ρ/τ product — the τ data points; see
rho_stats_hdu).path (str) – Output FITS path (overwritten).
rho_stats_hdu (astropy.io.fits.BinTableHDU, optional) – The rho-stats / tau-stats sidecar HDUs, copied verbatim as today’s assembly does. Required together to write the ρ/τ product; the SACC alone cannot rebuild the
varrho_*columns Sacha’s fork reads. When omitted, a pure ξ (± Cℓ) product is written.tau_stats_hdu (astropy.io.fits.BinTableHDU, optional) – The rho-stats / tau-stats sidecar HDUs, copied verbatim as today’s assembly does. Required together to write the ρ/τ product; the SACC alone cannot rebuild the
varrho_*columns Sacha’s fork reads. When omitted, a pure ξ (± Cℓ) product is written.n_bins (int, optional) – Number of source tomographic bins. Must be
1: this converter emits the single-bin 2pt-FITS today’s CosmoSIS pipeline consumes. Tomographic emission (multiple bin pairs, per-pair BIN1/BIN2, one NZ column per bin) lands with the tomographic round; the converter fails fast on anything else rather than silently truncating to bin(0, 0).
- Returns:
The assembled list, also written to
path.- Return type:
astropy.io.fits.HDUList
- Raises:
ValueError – If the SACC has no ξ points; if
n_bins != 1or the SACC’s ξ tracer pairs are anything other than exactly{(source_0, source_0)}(the single-bin contract); or if exactly one of the ρ/τ sidecars is supplied.
- _build_cell(s, bins)[source]¶
Build the CELL_EE 2pt HDU plus the COVMAT_CELL HDU from the SACC pseudo-Cℓ.
Returns
(None, None)when the SACC has no pseudo-Cℓ. Only CELL_EE is emitted — the harmonic2pt_likefitsdata_sets=CELL_EE, and today’s assembly appends CELL_EE alone (it builds a CELL_BB HDU but discards it). The SACC still carries EE/BB/EB with bandpower windows for the B-mode null-test path; this converter surfaces only the block CosmoSIS reads. The CELL covariance (the EE bandpower covariance) lives in its own COVMAT_CELL ImageHDU, matching today’s product.
- _build_covmat(s, bins, *, use_rho_tau)[source]¶
Assemble the blocked COVMAT (ξ± type-major, then the τ blocks).
The ξ covariance is pulled from the SACC as the contiguous ξ+/ξ− block for the pair and permuted from pair-major (SACC) to type-major (2pt-FITS). Under
use_rho_tauthe τ_0/τ_2 covariance blocks are appended block-diagonally with zero ξ↔τ cross-blocks, exactly ascovdat_to_fitsbuilds them.
- _build_rho_tau(rho_stats_hdu, tau_stats_hdu, theta, use_rho_tau)[source]¶
Build the TAU_{0,2}_PLUS 2pt HDUs and the verbatim RHO_STATS HDU.
Mirrors
tau_to_fits/rho_to_fits: τ_0/τ_2 read theirtau_k_pcolumns onto the shared ξ θ grid (consistency step); RHO_STATS is copied verbatim from the sidecar with its θ column forced onto the ξ grid. Thevarrho_*columns ride along in the copy — they are why the sidecar is required (the SACC cannot supply them).
- nz_table(s, n_bins)[source]¶
Stack the SACC
source_iNZ tracers into a OneCovariance n(z) table.- Parameters:
s (sacc.Sacc) – SACC holding
source_0 … source_{n_bins-1}NZ tracers.n_bins (int) – Number of tomographic source bins to write.
- Returns:
Array of shape
(n_z, n_bins + 1): column 0 the shared redshift grid, columns1 … n_binsthe per-binn(z). This is the OneCovariance combined-file layout (redshift n_1(z) … n_N(z)).- Return type:
- Raises:
ValueError – If any source bin is missing, or if the bins do not share one z grid (OneCovariance’s combined file has a single redshift column, so the grids must agree bin-for-bin).
- write_nz(s, path, n_bins, *, dir_key='zlens_directory', header=True)[source]¶
Write the OneCovariance combined n(z) input file from a SACC.
OneCovariance reads the source redshift distribution as a plain whitespace-delimited text file whose column 0 is the shared redshift grid and whose remaining columns are the per-bin
n(z)(redshift n_1(z) … n_N(z)) — noz_low/z_highedges. This writes that file from the SACCsource_iNZ tracers and returns the[redshift]config stanza that points OneCovariance at it.- Parameters:
s (sacc.Sacc) – Analysis SACC with the
source_iNZ tracers.path (str or pathlib.Path) – Output text-file path (overwritten). Its directory + basename become the
[redshift]directory/file config values.n_bins (int) – Number of tomographic source bins to write.
dir_key (str, optional) – Config key for the redshift directory. Default
"zlens_directory"(upstream canonical). Pass"z_directory"for the UNIONS template driven bypseudo_cl.py._modify_onecov_config.header (bool, optional) – If
True(default) prepend a# redshift n_1(z) …comment header naming the columns; OneCovariance’sgenfromtxt-style reader ignores it. SetFalsefor a bare numeric file.
- Returns:
The
[redshift]config stanza (seenz_config_stanza()), naming the file just written.- Return type:
- nz_config_stanza(directory, filename, *, dir_key='zlens_directory', value_loc='mid')[source]¶
Build the OneCovariance
[redshift]config stanza for an n(z) file.- Parameters:
directory (str) – Directory holding the n(z) file (OneCovariance
*_directoryvalue).filename (str) – n(z) file basename (OneCovariance
zlens_filevalue).dir_key (str, optional) – Directory config key —
"zlens_directory"(upstream) or"z_directory"(UNIONS template). Default"zlens_directory".value_loc (str, optional) –
value_loc_in_lensbin— where in each histogram bin the tabulatedn(z)value sits (mid/left/right). Default"mid", matching the bin-centred grids the SACC stores.
- Returns:
The
[redshift]key/value pairs:{dir_key: directory, "zlens_file": filename, "value_loc_in_lensbin": value_loc}. Assign these underconfig["redshift"]of a OneCovarianceconfigparserconfig.- Return type:
- read_nz(path)[source]¶
Read a OneCovariance combined n(z) file back to
(z, nz_columns).Inverse of
write_nz()(the numeric round-trip; the config stanza is not stored in the file). Comment/header lines are skipped.- Parameters:
path (str or pathlib.Path) – n(z) text file (column 0 = z, columns 1… = per-bin n(z)).
- Returns:
(z, nz)wherezis the shared redshift grid (shape(n_z,)) andnzis the per-bin distributions (shape(n_z, n_bins)).- Return type:
- covariance_blocks(cov_list, selectors, *, gaussian=True)[source]¶
Reshape a OneCovariance
covariance_listtable into SACC cov blocks.OneCovariance emits a flat
covariance_list_*.dattable with one row per(i, j)element pair (row-major,k = i·n + j); the covariance value lives in column 10 (Gaussian) or column 9 (Gaussian+non-Gaussian). This reshapes the flat table into dense square block(s) — reusingsp_validation.statistics.cov_from_one_covariance()for the per-block reshape — and pairs each with its SACC selector, ready forsp_validation.assemble_covariance().Single-statistic case: pass the whole table and one selector; you get one
(selector, dense)block. Multi-statistic case (tomography-ready): pass a sequence of(selector, sub_table)pairs — eachsub_tablea contiguous slice of the flat output for one statistic / bin-pair — and each is reshaped and re-paired with its selector in order. The API is thus shaped to extend to multi-probe blocking without over-fitting the single-bin case.- Parameters:
cov_list (numpy.ndarray or sequence) – Either the flat OneCovariance table (2-D array, one row per pair) for a single block, or — for the multi-block form — a sequence of
(selector, sub_table)pairs. In the multi-block formselectorsmust beNone(the selectors travel with the sub-tables).selectors (selector or None) – For the single-block form, the SACC selector for the whole table (a
(data_type, tracers[, tags])tuple or an index array, asassemble_covariance()accepts). Must beNonefor the multi-block form.gaussian (bool, optional) – Select the Gaussian-only column (
True, default) or the Gaussian+non-Gaussian column (False); passed straight through tocov_from_one_covariance.
- Returns:
Ordered
(selector, dense_cov)pairs, directly consumable byassemble_covariance(s, blocks).- Return type: