argosim.imaging_utils module#
Imaging utils.
This module contains functions to perform radio interferometric imaging.
The production forward model uses Kaiser-Bessel (KB) convolutional gridding
(simulate_dirty_observation()). A legacy nearest-neighbour (NN)
binary-mask path is kept at the bottom of the module for the GUI and for
teaching; see the “Legacy / educational” section there.
- Authors:
Ezequiel Centofanti <ezequiel.centofanti@cea.fr> Samuel Gullin <gullin@ia.forth.gr>
- argosim.imaging_utils.add_noise_vis(vis, sigma=0.1, seed=None)[source]#
Add independent complex Gaussian noise to ungridded visibilities.
Adds independent complex noise to each visibility datum. Real and imaginary parts are each drawn from
N(0, sigma/sqrt(2))so that the total noise power per visibility issigma^2. This prepares for the proper per-baseline noise model (radiometer equation) to be integrated later.
- argosim.imaging_utils.check_uv_in_grid(uv_px, grid_shape, fov_size, on_out_of_bounds='warn')[source]#
Check that UV samples fall inside the uv grid.
Convolutional gridding silently drops any visibility whose target pixel falls outside the grid (
grid_visibilities_convusesmode="drop"), so a grid too small for the longest baselines quietly loses data. This function flags that case, using the continuous pixel coordinates returned byscale_uv_samples_continuous: a sample is out of the grid when its pixel coordinate is< 0or> grid_shapealong either axis.The message therefore reports the largest field of view that keeps every sample on the grid for the chosen
Npixand uv coverage.- Parameters:
uv_px (jnp.ndarray) – Continuous pixel coordinates
(u, v)for each visibility, shape(n_vis, 2), as returned byscale_uv_samples_continuous.grid_shape (tuple) – Shape of the uv grid
(ny, nx).fov_size (float or tuple) – Field of view in degrees corresponding to
uv_px/grid_shape. A scalar is applied to both axes; a tuple is read as(fov_y, fov_x). Used to report the maximum field of view that keeps all samples on-grid.on_out_of_bounds ({"warn", "error", "ignore"}) – Action when one or more samples fall outside the grid:
"warn"(default) emits aUserWarningreporting the proportion of dropped samples,"error"raises aValueError, and"ignore"returns silently (samples are still dropped downstream).
- Raises:
ValueError – If
on_out_of_boundsis not one of the accepted options, or if it is"error"and any sample falls outside the grid.
- argosim.imaging_utils.check_uv_samples_range(uv_samples_indices, uv_samples, sky_uv_shape, fov_size)[source]#
Check uv samples range.
Function to check if the uv samples are within the uv-plane range.
- Parameters:
- argosim.imaging_utils.compute_visibilities_grid(sky_uv, uv_mask)[source]#
Compute visibilities gridded.
Function to compute the visibilities from the fourier sky and the uv sampling mask.
- Parameters:
sky_uv (np.ndarray) – The sky model in Fourier/uv domain.
uv_mask (np.ndarray) – The uv sampling mask.
- Returns:
visibilities – Gridded visibilities on the uv-plane.
- Return type:
np.ndarray
- argosim.imaging_utils.degrid_visibilities_conv(sky_uv, uv_px, grid_shape, W, beta)[source]#
Convolutional degridding with Kaiser-Bessel anti-aliasing kernel (JAX).
Interpolates complex visibility values from a gridded sky model at the given UV positions. This is the adjoint of
grid_visibilities_conv(). Differentiable w.r.t.sky_uv.- Parameters:
sky_uv (jnp.ndarray) – Gridded sky model in UV domain, shape
grid_shape, complex.uv_px (jnp.ndarray) – Continuous pixel coordinates
(u, v)for each visibility, shape(n_vis, 2).grid_shape (tuple of int) – Shape of
sky_uv(ny, nx). Must be a static argument.W (int) – Kernel support width in pixels (odd). Must be a static argument.
beta (float) – KB shape parameter. Must be a static argument.
- Returns:
vis – Interpolated complex visibilities, shape
(n_vis,). Contributions from out-of-bounds grid points are clipped to the nearest edge pixel.- Return type:
jnp.ndarray
- argosim.imaging_utils.grid_sampling_function(track, fov_size, npix, method='kb', kernel_support=7, beta=None, oversampling=2, weighting='natural')[source]#
Grid the unit sampling function and return the uv plane and dirty beam.
GUI helper. Grids unit visibilities (ones) at the uv sample positions to build the gridded sampling function, whose inverse Fourier transform is the dirty beam (impulse response). Supports the two gridding schemes offered in the GUI:
"nn": nearest-neighbour sampling mask (grid_uv_samples())."kb": Kaiser-Bessel convolutional gridding (grid_visibilities_conv()) with image-domain correction and oversampling, matchingsimulate_dirty_observation().
- Parameters:
track (np.ndarray) – The uv sampling points, shape
(n_vis, 3).fov_size (float or tuple) – Field of view in degrees, scalar or
(fov_y, fov_x).npix (int) – Number of pixels per side of the native image / uv grid.
method ({"kb", "nn"}) – Gridding scheme.
kernel_support (int) – KB kernel support width in pixels (odd). Only used for
method="kb".beta (float, optional) – KB shape parameter. If
None, uses2.34 * kernel_support.oversampling (float) – UV-grid oversampling factor for
method="kb".weighting ({"natural", "uniform"}) – Visibility weighting (see
_visibility_weights()). For NN it selects the mask (natural -> histogram, uniform -> binary).
- Returns:
uv_grid (jnp.ndarray) – The gridded sampling function on the uv plane. Shape
(npix, npix)for NN, or the oversampled(n_os, n_os)for KB.dirty_beam (jnp.ndarray) – The dirty beam (impulse response), shape
(npix, npix).
- argosim.imaging_utils.grid_uv_samples(uv_samples, sky_uv_shape, fov_size, mask_type='binary')[source]#
Grid uv samples.
Compute the uv sampling mask from the uv samples.
- Parameters:
- Returns:
uv_mask (np.ndarray) – The uv sampling mask.
uv_samples_indices (np.ndarray) – The indices of the uv samples in pixel coordinates.
- argosim.imaging_utils.grid_visibilities_conv(vis, uv_px, grid_shape, W, beta)[source]#
Convolutional gridding with Kaiser-Bessel anti-aliasing kernel (JAX).
Distributes complex visibility values onto a regular grid using a Kaiser-Bessel convolution kernel. The Python loop over the
W x Wkernel support is unrolled by JAX at JIT-compile time, so the compiled kernel is fully vectorised over all visibilities. Differentiable w.r.t.vis.- Parameters:
vis (jnp.ndarray) – Complex visibility values to grid, shape
(n_vis,).uv_px (jnp.ndarray) – Continuous pixel coordinates
(u, v)for each visibility, shape(n_vis, 2).grid_shape (tuple of int) – Shape of the output grid
(ny, nx). Must be a static argument.W (int) – Kernel support width in pixels (odd). Must be a static argument. Typically
W = 7.beta (float) – KB shape parameter. Must be a static argument. Typically
beta = 2.34 * W.
- Returns:
grid – Gridded visibilities, shape
grid_shape, complex dtype (complex64by default,complex128if JAX x64 is enabled). Out-of-bounds contributions are silently dropped.- Return type:
jnp.ndarray
- argosim.imaging_utils.kaiser_bessel(x, W, beta)[source]#
Kaiser-Bessel anti-aliasing kernel.
Evaluates the Kaiser-Bessel window function used as a gridding convolution kernel to suppress aliasing artefacts from non-uniform sampling.
- Parameters:
- Returns:
Kaiser-Bessel kernel values at
x. Evaluates to zero outside[-W/2, W/2]by the clip operation on the argument.- Return type:
jnp.ndarray
Notes
The epsilon inside the square root keeps its argument strictly positive. Without it
sqrthas an infinite derivative atarg == 0(the support edge|x| = W/2, always hit by the gridding stencil), giving a NaN gradient in single precision. The value change is negligible (~1e-12).
- argosim.imaging_utils.kb_correction(grid_shape, W, beta)[source]#
Image-domain correction for Kaiser-Bessel convolutional gridding.
Computes the 2D correction image
C(l, m)such that multiplying the dirty image byCcompensates for the amplitude taper introduced by the KB convolution kernel. The correction is separable:C(l, m) = C_1d(l) * C_1d(m), whereC_1dis the reciprocal of the discrete Fourier transform of the 1D KB kernel.
- argosim.imaging_utils.scale_uv_samples(uv_samples, sky_uv_shape, fov_size)[source]#
Scale uv samples to nearest integer pixel coordinates (NN snap).
Function to scale the uv samples to pixel coordinates, rounding to the nearest cell.
- Parameters:
- Returns:
uv_samples_indices – The indices of the uv samples in pixel coordinates.
- Return type:
np.ndarray
- argosim.imaging_utils.scale_uv_samples_continuous(uv_samples, sky_uv_shape, fov_size)[source]#
Scale UV samples to continuous pixel coordinates.
Returns floating-point (non-rounded) pixel positions, required for sub-pixel-accurate convolutional gridding.
- Parameters:
- Returns:
uv_px – Continuous pixel coordinates
(u, v)for each visibility, shape(n_vis, 2).- Return type:
jnp.ndarray
- argosim.imaging_utils.simulate_dirty_observation(sky, track, fov_size, multi_band=False, freqs=None, beam=None, sigma=0.2, seed=None, kernel_support=7, beta=None, oversampling=2, on_out_of_bounds='warn', weighting='natural')[source]#
Simulate dirty observation.
Function to simulate a radio observation of the sky model from the track uv-samples using convolutional gridding with a Kaiser-Bessel anti-aliasing kernel. The forward model is: degrid true visibilities from the sky FFT, add per-visibility complex Gaussian noise, re-grid with the KB kernel, and apply the image-domain correction.
- Parameters:
sky (np.ndarray) – The sky model image.
track (np.ndarray) – The uv sampling points.
fov_size (float) – The field of view size in degrees.
multi_band (bool) – If True, simulate a multi-band observation.
freqs (list) – The frequency list for the multi-band simulation.
beam (Beam) – The beam object to apply to the sky, only used in multi-band simulations.
sigma (float) – Standard deviation of the complex Gaussian noise added independently to each visibility (radiometer-style), in sky/flux units. The dirty image is normalised so a point source of flux
Speaks atS(Jy/beam), so the image noise scales roughly assigma / sqrt(n_vis).seed (int) – Optional seed to set for reproducibility in noise realisation.
kernel_support (int) – KB kernel support width in pixels (odd). Default is 7. Larger values give better anti-aliasing at the cost of more compute.
beta (float, optional) – KB kernel shape parameter. If
None(default), uses the standard heuristicbeta = 2.34 * kernel_support. Expose it to experiment with different main-lobe/side-lobe trade-offs.oversampling (float) – UV-grid oversampling factor. The sky is zero-padded to
oversampling * Npixels before gridding (finer UV cells, same angular pixel scale, FoV scaled byoversampling), and the dirty image/beam are cropped back to the originalN x Nafterwards. This discards the image borders where the KB correction amplifies noise and aliasing. Default is 2, matching thebeta = 2.34 * Wheuristic. Set to 1 to recover the un-padded native-resolution behaviour.on_out_of_bounds ({"warn", "error", "ignore"}) – Behaviour when UV samples fall outside the (oversampled) uv grid and would be silently dropped by the convolutional gridding.
"warn"(default) emits aUserWarningreporting the proportion of dropped samples,"error"raises aValueError, and"ignore"disables the check. Seecheck_uv_in_grid().weighting ({"natural", "uniform"}) – Visibility weighting scheme (see
_visibility_weights())."natural"(default) weights every visibility equally (best sensitivity, broadest PSF);"uniform"weights each by1/countof its uv cell (finer PSF, higher noise).
- Returns:
obs (np.ndarray) – The dirty observation(s).
dirty_beam (np.ndarray) – The dirty beam(s).
- argosim.imaging_utils.simulate_dirty_observation_nn(sky, track, fov_size, multi_band=False, freqs=None, beam=None, sigma=0.2, seed=None, weighting='natural')[source]#
Simulate a dirty observation with nearest-neighbour (NN) gridding.
Educational counterpart to
simulate_dirty_observation()(which uses Kaiser-Bessel convolutional gridding). Here each visibility is snapped to its nearest uv-grid cell: the sky FFT is multiplied by the sampling mask, per-visibility (per-cell) noise is added, and the result is inverse Fourier-transformed. Intended to contrast NN vs KB gridding in the GUI; the KB forward model is the one to use for prototyping and applications.- Parameters:
sky (np.ndarray) – The sky model image.
track (np.ndarray) – The uv sampling points.
fov_size (float or tuple) – The field of view size in degrees, scalar or
(fov_y, fov_x).multi_band (bool) – If True, simulate a multi-band observation.
freqs (list) – The frequency list for the multi-band simulation.
beam (Beam) – The beam object to apply to the sky, only used in multi-band simulations.
sigma (float) – Standard deviation of the complex Gaussian noise added independently to each sampled uv cell (visibility domain, matching the KB forward model), in sky/flux units. The dirty image is normalised so a point source of flux
Speaks atS(Jy/beam). See_add_cell_noise().seed (int) – Optional seed to set for reproducibility in the noise realisation.
weighting ({"natural", "uniform"}) – Visibility weighting. For NN this is exactly the sampling-mask choice:
"natural"uses the"histogram"mask (each cell weighted by its sample count),"uniform"uses the"binary"mask (each sampled cell weighted equally). Seesimulate_dirty_observation().
- Returns:
obs (np.ndarray) – The dirty observation(s).
dirty_beam (np.ndarray) – The dirty beam(s).