Skip to content

feat: potential corrections (gravitational imaging) — port Cao's package #618

Description

@Jammy2211

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)

  1. 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.
  2. 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.
  3. 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.
  4. Do not port covariance_reg.py / the GPy + numba-scipy kernel builders — GaussianKernelRegularization, ExponentialKernelRegularization, MaternKernelRegularization already exist in autoarray/inversion/regularization/.
  5. 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.pyautogalaxy/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.
  1. Fix the ported code smells: no except:-swallowing (per no-silent-guards rule), seed the random-solution draws, symmetrise covariance handling explicitly.
  2. 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.
  3. Parity script (workspace_test follow-up, not this PR): port outputs vs original repo on the same simulated dataset.
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions