Overview
Phase 2 (of 4) of the multi-dataset shared-state epic (#599 = phase 1 design, decisions D1–D6 + the H-removal amendment). Implements the imaging shared-state consumer: the shared object is the source-plane mesh geometry only (traced mesh centres) — per-exposure PSFs and pixel offsets make the mapper, mapping matrix, curvature matrix, and regularization matrix (user amendment: adaptive regularization is data-dependent) per-dataset.
Running under --auto (Autonomy: safe, feature/medium — mirrors the shipped PyAutoArray#344 / PyAutoLens#566 pattern): plan recorded here, run proceeds through the four-leg autonomous ship gate and ends at PR-open; merge stays human.
Plan
- PyAutoArray:
AbstractPreloads gains source_plane_mesh_grid; new PreloadsImaging sibling with the invariance-contract docstring (mesh geometry shareable across exposures under one lens model; mapper / F / blurred L / H are NOT — unlike the datacube whose channels share one grid, whose whole-mapper + F preload is untouched). JAX pytree registration mirroring PreloadsInterferometer.
- PyAutoLens:
AnalysisImaging(shared_preloads=False) opt-in + shared_state_from (apply the lead factor's aa.DatasetModel offset → trace the lead image-mesh once → PreloadsImaging(source_plane_mesh_grid=...)); shared= threaded through log_likelihood_function → fit_from → FitImaging → TracerToInversion, mirroring PR#566. New reuse path in TracerToInversion: when preloads.source_plane_mesh_grid is set, skip image_plane_mesh_grid_pg_list + mesh tracing and build this dataset's mapper (its own offset grid) onto the preloaded mesh.
- Unit tests (numpy-only): preloads container tests in
test_autoarray; in test_autolens, shared-vs-unshared figure_of_merit parity on offset datasets, opt-in default-off, single-dataset path byte-for-byte unchanged.
- Out of scope: same-λ joint stacked inversion (D2 follow-up prompt
multi_joint_stack_inversion); workspace/workspace_test/profiling examples (phase 3 — includes the shared-vs-unshared assertion + runtime scripts mirroring the datacube pattern); docs (phase 4).
Detailed implementation plan
Affected Repositories
- PyAutoArray (primary — new preloads surface)
- PyAutoLens (consumer)
- Downstream test surface at gate time: PyAutoGalaxy + PyAutoLens suites (public API touched)
Branch Survey (2026-07-10)
| Repository |
Current Branch |
Dirty? |
Note |
| ./PyAutoArray |
main |
clean |
claims kernel-forward-chunking, rect-adapt exist but touch only inversion/mesh/ kernel-CDF files — zero overlap with preloads/; override recorded in active.md |
| ./PyAutoLens |
main |
clean |
|
Branch: feature/multi-shared-state-core-api in worktree ~/Code/PyAutoLabs-wt/multi-shared-state-core-api/
Implementation Steps
PyAutoArray/autoarray/preloads/abstract.py — add source_plane_mesh_grid=None to AbstractPreloads.__init__ + docstring; keep pytree registration consistent.
PyAutoArray/autoarray/preloads/imaging.py (new) — PreloadsImaging(AbstractPreloads) with the invariance-contract docstring; export as aa.PreloadsImaging.
PyAutoLens/autolens/lens/to_inversion.py — in the mapper-construction flow, when self._preloads.source_plane_mesh_grid is set (and no whole-mapper preload), bypass image_plane_mesh_grid_pg_list + traced_mesh_grid_pg_list and build the mapper from this dataset's traced data grid onto the preloaded source-plane mesh.
PyAutoLens/autolens/imaging/model/analysis.py — shared_preloads flag, shared_state_from(instance) (lead DatasetModel offset honored), log_likelihood_function(..., shared=None), fit_from(..., preloads=shared) threading; JAX pytree registration for PreloadsImaging.
- Tests as above; full suites + downstream at the gate.
Key Files
autoarray/preloads/{abstract,interferometer}.py, autolens/interferometer/model/analysis.py — the shipped pattern to mirror
autolens/lens/to_inversion.py:379-460 — mapper_galaxy_dict construction + existing preload short-circuit (NOT valid cross-dataset; the new path is mesh-level)
autoarray/dataset/dataset_model.py — offset surface (no changes expected)
Original Prompt
Click to expand starting prompt
See PyAutoMind/issued/multi_shared_state_examples_phase_2_core_api.md (locked by #599 D1–D6 + amendment). Parent epic: issued/multi_shared_state_examples.md.
Overview
Phase 2 (of 4) of the multi-dataset shared-state epic (#599 = phase 1 design, decisions D1–D6 + the H-removal amendment). Implements the imaging shared-state consumer: the shared object is the source-plane mesh geometry only (traced mesh centres) — per-exposure PSFs and pixel offsets make the mapper, mapping matrix, curvature matrix, and regularization matrix (user amendment: adaptive regularization is data-dependent) per-dataset.
Running under
--auto(Autonomy: safe, feature/medium — mirrors the shipped PyAutoArray#344 / PyAutoLens#566 pattern): plan recorded here, run proceeds through the four-leg autonomous ship gate and ends at PR-open; merge stays human.Plan
AbstractPreloadsgainssource_plane_mesh_grid; newPreloadsImagingsibling with the invariance-contract docstring (mesh geometry shareable across exposures under one lens model; mapper /F/ blurredL/Hare NOT — unlike the datacube whose channels share one grid, whose whole-mapper +Fpreload is untouched). JAX pytree registration mirroringPreloadsInterferometer.AnalysisImaging(shared_preloads=False)opt-in +shared_state_from(apply the lead factor'saa.DatasetModeloffset → trace the lead image-mesh once →PreloadsImaging(source_plane_mesh_grid=...));shared=threaded throughlog_likelihood_function→fit_from→FitImaging→TracerToInversion, mirroring PR#566. New reuse path inTracerToInversion: whenpreloads.source_plane_mesh_gridis set, skipimage_plane_mesh_grid_pg_list+ mesh tracing and build this dataset's mapper (its own offset grid) onto the preloaded mesh.test_autoarray; intest_autolens, shared-vs-unsharedfigure_of_meritparity on offset datasets, opt-in default-off, single-dataset path byte-for-byte unchanged.multi_joint_stack_inversion); workspace/workspace_test/profiling examples (phase 3 — includes the shared-vs-unshared assertion + runtime scripts mirroring the datacube pattern); docs (phase 4).Detailed implementation plan
Affected Repositories
Branch Survey (2026-07-10)
kernel-forward-chunking,rect-adaptexist but touch onlyinversion/mesh/kernel-CDF files — zero overlap withpreloads/; override recorded in active.mdBranch:
feature/multi-shared-state-core-apiin worktree~/Code/PyAutoLabs-wt/multi-shared-state-core-api/Implementation Steps
PyAutoArray/autoarray/preloads/abstract.py— addsource_plane_mesh_grid=NonetoAbstractPreloads.__init__+ docstring; keep pytree registration consistent.PyAutoArray/autoarray/preloads/imaging.py(new) —PreloadsImaging(AbstractPreloads)with the invariance-contract docstring; export asaa.PreloadsImaging.PyAutoLens/autolens/lens/to_inversion.py— in the mapper-construction flow, whenself._preloads.source_plane_mesh_gridis set (and no whole-mapper preload), bypassimage_plane_mesh_grid_pg_list+traced_mesh_grid_pg_listand build the mapper from this dataset's traced data grid onto the preloaded source-plane mesh.PyAutoLens/autolens/imaging/model/analysis.py—shared_preloadsflag,shared_state_from(instance)(leadDatasetModeloffset honored),log_likelihood_function(..., shared=None),fit_from(..., preloads=shared)threading; JAX pytree registration forPreloadsImaging.Key Files
autoarray/preloads/{abstract,interferometer}.py,autolens/interferometer/model/analysis.py— the shipped pattern to mirrorautolens/lens/to_inversion.py:379-460—mapper_galaxy_dictconstruction + existing preload short-circuit (NOT valid cross-dataset; the new path is mesh-level)autoarray/dataset/dataset_model.py— offset surface (no changes expected)Original Prompt
Click to expand starting prompt
See
PyAutoMind/issued/multi_shared_state_examples_phase_2_core_api.md(locked by #599 D1–D6 + amendment). Parent epic:issued/multi_shared_state_examples.md.