Skip to content

feat: per-interface data_term override and sparse profile-term identity (streaming P4) - #599

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/streaming-p4-light-profile-identity
Oct 1, 2026
Merged

Jammy2211 merged 1 commit into
mainfrom
feature/streaming-p4-light-profile-identity

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

Streaming visibilities phase 4 (epic streaming-visibilities, Discussion https://github.com/orgs/PyAutoLabs/discussions/13; issue #598). Lets interferometer fits that contain ordinary (non-linear) light profiles run on an array-free dataset (Interferometer.from_stream / from_sparse_terms: no data, noise_map, uv_wavelengths or transformer) by the identity

Σ|d − F i_p|²/σ² = data_term − 2 i_pᵀ d̃ + i_pᵀ W̃ i_p

so the profile visibilities F i_p are never formed. This PR is the PyAutoArray half: the inversion's DatasetInterface gains a per-fit data_term override that fast_chi_squared prefers over the operator's cached (unsubtracted) scalar when data is None; a shared helper computes the subtracted dirty image and data term from one W̃ i_p product; and FitInterferometer gains an overridable sparse_chi_squared hook so light-profile-only fits (no inversion) get chi_squared / log_likelihood / figure_of_merit array-free. Companion PRs: PyAutoGalaxy and PyAutoLens (same branch name).

Why the override matters: without it, removing the array-free raise in the downstream fits makes fast_chi_squared silently fall back to the operator's unsubtracted data_term; the red-check on the companion branches gave a log-evidence wrong by 2.4–3.6 % with no error. With the override the array-free fit matches the in-memory dense fit at rel 1.8e-15.

API Changes

Additive only. aa.DatasetInterface accepts an optional data_term; aa.util.inversion_interferometer.sparse_profile_terms_from is new; aa.FitInterferometer.sparse_chi_squared is a new hook (None by default) and chi_squared consults it on an array-free dataset before raising. In-memory and pixelization-only sparse behaviour is unchanged.
See full details below.

Review

Codex gpt-6-astra (3 independent runs): no defect in this repo's changes (identity sign/factor, override precedence, jit tracing all checked). Its four findings land in the companion PyAutoGalaxy/PyAutoLens PRs (three fixed there, one pre-existing filed in Mind).

Test Plan

  • New: identity vs dense Σ|d − F i|²/σ² on interferometer_7 (rel 1e-10); data_term override used when given / operator scalar when absent / ignored when data is given; numpy == jax.jit; fit hook on an array-free fit vs the in-memory fit; maps still raise DatasetException matching "array-free".
  • test_autoarray: 1903 passed (main: 1898).
  • Companion branches: PyAutoGalaxy 1305 passed, PyAutoLens 793 passed + 1 xfailed.
  • CI green on all legs.
Full API Changes (for automation & release notes)

Added

  • aa.DatasetInterface(..., data_term=None) — χ² data term of this interface's (possibly profile-subtracted) visibilities; read by the sparse interferometer inversion's fast_chi_squared when data is None, in preference to sparse_operator.data_term.
  • aa.util.inversion_interferometer.sparse_profile_terms_from(sparse_operator, image, extent_index_for_masked_pixel, xp=np) → (operated_image, sparse_dirty_image, data_term) = (W̃ i_p, d̃ − W̃ i_p, data_term − 2 i_pᵀd̃ + i_pᵀW̃i_p); data_term is None if the operator has none. jit-safe.
  • aa.FitInterferometer.sparse_chi_squared — property hook, None by default; subclasses return the sparse-path χ².

Changed Behaviour

  • aa.FitInterferometer.chi_squared — on an array-free dataset (data is None) returns sparse_chi_squared when it is not None; otherwise raises DatasetException as before. Residual / normalized-residual / χ² maps still raise.
  • AbstractInversionInterferometer.fast_chi_squared — with dataset.data is None, term 3 is dataset.data_term if set, else sparse_operator.data_term, else InversionException (unchanged fallback order otherwise).

Heart RED development override (human-authorized, 2026-10-01)

Shipped under the AUTONOMY.md "Human override for Heart RED (development only)". Live human authorization in the CLI session (Fable 5.1), quoted: "Yes, ship (push + PR-open)" for task streaming-p4-light-profile-identity (#598). Exact RED reasons at ship time (pyauto-heart readiness):

  • release validation FAILED (stage integrate)
  • workspace validation not passing (0 failed, 1 timeout, cloud#36404726969: autolens_test scripts/multi_dataset/rectangular.py)
  • manifest drift: public front-door organ tables (generated) — 1 mismatch(es) vs PyAutoMind/repos.yaml

None relate to this branch. Branch gates passed: test_autoarray 1903, test_autogalaxy 1305, test_autolens 793 + 1 xfailed; Codex review 4 findings (3 fixed in-branch, 1 pre-existing filed). Scope: push + PR-open only. Merge requires a separate human /prm with every required check green; this is not a release and does not claim Heart is healthy.

Generated by the PyAutoLabs agent workflow.

🤖 Generated with Claude Code

…ty (streaming P4)

Array-free interferometer fits with ordinary light profiles need the chi-squared
data term of the profile-subtracted visibilities without forming them.

- DatasetInterface gains `data_term`; InversionInterferometer.fast_chi_squared
  prefers it over `sparse_operator.data_term` when `data is None`, so a fit that
  subtracted light profiles can never silently fall back to the unsubtracted
  scalar.
- inversion_interferometer_util.sparse_profile_terms_from(operator, image, ...)
  returns (W~ i_p, d~ - W~ i_p, data_term - 2 i_p.d~ + i_p.W~ i_p) from a single
  W~ product; jit-safe, traced with the image.
- FitInterferometer gains an overridable `sparse_chi_squared` hook (None by
  default); `chi_squared` returns it on an array-free dataset before raising, so
  subclasses can provide log_likelihood array-free. Maps still raise.
- Tests: identity vs the dense subtracted visibilities (rel 1e-10), override
  used / operator scalar when absent / ignored when data given, numpy == jax.jit,
  and the fit hook vs the in-memory fit.

Refs #598

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Oct 1, 2026
@Jammy2211
Jammy2211 merged commit 176f61e into main Oct 1, 2026
3 checks passed
@Jammy2211
Jammy2211 deleted the feature/streaming-p4-light-profile-identity branch October 1, 2026 08:52
@Jammy2211 Jammy2211 removed the pending-release PR queued for the next release build label Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant