viscube package#
Submodules#
viscube.deapodization module#
- viscube.deapodization.load_apodization_map(path: str) ndarray[source]#
Load only the apodization map from a .npz file created by save_apodization_map.
- viscube.deapodization.make_apodization_1d(*, npix: int, delta_u: float, window_name: str | None = 'kaiser_bessel', window_kwargs: dict | None = None, window_fn: Callable | None = None, normalize: str = 'peak') ndarray[source]#
Build the 1D image-plane apodization profile implied by a separable UV gridding kernel sampled on the FFT grid.
- Parameters:
npix (int) – FFT grid size.
delta_u (float) – UV-cell size of the final gridded plane, in wavelengths.
window_fn (window_name / window_kwargs /) – Same conventions as VisCube gridding.
normalize ({"peak", "center", None}) – Normalization applied to the 1D profile.
- Returns:
apo_1d – Real-valued, fftshifted image-plane apodization profile.
- Return type:
ndarray, shape (npix,)
- viscube.deapodization.make_apodization_map(*, npix: int, delta_u: float, window_name: str | None = 'kaiser_bessel', window_kwargs: dict | None = None, window_fn: Callable | None = None, normalize: str = 'peak') ndarray[source]#
Build the 2D separable image-plane apodization map.
- Returns:
apo_2d
- Return type:
ndarray, shape (npix, npix)
- viscube.deapodization.save_apodization_map(path: str, apodization_map: ndarray, *, npix: int | None = None, delta_u: float | None = None, window_name: str | None = None, window_kwargs: dict | None = None, normalize: str | None = None)[source]#
Save apodization map plus minimal metadata to a .npz file.
viscube.grid_cube module#
- viscube.grid_cube.build_grid_centers(u_edges: ndarray, v_edges: ndarray) ndarray[source]#
Measurement Set conventions for grid centers.
- viscube.grid_cube.grid_channel(uu_i: ndarray, vv_i: ndarray, vis_re_i: ndarray, vis_imag_i: ndarray, w_i: ndarray, u_edges: ndarray, v_edges: ndarray, window_fn, truncation_radius, uv_tree: cKDTree, grid_tree: cKDTree, pairs: Sequence[Sequence[int]], *, verbose_mean: int = 1, verbose_std: int = 2) Tuple[ndarray, ndarray, ndarray, ndarray, ndarray][source]#
Grid one frequency channel using your existing bin_data.
- viscube.grid_cube.grid_cube_all_stats(*, frequencies: ndarray, uu: ndarray, vv: ndarray, vis_re: ndarray, vis_imag: ndarray, weight: ndarray, invvar_group_re: ndarray, invvar_group_im: ndarray, npix: int = 501, fov_arcsec: float | None = None, pad_uv: float = 0.0, window_name: str | None = 'kaiser_bessel', window_kwargs: dict | None = None, window_fn=None, p_metric: int = 1, std_p: int = 1, std_workers: int = 6, std_min_effective: int = 5, n_eff_mode: str = 'both') Tuple[ndarray, ndarray, ndarray, ndarray, ndarray, ndarray, ndarray][source]#
- viscube.grid_cube.grid_cube_all_stats_wbinned(*, frequencies: ndarray, uu: ndarray, vv: ndarray, ww: ndarray, vis_re: ndarray, vis_imag: ndarray, weight: ndarray, invvar_group_re: ndarray, invvar_group_im: ndarray, npix: int = 501, fov_arcsec: float | None = None, pad_uv: float = 0.0, w_bins: int | ndarray = 8, w_range: Tuple[float, float] | None = None, w_abs: bool = False, window_name: str | None = 'kaiser_bessel', window_kwargs: dict | None = None, window_fn: Callable | None = None, p_metric: int = 1, std_p: int = 1, std_workers: int = 6, std_min_effective: int = 5, tqdm_ncols: int = 200, n_eff_mode: str = 'both') Tuple[ndarray, ndarray, ndarray, ndarray, ndarray, ndarray, ndarray, ndarray][source]#
Grid complex visibilities into UVW-binned UV pixels using bin_data.
- viscube.grid_cube.hermitian_augment(u0: ndarray, v0: ndarray, vis0: ndarray, w0: ndarray, sigma_re0: ndarray, sigma_im0: ndarray) Tuple[ndarray, ndarray, ndarray, ndarray, ndarray, ndarray, ndarray][source]#
- Hermitian augment:
(u, v, Re, Im, w, sigma_re, sigma_im) -> concat with (-u, -v, +Re, -Im, w, sigma_re, sigma_im)
- Return type:
uu, vv, vis_re, vis_imag, w, sigma_re_aug, sigma_im_aug
- viscube.grid_cube.load_and_mask(frequencies: ndarray, uu: ndarray, vv: ndarray, vis: ndarray, weight: ndarray, sigma_re: ndarray, sigma_im: ndarray, mask: ndarray) Tuple[ndarray, ndarray, ndarray, ndarray, ndarray, ndarray, ndarray][source]#
Apply per-channel mask and compact arrays. Returns frequencies, u0, v0, vis0, w0, sigma_re0, sigma_im0.
Assumes the number of valid visibilities is the same for every channel (as in your current implementation). If not, this should be changed to ragged lists.
- viscube.grid_cube.make_uv_grid(uu: ndarray, vv: ndarray, npix: int, pad_uv: float, *, fov_arcsec: float | None = None, warn_crop: bool = True) Tuple[ndarray, ndarray, float, float][source]#
Build symmetric square uv grid; truncation_radius == delta_u.
- Parameters:
fov_arcsec (float, optional) – Image-plane field of view in arcseconds. If provided, uv cell size is set by delta_u = 1 / fov_rad, where fov_rad = fov_arcsec / 206265.
Notes
- Assumes u,v are in wavelengths. Then:
image-plane angle is radians,
Fourier dual spacing satisfies FOV ≈ 1/delta_u.
viscube.gridder module#
- viscube.gridder.bin_data(u, v, values, weights, invvar_group, bins, window_fn: Callable, truncation_radius, uv_tree: cKDTree, grid_tree: cKDTree, pairs: Sequence[Sequence[int]], statistics_fn='mean', verbose=0, window_kwargs: Dict | None = None, std_p: int = 1, std_workers: int = 6, std_min_effective: int = 5, std_expand_step: float = 0.1, collect_stats: bool = False, n_eff_mode: str = 'both')[source]#
- Hybrid std behavior:
Normal pixels: empirical within-pixel scatter -> SE(mean)
Low-info pixels: propagated SE(mean) using invvar_group (per-visibility inverse variance)
- Parameters:
invvar_group (ndarray or None) – Per-visibility inverse variance aligned with values (same length as u/v/values). Used ONLY in low-info std fallback.
n_eff_mode ({"geometric", "both"}) –
Choice of effective sample size definition used consistently for both:
the fallback trigger
the normal-case SE(mean) correction
- ”geometric”:
n_eff = (sum imp)^2 / sum(imp^2) Uses kernel-only support / geometric weighting.
- ”both”:
n_eff = (sum local_w)^2 / sum(local_w^2) Uses full weights * kernel, i.e. incorporates both geometric interpolation weighting and measurement weighting.
- Returns:
grid (ndarray) – Output gridded statistic.
If collect_stats is True – returns (grid, n_fallback)
viscube.sigma_per_baseline module#
- viscube.sigma_per_baseline.mad_std(x: ndarray, axis=None) ndarray[source]#
Robust std estimate via MAD. For Gaussian: std ≈ 1.4826 * MAD.
- Parameters:
x (ndarray) – Input array (can contain NaNs).
axis (int or tuple of ints, optional) – Axis along which to compute the robust std.
- Returns:
std – Robust standard deviation estimate.
- Return type:
ndarray
- viscube.sigma_per_baseline.sigma_by_baseline_scan_time_diff(data: ndarray, mask: ndarray, time_row: ndarray, scan_row: ndarray, ant1_row: ndarray, ant2_row: ndarray, *, min_pairs: int = 8, sigma_floor: float = 1e-12) Tuple[ndarray, ndarray][source]#
Estimate per-visibility sigma separately for real and imaginary parts using time-differenced visibilities within groups defined by (scan, baseline).
Sigma is computed per-channel per-group, then assigned to all visibilities in that group.
- Uses consecutive time differences:
diff = x[t+1] - x[t]
- and converts diff-std to per-sample std via:
sigma = std(diff) / sqrt(2)
- Parameters:
data (ndarray, complex, shape (nchan, nvis)) – Complex visibilities.
mask (ndarray, bool, shape (nchan, nvis)) – Valid-data mask.
time_row (ndarray, shape (nvis,)) – Time stamps per visibility row.
scan_row (ndarray, shape (nvis,)) – Scan number per visibility row.
ant1_row (ndarray, shape (nvis,)) – Antenna IDs defining baselines.
ant2_row (ndarray, shape (nvis,)) – Antenna IDs defining baselines.
min_pairs (int, optional) – Minimum number of valid consecutive pairs required per channel/group.
sigma_floor (float, optional) – Lower floor for sigma values.
- Returns:
sigma_re (ndarray, shape (nchan, nvis)) – Estimated per-visibility sigma for real part.
sigma_im (ndarray, shape (nchan, nvis)) – Estimated per-visibility sigma for imaginary part.
viscube.windows module#
- viscube.windows.casa_pswf_window(u, center: float, *, pixel_size: float = 0.015, m: int = 5, normalize: bool = True) ndarray[source]#
CASA/Schwab prolate-spheroidal gridding kernel (1-D separable form).
- Parameters:
u (array-like)
center (float)
pixel_size (float)
m (int) – Total integer support (number of pixels). Typical choice: m=5.
normalize (bool) – Normalize so that peak value at center is 1.
- Returns:
w
- Return type:
ndarray
- viscube.windows.kaiser_bessel_window(u, center: float, *, pixel_size: float = 0.015, m: int = 6, beta: float | None = None, normalize: bool = True) ndarray[source]#
1D Kaiser–Bessel interpolation window (separable in u, v).
- Parameters:
u (array-like) – Coordinates (same units as center).
center (float) – Grid-cell center coordinate.
pixel_size (float) – Grid pixel size in uv units.
m (int) – Total support width in pixel units (covers m * pixel_size). Effective half-width = 0.5 * m * pixel_size.
beta (float, optional) –
- Shape parameter. If None, use a reasonable default for oversamp≈2:
beta ≈ π * sqrt( (m/2)^2 - 0.8 )
normalize (bool) – If True, normalize so that window(center) == 1.
- Returns:
w
- Return type:
ndarray (same shape as u)