Skip to content

Commit 24863a2

Browse files
Jammy2211claude
authored andcommitted
docs(transformer): state the real use_adjoint_scaling contract
`TransformerDFT.image_from` described `use_adjoint_scaling` as "Currently unused" and `TransformerNUFFT.image_from` as "accepted for API compatibility and otherwise unused". Read together those invite deleting the parameter and the `use_adjoint_scaling=True` at `Interferometer.apply_sparse_operator` — which would silently break the pynufft fallback by a factor of `4*N_y*N_x`. Measured against the DFT adjoint on random visibilities: shape legacy raw vs DFT legacy scaled vs DFT (16,16) 9.99e-01 2.61e-02 (32,32) 1.00e+00 4.23e-03 The parameter's contract is "normalise this transformer's adjoint onto the common scale" — a no-op for DFT and the nufftax-backed `TransformerNUFFT` (both already the plain mathematical adjoint), load-bearing for `TransformerNUFFTPyNUFFT`, whose pynufft-internal IFFT normalisation leaves its raw adjoint that factor low. Documented as such, with a do-not-remove note. Docstrings only; no behaviour change. Found while closing #326. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 616e8b4 commit 24863a2

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

autoarray/operators/transformer.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,14 @@ def image_from(
176176
visibilities
177177
The complex visibilities to be transformed into a real-space image.
178178
use_adjoint_scaling
179-
If True, the result is scaled by a normalization factor. Currently unused.
179+
If True, normalise the adjoint output onto the common scale shared by
180+
every transformer (that of the plain mathematical adjoint). This is a
181+
no-op for the DFT, whose adjoint is already on that scale; it is
182+
load-bearing for `TransformerNUFFTPyNUFFT`, whose pynufft-internal
183+
IFFT normalisation leaves its raw adjoint a factor `4 * N_y * N_x`
184+
low. Do not remove it as "unused" — see `Interferometer.
185+
apply_sparse_operator`, which passes `True` so the sparse-operator
186+
dirty image is scale-consistent across all three transformers.
180187
181188
Returns
182189
-------
@@ -734,11 +741,15 @@ def image_from(
734741
deconvolution). The structure of the dirty image is the same, and
735742
the values match `TransformerDFT.image_from` exactly.
736743
737-
`use_adjoint_scaling` is accepted for API compatibility with the
738-
legacy class and is otherwise unused (the nufftax adjoint is already
739-
the mathematical adjoint; no extra normalisation is needed). This
740-
matches `TransformerDFT.image_from` semantics so the sparse-operator
741-
path is scale-consistent across both transformers.
744+
`use_adjoint_scaling` normalises the adjoint onto the common scale
745+
shared by every transformer. It is a no-op here (and for
746+
`TransformerDFT`) because the nufftax adjoint is already the plain
747+
mathematical adjoint, but it is load-bearing for
748+
`TransformerNUFFTPyNUFFT`, whose pynufft-internal IFFT normalisation
749+
leaves its raw adjoint a factor `4 * N_y * N_x` low. Do not remove it
750+
as "unused" — `Interferometer.apply_sparse_operator` passes `True` so
751+
the sparse-operator dirty image is scale-consistent across all three
752+
transformers.
742753
"""
743754
n_y, n_x = self.real_space_mask.shape_native
744755
n_modes = (n_x, n_y) # nufftax wants (n1, n2) = (N_x, N_y)

0 commit comments

Comments
 (0)