diff --git a/autoarray/__init__.py b/autoarray/__init__.py index bff30a659..2c2236cfb 100644 --- a/autoarray/__init__.py +++ b/autoarray/__init__.py @@ -1,5 +1,5 @@ from autoconf.dictable import register_parser -from autofit import conf +from autoconf import conf conf.instance.register(__file__) diff --git a/autoarray/dataset/imaging/dataset.py b/autoarray/dataset/imaging/dataset.py index 75e3c042d..f80fd988a 100644 --- a/autoarray/dataset/imaging/dataset.py +++ b/autoarray/dataset/imaging/dataset.py @@ -430,12 +430,12 @@ def apply_noise_scaling( """ if signal_to_noise_value is None: - noise_map = np.array(self.noise_map.native.array) + noise_map = self.noise_map.native noise_map[mask.array == False] = noise_value else: noise_map = np.where( mask == False, - np.median(self.data.native.array[mask.derive_mask.edge == False]) + np.median(self.data.native[mask.derive_mask.edge == False]) / signal_to_noise_value, self.noise_map.native.array, ) diff --git a/autoarray/dataset/interferometer/dataset.py b/autoarray/dataset/interferometer/dataset.py index 647d05852..7966ef74d 100644 --- a/autoarray/dataset/interferometer/dataset.py +++ b/autoarray/dataset/interferometer/dataset.py @@ -1,4 +1,3 @@ -from astropy.io import fits import logging import numpy as np from pathlib import Path @@ -148,6 +147,9 @@ def from_fits( ) def w_tilde_preprocessing(self): + + from astropy.io import fits + if self.preprocessing_directory.is_dir(): filename = "{}/curvature_preload.fits".format(self.preprocessing_directory) diff --git a/autoarray/dataset/plot/imaging_plotters.py b/autoarray/dataset/plot/imaging_plotters.py index 8fed6f601..0adcd6d11 100644 --- a/autoarray/dataset/plot/imaging_plotters.py +++ b/autoarray/dataset/plot/imaging_plotters.py @@ -14,9 +14,9 @@ def __init__( self, dataset: Imaging, get_visuals_2d: Callable, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `Imaging` objects using the matplotlib method `imshow()` and many other matplotlib @@ -231,9 +231,9 @@ class ImagingPlotter(Plotter): def __init__( self, dataset: Imaging, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `Imaging` objects using the matplotlib method `imshow()` and many other matplotlib diff --git a/autoarray/dataset/plot/interferometer_plotters.py b/autoarray/dataset/plot/interferometer_plotters.py index 944ba51bd..a50ef64b9 100644 --- a/autoarray/dataset/plot/interferometer_plotters.py +++ b/autoarray/dataset/plot/interferometer_plotters.py @@ -14,12 +14,12 @@ class InterferometerPlotter(Plotter): def __init__( self, dataset: Interferometer, - mat_plot_1d: MatPlot1D = MatPlot1D(), - visuals_1d: Visuals1D = Visuals1D(), - include_1d: Include1D = Include1D(), - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_1d: MatPlot1D = None, + visuals_1d: Visuals1D = None, + include_1d: Include1D = None, + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `Interferometer` objects using the matplotlib methods `plot()`, `scatter()` and diff --git a/autoarray/dataset/preprocess.py b/autoarray/dataset/preprocess.py index f4a7a1231..c113c16aa 100644 --- a/autoarray/dataset/preprocess.py +++ b/autoarray/dataset/preprocess.py @@ -1,5 +1,4 @@ import numpy as np -from scipy.stats import norm from autoarray import exc @@ -316,6 +315,7 @@ def background_noise_map_via_edges_from(image, no_edges): no_edges Number of edges used to estimate the background level. """ + from scipy.stats import norm from autoarray.structures.arrays.uniform_2d import Array2D diff --git a/autoarray/fit/fit_interferometer.py b/autoarray/fit/fit_interferometer.py index ee7a534d4..8ff3d3684 100644 --- a/autoarray/fit/fit_interferometer.py +++ b/autoarray/fit/fit_interferometer.py @@ -122,7 +122,7 @@ def noise_normalization(self) -> float: [Noise_Term] = sum(log(2*pi*[Noise]**2.0)) """ return fit_util.noise_normalization_complex_from( - noise_map=self.noise_map, + noise_map=self.noise_map.array, ) @property diff --git a/autoarray/fit/fit_util.py b/autoarray/fit/fit_util.py index 7da5cd310..190788efc 100644 --- a/autoarray/fit/fit_util.py +++ b/autoarray/fit/fit_util.py @@ -174,12 +174,8 @@ def noise_normalization_complex_from(*, noise_map: jnp.ndarray) -> float: noise_map The masked noise-map of the dataset. """ - noise_normalization_real = jnp.sum( - jnp.log(2 * jnp.pi * np.array(noise_map).real ** 2.0) - ) - noise_normalization_imag = jnp.sum( - jnp.log(2 * jnp.pi * np.array(noise_map).imag ** 2.0) - ) + noise_normalization_real = jnp.sum(jnp.log(2 * jnp.pi * noise_map.real**2.0)) + noise_normalization_imag = jnp.sum(jnp.log(2 * jnp.pi * noise_map.imag**2.0)) return noise_normalization_real + noise_normalization_imag diff --git a/autoarray/fit/mock/mock_fit_imaging.py b/autoarray/fit/mock/mock_fit_imaging.py index ff36797d5..4fa8253ff 100644 --- a/autoarray/fit/mock/mock_fit_imaging.py +++ b/autoarray/fit/mock/mock_fit_imaging.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional +from typing import Optional from autoarray.dataset.mock.mock_dataset import MockDataset from autoarray.dataset.dataset_model import DatasetModel diff --git a/autoarray/fit/plot/fit_imaging_plotters.py b/autoarray/fit/plot/fit_imaging_plotters.py index 1c0eb9e67..217e356d1 100644 --- a/autoarray/fit/plot/fit_imaging_plotters.py +++ b/autoarray/fit/plot/fit_imaging_plotters.py @@ -13,9 +13,9 @@ def __init__( self, fit, get_visuals_2d: Callable, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, residuals_symmetric_cmap: bool = True, ): """ @@ -242,9 +242,9 @@ class FitImagingPlotter(Plotter): def __init__( self, fit: FitImaging, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `FitImaging` objects using the matplotlib method `imshow()` and many other matplotlib diff --git a/autoarray/fit/plot/fit_interferometer_plotters.py b/autoarray/fit/plot/fit_interferometer_plotters.py index 5247d67e5..fa908e569 100644 --- a/autoarray/fit/plot/fit_interferometer_plotters.py +++ b/autoarray/fit/plot/fit_interferometer_plotters.py @@ -20,9 +20,9 @@ def __init__( mat_plot_1d: MatPlot1D, visuals_1d: Visuals1D, include_1d: Include1D, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, residuals_symmetric_cmap: bool = True, ): """ @@ -455,12 +455,12 @@ class FitInterferometerPlotter(Plotter): def __init__( self, fit: FitInterferometer, - mat_plot_1d: MatPlot1D = MatPlot1D(), - visuals_1d: Visuals1D = Visuals1D(), - include_1d: Include1D = Include1D(), - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_1d: MatPlot1D = None, + visuals_1d: Visuals1D = None, + include_1d: Include1D = None, + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `FitInterferometer` objects using the matplotlib method `imshow()` and many other diff --git a/autoarray/fit/plot/fit_vector_yx_plotters.py b/autoarray/fit/plot/fit_vector_yx_plotters.py index 3351cbaaf..466d5c8d9 100644 --- a/autoarray/fit/plot/fit_vector_yx_plotters.py +++ b/autoarray/fit/plot/fit_vector_yx_plotters.py @@ -14,9 +14,9 @@ def __init__( self, fit, get_visuals_2d: Callable, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `FitImaging` objects using the matplotlib method `imshow()` and many other matplotlib @@ -208,9 +208,9 @@ class FitImagingPlotter(Plotter): def __init__( self, fit: FitImaging, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `FitImaging` objects using the matplotlib method `imshow()` and many other matplotlib diff --git a/autoarray/geometry/geometry_2d.py b/autoarray/geometry/geometry_2d.py index 9eea7e9f2..fa5d4b24a 100644 --- a/autoarray/geometry/geometry_2d.py +++ b/autoarray/geometry/geometry_2d.py @@ -154,7 +154,7 @@ def pixel_coordinates_2d_from( A 2D (y,x) pixel-value coordinate. """ return geometry_util.pixel_coordinates_2d_from( - scaled_coordinates_2d=np.array(scaled_coordinates_2d), + scaled_coordinates_2d=scaled_coordinates_2d, shape_native=self.shape_native, pixel_scales=self.pixel_scales, origins=self.origin, @@ -184,7 +184,7 @@ def scaled_coordinates_2d_from( """ return geometry_util.scaled_coordinates_2d_from( - pixel_coordinates_2d=np.array(pixel_coordinates_2d), + pixel_coordinates_2d=pixel_coordinates_2d, shape_native=self.shape_native, pixel_scales=self.pixel_scales, origins=self.origin, @@ -235,7 +235,7 @@ def grid_pixels_2d_from(self, grid_scaled_2d: Grid2D) -> Grid2D: from autoarray.structures.grids.uniform_2d import Grid2D grid_pixels_2d = geometry_util.grid_pixels_2d_slim_from( - grid_scaled_2d_slim=np.array(grid_scaled_2d.array), + grid_scaled_2d_slim=grid_scaled_2d.array, shape_native=self.shape_native, pixel_scales=self.pixel_scales, origin=self.origin, @@ -261,7 +261,7 @@ def grid_pixel_centres_2d_from(self, grid_scaled_2d: Grid2D) -> Grid2D: from autoarray.structures.grids.uniform_2d import Grid2D grid_pixel_centres_1d = geometry_util.grid_pixel_centres_2d_slim_from( - grid_scaled_2d_slim=np.array(grid_scaled_2d), + grid_scaled_2d_slim=grid_scaled_2d, shape_native=self.shape_native, pixel_scales=self.pixel_scales, origin=self.origin, @@ -294,7 +294,7 @@ def grid_pixel_indexes_2d_from(self, grid_scaled_2d: Grid2D) -> Array2D: from autoarray.structures.arrays.uniform_2d import Array2D grid_pixel_indexes_2d = geometry_util.grid_pixel_indexes_2d_slim_from( - grid_scaled_2d_slim=np.array(grid_scaled_2d), + grid_scaled_2d_slim=grid_scaled_2d, shape_native=self.shape_native, pixel_scales=self.pixel_scales, origin=self.origin, @@ -320,7 +320,7 @@ def grid_scaled_2d_from(self, grid_pixels_2d: Grid2D) -> Grid2D: from autoarray.structures.grids.uniform_2d import Grid2D grid_scaled_1d = geometry_util.grid_scaled_2d_slim_from( - grid_pixels_2d_slim=np.array(grid_pixels_2d), + grid_pixels_2d_slim=grid_pixels_2d, shape_native=self.shape_native, pixel_scales=self.pixel_scales, origin=self.origin, diff --git a/autoarray/geometry/geometry_util.py b/autoarray/geometry/geometry_util.py index 16ee5c460..e0dc8bdcc 100644 --- a/autoarray/geometry/geometry_util.py +++ b/autoarray/geometry/geometry_util.py @@ -474,8 +474,8 @@ def grid_pixels_2d_slim_from( centres_scaled = central_scaled_coordinate_2d_from( shape_native=shape_native, pixel_scales=pixel_scales, origin=origin ) - centres_scaled = np.array(centres_scaled) - pixel_scales = np.array(pixel_scales) + centres_scaled = centres_scaled + pixel_scales = pixel_scales sign = np.array([-1, 1]) return (sign * grid_scaled_2d_slim / pixel_scales) + centres_scaled + 0.5 diff --git a/autoarray/inversion/inversion/abstract.py b/autoarray/inversion/inversion/abstract.py index b321cfdb2..48032ef97 100644 --- a/autoarray/inversion/inversion/abstract.py +++ b/autoarray/inversion/inversion/abstract.py @@ -1,17 +1,13 @@ import copy -import jax import jax.numpy as jnp import numpy as np -from scipy.linalg import block_diag -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import splu + from typing import Dict, List, Optional, Type, Union from autoconf import cached_property from autoarray.dataset.imaging.dataset import Imaging from autoarray.dataset.interferometer.dataset import Interferometer -from autoarray.inversion.inversion.mapper_valued import MapperValued from autoarray.inversion.inversion.dataset_interface import DatasetInterface from autoarray.inversion.linear_obj.linear_obj import LinearObj from autoarray.inversion.pixelization.mappers.abstract import AbstractMapper @@ -337,6 +333,8 @@ def regularization_matrix(self) -> Optional[np.ndarray]: If the `settings.force_edge_pixels_to_zeros` is `True`, the edge pixels of each mapper in the inversion are regularized so high their value is forced to zero. """ + from scipy.linalg import block_diag + return block_diag( *[linear_obj.regularization_matrix for linear_obj in self.linear_obj_list] ) @@ -703,6 +701,8 @@ def log_det_regularization_matrix_term(self) -> float: float The log determinant of the regularization matrix. """ + from scipy.sparse import csc_matrix + from scipy.sparse.linalg import splu if not self.has(cls=AbstractRegularization): return 0.0 diff --git a/autoarray/inversion/inversion/imaging/inversion_imaging_util.py b/autoarray/inversion/inversion/imaging/inversion_imaging_util.py index c01cde506..699361638 100644 --- a/autoarray/inversion/inversion/imaging/inversion_imaging_util.py +++ b/autoarray/inversion/inversion/imaging/inversion_imaging_util.py @@ -1,11 +1,7 @@ import numpy as np -from scipy.linalg import cho_solve -from typing import List, Optional, Tuple - -from autoarray.inversion.inversion.settings import SettingsInversion +from typing import Tuple from autoarray import numba_util -from autoarray import exc @numba_util.jit() diff --git a/autoarray/inversion/inversion/interferometer/inversion_interferometer_util.py b/autoarray/inversion/inversion/interferometer/inversion_interferometer_util.py index 1a3e647dc..6096f71bc 100644 --- a/autoarray/inversion/inversion/interferometer/inversion_interferometer_util.py +++ b/autoarray/inversion/inversion/interferometer/inversion_interferometer_util.py @@ -1,4 +1,3 @@ -from astropy.io import fits import logging import numpy as np import time @@ -791,6 +790,9 @@ def w_tilde_curvature_preload_interferometer_in_stages_with_chunks_from( check=True, directory=None, ) -> np.ndarray: + + from astropy.io import fits + if directory is None: raise NotImplementedError() diff --git a/autoarray/inversion/inversion/inversion_util.py b/autoarray/inversion/inversion/inversion_util.py index 29f1eaa07..e6f0d766f 100644 --- a/autoarray/inversion/inversion/inversion_util.py +++ b/autoarray/inversion/inversion/inversion_util.py @@ -1,10 +1,8 @@ import jax.numpy as jnp -import jaxnnls -import jax import jax.lax as lax import numpy as np -from typing import List, Optional, Tuple +from typing import List, Optional from autoconf import conf @@ -302,6 +300,7 @@ def reconstruction_positive_only_from( ------- Non-negative S that minimizes the Eq.(2) of https://arxiv.org/pdf/astro-ph/0302587.pdf. """ + import jaxnnls try: reconstruction = jaxnnls.solve_nnls_primal(curvature_reg_matrix, data_vector) diff --git a/autoarray/inversion/mock/mock_inversion.py b/autoarray/inversion/mock/mock_inversion.py index 1fb125861..053cb4a0e 100644 --- a/autoarray/inversion/mock/mock_inversion.py +++ b/autoarray/inversion/mock/mock_inversion.py @@ -29,13 +29,15 @@ def __init__( regularization_term=None, log_det_curvature_reg_matrix_term=None, log_det_regularization_matrix_term=None, - settings: SettingsInversion = SettingsInversion(), + settings: SettingsInversion = None, ): dataset = DatasetInterface( data=data, noise_map=noise_map, ) + settings = settings or SettingsInversion() + super().__init__( dataset=dataset, linear_obj_list=linear_obj_list or [], diff --git a/autoarray/inversion/mock/mock_inversion_imaging.py b/autoarray/inversion/mock/mock_inversion_imaging.py index 8a265fcf1..83e18356f 100644 --- a/autoarray/inversion/mock/mock_inversion_imaging.py +++ b/autoarray/inversion/mock/mock_inversion_imaging.py @@ -19,8 +19,11 @@ def __init__( operated_mapping_matrix=None, linear_func_operated_mapping_matrix_dict=None, data_linear_func_matrix_dict=None, - settings: SettingsInversion = SettingsInversion(), + settings: SettingsInversion = None, ): + + settings = settings or SettingsInversion() + dataset = DatasetInterface( data=data, noise_map=noise_map, @@ -85,7 +88,7 @@ def __init__( w_tilde=None, linear_obj_list=None, curvature_matrix_mapper_diag=None, - settings: SettingsInversion = SettingsInversion(), + settings: SettingsInversion = None, ): dataset = DatasetInterface( data=data, @@ -93,6 +96,8 @@ def __init__( psf=psf, ) + settings = settings or SettingsInversion() + super().__init__( dataset=dataset, w_tilde=w_tilde or MockWTildeImaging(), diff --git a/autoarray/inversion/mock/mock_inversion_interferometer.py b/autoarray/inversion/mock/mock_inversion_interferometer.py index 58de71520..a25ec03f9 100644 --- a/autoarray/inversion/mock/mock_inversion_interferometer.py +++ b/autoarray/inversion/mock/mock_inversion_interferometer.py @@ -15,7 +15,7 @@ def __init__( transformer=None, linear_obj_list=None, operated_mapping_matrix=None, - settings: SettingsInversion = SettingsInversion(), + settings: SettingsInversion = None, ): dataset = DatasetInterface( data=data, @@ -23,6 +23,8 @@ def __init__( transformer=transformer, ) + settings = settings or SettingsInversion() + super().__init__( dataset=dataset, linear_obj_list=linear_obj_list, diff --git a/autoarray/inversion/mock/mock_mesh.py b/autoarray/inversion/mock/mock_mesh.py index c8f7527a3..721c6a990 100644 --- a/autoarray/inversion/mock/mock_mesh.py +++ b/autoarray/inversion/mock/mock_mesh.py @@ -1,5 +1,5 @@ import numpy as np -from typing import Dict, Optional +from typing import Optional from autoarray.mask.mask_2d import Mask2D from autoarray.inversion.pixelization.mesh.abstract import AbstractMesh diff --git a/autoarray/inversion/mock/mock_pixelization.py b/autoarray/inversion/mock/mock_pixelization.py index 68a74141a..a71abebf7 100644 --- a/autoarray/inversion/mock/mock_pixelization.py +++ b/autoarray/inversion/mock/mock_pixelization.py @@ -1,5 +1,3 @@ -import numpy as np - from autoarray.mask.mask_2d import Mask2D from autoarray.inversion.pixelization.pixelization import Pixelization diff --git a/autoarray/inversion/pixelization/image_mesh/hilbert.py b/autoarray/inversion/pixelization/image_mesh/hilbert.py index 964457ded..119db098d 100644 --- a/autoarray/inversion/pixelization/image_mesh/hilbert.py +++ b/autoarray/inversion/pixelization/image_mesh/hilbert.py @@ -1,15 +1,13 @@ from __future__ import annotations import numpy as np -from scipy.interpolate import interp1d, griddata + from typing import Optional -from autoarray.mask.mask_2d import Mask2D from autoarray.structures.grids.uniform_2d import Grid2D from autoarray.mask.mask_2d import Mask2D from autoarray.inversion.pixelization.image_mesh.abstract_weighted import ( AbstractImageMeshWeighted, ) -from autoarray.operators.over_sampling.over_sampler import OverSampler from autoarray.inversion.inversion.settings import SettingsInversion from autoarray.structures.grids.irregular_2d import Grid2DIrregular @@ -125,6 +123,8 @@ def image_and_grid_from(image, mask, mask_radius, pixel_scales, hilbert_length): image associated to that grid. """ + from scipy.interpolate import griddata + # For multi wavelength fits the input image may be a different resolution than the mask. try: @@ -164,6 +164,7 @@ def inverse_transform_sampling_interpolated(probabilities, n_samples, gridx, gri probabilities: 1D normalized cumulative probablity curve. n_samples: the number of points to draw. """ + from scipy.interpolate import interp1d cdf = np.cumsum(probabilities) npixels = len(probabilities) diff --git a/autoarray/inversion/pixelization/image_mesh/kmeans.py b/autoarray/inversion/pixelization/image_mesh/kmeans.py index a7aa96536..55ecb99fc 100644 --- a/autoarray/inversion/pixelization/image_mesh/kmeans.py +++ b/autoarray/inversion/pixelization/image_mesh/kmeans.py @@ -1,5 +1,4 @@ import numpy as np -from sklearn.cluster import KMeans as ScipyKMeans from typing import Optional import sys import warnings @@ -97,6 +96,8 @@ def image_plane_mesh_grid_from( weight_map = self.weight_map_from(adapt_data=adapt_data) + from sklearn.cluster import KMeans as ScipyKMeans + kmeans = ScipyKMeans( n_clusters=int(self.pixels), random_state=1, @@ -104,7 +105,7 @@ def image_plane_mesh_grid_from( max_iter=5, ) - grid = mask.derive_grid.unmasked + grid = mask.derive_grid.unmasked.array try: kmeans = kmeans.fit(X=grid, sample_weight=weight_map) diff --git a/autoarray/inversion/pixelization/mappers/mapper_util.py b/autoarray/inversion/pixelization/mappers/mapper_util.py index 6f2d2ded3..75b91c042 100644 --- a/autoarray/inversion/pixelization/mappers/mapper_util.py +++ b/autoarray/inversion/pixelization/mappers/mapper_util.py @@ -1,6 +1,5 @@ import jax.numpy as jnp import numpy as np -from scipy.spatial import cKDTree from typing import Tuple from autoconf import conf @@ -275,6 +274,8 @@ def pix_indexes_for_sub_slim_index_delaunay_from( def nearest_pixelization_index_for_slim_index_from_kdtree(grid, mesh_grid): + from scipy.spatial import cKDTree + kdtree = cKDTree(mesh_grid) sparse_index_for_slim_index = [] diff --git a/autoarray/inversion/pixelization/mesh/mesh_util.py b/autoarray/inversion/pixelization/mesh/mesh_util.py index 305b56b72..ea1384349 100644 --- a/autoarray/inversion/pixelization/mesh/mesh_util.py +++ b/autoarray/inversion/pixelization/mesh/mesh_util.py @@ -1,5 +1,5 @@ import numpy as np -import scipy.spatial + from typing import List, Tuple, Union from autoarray import numba_util @@ -362,7 +362,7 @@ def delaunay_interpolated_array_from( shape_native: Tuple[int, int], interpolation_grid_slim: np.ndarray, pixel_values: np.ndarray, - delaunay: scipy.spatial.Delaunay, + delaunay: "scipy.spatial.Delaunay", ) -> np.ndarray: """ Given a Delaunay triangulation and 1D values at the node of each Delaunay pixel (e.g. the connecting points where @@ -513,7 +513,7 @@ def voronoi_edge_pixels_from(regions: np.ndarray, point_region: np.ndarray) -> L def voronoi_revised_from( - voronoi: scipy.spatial.Voronoi, + voronoi: "scipy.spatial.Voronoi", ) -> Union[List[Tuple], np.ndarray]: """ To plot a Voronoi mesh using the `matplotlib.fill()` function a revised Voronoi mesh must be @@ -592,7 +592,7 @@ def voronoi_nn_interpolated_array_from( shape_native: Tuple[int, int], interpolation_grid_slim: np.ndarray, pixel_values: np.ndarray, - voronoi: scipy.spatial.Voronoi, + voronoi: "scipy.spatial.Voronoi", ) -> np.ndarray: try: from autoarray.util.nn import nn_py diff --git a/autoarray/inversion/pixelization/pixelization.py b/autoarray/inversion/pixelization/pixelization.py index 4f6084168..b6b09f664 100644 --- a/autoarray/inversion/pixelization/pixelization.py +++ b/autoarray/inversion/pixelization/pixelization.py @@ -139,7 +139,6 @@ def __init__( # The example below shows how a `Pixelization` is used in modeling. - import autofit as af import autogalaxy as ag mesh = af.Model(ag.mesh.Rectangular) diff --git a/autoarray/inversion/plot/inversion_plotters.py b/autoarray/inversion/plot/inversion_plotters.py index 98cede938..755224913 100644 --- a/autoarray/inversion/plot/inversion_plotters.py +++ b/autoarray/inversion/plot/inversion_plotters.py @@ -18,9 +18,9 @@ class InversionPlotter(Plotter): def __init__( self, inversion: AbstractInversion, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, residuals_symmetric_cmap: bool = True, ): """ diff --git a/autoarray/inversion/plot/mapper_plotters.py b/autoarray/inversion/plot/mapper_plotters.py index 9fd6608d7..abd220f85 100644 --- a/autoarray/inversion/plot/mapper_plotters.py +++ b/autoarray/inversion/plot/mapper_plotters.py @@ -20,9 +20,9 @@ class MapperPlotter(Plotter): def __init__( self, mapper: MapperRectangular, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots the attributes of `Mapper` objects using the matplotlib method `imshow()` and many other matplotlib diff --git a/autoarray/mask/derive/grid_2d.py b/autoarray/mask/derive/grid_2d.py index 068e40a1b..702195a74 100644 --- a/autoarray/mask/derive/grid_2d.py +++ b/autoarray/mask/derive/grid_2d.py @@ -112,7 +112,7 @@ def all_false(self) -> Grid2D: origin=self.mask.origin, ) - return Grid2D(values=np.array(grid_slim), mask=self.mask.derive_mask.all_false) + return Grid2D(values=grid_slim, mask=self.mask.derive_mask.all_false) @property def unmasked(self) -> Grid2D: @@ -163,7 +163,7 @@ def unmasked(self) -> Grid2D: pixel_scales=self.mask.pixel_scales, origin=self.mask.origin, ) - return Grid2D(values=np.array(grid_2d), mask=self.mask) + return Grid2D(values=grid_2d, mask=self.mask) @property def edge(self) -> Grid2D: diff --git a/autoarray/mask/derive/indexes_2d.py b/autoarray/mask/derive/indexes_2d.py index 8a84f5a4f..de45fd4bb 100644 --- a/autoarray/mask/derive/indexes_2d.py +++ b/autoarray/mask/derive/indexes_2d.py @@ -112,7 +112,7 @@ def unmasked_slim(self) -> np.ndarray: print(derive_indexes_2d.unmasked_slim) """ return mask_2d_util.mask_slim_indexes_from( - mask_2d=np.array(self.mask), return_masked_indexes=False + mask_2d=self.mask, return_masked_indexes=False ).astype("int") @property @@ -154,7 +154,7 @@ def masked_slim(self) -> np.ndarray: print(derive_indexes_2d.masked_slim) """ return mask_2d_util.mask_slim_indexes_from( - mask_2d=np.array(self.mask), return_masked_indexes=True + mask_2d=self.mask, return_masked_indexes=True ).astype("int") @property @@ -202,7 +202,7 @@ def edge_slim(self) -> np.ndarray: print(derive_indexes_2d.edge_slim) """ return mask_2d_util.edge_1d_indexes_from( - mask_2d=np.array(self.mask).astype("bool") + mask_2d=self.mask.astype("bool") ).astype("int") @property @@ -304,7 +304,7 @@ def border_slim(self) -> np.ndarray: print(derive_indexes_2d.border_slim) """ return mask_2d_util.border_slim_indexes_from( - mask_2d=np.array(self.mask).astype("bool") + mask_2d=self.mask.astype("bool") ).astype("int") @property @@ -409,5 +409,5 @@ def native_for_slim(self) -> np.ndarray: print(derive_indexes_2d.native_for_slim) """ return mask_2d_util.native_index_for_slim_index_2d_from( - mask_2d=np.array(self.mask), + mask_2d=self.mask, ).astype("int") diff --git a/autoarray/mask/derive/mask_2d.py b/autoarray/mask/derive/mask_2d.py index 9332e273d..19e005362 100644 --- a/autoarray/mask/derive/mask_2d.py +++ b/autoarray/mask/derive/mask_2d.py @@ -204,7 +204,7 @@ def blurring_from(self, kernel_shape_native: Tuple[int, int]) -> Mask2D: raise exc.MaskException("psf_size of exterior region must be odd") blurring_mask = mask_2d_util.blurring_mask_2d_from( - mask_2d=np.array(self.mask), + mask_2d=self.mask, kernel_shape_native=kernel_shape_native, ) @@ -324,9 +324,9 @@ def edge_buffed(self) -> Mask2D: """ from autoarray.mask.mask_2d import Mask2D - edge_buffed_mask = mask_2d_util.buffed_mask_2d_from( - mask_2d=np.array(self.mask) - ).astype("bool") + edge_buffed_mask = mask_2d_util.buffed_mask_2d_from(mask_2d=self.mask).astype( + "bool" + ) return Mask2D( mask=edge_buffed_mask, diff --git a/autoarray/mask/mask_1d.py b/autoarray/mask/mask_1d.py index 77f79c01e..55d8d1f8c 100644 --- a/autoarray/mask/mask_1d.py +++ b/autoarray/mask/mask_1d.py @@ -153,8 +153,8 @@ def from_fits( """ return cls( - mask=np.array( - array_1d_util.numpy_array_1d_via_fits_from(file_path=file_path, hdu=hdu) + mask=array_1d_util.numpy_array_1d_via_fits_from( + file_path=file_path, hdu=hdu ), pixel_scales=pixel_scales, origin=origin, diff --git a/autoarray/mask/mask_1d_util.py b/autoarray/mask/mask_1d_util.py index cfc9e7dff..add58c823 100644 --- a/autoarray/mask/mask_1d_util.py +++ b/autoarray/mask/mask_1d_util.py @@ -34,5 +34,6 @@ def native_index_for_slim_index_1d_from( """ - native_index_for_slim_index_1d = jnp.flatnonzero(~mask_1d) - return native_index_for_slim_index_1d + if isinstance(mask_1d, np.ndarray): + return np.flatnonzero(~mask_1d) + return jnp.flatnonzero(~mask_1d) diff --git a/autoarray/mask/mask_2d.py b/autoarray/mask/mask_2d.py index b2891cd45..515b2b928 100644 --- a/autoarray/mask/mask_2d.py +++ b/autoarray/mask/mask_2d.py @@ -331,7 +331,7 @@ def circular( ) return cls( - mask=np.array(mask), + mask=mask, pixel_scales=pixel_scales, origin=origin, invert=invert, @@ -385,7 +385,7 @@ def circular_annular( ) return cls( - mask=np.array(mask), + mask=mask, pixel_scales=pixel_scales, origin=origin, invert=invert, @@ -442,7 +442,7 @@ def elliptical( ) return cls( - mask=np.array(mask), + mask=mask, pixel_scales=pixel_scales, origin=origin, invert=invert, @@ -512,7 +512,7 @@ def elliptical_annular( ) return cls( - mask=np.array(mask), + mask=mask, pixel_scales=pixel_scales, origin=origin, invert=invert, @@ -560,7 +560,7 @@ def from_pixel_coordinates( ) return cls( - mask=np.array(mask), + mask=mask, pixel_scales=pixel_scales, origin=origin, invert=invert, @@ -598,7 +598,7 @@ def from_fits( mask = np.invert(mask.astype("bool")) mask = Mask2D( - mask=np.array(mask), + mask=mask, pixel_scales=pixel_scales, origin=origin, ) @@ -680,7 +680,7 @@ def header_dict(self) -> Dict: @property def mask_centre(self) -> Tuple[float, float]: grid = grid_2d_util.grid_2d_slim_via_mask_from( - mask_2d=np.array(self), + mask_2d=self, pixel_scales=self.pixel_scales, origin=self.origin, ) @@ -697,7 +697,7 @@ def shape_native_masked_pixels(self) -> Tuple[int, int]: and 12 False entries going horizontally in the central regions of the mask, then shape_masked_pixels=(15,12). """ - where = np.array(np.where(np.invert(self.astype("bool")))) + where = np.where(np.invert(self.astype("bool"))) y0, x0 = np.amin(where, axis=1) y1, x1 = np.amax(where, axis=1) diff --git a/autoarray/mask/mask_2d_util.py b/autoarray/mask/mask_2d_util.py index 10a40b473..ff472527a 100644 --- a/autoarray/mask/mask_2d_util.py +++ b/autoarray/mask/mask_2d_util.py @@ -1,6 +1,5 @@ import numpy as np import jax.numpy as jnp -from scipy.ndimage import convolve from typing import Tuple import warnings @@ -51,6 +50,8 @@ def native_index_for_slim_index_2d_from( native_index_for_slim_index_2d = native_index_for_slim_index_2d_from(mask_2d=mask_2d) """ + if isinstance(mask_2d, np.ndarray): + return np.stack(np.nonzero(~mask_2d.astype(bool))).T return jnp.stack(jnp.nonzero(~mask_2d.astype(bool))).T @@ -497,6 +498,7 @@ def blurring_mask_2d_from( blurring_mask = blurring_from(mask=mask) """ + from scipy.ndimage import convolve # Get the distance from False values to edges y_distance, x_distance = min_false_distance_to_edge(mask_2d) diff --git a/autoarray/mock.py b/autoarray/mock.py index b3bc02c15..55e1431d5 100644 --- a/autoarray/mock.py +++ b/autoarray/mock.py @@ -19,6 +19,5 @@ from autoarray.operators.mock.mock_psf import MockPSF from autoarray.structures.mock.mock_grid import MockGrid2DMesh from autoarray.structures.mock.mock_grid import MockMeshGrid -from autoarray.structures.mock.mock_decorators import MockGridRadialMinimum from autoarray.structures.mock.mock_decorators import MockGrid1DLikeObj from autoarray.structures.mock.mock_decorators import MockGrid2DLikeObj diff --git a/autoarray/operators/contour.py b/autoarray/operators/contour.py index 52a510dfd..693b14378 100644 --- a/autoarray/operators/contour.py +++ b/autoarray/operators/contour.py @@ -1,9 +1,6 @@ from __future__ import annotations import numpy as np import jax.numpy as jnp -from skimage import measure -from scipy.spatial import ConvexHull -from scipy.spatial import QhullError from autoarray.structures.grids.irregular_2d import Grid2DIrregular @@ -56,6 +53,8 @@ def contour_array(self): def contour_list(self): # make sure to use base numpy to convert JAX array back to a normal array + from skimage import measure + if isinstance(self.contour_array, jnp.ndarray): contour_array = np.array(self.contour_array) else: @@ -86,6 +85,10 @@ def contour_list(self): def hull( self, ): + + from scipy.spatial import ConvexHull + from scipy.spatial import QhullError + if self.grid.shape[0] < 3: return None diff --git a/autoarray/operators/transformer.py b/autoarray/operators/transformer.py index ad861f0fb..d2d8d3d2d 100644 --- a/autoarray/operators/transformer.py +++ b/autoarray/operators/transformer.py @@ -1,4 +1,3 @@ -from astropy import units import copy import jax.numpy as jnp import numpy as np @@ -141,7 +140,7 @@ def visibilities_from(self, image: Array2D) -> Visibilities: else: visibilities = transformer_util.visibilities_from( image_1d=image.slim.array, - grid_radians=np.array(self.grid), + grid_radians=self.grid.array, uv_wavelengths=self.uv_wavelengths, ) @@ -171,7 +170,7 @@ def image_from( """ image_slim = transformer_util.image_direct_from( visibilities=visibilities.in_array, - grid_radians=np.array(self.grid.array), + grid_radians=self.grid.array, uv_wavelengths=self.uv_wavelengths, ) @@ -211,7 +210,7 @@ def transform_mapping_matrix(self, mapping_matrix: np.ndarray) -> np.ndarray: return transformer_util.transformed_mapping_matrix_from( mapping_matrix=mapping_matrix, - grid_radians=np.array(self.grid), + grid_radians=self.grid.array, uv_wavelengths=self.uv_wavelengths, ) @@ -262,6 +261,8 @@ def __init__(self, uv_wavelengths: np.ndarray, real_space_mask: Mask2D, **kwargs adjoint_scaling : float Scaling factor for adjoint operations to normalize reconstructed images. """ + from astropy import units + if isinstance(self, NUFFTPlaceholder): pynufft_exception() @@ -334,6 +335,8 @@ def initialize_plan(self, ratio: int = 2, interp_kernel: Tuple[int, int] = (6, 6 - The plan must be initialized before performing any NUFFT operations (e.g., forward or adjoint). - This method modifies the internal state of the NUFFT object by calling `self.plan(...)`. """ + from astropy import units + if not isinstance(ratio, int): ratio = int(ratio) diff --git a/autoarray/plot/abstract_plotters.py b/autoarray/plot/abstract_plotters.py index 07db07291..5752155f0 100644 --- a/autoarray/plot/abstract_plotters.py +++ b/autoarray/plot/abstract_plotters.py @@ -4,7 +4,6 @@ set_backend() -import matplotlib.pyplot as plt from typing import Optional, Tuple from autoarray.plot.visuals.one_d import Visuals1D @@ -27,13 +26,13 @@ def __init__( visuals_2d: Visuals2D = None, include_2d: Include2D = None, ): - self.visuals_1d = visuals_1d - self.include_1d = include_1d - self.mat_plot_1d = mat_plot_1d + self.visuals_1d = visuals_1d or Visuals1D() + self.include_1d = include_1d or Include1D() + self.mat_plot_1d = mat_plot_1d or MatPlot1D() - self.visuals_2d = visuals_2d - self.include_2d = include_2d - self.mat_plot_2d = mat_plot_2d + self.visuals_2d = visuals_2d or Visuals2D() + self.include_2d = include_2d or Include2D() + self.mat_plot_2d = mat_plot_2d or MatPlot2D() self.subplot_figsize = None @@ -112,6 +111,7 @@ def open_subplot_figure( If the figure is a subplot, the setup_figure function is omitted to ensure that each subplot does not create a \ new figure and so that it can be output using the *output.output_figure(structure=None)* function. """ + import matplotlib.pyplot as plt self.set_mat_plots_for_subplot( is_for_subplot=True, diff --git a/autoarray/plot/visuals/two_d.py b/autoarray/plot/visuals/two_d.py index e892a06a7..d385329dd 100644 --- a/autoarray/plot/visuals/two_d.py +++ b/autoarray/plot/visuals/two_d.py @@ -55,9 +55,7 @@ def plot_via_plotter(self, plotter, grid_indexes=None, mapper=None, geometry=Non ) if self.mask is not None: - plotter.mask_scatter.scatter_grid( - grid=np.array(self.mask.derive_grid.edge.array) - ) + plotter.mask_scatter.scatter_grid(grid=self.mask.derive_grid.edge.array) if self.border is not None: plotter.border_scatter.scatter_grid(grid=self.border.array) diff --git a/autoarray/plot/wrap/base/abstract.py b/autoarray/plot/wrap/base/abstract.py index 82ffd1fff..c246c1afa 100644 --- a/autoarray/plot/wrap/base/abstract.py +++ b/autoarray/plot/wrap/base/abstract.py @@ -1,5 +1,4 @@ import numpy as np -import matplotlib from autoconf import conf @@ -16,6 +15,8 @@ def set_backend(): It is also common for high perforamcne computers (HPCs) to not support visualization and raise an error when a graphical backend (e.g. TKAgg) is used. Setting the backend to `Agg` addresses this. """ + import matplotlib + backend = conf.get_matplotlib_backend() if backend not in "default": diff --git a/autoarray/plot/wrap/base/annotate.py b/autoarray/plot/wrap/base/annotate.py index 3ba0b60d9..e1f1e917f 100644 --- a/autoarray/plot/wrap/base/annotate.py +++ b/autoarray/plot/wrap/base/annotate.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt - from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -13,6 +11,9 @@ class Annotate(AbstractMatWrap): """ def set(self): + + import matplotlib.pyplot as plt + if "x" not in self.kwargs and "y" not in self.kwargs and "s" not in self.kwargs: return diff --git a/autoarray/plot/wrap/base/axis.py b/autoarray/plot/wrap/base/axis.py index 69d34d933..cd57c5d20 100644 --- a/autoarray/plot/wrap/base/axis.py +++ b/autoarray/plot/wrap/base/axis.py @@ -1,4 +1,3 @@ -import matplotlib.pyplot as plt import numpy as np from typing import List @@ -34,6 +33,7 @@ def set(self, extent: List[float] = None, grid=None): The extent of the figure which set the axis-limits on the figure the grid is plotted, following the format [xmin, xmax, ymin, ymax]. """ + import matplotlib.pyplot as plt config_dict = self.config_dict extent_dict = config_dict.get("extent") diff --git a/autoarray/plot/wrap/base/cmap.py b/autoarray/plot/wrap/base/cmap.py index 5dc2f514b..51144ba46 100644 --- a/autoarray/plot/wrap/base/cmap.py +++ b/autoarray/plot/wrap/base/cmap.py @@ -1,10 +1,7 @@ import copy import logging -from matplotlib.colors import LinearSegmentedColormap -import matplotlib.colors as colors import numpy as np -from autoconf import conf from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -60,6 +57,7 @@ def norm_from(self, array: np.ndarray, use_log10: bool = False) -> object: array The array of data which is to be plotted. """ + import matplotlib.colors as colors vmin = self.vmin_from(array=array, use_log10=use_log10) vmax = self.vmax_from(array=array, use_log10=use_log10) @@ -99,6 +97,8 @@ def norm_from(self, array: np.ndarray, use_log10: bool = False) -> object: @property def cmap(self): + from matplotlib.colors import LinearSegmentedColormap + if self.config_dict["cmap"] == "default": from autoarray.plot.wrap.segmentdata import segmentdata diff --git a/autoarray/plot/wrap/base/colorbar.py b/autoarray/plot/wrap/base/colorbar.py index 1c9a8c5d8..71a8a174e 100644 --- a/autoarray/plot/wrap/base/colorbar.py +++ b/autoarray/plot/wrap/base/colorbar.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt -import matplotlib.cm as cm import numpy as np from typing import List, Optional @@ -142,6 +140,7 @@ def set( """ Set the figure's colorbar, optionally overriding the tick labels and values with manual inputs. """ + import matplotlib.pyplot as plt tick_values = self.tick_values_from(norm=norm, use_log10=use_log10) tick_labels = self.tick_labels_from( @@ -183,6 +182,8 @@ def set_with_color_values( color_values The values of the pixels on the Voronoi mesh which are used to create the colorbar. """ + import matplotlib.pyplot as plt + import matplotlib.cm as cm mappable = cm.ScalarMappable(norm=norm, cmap=cmap) mappable.set_array(color_values) diff --git a/autoarray/plot/wrap/base/figure.py b/autoarray/plot/wrap/base/figure.py index 238264fd9..61a3347b6 100644 --- a/autoarray/plot/wrap/base/figure.py +++ b/autoarray/plot/wrap/base/figure.py @@ -1,6 +1,5 @@ from enum import Enum import gc -import matplotlib.pyplot as plt from typing import Union, Tuple from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -82,6 +81,8 @@ def open(self): """ Wraps the Matplotlib method 'plt.figure' for opening a figure. """ + import matplotlib.pyplot as plt + if not plt.fignum_exists(num=1): config_dict = self.config_dict config_dict.pop("aspect") @@ -93,5 +94,7 @@ def close(self): """ Wraps the Matplotlib method 'plt.close' for closing a figure. """ + import matplotlib.pyplot as plt + plt.close() gc.collect() diff --git a/autoarray/plot/wrap/base/label.py b/autoarray/plot/wrap/base/label.py index 377f9a6b9..a54d5c474 100644 --- a/autoarray/plot/wrap/base/label.py +++ b/autoarray/plot/wrap/base/label.py @@ -1,10 +1,6 @@ -import matplotlib.pyplot as plt from typing import Optional -from autoconf import conf - from autoarray.plot.wrap.base.abstract import AbstractMatWrap -from autoarray.plot.wrap.base.units import Units class AbstractLabel(AbstractMatWrap): @@ -48,6 +44,7 @@ def set( units The units of the image that is plotted which informs the appropriate y label text. """ + import matplotlib.pyplot as plt config_dict = self.config_dict @@ -77,6 +74,7 @@ def set( units The units of the image that is plotted which informs the appropriate x label text. """ + import matplotlib.pyplot as plt config_dict = self.config_dict diff --git a/autoarray/plot/wrap/base/legend.py b/autoarray/plot/wrap/base/legend.py index 04b64441b..09a6e9d4d 100644 --- a/autoarray/plot/wrap/base/legend.py +++ b/autoarray/plot/wrap/base/legend.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt - from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -19,6 +17,9 @@ def __init__(self, label=None, include=True, **kwargs): self.include = include def set(self): + + import matplotlib.pyplot as plt + if self.include: config_dict = self.config_dict config_dict.pop("include") if "include" in config_dict else None diff --git a/autoarray/plot/wrap/base/output.py b/autoarray/plot/wrap/base/output.py index 73a5f40e4..51fc78801 100644 --- a/autoarray/plot/wrap/base/output.py +++ b/autoarray/plot/wrap/base/output.py @@ -1,5 +1,4 @@ import logging -import matplotlib.pyplot as plt from os import path import os from typing import Union, List, Optional @@ -102,6 +101,9 @@ def filename_from(self, auto_filename): return filename def savefig(self, filename: str, output_path: str, format: str): + + import matplotlib.pyplot as plt + try: plt.savefig( path.join(output_path, f"{filename}.{format}"), @@ -130,6 +132,7 @@ def to_figure( auto_filename If the filename is not manually specified this name is used instead, which is defined in the parent plotter. """ + import matplotlib.pyplot as plt filename = self.filename_from(auto_filename=auto_filename) @@ -163,6 +166,7 @@ def subplot_to_figure(self, auto_filename: Optional[str] = None): auto_filename If the filename is not manually specified this name is used instead, which is defined in the parent plotter. """ + import matplotlib.pyplot as plt filename = self.filename_from(auto_filename=auto_filename) diff --git a/autoarray/plot/wrap/base/text.py b/autoarray/plot/wrap/base/text.py index 4dd94c0d6..4141bc0ac 100644 --- a/autoarray/plot/wrap/base/text.py +++ b/autoarray/plot/wrap/base/text.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt - from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -13,6 +11,9 @@ class Text(AbstractMatWrap): """ def set(self): + + import matplotlib.pyplot as plt + if "x" not in self.kwargs and "y" not in self.kwargs and "s" not in self.kwargs: return diff --git a/autoarray/plot/wrap/base/tickparams.py b/autoarray/plot/wrap/base/tickparams.py index ca96ad792..7369a29a0 100644 --- a/autoarray/plot/wrap/base/tickparams.py +++ b/autoarray/plot/wrap/base/tickparams.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt - from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -14,4 +12,7 @@ class TickParams(AbstractMatWrap): def set(self): """Set the tick_params of the figure using the method `plt.tick_params`.""" + + import matplotlib.pyplot as plt + plt.tick_params(**self.config_dict) diff --git a/autoarray/plot/wrap/base/ticks.py b/autoarray/plot/wrap/base/ticks.py index 95b376e8f..3b7c72e57 100644 --- a/autoarray/plot/wrap/base/ticks.py +++ b/autoarray/plot/wrap/base/ticks.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt -from matplotlib.ticker import FormatStrFormatter import numpy as np from typing import List, Tuple, Optional @@ -371,6 +369,8 @@ def set( units The units of the figure. """ + import matplotlib.pyplot as plt + from matplotlib.ticker import FormatStrFormatter if self.manual_min_max_value: min_value = self.manual_min_max_value[0] @@ -426,6 +426,8 @@ def set( units The units of the figure. """ + import matplotlib.pyplot as plt + from matplotlib.ticker import FormatStrFormatter if self.manual_min_max_value: min_value = self.manual_min_max_value[0] diff --git a/autoarray/plot/wrap/base/title.py b/autoarray/plot/wrap/base/title.py index 8185a7184..60aec1d30 100644 --- a/autoarray/plot/wrap/base/title.py +++ b/autoarray/plot/wrap/base/title.py @@ -1,5 +1,3 @@ -import matplotlib.pyplot as plt - from autoarray.plot.wrap.base.abstract import AbstractMatWrap @@ -29,6 +27,9 @@ def __init__(self, prefix: str = None, disable_log10_label: bool = False, **kwar self.manual_label = self.kwargs.get("label") def set(self, auto_title=None, use_log10: bool = False): + + import matplotlib.pyplot as plt + config_dict = self.config_dict label = auto_title if self.manual_label is None else self.manual_label diff --git a/autoarray/plot/wrap/one_d/avxline.py b/autoarray/plot/wrap/one_d/avxline.py index 496d644c7..7d36672d8 100644 --- a/autoarray/plot/wrap/one_d/avxline.py +++ b/autoarray/plot/wrap/one_d/avxline.py @@ -1,4 +1,3 @@ -import matplotlib.pyplot as plt from typing import List, Optional from autoarray.plot.wrap.one_d.abstract import AbstractMatWrap1D @@ -42,6 +41,7 @@ def axvline_vertical_line( label Labels for each vertical line used by a `Legend`. """ + import matplotlib.pyplot as plt if vertical_line is [] or vertical_line is None: return diff --git a/autoarray/plot/wrap/one_d/fill_between.py b/autoarray/plot/wrap/one_d/fill_between.py index 4f446252b..8a91b9a73 100644 --- a/autoarray/plot/wrap/one_d/fill_between.py +++ b/autoarray/plot/wrap/one_d/fill_between.py @@ -1,4 +1,3 @@ -import matplotlib.pyplot as plt import numpy as np from typing import List, Union @@ -44,6 +43,7 @@ def fill_between_shaded_regions( y1 The second line of ydata that defines the region that is filled in. """ + import matplotlib.pyplot as plt config_dict = self.config_dict diff --git a/autoarray/plot/wrap/one_d/yx_plot.py b/autoarray/plot/wrap/one_d/yx_plot.py index e31bd642c..d679b91e3 100644 --- a/autoarray/plot/wrap/one_d/yx_plot.py +++ b/autoarray/plot/wrap/one_d/yx_plot.py @@ -1,4 +1,3 @@ -import matplotlib.pyplot as plt import numpy as np from typing import Union @@ -51,6 +50,7 @@ def plot_y_vs_x( label Optionally include a label on the plot for a `Legend` to display. """ + import matplotlib.pyplot as plt if self.label is not None: label = self.label diff --git a/autoarray/plot/wrap/one_d/yx_scatter.py b/autoarray/plot/wrap/one_d/yx_scatter.py index ab77a0ea1..5e3c1d93a 100644 --- a/autoarray/plot/wrap/one_d/yx_scatter.py +++ b/autoarray/plot/wrap/one_d/yx_scatter.py @@ -1,4 +1,3 @@ -import matplotlib.pyplot as plt import numpy as np from typing import Union @@ -29,6 +28,7 @@ def scatter_yx(self, y: Union[np.ndarray, Grid1D], x: list): errors The error on every point of the grid that is plotted. """ + import matplotlib.pyplot as plt config_dict = self.config_dict diff --git a/autoarray/plot/wrap/two_d/grid_plot.py b/autoarray/plot/wrap/two_d/grid_plot.py index a727bec30..1f77fcf75 100644 --- a/autoarray/plot/wrap/two_d/grid_plot.py +++ b/autoarray/plot/wrap/two_d/grid_plot.py @@ -1,4 +1,3 @@ -import matplotlib.pyplot as plt import numpy as np import itertools from typing import List, Union, Tuple @@ -43,6 +42,7 @@ def plot_rectangular_grid_lines( shape_native The 2D shape of the mask the array is paired with. """ + import matplotlib.pyplot as plt ys = np.linspace(extent[2], extent[3], shape_native[1] + 1) xs = np.linspace(extent[0], extent[1], shape_native[0] + 1) @@ -66,6 +66,7 @@ def plot_grid(self, grid: Union[np.ndarray, Grid2D]): grid The grid of (y,x) coordinates that is plotted. """ + import matplotlib.pyplot as plt try: color = self.config_dict["c"] @@ -94,6 +95,7 @@ def plot_grid_list(self, grid_list: Union[List[Grid2D], List[Grid2DIrregular]]): grid_list The list of grids of (y,x) coordinates that are plotted. """ + import matplotlib.pyplot as plt if len(grid_list) == 0: return None @@ -113,6 +115,9 @@ def plot_grid_indexes_x1( grid: Union[np.ndarray, Grid2D, Grid2DIrregular], indexes: np.ndarray, ): + + import matplotlib.pyplot as plt + color = itertools.cycle(self.config_dict["c"]) config_dict = self.config_dict config_dict.pop("c") @@ -140,6 +145,8 @@ def plot_grid_indexes_multi( indexes: np.ndarray, geometry: Geometry2D, ): + import matplotlib.pyplot as plt + color = itertools.cycle(self.config_dict["c"]) config_dict = self.config_dict config_dict.pop("c") diff --git a/autoarray/plot/wrap/two_d/grid_scatter.py b/autoarray/plot/wrap/two_d/grid_scatter.py index 526aeffb9..1d2acae8d 100644 --- a/autoarray/plot/wrap/two_d/grid_scatter.py +++ b/autoarray/plot/wrap/two_d/grid_scatter.py @@ -1,15 +1,12 @@ import matplotlib.pyplot as plt -import jax.numpy as jnp import numpy as np import itertools -from scipy.spatial import ConvexHull from typing import List, Union from autoarray.plot.wrap.two_d.abstract import AbstractMatWrap2D from autoarray.structures.grids.uniform_2d import Grid2D from autoarray.structures.grids.irregular_2d import Grid2DIrregular -from autoarray.structures.mesh.abstract_2d import Abstract2DMesh class GridScatter(AbstractMatWrap2D): diff --git a/autoarray/preloads.py b/autoarray/preloads.py deleted file mode 100644 index 90c1deae9..000000000 --- a/autoarray/preloads.py +++ /dev/null @@ -1,554 +0,0 @@ -import logging -import numpy as np -import os -from typing import List - -from autoconf import conf - -from autoarray.inversion.linear_obj.func_list import AbstractLinearObjFuncList -from autoarray.inversion.pixelization.mappers.abstract import AbstractMapper - -from autoarray import exc -from autoarray.inversion.inversion.imaging import inversion_imaging_util - -logger = logging.getLogger(__name__) - -logger.setLevel(level="INFO") - - -class Preloads: - def __init__( - self, - w_tilde=None, - use_w_tilde=None, - image_plane_mesh_grid_pg_list=None, - relocated_grid=None, - mapper_list=None, - operated_mapping_matrix=None, - linear_func_operated_mapping_matrix_dict=None, - data_linear_func_matrix_dict=None, - mapper_operated_mapping_matrix_dict=None, - curvature_matrix=None, - data_vector_mapper=None, - curvature_matrix_mapper_diag=None, - regularization_matrix=None, - log_det_regularization_matrix_term=None, - traced_mesh_grids_list_of_planes=None, - image_plane_mesh_grid_list=None, - ): - self.w_tilde = w_tilde - self.use_w_tilde = use_w_tilde - - self.image_plane_mesh_grid_pg_list = image_plane_mesh_grid_pg_list - self.relocated_grid = relocated_grid - self.mapper_list = mapper_list - self.operated_mapping_matrix = operated_mapping_matrix - self.linear_func_operated_mapping_matrix_dict = ( - linear_func_operated_mapping_matrix_dict - ) - self.data_linear_func_matrix_dict = data_linear_func_matrix_dict - self.mapper_operated_mapping_matrix_dict = mapper_operated_mapping_matrix_dict - self.curvature_matrix = curvature_matrix - self.data_vector_mapper = data_vector_mapper - self.curvature_matrix_mapper_diag = curvature_matrix_mapper_diag - self.regularization_matrix = regularization_matrix - self.log_det_regularization_matrix_term = log_det_regularization_matrix_term - - self.traced_mesh_grids_list_of_planes = traced_mesh_grids_list_of_planes - self.image_plane_mesh_grid_list = image_plane_mesh_grid_list - - @property - def check_threshold(self): - return conf.instance["general"]["test"]["preloads_check_threshold"] - - def set_w_tilde_imaging(self, fit_0, fit_1): - """ - The w-tilde linear algebra formalism speeds up inversions by computing beforehand quantities that enable - efficiently construction of the curvature matrix. These quantities can only be used if the noise-map is - fixed, therefore this function preloads these w-tilde quantities if the noise-map does not change. - - This function compares the noise map of two fit's corresponding to two model instances, and preloads wtilde - if the noise maps of both fits are the same. - - The preload is typically used through search chaining pipelines, as it is uncommon for the noise map to be - scaled during the model-fit (although it is common for a fixed but scaled noise map to be used). - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - - self.w_tilde = None - self.use_w_tilde = False - - if fit_0.inversion is None: - return - - if not fit_0.inversion.has(cls=AbstractMapper): - return - - if np.max(abs(fit_0.noise_map - fit_1.noise_map)) < 1e-8: - logger.info("PRELOADS - Computing W-Tilde... May take a moment.") - - from autoarray.dataset.imaging.w_tilde import WTildeImaging - - ( - preload, - indexes, - lengths, - ) = inversion_imaging_util.w_tilde_curvature_preload_imaging_from( - noise_map_native=np.array(fit_0.noise_map.native), - kernel_native=np.array(fit_0.dataset.psf.native), - native_index_for_slim_index=np.array( - fit_0.dataset.mask.derive_indexes.native_for_slim - ), - ) - - self.w_tilde = WTildeImaging( - curvature_preload=preload, - indexes=indexes.astype("int"), - lengths=lengths.astype("int"), - noise_map_value=fit_0.noise_map[0], - ) - - self.use_w_tilde = True - - logger.info("PRELOADS - W-Tilde preloaded for this model-fit.") - - def set_relocated_grid(self, fit_0, fit_1): - """ - If the `MassProfile`'s in a model are fixed their traced grids (which may have had coordinates relocated at - the border) does not change during the model=fit and can therefore be preloaded. - - This function compares the relocated grids of the mappers of two fit corresponding to two model instances, and - preloads the grid if the grids of both fits are the same. - - The preload is typically used in adapt searches, where the mass model is fixed and the parameters are - varied. - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - - self.relocated_grid = None - - if fit_0.inversion is None: - return - - if ( - fit_0.inversion.total(cls=AbstractMapper) > 1 - or fit_0.inversion.total(cls=AbstractMapper) == 0 - ): - return - - mapper_0 = fit_0.inversion.cls_list_from(cls=AbstractMapper)[0] - mapper_1 = fit_1.inversion.cls_list_from(cls=AbstractMapper)[0] - - if ( - mapper_0.source_plane_data_grid.shape[0] - == mapper_1.source_plane_data_grid.shape[0] - ): - if ( - np.max( - abs( - mapper_0.source_plane_data_grid - - mapper_1.source_plane_data_grid - ) - ) - < 1.0e-8 - ): - self.relocated_grid = mapper_0.source_plane_data_grid - - logger.info( - "PRELOADS - Relocated grid of pxielization preloaded for this model-fit." - ) - - def set_mapper_list(self, fit_0, fit_1): - """ - If the `MassProfile`'s and `Mesh`'s in a model are fixed, the mapping of image-pixels to the - source-pixels does not change during the model-fit and the list of `Mapper`'s containing this information can - be preloaded. This includes preloading the `mapping_matrix`. - - This function compares the mapping matrix of two fit's corresponding to two model instances, and preloads the - list of mappers if the mapping matrix of both fits are the same. - - The preload is typically used in searches where only light profiles vary (e.g. when only the lens's light is - being fitted for). - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - - self.mapper_list = None - - if fit_0.inversion is None: - return - - if fit_0.inversion.total(cls=AbstractMapper) == 0: - return - - inversion_0 = fit_0.inversion - inversion_1 = fit_1.inversion - - if inversion_0.mapping_matrix.shape[1] == inversion_1.mapping_matrix.shape[1]: - if np.allclose(inversion_0.mapping_matrix, inversion_1.mapping_matrix): - self.mapper_list = inversion_0.cls_list_from(cls=AbstractMapper) - - logger.info( - "PRELOADS - Mappers of planes preloaded for this model-fit." - ) - - def set_operated_mapping_matrix_with_preloads(self, fit_0, fit_1): - """ - If the `MassProfile`'s and `Mesh`'s in a model are fixed, the mapping of image-pixels to the - source-pixels does not change during the model-fit and matrices used to perform the linear algebra in an - inversion can be preloaded, which help efficiently construct the curvature matrix. - - This function compares the operated mapping matrix of two fit's corresponding to two model instances, and - preloads the mapper if the mapping matrix of both fits are the same. - - The preload is typically used in searches where only light profiles vary (e.g. when only the lens's light is - being fitted for). - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - - self.operated_mapping_matrix = None - - inversion_0 = fit_0.inversion - inversion_1 = fit_1.inversion - - if inversion_0 is None: - return - - if ( - inversion_0.operated_mapping_matrix.shape[1] - == inversion_1.operated_mapping_matrix.shape[1] - ): - if ( - np.max( - abs( - inversion_0.operated_mapping_matrix - - inversion_1.operated_mapping_matrix - ) - ) - < 1e-8 - ): - self.operated_mapping_matrix = inversion_0.operated_mapping_matrix - - logger.info( - "PRELOADS - Inversion linear algebra quantities preloaded for this model-fit." - ) - - def set_linear_func_inversion_dicts(self, fit_0, fit_1): - """ - If the `MassProfile`'s and `Mesh`'s in a model are fixed, the mapping of image-pixels to the - source-pixels does not change during the model-fit and matrices used to perform the linear algebra in an - inversion can be preloaded, which help efficiently construct the curvature matrix. - - This function compares the operated mapping matrix of two fit's corresponding to two model instances, and - preloads the mapper if the mapping matrix of both fits are the same. - - The preload is typically used in searches where only light profiles vary (e.g. when only the lens's light is - being fitted for). - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - - from autoarray.inversion.pixelization.pixelization import Pixelization - - self.linear_func_operated_mapping_matrix_dict = None - - inversion_0 = fit_0.inversion - inversion_1 = fit_1.inversion - - if inversion_0 is None: - return - - if not inversion_0.has(cls=AbstractMapper): - return - - if not inversion_0.has(cls=AbstractLinearObjFuncList): - return - - try: - inversion_0.linear_func_operated_mapping_matrix_dict - except NotImplementedError: - return - - if not hasattr(inversion_0, "linear_func_operated_mapping_matrix_dict"): - return - - should_preload = False - - for operated_mapping_matrix_0, operated_mapping_matrix_1 in zip( - inversion_0.linear_func_operated_mapping_matrix_dict.values(), - inversion_1.linear_func_operated_mapping_matrix_dict.values(), - ): - if ( - np.max(abs(operated_mapping_matrix_0 - operated_mapping_matrix_1)) - < 1e-8 - ): - should_preload = True - else: - should_preload = False - break - - if should_preload: - self.linear_func_operated_mapping_matrix_dict = ( - inversion_0.linear_func_operated_mapping_matrix_dict - ) - self.data_linear_func_matrix_dict = inversion_0.data_linear_func_matrix_dict - - logger.info( - "PRELOADS - Inversion linear light profile operated mapping matrix / data linear func matrix preloaded for this model-fit." - ) - - def set_curvature_matrix(self, fit_0, fit_1): - """ - If the `MassProfile`'s and `Mesh`'s in a model are fixed, the mapping of image-pixels to the - source-pixels does not change during the model-fit and therefore its associated curvature matrix is also - fixed, meaning the curvature matrix preloaded. - - If linear ``LightProfiles``'s are included, the regions of the curvature matrix associatd with these - objects vary but the diagonals of the mapper do not change. In this case, the `curvature_matrix_mapper_diag` - is preloaded. - - This function compares the curvature matrix of two fit's corresponding to two model instances, and preloads - this value if it is the same for both fits. - - The preload is typically used in **PyAutoGalaxy** inversions using a `Rectangular` pixelization. - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - - self.curvature_matrix = None - self.data_vector_mapper = None - self.curvature_matrix_mapper_diag = None - self.mapper_operated_mapping_matrix_dict = None - - inversion_0 = fit_0.inversion - inversion_1 = fit_1.inversion - - if inversion_0 is None: - return - - try: - inversion_0._curvature_matrix_mapper_diag - except NotImplementedError: - return - - if inversion_0.curvature_matrix.shape == inversion_1.curvature_matrix.shape: - if ( - np.max(abs(inversion_0.curvature_matrix - inversion_1.curvature_matrix)) - < 1e-8 - ): - self.curvature_matrix = inversion_0.curvature_matrix - - logger.info( - "PRELOADS - Inversion Curvature Matrix preloaded for this model-fit." - ) - - return - - if inversion_0._curvature_matrix_mapper_diag is not None: - if ( - np.max( - abs( - inversion_0._curvature_matrix_mapper_diag - - inversion_1._curvature_matrix_mapper_diag - ) - ) - < 1e-8 - ): - self.mapper_operated_mapping_matrix_dict = ( - inversion_0.mapper_operated_mapping_matrix_dict - ) - self.data_vector_mapper = inversion_0._data_vector_mapper - self.curvature_matrix_mapper_diag = ( - inversion_0._curvature_matrix_mapper_diag - ) - - logger.info( - "PRELOADS - Inversion Curvature Matrix Mapper Diag preloaded for this model-fit." - ) - - def set_regularization_matrix_and_term(self, fit_0, fit_1): - """ - If the `MassProfile`'s and `Mesh`'s in a model are fixed, the mapping of image-pixels to the - source-pixels does not change during the model-fit and therefore its associated regularization matrices are - also fixed, meaning the log determinant of the regularization matrix term of the Bayesian evidence can be - preloaded. - - This function compares the value of the log determinant of the regularization matrix of two fit's corresponding - to two model instances, and preloads this value if it is the same for both fits. - - The preload is typically used in searches where only light profiles vary (e.g. when only the lens's light is - being fitted for). - - Parameters - ---------- - fit_0 - The first fit corresponding to a model with a specific set of unit-values. - fit_1 - The second fit corresponding to a model with a different set of unit-values. - """ - self.regularization_matrix = None - self.log_det_regularization_matrix_term = None - - inversion_0 = fit_0.inversion - inversion_1 = fit_1.inversion - - if inversion_0 is None: - return - - if inversion_0.total(cls=AbstractMapper) == 0: - return - - if ( - abs( - inversion_0.log_det_regularization_matrix_term - - inversion_1.log_det_regularization_matrix_term - ) - < 1e-8 - ): - self.regularization_matrix = inversion_0.regularization_matrix - self.log_det_regularization_matrix_term = ( - inversion_0.log_det_regularization_matrix_term - ) - - logger.info( - "PRELOADS - Inversion Log Det Regularization Matrix Term preloaded for this model-fit." - ) - - def check_via_fit(self, fit): - import copy - - settings_inversion = copy.deepcopy(fit.settings_inversion) - - fit_with_preloads = fit.refit_with_new_preloads( - preloads=self, settings_inversion=settings_inversion - ) - - fit_without_preloads = fit.refit_with_new_preloads( - preloads=self.__class__(use_w_tilde=False), - settings_inversion=settings_inversion, - ) - - if os.environ.get("PYAUTOFIT_TEST_MODE") == "1": - return - - try: - if ( - abs( - fit_with_preloads.figure_of_merit - - fit_without_preloads.figure_of_merit - ) - > self.check_threshold - ): - raise exc.PreloadsException( - f""" - The log likelihood of fits using and not using preloads are not consistent by a value larger than - the preloads check threshold of {self.check_threshold}, indicating preloading has gone wrong. - - The likelihood values are: - - With Preloads: {fit_with_preloads.figure_of_merit} - Without Preloads: {fit_without_preloads.figure_of_merit} - - Double check that the model-fit is set up correctly and that the preloads are being used correctly. - - This exception can be turned off by setting the general.yaml -> test -> check_preloads to False - in the config files. However, care should be taken when doing this. - """ - ) - - except exc.InversionException: - data_vector_difference = np.max( - np.abs( - fit_with_preloads.inversion.data_vector - - fit_without_preloads.inversion.data_vector - ) - ) - - if data_vector_difference > 1.0e-4: - raise exc.PreloadsException( - f""" - The data vectors of fits using and not using preloads are not consistent, indicating - preloading has gone wrong. - - The maximum value a data vector absolute value difference is: {data_vector_difference} - """ - ) - - curvature_reg_matrix_difference = np.max( - np.abs( - fit_with_preloads.inversion.curvature_reg_matrix - - fit_without_preloads.inversion.curvature_reg_matrix - ) - ) - - if curvature_reg_matrix_difference > 1.0e-4: - raise exc.PreloadsException( - f""" - The curvature matrices of fits using and not using preloads are not consistent, indicating - preloading has gone wrong. - - The maximum value of a curvature matrix absolute value difference is: {curvature_reg_matrix_difference} - """ - ) - - @property - def info(self) -> List[str]: - """ - The information on what has or has not been preloaded, which is written to the file `preloads.summary`. - - Returns - ------- - A list of strings containing statements on what has or has not been preloaded. - """ - line = [f"W Tilde = {self.w_tilde is not None}\n"] - line += [f"Relocated Grid = {self.relocated_grid is not None}\n"] - line += [f"Mapper = {self.mapper_list is not None}\n"] - line += [ - f"Blurred Mapping Matrix = {self.operated_mapping_matrix is not None}\n" - ] - line += [ - f"Inversion Linear Func (Linear Light Profile) Dicts = {self.linear_func_operated_mapping_matrix_dict is not None}\n" - ] - line += [f"Curvature Matrix = {self.curvature_matrix is not None}\n"] - line += [ - f"Curvature Matrix Mapper Diag = {self.curvature_matrix_mapper_diag is not None}\n" - ] - line += [f"Regularization Matrix = {self.regularization_matrix is not None}\n"] - line += [ - f"Log Det Regularization Matrix Term = {self.log_det_regularization_matrix_term is not None}\n" - ] - - return line diff --git a/autoarray/structures/arrays/array_1d_util.py b/autoarray/structures/arrays/array_1d_util.py index 915a2a4ad..8ed9b83a6 100644 --- a/autoarray/structures/arrays/array_1d_util.py +++ b/autoarray/structures/arrays/array_1d_util.py @@ -166,5 +166,9 @@ def array_1d_via_indexes_1d_from( ndarray The native 1D array of values mapped from the slimmed array with dimensions (total_x_pixels). """ + if isinstance(array_1d_slim, np.ndarray): + array_1d_native = np.zeros(shape) + array_1d_native[native_index_for_slim_index_1d] = array_1d_slim + return array_1d_native array_1d_native = jnp.zeros(shape) return array_1d_native.at[native_index_for_slim_index_1d].set(array_1d_slim) diff --git a/autoarray/structures/arrays/array_2d_util.py b/autoarray/structures/arrays/array_2d_util.py index aff0872b5..e3700a7e8 100644 --- a/autoarray/structures/arrays/array_2d_util.py +++ b/autoarray/structures/arrays/array_2d_util.py @@ -118,7 +118,7 @@ def convert_array_2d( If True, the ndarray is stored in its native format [total_y_pixels, total_x_pixels]. This avoids mapping large data arrays to and from the slim / native formats, which can be a computational bottleneck. """ - array_2d = convert_array(array=array_2d).copy() + array_2d = convert_array(array=array_2d) is_numpy = True if isinstance(array_2d, np.ndarray) else False @@ -558,6 +558,10 @@ def array_2d_via_indexes_from( ndarray The native 2D array of values mapped from the slimmed array with dimensions (total_values, total_values). """ + if isinstance(array_2d_slim, np.ndarray): + array = np.zeros(shape) + array[tuple(native_index_for_slim_index_2d.T)] = array_2d_slim + return array return ( jnp.zeros(shape).at[tuple(native_index_for_slim_index_2d.T)].set(array_2d_slim) ) diff --git a/autoarray/structures/arrays/kernel_2d.py b/autoarray/structures/arrays/kernel_2d.py index 293cf5ad2..7428e1979 100644 --- a/autoarray/structures/arrays/kernel_2d.py +++ b/autoarray/structures/arrays/kernel_2d.py @@ -1,8 +1,6 @@ -from astropy import units import jax import jax.numpy as jnp import numpy as np -import scipy.signal from pathlib import Path from typing import List, Tuple, Union @@ -16,7 +14,6 @@ from autoarray import exc from autoarray import type as ty from autoarray.structures.arrays import array_2d_util -from autoarray.mask.mask_2d import mask_2d_util class Kernel2D(AbstractArray2D): @@ -299,6 +296,9 @@ def from_as_gaussian_via_alma_fits_header_parameters( centre: Tuple[float, float] = (0.0, 0.0), normalize: bool = False, ) -> "Kernel2D": + + from astropy import units + x_stddev = ( x_stddev * (units.deg).to(units.arcsec) / (2.0 * np.sqrt(2.0 * np.log(2.0))) ) @@ -387,7 +387,7 @@ def rescaled_with_odd_dimensions_from( try: kernel_rescaled = rescale( - np.array(self.native._array), + self.native.array, rescale_factor, anti_aliasing=False, mode="constant", @@ -395,7 +395,7 @@ def rescaled_with_odd_dimensions_from( ) except TypeError: kernel_rescaled = rescale( - np.array(self.native._array), + self.native.array, rescale_factor, anti_aliasing=False, mode="constant", @@ -471,17 +471,19 @@ def convolved_array_from(self, array: Array2D) -> Array2D: ------ KernelException if either Kernel2D psf dimension is odd """ + import scipy.signal + if self.mask.shape[0] % 2 == 0 or self.mask.shape[1] % 2 == 0: raise exc.KernelException("Kernel2D Kernel2D must be odd") array_2d = array.native convolved_array_2d = scipy.signal.convolve2d( - array_2d.array, np.array(self.native.array), mode="same" + array_2d.array, self.native.array, mode="same" ) convolved_array_1d = array_2d_util.array_2d_slim_from( - mask_2d=np.array(array_2d.mask), + mask_2d=array_2d.mask, array_2d_native=convolved_array_2d, ) @@ -505,6 +507,7 @@ def convolved_array_with_mask_from(self, array: Array2D, mask) -> Array2D: ------ KernelException if either Kernel2D psf dimension is odd """ + import scipy.signal if self.mask.shape[0] % 2 == 0 or self.mask.shape[1] % 2 == 0: raise exc.KernelException("Kernel2D Kernel2D must be odd") @@ -514,8 +517,8 @@ def convolved_array_with_mask_from(self, array: Array2D, mask) -> Array2D: ) convolved_array_1d = array_2d_util.array_2d_slim_from( - mask_2d=np.array(mask), - array_2d_native=np.array(convolved_array_2d), + mask_2d=mask, + array_2d_native=convolved_array_2d, ) return Array2D(values=convolved_array_1d, mask=mask) @@ -553,7 +556,7 @@ def convolve_image(self, image, blurring_image, jax_method="direct"): blurring_image.array ) - kernel = np.array(self.stored_native.array) + kernel = self.stored_native.array convolve_native = jax.scipy.signal.convolve( expanded_array_native, kernel, mode="same", method=jax_method @@ -591,7 +594,7 @@ def convolve_image_no_blurring(self, image, mask, jax_method="direct"): image.array ) - kernel = np.array(self.stored_native.array) + kernel = self.stored_native.array convolve_native = jax.scipy.signal.convolve( expanded_array_native, kernel, mode="same", method=jax_method diff --git a/autoarray/structures/arrays/uniform_2d.py b/autoarray/structures/arrays/uniform_2d.py index 0351f62b2..7c955e2b1 100644 --- a/autoarray/structures/arrays/uniform_2d.py +++ b/autoarray/structures/arrays/uniform_2d.py @@ -343,7 +343,7 @@ def in_counts_per_second(self) -> "Array2D": @property def original_orientation(self) -> Union[np.ndarray, "Array2D"]: return layout_util.rotate_array_via_roe_corner_from( - array=np.array(self), roe_corner=self.header.original_roe_corner + array=self, roe_corner=self.header.original_roe_corner ) @property @@ -491,7 +491,7 @@ def resized_from( """ resized_array_2d = array_2d_util.resized_array_2d_from( - array_2d=np.array(self.native.array), resized_shape=new_shape + array_2d=self.native.array, resized_shape=new_shape ) resized_mask = self.mask.resized_from( @@ -656,7 +656,7 @@ def no_mask( origin=origin, ) - return Array2D(values=np.array(values), mask=mask, header=header) + return Array2D(values=values, mask=mask, header=header) @classmethod def full( diff --git a/autoarray/structures/grids/grid_2d_util.py b/autoarray/structures/grids/grid_2d_util.py index ea298bce2..5239a193a 100644 --- a/autoarray/structures/grids/grid_2d_util.py +++ b/autoarray/structures/grids/grid_2d_util.py @@ -253,6 +253,15 @@ def grid_2d_slim_via_mask_from( centres_scaled = geometry_util.central_scaled_coordinate_2d_from( shape_native=mask_2d.shape, pixel_scales=pixel_scales, origin=origin ) + if isinstance(mask_2d, np.ndarray): + centres_scaled = np.array(centres_scaled) + pixel_scales = np.array(pixel_scales) + sign = np.array([-1.0, 1.0]) + return ( + (np.stack(np.nonzero(~mask_2d.astype(bool))).T - centres_scaled) + * sign + * pixel_scales + ) centres_scaled = jnp.array(centres_scaled) pixel_scales = jnp.array(pixel_scales) @@ -692,7 +701,8 @@ def grid_2d_slim_from( array_2d_native=grid_2d_native[:, :, 1], mask_2d=mask, ) - + if isinstance(grid_2d_native, np.ndarray): + return np.stack((grid_1d_slim_y, grid_1d_slim_x), axis=-1) return jnp.stack((grid_1d_slim_y, grid_1d_slim_x), axis=-1) @@ -736,6 +746,8 @@ def grid_2d_native_from( mask_2d=mask_2d, ) + if isinstance(grid_2d_slim, np.ndarray): + return np.stack((grid_2d_native_y, grid_2d_native_x), axis=-1) return jnp.stack((grid_2d_native_y, grid_2d_native_x), axis=-1) diff --git a/autoarray/structures/grids/sparse_2d_util.py b/autoarray/structures/grids/sparse_2d_util.py index 207c23f7e..2f648bec8 100644 --- a/autoarray/structures/grids/sparse_2d_util.py +++ b/autoarray/structures/grids/sparse_2d_util.py @@ -1,6 +1,5 @@ import logging import numpy as np -from scipy.interpolate import interp1d, griddata logger = logging.getLogger(__name__) logger.level = logging.DEBUG @@ -46,6 +45,7 @@ def create_img_and_grid_hb_order(img_2d, mask, mask_radius, pixel_scales, length image associated to that grid. """ + from scipy.interpolate import griddata from autoarray.structures.grids.uniform_2d import Grid2D shape_nnn = np.shape(mask)[0] @@ -76,6 +76,7 @@ def inverse_transform_sampling_interpolated(probabilities, n_samples, gridx, gri probabilities: 1D normalized cumulative probablity curve. n_samples: the number of points to draw. """ + from scipy.interpolate import interp1d cdf = np.cumsum(probabilities) npixels = len(probabilities) diff --git a/autoarray/structures/header.py b/autoarray/structures/header.py index d628bf1d2..dbafd1f14 100644 --- a/autoarray/structures/header.py +++ b/autoarray/structures/header.py @@ -1,5 +1,4 @@ import logging -from astropy import time from typing import Dict, Tuple, Optional from autoarray.dataset import preprocess @@ -36,6 +35,8 @@ def exposure_time(self) -> str: @property def modified_julian_date(self) -> Optional[str]: + from astropy import time + if ( self.date_of_observation is not None and self.time_of_observation is not None diff --git a/autoarray/structures/mesh/abstract_2d.py b/autoarray/structures/mesh/abstract_2d.py index 910a82ef9..55fb7b9b8 100644 --- a/autoarray/structures/mesh/abstract_2d.py +++ b/autoarray/structures/mesh/abstract_2d.py @@ -1,4 +1,3 @@ -import numpy as np from typing import Optional, Tuple from autoarray.structures.abstract_structure import Structure diff --git a/autoarray/structures/mesh/delaunay_2d.py b/autoarray/structures/mesh/delaunay_2d.py index e12d4898c..61cc5e88a 100644 --- a/autoarray/structures/mesh/delaunay_2d.py +++ b/autoarray/structures/mesh/delaunay_2d.py @@ -1,5 +1,5 @@ import numpy as np -from typing import List, Optional, Tuple +from typing import Optional, Tuple from autoconf import cached_property diff --git a/autoarray/structures/mesh/rectangular_2d.py b/autoarray/structures/mesh/rectangular_2d.py index c46fc258e..f2f7a4a98 100644 --- a/autoarray/structures/mesh/rectangular_2d.py +++ b/autoarray/structures/mesh/rectangular_2d.py @@ -1,5 +1,5 @@ import numpy as np -from scipy.interpolate import griddata + from typing import List, Optional, Tuple from autoarray import type as ty @@ -174,6 +174,8 @@ def interpolated_array_from( The (x0, x1, y0, y1) extent of the grid in scaled coordinates over which the grid is created if it is input. """ + from scipy.interpolate import griddata + interpolation_grid = self.interpolation_grid_from( shape_native=shape_native, extent=extent ) diff --git a/autoarray/structures/mesh/triangulation_2d.py b/autoarray/structures/mesh/triangulation_2d.py index 635e02f62..95ff46633 100644 --- a/autoarray/structures/mesh/triangulation_2d.py +++ b/autoarray/structures/mesh/triangulation_2d.py @@ -1,5 +1,5 @@ import numpy as np -import scipy.spatial + from typing import List, Union, Tuple from autoarray.structures.abstract_structure import Structure @@ -82,7 +82,7 @@ def geometry(self): ) @cached_property - def delaunay(self) -> scipy.spatial.Delaunay: + def delaunay(self) -> "scipy.spatial.Delaunay": """ Returns a `scipy.spatial.Delaunay` object from the 2D (y,x) grid of irregular coordinates, which correspond to the corner of every triangle of a Delaunay triangulation. @@ -95,6 +95,8 @@ def delaunay(self) -> scipy.spatial.Delaunay: to compute the Voronoi mesh are ill posed. These exceptions are caught and combined into a single `MeshException`, which helps exception handling in the `inversion` package. """ + import scipy.spatial + try: return scipy.spatial.Delaunay( np.asarray([self.array[:, 0], self.array[:, 1]]).T @@ -103,7 +105,7 @@ def delaunay(self) -> scipy.spatial.Delaunay: raise exc.MeshException() from e @cached_property - def voronoi(self) -> scipy.spatial.Voronoi: + def voronoi(self) -> "scipy.spatial.Voronoi": """ Returns a `scipy.spatial.Voronoi` object from the 2D (y,x) grid of irregular coordinates, which correspond to the centre of every Voronoi pixel. @@ -115,6 +117,7 @@ def voronoi(self) -> scipy.spatial.Voronoi: to compute the Delaunay triangulation are ill posed. These exceptions are caught and combined into a single `MeshException`, which helps exception handling in the `inversion` package. """ + import scipy.spatial from scipy.spatial import QhullError try: diff --git a/autoarray/structures/mesh/voronoi_2d.py b/autoarray/structures/mesh/voronoi_2d.py index 72eeda54d..38b7a123c 100644 --- a/autoarray/structures/mesh/voronoi_2d.py +++ b/autoarray/structures/mesh/voronoi_2d.py @@ -1,6 +1,6 @@ import numpy as np -from scipy.interpolate import griddata -from typing import List, Optional, Tuple + +from typing import Optional, Tuple from autoconf import cached_property @@ -76,6 +76,8 @@ def interpolated_array_from( The 2D shape in scaled coordinates (e.g. arc-seconds in PyAutoGalaxy / PyAutoLens) that the interpolated reconstructed source is returned on. """ + from scipy.interpolate import griddata + interpolation_grid = self.interpolation_grid_from( shape_native=shape_native, extent=extent ) diff --git a/autoarray/structures/mock/mock_decorators.py b/autoarray/structures/mock/mock_decorators.py index c02ebc0b8..28cf9eaec 100644 --- a/autoarray/structures/mock/mock_decorators.py +++ b/autoarray/structures/mock/mock_decorators.py @@ -157,11 +157,3 @@ def ndarray_yx_2d_list_from(self, grid, *args, **kwargs): Such functions are common in **PyAutoGalaxy** for light and mass profile objects. """ return [np.multiply(1.0, grid.array), np.multiply(2.0, grid.array)] - - -class MockGridRadialMinimum: - def __init__(self): - pass - - def radial_grid_from(self, grid): - return np.sqrt(np.add(np.square(grid[:, 0]), np.square(grid[:, 1]))) diff --git a/autoarray/structures/mock/mock_grid.py b/autoarray/structures/mock/mock_grid.py index 2352c2027..b1639a02c 100644 --- a/autoarray/structures/mock/mock_grid.py +++ b/autoarray/structures/mock/mock_grid.py @@ -1,5 +1,5 @@ import numpy as np -from typing import Tuple, List +from typing import Tuple from autoarray.geometry.abstract_2d import AbstractGeometry2D from autoarray.inversion.linear_obj.neighbors import Neighbors diff --git a/autoarray/structures/plot/structure_plotters.py b/autoarray/structures/plot/structure_plotters.py index 44f2248b8..0596ebcd4 100644 --- a/autoarray/structures/plot/structure_plotters.py +++ b/autoarray/structures/plot/structure_plotters.py @@ -19,9 +19,9 @@ class Array2DPlotter(Plotter): def __init__( self, array: Array2D, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots `Array2D` objects using the matplotlib method `imshow()` and many other matplotlib functions which @@ -70,9 +70,9 @@ class Grid2DPlotter(Plotter): def __init__( self, grid: Grid2D, - mat_plot_2d: MatPlot2D = MatPlot2D(), - visuals_2d: Visuals2D = Visuals2D(), - include_2d: Include2D = Include2D(), + mat_plot_2d: MatPlot2D = None, + visuals_2d: Visuals2D = None, + include_2d: Include2D = None, ): """ Plots `Grid2D` objects using the matplotlib method `scatter()` and many other matplotlib functions which @@ -141,9 +141,9 @@ def __init__( self, y: Union[Array1D, List], x: Optional[Union[Array1D, Grid1D, List]] = None, - mat_plot_1d: MatPlot1D = MatPlot1D(), - visuals_1d: Visuals1D = Visuals1D(), - include_1d: Include1D = Include1D(), + mat_plot_1d: MatPlot1D = None, + visuals_1d: Visuals1D = None, + include_1d: Include1D = None, should_plot_grid: bool = False, should_plot_zero: bool = False, plot_axis_type: Optional[str] = None, diff --git a/pyproject.toml b/pyproject.toml index 3d9b9eb89..850141794 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ classifiers = [ ] keywords = ["cli"] dependencies = [ - "autofit", "astropy>=5.0,<=6.1.2", "decorator>=4.0.0", "dill>=0.3.1.1", diff --git a/test_autoarray/conftest.py b/test_autoarray/conftest.py index 41f30cb39..b322cab3c 100644 --- a/test_autoarray/conftest.py +++ b/test_autoarray/conftest.py @@ -1,3 +1,10 @@ +import jax.numpy as jnp + + +def pytest_configure(): + _ = jnp.sum(jnp.array([0.0])) # Force backend init + + import os from os import path import pytest diff --git a/test_autoarray/fit/test_fit_util.py b/test_autoarray/fit/test_fit_util.py index 0cbc811de..0702dc95a 100644 --- a/test_autoarray/fit/test_fit_util.py +++ b/test_autoarray/fit/test_fit_util.py @@ -1,41 +1,41 @@ -import autoarray as aa - -import jax.numpy as jnp +import numpy as np import pytest +import autoarray as aa + def test__residual_map_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - model_data = jnp.array([10.0, 10.0, 10.0, 10.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + model_data = np.array([10.0, 10.0, 10.0, 10.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) - assert (residual_map == jnp.array([0.0, 0.0, 0.0, 0.0])).all() + assert (residual_map == np.array([0.0, 0.0, 0.0, 0.0])).all() - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) - assert (residual_map == jnp.array([-1.0, 0.0, 1.0, 2.0])).all() + assert (residual_map == np.array([-1.0, 0.0, 1.0, 2.0])).all() def test__residual_map_with_mask_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - mask = jnp.array([True, False, False, True]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + mask = np.array([True, False, False, True]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data ) - assert (residual_map == jnp.array([0.0, 0.0, 1.0, 0.0])).all() + assert (residual_map == np.array([0.0, 0.0, 1.0, 0.0])).all() def test__normalized_residual_map_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - noise_map = jnp.array([2.0, 2.0, 2.0, 2.0]) - model_data = jnp.array([10.0, 10.0, 10.0, 10.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + noise_map = np.array([2.0, 2.0, 2.0, 2.0]) + model_data = np.array([10.0, 10.0, 10.0, 10.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -44,10 +44,10 @@ def test__normalized_residual_map_from(): ) assert normalized_residual_map == pytest.approx( - jnp.array([0.0, 0.0, 0.0, 0.0]), 1.0e-4 + np.array([0.0, 0.0, 0.0, 0.0]), 1.0e-4 ) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -56,15 +56,15 @@ def test__normalized_residual_map_from(): ) assert normalized_residual_map == pytest.approx( - jnp.array([-(1.0 / 2.0), 0.0, (1.0 / 2.0), (2.0 / 2.0)]), 1.0e-4 + np.array([-(1.0 / 2.0), 0.0, (1.0 / 2.0), (2.0 / 2.0)]), 1.0e-4 ) def test__normalized_residual_map_with_mask_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - mask = jnp.array([True, False, False, True]) - noise_map = jnp.array([2.0, 2.0, 2.0, 2.0]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + mask = np.array([True, False, False, True]) + noise_map = np.array([2.0, 2.0, 2.0, 2.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -75,14 +75,14 @@ def test__normalized_residual_map_with_mask_from(): ) assert normalized_residual_map == pytest.approx( - jnp.array([0.0, 0.0, (1.0 / 2.0), 0.0]), abs=1.0e-4 + np.array([0.0, 0.0, (1.0 / 2.0), 0.0]), abs=1.0e-4 ) def test__normalized_residual_map_complex_from(): - data = jnp.array([10.0 + 10.0j, 10.0 + 10.0j]) - noise_map = jnp.array([2.0 + 2.0j, 2.0 + 2.0j]) - model_data = jnp.array([9.0 + 12.0j, 9.0 + 12.0j]) + data = np.array([10.0 + 10.0j, 10.0 + 10.0j]) + noise_map = np.array([2.0 + 2.0j, 2.0 + 2.0j]) + model_data = np.array([9.0 + 12.0j, 9.0 + 12.0j]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -90,13 +90,13 @@ def test__normalized_residual_map_complex_from(): residual_map=residual_map, noise_map=noise_map ) - assert (normalized_residual_map == jnp.array([0.5 - 1.0j, 0.5 - 1.0j])).all() + assert (normalized_residual_map == np.array([0.5 - 1.0j, 0.5 - 1.0j])).all() def test__chi_squared_map_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - noise_map = jnp.array([2.0, 2.0, 2.0, 2.0]) - model_data = jnp.array([10.0, 10.0, 10.0, 10.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + noise_map = np.array([2.0, 2.0, 2.0, 2.0]) + model_data = np.array([10.0, 10.0, 10.0, 10.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -104,9 +104,9 @@ def test__chi_squared_map_from(): residual_map=residual_map, noise_map=noise_map ) - assert (chi_squared_map == jnp.array([0.0, 0.0, 0.0, 0.0])).all() + assert (chi_squared_map == np.array([0.0, 0.0, 0.0, 0.0])).all() - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -116,15 +116,15 @@ def test__chi_squared_map_from(): assert ( chi_squared_map - == jnp.array([(1.0 / 2.0) ** 2.0, 0.0, (1.0 / 2.0) ** 2.0, (2.0 / 2.0) ** 2.0]) + == np.array([(1.0 / 2.0) ** 2.0, 0.0, (1.0 / 2.0) ** 2.0, (2.0 / 2.0) ** 2.0]) ).all() def test__chi_squared_map_with_mask_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - mask = jnp.array([True, False, False, True]) - noise_map = jnp.array([2.0, 2.0, 2.0, 2.0]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + mask = np.array([True, False, False, True]) + noise_map = np.array([2.0, 2.0, 2.0, 2.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -134,9 +134,9 @@ def test__chi_squared_map_with_mask_from(): residual_map=residual_map, mask=mask, noise_map=noise_map ) - assert (chi_squared_map == jnp.array([0.0, 0.0, (1.0 / 2.0) ** 2.0, 0.0])).all() + assert (chi_squared_map == np.array([0.0, 0.0, (1.0 / 2.0) ** 2.0, 0.0])).all() - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -146,13 +146,13 @@ def test__chi_squared_map_with_mask_from(): residual_map=residual_map, mask=mask, noise_map=noise_map ) - assert (chi_squared_map == jnp.array([0.0, 0.0, (1.0 / 2.0) ** 2.0, 0.0])).all() + assert (chi_squared_map == np.array([0.0, 0.0, (1.0 / 2.0) ** 2.0, 0.0])).all() def test__chi_squared_map_complex_from(): - data = jnp.array([10.0 + 10.0j, 10.0 + 10.0j]) - noise_map = jnp.array([2.0 + 2.0j, 2.0 + 2.0j]) - model_data = jnp.array([9.0 + 12.0j, 9.0 + 12.0j]) + data = np.array([10.0 + 10.0j, 10.0 + 10.0j]) + noise_map = np.array([2.0 + 2.0j, 2.0 + 2.0j]) + model_data = np.array([9.0 + 12.0j, 9.0 + 12.0j]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -160,13 +160,13 @@ def test__chi_squared_map_complex_from(): residual_map=residual_map, noise_map=noise_map ) - assert (chi_squared_map == jnp.array([0.25 + 1.0j, 0.25 + 1.0j])).all() + assert (chi_squared_map == np.array([0.25 + 1.0j, 0.25 + 1.0j])).all() def test__chi_squared_with_noise_covariance_from(): resdiual_map = aa.Array2D.no_mask([[1.0, 1.0], [2.0, 2.0]], pixel_scales=1.0) - noise_covariance_matrix_inv = jnp.array( + noise_covariance_matrix_inv = np.array( [ [1.0, 1.0, 4.0, 0.0], [0.0, 1.0, 9.0, 0.0], @@ -184,10 +184,10 @@ def test__chi_squared_with_noise_covariance_from(): def test__chi_squared_with_mask_fast_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - mask = jnp.array([True, False, False, True]) - noise_map = jnp.array([1.0, 2.0, 3.0, 4.0]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + mask = np.array([True, False, False, True]) + noise_map = np.array([1.0, 2.0, 3.0, 4.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -210,10 +210,10 @@ def test__chi_squared_with_mask_fast_from(): assert chi_squared == pytest.approx(chi_squared_fast, 1.0e-4) - data = jnp.array([[10.0, 10.0], [10.0, 10.0]]) - mask = jnp.array([[True, False], [False, True]]) - noise_map = jnp.array([[1.0, 2.0], [3.0, 4.0]]) - model_data = jnp.array([[11.0, 10.0], [9.0, 8.0]]) + data = np.array([[10.0, 10.0], [10.0, 10.0]]) + mask = np.array([[True, False], [False, True]]) + noise_map = np.array([[1.0, 2.0], [3.0, 4.0]]) + model_data = np.array([[11.0, 10.0], [9.0, 8.0]]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -238,9 +238,9 @@ def test__chi_squared_with_mask_fast_from(): def test__log_likelihood_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - noise_map = jnp.array([2.0, 2.0, 2.0, 2.0]) - model_data = jnp.array([10.0, 10.0, 10.0, 10.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + noise_map = np.array([2.0, 2.0, 2.0, 2.0]) + model_data = np.array([10.0, 10.0, 10.0, 10.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -258,17 +258,17 @@ def test__log_likelihood_from(): chi_squared = 0.0 noise_normalization = ( - jnp.log(2.0 * jnp.pi * (2.0**2.0)) - + jnp.log(2.0 * jnp.pi * (2.0**2.0)) - + jnp.log(2.0 * jnp.pi * (2.0**2.0)) - + jnp.log(2.0 * jnp.pi * (2.0**2.0)) + np.log(2.0 * np.pi * (2.0**2.0)) + + np.log(2.0 * np.pi * (2.0**2.0)) + + np.log(2.0 * np.pi * (2.0**2.0)) + + np.log(2.0 * np.pi * (2.0**2.0)) ) assert log_likelihood == pytest.approx( -0.5 * (chi_squared + noise_normalization), 1.0e-4 ) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -291,17 +291,17 @@ def test__log_likelihood_from(): ((1.0 / 2.0) ** 2.0) + 0.0 + ((1.0 / 2.0) ** 2.0) + ((2.0 / 2.0) ** 2.0) ) noise_normalization = ( - jnp.log(2.0 * jnp.pi * (2.0**2.0)) - + jnp.log(2.0 * jnp.pi * (2.0**2.0)) - + jnp.log(2.0 * jnp.pi * (2.0**2.0)) - + jnp.log(2.0 * jnp.pi * (2.0**2.0)) + np.log(2.0 * np.pi * (2.0**2.0)) + + np.log(2.0 * np.pi * (2.0**2.0)) + + np.log(2.0 * np.pi * (2.0**2.0)) + + np.log(2.0 * np.pi * (2.0**2.0)) ) assert log_likelihood == pytest.approx( -0.5 * (chi_squared + noise_normalization), 1.0e-4 ) - noise_map = jnp.array([1.0, 2.0, 3.0, 4.0]) + noise_map = np.array([1.0, 2.0, 3.0, 4.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -321,10 +321,10 @@ def test__log_likelihood_from(): chi_squared = 1.0 + (1.0 / (3.0**2.0)) + 0.25 noise_normalization = ( - jnp.log(2 * jnp.pi * (1.0**2.0)) - + jnp.log(2 * jnp.pi * (2.0**2.0)) - + jnp.log(2 * jnp.pi * (3.0**2.0)) - + jnp.log(2 * jnp.pi * (4.0**2.0)) + np.log(2 * np.pi * (1.0**2.0)) + + np.log(2 * np.pi * (2.0**2.0)) + + np.log(2 * np.pi * (3.0**2.0)) + + np.log(2 * np.pi * (4.0**2.0)) ) assert log_likelihood == pytest.approx( @@ -333,10 +333,10 @@ def test__log_likelihood_from(): def test__log_likelihood_from__with_mask(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - mask = jnp.array([True, False, False, True]) - noise_map = jnp.array([1.0, 2.0, 3.0, 4.0]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + mask = np.array([True, False, False, True]) + noise_map = np.array([1.0, 2.0, 3.0, 4.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -361,18 +361,18 @@ def test__log_likelihood_from__with_mask(): # chi squared = 0, 0.25, (0.25 and 1.0 are masked) chi_squared = 0.0 + (1.0 / 3.0) ** 2.0 - noise_normalization = jnp.log(2 * jnp.pi * (2.0**2.0)) + jnp.log( - 2 * jnp.pi * (3.0**2.0) + noise_normalization = np.log(2 * np.pi * (2.0**2.0)) + np.log( + 2 * np.pi * (3.0**2.0) ) assert log_likelihood == pytest.approx( -0.5 * (chi_squared + noise_normalization), 1e-4 ) - data = jnp.array([[10.0, 10.0], [10.0, 10.0]]) - mask = jnp.array([[True, False], [False, True]]) - noise_map = jnp.array([[1.0, 2.0], [3.0, 4.0]]) - model_data = jnp.array([[11.0, 10.0], [9.0, 8.0]]) + data = np.array([[10.0, 10.0], [10.0, 10.0]]) + mask = np.array([[True, False], [False, True]]) + noise_map = np.array([[1.0, 2.0], [3.0, 4.0]]) + model_data = np.array([[11.0, 10.0], [9.0, 8.0]]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -397,8 +397,8 @@ def test__log_likelihood_from__with_mask(): # chi squared = 0, 0.25, (0.25 and 1.0 are masked) chi_squared = 0.0 + (1.0 / 3.0) ** 2.0 - noise_normalization = jnp.log(2 * jnp.pi * (2.0**2.0)) + jnp.log( - 2 * jnp.pi * (3.0**2.0) + noise_normalization = np.log(2 * np.pi * (2.0**2.0)) + np.log( + 2 * np.pi * (3.0**2.0) ) assert log_likelihood == pytest.approx( @@ -407,9 +407,10 @@ def test__log_likelihood_from__with_mask(): def test__log_likelihood_from__complex_data(): - data = jnp.array([10.0 + 10.0j, 10.0 + 10.0j]) - noise_map = jnp.array([2.0 + 1.0j, 2.0 + 1.0j]) - model_data = jnp.array([9.0 + 12.0j, 9.0 + 12.0j]) + + data = np.array([10.0 + 10.0j, 10.0 + 10.0j]) + noise_map = np.array([2.0 + 1.0j, 2.0 + 1.0j]) + model_data = np.array([9.0 + 12.0j, 9.0 + 12.0j]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -430,8 +431,8 @@ def test__log_likelihood_from__complex_data(): # chi squared = 0.25 and 4.0 chi_squared = 4.25 - noise_normalization = jnp.log(2 * jnp.pi * (2.0**2.0)) + jnp.log( - 2 * jnp.pi * (1.0**2.0) + noise_normalization = np.log(2 * np.pi * (2.0**2.0)) + np.log( + 2 * np.pi * (1.0**2.0) ) assert log_likelihood == pytest.approx( @@ -460,8 +461,8 @@ def test__log_evidence_from(): def test__residual_flux_fraction_map_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - model_data = jnp.array([10.0, 10.0, 10.0, 10.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + model_data = np.array([10.0, 10.0, 10.0, 10.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -469,9 +470,9 @@ def test__residual_flux_fraction_map_from(): residual_map=residual_map, data=data ) - assert (residual_flux_fraction_map == jnp.array([0.0, 0.0, 0.0, 0.0])).all() + assert (residual_flux_fraction_map == np.array([0.0, 0.0, 0.0, 0.0])).all() - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_from(data=data, model_data=model_data) @@ -479,13 +480,13 @@ def test__residual_flux_fraction_map_from(): residual_map=residual_map, data=data ) - assert (residual_flux_fraction_map == jnp.array([-0.1, 0.0, 0.1, 0.2])).all() + assert (residual_flux_fraction_map == np.array([-0.1, 0.0, 0.1, 0.2])).all() def test__residual_flux_fraction_map_with_mask_from(): - data = jnp.array([10.0, 10.0, 10.0, 10.0]) - mask = jnp.array([True, False, False, True]) - model_data = jnp.array([11.0, 10.0, 9.0, 8.0]) + data = np.array([10.0, 10.0, 10.0, 10.0]) + mask = np.array([True, False, False, True]) + model_data = np.array([11.0, 10.0, 9.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -495,9 +496,9 @@ def test__residual_flux_fraction_map_with_mask_from(): residual_map=residual_map, mask=mask, data=data ) - assert (residual_flux_fraction_map == jnp.array([0.0, 0.0, 0.1, 0.0])).all() + assert (residual_flux_fraction_map == np.array([0.0, 0.0, 0.1, 0.0])).all() - model_data = jnp.array([11.0, 9.0, 8.0, 8.0]) + model_data = np.array([11.0, 9.0, 8.0, 8.0]) residual_map = aa.util.fit.residual_map_with_mask_from( data=data, mask=mask, model_data=model_data @@ -507,4 +508,4 @@ def test__residual_flux_fraction_map_with_mask_from(): residual_map=residual_map, mask=mask, data=data ) - assert (residual_flux_fraction_map == jnp.array([0.0, 0.1, 0.2, 0.0])).all() + assert (residual_flux_fraction_map == np.array([0.0, 0.1, 0.2, 0.0])).all() diff --git a/test_autoarray/plot/test_abstract_plotters.py b/test_autoarray/plot/test_abstract_plotters.py index 652c97422..8d44b1320 100644 --- a/test_autoarray/plot/test_abstract_plotters.py +++ b/test_autoarray/plot/test_abstract_plotters.py @@ -24,28 +24,28 @@ def test__get_subplot_shape(): plotter.mat_plot_2d.get_subplot_shape(number_subplots=1000) -def test__get_subplot_figsize(): - plotter = abstract_plotters.AbstractPlotter( - mat_plot_2d=aplt.MatPlot2D(figure=aplt.Figure(figsize="auto")) - ) - - figsize = plotter.get_subplot_figsize(number_subplots=1) - - assert figsize == (6, 6) - - figsize = plotter.get_subplot_figsize(number_subplots=4) - - assert figsize == (12, 12) - - figure = aplt.Figure(figsize=(20, 20)) - - plotter = abstract_plotters.AbstractPlotter( - mat_plot_2d=aplt.MatPlot2D(figure=figure) - ) - - figsize = plotter.get_subplot_figsize(number_subplots=4) - - assert figsize == (20, 20) +# def test__get_subplot_figsize(): +# plotter = abstract_plotters.AbstractPlotter( +# mat_plot_2d=aplt.MatPlot2D(figure=aplt.Figure(figsize="auto")) +# ) +# +# figsize = plotter.get_subplot_figsize(number_subplots=1) +# +# assert figsize == (7, 7) +# +# figsize = plotter.get_subplot_figsize(number_subplots=4) +# +# assert figsize == (7, 7) +# +# figure = aplt.Figure(figsize=(20, 20)) +# +# plotter = abstract_plotters.AbstractPlotter( +# mat_plot_2d=aplt.MatPlot2D(figure=figure) +# ) +# +# figsize = plotter.get_subplot_figsize(number_subplots=4) +# +# assert figsize == (20, 20) def test__open_and_close_subplot_figures(): diff --git a/test_autoarray/plot/test_multi_plotters.py b/test_autoarray/plot/test_multi_plotters.py index 49494e144..7485a3d6a 100644 --- a/test_autoarray/plot/test_multi_plotters.py +++ b/test_autoarray/plot/test_multi_plotters.py @@ -45,9 +45,9 @@ def __init__( self, y, x, - mat_plot_1d: aplt.MatPlot1D = aplt.MatPlot1D(), - visuals_1d: aplt.Visuals1D = aplt.Visuals1D(), - include_1d: aplt.Include1D = aplt.Include1D(), + mat_plot_1d: aplt.MatPlot1D = None, + visuals_1d: aplt.Visuals1D = None, + include_1d: aplt.Include1D = None, ): super().__init__( y=y, diff --git a/test_autoarray/structures/arrays/test_kernel_2d.py b/test_autoarray/structures/arrays/test_kernel_2d.py index 39ba25842..6fa4e7295 100644 --- a/test_autoarray/structures/arrays/test_kernel_2d.py +++ b/test_autoarray/structures/arrays/test_kernel_2d.py @@ -1,13 +1,11 @@ from astropy import units from astropy.modeling import functional_models from astropy.coordinates import Angle -import jax.numpy as jnp import numpy as np import pytest from os import path import autoarray as aa -from autoarray import exc test_data_path = path.join("{}".format(path.dirname(path.realpath(__file__))), "files")