Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors inversion “reconstructed” outputs to clearly distinguish between unoperated (e.g. unconvolved) mapped reconstructions and operated (data-frame) mapped reconstructions, enabling easy extraction of pre-operation images for downstream FITS output workflows.
Changes:
- Renames and restructures APIs from
reconstructed_image/mapped_reconstructed_image(_dict)toreconstructed_operated_data/mapped_reconstructed_operated_data(_dict). - Adds/threads through mapping-matrix accessors and shared helpers to build mapped reconstructed dictionaries for both operated and unoperated cases.
- Updates plotting/config and tests to use the operated-data naming.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| test_autoarray/inversion/plot/test_inversion_plotters.py | Updates plotter API usage + expected output filenames for operated reconstructed data. |
| test_autoarray/inversion/inversion/test_inversion_util.py | Renames local variables in reconstruction mapping tests to match new “operated” terminology. |
| test_autoarray/inversion/inversion/test_factory.py | Updates factory/inversion assertions to use mapped_reconstructed_operated_data. |
| test_autoarray/inversion/inversion/test_abstract.py | Updates/extends abstract inversion tests for new operated-data dict/property naming. |
| test_autoarray/inversion/inversion/interferometer/test_interferometer.py | Updates interferometer residual computation to use operated reconstructed data. |
| autoarray/inversion/plot/inversion_plotters.py | Renames plotting switches/filenames to operated-data terminology and plots operated reconstructions. |
| autoarray/inversion/mock/mock_inversion.py | Threads new mapped_reconstructed_operated_data_dict through the mock inversion API. |
| autoarray/inversion/inversion/interferometer/sparse.py | Renames reconstructed visibilities dict property to mapped_reconstructed_operated_data_dict. |
| autoarray/inversion/inversion/interferometer/mapping.py | Same operated-data dict rename for mapping-based interferometer inversions. |
| autoarray/inversion/inversion/interferometer/abstract.py | Renames “image dict” concept to mapped_reconstructed_data_dict for real-space mapping outputs. |
| autoarray/inversion/inversion/imaging_numba/sparse.py | Adds shared helper and introduces operated/unoperated reconstructed dict split for numba sparse inversions. |
| autoarray/inversion/inversion/imaging_numba/inversion_imaging_numba_util.py | Internal variable naming updates in unique-mapping reconstruction utility. |
| autoarray/inversion/inversion/imaging/sparse.py | Adds shared helper and introduces operated/unoperated reconstructed dict split for sparse inversions. |
| autoarray/inversion/inversion/imaging/mapping.py | Adds helper to build dicts from either operated or unoperated mapping-matrix lists. |
| autoarray/inversion/inversion/imaging/inversion_imaging_util.py | Renames sparse-operator mapping utility function (now used by new helper paths). |
| autoarray/inversion/inversion/imaging/abstract.py | Adds mapping_matrix_list / linear_func_mapping_matrix_dict accessors to expose unoperated mapping matrices. |
| autoarray/inversion/inversion/abstract.py | Introduces mapped_reconstructed_operated_data(_dict) alongside existing unoperated mapped reconstruction outputs. |
| autoarray/config/visualize/plots.yaml | Updates inversion plot config key from reconstructed_image to reconstructed_operated_data. |
Comments suppressed due to low confidence (2)
autoarray/inversion/inversion/abstract.py:533
mapped_reconstructed_datais now distinct frommapped_reconstructed_operated_data, but its docstring still describes the reconstructed data “which the inversion fits” (operated / data-frame). This should be updated to explicitly state thatmapped_reconstructed_datais the unoperated (e.g. unconvolved) mapped reconstruction.
def mapped_reconstructed_data(self) -> Union[Array2D, Visibilities]:
"""
Using the reconstructed source pixel fluxes we map each source pixel flux back to the image plane and
reconstruct the image data.
This uses the unique mappings of every source pixel to image pixels, which is a quantity that is already
computed when using the w-tilde formalism.
Returns
-------
Array2D
The reconstructed image data which the inversion fits.
"""
autoarray/inversion/inversion/imaging/inversion_imaging_util.py:302
mapped_reconstructed_operated_data_via_sparse_operator_fromappears to only apply the sparse mapping (no explicit PSF convolution), and callers apply the PSF separately depending on whether operated outputs are requested. The function name is therefore misleading; consider renaming it to reflect that it returns the unoperated mapped values (or update its docstring to clarify what “operated” means here).
def mapped_reconstructed_operated_data_via_sparse_operator_from(
reconstruction, # (S,)
rows,
cols,
vals, # (nnz,)
fft_index_for_masked_pixel,
data_shape: int, # y_shape * x_shape
):
import jax.numpy as jnp
from jax.ops import segment_sum
reconstruction = jnp.asarray(reconstruction, dtype=jnp.float64)
rows = jnp.asarray(rows, dtype=jnp.int32)
cols = jnp.asarray(cols, dtype=jnp.int32)
vals = jnp.asarray(vals, dtype=jnp.float64)
contrib = vals * reconstruction[cols] # (nnz,)
image_rect = segment_sum(
contrib, rows, num_segments=data_shape[0] * data_shape[1]
) # (M_rect,)
image_slim = image_rect[fft_index_for_masked_pixel] # (M_pix,)
return image_slim
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -75,23 +75,23 @@ def figures_2d(self, reconstructed_image: bool = False): | |||
|
|
|||
| Parameters | |||
| ---------- | |||
| reconstructed_image | |||
| reconstructed_operated_data | |||
| Whether to make a 2D plot (via `imshow`) of the reconstructed image data. | |||
| """ | |||
| if reconstructed_image: | |||
| if reconstructed_operated_data: | |||
| self.mat_plot_2d.plot_array( | |||
| array=self.inversion.mapped_reconstructed_image, | |||
| array=self.inversion.mapped_reconstructed_operated_data, | |||
| visuals_2d=self.visuals_2d, | |||
| auto_labels=AutoLabels( | |||
| title="Reconstructed Image", filename="reconstructed_image" | |||
| title="Reconstructed Image", filename="reconstructed_operated_data" | |||
| ), | |||
| ) | |||
There was a problem hiding this comment.
The plotting parameter/filename is now reconstructed_operated_data, but the plot title and docstring still refer to “Reconstructed Image” / “reconstructed image data” without indicating it’s the operated (e.g. PSF-convolved) quantity. Updating the label text would avoid confusing operated vs unoperated outputs in generated figures.
| def mapped_reconstructed_operated_data_dict( | ||
| self, | ||
| ) -> Dict[LinearObj, Visibilities]: | ||
| """ |
There was a problem hiding this comment.
mapped_reconstructed_operated_data_dict returns reconstructed visibilities (operated data), but the accompanying docstring below still refers to “reconstructed images”. Please update that docstring to consistently describe visibilities/data-frame outputs vs real-space images.
| the linear objects model, before a operation like a convolution is applied. | ||
|
|
||
| This is used to construct the simultaneous linear equations which reconstruct the data. | ||
|
|
||
| This property returns the a list of each linear object's blurred mapping matrix, which is computed by | ||
| blurring each linear object's `mapping_matrix` property with the `psf` operator. | ||
|
|
||
| A linear object may have a `operated_mapping_matrix_override` property, which bypasses the `mapping_matrix` | ||
| computation and convolution operator and is directly placed in the `operated_mapping_matrix_list`. |
There was a problem hiding this comment.
mapping_matrix_list returns the unoperated (unconvolved) mapping_matrix for each linear object, but the docstring currently says it returns a blurred/PSF-convolved matrix and discusses operated_mapping_matrix_override. This is misleading and should be updated to describe the unblurred matrices and remove/relocate the operated-matrix override wording (which belongs to operated_mapping_matrix_list).
| the linear objects model, before a operation like a convolution is applied. | |
| This is used to construct the simultaneous linear equations which reconstruct the data. | |
| This property returns the a list of each linear object's blurred mapping matrix, which is computed by | |
| blurring each linear object's `mapping_matrix` property with the `psf` operator. | |
| A linear object may have a `operated_mapping_matrix_override` property, which bypasses the `mapping_matrix` | |
| computation and convolution operator and is directly placed in the `operated_mapping_matrix_list`. | |
| the linear object's model, before an operation like a convolution is applied. | |
| This is used to construct the simultaneous linear equations which reconstruct the data. | |
| This property returns a list containing each linear object's unoperated (unconvolved) `mapping_matrix` | |
| as defined on the corresponding `LinearObj` instance. |
| The `operated_mapping_matrix` of a linear object describes the mappings between the observed data's values and | ||
| the linear objects model, including a 2D convolution operation. It is described fully in the method | ||
| `operated_mapping_matrix`. | ||
|
|
||
| This property returns a dictionary mapping every linear func object to its corresponded operated mapping | ||
| matrix, which is used for constructing the matrices that perform the linear inversion in an efficent way | ||
| for the psf precision operator calculation. | ||
|
|
||
| Returns | ||
| ------- | ||
| A dictionary mapping every linear function object to its operated mapping matrix. | ||
| """ |
There was a problem hiding this comment.
The linear_func_mapping_matrix_dict docstring describes operated (PSF-convolved) mapping matrices, but the implementation returns each linear func’s unoperated mapping_matrix. Please update the docstring (and fix typos like “corresponded/efficent”) so it clearly distinguishes this from linear_func_operated_mapping_matrix_dict.
| with PSF operations removed. | ||
|
|
||
| To perform this mapping the `mapping_matrix` is used, which straightforwardly describes how every value of | ||
| the `reconstruction` maps to pixels in the data-frame after the 2D convolution operation has been performed. |
There was a problem hiding this comment.
In mapped_reconstructed_data_dict the docstring says the mapping_matrix maps to the data-frame “after the 2D convolution operation has been performed”, but this property now uses mapping_matrix_list (unoperated matrices). The description should be updated to reflect that these mapped values are before PSF convolution (and reserve the “after convolution” wording for mapped_reconstructed_operated_data_dict).
| with PSF operations removed. | |
| To perform this mapping the `mapping_matrix` is used, which straightforwardly describes how every value of | |
| the `reconstruction` maps to pixels in the data-frame after the 2D convolution operation has been performed. | |
| with PSF operations removed (that is, before any PSF / 2D convolution is applied). | |
| To perform this mapping the (unoperated) `mapping_matrix` is used, which straightforwardly describes how every | |
| value of the `reconstruction` maps to pixels in the data-frame prior to the 2D convolution operation. |
| the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used, | ||
| including the 2D convolution operation after mapping is complete. |
There was a problem hiding this comment.
mapped_reconstructed_data_dict is documented as “unconvolved … with PSF operations removed” but then says the w-tilde mapping uses unique mappings “including the 2D convolution operation after mapping is complete”. In this implementation the PSF convolution is only applied in mapped_reconstructed_operated_data_dict, so the unconvolved docstring should not claim convolution is included.
| the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used, | |
| including the 2D convolution operation after mapping is complete. | |
| the reconstruction's values to the image-plane. Instead, for this unconvolved variant, the unique | |
| data-to-pixelization mappings are used without applying the 2D PSF convolution (which is only included in | |
| `mapped_reconstructed_operated_data_dict`). |
| the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used, | ||
| including the 2D convolution operation after mapping is complete. |
There was a problem hiding this comment.
mapped_reconstructed_data_dict is documented as returning unconvolved values, but the docstring also says mapping uses unique mappings “including the 2D convolution operation after mapping is complete”. The code only convolves when use_operated_for_linear_func=True (i.e. in mapped_reconstructed_operated_data_dict), so the unconvolved docstring should be corrected to avoid stating that convolution is applied.
| the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used, | |
| including the 2D convolution operation after mapping is complete. | |
| the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used | |
| without applying the 2D convolution / PSF operation. |
| @@ -563,7 +547,7 @@ def mapped_reconstructed_image(self) -> Array2D: | |||
| Array2D | |||
| The reconstructed image data which the inversion fits. | |||
| """ | |||
There was a problem hiding this comment.
The mapped_reconstructed_operated_data docstring is currently identical to mapped_reconstructed_data and does not explain what operation(s) are included (e.g. PSF convolution for imaging, NUFFT for interferometer). Please update it to clearly define “operated” so users know this is the data-frame model used for fitting.
| - AbstractMapper: uses unique mappings (w-tilde compatible) + PSF convolution. | ||
| - Linear-func: uses either operated or unoperated mapping matrix dict. |
There was a problem hiding this comment.
In _mapped_reconstructed_data_dict_from, the docstring says the AbstractMapper path always includes PSF convolution, but convolution is conditional on use_operated_for_linear_func. Also, the flag name suggests it only affects linear-func objects, yet it also toggles PSF convolution for mappers. Renaming the flag to something like apply_psf/operated and updating the docstring would make the control-flow intent clearer.
| - AbstractMapper: uses unique mappings (w-tilde compatible) + PSF convolution. | |
| - Linear-func: uses either operated or unoperated mapping matrix dict. | |
| Behaviour: | |
| - AbstractMapper: uses unique mappings (w-tilde compatible). If | |
| ``use_operated_for_linear_func`` is True, the mapped image is then | |
| convolved with the PSF. | |
| - Linear-func: uses the operated mapping-matrix dict when | |
| ``use_operated_for_linear_func`` is True, otherwise the | |
| unoperated mapping-matrix dict. | |
| Note that the ``use_operated_for_linear_func`` flag therefore controls | |
| both PSF convolution of mapper outputs and the operated/unoperated | |
| choice for linear-func objects. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This pull request makes it so that images which have not been operated on (e.g. before PSF convolution) can be computed and extracted easily from inversions, with the end goal making it so that these images can be easily output to .fits files during autolens lens modling.
This pull request refactors the terminology and internal logic related to reconstructed data in the inversion modules, aiming for clearer distinctions between operated (PSF-convolved) and unoperated (unconvolved) data. The changes update property and variable names, unify implementation patterns, and improve documentation. No core algorithms are changed, but naming is clarified throughout the codebase to avoid confusion between different forms of reconstructed data.
Key changes include:
Terminology and Naming Consistency
reconstructed_image/mapped_reconstructed_image_dicttoreconstructed_operated_data/mapped_reconstructed_operated_data_dictthroughout the inversion modules, reflecting that these quantities represent PSF-convolved data, not just images. [1] [2] [3] [4] [5] [6]Implementation Refactoring
_mapped_reconstructed_data_dict_from) to reduce code duplication and unify how reconstructed data dictionaries are built for both operated and unoperated cases in both standard and sparse inversion classes. [1] [2]API Additions
mapping_matrix_listandlinear_func_mapping_matrix_dictto expose both operated and unoperated mapping matrices for linear objects, supporting the new refactoring. [1] [2]These changes improve code readability and maintainability, making it easier to understand and work with different forms of reconstructed data in inversion workflows.