feat: per-interface data_term override and sparse profile-term identity (streaming P4) - #599
Merged
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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: nodata,noise_map,uv_wavelengthsor transformer) by the identityso the profile visibilities
F i_pare never formed. This PR is the PyAutoArray half: the inversion'sDatasetInterfacegains a per-fitdata_termoverride thatfast_chi_squaredprefers over the operator's cached (unsubtracted) scalar whendata is None; a shared helper computes the subtracted dirty image and data term from oneW̃ i_pproduct; andFitInterferometergains an overridablesparse_chi_squaredhook so light-profile-only fits (no inversion) getchi_squared/log_likelihood/figure_of_meritarray-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_squaredsilently fall back to the operator's unsubtracteddata_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.DatasetInterfaceaccepts an optionaldata_term;aa.util.inversion_interferometer.sparse_profile_terms_fromis new;aa.FitInterferometer.sparse_chi_squaredis a new hook (Noneby default) andchi_squaredconsults 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
Σ|d − F i|²/σ²oninterferometer_7(rel 1e-10);data_termoverride used when given / operator scalar when absent / ignored whendatais given; numpy ==jax.jit; fit hook on an array-free fit vs the in-memory fit; maps still raiseDatasetExceptionmatching "array-free".test_autoarray: 1903 passed (main: 1898).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'sfast_chi_squaredwhendata is None, in preference tosparse_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_termisNoneif the operator has none. jit-safe.aa.FitInterferometer.sparse_chi_squared— property hook,Noneby default; subclasses return the sparse-path χ².Changed Behaviour
aa.FitInterferometer.chi_squared— on an array-free dataset (data is None) returnssparse_chi_squaredwhen it is notNone; otherwise raisesDatasetExceptionas before. Residual / normalized-residual / χ² maps still raise.AbstractInversionInterferometer.fast_chi_squared— withdataset.data is None, term 3 isdataset.data_termif set, elsesparse_operator.data_term, elseInversionException(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):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
/prmwith 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