Data cubes (ps_eor.datacube)#

Data, image, weight, and noise cubes used throughout ps_eor.

The main analysis container is CartDataCube: a complex visibility array shaped (frequency, spatial mode), together with its frequency and UV coordinates, image metadata, and optional CartWeightCube. Keeping those objects together lets filtering, foreground fitting, and power-spectrum estimation preserve the geometry and statistical weights of the data.

For calibrated, frequency-dependent FITS images, the usual entry point is CartDataCube.load_from_fits_image_and_psf(). It Fourier-transforms the images, converts Jy/PSF to Kelvin when requested, uses the matching PSF FITS files for the normalization and visibility weights, and restricts the result to the requested baseline range:

import numpy as np

from ps_eor import datacube, psutil

image_files = psutil.sort_by_fits_key(image_files, 'CRVAL3')
psf_files = psutil.sort_by_fits_key(psf_files, 'CRVAL3')

cube = datacube.CartDataCube.load_from_fits_image_and_psf(
    image_files,
    psf_files,
    umin=50,
    umax=250,
    theta_fov=np.deg2rad(4),
    int_time=10,
    total_time=10 * 3600,
)
cube.save('visibilities.h5')

Here umin and umax are in wavelengths, theta_fov is in radians, and observing times are in seconds. When no PSF image is available, CartDataCube.load_from_fits_image() provides an unweighted alternative.

Saved cubes retain their weights and metadata. Frequency slicing returns a new cube, while methods named filter_* generally modify the cube in place:

cube = datacube.CartDataCube.load('visibilities.h5')
subband = cube.get_slice(120e6, 130e6)
subband.filter_uvrange(60, 200)

Use DataCube.copy() before an in-place operation when the original cube must be retained.

ps_eor.datacube.get_common_idx(cube1, cube2)[source]#

Return frequency and spatial-mode masks shared by two cubes.

ps_eor.datacube.get_common_cube(cube1, cube2, only_frequency=False)[source]#

Return two cubes restricted to their common coordinates.

ps_eor.datacube.concatenate_datacubes(cubes)[source]#

Concatenate Cartesian cubes with a shared UV grid along frequency.

class ps_eor.datacube.Mask(masks=None)[source]#

Bases: object

A sum of image-domain masks evaluated from cube metadata.

generate(meta_data)[source]#

Evaluate the combined mask on the grid described by meta_data.

Returns:

the mask image, shape meta_data.shape.

Return type:

ndarray

get_power(meta_data)[source]#

Return the mean squared mask response.

get_area(meta_data, normalize=False)[source]#

Effective area of the mask: its mean response.

Parameters:
  • meta_data – the image geometry to evaluate on.

  • normalize (bool) – divide by the peak response.

Returns:

the (optionally peak-normalized) mean response.

Return type:

float

class ps_eor.datacube.MaskProd(m1, m2)[source]#

Bases: Mask

Pairwise product of two mask collections.

generate(meta_data)[source]#

Evaluate and sum the paired mask products.

class ps_eor.datacube.WindowFunction(name, circular=True)[source]#

Bases: Mask

Two-dimensional spectral window applied in the image plane.

static parse_winfct_str(s)[source]#

Parse a SciPy window name and optional numeric argument.

static from_meta(image_meta)[source]#

Restore a window function from image metadata.

to_meta(image_meta)[source]#

Store this window function in image metadata.

generate_window(nx)[source]#

Generate an nx × nx window.

generate(meta_data)[source]#

Generate the window at the image size given by meta_data.shape.

class ps_eor.datacube.BasePrimaryBeam(masks, freq=None)[source]#

Bases: Mask

Base class for frequency-dependent primary-beam masks.

set_freq(freq)[source]#

Set the default evaluation frequency in Hz.

get_freq(freq=None)[source]#

Return an explicit frequency or the configured default.

class ps_eor.datacube.PrimaryBeam(antenna_diameter, alpha_tapering, beam_type, freq=None)[source]#

Bases: BasePrimaryBeam

Analytic primary beam defined by an effective aperture diameter.

static from_name(name)[source]#

Construct a primary beam by name.

name is either a registered telescope (e.g. 'lofar_hba', 'nenufar') or a custom ant_<diameter>_<alpha>_<beam_type> string.

Returns:

the matching beam.

Return type:

PrimaryBeam

get_fwhm(freq=None)[source]#

Return the beam FWHM in radians.

