Conversation
There was a problem hiding this comment.
Pull request overview
This PR clarifies and extends the “reconstructed data” terminology in the inversion/fit APIs to explicitly distinguish operated outputs (after PSF convolution / NUFFT) from unoperated outputs, and adds first-class support for extracting and outputting unoperated galaxy images (e.g. to FITS) for both imaging and interferometer fits.
Changes:
- Adds
galaxy_image_dicttoFitImagingandFitInterferometerfor accessing unoperated galaxy images. - Refactors inversion/fit terminology and plumbing to consistently use
use_operatedandmapped_reconstructed_operated_data. - Adds FITS output support for unoperated galaxy images via new
fits_galaxy_imagesconfig option and updates tests/configs accordingly.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| autogalaxy/imaging/fit_imaging.py | Uses mapped_reconstructed_operated_data for model data; adds galaxy_image_dict for unoperated images. |
| autogalaxy/interferometer/fit_interferometer.py | Switches model data to mapped_reconstructed_operated_data; renames galaxy image dict API to galaxy_image_dict. |
| autogalaxy/abstract_fit.py | Renames use_image to use_operated and changes which inversion dictionaries are accessed. |
| autogalaxy/imaging/model/plotter_interface.py | Adds FITS output block for galaxy_images.fits from fit.galaxy_image_dict. |
| autogalaxy/interferometer/model/plotter_interface.py | Routes FITS galaxy-image output via fits_galaxy_images and writes galaxy_images.fits. |
| autogalaxy/interferometer/plot/fit_interferometer_plotters.py | Updates plotting keyword to reconstructed_operated_data. |
| autogalaxy/config/visualize/plots.yaml | Adds config option for fits_galaxy_images; changes default fits_are_zoomed. |
| test_autogalaxy/imaging/test_fit_imaging.py | Adds coverage for galaxy_image_dict and updates operated naming in assertions. |
| test_autogalaxy/interferometer/test_fit_interferometer.py | Updates tests for renamed dict/property behavior and operated reconstruction naming. |
| test_autogalaxy/interferometer/test_simulate_and_fit_interferometer.py | Updates test to use galaxy_image_dict. |
| test_autogalaxy/galaxy/test_to_inversion.py | Updates assertions to mapped_reconstructed_operated_data. |
| test_autogalaxy/config/visualize.yaml | Adds fits_galaxy_images test config and clarifies descriptions. |
| test_autogalaxy/plot/mat_wrap/config/visualize/plots.ini | Renames inversion plotting key to reconstructed_operated_data. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| subplot_format: [png] # Output format of all subplots, can be png, pdf or both (e.g. [png, pdf]) | ||
| fits_are_zoomed: true # If true, output .fits files are zoomed in on the center of the unmasked region image, saving hard-disk space. | ||
| fits_are_zoomed: false # If true, output .fits files are zoomed in on the center of the unmasked region image, saving hard-disk space. |
There was a problem hiding this comment.
This changes the default fits_are_zoomed setting from true to false, which can significantly increase .fits output sizes and affect downstream workflows expecting zoomed outputs. If this is not directly required for the new operated/unoperated galaxy image outputs, consider keeping the previous default (or clearly documenting the behavior change and rationale).
| if should_plot("fits_galaxy_images"): | ||
| number_plots = len(fit.galaxy_image_dict.keys()) + 1 | ||
|
|
||
| image_list = [image.native_for_fits for image in fit.galaxy_image_dict.values()] | ||
|
|
||
| hdu_list = hdu_list_for_output_from( | ||
| values_list=[image_list[0].mask.astype("float")] + image_list, | ||
| ext_name_list=[ | ||
| "mask", | ||
| ] | ||
| + [f"galaxy_{i}" for i in range(number_plots)], | ||
| header_dict=fit.mask.header_dict, | ||
| ) |
There was a problem hiding this comment.
In the new fits_galaxy_images output, ext_name_list is built using range(number_plots) where number_plots = len(fit.galaxy_image_dict) + 1, but values_list is only 1 + len(image_list). This makes the number of extension names differ from the number of HDUs being written, which can lead to incorrect labeling or an exception depending on hdu_list_for_output_from's validation. Build ext_name_list from the actual number of galaxy images (e.g. len(image_list) / len(fit.galaxy_image_dict)) so it matches values_list exactly.
| @property | ||
| def galaxy_model_image_dict(self) -> Dict[Galaxy, np.ndarray]: | ||
| def galaxy_image_dict(self) -> Dict[Galaxy, np.ndarray]: | ||
| """ | ||
| A dictionary which associates every galaxy with its `image`. |
There was a problem hiding this comment.
FitInterferometer no longer defines galaxy_model_image_dict (it was renamed to galaxy_image_dict), but there are still call sites in the codebase that access galaxy_model_image_dict (e.g. autogalaxy/analysis/result.py uses self.max_log_likelihood_fit.galaxy_model_image_dict). This will raise AttributeError for interferometer results. Either update remaining call sites to the new name or keep a backwards-compatible alias property (potentially with a deprecation warning).
| If `use_operated=False`, the `reconstructed_data` of the inversion (e.g. an image for dataset data, | ||
| visibilities for interferometer data) is input in the dictionary. | ||
|
|
||
| if `use_image=True`, the `reconstructed_image` of the inversion (e.g. the image for dataset data, the | ||
| if `use_operated=True`, the `reconstructed_operated_data` of the inversion (e.g. the image for dataset data, the | ||
| real-space image for interferometer data) is input in the dictionary. |
There was a problem hiding this comment.
The docstring describing use_operated=True says the operated output is a “real-space image for interferometer data”, but in this refactor mapped_reconstructed_operated_data corresponds to the data after applying the operator (e.g. visibilities for interferometer, PSF-convolved image for imaging), as reflected by updated tests. Please update the docstring example for interferometer to avoid inverting the meaning of “operated”.
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.
Core logic and API changes:
galaxy_image_dictproperty to bothFitImagingandFitInterferometerclasses, which returns unoperated (pre-PSF-convolution) galaxy images, in contrast to the existing (now clarified) model image dictionaries that include operated images. [1] [2]use_operatedinstead ofuse_image, clarifying when operated (PSF-convolved) or unoperated images are used in dictionaries and outputs. [1] [2] [3] [4] [5] [6]Output and plotting improvements:
.fitsfiles (galaxy_images.fits) in both imaging and interferometer pipelines, controlled by the newfits_galaxy_imagesconfig option. [1] [2]plots.yamland test configs) to include options for both operated and unoperated galaxy image outputs, and clarified their descriptions. [1] [2] [3]Testing and validation:
galaxy_image_dictproperty, ensuring that unoperated images are correctly returned and match expectations for both normal and linear light profiles, as well as pixelizations. [1] [2] [3] [4] [5] [6]Other improvements:
These changes provide a more robust and explicit interface for handling galaxy images in both operated and unoperated forms, improving clarity for users and maintainers, and enabling more flexible output and testing workflows.