From 4b0ec39640870287d3d83318558b70d50898f74b Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Thu, 20 Mar 2025 10:23:08 +0000 Subject: [PATCH 01/28] dataset fits now output to datasset.fits file --- autogalaxy/analysis/analysis/dataset.py | 20 -------------------- autogalaxy/imaging/model/analysis.py | 17 +++++++++-------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index ff7a6088b..953da0ffd 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -168,26 +168,6 @@ def save_attributes(self, paths: af.DirectoryPaths): The paths object which manages all paths, e.g. where the non-linear search outputs are stored, visualization, and the pickled objects used by the aggregator output by this function. """ - paths.save_fits( - name="data", - fits=self.dataset.data.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="noise_map", - fits=self.dataset.noise_map.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="over_sample_size_lp", - fits=self.dataset.grids.lp.over_sample_size.native.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="over_sample_size_pixelization", - fits=self.dataset.grids.pixelization.over_sample_size.native.hdu_for_output, - prefix="dataset", - ) paths.save_json( name="settings_inversion", object_dict=to_dict(self.settings_inversion), diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index 8e1d69869..f40469bb4 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -231,14 +231,15 @@ def save_attributes(self, paths: af.DirectoryPaths): super().save_attributes(paths=paths) paths.save_fits( - name="psf", - fits=self.dataset.psf.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="mask", - fits=self.dataset.mask.hdu_for_output, - prefix="dataset", + name="dataset", + fits=[ + self.dataset.data.hdu_for_output, + self.dataset.noise_map.hdu_for_output, + self.dataset.psf.hdu_for_output, + self.dataset.mask.hdu_for_output, + self.dataset.grids.lp.over_sample_size.native.hdu_for_output, + self.dataset.grids.pixelization.over_sample_size.native.hdu_for_output, + ], ) def profile_log_likelihood_function( From bc8aa3f6bc237914c2540d61aebeee428bad32fe Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Thu, 20 Mar 2025 12:52:12 +0000 Subject: [PATCH 02/28] hdu_for_output now used in analysis --- autogalaxy/imaging/model/analysis.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index f40469bb4..1fe3a22fa 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -1,7 +1,9 @@ +from astropy.io import fits import numpy as np - from typing import Dict, Optional, Tuple +from autoconf.fitsable import hdu_for_output_from + import autofit as af import autoarray as aa @@ -232,14 +234,14 @@ def save_attributes(self, paths: af.DirectoryPaths): paths.save_fits( name="dataset", - fits=[ - self.dataset.data.hdu_for_output, - self.dataset.noise_map.hdu_for_output, - self.dataset.psf.hdu_for_output, - self.dataset.mask.hdu_for_output, - self.dataset.grids.lp.over_sample_size.native.hdu_for_output, - self.dataset.grids.pixelization.over_sample_size.native.hdu_for_output, - ], + fits=fits.HDUList(hdus=[ + hdu_for_output_from(arr=self.dataset.mask.astype("float"), ext_name="mask", return_as_primary=True), + hdu_for_output_from(arr=self.dataset.data, ext_name="data"), + hdu_for_output_from(arr=self.dataset.noise_map, ext_name="noise_map"), + hdu_for_output_from(arr=self.dataset.psf, ext_name="psf"), + hdu_for_output_from(arr=self.dataset.grids.lp.over_sample_size.native, ext_name="over_sample_size_lp"), + hdu_for_output_from(arr=self.dataset.grids.pixelization.over_sample_size.native, ext_name="over_sample_size_pixelization"), + ]), ) def profile_log_likelihood_function( From 54aaf2de3262684dc0858bd7f7f8eaa596cab7af Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:01:29 +0000 Subject: [PATCH 03/28] use hdu_list output in autoconf fitsable --- autogalaxy/imaging/model/analysis.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index 1fe3a22fa..a80aac5a4 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -1,8 +1,7 @@ -from astropy.io import fits import numpy as np from typing import Dict, Optional, Tuple -from autoconf.fitsable import hdu_for_output_from +from autoconf.fitsable import hdu_list_for_output_from import autofit as af import autoarray as aa @@ -234,16 +233,20 @@ def save_attributes(self, paths: af.DirectoryPaths): paths.save_fits( name="dataset", - fits=fits.HDUList(hdus=[ - hdu_for_output_from(arr=self.dataset.mask.astype("float"), ext_name="mask", return_as_primary=True), - hdu_for_output_from(arr=self.dataset.data, ext_name="data"), - hdu_for_output_from(arr=self.dataset.noise_map, ext_name="noise_map"), - hdu_for_output_from(arr=self.dataset.psf, ext_name="psf"), - hdu_for_output_from(arr=self.dataset.grids.lp.over_sample_size.native, ext_name="over_sample_size_lp"), - hdu_for_output_from(arr=self.dataset.grids.pixelization.over_sample_size.native, ext_name="over_sample_size_pixelization"), - ]), + fits=hdu_list_for_output_from( + values_list=[ + self.dataset.mask.astype("float"), + self.dataset.data.native, + self.dataset.noise_map.native, + self.dataset.psf.native, + self.dataset.grids.lp.over_sample_size.native, + self.dataset.grids.pixelization.over_sample_size.native, + ], + ext_name_list=["mask", "data", "noise_map", "psf", "over_sample_size_lp", "over_sample_size_pixelization"], + ), ) + def profile_log_likelihood_function( self, instance: af.ModelInstance, paths: Optional[af.DirectoryPaths] = None ) -> Tuple[Dict, Dict]: From 5f060738426b64e03daf2c724a90416e5f799c88 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:08:11 +0000 Subject: [PATCH 04/28] interferometer now uses fitsable --- autogalaxy/interferometer/model/analysis.py | 22 ++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index d4924f2bf..c335c365c 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -3,6 +3,7 @@ from typing import Dict, Optional, Tuple from autoconf.dictable import to_dict +from autoconf.fitsable import hdu_list_for_output_from import autofit as af import autoarray as aa @@ -234,19 +235,26 @@ def save_attributes(self, paths: af.DirectoryPaths): """ super().save_attributes(paths=paths) - hdu = aa.util.array_2d.hdu_for_output_from( - array_2d=self.dataset.uv_wavelengths, - ) - paths.save_fits(name="uv_wavelengths", fits=hdu, prefix="dataset") paths.save_fits( - name="real_space_mask", - fits=self.dataset.real_space_mask.hdu_for_output, - prefix="dataset", + name="dataset", + fits=hdu_list_for_output_from( + values_list=[ + self.dataset.real_space_mask.astype("float"), + self.dataset.data.in_array, + self.dataset.noise_map.in_array, + self.dataset.uv_wavelengths, + + ], + ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], + ), ) + paths.save_json( "transformer_class", to_dict(self.dataset.transformer.__class__), "dataset" ) + ggg + def profile_log_likelihood_function( self, instance: af.ModelInstance, paths: Optional[af.DirectoryPaths] = None ) -> Tuple[Dict, Dict]: From 33959cfc166a53dd1ee83b63d582a7d4016ab323 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:13:32 +0000 Subject: [PATCH 05/28] add adapt image output --- autogalaxy/analysis/analysis/dataset.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index 953da0ffd..30e6b49f9 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -5,6 +5,8 @@ from autoconf import conf from autoconf.dictable import to_dict, output_to_json +from autoconf.fitsable import hdu_list_for_output_from + import autofit as af import autoarray as aa @@ -178,21 +180,19 @@ def save_attributes(self, paths: af.DirectoryPaths): ) if self.adapt_images is not None: - paths.save_json( + + values_list = [self.adapt_images.galaxy_name_image_dict[name] for name in self.adapt_images.galaxy_name_image_dict.keys()] + + paths.save_fits( name="adapt_images", - object_dict=to_dict( - list(self.adapt_images.galaxy_name_image_dict.keys()) + fits=hdu_list_for_output_from( + values_list=[ + self.dataset.mask.astype("float"), + ] + values_list, + ext_name_list=["mask"] + list(self.adapt_images.galaxy_name_image_dict.keys()), ), - prefix="adapt_images", ) - for name in self.adapt_images.galaxy_name_image_dict.keys(): - paths.save_fits( - name=name, - fits=self.adapt_images.galaxy_name_image_dict[name].hdu_for_output, - prefix="adapt_images", - ) - def save_results(self, paths: af.DirectoryPaths, result: ResultDataset): """ At the end of a model-fit, this routine saves attributes of the `Analysis` object to the `files` From 4a2b8d4c74c17724c0d2112590085b7b1d08baa3 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:44:19 +0000 Subject: [PATCH 06/28] imaging agg updated --- autogalaxy/aggregator/dataset_model.py | 3 +- autogalaxy/aggregator/ellipse/ellipses.py | 6 +- autogalaxy/aggregator/ellipse/fit_ellipse.py | 46 ++++----- autogalaxy/aggregator/ellipse/multipoles.py | 6 +- autogalaxy/aggregator/galaxies.py | 6 +- autogalaxy/aggregator/imaging/fit_imaging.py | 76 ++++++++------- autogalaxy/aggregator/imaging/imaging.py | 97 +++++++++++-------- .../interferometer/fit_interferometer.py | 74 +++++++------- .../interferometer/interferometer.py | 54 ++++++----- autogalaxy/analysis/analysis/dataset.py | 12 ++- autogalaxy/imaging/model/analysis.py | 14 ++- autogalaxy/interferometer/model/analysis.py | 1 - 12 files changed, 217 insertions(+), 178 deletions(-) diff --git a/autogalaxy/aggregator/dataset_model.py b/autogalaxy/aggregator/dataset_model.py index bb585705a..2be68859b 100644 --- a/autogalaxy/aggregator/dataset_model.py +++ b/autogalaxy/aggregator/dataset_model.py @@ -14,7 +14,8 @@ def _dataset_model_from( """ Returns a `DatasetModel` object from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). diff --git a/autogalaxy/aggregator/ellipse/ellipses.py b/autogalaxy/aggregator/ellipse/ellipses.py index 7c92f4839..0b0bbd7d2 100644 --- a/autogalaxy/aggregator/ellipse/ellipses.py +++ b/autogalaxy/aggregator/ellipse/ellipses.py @@ -15,7 +15,8 @@ def _ellipses_from(fit: af.Fit, instance: af.ModelInstance) -> List[List[Ellipse """ Returns a list of `Ellipse` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). @@ -63,7 +64,8 @@ class EllipsesAgg(af.AggBase): Interfaces with an `PyAutoFit` aggregator object to create instances of `Ellipse` objects from the results of a model-fit. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). diff --git a/autogalaxy/aggregator/ellipse/fit_ellipse.py b/autogalaxy/aggregator/ellipse/fit_ellipse.py index 0fe101295..3301f0cb8 100644 --- a/autogalaxy/aggregator/ellipse/fit_ellipse.py +++ b/autogalaxy/aggregator/ellipse/fit_ellipse.py @@ -18,10 +18,11 @@ def _fit_ellipse_from( """ Returns a list of `FitEllipse` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). - - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). + - The mask used to mask the `Imaging` data structure in the fit (`dataset.fits[hdu=0]`). Each individual attribute can be loaded from the database via the `fit.value()` method. @@ -78,34 +79,35 @@ def __init__( aggregator: af.Aggregator, ): """ - Interfaces with an `PyAutoFit` aggregator object to create instances of `FitEllipse` objects from the results - of a model-fit. + Interfaces with an `PyAutoFit` aggregator object to create instances of `FitEllipse` objects from the results + of a model-fit. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). - - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). + - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). + - The mask used to mask the `Imaging` data structure in the fit (`dataset.fits[hdu=0]`). - The `aggregator` contains the path to each of these files, and they can be loaded individually. This class - can load them all at once and create an `FitEllipse` object via the `_fit_ellipse_from` method. + The `aggregator` contains the path to each of these files, and they can be loaded individually. This class + can load them all at once and create an `FitEllipse` object via the `_fit_ellipse_from` method. - This class's methods returns generators which create the instances of the `FitEllipse` objects. This ensures - that large sets of results can be efficiently loaded from the hard-disk and do not require storing all - `FitEllipse` instances in the memory at once. + This class's methods returns generators which create the instances of the `FitEllipse` objects. This ensures + that large sets of results can be efficiently loaded from the hard-disk and do not require storing all + `FitEllipse` instances in the memory at once. - For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which - creates instances of the corresponding 3 `FitEllipse` objects. + For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which + creates instances of the corresponding 3 `FitEllipse` objects. - If multiple `Ellipse` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method - is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of - `FitEllipse` objects. + If multiple `Ellipse` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method + is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of + `FitEllipse` objects. - This can be done manually, but this object provides a more concise API. + This can be done manually, but this object provides a more concise API. - Parameters - ---------- - aggregator - A `PyAutoFit` aggregator object which can load the results of model-fits. + Parameters + ---------- + aggregator + A `PyAutoFit` aggregator object which can load the results of model-fits. """ super().__init__(aggregator=aggregator) diff --git a/autogalaxy/aggregator/ellipse/multipoles.py b/autogalaxy/aggregator/ellipse/multipoles.py index ece37b7db..22e394b47 100644 --- a/autogalaxy/aggregator/ellipse/multipoles.py +++ b/autogalaxy/aggregator/ellipse/multipoles.py @@ -17,7 +17,8 @@ def _multipoles_from( """ Returns a list of `EllipseMultipole` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). @@ -65,7 +66,8 @@ class MultipolesAgg(af.AggBase): Interfaces with an `PyAutoFit` aggregator object to create instances of `EllipseMultipole` objects from the results of a model-fit. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). diff --git a/autogalaxy/aggregator/galaxies.py b/autogalaxy/aggregator/galaxies.py index b52b27634..3c542c9ea 100644 --- a/autogalaxy/aggregator/galaxies.py +++ b/autogalaxy/aggregator/galaxies.py @@ -15,7 +15,8 @@ def _galaxies_from(fit: af.Fit, instance: af.ModelInstance) -> List[Galaxy]: """ Returns a list of `Galaxy` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). - The adapt images associated with adaptive galaxy features (`adapt` folder). @@ -73,7 +74,8 @@ class GalaxiesAgg(af.AggBase): Interfaces with an `PyAutoFit` aggregator object to create instances of `Galaxy` objects from the results of a model-fit. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The model and its best fit parameters (e.g. `model.json`). - The adapt images associated with adaptive galaxy features (`adapt` folder). diff --git a/autogalaxy/aggregator/imaging/fit_imaging.py b/autogalaxy/aggregator/imaging/fit_imaging.py index e805df1ee..f4de2059a 100644 --- a/autogalaxy/aggregator/imaging/fit_imaging.py +++ b/autogalaxy/aggregator/imaging/fit_imaging.py @@ -24,10 +24,11 @@ def _fit_imaging_from( """ Returns a list of `FitImaging` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). - - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). + - The mask used to mask the `Imaging` data structure in the fit (`dataset.fits[hdu=0]`). - The settings of inversions used by the fit (`dataset/settings_inversion.json`). Each individual attribute can be loaded from the database via the `fit.value()` method. @@ -111,41 +112,42 @@ def __init__( use_preloaded_grid: bool = True, ): """ - Interfaces with an `PyAutoFit` aggregator object to create instances of `FitImaging` objects from the results - of a model-fit. - - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: - - - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). - - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). - - The settings of inversions used by the fit (`dataset/settings_inversion.json`). - - The `aggregator` contains the path to each of these files, and they can be loaded individually. This class - can load them all at once and create an `FitImaging` object via the `_fit_imaging_from` method. - - This class's methods returns generators which create the instances of the `FitImaging` objects. This ensures - that large sets of results can be efficiently loaded from the hard-disk and do not require storing all - `FitImaging` instances in the memory at once. - - For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which - creates instances of the corresponding 3 `FitImaging` objects. - - If multiple `Imaging` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method - is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of - `FitImaging` objects. - - This can be done manually, but this object provides a more concise API. - - Parameters - ---------- - aggregator - A `PyAutoFit` aggregator object which can load the results of model-fits. - settings_inversion - Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. - use_preloaded_grid - Certain pixelization's construct their mesh in the source-plane from a stochastic KMeans algorithm. This - grid may be output to hard-disk after the model-fit and loaded via the database to ensure the same grid is - used as the fit. + Interfaces with an `PyAutoFit` aggregator object to create instances of `FitImaging` objects from the results + of a model-fit. + + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: + + - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). + - The mask used to mask the `Imaging` data structure in the fit (`dataset.fits[hdu=0]`). + - The settings of inversions used by the fit (`dataset/settings_inversion.json`). + + The `aggregator` contains the path to each of these files, and they can be loaded individually. This class + can load them all at once and create an `FitImaging` object via the `_fit_imaging_from` method. + + This class's methods returns generators which create the instances of the `FitImaging` objects. This ensures + that large sets of results can be efficiently loaded from the hard-disk and do not require storing all + `FitImaging` instances in the memory at once. + + For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which + creates instances of the corresponding 3 `FitImaging` objects. + + If multiple `Imaging` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method + is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of + `FitImaging` objects. + + This can be done manually, but this object provides a more concise API. + + Parameters + ---------- + aggregator + A `PyAutoFit` aggregator object which can load the results of model-fits. + settings_inversion + Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. + use_preloaded_grid + Certain pixelization's construct their mesh in the source-plane from a stochastic KMeans algorithm. This + grid may be output to hard-disk after the model-fit and loaded via the database to ensure the same grid is + used as the fit. """ super().__init__(aggregator=aggregator) diff --git a/autogalaxy/aggregator/imaging/imaging.py b/autogalaxy/aggregator/imaging/imaging.py index c3a472820..0f4f06f92 100644 --- a/autogalaxy/aggregator/imaging/imaging.py +++ b/autogalaxy/aggregator/imaging/imaging.py @@ -1,6 +1,8 @@ from functools import partial from typing import List +from autoconf.fitsable import ndarray_via_hdu_from + import autofit as af import autoarray as aa @@ -11,13 +13,14 @@ def _imaging_from( """ Returns a list of `Imaging` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - - The imaging data as a .fits file (`dataset/data.fits`). - - The noise-map as a .fits file (`dataset/noise_map.fits`). - - The point spread function as a .fits file (`dataset/psf.fits`). + - The mask used to mask the `Imaging` data structure in the fit (`dataset.fits[hdu=0]`). + - The imaging data as a .fits file (`dataset.fits[hdu=1]`). + - The noise-map as a .fits file (`dataset.fits[hdu=2]`). + - The point spread function as a .fits file (`dataset.fits[hdu=3]`). - The settings of the `Imaging` data structure used in the fit (`dataset/settings.json`). - - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). Each individual attribute can be loaded from the database via the `fit.value()` method. @@ -39,16 +42,24 @@ def _imaging_from( dataset_list = [] for fit in fit_list: - data = aa.Array2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.data")[0] - ) - noise_map = aa.Array2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.noise_map")[0] + header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) + pixel_scales = ( + header.header_sci_obj["PIXSCAY"], + header.header_sci_obj["PIXSCAX"], ) - try: - psf = aa.Kernel2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.psf")[0] + + def values_from(hdu: int, cls): + return cls.no_mask( + values=ndarray_via_hdu_from(fit.value(name="dataset")[hdu]), + pixel_scales=pixel_scales, + header=header, ) + + data = values_from(hdu=1, cls=aa.Array2D) + noise_map = values_from(hdu=2, cls=aa.Array2D) + + try: + psf = values_from(hdu=3, cls=aa.Kernel2D) except TypeError: psf = None @@ -59,22 +70,21 @@ def _imaging_from( check_noise_map=False, ) - mask = aa.Mask2D.from_primary_hdu(primary_hdu=fit.value(name="dataset.mask")[0]) + mask = aa.Mask2D( + mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), + pixel_scales=pixel_scales, + ) dataset = dataset.apply_mask(mask=mask) try: - over_sample_size_lp = aa.Array2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.over_sample_size_lp")[0] - ).native + over_sample_size_lp = values_from(hdu=4, cls=aa.Array2D).native over_sample_size_lp = over_sample_size_lp.apply_mask(mask=mask) except TypeError: over_sample_size_lp = 1 try: - over_sample_size_pixelization = aa.Array2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.over_sample_size_pixelization")[0] - ).native + over_sample_size_pixelization = values_from(hdu=5, cls=aa.Array2D).native over_sample_size_pixelization = over_sample_size_pixelization.apply_mask( mask=mask ) @@ -94,37 +104,38 @@ def _imaging_from( class ImagingAgg: def __init__(self, aggregator: af.Aggregator): """ - Interfaces with an `PyAutoFit` aggregator object to create instances of `Imaging` objects from the results - of a model-fit. + Interfaces with an `PyAutoFit` aggregator object to create instances of `Imaging` objects from the results + of a model-fit. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - - The imaging data as a .fits file (`dataset/data.fits`). - - The noise-map as a .fits file (`dataset/noise_map.fits`). - - The point spread function as a .fits file (`dataset/psf.fits`). - - The settings of the `Imaging` data structure used in the fit (`dataset/settings.json`). - - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). + - The imaging data as a .fits file (`dataset.fits[hdu=1]`). + - The noise-map as a .fits file (`dataset.fits[hdu=2]`). + - The point spread function as a .fits file (`dataset.fits[hdu=3]`). + - The settings of the `Imaging` data structure used in the fit (`dataset/settings.json`). + - The mask used to mask the `Imaging` data structure in the fit (`dataset.fits[hdu=0]`). - The `aggregator` contains the path to each of these files, and they can be loaded individually. This class - can load them all at once and create an `Imaging` object via the `_imaging_from` method. + The `aggregator` contains the path to each of these files, and they can be loaded individually. This class + can load them all at once and create an `Imaging` object via the `_imaging_from` method. - This class's methods returns generators which create the instances of the `Imaging` objects. This ensures - that large sets of results can be efficiently loaded from the hard-disk and do not require storing all - `Imaging` instances in the memory at once. + This class's methods returns generators which create the instances of the `Imaging` objects. This ensures + that large sets of results can be efficiently loaded from the hard-disk and do not require storing all + `Imaging` instances in the memory at once. - For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which - creates instances of the corresponding 3 `Imaging` objects. + For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which + creates instances of the corresponding 3 `Imaging` objects. - If multiple `Imaging` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method - is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of - `Imaging` objects. + If multiple `Imaging` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method + is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of + `Imaging` objects. - This can be done manually, but this object provides a more concise API. + This can be done manually, but this object provides a more concise API. - Parameters - ---------- - aggregator - A `PyAutoFit` aggregator object which can load the results of model-fits. + Parameters + ---------- + aggregator + A `PyAutoFit` aggregator object which can load the results of model-fits. """ self.aggregator = aggregator diff --git a/autogalaxy/aggregator/interferometer/fit_interferometer.py b/autogalaxy/aggregator/interferometer/fit_interferometer.py index 316e3aac4..ade3d0d3e 100644 --- a/autogalaxy/aggregator/interferometer/fit_interferometer.py +++ b/autogalaxy/aggregator/interferometer/fit_interferometer.py @@ -25,7 +25,8 @@ def _fit_interferometer_from( """ Returns a list of `FitInterferometer` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - The interferometer data, noise-map, uv-wavelengths and settings as .fits files (e.g. `dataset/data.fits`). - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). @@ -116,41 +117,42 @@ def __init__( real_space_mask: Optional[aa.Mask2D] = None, ): """ - Interfaces with an `PyAutoFit` aggregator object to create instances of `FitInterferometer` objects from the - results of a model-fit. - - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: - - - The interferometer data, noise-map, uv-wavelengths and settings as .fits files (e.g. `dataset/data.fits`). - - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). - - The settings of inversions used by the fit (`dataset/settings_inversion.json`). - - The `aggregator` contains the path to each of these files, and they can be loaded individually. This class - can load them all at once and create an `FitInterferometer` object via the `_fit_interferometer_from` method. - - This class's methods returns generators which create the instances of the `FitInterferometer` objects. This ensures - that large sets of results can be efficiently loaded from the hard-disk and do not require storing all - `FitInterferometer` instances in the memory at once. - - For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which - creates instances of the corresponding 3 `FitInterferometer` objects. - - If multiple `Imaging` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method - is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of - `FitImaging` objects. - - This can be done manually, but this object provides a more concise API. - - Parameters - ---------- - aggregator - A `PyAutoFit` aggregator object which can load the results of model-fits. - settings_inversion - Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. - use_preloaded_grid - Certain pixelization's construct their mesh in the source-plane from a stochastic KMeans algorithm. This - grid may be output to hard-disk after the model-fit and loaded via the database to ensure the same grid is - used as the fit. + Interfaces with an `PyAutoFit` aggregator object to create instances of `FitInterferometer` objects from the + results of a model-fit. + + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: + + - The interferometer data, noise-map, uv-wavelengths and settings as .fits files (e.g. `dataset/data.fits`). + - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). + - The settings of inversions used by the fit (`dataset/settings_inversion.json`). + + The `aggregator` contains the path to each of these files, and they can be loaded individually. This class + can load them all at once and create an `FitInterferometer` object via the `_fit_interferometer_from` method. + + This class's methods returns generators which create the instances of the `FitInterferometer` objects. This ensures + that large sets of results can be efficiently loaded from the hard-disk and do not require storing all + `FitInterferometer` instances in the memory at once. + + For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which + creates instances of the corresponding 3 `FitInterferometer` objects. + + If multiple `Imaging` objects were fitted simultaneously via analysis summing, the `fit.child_values()` method + is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of + `FitImaging` objects. + + This can be done manually, but this object provides a more concise API. + + Parameters + ---------- + aggregator + A `PyAutoFit` aggregator object which can load the results of model-fits. + settings_inversion + Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. + use_preloaded_grid + Certain pixelization's construct their mesh in the source-plane from a stochastic KMeans algorithm. This + grid may be output to hard-disk after the model-fit and loaded via the database to ensure the same grid is + used as the fit. """ super().__init__(aggregator=aggregator) diff --git a/autogalaxy/aggregator/interferometer/interferometer.py b/autogalaxy/aggregator/interferometer/interferometer.py index 7bdf2ac2d..935b3c9eb 100644 --- a/autogalaxy/aggregator/interferometer/interferometer.py +++ b/autogalaxy/aggregator/interferometer/interferometer.py @@ -12,10 +12,11 @@ def _interferometer_from( """ Returns a list of `Interferometer` objects from a `PyAutoFit` sqlite database `Fit` object. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - - The interferometer visibilities data as a .fits file (`dataset/data.fits`). - - The visibilities noise-map as a .fits file (`dataset/noise_map.fits`). + - The interferometer visibilities data as a .fits file (`dataset.fits[hdu=1]`). + - The visibilities noise-map as a .fits file (`dataset.fits[hdu=2]`). - The uv wavelengths as a .fits file (`dataset/uv_wavelengths.fits`). - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). - The settings of the `Interferometer` data structure used in the fit (`dataset/settings.json`). @@ -74,37 +75,38 @@ def _interferometer_from( class InterferometerAgg: def __init__(self, aggregator: af.Aggregator): """ - Interfaces with an `PyAutoFit` aggregator object to create instances of `Interferometer` objects from the results - of a model-fit. + Interfaces with an `PyAutoFit` aggregator object to create instances of `Interferometer` objects from the results + of a model-fit. - The results of a model-fit can be stored in a sqlite database, including the following attributes of the fit: + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + attributes of the fit: - - The interferometer visibilities data as a .fits file (`dataset/data.fits`). - - The visibilities noise-map as a .fits file (`dataset/noise_map.fits`). - - The uv wavelengths as a .fits file (`dataset/uv_wavelengths.fits`). - - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). - - The settings of the `Interferometer` data structure used in the fit (`dataset/settings.json`). + - The interferometer visibilities data as a .fits file (`dataset.fits[hdu=1]`). + - The visibilities noise-map as a .fits file (`dataset.fits[hdu=2]`). + - The uv wavelengths as a .fits file (`dataset/uv_wavelengths.fits`). + - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). + - The settings of the `Interferometer` data structure used in the fit (`dataset/settings.json`). - The `aggregator` contains the path to each of these files, and they can be loaded individually. This class - can load them all at once and create an `Interferometer` object via the `_interferometer_from` method. + The `aggregator` contains the path to each of these files, and they can be loaded individually. This class + can load them all at once and create an `Interferometer` object via the `_interferometer_from` method. - This class's methods returns generators which create the instances of the `Interferometer` objects. This ensures - that large sets of results can be efficiently loaded from the hard-disk and do not require storing all - `Interferometer` instances in the memory at once. + This class's methods returns generators which create the instances of the `Interferometer` objects. This ensures + that large sets of results can be efficiently loaded from the hard-disk and do not require storing all + `Interferometer` instances in the memory at once. - For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which - creates instances of the corresponding 3 `Interferometer` objects. + For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which + creates instances of the corresponding 3 `Interferometer` objects. - If multiple `Interferometer` objects were fitted simultaneously via analysis summing, the `fit.child_values()` - method is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of - `Interferometer` objects. + If multiple `Interferometer` objects were fitted simultaneously via analysis summing, the `fit.child_values()` + method is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of + `Interferometer` objects. - This can be done manually, but this object provides a more concise API. + This can be done manually, but this object provides a more concise API. - Parameters - ---------- - aggregator - A `PyAutoFit` aggregator object which can load the results of model-fits. + Parameters + ---------- + aggregator + A `PyAutoFit` aggregator object which can load the results of model-fits. """ self.aggregator = aggregator diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index 30e6b49f9..bcd71bb57 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -180,16 +180,20 @@ def save_attributes(self, paths: af.DirectoryPaths): ) if self.adapt_images is not None: - - values_list = [self.adapt_images.galaxy_name_image_dict[name] for name in self.adapt_images.galaxy_name_image_dict.keys()] + values_list = [ + self.adapt_images.galaxy_name_image_dict[name] + for name in self.adapt_images.galaxy_name_image_dict.keys() + ] paths.save_fits( name="adapt_images", fits=hdu_list_for_output_from( values_list=[ self.dataset.mask.astype("float"), - ] + values_list, - ext_name_list=["mask"] + list(self.adapt_images.galaxy_name_image_dict.keys()), + ] + + values_list, + ext_name_list=["mask"] + + list(self.adapt_images.galaxy_name_image_dict.keys()), ), ) diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index a80aac5a4..eb83897e4 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -242,11 +242,21 @@ def save_attributes(self, paths: af.DirectoryPaths): self.dataset.grids.lp.over_sample_size.native, self.dataset.grids.pixelization.over_sample_size.native, ], - ext_name_list=["mask", "data", "noise_map", "psf", "over_sample_size_lp", "over_sample_size_pixelization"], + ext_name_list=[ + "mask", + "data", + "noise_map", + "psf", + "over_sample_size_lp", + "over_sample_size_pixelization", + ], + header_dict={ + "PIXSCAY": self.dataset.pixel_scales[0], + "PIXSCAX": self.dataset.pixel_scales[1], + }, ), ) - def profile_log_likelihood_function( self, instance: af.ModelInstance, paths: Optional[af.DirectoryPaths] = None ) -> Tuple[Dict, Dict]: diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index c335c365c..46818bb45 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -243,7 +243,6 @@ def save_attributes(self, paths: af.DirectoryPaths): self.dataset.data.in_array, self.dataset.noise_map.in_array, self.dataset.uv_wavelengths, - ], ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], ), From 4acdbdb5e7e31686d2000e954cb859df3518dcd7 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:51:35 +0000 Subject: [PATCH 07/28] aggregator interferometer fixed --- .../interferometer/interferometer.py | 36 +++++++++---------- autogalaxy/interferometer/model/analysis.py | 6 ++-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/autogalaxy/aggregator/interferometer/interferometer.py b/autogalaxy/aggregator/interferometer/interferometer.py index 935b3c9eb..25c7ff0d1 100644 --- a/autogalaxy/aggregator/interferometer/interferometer.py +++ b/autogalaxy/aggregator/interferometer/interferometer.py @@ -1,5 +1,7 @@ from functools import partial -from typing import List, Optional +from typing import List + +from autoconf.fitsable import ndarray_via_hdu_from import autofit as af import autoarray as aa @@ -7,7 +9,6 @@ def _interferometer_from( fit: af.Fit, - real_space_mask: Optional[aa.Mask2D] = None, ) -> List[aa.Interferometer]: """ Returns a list of `Interferometer` objects from a `PyAutoFit` sqlite database `Fit` object. @@ -41,20 +42,24 @@ def _interferometer_from( dataset_list = [] for fit in fit_list: + data = aa.Visibilities( - visibilities=fit.value(name="dataset.data")[0].data.astype("float") + visibilities=fit.value(name="dataset")[1].data.astype("float") ) noise_map = aa.VisibilitiesNoiseMap( - fit.value(name="dataset.noise_map")[0].data.astype("float") + fit.value(name="dataset")[2].data.astype("float") ) - uv_wavelengths = fit.value(name="dataset.uv_wavelengths")[0].data - - real_space_mask = ( - real_space_mask - if real_space_mask is not None - else aa.Mask2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.real_space_mask")[0] - ) + uv_wavelengths = fit.value(name="dataset")[3].data + + header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) + pixel_scales = ( + header.header_sci_obj["PIXSCAY"], + header.header_sci_obj["PIXSCAX"], + ) + + real_space_mask = aa.Mask2D( + mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), + pixel_scales=pixel_scales, ) transformer_class = fit.value(name="dataset.transformer_class") @@ -112,21 +117,14 @@ def __init__(self, aggregator: af.Aggregator): def dataset_gen_from( self, - real_space_mask: Optional[aa.Mask2D] = None, ) -> List[aa.Interferometer]: """ Returns a generator of `Interferometer` objects from an input aggregator. See `__init__` for a description of how the `Interferometer` objects are created by this method. - - Parameters - ---------- - real_space_mask - The real space mask. """ func = partial( _interferometer_from, - real_space_mask=real_space_mask, ) return self.aggregator.map(func=func) diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index 46818bb45..8347225fd 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -245,6 +245,10 @@ def save_attributes(self, paths: af.DirectoryPaths): self.dataset.uv_wavelengths, ], ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], + header_dict={ + "PIXSCAY": self.dataset.pixel_scales[0], + "PIXSCAX": self.dataset.pixel_scales[1], + }, ), ) @@ -252,8 +256,6 @@ def save_attributes(self, paths: af.DirectoryPaths): "transformer_class", to_dict(self.dataset.transformer.__class__), "dataset" ) - ggg - def profile_log_likelihood_function( self, instance: af.ModelInstance, paths: Optional[af.DirectoryPaths] = None ) -> Tuple[Dict, Dict]: From 2aa188164dbf3c207548ecc81c9823731eaadc36 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:55:23 +0000 Subject: [PATCH 08/28] now working on adapt images --- autogalaxy/aggregator/agg_util.py | 2 ++ autogalaxy/analysis/analysis/dataset.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index 91bf0f57f..1f576e783 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -30,6 +30,8 @@ def adapt_images_from( fit_list = [fit] if not fit.children else fit.children + aaa + if fit.value(name="adapt_images.adapt_images") is None: return [None] * len(fit_list) diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index bcd71bb57..ea1aaf117 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -194,6 +194,10 @@ def save_attributes(self, paths: af.DirectoryPaths): + values_list, ext_name_list=["mask"] + list(self.adapt_images.galaxy_name_image_dict.keys()), + header_dict={ + "PIXSCAY": self.dataset.pixel_scales[0], + "PIXSCAX": self.dataset.pixel_scales[1], + }, ), ) From 1803580e0b7ce6cfaa82af909f48cae9522dbd32 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 10:57:57 +0000 Subject: [PATCH 09/28] pixel scale header uses mask property --- autogalaxy/analysis/analysis/dataset.py | 5 +---- autogalaxy/imaging/model/analysis.py | 5 +---- autogalaxy/interferometer/model/analysis.py | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index ea1aaf117..86c51a10c 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -194,10 +194,7 @@ def save_attributes(self, paths: af.DirectoryPaths): + values_list, ext_name_list=["mask"] + list(self.adapt_images.galaxy_name_image_dict.keys()), - header_dict={ - "PIXSCAY": self.dataset.pixel_scales[0], - "PIXSCAX": self.dataset.pixel_scales[1], - }, + header_dict=self.dataset.mask.pixel_scale_header ), ) diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index eb83897e4..6d328ae06 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -250,10 +250,7 @@ def save_attributes(self, paths: af.DirectoryPaths): "over_sample_size_lp", "over_sample_size_pixelization", ], - header_dict={ - "PIXSCAY": self.dataset.pixel_scales[0], - "PIXSCAX": self.dataset.pixel_scales[1], - }, + header_dict=self.dataset.mask.pixel_scale_header ), ) diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index 8347225fd..180131dc9 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -245,10 +245,7 @@ def save_attributes(self, paths: af.DirectoryPaths): self.dataset.uv_wavelengths, ], ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], - header_dict={ - "PIXSCAY": self.dataset.pixel_scales[0], - "PIXSCAX": self.dataset.pixel_scales[1], - }, + header_dict=self.dataset.real_space_mask.pixel_scale_header ), ) From 999179c8eca43d9c0ecf801074b1120c92acf965 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:10:07 +0000 Subject: [PATCH 10/28] moved some aggregaotr loading to agg_util --- autogalaxy/aggregator/agg_util.py | 67 +++++++++++++------ autogalaxy/aggregator/dataset_model.py | 5 +- autogalaxy/aggregator/ellipse/ellipses.py | 8 ++- autogalaxy/aggregator/ellipse/fit_ellipse.py | 8 ++- autogalaxy/aggregator/ellipse/multipoles.py | 8 ++- autogalaxy/aggregator/galaxies.py | 8 ++- autogalaxy/aggregator/imaging/fit_imaging.py | 8 ++- autogalaxy/aggregator/imaging/imaging.py | 18 ++--- .../interferometer/fit_interferometer.py | 8 ++- .../interferometer/interferometer.py | 22 ++---- autogalaxy/analysis/analysis/dataset.py | 2 +- 11 files changed, 95 insertions(+), 67 deletions(-) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index 1f576e783..93e7ed9cb 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -1,17 +1,51 @@ from __future__ import annotations from typing import List, Optional +from autoconf.fitsable import ndarray_via_hdu_from + import autofit as af import autoarray as aa from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages +def mask_header_pixel_scales_from(fit): + """ + Returns the mask, header and pixel scales of the `PyAutoFit` `Fit` object. + + These quantities are commonly loaded during the aggregator interface therefore this method is used to + avoid code duplication. + + Parameters + ---------- + fit + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database. + + + Returns + ------- + The mask, header and pixel scales of the `PyAutoFit` `Fit` object. + """ + + header = aa.Header(header_sci_obj=fit.value(name="adapt_images")[0].header) + pixel_scales = ( + header.header_sci_obj["PIXSCAY"], + header.header_sci_obj["PIXSCAX"], + ) + mask = aa.Mask2D( + mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), + pixel_scales=pixel_scales, + ) + + return mask, header, pixel_scales + def adapt_images_from( fit: af.Fit, ) -> List[AdaptImages]: """ - Updates adaptive images when loading the galaxies from a `PyAutoFit` sqlite database `Fit` object. + Updates adaptive images when loading the galaxies from a `PyAutoFit` loaded directory `Fit` or sqlite + database `Fit` object. This function ensures that if adaptive features (e.g. an `Hilbert` image-mesh) are used in a model-fit, they work when using the database to load and inspect the results of the model-fit. @@ -19,7 +53,8 @@ def adapt_images_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database. galaxies A list of galaxies corresponding to a sample of a non-linear search and model-fit. @@ -30,33 +65,26 @@ def adapt_images_from( fit_list = [fit] if not fit.children else fit.children - aaa - - if fit.value(name="adapt_images.adapt_images") is None: + if fit.value(name="adapt_images") is None: return [None] * len(fit_list) adapt_images_list = [] for fit in fit_list: - try: - mask = aa.Mask2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.mask")[0] - ) - except TypeError: - mask = aa.Mask2D.from_primary_hdu( - primary_hdu=fit.value(name="dataset.real_space_mask")[0] - ) + + mask, header, pixel_scales = mask_header_pixel_scales_from(fit=fit) galaxy_name_image_dict = {} - adapt_image_name_list = fit.value(name="adapt_images.adapt_images") + for i, value in enumerate(fit.value(name="adapt_images")[1:]): - for name in adapt_image_name_list: - adapt_image = aa.Array2D.from_primary_hdu( - primary_hdu=fit.value(name=f"adapt_images.{name}")[0] + adapt_image = aa.Array2D.no_mask( + values=ndarray_via_hdu_from(value), + pixel_scales=pixel_scales, + header=header, ) adapt_image = adapt_image.apply_mask(mask=mask) - galaxy_name_image_dict[name] = adapt_image + galaxy_name_image_dict[value.header["EXTNAME"]] = adapt_image instance = fit.model.instance_from_prior_medians(ignore_prior_limits=True) @@ -93,7 +121,8 @@ def mesh_grids_of_planes_list_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. total_fits The total number of `Analysis` objects summed to create the fit. use_preloaded_grid diff --git a/autogalaxy/aggregator/dataset_model.py b/autogalaxy/aggregator/dataset_model.py index 2be68859b..7c56f8454 100644 --- a/autogalaxy/aggregator/dataset_model.py +++ b/autogalaxy/aggregator/dataset_model.py @@ -12,7 +12,7 @@ def _dataset_model_from( fit: af.Fit, instance: af.ModelInstance ) -> List[aa.DatasetModel]: """ - Returns a `DatasetModel` object from a `PyAutoFit` sqlite database `Fit` object. + Returns a `DatasetModel` object from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -31,7 +31,8 @@ def _dataset_model_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/ellipse/ellipses.py b/autogalaxy/aggregator/ellipse/ellipses.py index 0b0bbd7d2..dbdfd5709 100644 --- a/autogalaxy/aggregator/ellipse/ellipses.py +++ b/autogalaxy/aggregator/ellipse/ellipses.py @@ -13,7 +13,7 @@ def _ellipses_from(fit: af.Fit, instance: af.ModelInstance) -> List[List[Ellipse]]: """ - Returns a list of `Ellipse` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `Ellipse` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -32,7 +32,8 @@ def _ellipses_from(fit: af.Fit, instance: af.ModelInstance) -> List[List[Ellipse Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). @@ -102,7 +103,8 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/ellipse/fit_ellipse.py b/autogalaxy/aggregator/ellipse/fit_ellipse.py index 3301f0cb8..123ab907d 100644 --- a/autogalaxy/aggregator/ellipse/fit_ellipse.py +++ b/autogalaxy/aggregator/ellipse/fit_ellipse.py @@ -16,7 +16,7 @@ def _fit_ellipse_from( instance: Optional[af.ModelInstance] = None, ) -> List[List[FitEllipse]]: """ - Returns a list of `FitEllipse` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `FitEllipse` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -39,7 +39,8 @@ def _fit_ellipse_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). @@ -122,7 +123,8 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/ellipse/multipoles.py b/autogalaxy/aggregator/ellipse/multipoles.py index 22e394b47..b5eb58912 100644 --- a/autogalaxy/aggregator/ellipse/multipoles.py +++ b/autogalaxy/aggregator/ellipse/multipoles.py @@ -15,7 +15,7 @@ def _multipoles_from( fit: af.Fit, instance: af.ModelInstance ) -> List[List[List[EllipseMultipole]]]: """ - Returns a list of `EllipseMultipole` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `EllipseMultipole` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -34,7 +34,8 @@ def _multipoles_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). @@ -104,7 +105,8 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/galaxies.py b/autogalaxy/aggregator/galaxies.py index 3c542c9ea..8a4f3549d 100644 --- a/autogalaxy/aggregator/galaxies.py +++ b/autogalaxy/aggregator/galaxies.py @@ -13,7 +13,7 @@ def _galaxies_from(fit: af.Fit, instance: af.ModelInstance) -> List[Galaxy]: """ - Returns a list of `Galaxy` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `Galaxy` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -33,7 +33,8 @@ def _galaxies_from(fit: af.Fit, instance: af.ModelInstance) -> List[Galaxy]: Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). @@ -113,7 +114,8 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/imaging/fit_imaging.py b/autogalaxy/aggregator/imaging/fit_imaging.py index f4de2059a..26897c68a 100644 --- a/autogalaxy/aggregator/imaging/fit_imaging.py +++ b/autogalaxy/aggregator/imaging/fit_imaging.py @@ -22,7 +22,7 @@ def _fit_imaging_from( use_preloaded_grid: bool = True, ) -> List[FitImaging]: """ - Returns a list of `FitImaging` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `FitImaging` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -46,7 +46,8 @@ def _fit_imaging_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). @@ -165,7 +166,8 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/imaging/imaging.py b/autogalaxy/aggregator/imaging/imaging.py index 0f4f06f92..f00e0b93c 100644 --- a/autogalaxy/aggregator/imaging/imaging.py +++ b/autogalaxy/aggregator/imaging/imaging.py @@ -6,12 +6,13 @@ import autofit as af import autoarray as aa +from autogalaxy.aggregator import agg_util def _imaging_from( fit: af.Fit, ) -> List[aa.Imaging]: """ - Returns a list of `Imaging` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `Imaging` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -34,7 +35,8 @@ def _imaging_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. """ fit_list = [fit] if not fit.children else fit.children @@ -42,11 +44,8 @@ def _imaging_from( dataset_list = [] for fit in fit_list: - header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) - pixel_scales = ( - header.header_sci_obj["PIXSCAY"], - header.header_sci_obj["PIXSCAX"], - ) + + mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from(fit=fit) def values_from(hdu: int, cls): return cls.no_mask( @@ -70,11 +69,6 @@ def values_from(hdu: int, cls): check_noise_map=False, ) - mask = aa.Mask2D( - mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), - pixel_scales=pixel_scales, - ) - dataset = dataset.apply_mask(mask=mask) try: diff --git a/autogalaxy/aggregator/interferometer/fit_interferometer.py b/autogalaxy/aggregator/interferometer/fit_interferometer.py index ade3d0d3e..fdc4a8afb 100644 --- a/autogalaxy/aggregator/interferometer/fit_interferometer.py +++ b/autogalaxy/aggregator/interferometer/fit_interferometer.py @@ -23,7 +23,7 @@ def _fit_interferometer_from( use_preloaded_grid: bool = True, ) -> List[FitInterferometer]: """ - Returns a list of `FitInterferometer` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `FitInterferometer` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -48,7 +48,8 @@ def _fit_interferometer_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). @@ -171,7 +172,8 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance randomly from the PDF). diff --git a/autogalaxy/aggregator/interferometer/interferometer.py b/autogalaxy/aggregator/interferometer/interferometer.py index 25c7ff0d1..ac44fc81a 100644 --- a/autogalaxy/aggregator/interferometer/interferometer.py +++ b/autogalaxy/aggregator/interferometer/interferometer.py @@ -1,17 +1,17 @@ from functools import partial from typing import List -from autoconf.fitsable import ndarray_via_hdu_from - import autofit as af import autoarray as aa +from autogalaxy.aggregator import agg_util + def _interferometer_from( fit: af.Fit, ) -> List[aa.Interferometer]: """ - Returns a list of `Interferometer` objects from a `PyAutoFit` sqlite database `Fit` object. + Returns a list of `Interferometer` objects from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: @@ -34,7 +34,8 @@ def _interferometer_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry in a sqlite database. + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + an output directory or from an sqlite database.. """ fit_list = [fit] if not fit.children else fit.children @@ -43,6 +44,8 @@ def _interferometer_from( for fit in fit_list: + real_space_mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from(fit=fit) + data = aa.Visibilities( visibilities=fit.value(name="dataset")[1].data.astype("float") ) @@ -51,17 +54,6 @@ def _interferometer_from( ) uv_wavelengths = fit.value(name="dataset")[3].data - header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) - pixel_scales = ( - header.header_sci_obj["PIXSCAY"], - header.header_sci_obj["PIXSCAX"], - ) - - real_space_mask = aa.Mask2D( - mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), - pixel_scales=pixel_scales, - ) - transformer_class = fit.value(name="dataset.transformer_class") dataset = aa.Interferometer( diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index 86c51a10c..73f9ebe37 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -181,7 +181,7 @@ def save_attributes(self, paths: af.DirectoryPaths): if self.adapt_images is not None: values_list = [ - self.adapt_images.galaxy_name_image_dict[name] + self.adapt_images.galaxy_name_image_dict[name].native for name in self.adapt_images.galaxy_name_image_dict.keys() ] From 0c15d60598db09210f992c9d7ae3191f9f666fde Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:13:03 +0000 Subject: [PATCH 11/28] fix agg adapt images --- autogalaxy/aggregator/agg_util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index 93e7ed9cb..41fdfbbb6 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -84,7 +84,8 @@ def adapt_images_from( header=header, ) adapt_image = adapt_image.apply_mask(mask=mask) - galaxy_name_image_dict[value.header["EXTNAME"]] = adapt_image + + galaxy_name_image_dict[value.header["EXTNAME"].lower()] = adapt_image instance = fit.model.instance_from_prior_medians(ignore_prior_limits=True) From 57404aa4dd16642e7fd6ce2df1df6188b4d51fe5 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:13:57 +0000 Subject: [PATCH 12/28] update quantity --- autogalaxy/quantity/model/analysis.py | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/autogalaxy/quantity/model/analysis.py b/autogalaxy/quantity/model/analysis.py index 9b455200f..9cc592911 100644 --- a/autogalaxy/quantity/model/analysis.py +++ b/autogalaxy/quantity/model/analysis.py @@ -1,4 +1,5 @@ from autoconf.dictable import to_dict +from autoconf.fitsable import hdu_list_for_output_from import autofit as af @@ -151,19 +152,20 @@ def save_attributes(self, paths: af.DirectoryPaths): visualization, and the pickled objects used by the aggregator output by this function. """ paths.save_fits( - name="data", - fits=self.dataset.data.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="noise_map", - fits=self.dataset.noise_map.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="mask", - fits=self.dataset.mask.hdu_for_output, - prefix="dataset", + name="dataset", + fits=hdu_list_for_output_from( + values_list=[ + self.dataset.mask.astype("float"), + self.dataset.data.native, + self.dataset.noise_map.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + ], + header_dict=self.dataset.mask.pixel_scale_header + ), ) paths.save_json( name="cosmology", From 9ccf85a89243373929860d5128da1202f7a026f5 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:14:44 +0000 Subject: [PATCH 13/28] update ellipse analysis --- autogalaxy/ellipse/model/analysis.py | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/autogalaxy/ellipse/model/analysis.py b/autogalaxy/ellipse/model/analysis.py index 857c570d3..126f0d401 100644 --- a/autogalaxy/ellipse/model/analysis.py +++ b/autogalaxy/ellipse/model/analysis.py @@ -2,7 +2,7 @@ import time from typing import Dict, List, Optional, Tuple -from autoconf.dictable import to_dict +from autoconf.fitsable import hdu_list_for_output_from import autofit as af import autoarray as aa @@ -185,19 +185,20 @@ def save_attributes(self, paths: af.DirectoryPaths): visualization, and the pickled objects used by the aggregator output by this function. """ paths.save_fits( - name="data", - fits=self.dataset.data.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="noise_map", - fits=self.dataset.noise_map.hdu_for_output, - prefix="dataset", - ) - paths.save_fits( - name="mask", - fits=self.dataset.mask.hdu_for_output, - prefix="dataset", + name="dataset", + fits=hdu_list_for_output_from( + values_list=[ + self.dataset.mask.astype("float"), + self.dataset.data.native, + self.dataset.noise_map.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + ], + header_dict=self.dataset.mask.pixel_scale_header + ), ) def profile_log_likelihood_function( From 702945fa9c223c65a5c1f5f0c475264ffa36ede3 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:18:29 +0000 Subject: [PATCH 14/28] fix header loading --- autogalaxy/aggregator/agg_util.py | 2 +- autogalaxy/aggregator/interferometer/fit_interferometer.py | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index 41fdfbbb6..bdbfa0837 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -27,7 +27,7 @@ def mask_header_pixel_scales_from(fit): The mask, header and pixel scales of the `PyAutoFit` `Fit` object. """ - header = aa.Header(header_sci_obj=fit.value(name="adapt_images")[0].header) + header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) pixel_scales = ( header.header_sci_obj["PIXSCAY"], header.header_sci_obj["PIXSCAX"], diff --git a/autogalaxy/aggregator/interferometer/fit_interferometer.py b/autogalaxy/aggregator/interferometer/fit_interferometer.py index fdc4a8afb..6e0991406 100644 --- a/autogalaxy/aggregator/interferometer/fit_interferometer.py +++ b/autogalaxy/aggregator/interferometer/fit_interferometer.py @@ -18,7 +18,6 @@ def _fit_interferometer_from( fit: af.Fit, instance: Optional[af.ModelInstance] = None, - real_space_mask: Optional[aa.Mask2D] = None, settings_inversion: aa.SettingsInversion = None, use_preloaded_grid: bool = True, ) -> List[FitInterferometer]: @@ -64,7 +63,6 @@ def _fit_interferometer_from( dataset_list = _interferometer_from( fit=fit, - real_space_mask=real_space_mask, ) galaxies_list = _galaxies_from(fit=fit, instance=instance) @@ -115,7 +113,6 @@ def __init__( aggregator: af.Aggregator, settings_inversion: Optional[aa.SettingsInversion] = None, use_preloaded_grid: bool = True, - real_space_mask: Optional[aa.Mask2D] = None, ): """ Interfaces with an `PyAutoFit` aggregator object to create instances of `FitInterferometer` objects from the @@ -159,7 +156,6 @@ def __init__( self.settings_inversion = settings_inversion self.use_preloaded_grid = use_preloaded_grid - self.real_space_mask = real_space_mask def object_via_gen_from( self, fit, instance: Optional[af.ModelInstance] = None From fde289fa15438d8afaa7a40fcb712a9cc35ec028 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:21:25 +0000 Subject: [PATCH 15/28] fix aggregator via IndexError Exception --- autogalaxy/aggregator/imaging/imaging.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autogalaxy/aggregator/imaging/imaging.py b/autogalaxy/aggregator/imaging/imaging.py index f00e0b93c..0e020f117 100644 --- a/autogalaxy/aggregator/imaging/imaging.py +++ b/autogalaxy/aggregator/imaging/imaging.py @@ -59,7 +59,7 @@ def values_from(hdu: int, cls): try: psf = values_from(hdu=3, cls=aa.Kernel2D) - except TypeError: + except (TypeError, IndexError): psf = None dataset = aa.Imaging( @@ -74,7 +74,7 @@ def values_from(hdu: int, cls): try: over_sample_size_lp = values_from(hdu=4, cls=aa.Array2D).native over_sample_size_lp = over_sample_size_lp.apply_mask(mask=mask) - except TypeError: + except (TypeError, IndexError): over_sample_size_lp = 1 try: @@ -82,7 +82,7 @@ def values_from(hdu: int, cls): over_sample_size_pixelization = over_sample_size_pixelization.apply_mask( mask=mask ) - except TypeError: + except (TypeError, IndexError): over_sample_size_pixelization = 1 dataset = dataset.apply_over_sampling( From 7ee041d5fabd1dfc87185bc91073326ac1513a77 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 11:29:12 +0000 Subject: [PATCH 16/28] docs --- autogalaxy/imaging/model/analysis.py | 14 ++++++-------- autogalaxy/interferometer/model/analysis.py | 14 ++++++-------- .../quantity/files/array/output_test/data.fits | Bin 5760 -> 0 bytes .../files/array/output_test/noise_map.fits | Bin 5760 -> 0 bytes 4 files changed, 12 insertions(+), 16 deletions(-) delete mode 100644 test_autogalaxy/quantity/files/array/output_test/data.fits delete mode 100644 test_autogalaxy/quantity/files/array/output_test/noise_map.fits diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index 6d328ae06..6310b4846 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -204,19 +204,17 @@ def save_attributes(self, paths: af.DirectoryPaths): Before the non-linear search begins, this routine saves attributes of the `Analysis` object to the `files` folder such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. + It outputs the following attributes of the dataset: + + - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The imaging dataset as `dataset.fits` (data / noise-map / psf / over sampler / etc.). + For this analysis, it uses the `AnalysisDataset` object's method to output the following: - - The imaging dataset (data / noise-map / psf / over sampler / etc.). - - The mask applied to the dataset. - The settings associated with the inversion. - The settings associated with the pixelization. - The Cosmology. - - The adapt image's model image and galaxy images, if used. - - This function also outputs attributes specific to an imaging dataset: - - - Its PSF. - - Its mask. + - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. It is common for these attributes to be loaded by many of the template aggregator functions given in the `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index 180131dc9..f8136e032 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -208,19 +208,17 @@ def save_attributes(self, paths: af.DirectoryPaths): Before the model-fit begins, this routine saves attributes of the `Analysis` object to the `files` folder such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. + It outputs the following attributes of the dataset: + + - The real space mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The interferometer dataset as `dataset.fits` (data / noise-map / uv_wavelengths). + For this analysis, it uses the `AnalysisDataset` object's method to output the following: - - The interferometer dataset (data / noise-map / uv-wavelengths / settings / etc.). - - The real space mask defining how the images appear in real-space and used for the FFT. - The settings associated with the inversion. - The settings associated with the pixelization. - The Cosmology. - - The adapt image's model image and galaxy images, if used. - - This function also outputs attributes specific to an interferometer dataset: - - - Its uv-wavelengths - - Its real space mask. + - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. It is common for these attributes to be loaded by many of the template aggregator functions given in the `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for diff --git a/test_autogalaxy/quantity/files/array/output_test/data.fits b/test_autogalaxy/quantity/files/array/output_test/data.fits deleted file mode 100644 index 90140e2a097b37f65e658111f2b2834c9eca5bd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5760 zcmeH@u?oU45QZHc9UL4S?gd1&;wDzHLO_eq4zAI*(4mPWb?96B2!=LNhX_U7{BQX$ z$K@mWB6d6-0-_Z;DyAu2rO2czG?kL}ERIN*TqIm2j(s!QviQW#PTpj>Fg&gluPEUq zr?R@GZb~~1H)j@^qw{^9;fZ^3NfpWLMb3*<=v)fjLf*QXH~YYwzb$rbYo591eBZY` z?{~Z)+;#j3)?fezU;qYS00v+H2D%vV`@OpSvCV-^YI6Os=b_Cedj7~Z2pE6?7=Qs7 NfB_hQ0T}or15X=fgd+d| diff --git a/test_autogalaxy/quantity/files/array/output_test/noise_map.fits b/test_autogalaxy/quantity/files/array/output_test/noise_map.fits deleted file mode 100644 index 0f91870ec84681e085d2990fe43c8f4821fc0d65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5760 zcmeH@u?oU45QZHc9UL4S?gd1&;wDy6A)uwu4zAI*(4mQ>b?{O2ne<_N1JhcmLxdu3 z{{NEParwA>9^1IMcTJZEc z<9^@rtl#mL&Z6c|Fa`rK00S@p126ysFi^*U-Mr?x+1;p!-6~JAicIh4JQurN_8aAV Y=UF!p7=Qs7fB_hQ0T_S*82BRt4@wf84*&oF From 46f480d9aff4f6d4e8748e37f3282701994c2156 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 14:43:17 +0000 Subject: [PATCH 17/28] update imaging plotter interface --- autogalaxy/__init__.py | 5 ++ autogalaxy/aggregator/agg_util.py | 17 ++--- autogalaxy/aggregator/dataset_model.py | 2 +- autogalaxy/aggregator/ellipse/ellipses.py | 4 +- autogalaxy/aggregator/ellipse/fit_ellipse.py | 4 +- autogalaxy/aggregator/ellipse/multipoles.py | 4 +- autogalaxy/aggregator/galaxies.py | 4 +- autogalaxy/aggregator/imaging/fit_imaging.py | 4 +- autogalaxy/aggregator/imaging/imaging.py | 4 +- .../interferometer/fit_interferometer.py | 4 +- .../interferometer/interferometer.py | 7 +- autogalaxy/analysis/analysis/dataset.py | 2 +- autogalaxy/analysis/plotter_interface.py | 10 +-- autogalaxy/ellipse/model/analysis.py | 2 +- autogalaxy/imaging/model/analysis.py | 40 +++++----- autogalaxy/imaging/model/plotter_interface.py | 73 ++++++++----------- autogalaxy/interferometer/model/analysis.py | 40 +++++----- autogalaxy/quantity/model/analysis.py | 2 +- .../analysis/test_plotter_interface.py | 2 +- .../model/test_plotter_interface_imaging.py | 8 +- .../test_plotter_interface_interferometer.py | 8 +- 21 files changed, 121 insertions(+), 125 deletions(-) diff --git a/autogalaxy/__init__.py b/autogalaxy/__init__.py index 2c2aea6e9..6266a883b 100644 --- a/autogalaxy/__init__.py +++ b/autogalaxy/__init__.py @@ -107,6 +107,11 @@ from .gui.scribbler import Scribbler from autoconf import conf +from autoconf.fitsable import ndarray_via_hdu_from +from autoconf.fitsable import ndarray_via_fits_from +from autoconf.fitsable import header_obj_from +from autoconf.fitsable import output_to_fits +from autoconf.fitsable import hdu_list_for_output_from conf.instance.register(__file__) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index bdbfa0837..c47fe0389 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -8,25 +8,26 @@ from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages + def mask_header_pixel_scales_from(fit): """ Returns the mask, header and pixel scales of the `PyAutoFit` `Fit` object. - + These quantities are commonly loaded during the aggregator interface therefore this method is used to avoid code duplication. - + Parameters ---------- fit A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database. - + Returns ------- The mask, header and pixel scales of the `PyAutoFit` `Fit` object. """ - + header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) pixel_scales = ( header.header_sci_obj["PIXSCAY"], @@ -36,7 +37,7 @@ def mask_header_pixel_scales_from(fit): mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), pixel_scales=pixel_scales, ) - + return mask, header, pixel_scales @@ -44,7 +45,7 @@ def adapt_images_from( fit: af.Fit, ) -> List[AdaptImages]: """ - Updates adaptive images when loading the galaxies from a `PyAutoFit` loaded directory `Fit` or sqlite + Updates adaptive images when loading the galaxies from a `PyAutoFit` loaded directory `Fit` or sqlite database `Fit` object. This function ensures that if adaptive features (e.g. an `Hilbert` image-mesh) are used in a model-fit, @@ -71,13 +72,11 @@ def adapt_images_from( adapt_images_list = [] for fit in fit_list: - mask, header, pixel_scales = mask_header_pixel_scales_from(fit=fit) galaxy_name_image_dict = {} for i, value in enumerate(fit.value(name="adapt_images")[1:]): - adapt_image = aa.Array2D.no_mask( values=ndarray_via_hdu_from(value), pixel_scales=pixel_scales, @@ -122,7 +121,7 @@ def mesh_grids_of_planes_list_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. total_fits The total number of `Analysis` objects summed to create the fit. diff --git a/autogalaxy/aggregator/dataset_model.py b/autogalaxy/aggregator/dataset_model.py index 7c56f8454..130b00abd 100644 --- a/autogalaxy/aggregator/dataset_model.py +++ b/autogalaxy/aggregator/dataset_model.py @@ -31,7 +31,7 @@ def _dataset_model_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/ellipse/ellipses.py b/autogalaxy/aggregator/ellipse/ellipses.py index dbdfd5709..cc4f3ee15 100644 --- a/autogalaxy/aggregator/ellipse/ellipses.py +++ b/autogalaxy/aggregator/ellipse/ellipses.py @@ -32,7 +32,7 @@ def _ellipses_from(fit: af.Fit, instance: af.ModelInstance) -> List[List[Ellipse Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance @@ -103,7 +103,7 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/ellipse/fit_ellipse.py b/autogalaxy/aggregator/ellipse/fit_ellipse.py index 123ab907d..3773bb914 100644 --- a/autogalaxy/aggregator/ellipse/fit_ellipse.py +++ b/autogalaxy/aggregator/ellipse/fit_ellipse.py @@ -39,7 +39,7 @@ def _fit_ellipse_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance @@ -123,7 +123,7 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/ellipse/multipoles.py b/autogalaxy/aggregator/ellipse/multipoles.py index b5eb58912..518259b75 100644 --- a/autogalaxy/aggregator/ellipse/multipoles.py +++ b/autogalaxy/aggregator/ellipse/multipoles.py @@ -34,7 +34,7 @@ def _multipoles_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance @@ -105,7 +105,7 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/galaxies.py b/autogalaxy/aggregator/galaxies.py index 8a4f3549d..60dbd3779 100644 --- a/autogalaxy/aggregator/galaxies.py +++ b/autogalaxy/aggregator/galaxies.py @@ -33,7 +33,7 @@ def _galaxies_from(fit: af.Fit, instance: af.ModelInstance) -> List[Galaxy]: Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance @@ -114,7 +114,7 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/imaging/fit_imaging.py b/autogalaxy/aggregator/imaging/fit_imaging.py index 26897c68a..d10494fc1 100644 --- a/autogalaxy/aggregator/imaging/fit_imaging.py +++ b/autogalaxy/aggregator/imaging/fit_imaging.py @@ -46,7 +46,7 @@ def _fit_imaging_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance @@ -166,7 +166,7 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/imaging/imaging.py b/autogalaxy/aggregator/imaging/imaging.py index 0e020f117..19acfec22 100644 --- a/autogalaxy/aggregator/imaging/imaging.py +++ b/autogalaxy/aggregator/imaging/imaging.py @@ -8,6 +8,7 @@ from autogalaxy.aggregator import agg_util + def _imaging_from( fit: af.Fit, ) -> List[aa.Imaging]: @@ -35,7 +36,7 @@ def _imaging_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. """ @@ -44,7 +45,6 @@ def _imaging_from( dataset_list = [] for fit in fit_list: - mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from(fit=fit) def values_from(hdu: int, cls): diff --git a/autogalaxy/aggregator/interferometer/fit_interferometer.py b/autogalaxy/aggregator/interferometer/fit_interferometer.py index 6e0991406..f2f802396 100644 --- a/autogalaxy/aggregator/interferometer/fit_interferometer.py +++ b/autogalaxy/aggregator/interferometer/fit_interferometer.py @@ -47,7 +47,7 @@ def _fit_interferometer_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance @@ -168,7 +168,7 @@ def object_via_gen_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. instance A manual instance that overwrites the max log likelihood instance in fit (e.g. for drawing the instance diff --git a/autogalaxy/aggregator/interferometer/interferometer.py b/autogalaxy/aggregator/interferometer/interferometer.py index ac44fc81a..7fb8da683 100644 --- a/autogalaxy/aggregator/interferometer/interferometer.py +++ b/autogalaxy/aggregator/interferometer/interferometer.py @@ -34,7 +34,7 @@ def _interferometer_from( Parameters ---------- fit - A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from + A `PyAutoFit` `Fit` object which contains the results of a model-fit as an entry which has been loaded from an output directory or from an sqlite database.. """ @@ -43,8 +43,9 @@ def _interferometer_from( dataset_list = [] for fit in fit_list: - - real_space_mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from(fit=fit) + real_space_mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from( + fit=fit + ) data = aa.Visibilities( visibilities=fit.value(name="dataset")[1].data.astype("float") diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index 73f9ebe37..937b54a50 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -194,7 +194,7 @@ def save_attributes(self, paths: af.DirectoryPaths): + values_list, ext_name_list=["mask"] + list(self.adapt_images.galaxy_name_image_dict.keys()), - header_dict=self.dataset.mask.pixel_scale_header + header_dict=self.dataset.mask.pixel_scale_header, ), ) diff --git a/autogalaxy/analysis/plotter_interface.py b/autogalaxy/analysis/plotter_interface.py index c33e15424..0631f26fe 100644 --- a/autogalaxy/analysis/plotter_interface.py +++ b/autogalaxy/analysis/plotter_interface.py @@ -1,5 +1,5 @@ import os -from os import path +from pathlib import Path from typing import List, Union from autoconf import conf @@ -36,7 +36,7 @@ def plot_setting(section: Union[List[str], str], name: str) -> bool: class PlotterInterface: - def __init__(self, image_path: str, title_prefix: str = None): + def __init__(self, image_path: Union[Path, str], title_prefix: str = None): """ Provides an interface between an output path and all plotter objects. @@ -60,7 +60,7 @@ def __init__(self, image_path: str, title_prefix: str = None): A string that is added before the title of all figures output by visualization, for example to put the name of the dataset and galaxy in the title. """ - self.image_path = image_path + self.image_path = Path(image_path) self.title_prefix = title_prefix self.include_2d = Include2D() @@ -83,7 +83,7 @@ def mat_plot_1d_from(self) -> MatPlot1D: """ return MatPlot1D( title=aplt.Title(prefix=self.title_prefix), - output=aplt.Output(path=path.join(self.image_path), format=self.fmt), + output=aplt.Output(path=self.image_path, format=self.fmt), ) def mat_plot_2d_from(self) -> MatPlot2D: @@ -98,7 +98,7 @@ def mat_plot_2d_from(self) -> MatPlot2D: """ return MatPlot2D( title=aplt.Title(prefix=self.title_prefix), - output=aplt.Output(path=path.join(self.image_path), format=self.fmt), + output=aplt.Output(path=self.image_path, format=self.fmt), ) def galaxies( diff --git a/autogalaxy/ellipse/model/analysis.py b/autogalaxy/ellipse/model/analysis.py index 126f0d401..5af73ca9d 100644 --- a/autogalaxy/ellipse/model/analysis.py +++ b/autogalaxy/ellipse/model/analysis.py @@ -197,7 +197,7 @@ def save_attributes(self, paths: af.DirectoryPaths): "data", "noise_map", ], - header_dict=self.dataset.mask.pixel_scale_header + header_dict=self.dataset.mask.pixel_scale_header, ), ) diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index 6310b4846..86f6ddfc9 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -201,31 +201,31 @@ def fit_from( def save_attributes(self, paths: af.DirectoryPaths): """ - Before the non-linear search begins, this routine saves attributes of the `Analysis` object to the `files` - folder such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. + Before the non-linear search begins, this routine saves attributes of the `Analysis` object to the `files` + folder such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. - It outputs the following attributes of the dataset: + It outputs the following attributes of the dataset: - - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. - - The imaging dataset as `dataset.fits` (data / noise-map / psf / over sampler / etc.). + - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The imaging dataset as `dataset.fits` (data / noise-map / psf / over sampler / etc.). - For this analysis, it uses the `AnalysisDataset` object's method to output the following: + For this analysis, it uses the `AnalysisDataset` object's method to output the following: - - The settings associated with the inversion. - - The settings associated with the pixelization. - - The Cosmology. - - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. + - The settings associated with the inversion. + - The settings associated with the pixelization. + - The Cosmology. + - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. - It is common for these attributes to be loaded by many of the template aggregator functions given in the - `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for - the dataset, settings and other attributes necessary to perform the fit to be loaded via the pickle files - output by this function. + It is common for these attributes to be loaded by many of the template aggregator functions given in the + `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for + the dataset, settings and other attributes necessary to perform the fit to be loaded via the pickle files + output by this function. - Parameters - ---------- - paths - The paths object which manages all paths, e.g. where the non-linear search outputs are stored, - visualization, and the pickled objects used by the aggregator output by this function. + Parameters + ---------- + paths + The paths object which manages all paths, e.g. where the non-linear search outputs are stored, + visualization, and the pickled objects used by the aggregator output by this function. """ super().save_attributes(paths=paths) @@ -248,7 +248,7 @@ def save_attributes(self, paths: af.DirectoryPaths): "over_sample_size_lp", "over_sample_size_pixelization", ], - header_dict=self.dataset.mask.pixel_scale_header + header_dict=self.dataset.mask.pixel_scale_header, ), ) diff --git a/autogalaxy/imaging/model/plotter_interface.py b/autogalaxy/imaging/model/plotter_interface.py index 7074f2b2e..59459b8fd 100644 --- a/autogalaxy/imaging/model/plotter_interface.py +++ b/autogalaxy/imaging/model/plotter_interface.py @@ -1,5 +1,7 @@ -from os import path -from typing import ClassVar, List +from pathlib import Path +from typing import List + +from autoconf.fitsable import hdu_list_for_output_from import autoarray as aa import autoarray.plot as aplt @@ -13,9 +15,8 @@ def fits_to_fits( should_plot: bool, + image_path: Path, fit: FitImaging, - mat_plot_2d: aplt.MatPlot2D, - fit_plotter_cls: ClassVar, ): """ Output attributes of a `FitImaging` to .fits format. @@ -27,56 +28,47 @@ def fits_to_fits( ---------- should_plot The function which inspects the configuration files to determine if a .fits file should be output. + image_path + The path the .fits files are output and the name of the .fits files. fit The fit to output to a .fits file. - mat_plot_2d - The 2D matplotlib plot used to create the .fits files. - fit_plotter_cls - The plotter class used to create the .fits files. """ if should_plot("fits_fit"): - multi_plotter = aplt.MultiFigurePlotter( - plotter_list=[fit_plotter_cls(fit=fit, mat_plot_2d=mat_plot_2d)] * 4, - ) - - multi_plotter.output_to_fits( - func_name_list=["figures_2d"] * len(multi_plotter.plotter_list), - figure_name_list=[ - "model_image", - "residual_map", - "normalized_residual_map", - "chi_squared_map", + hdu_list = hdu_list_for_output_from( + values_list=[ + fit.mask.astype("float"), + fit.model_data, + fit.residual_map, + fit.normalized_residual_map, + fit.chi_squared_map, ], - # tag_list=[name for name, galaxy in galaxies.items()], - tag_list=[ - "model_image", + ext_name_list=[ + "mask", + "model_data", "residual_map", "normalized_residual_map", "chi_squared_map", ], - filename="fit", - remove_fits_first=True, + header_dict=fit.mask.pixel_scale_header, ) + hdu_list.writeto(image_path / "fit.fits", overwrite=True) + if should_plot("fits_model_galaxy_images"): - multi_plotter = aplt.MultiFigurePlotter( - plotter_list=[ - aplt.Array2DPlotter(array=image, mat_plot_2d=mat_plot_2d) - for (galaxy, image) in fit.galaxy_model_image_dict.items() - ], + number_plots = len(fit.galaxy_model_image_dict.keys()) + 1 + + hdu_list = hdu_list_for_output_from( + values_list=[fit.mask.astype("float")] + + [image.native for image in fit.galaxy_model_image_dict.values()], + ext_name_list=[ + "mask", + ] + + [f"galaxy_{i}" for i in range(number_plots)], + header_dict=fit.mask.pixel_scale_header, ) - number_plots = len(multi_plotter.plotter_list) - - multi_plotter.output_to_fits( - func_name_list=["figure_2d"] * number_plots, - figure_name_list=[None] * number_plots, - # tag_list=[name for name, galaxy in galaxies.items()], - tag_list=[f"galaxy_{i}" for i in range(number_plots)], - filename="model_galaxy_images", - remove_fits_first=True, - ) + hdu_list.writeto(image_path / "model_galaxy_images.fits", overwrite=True) class PlotterInterfaceImaging(PlotterInterface): @@ -151,9 +143,8 @@ def should_plot(name): fits_to_fits( should_plot=should_plot, + image_path=self.image_path, fit=fit, - mat_plot_2d=mat_plot_2d, - fit_plotter_cls=FitImagingPlotter, ) def imaging_combined(self, dataset_list: List[aa.Imaging]): diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index f8136e032..a4c149b76 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -205,31 +205,31 @@ def fit_from( def save_attributes(self, paths: af.DirectoryPaths): """ - Before the model-fit begins, this routine saves attributes of the `Analysis` object to the `files` folder - such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. + Before the model-fit begins, this routine saves attributes of the `Analysis` object to the `files` folder + such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. - It outputs the following attributes of the dataset: + It outputs the following attributes of the dataset: - - The real space mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. - - The interferometer dataset as `dataset.fits` (data / noise-map / uv_wavelengths). + - The real space mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The interferometer dataset as `dataset.fits` (data / noise-map / uv_wavelengths). - For this analysis, it uses the `AnalysisDataset` object's method to output the following: + For this analysis, it uses the `AnalysisDataset` object's method to output the following: - - The settings associated with the inversion. - - The settings associated with the pixelization. - - The Cosmology. - - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. + - The settings associated with the inversion. + - The settings associated with the pixelization. + - The Cosmology. + - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. - It is common for these attributes to be loaded by many of the template aggregator functions given in the - `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for - the dataset, settings and other attributes necessary to perform the fit to be loaded via the pickle files - output by this function. + It is common for these attributes to be loaded by many of the template aggregator functions given in the + `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for + the dataset, settings and other attributes necessary to perform the fit to be loaded via the pickle files + output by this function. - Parameters - ---------- - paths - The paths object which manages all paths, e.g. where the non-linear search outputs are stored, visualization, - and the pickled objects used by the aggregator output by this function. + Parameters + ---------- + paths + The paths object which manages all paths, e.g. where the non-linear search outputs are stored, visualization, + and the pickled objects used by the aggregator output by this function. """ super().save_attributes(paths=paths) @@ -243,7 +243,7 @@ def save_attributes(self, paths: af.DirectoryPaths): self.dataset.uv_wavelengths, ], ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], - header_dict=self.dataset.real_space_mask.pixel_scale_header + header_dict=self.dataset.real_space_mask.pixel_scale_header, ), ) diff --git a/autogalaxy/quantity/model/analysis.py b/autogalaxy/quantity/model/analysis.py index 9cc592911..3882a0422 100644 --- a/autogalaxy/quantity/model/analysis.py +++ b/autogalaxy/quantity/model/analysis.py @@ -164,7 +164,7 @@ def save_attributes(self, paths: af.DirectoryPaths): "data", "noise_map", ], - header_dict=self.dataset.mask.pixel_scale_header + header_dict=self.dataset.mask.pixel_scale_header, ), ) paths.save_json( diff --git a/test_autogalaxy/analysis/test_plotter_interface.py b/test_autogalaxy/analysis/test_plotter_interface.py index 3893e508c..2d65df924 100644 --- a/test_autogalaxy/analysis/test_plotter_interface.py +++ b/test_autogalaxy/analysis/test_plotter_interface.py @@ -34,7 +34,7 @@ def test__galaxies( path.join(plot_path, "subplot_galaxies_1d_decomposed.png") in plot_patch.paths ) - image = ag.util.array_2d.numpy_array_2d_via_fits_from( + image = ag.ndarray_via_fits_from( file_path=path.join(plot_path, "galaxy_images.fits"), hdu=0 ) diff --git a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py index de73868d2..f2c4dd9de 100644 --- a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py +++ b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py @@ -53,17 +53,17 @@ def test__fit_imaging( assert path.join(plot_path, "subplot_fit.png") in plot_patch.paths - image = ag.util.array_2d.numpy_array_2d_via_fits_from( + image = ag.ndarray_via_fits_from( file_path=path.join(plot_path, "fit.fits"), hdu=0 ) - assert image.shape == (5, 5) + assert image.shape == (7, 7) - image = ag.util.array_2d.numpy_array_2d_via_fits_from( + image = ag.ndarray_via_fits_from( file_path=path.join(plot_path, "model_galaxy_images.fits"), hdu=0 ) - assert image.shape == (5, 5) + assert image.shape == (7, 7) def test__fit_imaging_combined( diff --git a/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py b/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py index a313a768e..d0a13db4e 100644 --- a/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py +++ b/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py @@ -38,25 +38,25 @@ def test__fit_interferometer( assert path.join(plot_path, "subplot_fit.png") in plot_patch.paths - # visibilities = ag.util.array_2d.numpy_array_2d_via_fits_from( + # visibilities = ag.ndarray_via_fits_from( # file_path=path.join(plot_path, "fit.fits"), hdu=0 # ) # # assert visibilities.shape == (5, 5) - # visibilities = ag.util.array_2d.numpy_array_2d_via_fits_from( + # visibilities = ag.ndarray_via_fits_from( # file_path=path.join(plot_path, "model_galaxy_visibilities.fits"), hdu=0 # ) # # assert visibilities.shape == (5, 5) - image = ag.util.array_2d.numpy_array_2d_via_fits_from( + image = ag.ndarray_via_fits_from( file_path=path.join(plot_path, "model_galaxy_images.fits"), hdu=0 ) assert image.shape == (5, 5) - image = ag.util.array_2d.numpy_array_2d_via_fits_from( + image = ag.ndarray_via_fits_from( file_path=path.join(plot_path, "dirty_images.fits"), hdu=0 ) From 447b59250b9caf92b3694954bc9e5d18c7fbc8f1 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 15:36:52 +0000 Subject: [PATCH 18/28] fgalaxy imafges --- autogalaxy/analysis/plotter_interface.py | 24 +++++++------------ .../analysis/test_plotter_interface.py | 2 +- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/autogalaxy/analysis/plotter_interface.py b/autogalaxy/analysis/plotter_interface.py index 0631f26fe..ef1a66f3d 100644 --- a/autogalaxy/analysis/plotter_interface.py +++ b/autogalaxy/analysis/plotter_interface.py @@ -3,6 +3,8 @@ from typing import List, Union from autoconf import conf +from autoconf.fitsable import hdu_list_for_output_from + import autoarray as aa import autoarray.plot as aplt @@ -178,25 +180,15 @@ def should_plot(name): pass if should_plot("fits_galaxy_images"): - multi_plotter = aplt.MultiFigurePlotter( - plotter_list=[ - GalaxyPlotter(galaxy=galaxy, grid=grid, mat_plot_2d=mat_plot_2d) - for galaxy in galaxies - ], - ) - multi_plotter.output_to_fits( - func_name_list=["figures_2d"] * len(galaxies), - figure_name_list=[ - "image", - ] - * len(galaxies), - # tag_list=[name for name, galaxy in galaxies.items()], - tag_list=[f"galaxy_{i}" for i in range(len(galaxies))], - filename="galaxy_images", - remove_fits_first=True, + hdu_list = hdu_list_for_output_from( + values_list=[grid.mask.astype("float")] + [galaxy.image_2d_from(grid=grid) for galaxy in galaxies], + ext_name_list=["mask"] + [f"galaxy_{i}" for i in range(len(galaxies))], + header_dict=grid.mask.pixel_scale_header, ) + hdu_list.writeto(self.image_path / "galaxy_images.fits", overwrite=True) + def inversion(self, inversion: aa.Inversion): """ Visualizes an `Inversion` object. diff --git a/test_autogalaxy/analysis/test_plotter_interface.py b/test_autogalaxy/analysis/test_plotter_interface.py index 2d65df924..0831d38bd 100644 --- a/test_autogalaxy/analysis/test_plotter_interface.py +++ b/test_autogalaxy/analysis/test_plotter_interface.py @@ -38,7 +38,7 @@ def test__galaxies( file_path=path.join(plot_path, "galaxy_images.fits"), hdu=0 ) - assert image.shape == (5, 5) + assert image.shape == (7, 7) def test__inversion( From 9ea8bf70e22f8d5a61df8d6afe986443bae589ba Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 15:46:37 +0000 Subject: [PATCH 19/28] update intererometer plotter interface --- autogalaxy/analysis/plotter_interface.py | 4 +- .../interferometer/model/plotter_interface.py | 96 ++++++------------- .../model/test_plotter_interface_imaging.py | 4 +- .../test_plotter_interface_interferometer.py | 18 +--- 4 files changed, 34 insertions(+), 88 deletions(-) diff --git a/autogalaxy/analysis/plotter_interface.py b/autogalaxy/analysis/plotter_interface.py index ef1a66f3d..e9d2241bd 100644 --- a/autogalaxy/analysis/plotter_interface.py +++ b/autogalaxy/analysis/plotter_interface.py @@ -180,9 +180,9 @@ def should_plot(name): pass if should_plot("fits_galaxy_images"): - hdu_list = hdu_list_for_output_from( - values_list=[grid.mask.astype("float")] + [galaxy.image_2d_from(grid=grid) for galaxy in galaxies], + values_list=[grid.mask.astype("float")] + + [galaxy.image_2d_from(grid=grid) for galaxy in galaxies], ext_name_list=["mask"] + [f"galaxy_{i}" for i in range(len(galaxies))], header_dict=grid.mask.pixel_scale_header, ) diff --git a/autogalaxy/interferometer/model/plotter_interface.py b/autogalaxy/interferometer/model/plotter_interface.py index fa421cae5..c986a9cd6 100644 --- a/autogalaxy/interferometer/model/plotter_interface.py +++ b/autogalaxy/interferometer/model/plotter_interface.py @@ -1,5 +1,6 @@ -from os import path -from typing import ClassVar +from pathlib import Path + +from autoconf.fitsable import hdu_list_for_output_from import autoarray as aa import autoarray.plot as aplt @@ -15,9 +16,8 @@ def fits_to_fits( should_plot: bool, + image_path: Path, fit: FitInterferometer, - mat_plot_2d: aplt.MatPlot2D, - fit_plotter_cls: ClassVar, ): """ Output attributes of a `FitInterferometer` to .fits format. @@ -29,76 +29,36 @@ def fits_to_fits( ---------- should_plot The function which inspects the configuration files to determine if a .fits file should be output. + image_path + The path the .fits files are output and the name of the .fits files. fit The fit to output to a .fits file. - mat_plot_2d - The 2D matplotlib plot used to create the .fits files. - fit_plotter_cls - The plotter class used to create the .fits files. """ - # if should_plot("fits_fit"): - # - # multi_plotter = aplt.MultiFigurePlotter( - # plotter_list=[FitInterferometerPlotter(fit=fit, mat_plot_2d=mat_plot_2d)] * 4, - # ) - # - # multi_plotter.output_to_fits( - # func_name_list=["figures_2d"] * len(multi_plotter.plotter_list), - # figure_name_list=[ - # "model_data", - # "residual_map_real", - # "residual_map_real", - # "normalized_residual_map_real", - # "chi_squared_map_real", - # ], - # # tag_list=[name for name, galaxy in galaxies.items()], - # tag_list=[ - # "model_data", - # "residual_map", - # "normalized_residual_map", - # "chi_squared_map", - # ], - # filename="fit", - # remove_fits_first=True, - # ) if should_plot("fits_model_galaxy_images"): - multi_plotter = aplt.MultiFigurePlotter( - plotter_list=[ - aplt.Array2DPlotter(array=image, mat_plot_2d=mat_plot_2d) - for (galaxy, image) in fit.galaxy_model_image_dict.items() - ], + hdu_list = hdu_list_for_output_from( + values_list=[fit.dataset.real_space_mask.astype("float")] + + [image.native for image in fit.galaxy_model_image_dict.values()], + ext_name_list=["mask"] + + [f"galaxy_{i}" for i in range(len(fit.galaxy_model_image_dict.values()))], + header_dict=fit.dataset.real_space_mask.pixel_scale_header, ) - multi_plotter.output_to_fits( - func_name_list=["figure_2d"] * len(multi_plotter.plotter_list), - figure_name_list=[None] * len(multi_plotter.plotter_list), - # tag_list=[name for name, galaxy in galaxies.items()], - tag_list=[f"galaxy_{i}" for i in range(len(multi_plotter.plotter_list))], - filename="model_galaxy_images", - remove_fits_first=True, - ) + hdu_list.writeto(image_path / "model_galaxy_images.fits", overwrite=True) if should_plot("fits_dirty_images"): - number_plots = 6 - - multi_plotter = aplt.MultiFigurePlotter( - plotter_list=[FitInterferometerPlotter(fit=fit, mat_plot_2d=mat_plot_2d)] - * number_plots, - ) - - multi_plotter.output_to_fits( - func_name_list=["figures_2d"] * len(multi_plotter.plotter_list), - figure_name_list=[ - "dirty_image", - "dirty_noise_map", - "dirty_model_image", - "dirty_residual_map", - "dirty_normalized_residual_map", - "dirty_chi_squared_map", + hdu_list = hdu_list_for_output_from( + values_list=[ + fit.dataset.real_space_mask.astype("float"), + fit.dirty_image.native, + fit.dirty_noise_map.native, + fit.dirty_model_image.native, + fit.dirty_residual_map.native, + fit.dirty_normalized_residual_map.native, + fit.dirty_chi_squared_map.native, ], - # tag_list=[name for name, galaxy in galaxies.items()], - tag_list=[ + ext_name_list=["mask"] + + [ "dirty_image", "dirty_noise_map", "dirty_model_image", @@ -106,10 +66,11 @@ def fits_to_fits( "dirty_normalized_residual_map", "dirty_chi_squared_map", ], - filename="dirty_images", - remove_fits_first=True, + header_dict=fit.dataset.real_space_mask.pixel_scale_header, ) + hdu_list.writeto(image_path / "fit_dirty_images.fits", overwrite=True) + class PlotterInterfaceInterferometer(PlotterInterface): def interferometer(self, dataset: aa.Interferometer): @@ -194,7 +155,6 @@ def should_plot(name): fits_to_fits( should_plot=should_plot, + image_path=self.image_path, fit=fit, - mat_plot_2d=mat_plot_2d, - fit_plotter_cls=FitInterferometerPlotter, ) diff --git a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py index f2c4dd9de..7a0f29856 100644 --- a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py +++ b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py @@ -53,9 +53,7 @@ def test__fit_imaging( assert path.join(plot_path, "subplot_fit.png") in plot_patch.paths - image = ag.ndarray_via_fits_from( - file_path=path.join(plot_path, "fit.fits"), hdu=0 - ) + image = ag.ndarray_via_fits_from(file_path=path.join(plot_path, "fit.fits"), hdu=0) assert image.shape == (7, 7) diff --git a/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py b/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py index d0a13db4e..92970265d 100644 --- a/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py +++ b/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py @@ -38,26 +38,14 @@ def test__fit_interferometer( assert path.join(plot_path, "subplot_fit.png") in plot_patch.paths - # visibilities = ag.ndarray_via_fits_from( - # file_path=path.join(plot_path, "fit.fits"), hdu=0 - # ) - # - # assert visibilities.shape == (5, 5) - - # visibilities = ag.ndarray_via_fits_from( - # file_path=path.join(plot_path, "model_galaxy_visibilities.fits"), hdu=0 - # ) - # - # assert visibilities.shape == (5, 5) - image = ag.ndarray_via_fits_from( file_path=path.join(plot_path, "model_galaxy_images.fits"), hdu=0 ) - assert image.shape == (5, 5) + assert image.shape == (7, 7) image = ag.ndarray_via_fits_from( - file_path=path.join(plot_path, "dirty_images.fits"), hdu=0 + file_path=path.join(plot_path, "fit_dirty_images.fits"), hdu=0 ) - assert image.shape == (5, 5) + assert image.shape == (7, 7) From 825544bf310168fab8a44c0b372639628f028814 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 16:33:58 +0000 Subject: [PATCH 20/28] move save attributes stuff to plotter interface --- autogalaxy/aggregator/agg_util.py | 14 +++++--- autogalaxy/aggregator/imaging/imaging.py | 5 +-- .../interferometer/interferometer.py | 2 +- autogalaxy/analysis/analysis/dataset.py | 25 +++----------- autogalaxy/analysis/plotter_interface.py | 19 ++++++++++- autogalaxy/ellipse/model/analysis.py | 2 +- autogalaxy/imaging/model/analysis.py | 33 +++---------------- autogalaxy/imaging/model/plotter_interface.py | 26 +++++++++++++-- autogalaxy/imaging/model/visualizer.py | 6 +++- autogalaxy/interferometer/model/analysis.py | 22 ++++--------- .../interferometer/model/plotter_interface.py | 17 ++++++++-- autogalaxy/quantity/model/analysis.py | 2 +- .../analysis/test_plotter_interface.py | 6 ++++ .../model/test_plotter_interface_imaging.py | 5 +++ .../test_plotter_interface_interferometer.py | 6 ++++ 15 files changed, 111 insertions(+), 79 deletions(-) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index c47fe0389..aea2e695f 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -9,7 +9,7 @@ from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages -def mask_header_pixel_scales_from(fit): +def mask_header_from(fit): """ Returns the mask, header and pixel scales of the `PyAutoFit` `Fit` object. @@ -33,12 +33,17 @@ def mask_header_pixel_scales_from(fit): header.header_sci_obj["PIXSCAY"], header.header_sci_obj["PIXSCAX"], ) + origin = ( + header.header_sci_obj["ORIGINY"], + header.header_sci_obj["ORIGINX"], + ) mask = aa.Mask2D( mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]), pixel_scales=pixel_scales, + origin=origin, ) - return mask, header, pixel_scales + return mask, header def adapt_images_from( @@ -72,15 +77,16 @@ def adapt_images_from( adapt_images_list = [] for fit in fit_list: - mask, header, pixel_scales = mask_header_pixel_scales_from(fit=fit) + mask, header = mask_header_from(fit=fit) galaxy_name_image_dict = {} for i, value in enumerate(fit.value(name="adapt_images")[1:]): adapt_image = aa.Array2D.no_mask( values=ndarray_via_hdu_from(value), - pixel_scales=pixel_scales, + pixel_scales=mask.pixel_scales, header=header, + origin=mask.origin, ) adapt_image = adapt_image.apply_mask(mask=mask) diff --git a/autogalaxy/aggregator/imaging/imaging.py b/autogalaxy/aggregator/imaging/imaging.py index 19acfec22..dae4ed718 100644 --- a/autogalaxy/aggregator/imaging/imaging.py +++ b/autogalaxy/aggregator/imaging/imaging.py @@ -45,13 +45,14 @@ def _imaging_from( dataset_list = [] for fit in fit_list: - mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from(fit=fit) + mask, header = agg_util.mask_header_from(fit=fit) def values_from(hdu: int, cls): return cls.no_mask( values=ndarray_via_hdu_from(fit.value(name="dataset")[hdu]), - pixel_scales=pixel_scales, + pixel_scales=mask.pixel_scales, header=header, + origin=mask.origin, ) data = values_from(hdu=1, cls=aa.Array2D) diff --git a/autogalaxy/aggregator/interferometer/interferometer.py b/autogalaxy/aggregator/interferometer/interferometer.py index 7fb8da683..ed9edcb48 100644 --- a/autogalaxy/aggregator/interferometer/interferometer.py +++ b/autogalaxy/aggregator/interferometer/interferometer.py @@ -43,7 +43,7 @@ def _interferometer_from( dataset_list = [] for fit in fit_list: - real_space_mask, header, pixel_scales = agg_util.mask_header_pixel_scales_from( + real_space_mask, header = agg_util.mask_header_pixel_scales_origin_from( fit=fit ) diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index 937b54a50..3da87d19c 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -153,10 +153,14 @@ def save_attributes(self, paths: af.DirectoryPaths): For this analysis the following are output: - - The dataset (data / noise-map / over sampler / etc.). - The settings associated with the inversion. - The settings associated with the pixelization. - The Cosmology. + + The following .fits files are also output via the plotter interface: + + - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The dataset (data / noise-map / over sampler / etc.). - The adapt image's model image and galaxy images, if used. It is common for these attributes to be loaded by many of the template aggregator functions given in the @@ -179,25 +183,6 @@ def save_attributes(self, paths: af.DirectoryPaths): object_dict=to_dict(self.cosmology), ) - if self.adapt_images is not None: - values_list = [ - self.adapt_images.galaxy_name_image_dict[name].native - for name in self.adapt_images.galaxy_name_image_dict.keys() - ] - - paths.save_fits( - name="adapt_images", - fits=hdu_list_for_output_from( - values_list=[ - self.dataset.mask.astype("float"), - ] - + values_list, - ext_name_list=["mask"] - + list(self.adapt_images.galaxy_name_image_dict.keys()), - header_dict=self.dataset.mask.pixel_scale_header, - ), - ) - def save_results(self, paths: af.DirectoryPaths, result: ResultDataset): """ At the end of a model-fit, this routine saves attributes of the `Analysis` object to the `files` diff --git a/autogalaxy/analysis/plotter_interface.py b/autogalaxy/analysis/plotter_interface.py index e9d2241bd..bdf652f73 100644 --- a/autogalaxy/analysis/plotter_interface.py +++ b/autogalaxy/analysis/plotter_interface.py @@ -184,7 +184,7 @@ def should_plot(name): values_list=[grid.mask.astype("float")] + [galaxy.image_2d_from(grid=grid) for galaxy in galaxies], ext_name_list=["mask"] + [f"galaxy_{i}" for i in range(len(galaxies))], - header_dict=grid.mask.pixel_scale_header, + header_dict=grid.mask.header_dict, ) hdu_list.writeto(self.image_path / "galaxy_images.fits", overwrite=True) @@ -258,3 +258,20 @@ def should_plot(name): adapt_plotter.subplot_adapt_images( adapt_galaxy_name_image_dict=adapt_images.galaxy_image_dict ) + + values_list = [ + adapt_images.galaxy_name_image_dict[name].native + for name in adapt_images.galaxy_name_image_dict.keys() + ] + + hdu_list = hdu_list_for_output_from( + values_list=[ + adapt_images.mask.astype("float"), + ] + + values_list, + ext_name_list=["mask"] + + list(adapt_images.galaxy_name_image_dict.keys()), + header_dict=adapt_images.mask.header_dict, + ) + + hdu_list.writeto(self.image_path / "adapt_images.fits", overwrite=True) diff --git a/autogalaxy/ellipse/model/analysis.py b/autogalaxy/ellipse/model/analysis.py index 5af73ca9d..9e1879c28 100644 --- a/autogalaxy/ellipse/model/analysis.py +++ b/autogalaxy/ellipse/model/analysis.py @@ -197,7 +197,7 @@ def save_attributes(self, paths: af.DirectoryPaths): "data", "noise_map", ], - header_dict=self.dataset.mask.pixel_scale_header, + header_dict=self.dataset.mask.header_dict, ), ) diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index 86f6ddfc9..6f6b2f21e 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -204,11 +204,6 @@ def save_attributes(self, paths: af.DirectoryPaths): Before the non-linear search begins, this routine saves attributes of the `Analysis` object to the `files` folder such that they can be loaded after the analysis using PyAutoFit's database and aggregator tools. - It outputs the following attributes of the dataset: - - - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. - - The imaging dataset as `dataset.fits` (data / noise-map / psf / over sampler / etc.). - For this analysis, it uses the `AnalysisDataset` object's method to output the following: - The settings associated with the inversion. @@ -216,6 +211,11 @@ def save_attributes(self, paths: af.DirectoryPaths): - The Cosmology. - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. + The following .fits files are also output via the plotter interface: + + - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The imaging dataset as `dataset.fits` (data / noise-map / psf / over sampler / etc.). + It is common for these attributes to be loaded by many of the template aggregator functions given in the `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for the dataset, settings and other attributes necessary to perform the fit to be loaded via the pickle files @@ -229,29 +229,6 @@ def save_attributes(self, paths: af.DirectoryPaths): """ super().save_attributes(paths=paths) - paths.save_fits( - name="dataset", - fits=hdu_list_for_output_from( - values_list=[ - self.dataset.mask.astype("float"), - self.dataset.data.native, - self.dataset.noise_map.native, - self.dataset.psf.native, - self.dataset.grids.lp.over_sample_size.native, - self.dataset.grids.pixelization.over_sample_size.native, - ], - ext_name_list=[ - "mask", - "data", - "noise_map", - "psf", - "over_sample_size_lp", - "over_sample_size_pixelization", - ], - header_dict=self.dataset.mask.pixel_scale_header, - ), - ) - def profile_log_likelihood_function( self, instance: af.ModelInstance, paths: Optional[af.DirectoryPaths] = None ) -> Tuple[Dict, Dict]: diff --git a/autogalaxy/imaging/model/plotter_interface.py b/autogalaxy/imaging/model/plotter_interface.py index 59459b8fd..894e5154c 100644 --- a/autogalaxy/imaging/model/plotter_interface.py +++ b/autogalaxy/imaging/model/plotter_interface.py @@ -50,7 +50,7 @@ def fits_to_fits( "normalized_residual_map", "chi_squared_map", ], - header_dict=fit.mask.pixel_scale_header, + header_dict=fit.mask.header_dict, ) hdu_list.writeto(image_path / "fit.fits", overwrite=True) @@ -65,7 +65,7 @@ def fits_to_fits( "mask", ] + [f"galaxy_{i}" for i in range(number_plots)], - header_dict=fit.mask.pixel_scale_header, + header_dict=fit.mask.header_dict, ) hdu_list.writeto(image_path / "model_galaxy_images.fits", overwrite=True) @@ -103,6 +103,28 @@ def should_plot(name): if should_plot("subplot_dataset"): dataset_plotter.subplot_dataset() + hdu_list = hdu_list_for_output_from( + values_list=[ + dataset.mask.astype("float"), + dataset.data.native, + dataset.noise_map.native, + dataset.psf.native, + dataset.grids.lp.over_sample_size.native, + dataset.grids.pixelization.over_sample_size.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + "psf", + "over_sample_size_lp", + "over_sample_size_pixelization", + ], + header_dict=dataset.mask.header_dict, + ) + + hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) + def fit_imaging( self, fit: FitImaging, diff --git a/autogalaxy/imaging/model/visualizer.py b/autogalaxy/imaging/model/visualizer.py index feb2b79b1..c6560c6cd 100644 --- a/autogalaxy/imaging/model/visualizer.py +++ b/autogalaxy/imaging/model/visualizer.py @@ -1,3 +1,5 @@ +from autoconf.fitsable import hdu_list_for_output_from + import autofit as af from autoarray import exc @@ -26,12 +28,14 @@ def visualize_before_fit( The model object, which includes model components representing the galaxies that are fitted to the imaging data. """ + + dataset = analysis.dataset plotter = PlotterInterfaceImaging( image_path=paths.image_path, title_prefix=analysis.title_prefix ) - plotter.imaging(dataset=analysis.dataset) + plotter.imaging(dataset=dataset) if analysis.adapt_images is not None: plotter.adapt_images(adapt_images=analysis.adapt_images) diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index a4c149b76..1dce6801f 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -210,8 +210,7 @@ def save_attributes(self, paths: af.DirectoryPaths): It outputs the following attributes of the dataset: - - The real space mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. - - The interferometer dataset as `dataset.fits` (data / noise-map / uv_wavelengths). + For this analysis, it uses the `AnalysisDataset` object's method to output the following: @@ -220,6 +219,11 @@ def save_attributes(self, paths: af.DirectoryPaths): - The Cosmology. - The adapt image's model image and galaxy images, as `adapt_images.fits`, if used. + The following .fits files are also output via the plotter interface: + + - The real space mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The interferometer dataset as `dataset.fits` (data / noise-map / uv_wavelengths). + It is common for these attributes to be loaded by many of the template aggregator functions given in the `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for the dataset, settings and other attributes necessary to perform the fit to be loaded via the pickle files @@ -233,20 +237,6 @@ def save_attributes(self, paths: af.DirectoryPaths): """ super().save_attributes(paths=paths) - paths.save_fits( - name="dataset", - fits=hdu_list_for_output_from( - values_list=[ - self.dataset.real_space_mask.astype("float"), - self.dataset.data.in_array, - self.dataset.noise_map.in_array, - self.dataset.uv_wavelengths, - ], - ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], - header_dict=self.dataset.real_space_mask.pixel_scale_header, - ), - ) - paths.save_json( "transformer_class", to_dict(self.dataset.transformer.__class__), "dataset" ) diff --git a/autogalaxy/interferometer/model/plotter_interface.py b/autogalaxy/interferometer/model/plotter_interface.py index c986a9cd6..839868df8 100644 --- a/autogalaxy/interferometer/model/plotter_interface.py +++ b/autogalaxy/interferometer/model/plotter_interface.py @@ -41,7 +41,7 @@ def fits_to_fits( + [image.native for image in fit.galaxy_model_image_dict.values()], ext_name_list=["mask"] + [f"galaxy_{i}" for i in range(len(fit.galaxy_model_image_dict.values()))], - header_dict=fit.dataset.real_space_mask.pixel_scale_header, + header_dict=fit.dataset.real_space_mask.header_dict, ) hdu_list.writeto(image_path / "model_galaxy_images.fits", overwrite=True) @@ -66,7 +66,7 @@ def fits_to_fits( "dirty_normalized_residual_map", "dirty_chi_squared_map", ], - header_dict=fit.dataset.real_space_mask.pixel_scale_header, + header_dict=fit.dataset.real_space_mask.header_dict, ) hdu_list.writeto(image_path / "fit_dirty_images.fits", overwrite=True) @@ -108,6 +108,19 @@ def should_plot(name): if should_plot("subplot_dataset"): dataset_plotter.subplot_dataset() + hdu_list = hdu_list_for_output_from( + values_list=[ + self.dataset.real_space_mask.astype("float"), + self.dataset.data.in_array, + self.dataset.noise_map.in_array, + self.dataset.uv_wavelengths, + ], + ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], + header_dict=self.dataset.real_space_mask.header_dict, + ) + + hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) + def fit_interferometer( self, fit: FitInterferometer, diff --git a/autogalaxy/quantity/model/analysis.py b/autogalaxy/quantity/model/analysis.py index 3882a0422..7b752071c 100644 --- a/autogalaxy/quantity/model/analysis.py +++ b/autogalaxy/quantity/model/analysis.py @@ -164,7 +164,7 @@ def save_attributes(self, paths: af.DirectoryPaths): "data", "noise_map", ], - header_dict=self.dataset.mask.pixel_scale_header, + header_dict=self.dataset.mask.header_dict, ), ) paths.save_json( diff --git a/test_autogalaxy/analysis/test_plotter_interface.py b/test_autogalaxy/analysis/test_plotter_interface.py index 0831d38bd..eb46ab122 100644 --- a/test_autogalaxy/analysis/test_plotter_interface.py +++ b/test_autogalaxy/analysis/test_plotter_interface.py @@ -81,3 +81,9 @@ def test__adapt_images( plot_path = path.join(plot_path) assert path.join(plot_path, "subplot_adapt_images.png") in plot_patch.paths + + image = ag.ndarray_via_fits_from( + file_path=path.join(plot_path, "adapt_images.fits"), hdu=0 + ) + + assert image.shape == (7, 7) diff --git a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py index 7a0f29856..95a949c3e 100644 --- a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py +++ b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py @@ -23,6 +23,11 @@ def test__imaging(imaging_7x7, include_2d_all, plot_path, plot_patch): assert path.join(plot_path, "subplot_dataset.png") in plot_patch.paths + image = ag.ndarray_via_fits_from( + file_path=path.join(plot_path, "dataset.fits"), hdu=0 + ) + + assert image.shape == (7, 7) def test__imaging_combined(imaging_7x7, plot_path, plot_patch): if path.exists(plot_path): diff --git a/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py b/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py index 92970265d..6bf737532 100644 --- a/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py +++ b/test_autogalaxy/interferometer/model/test_plotter_interface_interferometer.py @@ -22,6 +22,12 @@ def test__interferometer(interferometer_7, include_2d_all, plot_path, plot_patch assert path.join(plot_path, "subplot_dataset.png") in plot_patch.paths + image = ag.ndarray_via_fits_from( + file_path=path.join(plot_path, "dataset.fits"), hdu=0 + ) + + assert image.shape == (7, 7) + def test__fit_interferometer( interferometer_7, From 20cc2d0b02060cd25783186c38d55ca07c8abc76 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 16:44:33 +0000 Subject: [PATCH 21/28] quantitiy refactor --- autogalaxy/quantity/model/analysis.py | 25 +++--------- .../quantity/model/plotter_interface.py | 40 +++++++++++++++++++ autogalaxy/quantity/model/visualizer.py | 29 ++++++++++++++ .../model/test_plotter_interface_quantity.py | 26 ++++++++++-- 4 files changed, 98 insertions(+), 22 deletions(-) diff --git a/autogalaxy/quantity/model/analysis.py b/autogalaxy/quantity/model/analysis.py index 7b752071c..4c764957d 100644 --- a/autogalaxy/quantity/model/analysis.py +++ b/autogalaxy/quantity/model/analysis.py @@ -134,11 +134,13 @@ def save_attributes(self, paths: af.DirectoryPaths): For this analysis, it uses the `AnalysisDataset` object's method to output the following: - - The dataset's data. - - The dataset's noise-map. - The settings associated with the dataset. - The Cosmology. - - Its mask. + + The following .fits files are also output via the plotter interface: + + - The mask applied to the dataset, in the `PrimaryHDU` of `dataset.fits`. + - The imaging dataset as `dataset.fits` (data / noise-map / psf / over sampler / etc.). It is common for these attributes to be loaded by many of the template aggregator functions given in the `aggregator` modules. For example, when using the database tools to perform a fit, the default behaviour is for @@ -151,22 +153,7 @@ def save_attributes(self, paths: af.DirectoryPaths): The paths object which manages all paths, e.g. where the non-linear search outputs are stored, visualization, and the pickled objects used by the aggregator output by this function. """ - paths.save_fits( - name="dataset", - fits=hdu_list_for_output_from( - values_list=[ - self.dataset.mask.astype("float"), - self.dataset.data.native, - self.dataset.noise_map.native, - ], - ext_name_list=[ - "mask", - "data", - "noise_map", - ], - header_dict=self.dataset.mask.header_dict, - ), - ) + paths.save_json( name="cosmology", object_dict=to_dict(self.cosmology), diff --git a/autogalaxy/quantity/model/plotter_interface.py b/autogalaxy/quantity/model/plotter_interface.py index 98070b253..430f653f6 100644 --- a/autogalaxy/quantity/model/plotter_interface.py +++ b/autogalaxy/quantity/model/plotter_interface.py @@ -1,3 +1,6 @@ +from autoconf.fitsable import hdu_list_for_output_from + +from autogalaxy.quantity.dataset_quantity import DatasetQuantity from autogalaxy.quantity.fit_quantity import FitQuantity from autogalaxy.quantity.plot.fit_quantity_plotters import FitQuantityPlotter from autogalaxy.analysis.plotter_interface import PlotterInterface @@ -6,6 +9,42 @@ class PlotterInterfaceQuantity(PlotterInterface): + + def dataset_quantity(self, dataset : DatasetQuantity): + """ + Output visualization of an `Imaging` dataset, typically before a model-fit is performed. + + Images are output to the `image` folder of the `image_path`. When used with a non-linear search the `image_path` + is the output folder of the non-linear search. + + Visualization includes a subplot of the individual images of attributes of the dataset (e.g. the image, + noise map, PSF). + + The images output by the `PlotterInterface` are customized using the file `config/visualize/plots.yaml` under + the `dataset` and `imaging` headers. + + Parameters + ---------- + dataset + The imaging dataset which is visualized. + """ + hdu_list = hdu_list_for_output_from( + values_list=[ + dataset.mask.astype("float"), + dataset.data.native, + dataset.noise_map.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + ], + header_dict=dataset.mask.header_dict, + ) + + hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) + + def fit_quantity( self, fit: FitQuantity, @@ -49,3 +88,4 @@ def should_plot(name): if should_plot("subplot_fit"): fit_quantity_plotter.subplot_fit() + diff --git a/autogalaxy/quantity/model/visualizer.py b/autogalaxy/quantity/model/visualizer.py index 398139d77..da6a956db 100644 --- a/autogalaxy/quantity/model/visualizer.py +++ b/autogalaxy/quantity/model/visualizer.py @@ -6,6 +6,35 @@ class VisualizerQuantity(af.Visualizer): + + @staticmethod + def visualize_before_fit( + analysis, + paths: af.AbstractPaths, + model: af.AbstractPriorModel, + ): + """ + PyAutoFit calls this function immediately before the non-linear search begins. + + It visualizes objects which do not change throughout the model fit like the dataset. + + Parameters + ---------- + paths + The paths object which manages all paths, e.g. where the non-linear search outputs are stored, + visualization and the pickled objects used by the aggregator output by this function. + model + The model object, which includes model components representing the galaxies that are fitted to + the imaging data. + """ + dataset = analysis.dataset + + plotter = PlotterInterfaceQuantity( + image_path=paths.image_path, title_prefix=analysis.title_prefix + ) + + plotter.dataset_quantity(dataset=dataset) + @staticmethod def visualize( analysis, diff --git a/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py b/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py index 699581d7b..d9523e725 100644 --- a/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py +++ b/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py @@ -2,6 +2,8 @@ from os import path import pytest +import autogalaxy as ag + from autogalaxy.quantity.model.plotter_interface import PlotterInterfaceQuantity directory = path.dirname(path.abspath(__file__)) @@ -12,6 +14,26 @@ def make_plotter_interface_plotter_setup(): return path.join("{}".format(directory), "files") +def test__dataset( + dataset_quantity_7x7_array_2d, + include_2d_all, + plot_path, + plot_patch, +): + if path.exists(plot_path): + shutil.rmtree(plot_path) + + PlotterInterface = PlotterInterfaceQuantity(image_path=plot_path) + + PlotterInterface.dataset_quantity(dataset=dataset_quantity_7x7_array_2d) + + image = ag.ndarray_via_fits_from( + file_path=path.join(plot_path, "dataset.fits"), hdu=0 + ) + + assert image.shape == (7, 7) + + def test__fit_quantity( fit_quantity_7x7_array_2d, fit_quantity_7x7_vector_yx_2d, @@ -26,6 +48,4 @@ def test__fit_quantity( PlotterInterface.fit_quantity(fit=fit_quantity_7x7_array_2d) - plot_path = path.join(plot_path, "fit_quantity") - - assert path.join(plot_path, "subplot_fit.png") not in plot_patch.paths + assert path.join(plot_path, "subplot_fit.png") not in plot_patch.paths \ No newline at end of file From 157bdb684259025138ced92b09336041b9c64579 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 21 Mar 2025 16:46:24 +0000 Subject: [PATCH 22/28] ellispe --- autogalaxy/ellipse/model/analysis.py | 17 +---------------- autogalaxy/ellipse/model/plotter_interface.py | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/autogalaxy/ellipse/model/analysis.py b/autogalaxy/ellipse/model/analysis.py index 9e1879c28..068b730c4 100644 --- a/autogalaxy/ellipse/model/analysis.py +++ b/autogalaxy/ellipse/model/analysis.py @@ -184,22 +184,7 @@ def save_attributes(self, paths: af.DirectoryPaths): The paths object which manages all paths, e.g. where the non-linear search outputs are stored, visualization, and the pickled objects used by the aggregator output by this function. """ - paths.save_fits( - name="dataset", - fits=hdu_list_for_output_from( - values_list=[ - self.dataset.mask.astype("float"), - self.dataset.data.native, - self.dataset.noise_map.native, - ], - ext_name_list=[ - "mask", - "data", - "noise_map", - ], - header_dict=self.dataset.mask.header_dict, - ), - ) + pass def profile_log_likelihood_function( self, instance: af.ModelInstance, paths: Optional[af.DirectoryPaths] = None diff --git a/autogalaxy/ellipse/model/plotter_interface.py b/autogalaxy/ellipse/model/plotter_interface.py index e1432730c..275d00ab9 100644 --- a/autogalaxy/ellipse/model/plotter_interface.py +++ b/autogalaxy/ellipse/model/plotter_interface.py @@ -1,5 +1,6 @@ from typing import List -from os import path + +from autoconf.fitsable import hdu_list_for_output_from import autoarray as aa import autoarray.plot as aplt @@ -43,6 +44,22 @@ def should_plot(name): if should_plot("subplot_dataset"): dataset_plotter.subplot_dataset() + hdu_list = hdu_list_for_output_from( + values_list=[ + dataset.mask.astype("float"), + dataset.data.native, + dataset.noise_map.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + ], + header_dict=dataset.mask.header_dict, + ) + + hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) + def fit_ellipse( self, fit_list: List[FitEllipse], From f149cc938548336fe178a6c3198f07d3e22f9c4e Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 24 Mar 2025 18:21:47 +0000 Subject: [PATCH 23/28] fix imaging aggregator tests --- test_autogalaxy/aggregator/conftest.py | 5 +++++ .../aggregator/imaging/test_aggregator_fit_imaging.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/test_autogalaxy/aggregator/conftest.py b/test_autogalaxy/aggregator/conftest.py index 235737d62..3eaa2ee31 100644 --- a/test_autogalaxy/aggregator/conftest.py +++ b/test_autogalaxy/aggregator/conftest.py @@ -47,6 +47,11 @@ def aggregator_from(database_file, analysis, model, samples): search.paths = af.DirectoryPaths(path_prefix=database_file) search.fit(model=model, analysis=analysis) + analysis.visualize_before_fit( + paths=search.paths, + model=model + ) + database_file = path.join(conf.instance.output_path, f"{database_file}.sqlite") agg = af.Aggregator.from_database(filename=database_file) diff --git a/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py b/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py index a01eb8b3b..fc7b05fe7 100644 --- a/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py +++ b/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py @@ -30,6 +30,11 @@ def make_agg_7x7(samples, model, analysis_imaging_7x7): search.paths = af.DirectoryPaths(path_prefix=file_prefix) search.fit(model=model, analysis=analysis_imaging_7x7) + analysis_imaging_7x7.visualize_before_fit( + paths=search.paths, + model=model + ) + database_file = output_path / f"{file_prefix}.sqlite" agg = af.Aggregator.from_database(filename=database_file) From a49314f92a76940747a24cfbf834c94b51532121 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 24 Mar 2025 18:24:41 +0000 Subject: [PATCH 24/28] fixinterferometer --- .../interferometer/interferometer.py | 50 +++++++++---------- autogalaxy/analysis/plotter_interface.py | 19 ++++--- autogalaxy/ellipse/model/plotter_interface.py | 24 ++++----- autogalaxy/imaging/model/visualizer.py | 2 +- .../interferometer/model/plotter_interface.py | 16 +++--- .../quantity/model/plotter_interface.py | 29 +++++------ autogalaxy/quantity/model/visualizer.py | 7 ++- test_autogalaxy/aggregator/conftest.py | 5 +- .../imaging/test_aggregator_fit_imaging.py | 5 +- .../model/test_plotter_interface_imaging.py | 1 + .../model/test_plotter_interface_quantity.py | 2 +- 11 files changed, 74 insertions(+), 86 deletions(-) diff --git a/autogalaxy/aggregator/interferometer/interferometer.py b/autogalaxy/aggregator/interferometer/interferometer.py index ed9edcb48..1886ad250 100644 --- a/autogalaxy/aggregator/interferometer/interferometer.py +++ b/autogalaxy/aggregator/interferometer/interferometer.py @@ -43,9 +43,7 @@ def _interferometer_from( dataset_list = [] for fit in fit_list: - real_space_mask, header = agg_util.mask_header_pixel_scales_origin_from( - fit=fit - ) + real_space_mask, header = agg_util.mask_header_from(fit=fit) data = aa.Visibilities( visibilities=fit.value(name="dataset")[1].data.astype("float") @@ -73,38 +71,38 @@ def _interferometer_from( class InterferometerAgg: def __init__(self, aggregator: af.Aggregator): """ - Interfaces with an `PyAutoFit` aggregator object to create instances of `Interferometer` objects from the results - of a model-fit. + Interfaces with an `PyAutoFit` aggregator object to create instances of `Interferometer` objects from the results + of a model-fit. - The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following + The results of a model-fit can be loaded from hard-disk or stored in a sqlite database, including the following attributes of the fit: - - The interferometer visibilities data as a .fits file (`dataset.fits[hdu=1]`). - - The visibilities noise-map as a .fits file (`dataset.fits[hdu=2]`). - - The uv wavelengths as a .fits file (`dataset/uv_wavelengths.fits`). - - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). - - The settings of the `Interferometer` data structure used in the fit (`dataset/settings.json`). + - The interferometer visibilities data as a .fits file (`dataset.fits[hdu=1]`). + - The visibilities noise-map as a .fits file (`dataset.fits[hdu=2]`). + - The uv wavelengths as a .fits file (`dataset/uv_wavelengths.fits`). + - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). + - The settings of the `Interferometer` data structure used in the fit (`dataset/settings.json`). - The `aggregator` contains the path to each of these files, and they can be loaded individually. This class - can load them all at once and create an `Interferometer` object via the `_interferometer_from` method. + The `aggregator` contains the path to each of these files, and they can be loaded individually. This class + can load them all at once and create an `Interferometer` object via the `_interferometer_from` method. - This class's methods returns generators which create the instances of the `Interferometer` objects. This ensures - that large sets of results can be efficiently loaded from the hard-disk and do not require storing all - `Interferometer` instances in the memory at once. + This class's methods returns generators which create the instances of the `Interferometer` objects. This ensures + that large sets of results can be efficiently loaded from the hard-disk and do not require storing all + `Interferometer` instances in the memory at once. - For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which - creates instances of the corresponding 3 `Interferometer` objects. + For example, if the `aggregator` contains 3 model-fits, this class can be used to create a generator which + creates instances of the corresponding 3 `Interferometer` objects. - If multiple `Interferometer` objects were fitted simultaneously via analysis summing, the `fit.child_values()` - method is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of - `Interferometer` objects. + If multiple `Interferometer` objects were fitted simultaneously via analysis summing, the `fit.child_values()` + method is instead used to load lists of the data, noise-map, PSF and mask and combine them into a list of + `Interferometer` objects. - This can be done manually, but this object provides a more concise API. + This can be done manually, but this object provides a more concise API. - Parameters - ---------- - aggregator - A `PyAutoFit` aggregator object which can load the results of model-fits. + Parameters + ---------- + aggregator + A `PyAutoFit` aggregator object which can load the results of model-fits. """ self.aggregator = aggregator diff --git a/autogalaxy/analysis/plotter_interface.py b/autogalaxy/analysis/plotter_interface.py index bdf652f73..6839aa221 100644 --- a/autogalaxy/analysis/plotter_interface.py +++ b/autogalaxy/analysis/plotter_interface.py @@ -258,20 +258,19 @@ def should_plot(name): adapt_plotter.subplot_adapt_images( adapt_galaxy_name_image_dict=adapt_images.galaxy_image_dict ) - + values_list = [ adapt_images.galaxy_name_image_dict[name].native for name in adapt_images.galaxy_name_image_dict.keys() ] hdu_list = hdu_list_for_output_from( - values_list=[ - adapt_images.mask.astype("float"), - ] - + values_list, - ext_name_list=["mask"] - + list(adapt_images.galaxy_name_image_dict.keys()), - header_dict=adapt_images.mask.header_dict, - ) - + values_list=[ + adapt_images.mask.astype("float"), + ] + + values_list, + ext_name_list=["mask"] + list(adapt_images.galaxy_name_image_dict.keys()), + header_dict=adapt_images.mask.header_dict, + ) + hdu_list.writeto(self.image_path / "adapt_images.fits", overwrite=True) diff --git a/autogalaxy/ellipse/model/plotter_interface.py b/autogalaxy/ellipse/model/plotter_interface.py index 275d00ab9..1c6767eac 100644 --- a/autogalaxy/ellipse/model/plotter_interface.py +++ b/autogalaxy/ellipse/model/plotter_interface.py @@ -45,18 +45,18 @@ def should_plot(name): dataset_plotter.subplot_dataset() hdu_list = hdu_list_for_output_from( - values_list=[ - dataset.mask.astype("float"), - dataset.data.native, - dataset.noise_map.native, - ], - ext_name_list=[ - "mask", - "data", - "noise_map", - ], - header_dict=dataset.mask.header_dict, - ) + values_list=[ + dataset.mask.astype("float"), + dataset.data.native, + dataset.noise_map.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + ], + header_dict=dataset.mask.header_dict, + ) hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) diff --git a/autogalaxy/imaging/model/visualizer.py b/autogalaxy/imaging/model/visualizer.py index c6560c6cd..fc2cc0d93 100644 --- a/autogalaxy/imaging/model/visualizer.py +++ b/autogalaxy/imaging/model/visualizer.py @@ -28,7 +28,7 @@ def visualize_before_fit( The model object, which includes model components representing the galaxies that are fitted to the imaging data. """ - + dataset = analysis.dataset plotter = PlotterInterfaceImaging( diff --git a/autogalaxy/interferometer/model/plotter_interface.py b/autogalaxy/interferometer/model/plotter_interface.py index 839868df8..18130f1e6 100644 --- a/autogalaxy/interferometer/model/plotter_interface.py +++ b/autogalaxy/interferometer/model/plotter_interface.py @@ -109,14 +109,14 @@ def should_plot(name): dataset_plotter.subplot_dataset() hdu_list = hdu_list_for_output_from( - values_list=[ - self.dataset.real_space_mask.astype("float"), - self.dataset.data.in_array, - self.dataset.noise_map.in_array, - self.dataset.uv_wavelengths, - ], - ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], - header_dict=self.dataset.real_space_mask.header_dict, + values_list=[ + dataset.real_space_mask.astype("float"), + dataset.data.in_array, + dataset.noise_map.in_array, + dataset.uv_wavelengths, + ], + ext_name_list=["mask", "data", "noise_map", "uv_wavelengths"], + header_dict=dataset.real_space_mask.header_dict, ) hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) diff --git a/autogalaxy/quantity/model/plotter_interface.py b/autogalaxy/quantity/model/plotter_interface.py index 430f653f6..1d925b40c 100644 --- a/autogalaxy/quantity/model/plotter_interface.py +++ b/autogalaxy/quantity/model/plotter_interface.py @@ -9,8 +9,7 @@ class PlotterInterfaceQuantity(PlotterInterface): - - def dataset_quantity(self, dataset : DatasetQuantity): + def dataset_quantity(self, dataset: DatasetQuantity): """ Output visualization of an `Imaging` dataset, typically before a model-fit is performed. @@ -29,22 +28,21 @@ def dataset_quantity(self, dataset : DatasetQuantity): The imaging dataset which is visualized. """ hdu_list = hdu_list_for_output_from( - values_list=[ - dataset.mask.astype("float"), - dataset.data.native, - dataset.noise_map.native, - ], - ext_name_list=[ - "mask", - "data", - "noise_map", - ], - header_dict=dataset.mask.header_dict, - ) + values_list=[ + dataset.mask.astype("float"), + dataset.data.native, + dataset.noise_map.native, + ], + ext_name_list=[ + "mask", + "data", + "noise_map", + ], + header_dict=dataset.mask.header_dict, + ) hdu_list.writeto(self.image_path / "dataset.fits", overwrite=True) - def fit_quantity( self, fit: FitQuantity, @@ -88,4 +86,3 @@ def should_plot(name): if should_plot("subplot_fit"): fit_quantity_plotter.subplot_fit() - diff --git a/autogalaxy/quantity/model/visualizer.py b/autogalaxy/quantity/model/visualizer.py index da6a956db..30a5feeca 100644 --- a/autogalaxy/quantity/model/visualizer.py +++ b/autogalaxy/quantity/model/visualizer.py @@ -6,12 +6,11 @@ class VisualizerQuantity(af.Visualizer): - @staticmethod def visualize_before_fit( - analysis, - paths: af.AbstractPaths, - model: af.AbstractPriorModel, + analysis, + paths: af.AbstractPaths, + model: af.AbstractPriorModel, ): """ PyAutoFit calls this function immediately before the non-linear search begins. diff --git a/test_autogalaxy/aggregator/conftest.py b/test_autogalaxy/aggregator/conftest.py index 3eaa2ee31..6a125ca14 100644 --- a/test_autogalaxy/aggregator/conftest.py +++ b/test_autogalaxy/aggregator/conftest.py @@ -47,10 +47,7 @@ def aggregator_from(database_file, analysis, model, samples): search.paths = af.DirectoryPaths(path_prefix=database_file) search.fit(model=model, analysis=analysis) - analysis.visualize_before_fit( - paths=search.paths, - model=model - ) + analysis.visualize_before_fit(paths=search.paths, model=model) database_file = path.join(conf.instance.output_path, f"{database_file}.sqlite") diff --git a/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py b/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py index fc7b05fe7..216f9d105 100644 --- a/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py +++ b/test_autogalaxy/aggregator/imaging/test_aggregator_fit_imaging.py @@ -30,10 +30,7 @@ def make_agg_7x7(samples, model, analysis_imaging_7x7): search.paths = af.DirectoryPaths(path_prefix=file_prefix) search.fit(model=model, analysis=analysis_imaging_7x7) - analysis_imaging_7x7.visualize_before_fit( - paths=search.paths, - model=model - ) + analysis_imaging_7x7.visualize_before_fit(paths=search.paths, model=model) database_file = output_path / f"{file_prefix}.sqlite" diff --git a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py index 95a949c3e..0f86cd413 100644 --- a/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py +++ b/test_autogalaxy/imaging/model/test_plotter_interface_imaging.py @@ -29,6 +29,7 @@ def test__imaging(imaging_7x7, include_2d_all, plot_path, plot_patch): assert image.shape == (7, 7) + def test__imaging_combined(imaging_7x7, plot_path, plot_patch): if path.exists(plot_path): shutil.rmtree(plot_path) diff --git a/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py b/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py index d9523e725..96e3c5484 100644 --- a/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py +++ b/test_autogalaxy/quantity/model/test_plotter_interface_quantity.py @@ -48,4 +48,4 @@ def test__fit_quantity( PlotterInterface.fit_quantity(fit=fit_quantity_7x7_array_2d) - assert path.join(plot_path, "subplot_fit.png") not in plot_patch.paths \ No newline at end of file + assert path.join(plot_path, "subplot_fit.png") not in plot_patch.paths From b7edac88d24477f0dca2879b6712146a893c01f5 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 24 Mar 2025 18:26:36 +0000 Subject: [PATCH 25/28] fix aggregator ellipse --- test_autogalaxy/aggregator/ellipse/conftest.py | 2 ++ .../aggregator/ellipse/test_aggregator_fit_ellipse.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test_autogalaxy/aggregator/ellipse/conftest.py b/test_autogalaxy/aggregator/ellipse/conftest.py index 7e1a40e88..4df8107f6 100644 --- a/test_autogalaxy/aggregator/ellipse/conftest.py +++ b/test_autogalaxy/aggregator/ellipse/conftest.py @@ -47,6 +47,8 @@ def aggregator_from(database_file, analysis, model, samples): search.paths = af.DirectoryPaths(path_prefix=database_file) search.fit(model=model, analysis=analysis) + analysis.visualize_before_fit(paths=search.paths, model=model) + database_file = path.join(conf.instance.output_path, f"{database_file}.sqlite") agg = af.Aggregator.from_database(filename=database_file) diff --git a/test_autogalaxy/aggregator/ellipse/test_aggregator_fit_ellipse.py b/test_autogalaxy/aggregator/ellipse/test_aggregator_fit_ellipse.py index 0b09c76c5..d799bb446 100644 --- a/test_autogalaxy/aggregator/ellipse/test_aggregator_fit_ellipse.py +++ b/test_autogalaxy/aggregator/ellipse/test_aggregator_fit_ellipse.py @@ -30,6 +30,8 @@ def make_agg_7x7(samples, model, analysis_ellipse_7x7): search.paths = af.DirectoryPaths(path_prefix=file_prefix) search.fit(model=model, analysis=analysis_ellipse_7x7) + analysis_ellipse_7x7.visualize_before_fit(paths=search.paths, model=model) + database_file = output_path / f"{file_prefix}.sqlite" agg = af.Aggregator.from_database(filename=database_file) From 4726e756c759cde728dc4297c05ec810bb62e0a0 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 24 Mar 2025 18:49:01 +0000 Subject: [PATCH 26/28] fix adapt image test --- autogalaxy/analysis/plotter_interface.py | 2 +- test_autogalaxy/analysis/test_plotter_interface.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/autogalaxy/analysis/plotter_interface.py b/autogalaxy/analysis/plotter_interface.py index 6839aa221..a1de60d1b 100644 --- a/autogalaxy/analysis/plotter_interface.py +++ b/autogalaxy/analysis/plotter_interface.py @@ -256,7 +256,7 @@ def should_plot(name): if should_plot("subplot_adapt_images"): adapt_plotter.subplot_adapt_images( - adapt_galaxy_name_image_dict=adapt_images.galaxy_image_dict + adapt_galaxy_name_image_dict=adapt_images.galaxy_name_image_dict ) values_list = [ diff --git a/test_autogalaxy/analysis/test_plotter_interface.py b/test_autogalaxy/analysis/test_plotter_interface.py index eb46ab122..ef7e96878 100644 --- a/test_autogalaxy/analysis/test_plotter_interface.py +++ b/test_autogalaxy/analysis/test_plotter_interface.py @@ -71,7 +71,7 @@ def test__adapt_images( plotter_interface = PlotterInterface(image_path=plot_path) adapt_images = ag.AdaptImages( - galaxy_image_dict=adapt_galaxy_name_image_dict_7x7, + galaxy_name_image_dict=adapt_galaxy_name_image_dict_7x7, ) plotter_interface.adapt_images( From 677d1959413137650ce9fb21e7d7aa5b9142f2c2 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 24 Mar 2025 19:37:16 +0000 Subject: [PATCH 27/28] missing files --- .../quantity/files/array/output_test/data.fits | Bin 0 -> 5760 bytes .../files/array/output_test/noise_map.fits | Bin 0 -> 5760 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test_autogalaxy/quantity/files/array/output_test/data.fits create mode 100644 test_autogalaxy/quantity/files/array/output_test/noise_map.fits diff --git a/test_autogalaxy/quantity/files/array/output_test/data.fits b/test_autogalaxy/quantity/files/array/output_test/data.fits new file mode 100644 index 0000000000000000000000000000000000000000..4746fc2e7e4b3e40b51f14910fa208347773734d GIT binary patch literal 5760 zcmeH^v2MaJ6h$+3Wa!X=;cZN9fmGe9h89{`f`FO~sj3bx2@*r>%1H;L74n|=B24DaNU;qX#!9Z~3RV!$_Y`LU5pV#hu?XnIpxN#c<48Q;kzyJ)u01UtY I3|x?b4Zo6%rvLx| literal 0 HcmV?d00001 diff --git a/test_autogalaxy/quantity/files/array/output_test/noise_map.fits b/test_autogalaxy/quantity/files/array/output_test/noise_map.fits new file mode 100644 index 0000000000000000000000000000000000000000..9a8e8e0cb2789aba96d26ef925ebd3282922980c GIT binary patch literal 5760 zcmWIc^bPQFRZy^1zyd-P^c9lx^V0H*a*Gv8@)g`XLxL5GOA_-^5{pu>s0Ru;d4>dd zMqo8h*USWHUSd&EVx>Y#Vo9PxNo7GQc2f|devT2I!9Xrn_Zb7t%PY-IN-a{zPlK79 znVXtdoSC0jj4%X=1vbwRhj~Uw3W;Qb%>(Mg>OOMKGp3$-z{m)8c8tX4K0`eNVE9F= ztH%=QSCBG@c@b1I&p*i1-O~@N`wYl&AH+PY?jy@QS3egLLT6OzXb6mkz-S1JhQMeD zjE2BS2muFRZa(GVC7fzc2c T4S~@R7!85Z5Eu=C5flOd?mncG literal 0 HcmV?d00001 From 4d9af454a12a15e77d9afa12c8a44cc539c4f561 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Wed, 2 Apr 2025 15:47:36 +0100 Subject: [PATCH 28/28] aggregator uses enum --- autogalaxy/aggregator/agg_util.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/autogalaxy/aggregator/agg_util.py b/autogalaxy/aggregator/agg_util.py index aea2e695f..da3fa69e3 100644 --- a/autogalaxy/aggregator/agg_util.py +++ b/autogalaxy/aggregator/agg_util.py @@ -6,6 +6,8 @@ import autofit as af import autoarray as aa +from autoarray.mask.mask_2d import Mask2DKeys + from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages @@ -30,12 +32,12 @@ def mask_header_from(fit): header = aa.Header(header_sci_obj=fit.value(name="dataset")[0].header) pixel_scales = ( - header.header_sci_obj["PIXSCAY"], - header.header_sci_obj["PIXSCAX"], + header.header_sci_obj[Mask2DKeys.PIXSCAY.value], + header.header_sci_obj[Mask2DKeys.PIXSCAY.value], ) origin = ( - header.header_sci_obj["ORIGINY"], - header.header_sci_obj["ORIGINX"], + header.header_sci_obj[Mask2DKeys.ORIGINY.value], + header.header_sci_obj[Mask2DKeys.ORIGINX.value], ) mask = aa.Mask2D( mask=ndarray_via_hdu_from(fit.value(name="dataset")[0]),