From 2a6608ac9b9c5987690ca8292a5ce6c1aa4ab031 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 20 Oct 2023 18:10:03 +0100 Subject: [PATCH 1/4] more informatie error --- autoarray/config/general.yaml | 2 +- autoarray/exc.py | 10 ++++++ autoarray/plot/mat_plot/two_d.py | 18 +++++------ autoarray/structures/structure_decorators.py | 32 ++++++++++++++++++-- test_autoarray/config/general.yaml | 2 +- 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/autoarray/config/general.yaml b/autoarray/config/general.yaml index 7915cf642..7beab815c 100644 --- a/autoarray/config/general.yaml +++ b/autoarray/config/general.yaml @@ -10,7 +10,7 @@ numba: nopython: true parallel: false pixelization: - voronoi_nn_max_interpolation_neighbors: 100 + voronoi_nn_max_interpolation_neighbors: 300 structures: native_binned_only: false # If True, data structures are only stored in their native and binned format. This is used to reduce memory usage in autocti. test: diff --git a/autoarray/exc.py b/autoarray/exc.py index 657ec8324..dd0b9a3b7 100644 --- a/autoarray/exc.py +++ b/autoarray/exc.py @@ -18,6 +18,16 @@ class ArrayException(Exception): pass + +class ConfigException(Exception): + """ + Raises exceptions associated with the `structures/array` modules and `Array` classes. + + For example if a 2D array's shape and its corresponding 2D mask shape do not match. + """ + + pass + class GridException(Exception): """ Raises exceptions associated with the `structures/grid` modules and `Grid` classes. diff --git a/autoarray/plot/mat_plot/two_d.py b/autoarray/plot/mat_plot/two_d.py index 888838957..dc9de56f1 100644 --- a/autoarray/plot/mat_plot/two_d.py +++ b/autoarray/plot/mat_plot/two_d.py @@ -241,7 +241,7 @@ def plot_array( # so that if a mask is irregular and zooming in creates white edges, that instead it doesnt have the eddge. # This could just be a matplotlib settings to change the edge color? - # array = array.resized_from(new_shape=(401, 401)) +# array = array.resized_from(new_shape=(401, 401)) if array.mask.is_all_false: buffer = 0 @@ -338,14 +338,14 @@ def plot_array( ) self.colorbar_tickparams.set(cb=cb) - # levels = np.logspace(np.log10(0.3), np.log10(20.0), 10) - # plt.contour( - # # array.mask.derive_grid.unmasked_sub_1, - # array.native[::-1], - # levels=levels, - # colors="black", - # extent=extent, - # ) + levels = np.logspace(np.log10(0.3), np.log10(20.0), 10) + plt.contour( + # array.mask.derive_grid.unmasked_sub_1, + array.native[::-1], + levels=levels, + colors="black", + extent=extent, + ) grid_indexes = None diff --git a/autoarray/structures/structure_decorators.py b/autoarray/structures/structure_decorators.py index 864080601..f5a6d30aa 100644 --- a/autoarray/structures/structure_decorators.py +++ b/autoarray/structures/structure_decorators.py @@ -542,9 +542,35 @@ def wrapper( The grid_like object whose coordinates are radially moved from (0.0, 0.0). """ - grid_radial_minimum = conf.instance["grids"]["radial_minimum"][ - "radial_minimum" - ][cls.__class__.__name__] + try: + grid_radial_minimum = conf.instance["grids"]["radial_minimum"][ + "radial_minimum" + ][cls.__class__.__name__] + except KeyError as e: + print( + fr""" + The {cls.__class__.__name__} profile you are using does not have a corresponding + entry in the `config/grid.yaml` config file. + + When a profile is evaluated at (0.0, 0.0), they commonly break due to numericalinstabilities (e.g. + division by zero). To prevent this, the code relocates the (y,x) coordinates of the grid to a + minimum radial value, specified in the `config/grids.yaml` config file. + + For example, if the value in `grid.yaml` is `radial_minimum: 1e-6`, then any (y,x) coordinates + with a radial distance less than 1e-6 to (0.0, 0.0) are relocated to 1e-6. + + For a profile to be used it must have an entry in the `config/grids.yaml` config file. Go to this + file now and add your profile to the `radial_minimum` section. Adopting a value of 1e-6 is a good + default choice. + + If you are going to make a pull request to add your profile to the source code, you should also + add an entry to the `config/grids.yaml` config file of the source code itself + (e.g. `PyAutoGalaxy/autogalaxy/config/grids.yaml`). + """ + ) + + import sys + sys.exit(1) with np.errstate(all="ignore"): # Division by zero fixed via isnan grid_radii = cls.radial_grid_from(grid=grid) diff --git a/test_autoarray/config/general.yaml b/test_autoarray/config/general.yaml index 307b3f67f..8d0325a13 100644 --- a/test_autoarray/config/general.yaml +++ b/test_autoarray/config/general.yaml @@ -29,7 +29,7 @@ output: model_results_every_update: 100 remove_files: false pixelization: - voronoi_nn_max_interpolation_neighbors: 100 + voronoi_nn_max_interpolation_neighbors: 300 profiling: perform: false repeats: 1 From cda59078b2caabf20d9a7d440dc52b6639be9319 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Fri, 20 Oct 2023 18:12:33 +0100 Subject: [PATCH 2/4] fix exception --- autoarray/exc.py | 10 ---------- autoarray/structures/structure_decorators.py | 6 ++---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/autoarray/exc.py b/autoarray/exc.py index dd0b9a3b7..657ec8324 100644 --- a/autoarray/exc.py +++ b/autoarray/exc.py @@ -18,16 +18,6 @@ class ArrayException(Exception): pass - -class ConfigException(Exception): - """ - Raises exceptions associated with the `structures/array` modules and `Array` classes. - - For example if a 2D array's shape and its corresponding 2D mask shape do not match. - """ - - pass - class GridException(Exception): """ Raises exceptions associated with the `structures/grid` modules and `Grid` classes. diff --git a/autoarray/structures/structure_decorators.py b/autoarray/structures/structure_decorators.py index f5a6d30aa..f275111b2 100644 --- a/autoarray/structures/structure_decorators.py +++ b/autoarray/structures/structure_decorators.py @@ -3,6 +3,7 @@ from typing import List, Optional, Union from autoconf import conf +from autoconf.exc import ConfigException from autoarray.structures.arrays.uniform_1d import Array1D from autoarray.structures.arrays.uniform_2d import Array2D from autoarray.structures.grids.uniform_1d import Grid1D @@ -547,7 +548,7 @@ def wrapper( "radial_minimum" ][cls.__class__.__name__] except KeyError as e: - print( + raise ConfigException( fr""" The {cls.__class__.__name__} profile you are using does not have a corresponding entry in the `config/grid.yaml` config file. @@ -569,9 +570,6 @@ def wrapper( """ ) - import sys - sys.exit(1) - with np.errstate(all="ignore"): # Division by zero fixed via isnan grid_radii = cls.radial_grid_from(grid=grid) From 470ce3b43f0a795d26365802d8ab90e30d86eb3f Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 23 Oct 2023 10:12:45 +0100 Subject: [PATCH 3/4] black --- autoarray/mask/mask_2d_util.py | 2 +- autoarray/plot/mat_plot/two_d.py | 4 ++-- autoarray/plot/wrap/base/colorbar.py | 10 +++++++--- autoarray/structures/arrays/kernel_2d.py | 2 +- autoarray/structures/structure_decorators.py | 18 +++++++++--------- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/autoarray/mask/mask_2d_util.py b/autoarray/mask/mask_2d_util.py index dfb2e991c..1944774d5 100644 --- a/autoarray/mask/mask_2d_util.py +++ b/autoarray/mask/mask_2d_util.py @@ -1129,7 +1129,7 @@ def rescaled_mask_2d_from(mask_2d: np.ndarray, rescale_factor: float) -> np.ndar scale=rescale_factor, mode="edge", anti_aliasing=False, - # multichannel=False, + # multichannel=False, ) rescaled_mask_2d[0, :] = 1 diff --git a/autoarray/plot/mat_plot/two_d.py b/autoarray/plot/mat_plot/two_d.py index dc9de56f1..ac4583f2c 100644 --- a/autoarray/plot/mat_plot/two_d.py +++ b/autoarray/plot/mat_plot/two_d.py @@ -241,7 +241,7 @@ def plot_array( # so that if a mask is irregular and zooming in creates white edges, that instead it doesnt have the eddge. # This could just be a matplotlib settings to change the edge color? -# array = array.resized_from(new_shape=(401, 401)) + # array = array.resized_from(new_shape=(401, 401)) if array.mask.is_all_false: buffer = 0 @@ -340,7 +340,7 @@ def plot_array( levels = np.logspace(np.log10(0.3), np.log10(20.0), 10) plt.contour( - # array.mask.derive_grid.unmasked_sub_1, + # array.mask.derive_grid.unmasked_sub_1, array.native[::-1], levels=levels, colors="black", diff --git a/autoarray/plot/wrap/base/colorbar.py b/autoarray/plot/wrap/base/colorbar.py index d08f99a1e..fc545b7ab 100644 --- a/autoarray/plot/wrap/base/colorbar.py +++ b/autoarray/plot/wrap/base/colorbar.py @@ -18,7 +18,7 @@ def __init__( manual_tick_values: Optional[List[float]] = None, manual_alignment: Optional[str] = None, manual_unit: Optional[str] = None, - manual_log10 : bool = False, + manual_log10: bool = False, **kwargs, ): """ @@ -102,8 +102,12 @@ def manual_tick_labels_from( ] if self.manual_log10: - manual_tick_labels = ["{:.0e}".format(label) for label in manual_tick_labels] - manual_tick_labels = [label.replace("1e", "$10^{") + "}$" for label in manual_tick_labels] + manual_tick_labels = [ + "{:.0e}".format(label) for label in manual_tick_labels + ] + manual_tick_labels = [ + label.replace("1e", "$10^{") + "}$" for label in manual_tick_labels + ] manual_tick_labels = [ label.replace("{-0", "{-").replace("{+0", "{+").replace("+", "") for label in manual_tick_labels diff --git a/autoarray/structures/arrays/kernel_2d.py b/autoarray/structures/arrays/kernel_2d.py index 1af1bc3ad..8a595d9b7 100644 --- a/autoarray/structures/arrays/kernel_2d.py +++ b/autoarray/structures/arrays/kernel_2d.py @@ -465,7 +465,7 @@ def rescaled_with_odd_dimensions_from( rescale_factor, anti_aliasing=False, mode="constant", - # multichannel=False, + # multichannel=False, ) if kernel_rescaled.shape[0] % 2 == 0 and kernel_rescaled.shape[1] % 2 == 0: diff --git a/autoarray/structures/structure_decorators.py b/autoarray/structures/structure_decorators.py index f275111b2..15179916f 100644 --- a/autoarray/structures/structure_decorators.py +++ b/autoarray/structures/structure_decorators.py @@ -40,7 +40,7 @@ def wrapper( obj: object, grid: Union[Grid1D, Grid2D, Grid2DIterate, Grid2DIrregular], *args, - **kwargs + **kwargs, ) -> Union[Array1D, ArrayIrregular]: """ This decorator homogenizes the input of a "grid_like" 2D structure (`Grid2D`, `Grid2DIterate`, @@ -129,7 +129,7 @@ def wrapper( obj, grid: Union[Grid1D, Grid2D, Grid2DIterate, Grid2DIrregular], *args, - **kwargs + **kwargs, ) -> Union[Array1D, ArrayIrregular]: """ This decorator homogenizes the output of functions which compute a 1D result, by inspecting the output @@ -185,7 +185,7 @@ def wrapper( obj: object, grid: Union[np.ndarray, Grid2D, Grid2DIterate, Grid2DIrregular, Grid1D], *args, - **kwargs + **kwargs, ) -> Union[np.ndarray, Array2D, ArrayIrregular, Grid2D, Grid2DIrregular]: """ This decorator homogenizes the input of a "grid_like" 2D structure (`Grid2D`, `Grid2DIterate`, @@ -262,7 +262,7 @@ def wrapper( obj: object, grid: Union[np.ndarray, Grid2D, Grid2DIterate, Grid2DIrregular, Grid1D], *args, - **kwargs + **kwargs, ) -> List[Union[np.ndarray, Array2D, ArrayIrregular, Grid2D, Grid2DIrregular]]: """ This decorator serves the same purpose as the `grid_2d_to_structure` decorator, but it deals with functions @@ -330,7 +330,7 @@ def wrapper( obj: object, grid: Union[np.ndarray, Grid2D, Grid2DIterate, Grid2DIrregular, Grid1D], *args, - **kwargs + **kwargs, ) -> Union[np.ndarray, Array2D, ArrayIrregular, Grid2D, Grid2DIrregular]: """ This decorator homogenizes the input of a "grid_like" 2D vector_yx (`Grid2D`, `Grid2DIterate`, @@ -400,7 +400,7 @@ def wrapper( obj: object, grid: Union[np.ndarray, Grid2D, Grid2DIterate, Grid2DIrregular, Grid1D], *args, - **kwargs + **kwargs, ) -> List[Union[np.ndarray, Array2D, ArrayIrregular, Grid2D, Grid2DIrregular]]: """ This decorator serves the same purpose as the `grid_2d_to_vector_yx` decorator, but it deals with functions @@ -464,7 +464,7 @@ def wrapper( Grid2DIrregularTransformed, ], *args, - **kwargs + **kwargs, ) -> Union[ np.ndarray, Grid2D, @@ -527,7 +527,7 @@ def wrapper( cls, grid: Union[np.ndarray, Grid2D, Grid2DIrregular, Grid2DIterate], *args, - **kwargs + **kwargs, ) -> Union[np.ndarray, Grid2D, Grid2DIrregular, Grid2DIterate]: """ @@ -549,7 +549,7 @@ def wrapper( ][cls.__class__.__name__] except KeyError as e: raise ConfigException( - fr""" + rf""" The {cls.__class__.__name__} profile you are using does not have a corresponding entry in the `config/grid.yaml` config file. From cc270660ef2e0417ccac2a2f6619fcef23213599 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Mon, 23 Oct 2023 11:18:39 +0100 Subject: [PATCH 4/4] build serve fixes --- autoarray/inversion/inversion/inversion_util.py | 2 +- autoarray/preloads.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/autoarray/inversion/inversion/inversion_util.py b/autoarray/inversion/inversion/inversion_util.py index 644dd5f60..6be308bad 100644 --- a/autoarray/inversion/inversion/inversion_util.py +++ b/autoarray/inversion/inversion/inversion_util.py @@ -292,7 +292,7 @@ def reconstruction_positive_only_from( P_initial=P_initial, ) - except (RuntimeError, np.linalg.LinAlgError) as e: + except (RuntimeError, np.linalg.LinAlgError, ValueError) as e: raise exc.InversionException() from e else: diff --git a/autoarray/preloads.py b/autoarray/preloads.py index 99a5a1be0..e49e2b183 100644 --- a/autoarray/preloads.py +++ b/autoarray/preloads.py @@ -1,5 +1,6 @@ import logging import numpy as np +import os from typing import List from autoconf import conf @@ -465,6 +466,9 @@ def check_via_fit(self, fit): settings_inversion=settings_inversion, ) + if os.environ.get("PYAUTOFIT_TEST_MODE") == "1": + return + try: if ( abs(