generate_beam(fwhm, res, shape)[source]#

Render the beam on a Cartesian grid.

Parameters:
  • fwhm – beam full-width at half-maximum, in radians.

  • res – pixel size, in radians.

  • shape – image shape (nx, ny).

Returns:

the beam image.

Return type:

ndarray

generate(meta_data, freq=None)[source]#

Render the beam on the grid given by meta_data at freq (Hz; default the configured frequency).

Returns:

the beam image, shape meta_data.shape.

Return type:

ndarray

class ps_eor.datacube.LofarHBAPrimaryBeam[source]#

Bases: PrimaryBeam

Analytic beam approximation for a LOFAR HBA station.

class ps_eor.datacube.AartfaacA12HBAPrimaryBeam[source]#

Bases: PrimaryBeam

Analytic beam approximation for an AARTFAAC-12 HBA tile.

class ps_eor.datacube.LofarLBAInnerPrimaryBeam[source]#

Bases: PrimaryBeam

Analytic beam approximation for LOFAR LBA inner mode.

class ps_eor.datacube.LofarLBAOuterPrimaryBeam[source]#

Bases: PrimaryBeam

Analytic beam approximation for LOFAR LBA outer mode.

class ps_eor.datacube.SkaLowPrimaryBeam[source]#

Bases: PrimaryBeam

Analytic beam approximation for an SKA-Low station.

class ps_eor.datacube.NenuFARPrimaryBeam[source]#

Bases: PrimaryBeam

Analytic beam approximation for a NenuFAR mini-array.

class ps_eor.datacube.NoPrimaryBeam[source]#

Bases: BasePrimaryBeam

Unit primary beam.

generate(meta_data, freq=None)[source]#

Return a unit-response image.

class ps_eor.datacube.ImageMetaData(wcs, shape, **kargs)[source]#

Bases: object

WCS, image shape, and ps_eor-specific FITS metadata.

set(name, value)[source]#

Set a metadata value.

get(name, default=None)[source]#

Return metadata value name, or default if absent.

remove(name)[source]#

Delete metadata key name if present.

update(d)[source]#

Merge the mapping d into the metadata.

property res#

Angular pixel size (resolution), in radians.

property theta_fov#

Image field of view, in radians (shape[0] * res).

property total_time#

Total observing time in seconds (PETOTTIM; 1 if unset).

property int_time#

Integration (correlator dump) time in seconds (PEINTTIM; 1 if unset).

property freq_width#

Frequency-axis increment (channel spacing) in Hz, from the WCS.

property chan_width#

PECHWIDT if set, else the WCS increment (differs from freq_width when channels were averaged).

Type:

Physical channel width in Hz

property obs_mjd#

Observation reference time (MJD), from the WCS.

property ra_dec_center_deg#

Phase-centre (RA, Dec) in degrees, from the WCS.

property win_fct#

The spectral WindowFunction for this image (from its metadata).

property win_fct_power#

The window function’s power normalization (see WindowFunction.get_power()).

property win_fct_area#

The window function’s effective area (see WindowFunction.get_area()).

slice(x_s, x_e, y_s, y_e)[source]#

Update the WCS and shape for an image-plane slice.

average_freqs(n_freqs)[source]#

Update channel width after averaging n_freqs channels.

items(add_origin=False)[source]#

Return metadata as (key, value) pairs.

to_header(add_origin=False)[source]#

Return an Astropy FITS header.

static from_res(res, shape, **kargs)[source]#

Build metadata from a pixel size and image shape (phase centre at the origin).

Parameters:
  • res – angular pixel size, in radians.

  • shape – image shape (nx, ny).

  • **kargs – extra FITS-style metadata (PE* / WSC* / allowed keys).

Returns:

the new metadata.

Return type:

ImageMetaData

static from_header(header, shape)[source]#

Build metadata from a FITS header and image shape.

Parameters:
  • header – an Astropy FITS header (its WCS and PE* / WSC* keys).

  • shape – image shape (nx, ny).

Returns:

the new metadata.

Return type:

ImageMetaData

copy()[source]#

Return an independent metadata copy.

class ps_eor.datacube.ImageCube(image_cube, freqs, meta)[source]#

Bases: object

Base frequency-dependent image cube.

get_slice(freq_start, freq_end)[source]#

The channels within [freq_start, freq_end] (Hz).

Returns:

the frequency-sliced cube.

