Overview
Port Xiaoyue Cao's lensing_potential_correction package — the gravitational-imaging technique (pixelised corrections δψ to the lensing potential, reconstructed jointly with the pixelised source by maximising Bayesian evidence, Matérn-family regularisation) — into the PyAuto libraries as first-class, tested source code. The external package is a wrapper pinned to autolens 2024.1.27.4; the port modernises it to the current API and layers it correctly across autoarray / autogalaxy / autolens. All docs and docstrings cite Cao et al. (2025) via potential_correction_paper and credit the origin repository.
Plan
- Phase 1 — PyAutoArray: port the generic linear algebra — masked-grid sparse differential operators (1st/2nd/4th order, numba), curvature + fourth-order regularizations for rectangular masked meshes, and the coarse-mesh→data-grid interpolation matrix builder. Reuse the existing Gaussian/Exponential/Matérn kernel regularizations (do not port
covariance_reg.py).
- Phase 2 — PyAutoGalaxy: pixelised input mass profiles (
InputDeflections, InputPotential) on the current decorator API; GaussianRandomField perturbation profile reimplemented with plain numpy FFT (no powerbox).
- Phase 3 — PyAutoLens: new
autolens/potential_correction/ subpackage (mirroring autolens/weak) — δψ mesh + data pairing, FitDpsiImaging (δψ-only), FitDpsiSrcImaging (joint source+δψ with full covariance), SrcFactory interpolator family, af.Analysis classes, anchor-point rescaling, visualization; docs + citations.
- NumPy/numba only — the JAX port is a known follow-up PR.
- No new heavy dependencies: GPy, multiprocess, powerbox, numba-scipy stay out (GPR source interpolator dropped or lazily optional).
- Parity check of the port against the original repo's outputs on a small simulated dataset before shipping.
Detailed implementation plan
Affected Repositories
- PyAutoLens (primary — final home of the feature)
- PyAutoArray (phase 1)
- PyAutoGalaxy (phase 2)
Work Classification
Library
Branch Survey
| Repository |
Current Branch |
Dirty? |
Claimable now? |
| ./PyAutoArray |
main |
clean |
yes |
| ./PyAutoGalaxy |
main |
clean |
no — claimed by slam-resume-fastpath |
| ./PyAutoLens |
main |
1 file (paper_jax/paper.md, unrelated JOSS draft) |
no — claimed by slam-resume-fastpath |
Suggested branch: feature/potential-correction
Worktree root: ~/Code/PyAutoLabs-wt/potential-correction-port/ (created by /start_library)
Phase 1 (PyAutoArray) starts immediately; phases 2–3 queue behind slam-resume-fastpath (PyAutoGalaxy#502).
Implementation Steps
Phase 1 — PyAutoArray (generic linear algebra)
- Port masked-grid sparse differential-operator builders from
potential_correction/util.py (diff_1st_operator_numba_from, diff_2nd_operator_numba_from, the 2nd/4th-order regularization operator builders diff_2nd_operator_dpsi_reg_numba_func / diff_4th_operator_dpsi_reg_numba_func, clean_mask / iterative_clean_mask) into a new util module in the inversion layer (e.g. autoarray/inversion/regularization/derivative_util.py), using autoarray.numba_util conventions.
- New regularization classes
autoarray/inversion/regularization/curvature_mask.py + fourth_order_mask.py implementing Cao's CurvatureRegularizationDpsi / FourthOrderRegularizationDpsi as mask-based AbstractRegularization subclasses (renamed to PyAuto conventions, e.g. CurvatureMask / FourthOrderMask); export via autoarray/inversion/regularization/__init__.py and the aa.reg namespace.
- Port the coarse-mesh→data interpolation matrix machinery (
dpsi_mask_from, itp_box_mask_from, dpsi2data_itp_mat_from, linear_weight_from_box) as generic "paired coarse rectangular mesh" utilities.
- Do not port
covariance_reg.py / the GPy + numba-scipy kernel builders — GaussianKernelRegularization, ExponentialKernelRegularization, MaternKernelRegularization already exist in autoarray/inversion/regularization/.
- Unit tests (numpy-only): operator matrices vs finite-difference expectations on small masks; regularization matrices symmetric/PSD; interpolation matrix partition-of-unity rows.
Phase 2 — PyAutoGalaxy (pixelised input mass profiles)
6. Port pix_mass.py → autogalaxy/profiles/mass/input/ (or alongside existing sheets): InputDeflections (from y/x deflection grids; convergence via 1st-order operators) and InputPotential (deflections/convergence via 1st/2nd-order operators), replacing old aa.grid_dec.* decorators with the current aa.decorators equivalents and LinearNDInterpolatorExt with a shared util.
7. Reimplement GaussianRandomField mass profile (from custom_mass.py) with plain numpy FFT — needed to simulate extended perturbations for tests/validation. Skip EPL/Multipole/EPLBoxyDisky (duplicates of existing profiles).
8. Unit tests: interpolated deflections/convergence round-trip against an analytic profile evaluated on a grid.
Phase 3 — PyAutoLens (the technique itself)
9. New subpackage autolens/potential_correction/:
mesh.py: RegularDpsiMesh, PairRegularDpsiMesh (from dpsi_mesh.py), grid pairing + operators built from the phase-1 autoarray utils.
pixelization.py: DpsiPixelization, DpsiSrcPixelization model components.
fit.py: FitDpsiImaging (linear δψ inversion of an image residual) and FitDpsiSrcImaging (joint source+δψ: block mapping matrix [F_src | −B·D_s·D_ψ], block-diag regularization, evidence terms), re-anchored on current FitImaging / AdaptImages / SettingsInversion API (over-sampling replaces SettingsImaging(sub_size=…); Tracer(galaxies=…) replaces Tracer.from_galaxies).
src_factory.py: SrcFactory ABC + AnalyticSrcFactory, PixSrcFactory (Delaunay/RBF), NN variant behind the existing optional nn_py guard; GPy GPR variant dropped.
analysis.py: DpsiInvAnalysis, DpsiSrcInvAnalysis, SrcInvAnalysis (af.Analysis subclasses); InversionException → penalty handling per current conventions (no bare except).
util.py: anchor-point rescaling (solve_dpsi_rescale_factor, Suyu scheme), PSF blur-matrix builder (reuse/extend aa.Convolver where possible), inverse-noise covariance.
plot/: port visualize.py figures onto the matplotlib function conventions used by the current plot API.
- Fix the ported code smells: no
except:-swallowing (per no-silent-guards rule), seed the random-solution draws, symmetrise covariance handling explicitly.
- Unit tests (numpy-only, no JAX): evidence pipeline on a tiny simulated dataset; δψ recovery of an injected SIS perturber sign/scale sanity check; anchor rescaling exactness on a plane.
- Parity script (workspace_test follow-up, not this PR): port outputs vs original repo on the same simulated dataset.
- Docs:
docs/api entries; citation block (Cao et al. 2025 + both repo URLs) in the subpackage __init__/module docstrings and the relevant docs page; README/docs "cite us" material updated.
Key Files
PyAutoArray/autoarray/inversion/regularization/ — existing kernel regs to reuse; new curvature/fourth-order mask regs land here.
PyAutoArray/autoarray/numba_util.py — numba decorator conventions for the ported operators.
PyAutoGalaxy/autogalaxy/profiles/mass/ — home for input pixelised mass profiles.
PyAutoLens/autolens/weak/ — structural precedent for a new technique subpackage.
PyAutoLens/autolens/interop/coolest.py — precedent for optional-dependency + citation handling.
- External source:
potential_correction/{util,dpsi_mesh,dpsi_inv,dpsi_src_inv,pix_mass,covariance_reg,visualize}.py.
Citation requirement
Every new module docstring group and docs page cites:
Original Prompt
Click to expand starting prompt
This is an implmeentation of the potential corrections, which supports PyAutoLens, can you take this and incorporate it proeprly into the PyAuto ecosystem source code: https://github.com/caoxiaoyue/lensing_potential_correction . It uses a lot of linear algebra, so maybe belongs in the autoarray inversion module, but its also very lensing specific so could go further down. For now, dont worry about JAX, we have a JAX code whichw e can bring in in a future PR, or maybe I'll just ask you to do it later. Also make sure docs and other materials cite this properly https://github.com/caoxiaoyue/potential_correction_paper.
Prompt file: PyAutoMind/active/potential_correction_port.md
Overview
Port Xiaoyue Cao's
lensing_potential_correctionpackage — the gravitational-imaging technique (pixelised corrections δψ to the lensing potential, reconstructed jointly with the pixelised source by maximising Bayesian evidence, Matérn-family regularisation) — into the PyAuto libraries as first-class, tested source code. The external package is a wrapper pinned to autolens 2024.1.27.4; the port modernises it to the current API and layers it correctly across autoarray / autogalaxy / autolens. All docs and docstrings cite Cao et al. (2025) viapotential_correction_paperand credit the origin repository.Plan
covariance_reg.py).InputDeflections,InputPotential) on the current decorator API;GaussianRandomFieldperturbation profile reimplemented with plain numpy FFT (no powerbox).autolens/potential_correction/subpackage (mirroringautolens/weak) — δψ mesh + data pairing,FitDpsiImaging(δψ-only),FitDpsiSrcImaging(joint source+δψ with full covariance),SrcFactoryinterpolator family,af.Analysisclasses, anchor-point rescaling, visualization; docs + citations.Detailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
slam-resume-fastpathpaper_jax/paper.md, unrelated JOSS draft)slam-resume-fastpathSuggested branch:
feature/potential-correctionWorktree root:
~/Code/PyAutoLabs-wt/potential-correction-port/(created by/start_library)Phase 1 (PyAutoArray) starts immediately; phases 2–3 queue behind
slam-resume-fastpath(PyAutoGalaxy#502).Implementation Steps
Phase 1 — PyAutoArray (generic linear algebra)
potential_correction/util.py(diff_1st_operator_numba_from,diff_2nd_operator_numba_from, the 2nd/4th-order regularization operator buildersdiff_2nd_operator_dpsi_reg_numba_func/diff_4th_operator_dpsi_reg_numba_func,clean_mask/iterative_clean_mask) into a new util module in the inversion layer (e.g.autoarray/inversion/regularization/derivative_util.py), usingautoarray.numba_utilconventions.autoarray/inversion/regularization/curvature_mask.py+fourth_order_mask.pyimplementing Cao'sCurvatureRegularizationDpsi/FourthOrderRegularizationDpsias mask-basedAbstractRegularizationsubclasses (renamed to PyAuto conventions, e.g.CurvatureMask/FourthOrderMask); export viaautoarray/inversion/regularization/__init__.pyand theaa.regnamespace.dpsi_mask_from,itp_box_mask_from,dpsi2data_itp_mat_from,linear_weight_from_box) as generic "paired coarse rectangular mesh" utilities.covariance_reg.py/ the GPy + numba-scipy kernel builders —GaussianKernelRegularization,ExponentialKernelRegularization,MaternKernelRegularizationalready exist inautoarray/inversion/regularization/.Phase 2 — PyAutoGalaxy (pixelised input mass profiles)
6. Port
pix_mass.py→autogalaxy/profiles/mass/input/(or alongside existing sheets):InputDeflections(from y/x deflection grids; convergence via 1st-order operators) andInputPotential(deflections/convergence via 1st/2nd-order operators), replacing oldaa.grid_dec.*decorators with the currentaa.decoratorsequivalents andLinearNDInterpolatorExtwith a shared util.7. Reimplement
GaussianRandomFieldmass profile (fromcustom_mass.py) with plain numpy FFT — needed to simulate extended perturbations for tests/validation. SkipEPL/Multipole/EPLBoxyDisky(duplicates of existing profiles).8. Unit tests: interpolated deflections/convergence round-trip against an analytic profile evaluated on a grid.
Phase 3 — PyAutoLens (the technique itself)
9. New subpackage
autolens/potential_correction/:mesh.py:RegularDpsiMesh,PairRegularDpsiMesh(fromdpsi_mesh.py), grid pairing + operators built from the phase-1 autoarray utils.pixelization.py:DpsiPixelization,DpsiSrcPixelizationmodel components.fit.py:FitDpsiImaging(linear δψ inversion of an image residual) andFitDpsiSrcImaging(joint source+δψ: block mapping matrix[F_src | −B·D_s·D_ψ], block-diag regularization, evidence terms), re-anchored on currentFitImaging/AdaptImages/SettingsInversionAPI (over-sampling replacesSettingsImaging(sub_size=…);Tracer(galaxies=…)replacesTracer.from_galaxies).src_factory.py:SrcFactoryABC +AnalyticSrcFactory,PixSrcFactory(Delaunay/RBF), NN variant behind the existing optionalnn_pyguard; GPy GPR variant dropped.analysis.py:DpsiInvAnalysis,DpsiSrcInvAnalysis,SrcInvAnalysis(af.Analysissubclasses);InversionException→ penalty handling per current conventions (no bareexcept).util.py: anchor-point rescaling (solve_dpsi_rescale_factor, Suyu scheme), PSF blur-matrix builder (reuse/extendaa.Convolverwhere possible), inverse-noise covariance.plot/: portvisualize.pyfigures onto the matplotlib function conventions used by the current plot API.except:-swallowing (per no-silent-guards rule), seed the random-solution draws, symmetrise covariance handling explicitly.docs/apientries; citation block (Cao et al. 2025 + both repo URLs) in the subpackage__init__/module docstrings and the relevant docs page; README/docs "cite us" material updated.Key Files
PyAutoArray/autoarray/inversion/regularization/— existing kernel regs to reuse; new curvature/fourth-order mask regs land here.PyAutoArray/autoarray/numba_util.py— numba decorator conventions for the ported operators.PyAutoGalaxy/autogalaxy/profiles/mass/— home for input pixelised mass profiles.PyAutoLens/autolens/weak/— structural precedent for a new technique subpackage.PyAutoLens/autolens/interop/coolest.py— precedent for optional-dependency + citation handling.potential_correction/{util,dpsi_mesh,dpsi_inv,dpsi_src_inv,pix_mass,covariance_reg,visualize}.py.Citation requirement
Every new module docstring group and docs page cites:
Original Prompt
Click to expand starting prompt
Prompt file:
PyAutoMind/active/potential_correction_port.md