diff --git a/autoarray/dataset/abstract/w_tilde.py b/autoarray/dataset/abstract/w_tilde.py index 760516b56..59f72147d 100644 --- a/autoarray/dataset/abstract/w_tilde.py +++ b/autoarray/dataset/abstract/w_tilde.py @@ -2,7 +2,7 @@ class AbstractWTilde: - def __init__(self, curvature_preload, noise_map_value): + def __init__(self, curvature_preload): """ Packages together all derived data quantities necessary to fit `data (e.g. `Imaging`, Interferometer`) using an ` Inversion` via the w_tilde formalism. @@ -16,20 +16,5 @@ def __init__(self, curvature_preload, noise_map_value): curvature_preload A matrix which uses the imaging's noise-map and PSF to preload as much of the computation of the curvature matrix as possible. - noise_map_value - The first value of the noise-map used to construct the curvature preload, which is used as a sanity - check when performing the inversion to ensure the preload corresponds to the data being fitted. """ self.curvature_preload = curvature_preload - self.noise_map_value = noise_map_value - - def check_noise_map(self, noise_map): - if noise_map[0] != self.noise_map_value: - raise exc.InversionException( - "The preloaded values of WTildeImaging are not consistent with the noise-map passed to them, thus " - "they cannot be used for the inversion." - "" - f"The value of the noise map is {noise_map[0]} whereas in WTildeImaging it is {self.noise_map_value}" - "" - "Update WTildeImaging or do not use the w_tilde formalism to perform the Inversion." - ) diff --git a/autoarray/dataset/imaging/dataset.py b/autoarray/dataset/imaging/dataset.py index 967054a49..1eef061fa 100644 --- a/autoarray/dataset/imaging/dataset.py +++ b/autoarray/dataset/imaging/dataset.py @@ -32,6 +32,7 @@ def __init__( disable_fft_pad: bool = True, use_normalized_psf: Optional[bool] = True, check_noise_map: bool = True, + w_tilde: Optional[WTildeImaging] = None, ): """ An imaging dataset, containing the image data, noise-map, PSF and associated quantities @@ -85,6 +86,10 @@ def __init__( the PSF kernel does not change the overall normalization of the image when it is convolved with it. check_noise_map If True, the noise-map is checked to ensure all values are above zero. + w_tilde + The w_tilde formalism of the linear algebra equations precomputes the convolution of every pair of masked + noise-map values given the PSF (see `inversion.inversion_util`). Pass the `WTildeImaging` object here to + enable this linear algebra formalism for pixelized reconstructions. """ self.disable_fft_pad = disable_fft_pad @@ -193,58 +198,7 @@ def __init__( psf=self.psf, ) - @cached_property - def w_tilde(self): - """ - The w_tilde formalism of the linear algebra equations precomputes the convolution of every pair of masked - noise-map values given the PSF (see `inversion.inversion_util`). - - The `WTilde` object stores these precomputed values in the imaging dataset ensuring they are only computed once - per analysis. - - This uses lazy allocation such that the calculation is only performed when the wtilde matrices are used, - ensuring efficient set up of the `Imaging` class. - - Returns - ------- - WTildeImaging - Precomputed values used for the w tilde formalism of linear algebra calculations. - """ - - logger.info("IMAGING - Computing W-Tilde... May take a moment.") - - try: - import numba - except ModuleNotFoundError: - raise exc.InversionException( - "Inversion w-tilde functionality (pixelized reconstructions) is " - "disabled if numba is not installed.\n\n" - "This is because the run-times without numba are too slow.\n\n" - "Please install numba, which is described at the following web page:\n\n" - "https://pyautolens.readthedocs.io/en/latest/installation/overview.html" - ) - - ( - curvature_preload, - indexes, - lengths, - ) = inversion_imaging_numba_util.w_tilde_curvature_preload_imaging_from( - noise_map_native=np.array(self.noise_map.native.array).astype("float64"), - kernel_native=np.array(self.psf.native.array).astype("float64"), - native_index_for_slim_index=np.array( - self.mask.derive_indexes.native_for_slim - ).astype("int"), - ) - - return WTildeImaging( - curvature_preload=curvature_preload, - indexes=indexes.astype("int"), - lengths=lengths.astype("int"), - noise_map_value=self.noise_map[0], - noise_map=self.noise_map, - psf=self.psf, - mask=self.mask, - ) + self.w_tilde = w_tilde @classmethod def from_fits( @@ -517,6 +471,69 @@ def apply_over_sampling( return dataset + def apply_w_tilde(self, disable_fft_pad: bool = False): + """ + The w_tilde formalism of the linear algebra equations precomputes the convolution of every pair of masked + noise-map values given the PSF (see `inversion.inversion_util`). + + The `WTilde` object stores these precomputed values in the imaging dataset ensuring they are only computed once + per analysis. + + This uses lazy allocation such that the calculation is only performed when the wtilde matrices are used, + ensuring efficient set up of the `Imaging` class. + + Returns + ------- + WTildeImaging + Precomputed values used for the w tilde formalism of linear algebra calculations. + """ + + logger.info("IMAGING - Computing W-Tilde... May take a moment.") + + try: + import numba + except ModuleNotFoundError: + raise exc.InversionException( + "Inversion w-tilde functionality (pixelized reconstructions) is " + "disabled if numba is not installed.\n\n" + "This is because the run-times without numba are too slow.\n\n" + "Please install numba, which is described at the following web page:\n\n" + "https://pyautolens.readthedocs.io/en/latest/installation/overview.html" + ) + + ( + curvature_preload, + indexes, + lengths, + ) = inversion_imaging_numba_util.w_tilde_curvature_preload_imaging_from( + noise_map_native=np.array(self.noise_map.native.array).astype("float64"), + kernel_native=np.array(self.psf.native.array).astype("float64"), + native_index_for_slim_index=np.array( + self.mask.derive_indexes.native_for_slim + ).astype("int"), + ) + + w_tilde = WTildeImaging( + curvature_preload=curvature_preload, + indexes=indexes.astype("int"), + lengths=lengths.astype("int"), + noise_map=self.noise_map, + psf=self.psf, + mask=self.mask, + ) + + return Imaging( + data=self.data, + noise_map=self.noise_map, + psf=self.psf, + noise_covariance_matrix=self.noise_covariance_matrix, + over_sample_size_lp=self.over_sample_size_lp, + over_sample_size_pixelization=self.over_sample_size_pixelization, + disable_fft_pad=disable_fft_pad, + check_noise_map=False, + w_tilde=w_tilde, + ) + def output_to_fits( self, data_path: Union[Path, str], diff --git a/autoarray/dataset/imaging/w_tilde.py b/autoarray/dataset/imaging/w_tilde.py index f8187d5ee..0dc181f1f 100644 --- a/autoarray/dataset/imaging/w_tilde.py +++ b/autoarray/dataset/imaging/w_tilde.py @@ -18,7 +18,6 @@ def __init__( noise_map: np.ndarray, psf: np.ndarray, mask: np.ndarray, - noise_map_value: float, ): """ Packages together all derived data quantities necessary to fit `Imaging` data using an ` Inversion` via the @@ -39,12 +38,9 @@ def __init__( lengths The lengths of how many indexes each curvature preload contains, again used to compute the curvature matrix efficienctly. - noise_map_value - The first value of the noise-map used to construct the curvature preload, which is used as a sanity - check when performing the inversion to ensure the preload corresponds to the data being fitted. """ super().__init__( - curvature_preload=curvature_preload, noise_map_value=noise_map_value + curvature_preload=curvature_preload, ) self.indexes = indexes diff --git a/autoarray/dataset/interferometer/dataset.py b/autoarray/dataset/interferometer/dataset.py index 3e37dc454..aa62fb3a2 100644 --- a/autoarray/dataset/interferometer/dataset.py +++ b/autoarray/dataset/interferometer/dataset.py @@ -1,6 +1,7 @@ import logging import numpy as np from pathlib import Path +from typing import Optional from autoconf import cached_property @@ -30,7 +31,7 @@ def __init__( real_space_mask: Mask2D, transformer_class=TransformerNUFFT, dft_preload_transform: bool = True, - preprocessing_directory=None, + w_tilde: Optional[WTildeInterferometer] = None, ): """ An interferometer dataset, containing the visibilities data, noise-map, real-space msk, Fourier transformer and @@ -97,11 +98,7 @@ def __init__( preload_transform=dft_preload_transform, ) - self.preprocessing_directory = ( - Path(preprocessing_directory) - if preprocessing_directory is not None - else None - ) + self.dft_preload_transform = dft_preload_transform self.grids = GridsDataset( mask=self.real_space_mask, @@ -109,6 +106,8 @@ def __init__( over_sample_size_pixelization=self.over_sample_size_pixelization, ) + self.w_tilde = w_tilde + @classmethod def from_fits( cls, @@ -149,28 +148,7 @@ def from_fits( dft_preload_transform=dft_preload_transform, ) - def w_tilde_preprocessing(self): - - from astropy.io import fits - - if self.preprocessing_directory.is_dir(): - filename = "{}/curvature_preload.fits".format(self.preprocessing_directory) - - if not self.preprocessing_directory.isfile(filename): - print("The file {} does not exist".format(filename)) - logger.info("INTERFEROMETER - Computing W-Tilde... May take a moment.") - - curvature_preload = inversion_interferometer_util.w_tilde_curvature_preload_interferometer_from( - noise_map_real=self.noise_map.real, - uv_wavelengths=self.uv_wavelengths, - shape_masked_pixels_2d=self.transformer.grid.mask.shape_native_masked_pixels, - grid_radians_2d=self.transformer.grid.mask.unmasked_grid_sub_1.in_radians.native, - ) - - fits.writeto(filename, data=curvature_preload) - - @cached_property - def w_tilde(self): + def apply_w_tilde(self): """ The w_tilde formalism of the linear algebra equations precomputes the Fourier Transform of all the visibilities given the `uv_wavelengths` (see `inversion.inversion_util`). @@ -226,12 +204,21 @@ def w_tilde(self): use_adjoint_scaling=True, ) - return WTildeInterferometer( + w_tilde = WTildeInterferometer( w_matrix=w_matrix, curvature_preload=curvature_preload, dirty_image=np.array(dirty_image.array), real_space_mask=self.real_space_mask, - noise_map_value=self.noise_map[0], + ) + + return Interferometer( + real_space_mask=self.real_space_mask, + data=self.data, + noise_map=self.noise_map, + uv_wavelengths=self.uv_wavelengths, + transformer_class=lambda uv_wavelengths, real_space_mask, preload_transform: self.transformer, + dft_preload_transform=self.dft_preload_transform, + w_tilde=w_tilde, ) @property diff --git a/autoarray/dataset/interferometer/w_tilde.py b/autoarray/dataset/interferometer/w_tilde.py index dbd27247d..5074d6d3b 100644 --- a/autoarray/dataset/interferometer/w_tilde.py +++ b/autoarray/dataset/interferometer/w_tilde.py @@ -11,7 +11,6 @@ def __init__( curvature_preload: np.ndarray, dirty_image: np.ndarray, real_space_mask: Mask2D, - noise_map_value: float, ): """ Packages together all derived data quantities necessary to fit `Interferometer` data using an ` Inversion` via @@ -35,12 +34,9 @@ def __init__( real_space_mask The 2D mask in real-space defining the area where the interferometer data's visibilities are observing a signal. - noise_map_value - The first value of the noise-map used to construct the curvature preload, which is used as a sanity - check when performing the inversion to ensure the preload corresponds to the data being fitted. """ super().__init__( - curvature_preload=curvature_preload, noise_map_value=noise_map_value + curvature_preload=curvature_preload, ) self.dirty_image = dirty_image diff --git a/autoarray/inversion/inversion/factory.py b/autoarray/inversion/inversion/factory.py index ae0a06172..ce04ca5db 100644 --- a/autoarray/inversion/inversion/factory.py +++ b/autoarray/inversion/inversion/factory.py @@ -107,23 +107,20 @@ def inversion_imaging_from( ------- An `Inversion` whose type is determined by the input `dataset` and `settings`. """ + + use_w_tilde = True + if all( isinstance(linear_obj, AbstractLinearObjFuncList) for linear_obj in linear_obj_list ): use_w_tilde = False - else: - use_w_tilde = settings.use_w_tilde - if not settings.use_w_tilde: - use_w_tilde = False - - if use_w_tilde: - w_tilde = dataset.w_tilde + if dataset.w_tilde is not None and use_w_tilde: return InversionImagingWTilde( dataset=dataset, - w_tilde=w_tilde, + w_tilde=dataset.w_tilde, linear_obj_list=linear_obj_list, settings=settings, xp=xp, @@ -179,30 +176,27 @@ def inversion_interferometer_from( ------- An `Inversion` whose type is determined by the input `dataset` and `settings`. """ - if any( + use_w_tilde = True + + if all( isinstance(linear_obj, AbstractLinearObjFuncList) for linear_obj in linear_obj_list ): use_w_tilde = False - else: - use_w_tilde = settings.use_w_tilde - - if not settings.use_linear_operators: - if use_w_tilde: - w_tilde = dataset.w_tilde - - return InversionInterferometerWTilde( - dataset=dataset, - w_tilde=w_tilde, - linear_obj_list=linear_obj_list, - settings=settings, - xp=xp, - ) - - else: - return InversionInterferometerMapping( - dataset=dataset, - linear_obj_list=linear_obj_list, - settings=settings, - xp=xp, - ) + + if dataset.w_tilde is not None and use_w_tilde: + + return InversionInterferometerWTilde( + dataset=dataset, + w_tilde=dataset.w_tilde, + linear_obj_list=linear_obj_list, + settings=settings, + xp=xp, + ) + + return InversionInterferometerMapping( + dataset=dataset, + linear_obj_list=linear_obj_list, + settings=settings, + xp=xp, + ) diff --git a/autoarray/inversion/inversion/imaging/w_tilde.py b/autoarray/inversion/inversion/imaging/w_tilde.py index a5400e299..67d42544c 100644 --- a/autoarray/inversion/inversion/imaging/w_tilde.py +++ b/autoarray/inversion/inversion/imaging/w_tilde.py @@ -62,11 +62,7 @@ def __init__( dataset=dataset, linear_obj_list=linear_obj_list, settings=settings, xp=xp ) - if self.settings.use_w_tilde: - self.w_tilde = w_tilde - self.w_tilde.check_noise_map(noise_map=dataset.noise_map) - else: - self.w_tilde = None + self.w_tilde = dataset.w_tilde @property def w_tilde_data(self): diff --git a/autoarray/inversion/inversion/interferometer/w_tilde.py b/autoarray/inversion/inversion/interferometer/w_tilde.py index 888241081..5270316bf 100644 --- a/autoarray/inversion/inversion/interferometer/w_tilde.py +++ b/autoarray/inversion/inversion/interferometer/w_tilde.py @@ -66,7 +66,6 @@ def __init__( ) self.w_tilde = w_tilde - self.w_tilde.check_noise_map(noise_map=dataset.noise_map) super().__init__( dataset=dataset, diff --git a/autoarray/inversion/inversion/settings.py b/autoarray/inversion/inversion/settings.py index 3deab4a6e..f81b839c7 100644 --- a/autoarray/inversion/inversion/settings.py +++ b/autoarray/inversion/inversion/settings.py @@ -10,7 +10,6 @@ class SettingsInversion: def __init__( self, - use_w_tilde: bool = False, use_positive_only_solver: Optional[bool] = None, positive_only_uses_p_initial: Optional[bool] = None, use_border_relocator: Optional[bool] = None, @@ -18,7 +17,6 @@ def __init__( no_regularization_add_to_curvature_diag_value: float = None, use_w_tilde_numpy: bool = False, use_source_loop: bool = False, - use_linear_operators: bool = False, image_mesh_min_mesh_pixels_per_pixel=None, image_mesh_min_mesh_number: int = 5, image_mesh_adapt_background_percent_threshold: float = None, @@ -33,10 +31,6 @@ def __init__( Parameters ---------- - use_w_tilde - Whether to use the w-tilde formalism to perform the inversion, which speeds up the construction of the - simultaneous linear equations (by bypassing the construction of a `mapping_matrix`) for many dataset - use cases. use_positive_only_solver Whether to use a positive-only linear system solver, which requires that every reconstructed value is positive but is computationally much slower than the default solver (which allows for positive and @@ -52,9 +46,6 @@ def __init__( which exploit sparsity to do the calculation normally in a more efficient way). use_source_loop Shhhh its a secret. - use_linear_operators - For an interferometer inversion, whether to use the linear operator solution to solve the linear system - or not (this input does nothing for dataset data). image_mesh_min_mesh_pixels_per_pixel If not None, the image-mesh must place this many mesh pixels per image pixels in the N highest weighted regions of the adapt data, or an `InversionException` is raised. This can be used to force the image-mesh @@ -75,12 +66,9 @@ def __init__( For an interferometer inversion using the linear operators method, sets the maximum number of iterations of the solver (this input does nothing for dataset data and other interferometer methods). """ - - self.use_w_tilde = use_w_tilde self._use_positive_only_solver = use_positive_only_solver self._positive_only_uses_p_initial = positive_only_uses_p_initial self._use_border_relocator = use_border_relocator - self.use_linear_operators = use_linear_operators self.force_edge_pixels_to_zeros = force_edge_pixels_to_zeros self._no_regularization_add_to_curvature_diag_value = ( no_regularization_add_to_curvature_diag_value diff --git a/autoarray/inversion/mock/mock_inversion_imaging.py b/autoarray/inversion/mock/mock_inversion_imaging.py index 673f33566..4418ba398 100644 --- a/autoarray/inversion/mock/mock_inversion_imaging.py +++ b/autoarray/inversion/mock/mock_inversion_imaging.py @@ -73,8 +73,7 @@ def data_linear_func_matrix_dict(self) -> Dict: class MockWTildeImaging: - def check_noise_map(self, noise_map): - pass + pass class MockInversionImagingWTilde(InversionImagingWTilde): diff --git a/autoarray/structures/arrays/kernel_2d.py b/autoarray/structures/arrays/kernel_2d.py index a097a9644..abc74dc3d 100644 --- a/autoarray/structures/arrays/kernel_2d.py +++ b/autoarray/structures/arrays/kernel_2d.py @@ -575,9 +575,9 @@ def mapping_matrix_native_from( # Scatter main mapping matrix into native cube if xp.__name__.startswith("jax"): - mapping_matrix_native = mapping_matrix_native.at[mask.slim_to_native_tuple].set( - mapping_matrix - ) + mapping_matrix_native = mapping_matrix_native.at[ + mask.slim_to_native_tuple + ].set(mapping_matrix) else: mapping_matrix_native[mask.slim_to_native_tuple] = mapping_matrix @@ -673,12 +673,16 @@ def convolved_image_from(self, image, blurring_image, jax_method="direct", xp=np # start with native image padded with zeros image_both_native = xp.zeros(image.mask.shape, dtype=image.dtype) - image_both_native = image_both_native.at[image.mask.slim_to_native_tuple].set(image.array) + image_both_native = image_both_native.at[image.mask.slim_to_native_tuple].set( + image.array + ) # add blurring contribution if provided if blurring_image is not None: - image_both_native = image_both_native.at[blurring_image.mask.slim_to_native_tuple].set(blurring_image.array) + image_both_native = image_both_native.at[ + blurring_image.mask.slim_to_native_tuple + ].set(blurring_image.array) else: warnings.warn( @@ -707,7 +711,8 @@ def convolved_image_from(self, image, blurring_image, jax_method="direct", xp=np ) blurred_image = Array2D( - values=blurred_image_native[image.mask.slim_to_native_tuple], mask=image.mask + values=blurred_image_native[image.mask.slim_to_native_tuple], + mask=image.mask, ) if self.fft_shape is None: @@ -987,7 +992,9 @@ def convolved_image_via_real_space_from( # add blurring contribution if provided if blurring_image is not None: - image_native = image_native.at[blurring_image.mask.slim_to_native_tuple].set(blurring_image.array) + image_native = image_native.at[ + blurring_image.mask.slim_to_native_tuple + ].set(blurring_image.array) else: warnings.warn( @@ -1114,7 +1121,9 @@ def convolved_image_via_real_space_np_from( # add blurring contribution if provided if blurring_image is not None: - image_native[blurring_image.mask.slim_to_native_tuple] = blurring_image.array + image_native[blurring_image.mask.slim_to_native_tuple] = ( + blurring_image.array + ) else: warnings.warn( diff --git a/test_autoarray/dataset/imaging/test_dataset.py b/test_autoarray/dataset/imaging/test_dataset.py index 98283298b..8aa6ea3c2 100644 --- a/test_autoarray/dataset/imaging/test_dataset.py +++ b/test_autoarray/dataset/imaging/test_dataset.py @@ -192,6 +192,9 @@ def test__apply_mask(imaging_7x7, mask_2d_7x7, psf_3x3): ) assert type(masked_imaging_7x7.psf) == aa.Kernel2D + + masked_imaging_7x7 = masked_imaging_7x7.apply_w_tilde() + assert masked_imaging_7x7.w_tilde.curvature_preload.shape == (35,) assert masked_imaging_7x7.w_tilde.indexes.shape == (35,) assert masked_imaging_7x7.w_tilde.lengths.shape == (9,) diff --git a/test_autoarray/inversion/inversion/imaging/test_imaging.py b/test_autoarray/inversion/inversion/imaging/test_imaging.py index 46bfe55ac..d4464545d 100644 --- a/test_autoarray/inversion/inversion/imaging/test_imaging.py +++ b/test_autoarray/inversion/inversion/imaging/test_imaging.py @@ -131,43 +131,3 @@ def test__curvature_matrix(rectangular_mapper_7x7_3x3): assert inversion.curvature_matrix[0, 0] - 10.0 > 0.0 assert inversion.curvature_matrix[3, 3] - 2.0 < 1.0e-12 - - -def test__w_tilde_checks_noise_map_and_raises_exception_if_preloads_dont_match_noise_map(): - matrix_shape = (9, 3) - - mask = aa.Mask2D( - mask=np.array([[True, True, True], [False, False, False], [True, True, True]]), - pixel_scales=1.0, - ) - - grid = aa.Grid2D.from_mask(mask=mask) - - w_tilde = WTildeImaging( - curvature_preload=None, - indexes=None, - lengths=None, - noise_map_value=2.0, - noise_map=None, - psf=None, - mask=mask, - ) - - with pytest.raises(exc.InversionException): - dataset = aa.DatasetInterface( - data=np.ones(9), - noise_map=np.ones(9), - psf=aa.m.MockPSF(matrix_shape), - ) - - # noinspection PyTypeChecker - InversionImagingWTilde( - dataset=dataset, - w_tilde=w_tilde, - linear_obj_list=[ - aa.m.MockMapper( - mapping_matrix=np.ones(matrix_shape), source_plane_data_grid=grid - ) - ], - settings=aa.SettingsInversion(use_w_tilde=True), - ) diff --git a/test_autoarray/inversion/inversion/interferometer/test_inversion_interferometer_util.py b/test_autoarray/inversion/inversion/interferometer/test_inversion_interferometer_util.py index 0167dd1df..dc0943e31 100644 --- a/test_autoarray/inversion/inversion/interferometer/test_inversion_interferometer_util.py +++ b/test_autoarray/inversion/inversion/interferometer/test_inversion_interferometer_util.py @@ -245,16 +245,18 @@ def test__identical_inversion_values_for_two_methods(): transformer_class=aa.TransformerDFT, ) + dataset_w_tilde = dataset.apply_w_tilde() + inversion_w_tilde = aa.Inversion( - dataset=dataset, + dataset=dataset_w_tilde, linear_obj_list=[mapper], - settings=aa.SettingsInversion(use_w_tilde=True, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), ) inversion_mapping_matrices = aa.Inversion( dataset=dataset, linear_obj_list=[mapper], - settings=aa.SettingsInversion(use_w_tilde=False, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), ) assert (inversion_w_tilde.data == inversion_mapping_matrices.data).all() @@ -344,19 +346,21 @@ def test__identical_inversion_source_and_image_loops(): transformer_class=aa.TransformerDFT, ) + dataset_w_tilde = dataset.apply_w_tilde() + inversion_image_loop = aa.Inversion( - dataset=dataset, + dataset=dataset_w_tilde, linear_obj_list=[mapper], settings=aa.SettingsInversion( - use_w_tilde=True, use_source_loop=False, use_positive_only_solver=True + use_source_loop=False, use_positive_only_solver=True ), ) inversion_source_loop = aa.Inversion( - dataset=dataset, + dataset=dataset_w_tilde, linear_obj_list=[mapper], settings=aa.SettingsInversion( - use_w_tilde=True, use_source_loop=True, use_positive_only_solver=True + use_source_loop=True, use_positive_only_solver=True ), ) diff --git a/test_autoarray/inversion/inversion/test_abstract.py b/test_autoarray/inversion/inversion/test_abstract.py index 5f1a918cf..3eb481731 100644 --- a/test_autoarray/inversion/inversion/test_abstract.py +++ b/test_autoarray/inversion/inversion/test_abstract.py @@ -146,16 +146,16 @@ def test__curvature_matrix__via_w_tilde__identical_to_mapping(): masked_dataset = dataset.apply_mask(mask=mask) + masked_dataset_w_tilde = masked_dataset.apply_w_tilde() + inversion_w_tilde = aa.Inversion( - dataset=masked_dataset, + dataset=masked_dataset_w_tilde, linear_obj_list=[mapper_0, mapper_1], - settings=aa.SettingsInversion(use_w_tilde=True), ) inversion_mapping = aa.Inversion( dataset=masked_dataset, linear_obj_list=[mapper_0, mapper_1], - settings=aa.SettingsInversion(use_w_tilde=False), ) assert inversion_w_tilde.curvature_matrix == pytest.approx( @@ -221,16 +221,16 @@ def test__curvature_matrix_via_w_tilde__includes_source_interpolation__identical masked_dataset = dataset.apply_mask(mask=mask) + masked_dataset_w_tilde = masked_dataset.apply_w_tilde() + inversion_w_tilde = aa.Inversion( - dataset=masked_dataset, + dataset=masked_dataset_w_tilde, linear_obj_list=[mapper_0, mapper_1], - settings=aa.SettingsInversion(use_w_tilde=True), ) inversion_mapping = aa.Inversion( dataset=masked_dataset, linear_obj_list=[mapper_0, mapper_1], - settings=aa.SettingsInversion(use_w_tilde=False), ) assert inversion_w_tilde.curvature_matrix == pytest.approx( diff --git a/test_autoarray/inversion/inversion/test_factory.py b/test_autoarray/inversion/inversion/test_factory.py index 78919b892..17ff24738 100644 --- a/test_autoarray/inversion/inversion/test_factory.py +++ b/test_autoarray/inversion/inversion/test_factory.py @@ -18,7 +18,6 @@ def test__inversion_imaging__via_linear_obj_func_list(masked_imaging_7x7_no_blur inversion = aa.Inversion( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj], - settings=aa.SettingsInversion(use_w_tilde=False), ) assert isinstance(inversion.linear_obj_list[0], aa.m.MockLinearObjFuncList) @@ -28,10 +27,11 @@ def test__inversion_imaging__via_linear_obj_func_list(masked_imaging_7x7_no_blur # Overwrites use_w_tilde to false. + masked_imaging_7x7_no_blur_w_tilde = masked_imaging_7x7_no_blur.apply_w_tilde() + inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[linear_obj], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.m.MockLinearObjFuncList) @@ -49,7 +49,6 @@ def test__inversion_imaging__via_linear_obj_func_list(masked_imaging_7x7_no_blur inversion = aa.Inversion( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj], - settings=aa.SettingsInversion(use_w_tilde=False), ) assert isinstance(inversion.linear_obj_list[0], aa.m.MockLinearObjFuncList) @@ -67,7 +66,6 @@ def test__inversion_imaging__via_mapper( inversion = aa.Inversion( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=False), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperRectangularUniform) @@ -80,10 +78,11 @@ def test__inversion_imaging__via_mapper( # ) assert inversion.mapped_reconstructed_image == pytest.approx(np.ones(9), 1.0e-4) + masked_imaging_7x7_no_blur_w_tilde = masked_imaging_7x7_no_blur.apply_w_tilde() + inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperRectangularUniform) @@ -96,7 +95,6 @@ def test__inversion_imaging__via_mapper( inversion = aa.Inversion( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[delaunay_mapper_9_3x3], - settings=aa.SettingsInversion(use_w_tilde=False), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperDelaunay) @@ -105,9 +103,8 @@ def test__inversion_imaging__via_mapper( assert inversion.mapped_reconstructed_image == pytest.approx(np.ones(9), 1.0e-4) inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[delaunay_mapper_9_3x3], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperDelaunay) @@ -130,10 +127,11 @@ def test__inversion_imaging__via_regularizations( mapper = copy.copy(delaunay_mapper_9_3x3) mapper.regularization = regularization_constant + masked_imaging_7x7_no_blur_w_tilde = masked_imaging_7x7_no_blur.apply_w_tilde() + inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[mapper], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperDelaunay) @@ -146,9 +144,8 @@ def test__inversion_imaging__via_regularizations( mapper.regularization = regularization_adaptive_brightness inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[mapper], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperDelaunay) @@ -166,9 +163,8 @@ def test__inversion_imaging__via_regularizations( mapper.regularization = regularization_constant inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[mapper], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperVoronoi) @@ -181,9 +177,8 @@ def test__inversion_imaging__via_regularizations( mapper.regularization = regularization_constant_split inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[mapper], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperVoronoi) @@ -200,7 +195,7 @@ def test__inversion_imaging__source_pixel_zeroed_indices( inversion = aa.Inversion( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=False, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), preloads=aa.Preloads( mapper_indices=range(0, 9), source_pixel_zeroed_indices=np.array([0]) ), @@ -231,7 +226,6 @@ def test__inversion_imaging__via_linear_obj_func_and_mapper( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj, rectangular_mapper_7x7_3x3], settings=aa.SettingsInversion( - use_w_tilde=False, no_regularization_add_to_curvature_diag_value=False, ), ) @@ -248,11 +242,12 @@ def test__inversion_imaging__via_linear_obj_func_and_mapper( assert inversion.reconstruction_dict[rectangular_mapper_7x7_3x3][0] < 1.0e-4 assert inversion.mapped_reconstructed_image == pytest.approx(np.ones(9), 1.0e-4) + masked_imaging_7x7_no_blur_w_tilde = masked_imaging_7x7_no_blur.apply_w_tilde() + inversion = aa.Inversion( - dataset=masked_imaging_7x7_no_blur, + dataset=masked_imaging_7x7_no_blur_w_tilde, linear_obj_list=[linear_obj, rectangular_mapper_7x7_3x3], settings=aa.SettingsInversion( - use_w_tilde=True, no_regularization_add_to_curvature_diag_value=False, ), ) @@ -285,7 +280,6 @@ def test__inversion_imaging__via_linear_obj_func_and_mapper__force_edge_pixels_t dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj, delaunay_mapper_9_3x3], settings=aa.SettingsInversion( - use_w_tilde=False, no_regularization_add_to_curvature_diag_value=False, force_edge_pixels_to_zeros=True, ), @@ -299,7 +293,6 @@ def test__inversion_imaging__via_linear_obj_func_and_mapper__force_edge_pixels_t dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj, delaunay_mapper_9_3x3], settings=aa.SettingsInversion( - use_w_tilde=False, use_positive_only_solver=True, no_regularization_add_to_curvature_diag_value=False, force_edge_pixels_to_zeros=True, @@ -319,16 +312,18 @@ def test__inversion_imaging__via_linear_obj_func_and_mapper__force_edge_pixels_t def test__inversion_imaging__compare_mapping_and_w_tilde_values( masked_imaging_7x7, delaunay_mapper_9_3x3 ): + + masked_imaging_7x7_w_tilde = masked_imaging_7x7.apply_w_tilde() + inversion_w_tilde = aa.Inversion( - dataset=masked_imaging_7x7, + dataset=masked_imaging_7x7_w_tilde, linear_obj_list=[delaunay_mapper_9_3x3], - settings=aa.SettingsInversion(use_w_tilde=True), ) inversion_mapping = aa.Inversion( dataset=masked_imaging_7x7, linear_obj_list=[delaunay_mapper_9_3x3], - settings=aa.SettingsInversion(use_w_tilde=False), + settings=aa.SettingsInversion(), ) assert inversion_w_tilde._curvature_matrix_mapper_diag == pytest.approx( @@ -366,7 +361,6 @@ def test__inversion_imaging__linear_obj_func_and_non_func_give_same_terms( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj, rectangular_mapper_7x7_3x3], settings=aa.SettingsInversion( - use_w_tilde=False, use_positive_only_solver=True, force_edge_pixels_to_zeros=False, ), @@ -382,7 +376,6 @@ def test__inversion_imaging__linear_obj_func_and_non_func_give_same_terms( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[rectangular_mapper_7x7_3x3], settings=aa.SettingsInversion( - use_w_tilde=False, use_positive_only_solver=True, force_edge_pixels_to_zeros=False, ), @@ -420,13 +413,15 @@ def test__inversion_imaging__linear_obj_func_with_w_tilde( inversion_mapping = aa.Inversion( dataset=masked_imaging_7x7, linear_obj_list=[linear_obj, rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=False, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), ) + masked_imaging_7x7_w_tilde = masked_imaging_7x7.apply_w_tilde() + inversion_w_tilde = aa.Inversion( - dataset=masked_imaging_7x7, + dataset=masked_imaging_7x7_w_tilde, linear_obj_list=[linear_obj, rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=True, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), ) assert inversion_mapping.data_vector == pytest.approx( @@ -462,11 +457,13 @@ def test__inversion_imaging__linear_obj_func_with_w_tilde( linear_obj_1, linear_obj_2, ], - settings=aa.SettingsInversion(use_w_tilde=False), + settings=aa.SettingsInversion(), ) + masked_imaging_7x7_w_tilde = masked_imaging_7x7.apply_w_tilde() + inversion_w_tilde = aa.Inversion( - dataset=masked_imaging_7x7, + dataset=masked_imaging_7x7_w_tilde, linear_obj_list=[ rectangular_mapper_7x7_3x3, linear_obj, @@ -474,7 +471,6 @@ def test__inversion_imaging__linear_obj_func_with_w_tilde( linear_obj_1, linear_obj_2, ], - settings=aa.SettingsInversion(use_w_tilde=True), ) assert inversion_mapping.data_vector == pytest.approx( @@ -493,7 +489,7 @@ def test__inversion_interferometer__via_mapper( inversion = aa.Inversion( dataset=interferometer_7_no_fft, linear_obj_list=[rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=False), + settings=aa.SettingsInversion(), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperRectangularUniform) @@ -508,7 +504,7 @@ def test__inversion_interferometer__via_mapper( inversion = aa.Inversion( dataset=interferometer_7_no_fft, linear_obj_list=[delaunay_mapper_9_3x3], - settings=aa.SettingsInversion(use_w_tilde=False), + settings=aa.SettingsInversion(), ) assert isinstance(inversion.linear_obj_list[0], aa.MapperDelaunay) @@ -606,7 +602,7 @@ def test__inversion_imaging__positive_only_solver(masked_imaging_7x7_no_blur): inversion = aa.Inversion( dataset=masked_imaging_7x7_no_blur, linear_obj_list=[linear_obj], - settings=aa.SettingsInversion(use_w_tilde=False, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), ) assert isinstance(inversion.linear_obj_list[0], aa.m.MockLinearObjFuncList) @@ -635,7 +631,7 @@ def test__data_linear_func_matrix_dict( inversion_mapping = aa.Inversion( dataset=masked_imaging_7x7, linear_obj_list=[linear_obj, rectangular_mapper_7x7_3x3], - settings=aa.SettingsInversion(use_w_tilde=False, use_positive_only_solver=True), + settings=aa.SettingsInversion(use_positive_only_solver=True), ) assert inversion_mapping.data_linear_func_matrix_dict[linear_obj][ diff --git a/test_autoarray/inversion/inversion/test_settings_dict.py b/test_autoarray/inversion/inversion/test_settings_dict.py index 21540bdd3..68db6465c 100644 --- a/test_autoarray/inversion/inversion/test_settings_dict.py +++ b/test_autoarray/inversion/inversion/test_settings_dict.py @@ -13,14 +13,12 @@ def make_settings_dict(): "class_path": "autoarray.inversion.inversion.settings.SettingsInversion", "type": "instance", "arguments": { - "use_w_tilde": True, "use_positive_only_solver": False, "positive_only_uses_p_initial": False, "force_edge_pixels_to_zeros": True, "no_regularization_add_to_curvature_diag_value": 1e-08, "use_w_tilde_numpy": False, "use_source_loop": False, - "use_linear_operators": False, "tolerance": 1e-08, "maxiter": 250, },