Return type:

CartImageCube

get_freq(freq)[source]#

The single channel at or just above freq (Hz).

Returns:

a one-channel cube.

Return type:

CartImageCube

class ps_eor.datacube.CartImageCube(image_cube, freqs, meta)[source]#

Bases: ImageCube

Frequency cube of Cartesian sky images.

trim(new_theta_fov)[source]#

Trim the image in place to new_theta_fov radians.

apply_window_function(win_fct, add_to_meta=True)[source]#

Apply an image-plane window in place.

ft(umin, umax)[source]#

Fourier transform image cube and return a CartDataCube.

Parameters:
  • umin (float) – Min U in wavelength

  • umax (float) – Max U in wavelength

Returns:

a new visibility cube.

Return type:

CartDataCube

save_to_fits(fname, overwrite=True)[source]#

Write the image cube to a FITS file (in Kelvin).

Parameters:
  • fname – output file path.

  • overwrite (bool) – replace an existing file.

plot(fmhz='med', action_fct=None, theta_lines=None, ax=None, title=None, auto_scale_quantiles=None, **kargs)[source]#

Show one channel (or a frequency reduction) as a sky image.

Parameters:
  • fmhz – channel to show, in MHz, or 'med' / 'first' / 'last' (ignored if action_fct is given).

  • action_fct – a reducer f(data, axis=0) over frequency instead of one channel.

  • theta_lines (list) – angular radii (deg) at which to draw guide circles.

  • ax – matplotlib Axes (new figure if None).

  • auto_scale_quantiles(lo, hi) quantiles for the colour limits.

  • **kargs – forwarded to imshow.

plot_slice(ax=None, **kargs)[source]#

Plot the central spatial slice as a function of frequency.

copy()[source]#

Return an independent deep copy of this image cube.

class ps_eor.datacube.GriddedCartDataCube(g_vis, g_uu, g_vv, freqs, meta)[source]#

Bases: object

Visibility cube stored on a regular Cartesian UV grid.

image(res=None, low_memory=False)[source]#

Fourier-transform the gridded visibilities to the image plane.

Parameters:
  • res – output pixel size, in radians (default: set by the uv grid).

  • low_memory (bool) – transform one channel at a time.

Returns:

the sky image cube.

Return type:

CartImageCube

class ps_eor.datacube.DataCubeCombiner(umin, umax, weighting_mode='uv', inhomogeneous=False, w_square=False)[source]#

Bases: object

Incrementally combine visibility cubes using configurable weights.

add(cube, night_id)[source]#

Accumulate one cube and its observing-night identifier.

get(min_n_nights=None)[source]#

The inverse-variance-weighted combination of all added cubes.

Parameters:

min_n_nights – drop channels covered by fewer than this many nights.

Returns:

the combined cube (None if nothing was added).

Return type:

CartDataCube

class ps_eor.datacube.DataCube(data, freqs, weights=None)[source]#

Bases: object

Base class for frequency-dependent data and optional weights.

get_unique_xy()[source]#

The unique (u, v) coordinates of the cube’s modes. Subclass hook.

set_weights(weights_cube)[source]#

Attach a copy of weights_cube.

new_with_data(data, weights=None, freqs=None)[source]#

Build a cube of the same type/geometry with new data (and, optionally, weights / freqs). Subclass hook.

get_slice_from_idx(idx_freqs)[source]#

The channels selected by idx_freqs (a mask, index array, or slice).

Returns:

the frequency-selected cube (same type as self).

Return type:

DataCube

get_slice(freq_start, freq_end)[source]#

The channels within [freq_start, freq_end] (Hz).

Returns:

the frequency-sliced cube.

Return type:

DataCube

get_freq(freq)[source]#

The single channel at or just above freq (Hz).

Returns:

a one-channel cube.

Return type:

DataCube

filter_uv_from_index(idx_uv)[source]#

Filter spatial modes in place using idx_uv.

make_diff_cube()[source]#

Adjacent-channel differences (times sqrt(0.5)) – a signal-free, noise-like cube used to estimate the noise level.

Returns:

the difference cube (one fewer channel).

Return type:

DataCube

make_diff_cube_interp()[source]#

Like make_diff_cube() but padded back to the original number of channels (last difference repeated).

Returns:

the difference cube (same channel count).

Return type:

DataCube

copy()[source]#

Return an independent cube copy.

static load(filename)[source]#

