Data representation and regression#

MultiData groups visibilities into UV bins for a single observation. MultiEpochData adds an epoch axis and is the input representation used by Cross-GPR models. MultiGPRegressor binds covariance components to either representation, evaluates the likelihood, and predicts components.

Adapt data cubes to the matrices consumed by ML-GPR.

MultiData handles one cube; MultiEpochData handles cubes with a shared frequency and UV layout. Predictions are converted back to denormalized data cubes.

ps_eor.ml_gpr.multidata.get_uv_bins(umin, umax, du)[source]#

Return constant-width UV bins spanning umin to umax.

ps_eor.ml_gpr.multidata.get_n_uniform_uv_bins(u_min, u_max, n_bins)[source]#

Return n_bins with approximately equal UV-cell occupancy.

ps_eor.ml_gpr.multidata.validate_uv_bins(uv_bins)[source]#

Validate and return UV bins as a finite (n_bins, 2) array.

Gaps are allowed, but bins must be ordered, non-overlapping, and have strictly increasing bounds.

ps_eor.ml_gpr.multidata.get_uv_bin_masks(ru, uv_bins, require_nonempty=True)[source]#

Return a disjoint mask for each uv bin.

Internal upper edges are excluded; only the final bin includes its upper edge. Thus a visibility exactly on a shared boundary belongs to the bin on its right and is never counted twice.

ps_eor.ml_gpr.multidata.resolve_norm_factor(data, norm_factor)[source]#

Return a finite, positive data normalization factor.

class ps_eor.ml_gpr.multidata.AbstractMultiData[source]#

Bases: object

Interface shared by single- and multi-epoch GP data adapters.

property ref_cube#

Cube defining the frequency and uv layout, shared by all epochs.

resolve_uv_bins(uv_bins, uv_bins_du, uv_bins_n_uni)[source]#

Validate explicit UV bins or construct them from the data range.

c2f(c, axis=1)[source]#

Place real and imaginary visibility parts side by side.

f2c(f)[source]#

Inverse of c2f().

get_split_idx()[source]#

Return one visibility mask per UV bin.

get_freqs(fill_gaps=False)[source]#

Return the observed or gap-filled frequency grid.

make_X(freqs)[source]#

GP input grid for the given frequencies.

split(cubes=None)[source]#

Real-valued data matrix per uv bin.

get_noise_variance_split()[source]#

Per-uv-bin noise variance, for binding the noise kernel.

get_uv_ps_fct(uv_bins_du=None, uv_log_poly_deg=4)[source]#

Angular power spectrum vs baseline, for use_uv_ps=True kernels.

get_uv_weight_split()[source]#

Per-uv-bin likelihood weights, for use_uv_weight=True.

gen_cube(Ys_and_covYs, fill_gaps=False)[source]#

Rebuild a data cube from per-uv-bin predicted (mean, covariance).

class ps_eor.ml_gpr.multidata.MultiData(i_cube, noise_cube=1, uv_bins_du=25, norm_factor=None, uv_bins=None, uv_bins_n_uni=0)[source]#

Bases: AbstractMultiData

One data cube, ready for a regressor.

Parameters:
  • i_cube – the data, a CartDataCube.

  • noise_cube – Matching noise cube or scalar variance.

  • uv_bins_du – uv bin width. Alternatively pass uv_bins directly, or uv_bins_n_uni for that many equal-occupancy bins.

  • norm_factor – Data scale. By default, the real part has unit variance.

property ref_cube#

Cube defining the frequency and uv layout, shared by all epochs.

make_X(freqs)[source]#

Return the (n_freq, 1) frequency grid in MHz.

split(cubes=None)[source]#

Real-valued data matrix per uv bin.

get_noise_variance_split()[source]#

Per-uv-bin noise variance, for binding the noise kernel.

get_uv_ps_fct(uv_bins_du=None, uv_log_poly_deg=4)[source]#

Angular power spectrum vs baseline, for use_uv_ps=True kernels.

get_uv_weight_split()[source]#

Per-uv-bin likelihood weights, for use_uv_weight=True.

gen_cube(Ys_and_covYs, fill_gaps=False)[source]#

Draw one data-cube realization from binned GP predictions.

ps_eor.ml_gpr.multidata.combine_epoch_cubes(cubes)[source]#

Average per-epoch cubes into one, weighted when weight cubes exist.

Averaging suppresses components that are incoherent between epochs.

class ps_eor.ml_gpr.multidata.MultiEpochData(i_cubes, epoch_times, noise_cubes=1, uv_bins_du=25, norm_factor=None, uv_bins=None, uv_bins_n_uni=0)[source]#

