autolens.TransformerNUFFT#
- class TransformerNUFFT[source]#
Bases:
_PrimaryBeamMixinNon-Uniform FFT for image -> visibilities, backed by finufft on the NumPy path and nufftax on the JAX path.
This is the default TransformerNUFFT in PyAutoArray. The array namespace of each call picks the backend:
xp=np (eager NumPy) runs finufft (https://github.com/flatironinstitute/finufft), the CPU C++ NUFFT, via autoarray.operators.nufft_cpu. This path never imports JAX, so a NumPy fit (e.g. a numba Nautilus search with forked workers) does not start XLA in its parent process. finufft uses OpenMP and honours OMP_NUM_THREADS.
xp=jnp runs nufftax (https://github.com/GragasLab/nufftax), a pure-JAX port of finufft that supports jax.jit, jax.grad and jax.vmap. nufftax is imported only on this path.
The two agree to ~1e-14 relative. Where finufft has no wheel (e.g. Linux aarch64) the NumPy path falls back to nufftax with a warning; where neither is installed use TransformerDFT instead.
Convention recipe (matches TransformerDFT to ~1e-13 relative across odd/even/non-square image sizes):
image_flipped = image[::-1, :] x = 2 * pi * u_lambda * pixel_scale_rad y = 2 * pi * v_lambda * pixel_scale_rad offset_x = 0.5 if N_x is even else 0.0 offset_y = 0.5 if N_y is even else 0.0 shift = exp(-i * (offset_x * x + offset_y * y)) visibilities = nufftax.nufft2d2(x, y, image_flipped, eps, -1) * shift
The shift factor is the half-pixel correction between autoarray’s grid centre at index (N - 1) / 2 and the NUFFT’s mode-0 at index N // 2; neither backend applies it internally.
- Parameters:
uv_wavelengths (
ndarray) – The (u, v) coordinates of the measured visibilities in wavelengths, shape (n_vis, 2).real_space_mask (
Mask2D) – The 2D mask defining the real-space image grid.eps (
float) – Requested NUFFT precision passed to the backend. Defaults to 1e-12 (effectively machine precision); relax to 1e-9 or 1e-6 for faster execution if marginal accuracy is acceptable.chunk_size (
Optional[int]) – If set to a positive integer, the forward and adjoint NUFFT calls split the visibility axis into chunks of this size and iterate (viajax.lax.scanon the JAX path, a Python loop on the numpy path). This caps the NUFFT gather-buffer allocation (~``2 * chunk_size * nspread^2 * dtype_size``) at the cost of per-chunk overhead. Required for visibility counts above ~5M on a 40-80 GB GPU. IfNone(default), a single one-shot call is used — preserves existing behaviour for small-N callers (sma-class datasets).xp – Accepted for signature compatibility with the legacy class; not stored. The active backend is selected per-call via the xp argument to visibilities_from / image_from.
primary_beam – The primary beam P of the antennas, an Array2D on real_space_mask (or a native / slim array). When set, visibilities_from and transform_mapping_matrix multiply their input by P on the slim grid before the scatter to the native grid; image_from stays the un-beamed adjoint. None (default) applies no primary beam.
- grid#
The real-space pixel grid in radians (computed from the mask).
- total_visibilities#
Number of measured visibilities.
- total_image_pixels#
Number of unmasked pixels in the image grid.
- __init__(uv_wavelengths, real_space_mask, eps=1e-12, chunk_size=None, xp=<module 'numpy' from '/home/docs/checkouts/readthedocs.org/user_builds/pyautolens/envs/latest/lib/python3.12/site-packages/numpy/__init__.py'>, primary_beam=None, **kwargs)[source]#
Non-Uniform FFT for image -> visibilities, backed by finufft on the NumPy path and nufftax on the JAX path.
This is the default TransformerNUFFT in PyAutoArray. The array namespace of each call picks the backend:
xp=np (eager NumPy) runs finufft (https://github.com/flatironinstitute/finufft), the CPU C++ NUFFT, via autoarray.operators.nufft_cpu. This path never imports JAX, so a NumPy fit (e.g. a numba Nautilus search with forked workers) does not start XLA in its parent process. finufft uses OpenMP and honours OMP_NUM_THREADS.
xp=jnp runs nufftax (https://github.com/GragasLab/nufftax), a pure-JAX port of finufft that supports jax.jit, jax.grad and jax.vmap. nufftax is imported only on this path.
The two agree to ~1e-14 relative. Where finufft has no wheel (e.g. Linux aarch64) the NumPy path falls back to nufftax with a warning; where neither is installed use TransformerDFT instead.
Convention recipe (matches TransformerDFT to ~1e-13 relative across odd/even/non-square image sizes):
image_flipped = image[::-1, :] x = 2 * pi * u_lambda * pixel_scale_rad y = 2 * pi * v_lambda * pixel_scale_rad offset_x = 0.5 if N_x is even else 0.0 offset_y = 0.5 if N_y is even else 0.0 shift = exp(-i * (offset_x * x + offset_y * y)) visibilities = nufftax.nufft2d2(x, y, image_flipped, eps, -1) * shift
The shift factor is the half-pixel correction between autoarray’s grid centre at index (N - 1) / 2 and the NUFFT’s mode-0 at index N // 2; neither backend applies it internally.
- Parameters:
uv_wavelengths (
ndarray) – The (u, v) coordinates of the measured visibilities in wavelengths, shape (n_vis, 2).real_space_mask (
Mask2D) – The 2D mask defining the real-space image grid.eps (
float) – Requested NUFFT precision passed to the backend. Defaults to 1e-12 (effectively machine precision); relax to 1e-9 or 1e-6 for faster execution if marginal accuracy is acceptable.chunk_size (
Optional[int]) – If set to a positive integer, the forward and adjoint NUFFT calls split the visibility axis into chunks of this size and iterate (viajax.lax.scanon the JAX path, a Python loop on the numpy path). This caps the NUFFT gather-buffer allocation (~``2 * chunk_size * nspread^2 * dtype_size``) at the cost of per-chunk overhead. Required for visibility counts above ~5M on a 40-80 GB GPU. IfNone(default), a single one-shot call is used — preserves existing behaviour for small-N callers (sma-class datasets).xp – Accepted for signature compatibility with the legacy class; not stored. The active backend is selected per-call via the xp argument to visibilities_from / image_from.
primary_beam – The primary beam P of the antennas, an Array2D on real_space_mask (or a native / slim array). When set, visibilities_from and transform_mapping_matrix multiply their input by P on the slim grid before the scatter to the native grid; image_from stays the un-beamed adjoint. None (default) applies no primary beam.
- grid#
The real-space pixel grid in radians (computed from the mask).
- total_visibilities#
Number of measured visibilities.
- total_image_pixels#
Number of unmasked pixels in the image grid.
Methods
__init__(uv_wavelengths, real_space_mask[, ...])Non-Uniform FFT for image -> visibilities, backed by finufft on the NumPy path and nufftax on the JAX path.
image_from(visibilities[, xp])Adjoint NUFFT: visibilities -> real-space (dirty) image.
transform_mapping_matrix(mapping_matrix[, xp])Apply the forward NUFFT to each column of a mapping matrix.
visibilities_from(image[, xp])Forward NUFFT: real-space image -> visibilities at the configured uv points.
with_primary_beam(primary_beam)Returns a shallow copy of this transformer whose forward transforms apply the primary beam primary_beam (an Array2D on the real-space mask, or a native / slim array), or none if it is None.
Attributes
primary_beam_slim- __init__(uv_wavelengths, real_space_mask, eps=1e-12, chunk_size=None, xp=<module 'numpy' from '/home/docs/checkouts/readthedocs.org/user_builds/pyautolens/envs/latest/lib/python3.12/site-packages/numpy/__init__.py'>, primary_beam=None, **kwargs)[source]#
Non-Uniform FFT for image -> visibilities, backed by finufft on the NumPy path and nufftax on the JAX path.
This is the default TransformerNUFFT in PyAutoArray. The array namespace of each call picks the backend:
xp=np (eager NumPy) runs finufft (https://github.com/flatironinstitute/finufft), the CPU C++ NUFFT, via autoarray.operators.nufft_cpu. This path never imports JAX, so a NumPy fit (e.g. a numba Nautilus search with forked workers) does not start XLA in its parent process. finufft uses OpenMP and honours OMP_NUM_THREADS.
xp=jnp runs nufftax (https://github.com/GragasLab/nufftax), a pure-JAX port of finufft that supports jax.jit, jax.grad and jax.vmap. nufftax is imported only on this path.
The two agree to ~1e-14 relative. Where finufft has no wheel (e.g. Linux aarch64) the NumPy path falls back to nufftax with a warning; where neither is installed use TransformerDFT instead.
Convention recipe (matches TransformerDFT to ~1e-13 relative across odd/even/non-square image sizes):
image_flipped = image[::-1, :] x = 2 * pi * u_lambda * pixel_scale_rad y = 2 * pi * v_lambda * pixel_scale_rad offset_x = 0.5 if N_x is even else 0.0 offset_y = 0.5 if N_y is even else 0.0 shift = exp(-i * (offset_x * x + offset_y * y)) visibilities = nufftax.nufft2d2(x, y, image_flipped, eps, -1) * shift
The shift factor is the half-pixel correction between autoarray’s grid centre at index (N - 1) / 2 and the NUFFT’s mode-0 at index N // 2; neither backend applies it internally.
- Parameters:
uv_wavelengths (
ndarray) – The (u, v) coordinates of the measured visibilities in wavelengths, shape (n_vis, 2).real_space_mask (
Mask2D) – The 2D mask defining the real-space image grid.eps (
float) – Requested NUFFT precision passed to the backend. Defaults to 1e-12 (effectively machine precision); relax to 1e-9 or 1e-6 for faster execution if marginal accuracy is acceptable.chunk_size (
Optional[int]) – If set to a positive integer, the forward and adjoint NUFFT calls split the visibility axis into chunks of this size and iterate (viajax.lax.scanon the JAX path, a Python loop on the numpy path). This caps the NUFFT gather-buffer allocation (~``2 * chunk_size * nspread^2 * dtype_size``) at the cost of per-chunk overhead. Required for visibility counts above ~5M on a 40-80 GB GPU. IfNone(default), a single one-shot call is used — preserves existing behaviour for small-N callers (sma-class datasets).xp – Accepted for signature compatibility with the legacy class; not stored. The active backend is selected per-call via the xp argument to visibilities_from / image_from.
primary_beam – The primary beam P of the antennas, an Array2D on real_space_mask (or a native / slim array). When set, visibilities_from and transform_mapping_matrix multiply their input by P on the slim grid before the scatter to the native grid; image_from stays the un-beamed adjoint. None (default) applies no primary beam.
- grid#
The real-space pixel grid in radians (computed from the mask).
- total_visibilities#
Number of measured visibilities.
- total_image_pixels#
Number of unmasked pixels in the image grid.
- visibilities_from(image, xp=<module 'numpy' from '/home/docs/checkouts/readthedocs.org/user_builds/pyautolens/envs/latest/lib/python3.12/site-packages/numpy/__init__.py'>)[source]#
Forward NUFFT: real-space image -> visibilities at the configured uv points.
For numpy callers (xp=np) the result is materialised back to numpy before being wrapped in Visibilities. For JAX callers (xp=jnp) the result stays as a jax.Array so it can flow through jax.jit / jax.grad / jax.vmap without device round-trips.
If the transformer has a primary_beam_slim the image is multiplied by it on the slim grid before the scatter to the native grid, so the visibilities are those of P * image.
- image_from(visibilities, xp=<module 'numpy' from '/home/docs/checkouts/readthedocs.org/user_builds/pyautolens/envs/latest/lib/python3.12/site-packages/numpy/__init__.py'>)[source]#
Adjoint NUFFT: visibilities -> real-space (dirty) image.
Implemented as a type-1 nufft2d1 (finufft via nufft_cpu for xp=np, nufftax for xp=jnp) with conj(shift) applied to the visibilities and a final row-flip to return to autoarray’s native orientation. The real part is taken to discard imaginary residue.
Note that this is the mathematical adjoint of visibilities_from, with no kernel deconvolution applied. The values match TransformerDFT.image_from exactly, which is what makes Interferometer.apply_sparse_operator scale-consistent across both transformers.
The primary beam is deliberately not applied: this is the adjoint of the un-beamed transform, so the dirty image, dirty beam and the w-tilde quantities built from it do not depend on primary_beam_slim.
- transform_mapping_matrix(mapping_matrix, xp=<module 'numpy' from '/home/docs/checkouts/readthedocs.org/user_builds/pyautolens/envs/latest/lib/python3.12/site-packages/numpy/__init__.py'>)[source]#
Apply the forward NUFFT to each column of a mapping matrix.
All columns are scattered into a single batched native-shape image of shape
(n_src, N_y, N_x)and passed through nufft2d2 in one call (nufft2d2 supports batchedf). This avoids the per-column Python loop that, underjax.jit, would unroll inton_srcseparate NUFFT invocations and blow up the JIT graph for pixelization-heavy fits (notably double-source-plane).If the transformer has a primary_beam_slim every column is multiplied by it on the slim grid before the scatter, giving F P M.
The numpy path runs finufft (nufft_cpu), the JAX path nufftax.