Skip to content

feat: oversampled PSF inversion wiring — mapping formalism (phase 2b) #356

Description

@Jammy2211

Overview

Phase 2b of oversampled PSF convolution: wire the phase-2a Convolver API (#354, PR #355) into the inversion's mapping formalism, per §4 of the approved design (PyAutoMind/feature/autoarray/oversampling_design.md, approved in #353). Blocked until PR #355 merges — it builds directly on the 2a API.

Plan

  • Add Mapper.mapping_matrix_over_sampled: one row per sub-pixel, no sub_fraction fold (the existing mapping_matrix folds sub-pixels to image resolution before the Convolver ever sees them, which is exactly what oversampled convolution must intercept).
  • Route AbstractInversionImaging.operated_mapping_matrix_list (autoarray/inversion/inversion/imaging/abstract.py:104-116 — the actual PSF application site; mapping.py itself needs no logic change) through the oversampled Convolver path when psf.convolve_over_sample_size > 1.
  • Loud guards on the two paths that consume psf.kernel.native directly and cannot support oversampling yet: InversionImagingSparse.psf_weighted_data and the preloaded linear-func operated matrices (abstract.py:215-230).
  • Memory profile of the ×s² FFT cube ((ny·s, nx·s, n_src)) on a realistic pixelization before anything defaults on — the main risk flagged in the design; chunking is the noted mitigation.
Detailed implementation plan

Affected Repositories

  • PyAutoArray (primary, only repo edited)

Branch Survey

Deferred to start (task is blocked on PR #355; survey ages out).

Suggested branch: feature/psf-oversample-inversion

Implementation Steps

  1. inversion/mappers/abstract.py: mapping_matrix_over_sampled property reusing the existing sub→pix index maps (slim_for_sub_slim), emitting shape (n_unmasked·s², n_src) in per-pixel sub-block order — the 2a Convolver input format.
  2. inversion/inversion/imaging/abstract.py::operated_mapping_matrix_list: when self.psf.convolve_over_sample_size > 1, pass linear_obj.mapping_matrix_over_sampled to psf.convolved_mapping_matrix_from (which already handles the fine-grid scatter/convolve/bin from 2a); otherwise unchanged.
  3. Guards: InversionImagingSparse.psf_weighted_data and the linear-func kernel consumers raise InversionException/DatasetException when the psf is oversampled (deferred formalism, per the approved design).
  4. Tests (numpy-only): delta-kernel identity (mapping_matrix_over_sampled binned by mean == mapping_matrix); end-to-end mapping-formalism inversion at s=2 against a brute-force reference built from the ground-truth machinery; guard tests; full suite.
  5. Memory profile note in the PR (realistic pixelization, s=2), per design §4.

Key Files

  • autoarray/inversion/mappers/abstract.py — mapping_matrix (sub_fraction fold) at lines 255–275
  • autoarray/inversion/inversion/imaging/abstract.py — PSF application + linear-func preloads
  • autoarray/inversion/inversion/imaging/sparse.py — guard target
  • PyAutoMind/feature/autoarray/oversampling_design.md §4 — the approved design (do not re-design)

Acceptance

  • Full PyAutoArray pytest suite green; s=1 inversions byte-identical.
  • s=2 mapping-formalism inversion matches the brute-force reference.
  • Memory profile recorded in the PR body.

Original Prompt

Click to expand starting prompt

See PyAutoMind/issued/oversampling_phase_2b_inversion_wiring.md (phase 2b split of oversampling_phase_2_core_api.md; design approved in #353; predecessor #354 / PR #355).

Activity

  1. Jammy2211 commented on Jul 8, 2026

    @Jammy2211
    CollaboratorAuthor

    Phase 2b implemented — at the ship sign-off checkpoint

    Committed locally on feature/psf-oversample-inversion (efa985d2, not pushed). Diff: 5 files, +191/−3 (an initial line-ending normalization of two CRLF files was caught and reverted, so the diff is content-only).

    Verification

    Leg Result
    Tests PyAutoArray 860 passed (3 new); downstream PyAutoGalaxy 940, PyAutoLens 334 against the branch
    Delta-kernel identity mapping_matrix_over_sampled mean-binned == mapping_matrix to 1e-14
    End-to-end s=2 operated_mapping_matrix_list matches an independent brute-force fine-raster convolution to ≤2.3e-16
    Guards linear-func objects, data_linear_func_matrix preload, and sparse psf_weighted_data all raise under an oversampled PSF
    Review Surface: python-source flag. Verdict: CLEAN
    Memory profile ×s² FFT cube at s=2 / 1000 src ≈ 2.1 GB fp64 (vs 0.52 GB at s=1) — fine on A100, tight on 6 GB cards; feature stays opt-in, chunking / fp32 are the mitigations (full table in the drafted PR body)

    Awaiting ship approval (supervised --auto): on approval the branch is pushed and the pending-release PR opens with the drafted body.

    🤖 Generated with Claude Code

  2. Jammy2211 commented on Jul 8, 2026

    @Jammy2211
    CollaboratorAuthor

    🚢 Shipped (human-approved; workspace-level tests deferred to phase 3 by explicit decision): PR #357 (pending-release). Ends at PR-open per the --auto contract — merge on your word. Phase 2c (PyAutoGalaxy consumer switch) is now unblocked and starting.

    🤖 Generated with Claude Code

  3. Jammy2211 commented on Jul 8, 2026

    @Jammy2211
    CollaboratorAuthor

    ✅ Merged as PR #357 (squash). Phase 2b complete — oversampled inversion wiring (mapping formalism) is on main. Workspace-level tests follow in phase 3.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions