fix(inversion): guard data_subtracted_dict on data=None, harden sparse noise check and data-term dtype - #591
Merged
Conversation
…e noise check and data-term dtype (#590) Corrective follow-up to Discussion #13 phase 1 (#589), from the independent review on PyAutoLens#757: - AbstractInversion.data_subtracted_dict raises a clear InversionException (naming fit.inversion_with_data) when the inversion was built without data, instead of TypeError / {mapper: None}; subplot_of_mapper and subplot_mappings catch it and skip the panel. - check_noise_map_real_imag_equal uses atol=0.0 so tiny unequal sigmas are rejected rather than waved through by the default absolute tolerance. - apply_sparse_operator computes the cached data_term from complex128-promoted copies so one-shot equals sparse_terms_from_chunks for complex64 data. Tests for all four; red-checked against the reverted source. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Collaborator
Author
|
Workspace PR: PyAutoLabs/autogalaxy_workspace#253 |
2 of 3 tasks
Collaborator
Author
|
Workspace PR: PyAutoLabs/autolens_workspace#581 |
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
Corrective follow-up to phase 1 of https://github.com/orgs/PyAutoLabs/discussions/13 (#589, PyAutoLabs/PyAutoGalaxy#637, PyAutoLabs/PyAutoLens#757). Closes #590. An independent Codex review reproduced three defects on the sparse
data=Nonepath (record: PyAutoLabs/PyAutoLens#757 (comment)). This PR:data_subtracted_dicton an inversion built without data (introduced by phase 1): previously a multi-object inversion raisedTypeError: unsupported operand type(s) for -: 'NoneType' and 'complex'and a single-mapper inversion returned{mapper: None}, which madesubplot_of_mapperfail with aValueErrorinsideplot_array. It now raises a clearexc.InversionExceptionnamingfit.inversion_with_data/fit.data, and the two mapper subplots (subplot_of_mapper,subplot_mappings) catch it and skip the data-subtracted panel as they already do forAttributeError/KeyError. The workspaceinterferometer/features/pixelization/fit.pyscripts (autogalaxy_workspace, autolens_workspace) are migrated tofit.inversion_with_datain sibling PRs.check_noise_map_real_imag_equalabsolute tolerance (pre-existing):np.allclose/np.iscloseran at the defaultatol=1e-8, so sigma 1e-9 vs 2e-9 passed and the sparse curvature was 1.5x wrong. Nowatol=0.0with the default relative tolerance, so the check is scale-free.data_termdtype (pre-existing path, exposed by the cache):apply_sparse_operatorsquareddata.real/data.imagin the data's own dtype, so complex64 data gave 700140000.0 instead of 700140007.0 (log_evidence +3.5) and disagreed withsparse_terms_from_chunks, which promotes to complex128. The scalar is now computed from complex128-promoted local copies; complex128 inputs are bit-identical to before.Not in scope: mutating
noise_mapafterapply_sparse_operatorstales the operator (W~, dirty image and now the two scalars); that predates phase 1 and is unchanged.API Changes
Behaviour only.
AbstractInversion.data_subtracted_dictraisesexc.InversionException(wasTypeError/ a dict ofNone) when the inversion has no data;subplot_of_mapper/subplot_mappingstolerate it.check_noise_map_real_imag_equalis stricter for sub-1e-8 sigmas.apply_sparse_operatorcomputesdata_termin float64 for any input dtype. No symbol added, removed or renamed; no default changed for complex128 data with Jy-scale noise.See full details below.
Test Plan
pytest test_autoarray— 1765 passeddata_subtracted_dictraisesInversionExceptionmatchinginversion_with_data; both subplots run when it raises;check_noise_map_real_imag_equalrejects1e-9+2e-9jand accepts1e-9+1e-9j; complex64apply_sparse_operatordata_term== complex128 value ==sparse_terms_from_chunks(rtol 1e-12)InversionException, both subplots run; D → rejects 1e-9/2e-9; A → 700140007.0 on complex64fit.pyscripts fail on this PR's base withfit.inversion(TypeError / ValueError) and pass withfit.inversion_with_dataunder the smoke profileFull API Changes (for automation & release notes)
Changed Behaviour
AbstractInversion.data_subtracted_dict— raisesexc.InversionExceptionwheninversion.data is None(sparse-operator path with a precomputed data term); message points atfit.inversion_with_data/fit.dataautoarray.inversion.plot.inversion_plots.subplot_of_mapper/subplot_mappings— the data-subtracted panel is skipped (not an error) whendata_subtracted_dictraisesexc.InversionExceptioninversion_interferometer_util.check_noise_map_real_imag_equal—np.allclose/np.isclosewithatol=0.0(default rtol kept)Interferometer.apply_sparse_operator—sparse_operator.data_termcomputed from complex128-promoted copies ofdata/noise_map; equalssparse_terms_from_chunks(...).data_termfor any input dtypeMigration
subplot_of_mapper(inversion=fit.inversion, ...)(or readingfit.inversion.data_subtracted_dict) on a sparse-operator interferometer fit with no non-linear light profile should passfit.inversion_with_data.Generated by the PyAutoLabs agent workflow.
🤖 Generated with Claude Code