Bases: AbstractMultiData

Several epochs of the same field, ready for a regressor.

Epochs are stored on an epoch-major (frequency, time) grid. Every signal component must use TimeKron.

Parameters:
  • i_cubes – one cube per epoch. All must share a frequency and uv layout.

  • epoch_times – Strictly increasing observation times. Time-kernel coherence scales use the same units.

  • noise_cubes – one noise cube per epoch, or a scalar variance.

  • uv_bins_du – as in MultiData.

  • norm_factor – One normalization shared by all epochs.

use_uv_weight is not supported here.

property ref_cube#

Cube defining the frequency and uv layout, shared by all epochs.

property n_epochs#

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4

make_X(freqs)[source]#

Return the epoch-major (frequency, time) GP grid.

split(cubes=None)[source]#

Return real-valued data matrices with epochs stacked by UV bin.

get_noise_variance_split()[source]#

Return noise variance by UV bin, epoch, and frequency.

get_uv_ps_fct(uv_bins_du=None, uv_log_poly_deg=4)[source]#

Fit the angular power spectrum of the epoch-mean cube.

get_uv_weight_split()[source]#

Not available: use_uv_weight is unsupported for multi-epoch data.

gen_cube(Ys_and_covYs, fill_gaps=False)[source]#

Draw one joint realization and return one cube per epoch.

Drawing from the full covariance preserves cross-epoch correlations.

Condition ML-GPR covariance models and predict their components.

MultiGPRegressor evaluates the likelihood at the current hyperparameters. Samplers in ps_eor.ml_gpr.samplers fit those hyperparameters.

ps_eor.ml_gpr.regressor.batched_cholesky(K, max_rel_jitter=0.1, return_jitter=False)[source]#

Cholesky of a batch of (n_bins, n, n) covariances.

Falls back to per-bin jitter if the vectorized factorization fails. With return_jitter=True, also returns the largest relative jitter used.

class ps_eor.ml_gpr.regressor.MultiGPRegressor(multi_data, components: dict, use_uv_weight=False)[source]#

Bases: object

A covariance model conditioned on data.

Parameters:
  • multi_data – a MultiData or MultiEpochData, or anything exposing the same interface.

  • components – Named kernels plus a 'noise' entry. Multi-epoch signal components must use TimeKron.

  • use_uv_weight – weight the likelihood’s data term by the per-uv-bin weights from the data. Not supported for multi-epoch data.

Kernels are bound to the data during construction.

condition()[source]#

Factorize K and solve for the data at the current hyperparameters.

Nothing is fitted: hyperparameters come from a sampler. predict() and log_marginal_likelihood() both do this themselves when needed, so calling it directly only controls when the Cholesky happens.

predict(kern=None, X_p=None)[source]#

Posterior mean and covariance of a component.

Parameters:
  • kern – the component to predict, e.g. from get_kern_part(). Defaults to the full signal model, excluding noise – predicting a component never includes it.

  • X_p – grid to predict on. Defaults to the data’s own grid; pass another to interpolate, e.g. across flagged channels.

Returns (means, cov), one entry per uv bin.

predict_cube(kern=None, fill_gaps=False)[source]#

Like predict(), but returns a data cube.

One realization is drawn from the posterior, so repeated calls differ. With fill_gaps=True the cube is predicted on the gap-filled frequency grid. Multi-epoch data gives a list, one cube per epoch.

get_interpolated_i_cube()[source]#

The data with flagged channels filled in by the GP.

Predicts on the gap-filled grid using the full model, then writes the observed data back over the channels that were actually measured.

log_marginal_likelihood()[source]#

Log marginal likelihood at the current hyperparameters – the quantity samplers explore.

raw_param_overrides(entries, naturals)[source]#

Parameter overrides for log_marginal_likelihood_from_raw().

Converts natural values to GPyTorch’s raw constrained representation.

log_marginal_likelihood_from_raw(raw_overrides)[source]#

Log marginal likelihood at externally supplied parameters, differentiable with respect to them.

Unlike log_marginal_likelihood() this neither mutates the kernel nor touches the cache, which is what lets a gradient sampler evaluate and differentiate proposed values.

ps_eor.ml_gpr.regressor.get_kern_part(components: dict, pattern: str)[source]#

Sum of the components whose labels match pattern.

pattern is one or more ;-separated glob patterns, e.g. 'fg*' or 'eor_ratquad;eor_vae'. A shared-fraction component also accepts the ':coherent' and ':independent' suffixes. Every selection must match at least one component. This is how a component is selected for prediction.