You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PyAutoArray has accumulated 8 public rectangular mesh classes, 5 interpolators and 2 geometries from three generations of gradient work (linear empirical-CDF → spline-CDF → kernel-density-CDF, plus the PCA-rotated multi-node experiment). Only the kernel meshes (the certified gradient path, PR #374) and RectangularUniform (HowToLens methodology illustration) are needed. This task consolidates the family: the kernel implementation takes over the plain names RectangularAdaptDensity/RectangularAdaptImage (zero churn in workspaces, prior YAMLs and saved results), and the linear, spline and rotated variants are deleted from source (recoverable via git history + PyAutoGut condemned refs).
Plan
Merge the kernel-CDF interpolator into interpolator/rectangular.py; InterpolatorRectangular becomes the kernel implementation (name + module path survive → zero forced downstream edits).
Delete the spline pair, rotated mesh/interpolator/geometry, density_components.py, the RectangularKernel* names and the linear empirical-CDF path.
RectangularAdaptDensity/AdaptImage gain bandwidth/n_knots kwargs; RectangularUniform unchanged behaviorally.
Redistribute the 17 kernel tests under the plain names; delete spline/rotated tests; replace kernel-vs-linear comparisons with analytic invariants.
Downstream (PyAutoGalaxy/PyAutoLens): expected zero-diff — verify by test suite.
Workspace leg: user workspaces need zero code edits; update autolens_workspace_test jax_grad variants to the plain names (FD certification is the gate); stash autolens_workspace_developer spline/rotated experiments in PyAutoGut.
Autodiff evidence for keeping kernel (gradient audit #87 + certified jax_grad harness): linear is exactly piecewise-constant in mass/shear at os=1 and on the interferometer sparse path (no usable gradients; 1–3% FD contamination at os=4); spline was never certified (eager-vs-JIT LL gap ~15, erratic FD; superseded); kernel is C∞, strict FD-certified on ALL params in every configuration (imaging os=1/os=4/production shape, interferometer sparse) with FoM parity 2.7e-5–6.3e-4 vs linear; uniform is exactly smooth with no transform.
Detailed implementation plan
Affected Repositories
PyAutoArray (primary)
PyAutoGalaxy, PyAutoLens (verify zero-diff; refresh linear-CDF prose if found)
Merge autoarray/inversion/mesh/interpolator/rectangular_kernel.py INTO interpolator/rectangular.py (delete kernel file). Keep from the linear module only reverse_interp/reverse_interp_np (kernel inverse table). Delete forward_interp*, linear create_transforms, linear transformed-grid/mappings helpers, the linear InterpolatorRectangular class body. Rename kernel functions to plain names (create_transforms_kernel → create_transforms, adaptive_rectangular_*_from_kernel → adaptive_rectangular_*_from); InterpolatorRectangularKernel → InterpolatorRectangular(AbstractInterpolator) with ctor (mesh, mesh_grid, data_grid, mesh_weight_map, adapt_data=None, bandwidth=KERNEL_CDF_DEFAULT_BANDWIDTH, n_knots=KERNEL_CDF_DEFAULT_KNOTS, xp=np). Carry over the _mappings_sizes_weights_split passthrough explicitly. Rewrite module docstring.
Delete interpolator/rectangular_spline.py (incl. InvertPolySpline + its pytree registration — the only pytree in the family), interpolator/rectangular_rotated_spline.py, interpolator/density_components.py (unwired).
Geometry: mesh_geometry/abstract.py drops spline_deg (keeps None-able kernel_bandwidth/kernel_knots → Delaunay + pickle tests untouched). mesh_geometry/rectangular.py: delete module-level linear adaptive_rectangular_areas_from (~390–418); collapse 3-branch areas_transformed/edges_transformed to a single kernel call with default-resolved bandwidth/knots (keeps the no-kernel-args uniform path working); keep neighbors/edges helpers + rectangular_edge_pixel_list_from (downstream import) + the issue-fix: rectangular-mesh pcolormesh plots misaligned with mapper node convention #372 node-midpoint edge logic exactly as is. Delete mesh_geometry/rectangular_rotated.py.
Mesh classes: RectangularAdaptDensity.__init__ gains bandwidth/n_knots + an interpolator_kwargs property hook consumed by the base interpolator_from (collapses the duplicated kernel interpolator_from copies). RectangularAdaptImage forwards kwargs, keeps mesh_weight_map_from verbatim. RectangularUniform overrides interpolator_kwargs → {} (its interpolator ctor has no bandwidth/knots — would TypeError). Delete rectangular_kernel_adapt_*.py ×2, rectangular_spline_adapt_*.py ×2, rectangular_rotated_adapt_image.py.
mesh/mesh/__init__.py shrinks to Mesh, RectangularAdaptDensity, RectangularAdaptImage, RectangularUniform, Delaunay, KNearestNeighbor, KNNBarycentric — no compatibility aliases. autoarray/__init__.py unchanged (optional: drop duplicate line-81 import). plot/inversion.py isinstance dispatch works with zero edits (uniform does NOT subclass InterpolatorRectangular — imshow-vs-pcolormesh split preserved).
Tests: delete mesh/test_rectangular_spline.py (12) + mesh/test_rectangular_rotated_adapt_image.py (14). Redistribute the 17 tests of mesh/test_rectangular_kernel.py: construction/weight-map → mesh/test_rectangular.py under plain names (RectangularAdaptImage's first dedicated coverage); transform/helper → interpolator/test_rectangular.py (currently an empty pass stub). Kernel-vs-linear comparisons → analytic invariants (areas sum to bounding-box area; large-bandwidth → uniform limit). Recompute the hard-coded linear value in mesh_geometry/test_rectangular.py::test__areas_transformed; port the fix: rectangular-mesh pcolormesh plots misaligned with mapper node convention #372 regression test's helper imports.
User workspaces (autolens_workspace, autogalaxy_workspace, HowToLens, HowToGalaxy, euclid pipeline): zero code edits; spot-check tutorial prose describing CDF mechanics.
autolens_workspace_test: merge jax_grad kernel variants (E/F/G in scripts/jax_grad/imaging_pixelization.py, D in interferometer.py) into the plain-named variants; drop linear-only variants; FD certification stays green.
autolens_workspace_developer (wait on blackjax claim): stash rect_adapt_duo/, searches_minimal/probe_grad_pix*.py, jax_profiling/misc/pixelization_spline_vs_linear.py + _fit_comparison.py in PyAutoGut; rename kernel-named scripts to plain names; update jax_profiling/gradient/README.md rows.
Key Files
autoarray/inversion/mesh/interpolator/rectangular.py — becomes the kernel implementation
autoarray/inversion/mesh/interpolator/rectangular_kernel.py — merged in, deleted
python -m pytest test_autoarray/ green; grep sweep RectangularKernel|RectangularSpline|RectangularRotated|InvertPolySpline|create_transforms_kernel|spline_deg|density_components|forward_interp returns zero hits in autoarray/ + test_autoarray/.
PyAutoGalaxy + PyAutoLens full pytest against the new autoarray (expected zero-diff).
autolens_workspace_test jax_grad strict-FD assertions green on the plain-named meshes (os=1, os=4, production shape, interferometer sparse).
Aggregator round-trip: old plain-name result loads under the new classes.
Original Prompt
Click to expand starting prompt
In PYAutoArray we have ended up with loads of Rectangular mesh classes and associated other classes, and its confusing and unecessary. I think only two are actually use: The kernel one which actually does gradients ok, and the uniform one which does not use interpolation which is used in HowToLens to illustrate the methodology. Can you do a census of all these different classes, confirm only these are useful (but keep both adaptdensity and adaptimage) and refactor and tidy up this part of the source code? In turn make sure all workspaces only use this gradient one which is the one users will actually use. Double check none others have any use. We also did some work on a more adaptive rectangular mesh which for example adapts to multiple nodes. This work may come back (e.g. once we have the basic rectangular working with gradients well) but lets move it out the source code, if its thre, for now, and stash workspace work in PyAutoGut. im not usre what rectangular_rotated_adapt_image.py is for and if we still need it, and if the split / kernel separrate methods both have uses but lets get down to just one
Overview
PyAutoArray has accumulated 8 public rectangular mesh classes, 5 interpolators and 2 geometries from three generations of gradient work (linear empirical-CDF → spline-CDF → kernel-density-CDF, plus the PCA-rotated multi-node experiment). Only the kernel meshes (the certified gradient path, PR #374) and
RectangularUniform(HowToLens methodology illustration) are needed. This task consolidates the family: the kernel implementation takes over the plain namesRectangularAdaptDensity/RectangularAdaptImage(zero churn in workspaces, prior YAMLs and saved results), and the linear, spline and rotated variants are deleted from source (recoverable via git history + PyAutoGut condemned refs).Plan
interpolator/rectangular.py;InterpolatorRectangularbecomes the kernel implementation (name + module path survive → zero forced downstream edits).density_components.py, theRectangularKernel*names and the linear empirical-CDF path.RectangularAdaptDensity/AdaptImagegainbandwidth/n_knotskwargs;RectangularUniformunchanged behaviorally.autolens_workspace_testjax_grad variants to the plain names (FD certification is the gate); stashautolens_workspace_developerspline/rotated experiments in PyAutoGut.Autodiff evidence for keeping kernel (gradient audit #87 + certified jax_grad harness): linear is exactly piecewise-constant in mass/shear at os=1 and on the interferometer sparse path (no usable gradients; 1–3% FD contamination at os=4); spline was never certified (eager-vs-JIT LL gap ~15, erratic FD; superseded); kernel is C∞, strict FD-certified on ALL params in every configuration (imaging os=1/os=4/production shape, interferometer sparse) with FoM parity 2.7e-5–6.3e-4 vs linear; uniform is exactly smooth with no transform.
Detailed implementation plan
Affected Repositories
Branch Survey (2026-07-23)
Suggested branch:
feature/rectangular-mesh-consolidationImplementation Steps (library leg)
autoarray/inversion/mesh/interpolator/rectangular_kernel.pyINTOinterpolator/rectangular.py(delete kernel file). Keep from the linear module onlyreverse_interp/reverse_interp_np(kernel inverse table). Deleteforward_interp*, linearcreate_transforms, linear transformed-grid/mappings helpers, the linearInterpolatorRectangularclass body. Rename kernel functions to plain names (create_transforms_kernel→create_transforms,adaptive_rectangular_*_from_kernel→adaptive_rectangular_*_from);InterpolatorRectangularKernel→InterpolatorRectangular(AbstractInterpolator)with ctor(mesh, mesh_grid, data_grid, mesh_weight_map, adapt_data=None, bandwidth=KERNEL_CDF_DEFAULT_BANDWIDTH, n_knots=KERNEL_CDF_DEFAULT_KNOTS, xp=np). Carry over the_mappings_sizes_weights_splitpassthrough explicitly. Rewrite module docstring.interpolator/rectangular_spline.py(incl.InvertPolySpline+ its pytree registration — the only pytree in the family),interpolator/rectangular_rotated_spline.py,interpolator/density_components.py(unwired).mesh_geometry/abstract.pydropsspline_deg(keeps None-ablekernel_bandwidth/kernel_knots→ Delaunay + pickle tests untouched).mesh_geometry/rectangular.py: delete module-level linearadaptive_rectangular_areas_from(~390–418); collapse 3-branchareas_transformed/edges_transformedto a single kernel call with default-resolved bandwidth/knots (keeps the no-kernel-args uniform path working); keep neighbors/edges helpers +rectangular_edge_pixel_list_from(downstream import) + the issue-fix: rectangular-mesh pcolormesh plots misaligned with mapper node convention #372 node-midpoint edge logic exactly as is. Deletemesh_geometry/rectangular_rotated.py.RectangularAdaptDensity.__init__gainsbandwidth/n_knots+ aninterpolator_kwargsproperty hook consumed by the baseinterpolator_from(collapses the duplicated kernelinterpolator_fromcopies).RectangularAdaptImageforwards kwargs, keepsmesh_weight_map_fromverbatim.RectangularUniformoverridesinterpolator_kwargs→{}(its interpolator ctor has no bandwidth/knots — would TypeError). Deleterectangular_kernel_adapt_*.py×2,rectangular_spline_adapt_*.py×2,rectangular_rotated_adapt_image.py.mesh/mesh/__init__.pyshrinks to Mesh, RectangularAdaptDensity, RectangularAdaptImage, RectangularUniform, Delaunay, KNearestNeighbor, KNNBarycentric — no compatibility aliases.autoarray/__init__.pyunchanged (optional: drop duplicate line-81 import).plot/inversion.pyisinstance dispatch works with zero edits (uniform does NOT subclass InterpolatorRectangular — imshow-vs-pcolormesh split preserved).mesh/test_rectangular_spline.py(12) +mesh/test_rectangular_rotated_adapt_image.py(14). Redistribute the 17 tests ofmesh/test_rectangular_kernel.py: construction/weight-map →mesh/test_rectangular.pyunder plain names (RectangularAdaptImage's first dedicated coverage); transform/helper →interpolator/test_rectangular.py(currently an emptypassstub). Kernel-vs-linear comparisons → analytic invariants (areas sum to bounding-box area; large-bandwidth → uniform limit). Recompute the hard-coded linear value inmesh_geometry/test_rectangular.py::test__areas_transformed; port the fix: rectangular-mesh pcolormesh plots misaligned with mapper node convention #372 regression test's helper imports.Behavioural risks (flag in PR body)
areas_for_magnificationlatently switches to kernel defaults (no consumer found).Workspace leg (after library merge)
scripts/jax_grad/imaging_pixelization.py, D ininterferometer.py) into the plain-named variants; drop linear-only variants; FD certification stays green.rect_adapt_duo/,searches_minimal/probe_grad_pix*.py,jax_profiling/misc/pixelization_spline_vs_linear.py+_fit_comparison.pyin PyAutoGut; rename kernel-named scripts to plain names; updatejax_profiling/gradient/README.mdrows.Key Files
autoarray/inversion/mesh/interpolator/rectangular.py— becomes the kernel implementationautoarray/inversion/mesh/interpolator/rectangular_kernel.py— merged in, deletedautoarray/inversion/mesh/mesh_geometry/rectangular.py— branch collapseautoarray/inversion/mesh/mesh/rectangular_adapt_density.py/rectangular_adapt_image.py/rectangular_uniform.py— surviving meshestest_autoarray/inversion/pixelization/mesh/test_rectangular_kernel.py— redistributedVerification
python -m pytest test_autoarray/green; grep sweepRectangularKernel|RectangularSpline|RectangularRotated|InvertPolySpline|create_transforms_kernel|spline_deg|density_components|forward_interpreturns zero hits in autoarray/ + test_autoarray/.Original Prompt
Click to expand starting prompt
In PYAutoArray we have ended up with loads of Rectangular mesh classes and associated other classes, and its confusing and unecessary. I think only two are actually use: The kernel one which actually does gradients ok, and the uniform one which does not use interpolation which is used in HowToLens to illustrate the methodology. Can you do a census of all these different classes, confirm only these are useful (but keep both adaptdensity and adaptimage) and refactor and tidy up this part of the source code? In turn make sure all workspaces only use this gradient one which is the one users will actually use. Double check none others have any use. We also did some work on a more adaptive rectangular mesh which for example adapts to multiple nodes. This work may come back (e.g. once we have the basic rectangular working with gradients well) but lets move it out the source code, if its thre, for now, and stash workspace work in PyAutoGut. im not usre what rectangular_rotated_adapt_image.py is for and if we still need it, and if the split / kernel separrate methods both have uses but lets get down to just one