Skip to content

feat: source-plane magnification maps per mesh pixel (arc 8b) #673

Closed

Description

@Jammy2211

Overview

Second slice (8b) of phase 8 of the cluster strong-lensing arc: source-plane magnification maps, the counterpart of 8a's image-plane map (PyAutoGalaxy#689). Each source-plane pixel shows how much the lens magnifies that region of the source, summed over all its images: on the reconstruction's own mesh for pixelized sources, and on a square grid for parametric and MGE sources.

Plan

  • PyAutoArray: the Mapper gains mesh_magnification — for each mesh pixel, the image-plane area mapped into it divided by its source-plane area (phase 4's areas_for_magnification).
  • PyAutoGalaxy: a mesh plot of that magnification (log10 mu, 8a colour conventions, optional caustics), and a square-pixel version that ray-traces a fine image grid for any mass object.
  • Check the two agree on a simulated lens (median per-pixel agreement reported).
  • PyAutoLens: export both through aplt, with Tracer tests.
  • Workspace: show both in the imaging source science examples; regenerate the catalogue; smoke.

Tier: judge — merge mode: human /prm (PyAutoArray → PyAutoGalaxy → PyAutoLens → autolens_workspace).

Detailed implementation plan

Affected Repositories

  • PyAutoArray (primary)
  • PyAutoGalaxy
  • PyAutoLens
  • autolens_workspace

Branch Survey

Repository Current Branch Dirty?
./PyAutoArray main clean
./PyAutoGalaxy main clean
./PyAutoLens main clean
./autolens_workspace main clean

Suggested branch: feature/magnification-maps-source-plane

Implementation Steps

  1. autoarray/inversion/mappers/abstract.py: Mapper.mesh_magnification → np.ndarray of length pixels: mapping_matrix.sum(axis=0) * pixel_area / mesh_geometry.areas_for_magnification (pixel area from self.mask.pixel_scales). Pixels with zero area or no mapped image area return 0 (documented). Tests in test_autoarray/inversion/pixelization/mappers/: area identity sum(mu * area) == masked image area (to quadrature tolerance), identity mapping gives mu ~ 1 away from the mesh edge; rectangular, Delaunay, KNN.
  2. PyAutoGalaxy autogalaxy/galaxy/plot/galaxies_plots.py:
    • plot_magnification_source_plane(mapper, caustics=None, vmin=None, vmax=None, title=..., output_path=..., ax=None) — plot_inversion_reconstruction(pixel_values=log10(mesh_magnification), mapper=..., lines=caustics).
    • plot_magnification_source_plane_grid(mass_obj, grid, source_shape_native=(100, 100), source_extent=None, sub_size=8, contour_levels=(...), include_caustics=True, ...) — over-sample the image grid, trace with grid - deflections_yx_2d_from(grid), np.histogram2d the sub-pixel areas into square source pixels, mu = area / pixel area, plot log10 mu with the 8a contour helper.
    • Export from autogalaxy/plot/__init__.py; tests.
  3. Witness script (scratch, numbers in the PR): simulated simple__no_lens_light-style lens, Delaunay reconstruction with the true mass model; compare mesh mu per pixel against the square-pixel truth sampled at each mesh pixel centre.
  4. PyAutoLens autolens/plot/__init__.py exports; Tracer tests.
  5. autolens_workspace: scripts/imaging/features/pixelization/source_science.py and scripts/imaging/source_science.py new sections; regenerate_navigator.py autolens; smoke.

Key Files

  • autoarray/inversion/mappers/abstract.py — Mapper
  • autoarray/inversion/mesh/mesh_geometry/{rectangular,delaunay}.py — areas_for_magnification
  • autoarray/plot/inversion.py — plot_inversion_reconstruction
  • autogalaxy/galaxy/plot/galaxies_plots.py — 8a's plot_magnification_2d, _magnification_contours

Original Prompt

Click to expand starting prompt

Magnification maps 8b: source-plane magnification per mesh pixel

Type: feature
Target: PyAutoArray
Repos:

  • PyAutoArray
  • PyAutoGalaxy
  • PyAutoLens
  • autolens_workspace
    Themes:
  • visualization
  • cluster
    Epic: cluster-strong-lensing
    Phase: 8b
    Parent: draft/feature/autolens/magnification_maps_visualization.md
    Difficulty: medium
    Autonomy: supervised
    Priority: high
    Status: formalised
    Consequence: judge
    Review-minutes: 25
    Unattended: no
    Filed: 2026-11-02

Context

Slice of phase 8. Per mesh pixel j: mu_j = (image-plane area mapped into pixel j: sum_i M_ij * pixel area) /
mesh_geometry.areas_for_magnification[j] (phase 4, all meshes). Plot via plot_mapper(mapper, solution_vector=mu).
Square-pixel variant for parametric / MGE sources: ray-trace a fine image-plane grid, histogram image area per
source-plane pixel over its area. Uses the 8a colour/contour conventions. Workspace: pixelization source_science.
Witness: mesh mu map vs the forward-traced truth on a simulated lens (median per-pixel agreement stated).

Original request (human, 2026-11-02)

start 8b
rtu frame should be done so autoarray free now?
yes go ahead, create the issue

Approved plan (2026-11-02)

  1. PyAutoArray: Mapper.mesh_magnification — mu_j = (sum_i M_ij * image pixel area) /
    mesh_geometry.areas_for_magnification[j]; tests: sum(mu_j * area_j) = masked image area, no-lens identity
    mapping gives mu ~ 1 in the mesh interior, rectangular / Delaunay / KNN.
  2. PyAutoGalaxy: plot_magnification_source_plane(mapper, ...) (log10 mu on the mesh via
    plot_inversion_reconstruction, 8a conventions, optional caustics) and
    plot_magnification_source_plane_grid(mass_obj, grid, ...) (square-pixel: ray-trace a fine image grid,
    histogram traced image area per source pixel / pixel area; constant-mu contours).
  3. Witness: mesh mu map vs forward-traced square-pixel truth on a simulated lens; median per-pixel agreement stated.
  4. PyAutoLens: aplt exports + Tracer tests.
  5. autolens_workspace: source-plane map sections in imaging/features/pixelization/source_science.py (mesh) and
    imaging/source_science.py (square-pixel); catalogue regen; smoke.

Activity

  1. Jammy2211 commented on Nov 2, 2026

    @Jammy2211
    CollaboratorAuthor

    Scope update (human, 2026-11-02: "other source_science files which are on mesh ... makes sense"): the mesh source-plane magnification map goes into all four pixelization source_science scripts in autolens_workspace — imaging/, interferometer/, multi_galaxy/ and group/features/pixelization/source_science.py. (No other workspace has source_science scripts.) The square-pixel map stays in imaging/source_science.py.

  2. Jammy2211 commented on Nov 2, 2026

    @Jammy2211
    CollaboratorAuthor

    PRs open (judge tier, human /prm, merge in this order):

    1. feat: Mapper.mesh_magnification — source-plane magnification per mesh pixel #674 — Mapper.mesh_magnification (test_autoarray 2287 passed)
    2. feat: source-plane magnification maps — mesh and square-pixel PyAutoGalaxy#691 — mesh + square-pixel plots, LensCalc.source_plane_magnification_from (1473 passed)
    3. feat: aplt source-plane magnification maps PyAutoLens#816 — aplt exports (1020 passed)
    4. docs: source-plane magnification maps (arc phase 8b) autolens_workspace#615 — mesh map in all four pixelization source_science scripts + square-pixel map in imaging (smoke clean)

    Witness: mesh mu vs area-averaged forward-traced truth, median per-pixel agreement 1.2% (rectangular) / 3.9% (Delaunay), no bias. Heart STALE acknowledged by the human 2026-11-02.

  3. Jammy2211 commented on Nov 2, 2026

    @Jammy2211
    CollaboratorAuthor

    Shipped

    Merged in order:

    1. feat: Mapper.mesh_magnification — source-plane magnification per mesh pixel #674 (c012fa69) — Mapper.mesh_magnification, data_pixel_area_for_pix_from, plot_inversion_reconstruction(cb_unit=)
    2. feat: source-plane magnification maps — mesh and square-pixel PyAutoGalaxy#691 (1800a4eb) — plot_magnification_source_plane, plot_magnification_source_plane_grid, LensCalc.source_plane_magnification_from; 8a colour-bar unit fix
    3. feat: aplt source-plane magnification maps PyAutoLens#816 (70b317bd) — aplt exports
    4. docs: source-plane magnification maps (arc phase 8b) autolens_workspace#615 (238666e0) — mesh map in all four pixelization source_science scripts, square-pixel map in imaging/source_science.py

    Library PRs pending release. Follow-up filed: DelaunayNN per-pixel magnification investigation (PyAutoMind draft/research/autoarray/delaunaynn_per_pixel_magnification_off_by_9.md). Next in phase 8: 8c, the LEGGOS Fig-4 magnification uncertainty map.

    🤖 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