Load a data cube from HDF5, dispatching on the stored format.

Returns:

whichever the file holds.

Return type:

CartDataCube or SphDataCube

class ps_eor.datacube.CartDataCube(data, uu, vv, freqs, meta, weights=None)[source]#

Bases: DataCube

Complex visibilities on a non-gridded Cartesian UV plane.

get_unique_xy()[source]#

A per-mode key encoding (u, v), used to match modes between cubes.

Returns:

one float per mode, combining rounded uu and vv.

Return type:

ndarray

static load_from_fits(files, umin, umax, convert_jy2k=True)[source]#

Build a visibility cube from UV-plane FITS files (already gridded uv, not images).

Parameters:
  • files – UV-plane FITS files, in frequency order.

  • umin – baseline range kept, in wavelengths.

  • umax – baseline range kept, in wavelengths.

  • convert_jy2k (bool) – convert from Jy to Kelvin.

Returns:

the visibility cube.

Return type:

CartDataCube

static load_from_fits_image(files, umin, umax, theta_fov, imager_scale_factor=None, convert_jy2k=True, compat_wscnormf='old_normpsf', int_time=None, total_time=None, window_function=None, data_dtype=<class 'numpy.complex128'>)[source]#

Build a visibility cube from frequency-dependent FITS images (no PSF).

Images are optionally trimmed and windowed, converted from Jy/PSF to Kelvin, Fourier-transformed, and restricted to [umin, umax]. Use load_from_fits_image_and_psf() when a PSF is available (it also derives weights).

Parameters:
  • files – FITS image files, in frequency order.

  • umin – baseline range kept, in wavelengths.

  • umax – baseline range kept, in wavelengths.

  • theta_fov – output field of view, in radians.

  • imager_scale_factor – explicit PSF area (pixel units); by default taken from WSCNORMF or a Gaussian-beam approximation.

  • convert_jy2k (bool) – convert Jy/PSF images to Kelvin.

  • compat_wscnormf (str) – interpretation of legacy WSCNORMF metadata.

  • int_time – integration and total observing time (s), stored in the metadata.

  • total_time – integration and total observing time (s), stored in the metadata.

  • window_function – optional image-plane WindowFunction.

Returns:

the visibility cube (unweighted).

Return type:

CartDataCube

static load_from_fits_image_and_psf(files, files_psf, umin, umax, theta_fov, int_time=None, total_time=None, convert_jy2k=True, min_weight_ratio=0.01, trim_method='before', use_wscnormf=False, compat_wscnormf='old_normpsf', window_function=None, abs_min_weight=0.5, data_dtype=<class 'numpy.complex128'>)[source]#

Build a visibility cube from matched image + PSF FITS files.

The standard loader when a per-frequency PSF is available: it divides the imaged visibilities by the PSF (undoing the dirty-image sampling response) and derives per-mode weights from that PSF, giving a properly weighted cube.

Parameters:
  • files – image FITS files, in frequency order.

  • files_psf – matching PSF FITS files, one per image.

  • umin – baseline range kept, in wavelengths.

  • umax – baseline range kept, in wavelengths.

  • theta_fov – output field of view, in radians.

  • int_time – integration and total observing time (s), stored in the metadata for later noise / SEFD estimation.

  • total_time – integration and total observing time (s), stored in the metadata for later noise / SEFD estimation.

  • convert_jy2k (bool) – convert Jy/PSF images to Kelvin.

  • min_weight_ratio (float) – drop modes whose weight is below this fraction of the per-mode maximum (0 disables).

  • abs_min_weight (float) – absolute floor applied to that threshold.

  • trim_method (str) – 'before' trims to theta_fov before the PSF division, 'after' trims afterwards.

  • use_wscnormf (bool) – normalise from the image WSCNORMF metadata instead of the PSF (weights still come from the PSF files).

  • window_function – optional image-plane WindowFunction.

Returns:

the PSF-weighted visibility cube.

Return type:

CartDataCube

static load_from_hd5(h5_group)[source]#

Deprecated alias for load_from_h5().

static load_from_h5(h5_group)[source]#

Load a Cartesian visibility cube from an open HDF5 group.

static load(filename)[source]#

Load a Cartesian visibility cube (and its weights, if present) from HDF5.

Returns:

the loaded cube.

Return type:

CartDataCube

static join_cubes(cubes)[source]#

Concatenate cubes along frequency, keeping the first copy of any overlapping channels.

Returns:

the joined cube.

Return type:

CartDataCube

save_to_hd5(h5_file, group)[source]#

Deprecated alias for save_to_h5().

save_to_h5(h5_file, group)[source]#

Write this cube into an open HDF5 group.

save(filename)[source]#

Save the cube and optional weights to HDF5.

new_with_data(data, weights=None, freqs=None, interpolate_weights=True)[source]#

A new cube with new data on this cube’s uv geometry.

Parameters:
  • data (n_freqs, n_vis) – the new visibilities.

  • weights – weights to attach (default: this cube’s).

  • freqs – frequencies for data (default: this cube’s).

  • interpolate_weights (bool) – interpolate the weights onto freqs when the frequency grids differ.

Returns:

the new cube.

Return type:

CartDataCube

make_full_cube(umin, umax, output_idx=False)[source]#

Place the data on a complete frequency + uv grid, filling gaps with zero.

Parameters:
  • umin – baseline range of the target uv grid, in wavelengths.

  • umax – baseline range of the target uv grid, in wavelengths.

  • output_idx (bool) – also return the index arrays mapping this cube into the full grid.

Returns:

the gap-filled cube (or (cube, idx1, idx1_uv) when output_idx).

Return type:

CartDataCube

estimate_sefd(sefd_jansky=True)[source]#

Overall system-equivalent flux density from this cube and its weights.

Returns:

the SEFD, in Jy (sefd_jansky=True) or Kelvin.

Return type:

float

estimate_uv_sefd(sefd_jansky=True)[source]#

SEFD per uv sample (see estimate_sefd() for units).

Returns:

the per-mode SEFD.

Return type:

CartDataCube

estimate_freqs_sefd(sefd_jansky=True, sefd_poly_fit_deg=0)[source]#

SEFD per frequency channel (see estimate_sefd() for units).

Parameters:
  • sefd_jansky (bool) – return Jy (else Kelvin).

  • sefd_poly_fit_deg (int) – if > 0, smooth the SEFD with a polynomial of this degree in log-log space.

Returns:

the SEFD per channel, shape (n_freqs,).

Return type:

ndarray

get_hermitian_index()[source]#

Indices pairing each mode with its Hermitian conjugate (-u, -v).

Returns:

(idx1, idx2) – the positive-half modes and their conjugate partners.

Return type:

tuple

regrid()[source]#

Place the visibilities on their regular 2-D uv grid.

Returns:

the gridded cube.

Return type:

GriddedCartDataCube

image()[source]#

Fourier-transform the visibilities to the image plane.

Returns:

the image cube.

Return type:

CartImageCube

reduce_fov(new_fov, low_memory=False, umin=None, umax=None)[source]#

A copy with a smaller image-plane field of view.

Regrids, images, trims to new_fov (radians), and Fourier-transforms back. A new_fov larger than the current one returns self.

Parameters:
  • new_fov – target field of view, in radians.

  • low_memory (bool) – process one channel at a time.

  • umin – baseline range of the output (defaults to this cube’s).

  • umax – baseline range of the output (defaults to this cube’s).

Returns:

the reduced-FoV cube (weights reduced too if present).

Return type:

CartDataCube

apply_window_function(win_fct, umin=None, umax=None, add_to_meta=True)[source]#

A copy with the image-plane window function win_fct applied.

Parameters:
  • win_fct – the WindowFunction to apply (or its name).

  • umin – baseline range of the output (defaults to this cube’s).

  • umax – baseline range of the output (defaults to this cube’s).

  • add_to_meta (bool) – record the window in the output metadata.

Returns:

the windowed cube.

Return type:

CartDataCube

filter_uvrange(umin, umax)[source]#

Keep UV samples within [umin, umax] in place.

filter_outliers(idx_outliers)[source]#

Remove channels marked by idx_outliers in place.

filter_freqs_from_other(other)[source]#

Keep only channels also present in other.

filter_nan()[source]#

Remove channels containing any NaN visibility.

filter_min_weight(min_weight, replace=False, verbose=True)[source]#

Discard low-weight uv data in place.

Parameters:
  • min_weight – weight threshold below which data is removed.

  • replace (bool) – if True, zero individual samples below the threshold (keeping the mode); if False, drop whole modes whose median weight is below it.

  • verbose (bool) – print how many modes/samples were filtered.

