Remove pynufft and the legacy TransformerNUFFTPyNUFFT backend - #475
Merged
Conversation
Deletes the legacy pynufft-backed interferometer transformer and drops pynufft from the `optional` and `dev` extras. The nufftax-backed `TransformerNUFFT` has been the default backend since the nufftax migration, and `TransformerDFT` remains as the pure-numpy transformer. Removed: - `TransformerNUFFTPyNUFFT`, the `NUFFTPlaceholder` / `NUFFT_cpu` module-scope try-import, and `pynufft_exception()` - the `TransformerNUFFTPyNUFFT` re-exports from `autoarray/__init__.py` and `autoarray/type.py`, and its arm of the `Transformer` union - the three `test__nufft_pynufft__*` tests and the `"pynufft"` arm of the nufftax-absent skip filter in `test_autoarray/conftest.py` - `pynufft` from `[project.optional-dependencies]` `optional` and the `pynufft==2022.2.2` pin from `dev` `nufftax_exception()` no longer points users at the deleted class; it now names `TransformerDFT` as the fallback where JAX is unavailable, and the `use_adjoint_scaling` docstrings no longer describe a pynufft-specific normalisation. This also resolves the pinned `pynufft==2022.2.2` dev-extra failure under SciPy >= 1.17 (it calls the removed `scipy.linalg.pinv2`). Note on import time: the measured saving is ~10 ms, not the ~230 ms the task assumed. `pynufft`'s 0.19 s cumulative import is ~95% `scipy.sparse`, which `autoarray/operators/derivative_util.py` imports eagerly for `csr_matrix` regardless. Deferring that import is the real ~0.10 s win and is filed separately.
This was referenced Aug 22, 2026
This was referenced Aug 22, 2026
Merged
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the legacy pynufft-backed interferometer transformer and drops
pynufftfrom theoptionalanddevextras. The nufftax-backedTransformerNUFFThas been the default backend since the nufftax migration, andTransformerDFTremains as the pure-numpy transformer.This also resolves a pre-existing break: the pinned
pynufft==2022.2.2callsscipy.linalg.pinv2, which SciPy 1.17.1 no longer provides, so thedevextra could not install-and-pass on Python 3.13. Confirmed on a clean 3.13 environment —hasattr(scipy.linalg, "pinv2")isFalse. pynufft 2022.2.2 also emitsSyntaxWarning: "is" with 'str' literalon 3.13, i.e. it is unmaintained against the supported interpreter range.Merge order: merge PyAutoGalaxy#(see below) and PyAutoLens# first, then this. Those two only drop a re-export, which is safe against an autoarray that still has the class — so main is never red. Merging this one first would break their main CI.
Two corrections to the task's premise
The task assumed pynufft was a base dependency costing ~0.23 s of import. Both were wrong, and measuring is what found it:
optionalanddevextras only. A plainpip install autoarraynever had it, soTransformerNUFFTPyNUFFTalready raised for most users.import autoarray369.8 ms → 359.9 ms. pynufft's 0.19 s cumulative import is ~95%scipy.sparse(0.11 s), whichautoarray/operators/derivative_util.py:30imports eagerly forcsr_matrixregardless. Only ~10 modules are exclusive to pynufft.The removal still stands on its own merits — unmaintained dependency, dead class, broken dev extra — just not on import-time grounds. The real ~0.10 s win is deferring that
scipy.sparseimport, filed separately.Platform note (Intel macOS)
nufftaxis pure-JAX; even itsxp=nppath callsnufftax.nufft2d2. jaxlib's last macOS x86_64 wheel is 0.4.38 (2024-12-17) and jaxlib has never shipped an sdist, so there is no pip path to JAX on Intel Mac. Those users therefore keepTransformerDFTonly for interferometry — exact, but O(N_vis × N_pix). Accepted deliberately; the broader platform-support question is filed separately.API Changes
Breaking:
TransformerNUFFTPyNUFFTis removed, along with itsautoarraytop-level andautoarray.typere-exports and its arm of theTransformerunion. Migration isTransformerNUFFT(nufftax-backed, differentiable, ~zero gridding error), orTransformerDFTwhere JAX is unavailable.pynufftis no longer an optional or dev dependency.See full details below.
Test Plan
pytest test_autoarray— 1164 passed, 1 skipped (Python 3.13, dev extras)import autoarraysucceeds;hasattr(aa, "TransformerNUFFTPyNUFFT")isFalsepython -X importtime -c "import autoarray" | grep pynufftis emptyFull API Changes (for automation & release notes)
Removed
autoarray.TransformerNUFFTPyNUFFT— the legacy pynufft-backed NUFFT transformer; replaced byautoarray.TransformerNUFFTautoarray.operators.transformer.TransformerNUFFTPyNUFFT— same class at its defining moduleautoarray.operators.transformer.pynufft_exception()— raised only by the removed classautoarray.operators.transformer.NUFFTPlaceholder— the absent-pynufft stand-in base classpynufftfrom[project.optional-dependencies] optional, and thepynufft==2022.2.2pin fromdevChanged Behaviour
autoarray.type.Transformer— union narrows fromUnion[TransformerDFT, TransformerNUFFT, TransformerNUFFTPyNUFFT]toUnion[TransformerDFT, TransformerNUFFT]nufftax_exception()message — no longer directs users to the removed pynufft backend; now namesTransformerDFTas the fallback where JAX is unavailableuse_adjoint_scalingis now a no-op on every remaining transformer. It was load-bearing only for the removed class, whose pynufft-internal IFFT normalisation left its raw adjoint a factor4 * N_y * N_xlow. The parameter is retained as a stable part of the transformer interface and its docstrings updated; removing it is deliberately left as a separate change.Migration
transformer = aa.TransformerNUFFTPyNUFFT(uv_wavelengths=uv, real_space_mask=mask)transformer = aa.TransformerNUFFT(uv_wavelengths=uv, real_space_mask=mask)transformer = aa.TransformerDFT(uv_wavelengths=uv, real_space_mask=mask)Note that
TransformerNUFFT.image_fromreturns the plain mathematical adjoint, which differs in absolute scale from the removed class' adjoint (that one applied pynufft's internal IFFT and kernel deconvolution). The structure of the dirty image is unchanged, and the values matchTransformerDFT.image_fromexactly.Generated by Claude Code