fix: name adapt_images when an adaptive mesh has no image-plane grid (#332) - #442
Merged
Merged
Conversation
…332) Omitting adapt_images with Delaunay / KNearestNeighbor / KNNBarycentric used to surface as: AttributeError: 'NoneType' object has no attribute 'array' autoarray/inversion/mesh/border_relocator.py, relocated_mesh_grid_from naming nothing the caller controls, in a file they have never opened. It now raises MeshException at the point the precondition is known to be unmet, naming adapt_images, showing the AdaptImages idiom, and noting that the rectangular family needs no adapt_images at all. The guard sits at Delaunay.interpolator_from, the entry point the whole adaptive family inherits, so one check covers all three meshes. Chose fail-fast over having the mesh wire the grid up itself (the reporter's own suggestion). Building an image-plane mesh grid requires a weighting policy — which is exactly what adapt_images carries — so inventing one here would silently make a science choice on the user's behalf. This matches how phase 1 handled the rectangular/split combination: an explicit "you must supply X" rather than implementing a missing capability. THE MESHES ARE NOT BROKEN. The issue headline says Delaunay and KNNBarycentric are "unusable in FitImaging"; that is false and the reply on #332 already corrects it. Verified again here: with adapt_images supplied, Delaunay+Constant, KNNBarycentric+Constant and Delaunay+ConstantSplit all fit, and RectangularUniform+Constant fits with no adapt_images at all. The tests assert the CLEAR FAILURE plus those controls — asserting bare construction succeeds would have enshrined the misreading. One correction to the recorded diagnosis: the None is `mesh_grid` (border_relocator.py:450), not `grid` (line 446) as the prompt stated. Part 2 of #332 (ConstantSplit on RectangularUniform) shipped in phase 1 and is untouched. Tests: 10 new cases in test_autoarray/inversion/pixelization/mesh/test_adapt_images_precondition.py. Suite 991 passed; the 3 pynufft failures in test_transformer.py are pre-existing on main and tracked separately. Closes #332. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013PgqSCLTemK5bApVAwhVM4
This was referenced Aug 9, 2026
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.
Closes #332. Phase 3 of the @rhayes777 API audit epic #415.
The issue's headline says
DelaunayandKNNBarycentricare "unusable inFitImaging". That is false, and the reply already posted on #332 corrects it while crediting the underlying finding. This PR keeps that framing.Re-verified on this branch — with
adapt_imagessupplied, everything fits:Delaunay+Constant+adapt_imagesDelaunay+ConstantSplit+adapt_imagesKNNBarycentric+Constant+adapt_imagesRectangularUniform+Constant(noadapt_imagesneeded)Delaunay/KNNBarycentric, noadapt_imagesSo the defect is the error, not the mesh.
What this fixes
Omitting
adapt_imagesused to surface as:— naming nothing the caller controls, in a file they have never opened. It now raises
MeshExceptionat the point the precondition is known to be unmet, namingadapt_images, showing theAdaptImagesidiom, and noting that the rectangular family needs noadapt_imagesat all.The guard sits at
Delaunay.interpolator_from, the entry pointKNearestNeighborandKNNBarycentricboth inherit, so one check covers all three adaptive meshes.Option 1 vs option 2 — recorded, as the issue asked
The issue offered two routes, and @rhayes777 raised the first himself ("the wiring ... probably needs to move inside the mesh classes themselves"):
adapt_images.Chose option 2. Building an image-plane mesh grid requires a weighting policy — which is exactly what
adapt_imagescarries. Inventing one inside the mesh would silently make a science choice on the user's behalf, and would do it invisibly, in the case where the user has given no indication of what they want. Failing fast keeps that choice explicit.It also matches how phase 1 handled the rectangular-mesh / split-regularization case (#417): an explicit "you must supply X" exception rather than implementing a missing capability.
Declining option 1 is a judgement call, not a shortcut — happy to revisit if the intended API really is for
Delaunay(pixels=N)to self-wire.One correction to the recorded diagnosis
The prompt for this task states the
Noneis thegridpassed intoBorderRelocator.relocated_mesh_grid_from(). It is actuallymesh_grid—border_relocator.py:450(mesh_grid.array), not line 446 (grid.array). Same fix, but the note is wrong in the campaign record and worth correcting there.API Changes
No signatures, names or return types change. An adaptive mesh given no
source_plane_mesh_gridnow raisesexc.MeshExceptionatinterpolator_frominstead ofAttributeErrorseveral frames deeper. Both were failures; only the message changes.RectangularUniformand the rest of the rectangular family are explicitly unaffected — they build their own grid, and a control test pins that the guard does not fire for them.Test Plan
test_autoarray/inversion/pixelization/mesh/test_adapt_images_precondition.py— 10 cases.adapt_imagescarries, still builds its interpolator. If those ever fail, the mesh really is broken and the posted reply needs revisiting.RectangularUniformneeds noadapt_images.991 passed, 51 skipped. The 3test_transformer.pypynufft failures are pre-existing onmain(baselined) and tracked separately. Zero regressions.Out of scope
ConstantSplitonRectangularUniform) — already shipped in phase 1 (fix: reject split regularization on rectangular meshes at construction #417,9411904d), covering all 9 rectangular × split combinations. Untouched here.Pixelizationinstantiation rather thanaf.Modelcomposition time — a possible follow-up, not this PR.Generated by Claude Code