filter_sefd_uv(max_sefd, min_sefd=0)[source]#

Keep, in place, only uv modes whose mean estimated SEFD is within [min_sefd, max_sefd].

Returns:

boolean mask of the kept modes.

Return type:

ndarray

filter_uv_from_index(idx_uv)[source]#

Keep only the uv modes selected by idx_uv (a boolean mask or index array), dropping the rest in place (data, weights, and uu/vv/ru).

average_freqs(n_freqs)[source]#

Weight-average consecutive groups of n_freqs channels together.

Returns:

the down-sampled cube (weights summed accordingly).

Return type:

CartDataCube

average_same_uv()[source]#

Weight-average visibilities sharing the same (u, v) into one mode each.

Returns:

the cube with unique uv coordinates.

Return type:

CartDataCube

plot_uv(fmhz='med', action_fct=None, uv_lines=None, ax=None, apply_uv_scale=False, title=None, **kargs)[source]#

Scatter-plot the visibilities on the uv plane.

Parameters:
  • fmhz – channel to show, in MHz, or one of 'med' / 'first' / 'last' (ignored if action_fct is given).

  • action_fct – a reducer f(data, axis=0) applied over frequency instead of picking one channel (e.g. np.mean).

  • uv_lines (list) – baseline lengths at which to draw guide circles.

  • ax – matplotlib Axes (new figure if None).

  • apply_uv_scale (bool) – plot the uv-scaled (weighted) data.

  • **kargs – forwarded to the matplotlib scatter call.

class ps_eor.datacube.CartDataCubeMeter(data, uu, vv, freqs, meta, weights=None)[source]#

Bases: CartDataCube

Cartesian cube whose UV coordinates are stored in metres.

get_cube(mfreq)[source]#

Convert to a wavelength-coordinate CartDataCube at reference frequency mfreq (Hz), dividing the metre coordinates by that wavelength.

Returns:

the wavelength-coordinate cube.

Return type:

CartDataCube

get_baseline(mfreq, baseline)[source]#

The single mode at baseline length baseline (metres), as a wavelength-coordinate cube at reference frequency mfreq (Hz).

Returns:

a one-mode cube (None if no such baseline).

Return type:

CartDataCube

new_with_data(data, weights=None, freqs=None)[source]#

A new CartDataCubeMeter of the same geometry with new data (and optionally weights / freqs).

static load(filename)[source]#

Load a CartDataCubeMeter (and its weights) from an HDF5 file.

class ps_eor.datacube.MultiNightsCube(cubes=None, nights=None, inhomogeneous=False)[source]#

Bases: object

Collection of compatible cubes indexed by observing night.

concat()[source]#

Stack all nights into one cube along the visibility axis (each mode’s night recorded in cube.origin).

Returns:

the concatenated cube.

Return type:

CartDataCube

property data#

All nights’ data stacked along a third axis, (n_freqs, n_vis, n_nights).

property uu#

Shared u coordinates (from the first night).

property vv#

Shared v coordinates (from the first night).

property ru#

Shared baseline lengths (from the first night).

property freqs#

Shared frequencies (from the first night).

property meta#

Shared image metadata (from the first night).

get_slice_from_idx(idx_freqs)[source]#

Restrict every night to the channels idx_freqs, in place.

Returns:

self, for chaining.

Return type:

MultiNightsCube

get_slice(freq_start, freq_end)[source]#

Return all nights restricted to the given frequency slice.

add(cube, night)[source]#

Add a cube, intersecting coordinates when required.

done()[source]#

Restrict all stored cubes to the coordinates of the first night.

class ps_eor.datacube.MultiDataInfo(filename)[source]#

Bases: object

Observation start, end, and duration values loaded from a text table.

start(night)[source]#

Start time recorded for night.

end(night)[source]#

End time recorded for night.

duration(night)[source]#

Observation duration recorded for night.

class ps_eor.datacube.NoiseStdCube(data, uu, vv, freqs, meta, weights=None)[source]#

Bases: CartDataCube

Full complex thermal-noise standard deviation on a visibility grid.

data is real and non-negative and represents sqrt(E[abs(noise) ** 2]). For circular complex Gaussian noise, each of the real and imaginary components therefore has variance data ** 2 / 2.

property variance#

Full complex noise variance E[abs(noise) ** 2].

make_diff_cube()[source]#

Return an unchanged copy; channel differencing is not defined here.

