Repository navigation
Description
Overview
Delaunay(pixels, zeroed_pixels) inflates self.pixels by zeroed_pixels and derives the zeroed edge-ring indices from that inflated count. Every autolens_workspace feature script and the Euclid pipeline pass the appended grid length as pixels, so mesh.pixels overstates the mapper's real parameter count by the ring size. For a single mapper the error cancels inside zeroed_ids_to_keep (the ring is still zeroed, which is why nothing ever failed); with two or more pixelized mappers the first mapper's ring stays live and interior vertices are zeroed instead. The same inflated pixels plus the index-array zeroed_pixels property also break to_dict round-trips (a Delaunay fit reloaded from tracer.json crashes). Full history in PyAutoMind/draft/bug/euclid/delaunay_edge_ring_never_zeroed.md.
Plan
- Make the zeroed ring a property of the mapper's actual source-plane mesh grid: always its last
zeroed_pixelsvertices, whateverpixelssays. - Stop inflating
Delaunay.pixels; store the count the caller passed and the zeroed count as plain ints so the mesh round-trips throughto_dict. - Route
zeroed_ids_to_keepthroughmapper.paramsand a newmapper.zeroed_pixels, and cover the one- and two-mapper cases with tests. - Then fix the call sites to the correct form (
pixels=<interior count>) inautolens_workspaceand the Euclid pipeline, with a Euclid unit test on the mesh construction.
Detailed implementation plan
Affected Repositories
- PyAutoArray (primary)
- euclid_strong_lens_modeling_pipeline
- autolens_workspace
Branch Survey
| Repository | Current Branch | Dirty? |
|---|---|---|
| ./PyAutoArray | main | clean |
| ./euclid_strong_lens_modeling_pipeline | main | clean |
| ./autolens_workspace | main | clean |
Suggested branch: claude/delaunay-edge-ring-zeroed-8l4u1z on all three repos (the workspace and Euclid CI check the library chain out at the same-named branch).
Implementation Steps
autoarray/inversion/mesh/mesh/abstract.py— addAbstractMesh.zeroed_pixels_from(pixels)returning the mesh's ownzeroed_pixelsindex array (empty if the mesh has none).autoarray/inversion/mesh/mesh/delaunay.py—__init__storesself.pixels = int(pixels)andself.zeroed_pixels = int(zeroed_pixels); overridezeroed_pixels_from(pixels)tonp.arange(pixels - zeroed_pixels, pixels); rewrite the docstring (pixels documents the interior count, the ring is the lastzeroed_pixelsvertices of the grid actually handed to the mapper).autoarray/inversion/mappers/abstract.py— addMapper.zeroed_pixels=self.mesh.zeroed_pixels_from(pixels=self.params).autoarray/inversion/inversion/abstract.py—zeroed_ids_to_keepusesm.paramsfor block sizes andm.zeroed_pixelsfor local ids; docstring updated.- Tests:
test_autoarray/inversion/mesh/mesh/test_delaunay.py(ring indices vs grid length,to_dictround-trip) andtest_autoarray/inversion/inversion/test_abstract.py(zeroed_ids_to_keepwith Delaunay mappers: one mapper under both call forms, two mappers). euclid_strong_lens_modeling_pipeline—scripts/initial_lens_model.py, both sites inscripts/full_model.py,hpc/diagnostics/jax_fork_control.pypass the interior count; a test intests/builds the mesh as the script does and asserts the ring indices are the appended points.autolens_workspace— the 20pixels=image_plane_mesh_grid.shape[0]sites underscripts/pass the image-mesh pixel count; prose updated; notebooks regenerated.
Key Files
autoarray/inversion/mesh/mesh/delaunay.py— the constructor and ring semanticsautoarray/inversion/inversion/abstract.py—zeroed_ids_to_keep, the only consumer of the ringautoarray/inversion/mappers/abstract.py—paramsis the real parameter count
Follow-ups (not in this task)
autolens_workspace_test/scripts/multi_dataset/dataset_model_parity_delaunay.pyandautolens_workspace_developer/jax_profiling/*/delaunay.pystill pass the appended length; harmless after step 4, tidy separately.
Original Prompt
Click to expand starting prompt
See PyAutoMind/draft/bug/euclid/delaunay_edge_ring_never_zeroed.md (finding, provenance and the 2026-09-05 history audit).
Activity
Jammy2211 commentedon Sep 5, 2026
Library PR Created — workspace legs open behind the library-first gate
pixels#527 (pending-release)pixelseuclid_strong_lens_modeling_pipeline#52, fix: Delaunaypixelsis the interior vertex count, not the appended grid length autolens_workspace#535 (bothpending-release; their CI checks the library chain out at the same-named branchclaude/delaunay-edge-ring-zeroed-8l4u1z)API-change summary.
Delaunay.pixelsis no longer inflated byzeroed_pixels(it is the interior count as passed;total_pixelsadds the ring);Delaunay.zeroed_pixelsis the int count and the indices come fromzeroed_pixels_from(pixels); newAbstractMesh.zeroed_pixels_fromandMapper.zeroed_pixels;zeroed_ids_to_keepsizes blocks bymapper.params. Both call forms in the wild zero the same vertices; two-mapper inversions are now correct; the mesh round-trips throughto_dict.Verified. autoarray 1369 passed / 62 skipped; Euclid fast suite 74 passed against the branch; workspace imaging and multi-galaxy Delaunay scripts run end-to-end under the smoke profile.
Next:
/prmmerges library-first, then the two workspace PRs. Follow-ups outside this task:autolens_workspace_test/scripts/multi_dataset/dataset_model_parity_delaunay.pyandautolens_workspace_developer/jax_profiling/*/delaunay.pystill pass the appended length (harmless after #527).Generated by Claude Code
Jammy2211 commentedon Sep 5, 2026
Shipped
pixels#527 merged (a0e5c61) — the Delaunay zeroed ring is resolved against the mapper's real grid (Mapper.zeroed_pixels→mesh.zeroed_pixels_from(params));Delaunay.pixels/zeroed_pixelsstored as passed,total_pixelsadded,to_dictround-trips. CI 3/3 legs green.pixelseuclid_strong_lens_modeling_pipeline#52 merged (dbdbe1d) — the four vis_pix sites pass the interior count;tests/test_delaunay_edge_ring.pyadded. CI 9/9 legs green.pixelsis the interior vertex count, not the appended grid length autolens_workspace#535 merged (715144c) — 18 feature-script sites, the Edge Zeroing prose, and the two likelihood walkthroughs that zeroed interior overlay points; notebooks regenerated. CI 7/7 legs green.Summary. The over-count cancelled for a single mapper, so no archived single-source result changes; two-mapper inversions now zero every ring correctly and a Delaunay fit reloads from
tracer.json. History of how the fix landed only in the SLaM and test-workspace scripts is in the completion recordPyAutoMind/complete/2026/09/delaunay-edge-ring-zeroed.md.Pending release. PyAutoArray#527 carries
pending-release; the workspace and Euclid changes need no new API and run against any autoarray.Follow-ups (not filed).
autolens_workspace_test/scripts/multi_dataset/dataset_model_parity_delaunay.pyandautolens_workspace_developer/jax_profiling/*/delaunay.pystill pass the appended length — harmless now, tidy when next touched.Generated by Claude Code