fix: resolve the Delaunay zeroed edge ring against the mapper's grid, not pixels - #527
Merged
Merged
Conversation
… not `pixels` (#526) `Delaunay(pixels, zeroed_pixels)` inflated `self.pixels` by `zeroed_pixels` and derived the zeroed ring from that count, while `zeroed_ids_to_keep` offset each mapper's block by `mesh.pixels`. A caller passing the appended grid length as `pixels` (every workspace feature script and the Euclid pipeline) therefore overstated the block by the ring size: for one mapper the error cancelled, for two or more the first mapper's ring stayed live and interior vertices were zeroed instead. The inflated `pixels` plus the index-array `zeroed_pixels` property also broke the `to_dict` round-trip. - `Delaunay.__init__` stores `pixels` and `zeroed_pixels` as the ints passed (so the mesh round-trips through `to_dict`); `total_pixels` adds the ring back on; `zeroed_pixels_from(pixels)` returns the last `zeroed_pixels` indices of a grid of that length. - `AbstractMesh.zeroed_pixels_from(pixels)` returns a mesh's own index array (the rectangular family) or nothing. - `Mapper.zeroed_pixels` resolves the mesh's ring against `params`, the real parameter count. - `zeroed_ids_to_keep` uses `mapper.params` and `mapper.zeroed_pixels`, so the ring is the appended edge points whatever `pixels` says, for every mapper. Tests: mesh semantics, the dict round-trip and both call forms (`test_delaunay.py`); `zeroed_ids_to_keep` with one and two Delaunay mappers (`test_abstract.py`); the DelaunayNN assertion updated to the new counts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XCQK1pjQx7YH5e9dtWrX76
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
Closes #526.
Delaunay(pixels, zeroed_pixels)inflatedself.pixelsbyzeroed_pixelsand derived the zeroed edge-ring indices from that inflated count, whileAbstractInversion.zeroed_ids_to_keepoffset each mapper's block bymesh.pixels. Everyautolens_workspacefeature script and the Euclid pipeline pass the appended grid length aspixels, somesh.pixelsoverstated the mapper's real parameter count by the ring size. For one mapper the error cancelled (the ring was still zeroed, which is why nothing ever failed); with two or more pixelized mappers the first mapper's ring stayed live and interior vertices were zeroed instead. The same inflatedpixelsplus the index-arrayzeroed_pixelsproperty also broke theto_dictround-trip (a Delaunay fit reloaded fromtracer.jsoncrashed).The ring is now a property of the grid the mapper is actually built from: always its last
zeroed_pixelsvertices, resolved throughmapper.params, whateverpixelssays. Both call forms in the wild zero the same vertices, and every mapper's ring lands in the right place.API Changes
Delaunay.pixelsis now the count the caller passed (the interior vertices), no longer inflated byzeroed_pixels;Delaunay.total_pixelsgives the sum.Delaunay.zeroed_pixelsis now the plain int count (it was a derived index array); the indices come from the newDelaunay.zeroed_pixels_from(pixels).AbstractMesh.zeroed_pixels_from(pixels)(returns a mesh's ownzeroed_pixelsindex array, or nothing) andMapper.zeroed_pixels(the mesh's ring resolved againstmapper.params).zeroed_ids_to_keepsizes blocks bymapper.paramsand readsmapper.zeroed_pixels.to_dict/from_dictwith integerpixelsandzeroed_pixels.No downstream reader of
mesh.pixelsor the Delaunayzeroed_pixelsarray exists in PyAutoGalaxy or PyAutoLens; the only consumer waszeroed_ids_to_keep.Test Plan
test_autoarray/inversion/pixelization/mesh/test_delaunay.py— counts stored as passed,zeroed_pixels_fromunder both call forms, subclasses, the rectangular family, the dict round-trip,Mapper.zeroed_pixels.test_autoarray/inversion/inversion/test_abstract.py—zeroed_ids_to_keepwith one Delaunay mapper (both forms, with and without linear light profiles ahead of the block) and with two mappers (the regression: the first ring used to land five indices too low).test_delaunay_nn.pyassertion updated to the new counts.Full API Changes (for automation & release notes)
Changed
autoarray.mesh.Delaunay.__init__(pixels, zeroed_pixels=0, areas_factor=0.5)—self.pixels = int(pixels)(wasint(pixels) + zeroed_pixels);self.zeroed_pixels = int(zeroed_pixels or 0)(was a property returningnp.arange(pixels - n, pixels)). Applies toDelaunayNN,KNearestNeighbor,KNNBarycentric.AbstractInversion.zeroed_ids_to_keep— block sizes frommapper.params, local ids frommapper.zeroed_pixels.Added
Delaunay.total_pixels—pixels + zeroed_pixels.Delaunay.zeroed_pixels_from(pixels)—np.arange(pixels - zeroed_pixels, pixels).AbstractMesh.zeroed_pixels_from(pixels)— the mesh'szeroed_pixelsindex array, or an empty array.Mapper.zeroed_pixels—self.mesh.zeroed_pixels_from(pixels=self.params).Migration
mesh.zeroed_pixels(index array);mesh.pixels(total including ring).mapper.zeroed_pixelsormesh.zeroed_pixels_from(grid_length)for indices;mesh.zeroed_pixelsis the count;mesh.total_pixelsfor the total.pixelskeep working; the documented form ispixels=<interior count>(workspace and Euclid PRs follow).Generated by the PyAutoLabs agent workflow.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XCQK1pjQx7YH5e9dtWrX76
Generated by Claude Code