make_diff_cube_interp()[source]#

Return an unchanged copy; channel differencing is not defined here.

generate_noise_cube(hermitian=True, rng=None)[source]#

Draw a complex Gaussian noise realization at this per-mode std.

Parameters:

hermitian (bool) – enforce V(-u,-v) = conj(V(u,v)) so the image transform is real.

Returns:

one noise realization.

Return type:

CartDataCube

new_with_data(data, weights=None, freqs=None)[source]#

A new NoiseStdCube of this geometry with new data (a real, non-negative standard deviation).

Returns:

the new cube.

Return type:

NoiseStdCube

static load(filename)[source]#

Load a noise-standard-deviation cube from HDF5 (converting legacy data).

Returns:

the loaded cube.

Return type:

NoiseStdCube

class ps_eor.datacube.CartWeightCube(weight_cube, uu, vv, freqs, meta, uv_scale=None, freqs_n_nights=None)[source]#

Bases: CartDataCube

Visibility sampling weights with an optional UV-dependent scale.

get(with_uv_scale=True)[source]#

The effective (absolute) weights.

Parameters:

with_uv_scale (bool) – fold in uv_scale (the per-mode noise scaling); False returns the raw PSF weights.

Returns:

the weights, shape (n_freqs, n_vis).

Return type:

ndarray

copy_with_applied_uv_scale()[source]#

Return a copy with uv_scale absorbed into stored weights.

filter_uv_from_index(idx_uv)[source]#

Keep only the uv modes idx_uv (as CartDataCube.filter_uv_from_index()), also slicing uv_scale.

get_slice_from_idx(idx)[source]#

Select the channels idx, carrying the per-channel night counts.

Returns:

the sliced weights.

Return type:

CartWeightCube

filter_outliers(idx_outliers)[source]#

Remove channels marked by idx_outliers in place.

make_full_cube(umin, umax)[source]#

Expand onto the full [umin, umax] uv grid (as CartDataCube.make_full_cube()), filling absent uv_scale with 1.

Returns:

the gridded weights.

Return type:

CartWeightCube

reduce_fov(new_theta_fov, low_memory=False, umin=None, umax=None)[source]#

Re-grid to a smaller field of view (as CartDataCube.reduce_fov()).

Returns:

the re-gridded weights.

Return type:

CartWeightCube

apply_window_function(win_fct, umin=None, umax=None, mc_n_samples=2000, add_to_meta=True)[source]#

Apply a spatial window function (as CartDataCube.apply_window_function()).

Returns:

the windowed weights.

Return type:

CartWeightCube

static load_from_fits_psf(files, umin, umax, int_time=None, total_time=None, theta_fov=None, low_memory=False, output_psf_cube=False, window_function=None, data_dtype=<class 'numpy.complex128'>)[source]#

Build a weight cube from frequency-dependent PSF FITS files.

The Fourier transform of the PSF is the uv sampling, which sets the per-mode weights. Used by CartDataCube.load_from_fits_image_and_psf().

Parameters:
  • files – PSF FITS files, in frequency order.

  • umin – baseline range kept, in wavelengths.

  • umax – baseline range kept, in wavelengths.

  • int_time – integration and total observing time (s), required if not already in the FITS metadata.

  • total_time – integration and total observing time (s), required if not already in the FITS metadata.

  • theta_fov – output field of view, in radians.

  • low_memory (bool) – process one channel at a time.

  • output_psf_cube (bool) – also return the (unweighted) PSF cube.

  • window_function – optional image-plane WindowFunction.

Returns:

the weights (or (psf_cube, weights) when output_psf_cube).

Return type:

CartWeightCube

static load(filename)[source]#

Load a weight cube from HDF5.

static load_from_hd5(h5_group)[source]#

Deprecated alias for load_from_h5().

static load_from_h5(h5_group)[source]#

Load a weight cube from an open HDF5 group.

save_to_hd5(h5_file, group)[source]#

Deprecated alias for save_to_h5().

save_to_h5(h5_file, group)[source]#

Write weights and scaling metadata into an HDF5 group.

static from_noise_cube(noise_cube, delta_u)[source]#

Build inverse-variance weights from a noise cube.

Bins the noise by baseline length (steps of delta_u wavelengths), measures its MAD per bin, and returns weights proportional to 1 / noise_scale**2 (normalised to unit mean).

Returns:

the derived weights.

Return type:

CartWeightCube

estimate_sefd(noise_cube, sefd_jansky=True, axis=None)[source]#

SEFD estimated from a noise realization and these weights.

Parameters:
  • noise_cube – a noise CartDataCube on the same geometry.

  • sefd_jansky (bool) – return Jy (else Kelvin).

  • axis – reduce over this axis (0 -> per uv mode, 1 -> per channel, None -> a single overall value).

Returns:

The SEFD (MAD-averaged over axis); scalar or array per axis.

estimate_uv_sefd(noise_cube, sefd_jansky=True)[source]#

SEFD per uv sample (see estimate_sefd()).

Returns:

the per-mode SEFD (single averaged channel).

Return type:

CartDataCube

estimate_freqs_sefd(noise_cube, sefd_jansky=True)[source]#

SEFD per frequency channel (see estimate_sefd()).

Returns:

the SEFD per channel, shape (n_freqs,).

Return type:

ndarray

scale_with_noise_cube(noise_cube, sefd_poly_fit_deg=0, sefd_filter_n_bins=0, expected_sefd=None, scale_freqs=False)[source]#

Set uv_scale (in place) so the weights reflect the SEFD measured from noise_cube – down-weighting noisier uv modes.

Parameters:
  • noise_cube – a noise CartDataCube on the same geometry.

  • sefd_poly_fit_deg (int) – if > 0, smooth the radial scale with a log-log polynomial of this degree.

  • sefd_filter_n_bins (int) – if > 0, smooth the scale over this many baseline-length bins instead.

  • expected_sefd – reference SEFD the scale normalises to (default: the median measured SEFD).

  • scale_freqs (bool) – also apply a per-channel SEFD scaling.

random_scale(max_ratio=2, hermitian=True, rng=None)[source]#

Randomly perturb uv_scale in place (log-uniform up to max_ratio).

Parameters:
  • max_ratio – largest multiplicative perturbation.

  • hermitian (bool) – keep conjugate modes consistent.

unscale()[source]#

Reset uv_scale to one.

simulate_noise(sefd, time, hermitian=True, weights_uncertainity_ratio=None, sefd_jansky=True, fake_apply_win_fct=False, rng=None)[source]#

Draw a thermal-noise visibility cube for a given SEFD and integration.

Noise per mode follows the radiometer equation, scaled by these weights.

Parameters:
  • sefd – system-equivalent flux density (Jy if sefd_jansky, else K).

  • time – total integration time, in seconds.

  • hermitian (bool) – make the realization Hermitian (real image).

  • weights_uncertainity_ratio – if set, also perturb the weights randomly by up to this ratio (see random_scale()).

  • sefd_jansky (bool) – interpret sefd in Jy (else Kelvin).

  • fake_apply_win_fct (bool) – scale as if a spatial taper were applied.

Returns:

the simulated noise cube.

Return type:

CartDataCube

get_noise_std_cube(sefd, time, fake_apply_win_fct=False)[source]#

The expected per-mode thermal-noise standard deviation (not a realization – see simulate_noise() for that).

Parameters:
  • sefd – system-equivalent flux density, in Jy.

  • time – total integration time, in seconds.

  • fake_apply_win_fct (bool) – scale as if a spatial taper were applied.

Returns:

the per-mode noise standard deviation.

Return type:

NoiseStdCube

new_with_data(data, weights=None, freqs=None)[source]#

A new CartWeightCube of this geometry with new weight data (and, optionally, freqs); uv_scale is carried over.

Returns:

the new weight cube.

Return type:

CartWeightCube

static join_cubes(cubes)[source]#

Concatenate weight cubes over frequency (uv_scale folded into the data).

Returns:

the joined weights.

Return type:

CartWeightCube

copy()[source]#

Return an independent deep copy of this weight cube.

class ps_eor.datacube.CartWeightsCubeMeter(weight_cube, uu, vv, freqs, meta, uv_scale=None, freqs_n_nights=None)[source]#

Bases: CartWeightCube, CartDataCubeMeter

Weight-cube counterpart of CartDataCubeMeter.

get_cube(mfreq)[source]#

A CartWeightCube with uv in wavelengths at frequency mfreq (Hz), converting from the metre coordinates held here.

new_with_data(data, weights=None, freqs=None)[source]#

A new CartWeightsCubeMeter of the same geometry with new data.

copy()[source]#

Return an independent deep copy of this weight cube.