From 16ee88a35fb906ab6a7fe81eb2695af3a68cc69f Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Wed, 25 Mar 2026 12:05:52 +0000 Subject: [PATCH 1/2] fixes to plotting --- autogalaxy/ellipse/model/plotter.py | 4 +- autogalaxy/imaging/model/plotter.py | 4 +- autogalaxy/plot/__init__.py | 2 +- docs/general/workspace.rst | 2 +- docs/index.rst | 2 +- test_autogalaxy/galaxy/test_galaxies.py | 150 +- test_autogalaxy/galaxy/test_galaxy.py | 173 +- test_autogalaxy/galaxy/test_to_inversion.py | 77 +- test_autogalaxy/imaging/test_fit_imaging.py | 1460 ++++++++++------- .../imaging/test_simulate_and_fit_imaging.py | 581 ++++--- test_autogalaxy/imaging/test_simulator.py | 417 +++-- .../interferometer/test_fit_interferometer.py | 875 ++++++---- .../interferometer/test_simulator.py | 282 +++- test_autogalaxy/operate/test_image.py | 67 +- .../profiles/light/linear/test_abstract.py | 43 +- .../light/shapelets/test_cartesian.py | 8 +- .../light/shapelets/test_exponential.py | 8 +- .../profiles/light/shapelets/test_polar.py | 8 +- .../profiles/light/standard/test_abstract.py | 65 +- .../profiles/light/standard/test_chameleon.py | 10 +- .../light/standard/test_dev_vaucouleurs.py | 11 +- .../profiles/light/standard/test_eff.py | 12 +- .../light/standard/test_exponential.py | 10 +- .../profiles/light/standard/test_gaussian.py | 10 +- .../profiles/light/standard/test_moffat.py | 6 +- .../profiles/light/standard/test_sersic.py | 10 +- .../light/standard/test_sersic_core.py | 5 +- .../profiles/light/test_decorators.py | 44 +- test_autogalaxy/profiles/light/test_snr.py | 11 +- test_autogalaxy/profiles/test_basis.py | 44 +- .../profiles/test_geometry_profiles.py | 63 +- .../profiles/test_light_and_mass_profiles.py | 319 +++- .../quantity/test_dataset_quantity.py | 31 +- test_autogalaxy/quantity/test_fit_quantity.py | 36 +- 34 files changed, 3232 insertions(+), 1618 deletions(-) diff --git a/autogalaxy/ellipse/model/plotter.py b/autogalaxy/ellipse/model/plotter.py index 0adbba405..96565bbae 100644 --- a/autogalaxy/ellipse/model/plotter.py +++ b/autogalaxy/ellipse/model/plotter.py @@ -4,7 +4,7 @@ import autoarray as aa -from autoarray.dataset.plot.imaging_plots import subplot_imaging +from autoarray.dataset.plot.imaging_plots import subplot_imaging_dataset from autogalaxy.ellipse.fit_ellipse import FitEllipse from autogalaxy.ellipse.plot import fit_ellipse_plots @@ -29,7 +29,7 @@ def should_plot(name): return plot_setting(section=["dataset", "imaging"], name=name) if should_plot("subplot_dataset"): - subplot_imaging( + subplot_imaging_dataset( dataset, output_path=self.image_path, output_format=self.fmt, diff --git a/autogalaxy/imaging/model/plotter.py b/autogalaxy/imaging/model/plotter.py index 8a24db78e..aba09e0c2 100644 --- a/autogalaxy/imaging/model/plotter.py +++ b/autogalaxy/imaging/model/plotter.py @@ -5,7 +5,7 @@ import autoarray as aa -from autoarray.dataset.plot.imaging_plots import subplot_imaging, subplot_imaging_dataset_list +from autoarray.dataset.plot.imaging_plots import subplot_imaging_dataset, subplot_imaging_dataset_list from autogalaxy.imaging.fit_imaging import FitImaging from autogalaxy.imaging.plot import fit_imaging_plots @@ -91,7 +91,7 @@ def should_plot(name): return plot_setting(section=["dataset", "imaging"], name=name) if should_plot("subplot_dataset"): - subplot_imaging( + subplot_imaging_dataset( dataset, output_path=self.image_path, output_format=self.fmt, diff --git a/autogalaxy/plot/__init__.py b/autogalaxy/plot/__init__.py index 69d766f51..f83ad9fd2 100644 --- a/autogalaxy/plot/__init__.py +++ b/autogalaxy/plot/__init__.py @@ -1,7 +1,7 @@ from autogalaxy.plot.plot_utils import plot_array, plot_grid from autoarray.dataset.plot.imaging_plots import ( - subplot_imaging, + subplot_imaging_dataset, subplot_imaging_dataset_list, ) from autoarray.dataset.plot.interferometer_plots import subplot_interferometer_dirty_images diff --git a/docs/general/workspace.rst b/docs/general/workspace.rst index 4c4a97806..8d082cc4d 100644 --- a/docs/general/workspace.rst +++ b/docs/general/workspace.rst @@ -54,5 +54,5 @@ The **HowToGalaxy** lecture series are a collection of Jupyter notebooks describ fitting project and giving illustrations of different statistical methods and techniques. Checkout the -`tutorials section `_ for a +`tutorials section `_ for a full description of the lectures and online examples of every notebook. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 72a6d8ce9..8d1f00357 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -133,7 +133,7 @@ and `PyNUFFT` [@pynufft]. We can use the grid and galaxies to perform many calculations, for example plotting the image of the galaxies. """ - galaxies_plotter = aplt.GalaxiesPlotter(galaxies=[galaxy], grid=grid) + galaxies_plotter = aplt.Galaxies(galaxies=[galaxy], grid=grid) galaxies_plotter.figures_2d(image=True) diff --git a/test_autogalaxy/galaxy/test_galaxies.py b/test_autogalaxy/galaxy/test_galaxies.py index 119655458..2042f6036 100644 --- a/test_autogalaxy/galaxy/test_galaxies.py +++ b/test_autogalaxy/galaxy/test_galaxies.py @@ -12,7 +12,9 @@ from autogalaxy import exc -def test__image_2d_from(grid_2d_7x7, gal_x1_lp): +def test__image_2d_from__single_galaxy__matches_light_profile_image( + grid_2d_7x7, gal_x1_lp +): light_profile = gal_x1_lp.cls_list_from(cls=ag.LightProfile)[0] lp_image = light_profile.image_2d_from(grid=grid_2d_7x7) @@ -23,6 +25,8 @@ def test__image_2d_from(grid_2d_7x7, gal_x1_lp): assert (image == lp_image).all() + +def test__image_2d_from__single_galaxy__matches_galaxy_image(grid_2d_7x7, gal_x1_lp): galaxy_image = gal_x1_lp.image_2d_from(grid=grid_2d_7x7) galaxies = ag.Galaxies(galaxies=[gal_x1_lp]) @@ -31,6 +35,10 @@ def test__image_2d_from(grid_2d_7x7, gal_x1_lp): assert image == pytest.approx(galaxy_image.array, 1.0e-4) + +def test__image_2d_from__two_galaxies__sum_matches_individual_galaxy_images( + grid_2d_7x7, +): # Overwrite one value so intensity in each pixel is different grid_2d_7x7[5] = np.array([2.0, 2.0]) @@ -38,7 +46,6 @@ def test__image_2d_from(grid_2d_7x7, gal_x1_lp): g1 = ag.Galaxy(redshift=0.5, light_profile=ag.lp.Sersic(intensity=2.0)) g0_image = g0.image_2d_from(grid=grid_2d_7x7) - g1_image = g1.image_2d_from(grid=grid_2d_7x7) galaxies = ag.Galaxies(galaxies=[g0, g1]) @@ -76,9 +83,10 @@ def test__image_2d_list_from(grid_2d_7x7): assert image_of_galaxies[1][1] == lp1_image[1] -def test__image_2d_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): +def test__image_2d_from__operated_only_false__returns_only_non_operated_images( + grid_2d_7x7, lp_0, lp_operated_0 +): image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) - image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) galaxy_0 = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) galaxy_1 = ag.Galaxy( @@ -91,18 +99,48 @@ def test__image_2d_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): image_2d = galaxies.image_2d_from(grid=grid_2d_7x7, operated_only=False) assert image_2d == pytest.approx(image_2d_not_operated.array, 1.0e-4) + +def test__image_2d_from__operated_only_true__returns_only_operated_images_summed( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + galaxy_1 = ag.Galaxy( + redshift=1.0, light_operated_0=lp_operated_0, light_operated_1=lp_operated_0 + ) + galaxy_2 = ag.Galaxy(redshift=2.0) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1, galaxy_2]) + image_2d = galaxies.image_2d_from(grid=grid_2d_7x7, operated_only=True) assert image_2d == pytest.approx(3.0 * image_2d_operated.array, 1.0e-4) + +def test__image_2d_from__operated_only_none__returns_all_images_summed( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + galaxy_1 = ag.Galaxy( + redshift=1.0, light_operated_0=lp_operated_0, light_operated_1=lp_operated_0 + ) + galaxy_2 = ag.Galaxy(redshift=2.0) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1, galaxy_2]) + image_2d = galaxies.image_2d_from(grid=grid_2d_7x7, operated_only=None) assert image_2d == pytest.approx( image_2d_not_operated.array + 3.0 * image_2d_operated.array, 1.0e-4 ) -def test__image_2d_list_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): +def test__image_2d_list_from__operated_only_false__non_operated_returned_operated_zeros( + grid_2d_7x7, lp_0, lp_operated_0 +): image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) - image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) galaxy_0 = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) galaxy_1 = ag.Galaxy( @@ -117,25 +155,55 @@ def test__image_2d_list_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated assert image_2d_list[1] == pytest.approx(np.zeros((9)), 1.0e-4) assert image_2d_list[2] == pytest.approx(np.zeros((9)), 1.0e-4) + +def test__image_2d_list_from__operated_only_true__operated_images_returned_non_operated_zeros( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + galaxy_1 = ag.Galaxy( + redshift=1.0, light_operated_0=lp_operated_0, light_operated_1=lp_operated_0 + ) + galaxy_2 = ag.Galaxy(redshift=2.0) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1, galaxy_2]) + image_2d_list = galaxies.image_2d_list_from(grid=grid_2d_7x7, operated_only=True) assert image_2d_list[0] == pytest.approx(image_2d_operated.array, 1.0e-4) assert image_2d_list[1] == pytest.approx(2.0 * image_2d_operated.array, 1.0e-4) assert image_2d_list[2] == pytest.approx(np.zeros((9)), 1.0e-4) + +def test__image_2d_list_from__operated_only_none__sum_of_list_matches_total_image( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + galaxy_1 = ag.Galaxy( + redshift=1.0, light_operated_0=lp_operated_0, light_operated_1=lp_operated_0 + ) + galaxy_2 = ag.Galaxy(redshift=2.0) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1, galaxy_2]) + image_2d_list = galaxies.image_2d_list_from(grid=grid_2d_7x7, operated_only=None) assert image_2d_list[0] + image_2d_list[1] == pytest.approx( image_2d_not_operated.array + 3.0 * image_2d_operated.array, 1.0e-4 ) -def test__galaxy_image_2d_dict_from(grid_2d_7x7): +def test__galaxy_image_2d_dict_from__no_operated_only__all_galaxies_correct( + grid_2d_7x7, +): g0 = ag.Galaxy(redshift=0.5, light_profile=ag.lp.Sersic(intensity=1.0)) g1 = ag.Galaxy( redshift=0.5, mass_profile=ag.mp.IsothermalSph(einstein_radius=1.0), light_profile=ag.lp.Sersic(intensity=2.0), ) - g2 = ag.Galaxy(redshift=0.5, light_profile=ag.lp_operated.Gaussian(intensity=3.0)) g0_image = g0.image_2d_from(grid=grid_2d_7x7) @@ -150,6 +218,22 @@ def test__galaxy_image_2d_dict_from(grid_2d_7x7): assert (galaxy_image_2d_dict[g1] == g1_image).all() assert (galaxy_image_2d_dict[g2] == g2_image).all() + +def test__galaxy_image_2d_dict_from__operated_only_true__non_operated_galaxies_return_zeros( + grid_2d_7x7, +): + g0 = ag.Galaxy(redshift=0.5, light_profile=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy( + redshift=0.5, + mass_profile=ag.mp.IsothermalSph(einstein_radius=1.0), + light_profile=ag.lp.Sersic(intensity=2.0), + ) + g2 = ag.Galaxy(redshift=0.5, light_profile=ag.lp_operated.Gaussian(intensity=3.0)) + + g2_image = g2.image_2d_from(grid=grid_2d_7x7) + + galaxies = ag.Galaxies(galaxies=[g1, g0, g2]) + galaxy_image_2d_dict = galaxies.galaxy_image_2d_dict_from( grid=grid_2d_7x7, operated_only=True ) @@ -158,6 +242,23 @@ def test__galaxy_image_2d_dict_from(grid_2d_7x7): assert (galaxy_image_2d_dict[g1] == np.zeros(shape=(9,))).all() assert (galaxy_image_2d_dict[g2] == g2_image).all() + +def test__galaxy_image_2d_dict_from__operated_only_false__operated_galaxy_returns_zeros( + grid_2d_7x7, +): + g0 = ag.Galaxy(redshift=0.5, light_profile=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy( + redshift=0.5, + mass_profile=ag.mp.IsothermalSph(einstein_radius=1.0), + light_profile=ag.lp.Sersic(intensity=2.0), + ) + g2 = ag.Galaxy(redshift=0.5, light_profile=ag.lp_operated.Gaussian(intensity=3.0)) + + g0_image = g0.image_2d_from(grid=grid_2d_7x7) + g1_image = g1.image_2d_from(grid=grid_2d_7x7) + + galaxies = ag.Galaxies(galaxies=[g1, g0, g2]) + galaxy_image_2d_dict = galaxies.galaxy_image_2d_dict_from( grid=grid_2d_7x7, operated_only=False ) @@ -172,7 +273,6 @@ def test__convergence_2d_from(grid_2d_7x7): g1 = ag.Galaxy(redshift=0.5, mass_profile=ag.mp.IsothermalSph(einstein_radius=2.0)) g0_convergence = g0.convergence_2d_from(grid=grid_2d_7x7) - g1_convergence = g1.convergence_2d_from(grid=grid_2d_7x7) galaxies = ag.Galaxies(galaxies=[g0, g1]) @@ -189,7 +289,6 @@ def test__potential_2d_from(grid_2d_7x7): g1 = ag.Galaxy(redshift=0.5, mass_profile=ag.mp.IsothermalSph(einstein_radius=2.0)) g0_potential = g0.potential_2d_from(grid=grid_2d_7x7) - g1_potential = g1.potential_2d_from(grid=grid_2d_7x7) galaxies = ag.Galaxies(galaxies=[g0, g1]) @@ -207,7 +306,6 @@ def test__deflections_yx_2d_from(grid_2d_7x7): g1 = ag.Galaxy(redshift=0.5, mass_profile=ag.mp.IsothermalSph(einstein_radius=2.0)) g0_deflections = g0.deflections_yx_2d_from(grid=grid_2d_7x7) - g1_deflections = g1.deflections_yx_2d_from(grid=grid_2d_7x7) galaxies = ag.Galaxies(galaxies=[g0, g1]) @@ -219,15 +317,19 @@ def test__deflections_yx_2d_from(grid_2d_7x7): ) -def test__has(): +def test__has__no_light_profiles__returns_false(): galaxies = ag.Galaxies(galaxies=[ag.Galaxy(redshift=0.5)]) assert galaxies.has(cls=ag.LightProfile) is False + +def test__has__single_galaxy_with_light_profile__returns_true(): galaxies = ag.Galaxies( galaxies=[ag.Galaxy(redshift=0.5, light_profile=ag.LightProfile())], ) assert galaxies.has(cls=ag.LightProfile) is True + +def test__has__mixed_galaxies_one_with_light_profile__returns_true(): galaxies = ag.Galaxies( galaxies=[ ag.Galaxy(redshift=0.5, light_profile=ag.LightProfile()), @@ -237,18 +339,24 @@ def test__has(): assert galaxies.has(cls=ag.LightProfile) is True -def test__cls_list_from(): +def test__cls_list_from__no_mass_profiles__returns_empty_list(): galaxies = ag.Galaxies(galaxies=[ag.Galaxy(redshift=0.5)]) assert galaxies.cls_list_from(cls=ag.mp.MassProfile) == [] + +def test__cls_list_from__single_galaxy_single_mass_profile__returns_profile(): sis_0 = ag.mp.IsothermalSph(einstein_radius=1.0) - sis_1 = ag.mp.IsothermalSph(einstein_radius=2.0) - sis_2 = ag.mp.IsothermalSph(einstein_radius=3.0) galaxies = ag.Galaxies(galaxies=[ag.Galaxy(redshift=0.5, mass_profile=sis_0)]) assert galaxies.cls_list_from(cls=ag.mp.MassProfile) == [sis_0] + +def test__cls_list_from__two_galaxies_multiple_mass_profiles__returns_all_profiles(): + sis_0 = ag.mp.IsothermalSph(einstein_radius=1.0) + sis_1 = ag.mp.IsothermalSph(einstein_radius=2.0) + sis_2 = ag.mp.IsothermalSph(einstein_radius=3.0) + galaxies = ag.Galaxies( galaxies=[ ag.Galaxy(redshift=0.5, mass_profile_0=sis_0, mass_profile_1=sis_1), @@ -257,6 +365,8 @@ def test__cls_list_from(): ) assert galaxies.cls_list_from(cls=ag.mp.MassProfile) == [sis_0, sis_1, sis_2, sis_1] + +def test__cls_list_from__single_pixelization_galaxy__returns_pixelization(): pixelization = ag.m.MockPixelization(mapper=1) galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) @@ -265,17 +375,21 @@ def test__cls_list_from(): assert galaxies.cls_list_from(cls=ag.Pixelization)[0].mapper == 1 - galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - pixelization = ag.m.MockPixelization(mapper=2) +def test__cls_list_from__two_pixelization_galaxies__returns_both_pixelizations(): + pixelization_0 = ag.m.MockPixelization(mapper=1) + pixelization_1 = ag.m.MockPixelization(mapper=2) - galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization_0) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization_1) galaxies = ag.Galaxies(galaxies=[galaxy_pix_0, galaxy_pix_1]) assert galaxies.cls_list_from(cls=ag.Pixelization)[0].mapper == 1 assert galaxies.cls_list_from(cls=ag.Pixelization)[1].mapper == 2 + +def test__cls_list_from__no_pixelization_galaxy__returns_empty_list(): galaxy_no_pix = ag.Galaxy(redshift=0.5) galaxies = ag.Galaxies(galaxies=[galaxy_no_pix]) diff --git a/test_autogalaxy/galaxy/test_galaxy.py b/test_autogalaxy/galaxy/test_galaxy.py index 7cf02fc75..a2069dbe1 100644 --- a/test_autogalaxy/galaxy/test_galaxy.py +++ b/test_autogalaxy/galaxy/test_galaxy.py @@ -8,13 +8,17 @@ from autogalaxy import exc -def test__cls_list_from(lp_0, lp_linear_0): +def test__cls_list_from__single_standard_light_profile__returns_profile_in_list(lp_0): gal = ag.Galaxy(redshift=0.5, light_0=lp_0) cls_list = gal.cls_list_from(cls=ag.LightProfile) assert cls_list == [lp_0] + +def test__cls_list_from__linear_profiles_with_cls_filtered__returns_empty_list( + lp_linear_0, +): gal = ag.Galaxy( redshift=0.5, light_linear_0=lp_linear_0, light_linear_1=lp_linear_0 ) @@ -25,16 +29,34 @@ def test__cls_list_from(lp_0, lp_linear_0): assert cls_list == [] + +def test__cls_list_from__linear_profiles_without_filter__returns_all_profiles( + lp_linear_0, +): + gal = ag.Galaxy( + redshift=0.5, light_linear_0=lp_linear_0, light_linear_1=lp_linear_0 + ) + cls_list = gal.cls_list_from(cls=ag.LightProfile) assert cls_list == [lp_linear_0, lp_linear_0] + +def test__cls_list_from__filter_by_linear_class__returns_only_linear_profiles( + lp_linear_0, +): + gal = ag.Galaxy( + redshift=0.5, light_linear_0=lp_linear_0, light_linear_1=lp_linear_0 + ) + cls_list = gal.cls_list_from(cls=ag.lp_linear.LightProfileLinear) assert cls_list == [lp_linear_0, lp_linear_0] -def test__image_2d_from(grid_2d_7x7, gal_x2_lp): +def test__image_2d_from__two_light_profiles__sum_matches_individual_profile_images( + grid_2d_7x7, gal_x2_lp +): lp_0_image = gal_x2_lp.light_profile_0.image_2d_from(grid=grid_2d_7x7) lp_1_image = gal_x2_lp.light_profile_1.image_2d_from(grid=grid_2d_7x7) @@ -45,25 +67,44 @@ def test__image_2d_from(grid_2d_7x7, gal_x2_lp): assert gal_image == pytest.approx(lp_image.array, 1.0e-4) -def test__image_2d_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): +def test__image_2d_from__operated_only_false__returns_only_non_operated_profile_image( + grid_2d_7x7, lp_0, lp_operated_0 +): image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) - image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) galaxy = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) image_2d = galaxy.image_2d_from(grid=grid_2d_7x7, operated_only=False) assert (image_2d == image_2d_not_operated).all() + +def test__image_2d_from__operated_only_true__returns_only_operated_profile_image( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + image_2d = galaxy.image_2d_from(grid=grid_2d_7x7, operated_only=True) assert (image_2d == image_2d_operated).all() + +def test__image_2d_from__operated_only_none__returns_sum_of_operated_and_non_operated_images( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + image_2d = galaxy.image_2d_from(grid=grid_2d_7x7, operated_only=None) assert (image_2d == image_2d_not_operated + image_2d_operated).all() -def test__image_2d_list_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): +def test__image_2d_list_from__operated_only_false__non_operated_returned_operated_zeros( + grid_2d_7x7, lp_0, lp_operated_0 +): image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) - image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) galaxy = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) @@ -71,34 +112,54 @@ def test__image_2d_list_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated assert (image_2d_list[0] == image_2d_not_operated).all() assert (image_2d_list[1] == np.zeros((9))).all() + +def test__image_2d_list_from__operated_only_true__non_operated_zeros_operated_returned( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + image_2d_list = galaxy.image_2d_list_from(grid=grid_2d_7x7, operated_only=True) assert (image_2d_list[0] == np.zeros((9))).all() assert (image_2d_list[1] == image_2d_operated).all() + +def test__image_2d_list_from__operated_only_none__list_sums_to_total_image( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + galaxy = ag.Galaxy(redshift=0.5, light=lp_0, light_operated=lp_operated_0) + image_2d_list = galaxy.image_2d_list_from(grid=grid_2d_7x7, operated_only=None) assert ( image_2d_list[0] + image_2d_list[1] == image_2d_not_operated + image_2d_operated ).all() -def test__luminosity_within_circle(lp_0, lp_1, gal_x2_lp): +def test__luminosity_within_circle__two_light_profiles__sums_individual_luminosities( + lp_0, lp_1, gal_x2_lp +): lp_0_luminosity = lp_0.luminosity_within_circle_from(radius=0.5) - lp_1_luminosity = lp_1.luminosity_within_circle_from(radius=0.5) gal_luminosity = gal_x2_lp.luminosity_within_circle_from(radius=0.5) assert lp_0_luminosity + lp_1_luminosity == gal_luminosity + +def test__luminosity_within_circle__no_light_profile__returns_none(): gal_no_lp = ag.Galaxy(redshift=0.5, mass=ag.mp.IsothermalSph()) assert gal_no_lp.luminosity_within_circle_from(radius=1.0) == None -def test__convergence_2d_from(grid_2d_7x7, mp_0, gal_x1_mp, mp_1, gal_x2_mp): +def test__convergence_2d_from__two_mass_profiles__matches_sum_of_individual_convergences( + grid_2d_7x7, mp_0, gal_x1_mp, mp_1, gal_x2_mp +): mp_0_convergence = gal_x2_mp.mass_profile_0.convergence_2d_from(grid=grid_2d_7x7) - mp_1_convergence = gal_x2_mp.mass_profile_1.convergence_2d_from(grid=grid_2d_7x7) - mp_convergence = mp_0_convergence + mp_1_convergence gal_convergence = gal_x2_mp.convergence_2d_from(grid=grid_2d_7x7) @@ -106,11 +167,11 @@ def test__convergence_2d_from(grid_2d_7x7, mp_0, gal_x1_mp, mp_1, gal_x2_mp): assert gal_convergence[0] == mp_convergence[0] -def test__potential_2d_from(grid_2d_7x7, gal_x2_mp): +def test__potential_2d_from__two_mass_profiles__matches_sum_of_individual_potentials( + grid_2d_7x7, gal_x2_mp +): mp_0_potential = gal_x2_mp.mass_profile_0.potential_2d_from(grid=grid_2d_7x7) - mp_1_potential = gal_x2_mp.mass_profile_1.potential_2d_from(grid=grid_2d_7x7) - mp_potential = mp_0_potential + mp_1_potential gal_potential = gal_x2_mp.potential_2d_from(grid=grid_2d_7x7) @@ -118,11 +179,11 @@ def test__potential_2d_from(grid_2d_7x7, gal_x2_mp): assert gal_potential[0] == mp_potential[0] -def test__deflections_yx_2d_from(grid_2d_7x7, gal_x2_mp): +def test__deflections_yx_2d_from__two_mass_profiles__matches_sum_of_individual_deflections( + grid_2d_7x7, gal_x2_mp +): mp_0_deflections = gal_x2_mp.mass_profile_0.deflections_yx_2d_from(grid=grid_2d_7x7) - mp_1_deflections = gal_x2_mp.mass_profile_1.deflections_yx_2d_from(grid=grid_2d_7x7) - mp_deflections = mp_0_deflections + mp_1_deflections gal_deflections = gal_x2_mp.deflections_yx_2d_from(grid=grid_2d_7x7) @@ -131,37 +192,44 @@ def test__deflections_yx_2d_from(grid_2d_7x7, gal_x2_mp): assert gal_deflections[1, 0] == mp_deflections[1, 0] -def test__no_mass_profile__quantities_returned_as_0s_of_shape_grid( - grid_2d_7x7, mp_0, gal_x1_mp, mp_1, gal_x2_mp -): +def test__no_mass_profile__potential_2d_from__returns_zeros_of_grid_shape(grid_2d_7x7): galaxy = ag.Galaxy(redshift=0.5) potential = galaxy.potential_2d_from(grid=grid_2d_7x7) assert (potential.slim == np.zeros(shape=grid_2d_7x7.shape_slim)).all() + +def test__no_mass_profile__deflections_yx_2d_from__returns_zeros_of_grid_shape( + grid_2d_7x7, +): + galaxy = ag.Galaxy(redshift=0.5) + deflections = galaxy.deflections_yx_2d_from(grid=grid_2d_7x7) assert (deflections.slim == np.zeros(shape=(grid_2d_7x7.shape_slim, 2))).all() assert (deflections.native == np.zeros(shape=(7, 7, 2))).all() -def test__mass_angular_within_circle_from(mp_0, mp_1, gal_x2_mp): +def test__mass_angular_within_circle_from__two_mass_profiles__sums_individual_masses( + mp_0, mp_1, gal_x2_mp +): mp_0_mass = mp_0.mass_angular_within_circle_from(radius=0.5) - mp_1_mass = mp_1.mass_angular_within_circle_from(radius=0.5) gal_mass = gal_x2_mp.mass_angular_within_circle_from(radius=0.5) assert mp_0_mass + mp_1_mass == gal_mass + +def test__mass_angular_within_circle_from__no_mass_profile__raises_galaxy_exception(): gal_no_mp = ag.Galaxy(redshift=0.5, light=ag.lp.SersicSph()) with pytest.raises(exc.GalaxyException): gal_no_mp.mass_angular_within_circle_from(radius=1.0) -def test__light_and_mass_profiles__contained_in_light_and_mass_profile_lists( - lmp_0, lp_0, lp_1, mp_0 +def test__light_and_mass_profiles__single_lmp__contained_in_both_light_and_mass_lists( + lmp_0, ): gal_x1_lmp = ag.Galaxy(redshift=0.5, profile=lmp_0) @@ -171,19 +239,25 @@ def test__light_and_mass_profiles__contained_in_light_and_mass_profile_lists( assert gal_x1_lmp.cls_list_from(cls=ag.mp.MassProfile)[0] == lmp_0 assert gal_x1_lmp.cls_list_from(cls=ag.LightProfile)[0] == lmp_0 + +def test__light_and_mass_profiles__mixed_galaxy__counts_match_profile_types( + lmp_0, lp_0, mp_0 +): gal_multi_profiles = ag.Galaxy(redshift=0.5, profile=lmp_0, light=lp_0, sie=mp_0) assert 2 == len(gal_multi_profiles.cls_list_from(cls=ag.LightProfile)) assert 2 == len(gal_multi_profiles.cls_list_from(cls=ag.mp.MassProfile)) -def test__extract_attribute(): +def test__extract_attribute__no_profiles__returns_none(): galaxy = ag.Galaxy(redshift=0.5) values = galaxy.extract_attribute(cls=ag.LightProfile, attr_name="value") assert values == None + +def test__extract_attribute__three_light_profiles__returns_scalar_values_in_list(): galaxy = ag.Galaxy( redshift=0.5, lp_0=ag.m.MockLightProfile(value=0.9, value1=(0.0, 1.0)), @@ -199,6 +273,8 @@ def test__extract_attribute(): assert values.in_list == [(0.0, 1.0), (2.0, 3.0), (4.0, 5.0)] + +def test__extract_attribute__mixed_light_and_mass_profiles__filters_by_cls(): galaxy = ag.Galaxy( redshift=0.5, lp_3=ag.LightProfile(), @@ -225,9 +301,8 @@ def test__image_2d_from__does_not_include_linear_light_profiles(grid_2d_7x7, lp_ assert (image == lp_image).all() -def test__light_profile_2d_quantity_from_grid__symmetric_profiles_give_symmetric_results(): +def test__light_profile_2d_quantity_from_grid__x2_sersic_profiles__images_at_symmetric_positions_match(): lp_0 = ag.lp.Sersic(centre=(0.0, 0.0), intensity=1.0) - lp_1 = ag.lp.Sersic(centre=(100.0, 0.0), intensity=1.0) gal_x2_lp = ag.Galaxy(redshift=0.5, light_profile_0=lp_0, light_profile_1=lp_1) @@ -244,6 +319,8 @@ def test__light_profile_2d_quantity_from_grid__symmetric_profiles_give_symmetric gal_x2_lp.image_2d_from(grid=ag.Grid2DIrregular([[51.0, 0.0]])).array, 1.0e-4 ) + +def test__light_profile_2d_quantity_from_grid__x4_sersic_profiles__images_at_four_way_symmetric_positions_match(): lp_0 = ag.lp.Sersic( ell_comps=(0.0, 0.0), intensity=1.0, @@ -308,7 +385,7 @@ def test__light_profile_2d_quantity_from_grid__symmetric_profiles_give_symmetric ) -def test__mass_profile_2d_quantity_from_grid__symmetric_profiles_give_symmetric_results(): +def test__mass_profile_2d_quantity_from_grid__isothermal_x2_profiles__symmetric_convergence_potential_deflections(): mp_0 = ag.mp.Isothermal(ell_comps=(0.333333, 0.0), einstein_radius=1.0) mp_1 = ag.mp.Isothermal( @@ -357,12 +434,11 @@ def test__mass_profile_2d_quantity_from_grid__symmetric_profiles_give_symmetric_ 1e-6, ) - mp_0 = ag.mp.IsothermalSph(einstein_radius=1.0) +def test__mass_profile_2d_quantity_from_grid__isothermal_sph_x4_profiles__four_way_symmetric_convergence_potential_deflections(): + mp_0 = ag.mp.IsothermalSph(einstein_radius=1.0) mp_1 = ag.mp.IsothermalSph(centre=(100, 0), einstein_radius=1.0) - mp_2 = ag.mp.IsothermalSph(centre=(0, 100), einstein_radius=1.0) - mp_3 = ag.mp.IsothermalSph(centre=(100, 100), einstein_radius=1.0) gal_x4_mp = ag.Galaxy( @@ -499,7 +575,7 @@ def test__mass_profile_2d_quantity_from_grid__symmetric_profiles_give_symmetric_ ) -def test__centre_of_profile_in_right_place(): +def test__centre_of_profile_in_right_place__isothermal_elliptical__convergence_potential_deflections_peak_at_correct_pixel(): grid = ag.Grid2D.uniform(shape_native=(7, 7), pixel_scales=1.0) galaxy = ag.Galaxy( @@ -524,11 +600,16 @@ def test__centre_of_profile_in_right_place(): assert deflections.native[1, 4, 1] > 0 assert deflections.native[1, 3, 1] < 0 + +def test__centre_of_profile_in_right_place__isothermal_sph__convergence_potential_deflections_peak_at_correct_pixel(): + grid = ag.Grid2D.uniform(shape_native=(7, 7), pixel_scales=1.0) + galaxy = ag.Galaxy( redshift=0.5, mass=ag.mp.IsothermalSph(centre=(1.99999, 0.99999), einstein_radius=1.0), mass_0=ag.mp.IsothermalSph(centre=(1.99999, 0.99999), einstein_radius=1.0), ) + convergence = galaxy.convergence_2d_from(grid=grid) max_indexes = np.unravel_index( convergence.native.argmax(), convergence.shape_native @@ -546,17 +627,24 @@ def test__centre_of_profile_in_right_place(): assert deflections.native[1, 3, 1] < 0 -def test__cannot_pass_light_or_mass_list(): +def test__cannot_pass_light_list__raises_galaxy_exception(): light_list = [ag.lp.Sersic(), ag.lp.Sersic()] with pytest.raises(exc.GalaxyException): ag.Galaxy(redshift=0.5, light=light_list) + +def test__cannot_pass_mass_list__raises_galaxy_exception(): mass_list = [ag.mp.Sersic(), ag.mp.Sersic()] with pytest.raises(exc.GalaxyException): ag.Galaxy(redshift=0.5, mass=mass_list) + +def test__cannot_pass_light_and_mass_lists__raises_galaxy_exception(): + light_list = [ag.lp.Sersic(), ag.lp.Sersic()] + mass_list = [ag.mp.Sersic(), ag.mp.Sersic()] + with pytest.raises(exc.GalaxyException): ag.Galaxy(redshift=0.5, light=light_list, mass=mass_list) @@ -583,7 +671,9 @@ def test__decorator__grid_sub_in__numericas(): image = galaxy.image_2d_from(grid=grid) -def test__decorator__oversample_uniform__numerical_values(gal_x1_lp): +def test__decorator__oversample_uniform__over_sample_size_1__correct_numerical_values( + gal_x1_lp, +): mask = ag.Mask2D( mask=[ [True, True, True, True, True], @@ -610,6 +700,21 @@ def test__decorator__oversample_uniform__numerical_values(gal_x1_lp): assert image[0] == pytest.approx(0.17481917162057087, 1.0e-6) assert image[1] == pytest.approx(0.391168560508937, 1.0e-6) + +def test__decorator__oversample_uniform__profile_offset_from_centre__correct_numerical_values( + gal_x1_lp, +): + mask = ag.Mask2D( + mask=[ + [True, True, True, True, True], + [True, False, False, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + ], + pixel_scales=(1.0, 1.0), + ) + galaxy = ag.Galaxy( redshift=0.5, light=ag.lp.Sersic(centre=(3.0, 3.0), intensity=1.0) ) diff --git a/test_autogalaxy/galaxy/test_to_inversion.py b/test_autogalaxy/galaxy/test_to_inversion.py index 55a3ec6c6..2e609cd08 100644 --- a/test_autogalaxy/galaxy/test_to_inversion.py +++ b/test_autogalaxy/galaxy/test_to_inversion.py @@ -4,7 +4,9 @@ import autogalaxy as ag -def test__lp_linear_func_list_galaxy_dict(lp_0, masked_imaging_7x7): +def test__lp_linear_func_list_galaxy_dict__no_linear_profiles__returns_empty_dict( + lp_0, masked_imaging_7x7 +): to_inversion = ag.GalaxiesToInversion( galaxies=[ag.Galaxy(redshift=0.5)], dataset=masked_imaging_7x7 ) @@ -13,6 +15,10 @@ def test__lp_linear_func_list_galaxy_dict(lp_0, masked_imaging_7x7): assert lp_linear_func_galaxy_dict == {} + +def test__lp_linear_func_list_galaxy_dict__multiple_galaxies_with_linear_profiles__maps_profiles_to_correct_galaxies( + lp_0, masked_imaging_7x7 +): lp_linear_0 = ag.lp_linear.LightProfileLinear() lp_linear_1 = ag.lp_linear.LightProfileLinear() lp_linear_2 = ag.lp_linear.LightProfileLinear() @@ -20,7 +26,6 @@ def test__lp_linear_func_list_galaxy_dict(lp_0, masked_imaging_7x7): g0 = ag.Galaxy( redshift=0.5, lp_0=lp_0, light_linear_0=lp_linear_0, light_linear_1=lp_linear_1 ) - g1 = ag.Galaxy(redshift=0.5, light_linear=lp_linear_2) to_inversion = ag.GalaxiesToInversion(galaxies=[g0, g1], dataset=masked_imaging_7x7) @@ -37,9 +42,18 @@ def test__lp_linear_func_list_galaxy_dict(lp_0, masked_imaging_7x7): assert lp_linear_func_list[1].light_profile_list[0] == lp_linear_1 assert lp_linear_func_list[2].light_profile_list[0] == lp_linear_2 + +def test__lp_linear_func_list_galaxy_dict__basis_galaxy__groups_profiles_under_basis( + masked_imaging_7x7 +): + lp_linear_0 = ag.lp_linear.LightProfileLinear() + lp_linear_1 = ag.lp_linear.LightProfileLinear() + lp_linear_2 = ag.lp_linear.LightProfileLinear() + basis = ag.lp_basis.Basis(profile_list=[lp_linear_0, lp_linear_1]) g0 = ag.Galaxy(redshift=0.5, bulge=basis) + g1 = ag.Galaxy(redshift=0.5, light_linear=lp_linear_2) to_inversion = ag.GalaxiesToInversion(galaxies=[g0, g1], dataset=masked_imaging_7x7) @@ -55,14 +69,12 @@ def test__lp_linear_func_list_galaxy_dict(lp_0, masked_imaging_7x7): assert lp_linear_func_list[1].light_profile_list[1] == lp_linear_1 -def test__image_plane_mesh_grid_list(masked_imaging_7x7): - +def test__image_plane_mesh_grid_list__with_adapt_images__returns_adapt_mesh_grid( + masked_imaging_7x7, +): pixelization = ag.m.MockPixelization() - galaxy_pix = ag.Galaxy( - redshift=0.5, - pixelization=pixelization, - ) + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) adapt_images = ag.AdaptImages( galaxy_image_dict={galaxy_pix: 2}, @@ -77,7 +89,13 @@ def test__image_plane_mesh_grid_list(masked_imaging_7x7): assert image_plane_mesh_grid_list[0] == 3 - # No Adapt Images + +def test__image_plane_mesh_grid_list__no_adapt_images__returns_none_in_list( + masked_imaging_7x7, +): + pixelization = ag.m.MockPixelization() + + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) to_inversion = ag.GalaxiesToInversion( galaxies=[galaxy_pix], @@ -88,8 +106,10 @@ def test__image_plane_mesh_grid_list(masked_imaging_7x7): assert image_plane_mesh_grid_list[0] is None - # No Galalxies +def test__image_plane_mesh_grid_list__no_pixelization_galaxies__returns_none( + masked_imaging_7x7, +): galaxy_no_pix = ag.Galaxy(redshift=0.5) to_inversion = ag.GalaxiesToInversion( @@ -101,9 +121,10 @@ def test__image_plane_mesh_grid_list(masked_imaging_7x7): assert image_plane_mesh_grid_list is None -def test__mapper_galaxy_dict(masked_imaging_7x7): +def test__mapper_galaxy_dict__single_pixelization_galaxy__mapper_has_correct_pixels( + masked_imaging_7x7, +): mesh = ag.mesh.RectangularUniform(shape=(3, 3)) - pixelization = ag.m.MockPixelization(mesh=mesh) galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) @@ -120,10 +141,18 @@ def test__mapper_galaxy_dict(masked_imaging_7x7): assert mapper_list[0].pixels == 9 assert mapper_galaxy_dict[mapper_list[0]] == galaxy_pix - mesh = ag.mesh.RectangularUniform(shape=(4, 3)) + +def test__mapper_galaxy_dict__two_pixelization_galaxies__both_mappers_correct( + masked_imaging_7x7, +): + mesh = ag.mesh.RectangularUniform(shape=(3, 3)) pixelization = ag.m.MockPixelization(mesh=mesh) + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + mesh_2 = ag.mesh.RectangularUniform(shape=(4, 3)) + pixelization_2 = ag.m.MockPixelization(mesh=mesh_2) + galaxy_pix_2 = ag.Galaxy(redshift=0.5, pixelization=pixelization_2) - galaxy_pix_2 = ag.Galaxy(redshift=0.5, pixelization=pixelization) galaxy_no_pix = ag.Galaxy(redshift=0.5) to_inversion = ag.GalaxiesToInversion( @@ -141,6 +170,10 @@ def test__mapper_galaxy_dict(masked_imaging_7x7): assert mapper_galaxy_dict[mapper_list[0]] == galaxy_pix assert mapper_galaxy_dict[mapper_list[1]] == galaxy_pix_2 + +def test__mapper_galaxy_dict__no_pixelization_galaxy__returns_empty_dict( + masked_imaging_7x7, +): galaxy_no_pix = ag.Galaxy(redshift=0.5) to_inversion = ag.GalaxiesToInversion( @@ -152,7 +185,9 @@ def test__mapper_galaxy_dict(masked_imaging_7x7): assert mapper_galaxy_dict == {} -def test__inversion_imaging_from(grid_2d_7x7, masked_imaging_7x7): +def test__inversion_imaging_from__linear_light_profile__correct_reconstruction( + grid_2d_7x7, masked_imaging_7x7 +): g_linear = ag.Galaxy( redshift=0.5, light_linear=ag.lp_linear.Sersic(centre=(0.05, 0.05)) ) @@ -166,6 +201,10 @@ def test__inversion_imaging_from(grid_2d_7x7, masked_imaging_7x7): assert inversion.reconstruction[0] == pytest.approx(0.186868464426, 1.0e-2) + +def test__inversion_imaging_from__rectangular_pixelization__reconstructed_data_matches_input( + grid_2d_7x7, masked_imaging_7x7 +): pixelization = ag.Pixelization( mesh=ag.mesh.RectangularUniform(shape=(3, 3)), regularization=ag.reg.Constant(coefficient=0.0), @@ -185,7 +224,9 @@ def test__inversion_imaging_from(grid_2d_7x7, masked_imaging_7x7): ) -def test__inversion_interferometer_from(grid_2d_7x7, interferometer_7): +def test__inversion_interferometer_from__linear_light_profile__correct_reconstruction( + grid_2d_7x7, interferometer_7 +): g_linear = ag.Galaxy( redshift=0.5, light_linear=ag.lp_linear.Sersic(centre=(0.05, 0.05)) ) @@ -199,6 +240,10 @@ def test__inversion_interferometer_from(grid_2d_7x7, interferometer_7): assert inversion.reconstruction[0] == pytest.approx(0.04124846952, 1.0e-2) + +def test__inversion_interferometer_from__rectangular_pixelization__reconstructed_visibilities_match_input( + grid_2d_7x7, interferometer_7 +): interferometer_7.data = ag.Visibilities.ones(shape_slim=(7,)) pixelization = ag.Pixelization( diff --git a/test_autogalaxy/imaging/test_fit_imaging.py b/test_autogalaxy/imaging/test_fit_imaging.py index 030d8593a..7e6d509e0 100644 --- a/test_autogalaxy/imaging/test_fit_imaging.py +++ b/test_autogalaxy/imaging/test_fit_imaging.py @@ -1,638 +1,822 @@ -import copy -import numpy as np -import pytest - -import autogalaxy as ag - - -def test__model_image__with_and_without_psf_blurring( - masked_imaging_7x7_no_blur, masked_imaging_7x7 -): - g0 = ag.Galaxy( - redshift=0.5, - bulge=ag.m.MockLightProfile(image_2d_value=1.0, image_2d_first_value=2.0), - ) - - fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0]) - - assert fit.model_data.slim == pytest.approx( - np.array([2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), 1.0e-4 - ) - assert fit.log_likelihood == pytest.approx(-14.63377, 1.0e-4) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0]) - - assert fit.model_data.slim == pytest.approx( - np.array([1.33, 1.16, 1.0, 1.16, 1.0, 1.0, 1.0, 1.0, 1.0]), 1.0e-1 - ) - assert fit.log_likelihood == pytest.approx(-14.52960, 1.0e-4) - - -def test__fit_figure_of_merit( - masked_imaging_7x7, - masked_imaging_covariance_7x7, -): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) - - assert fit.perform_inversion is False - assert fit.figure_of_merit == pytest.approx(-71.46911964, 1.0e-4) - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), - ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), - ] - ) - - g0 = ag.Galaxy(redshift=0.5, bulge=basis) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0]) - - assert fit.perform_inversion is False - assert fit.figure_of_merit == pytest.approx(-71.46911964, 1.0e-4) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, galaxies=[ag.Galaxy(redshift=0.5), galaxy_pix] - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-22.91411868616, 1.0e-4) - - galaxy_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)) - ) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[galaxy_light, galaxy_pix]) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-29.235208518732776, 1.0e-4) - - g0_linear_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) - ) - - g1_linear_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) - ) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, galaxies=[g0_linear_light, g1_linear_light] - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-14.544339716, 1.0e-4) - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), - ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), - ] - ) - - g0 = ag.Galaxy(redshift=0.5, bulge=basis) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0]) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-14.544339716, 1.0e-4) - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), - ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), - ], - regularization=ag.reg.Constant(coefficient=1.0), - ) - - g0 = ag.Galaxy(redshift=0.5, bulge=basis) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0]) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-25.83890655, 1.0e-4) - - g0_operated_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp_operated.Sersic(intensity=1.0, centre=(0.05, 0.05)) - ) - g1_operated_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp_operated.Sersic(intensity=1.0, centre=(0.05, 0.05)) - ) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, galaxies=[g0_operated_light, g1_operated_light] - ) - - assert fit.perform_inversion is False - assert fit.figure_of_merit == pytest.approx(-289.6050404, 1.0e-4) - - g0_linear_operated_light = ag.Galaxy( - redshift=0.5, - bulge=ag.lp_linear_operated.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), - ) - g1_linear_operated_light = ag.Galaxy( - redshift=0.5, - bulge=ag.lp_linear_operated.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), - ) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, - galaxies=[g0_linear_operated_light, g1_linear_operated_light], - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-14.7635041, 1.0e-4) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, galaxies=[g0_linear_light, galaxy_pix] - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-22.8918119554022, 1.0e-4) - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - - fit = ag.FitImaging(dataset=masked_imaging_covariance_7x7, galaxies=[g0, g1]) - - assert fit.perform_inversion is False - assert fit.figure_of_merit == pytest.approx(-107.62350171, 1.0e-4) - - -def test__fit__model_dataset__sky___handles_special_behaviour(masked_imaging_7x7): - g0 = ag.Galaxy( - redshift=0.5, - bulge=ag.lp_linear.Sersic(sersic_index=1.0), - ) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, - galaxies=[g0], - dataset_model=ag.DatasetModel(background_sky_level=5.0), - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-21.6970706693, 1.0e-4) - - -def test__fit__model_dataset__grid_offset__handles_special_behaviour( - masked_imaging_7x7, - masked_imaging_7x7_sub_2, -): - g0 = ag.Galaxy( - redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) - ) - g1 = ag.Galaxy( - redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) - ) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, - galaxies=[g0, g1], - dataset_model=ag.DatasetModel(grid_offset=(1.0, 2.0)), - ) - - assert fit.figure_of_merit == pytest.approx(-71.4691196459, 1.0e-4) - - g0 = ag.Galaxy( - redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) - ) - g1 = ag.Galaxy( - redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) - ) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7_sub_2, - galaxies=[g0, g1], - dataset_model=ag.DatasetModel(grid_offset=(1.0, 2.0)), - ) - - assert fit.figure_of_merit == pytest.approx(-14.93272811, 1.0e-4) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, - galaxies=[ag.Galaxy(redshift=0.5), galaxy_pix], - dataset_model=ag.DatasetModel(grid_offset=(1.0, 2.0)), - ) - - assert fit.figure_of_merit == pytest.approx(-22.914118686169, 1.0e-4) - - -def test__galaxy_image_dict(masked_imaging_7x7): - # Normal Light Profiles Only - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0)) - g2 = ag.Galaxy( - redshift=0.5, - light_profile_0=ag.lp.Sersic(intensity=1.0), - light_profile_1=ag.lp.Sersic(intensity=2.0), - ) - g3 = ag.Galaxy(redshift=0.5) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1, g2, g3]) - - g0_image_2d = g0.image_2d_from( - grid=masked_imaging_7x7.grids.lp, - ) - - g1_image_2d = g1.image_2d_from( - grid=masked_imaging_7x7.grids.lp, - ) - - assert fit.galaxy_image_dict[g0] == pytest.approx(g0_image_2d.array, 1.0e-4) - assert fit.galaxy_image_dict[g1] == pytest.approx(g1_image_2d.array, 1.0e-4) - assert fit.galaxy_image_dict[g2] == pytest.approx( - g0_image_2d.array + g1_image_2d.array, 1.0e-4 - ) - assert (fit.galaxy_image_dict[g3].slim == np.zeros(9)).all() - - # Linear Light PRofiles + Pixelization + Regularizaiton - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - masked_imaging_7x7.data[0] = 3.0 - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, - galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], - ) - - assert (fit.galaxy_image_dict[g3] == np.zeros(9)).all() - - assert fit.galaxy_image_dict[g0][4] == pytest.approx(23.944378406, 1.0e-4) - assert fit.galaxy_image_dict[g1_linear][4] == pytest.approx(-28.1424200, 1.0e-4) - assert fit.galaxy_image_dict[galaxy_pix_0][4] == pytest.approx(1.107972830, 1.0e-4) - assert fit.galaxy_image_dict[galaxy_pix_1][4] == pytest.approx(1.1079728213, 1.0e-4) - - mapped_reconstructed_data = ( - fit.galaxy_image_dict[g1_linear] - + fit.galaxy_image_dict[galaxy_pix_0] - + fit.galaxy_image_dict[galaxy_pix_1] - ) - - assert mapped_reconstructed_data == pytest.approx( - fit.inversion.mapped_reconstructed_data.array, 1.0e-4 - ) - - -def test__galaxy_model_image_dict(masked_imaging_7x7): - # Normal Light Profiles Only - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0)) - g2 = ag.Galaxy( - redshift=0.5, - light_profile_0=ag.lp.Sersic(intensity=1.0), - light_profile_1=ag.lp.Sersic(intensity=2.0), - ) - g3 = ag.Galaxy(redshift=0.5) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1, g2, g3]) - - g0_blurred_image_2d = g0.blurred_image_2d_from( - grid=masked_imaging_7x7.grids.lp, - blurring_grid=masked_imaging_7x7.grids.blurring, - psf=masked_imaging_7x7.psf, - ) - - g1_blurred_image_2d = g1.blurred_image_2d_from( - grid=masked_imaging_7x7.grids.lp, - blurring_grid=masked_imaging_7x7.grids.blurring, - psf=masked_imaging_7x7.psf, - ) - - assert fit.galaxy_model_image_dict[g0] == pytest.approx( - g0_blurred_image_2d.array, 1.0e-4 - ) - assert fit.galaxy_model_image_dict[g1] == pytest.approx( - g1_blurred_image_2d.array, 1.0e-4 - ) - assert fit.galaxy_model_image_dict[g2] == pytest.approx( - g0_blurred_image_2d.array + g1_blurred_image_2d.array, 1.0e-4 - ) - assert (fit.galaxy_model_image_dict[g3].slim == np.zeros(9)).all() - - assert fit.model_data == pytest.approx( - fit.galaxy_model_image_dict[g0].array - + fit.galaxy_model_image_dict[g1].array - + fit.galaxy_model_image_dict[g2].array, - 1.0e-4, - ) - - # Linear Light Profiles only - - g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0_linear, g3]) - - assert fit.galaxy_model_image_dict[g0_linear][4] == pytest.approx( - 1.5355385003, 1.0e-4 - ) - assert (fit.galaxy_model_image_dict[g3] == np.zeros(9)).all() - - assert fit.model_data.native.array == pytest.approx( - fit.galaxy_model_image_dict[g0_linear].native.array, 1.0e-4 - ) - - # Pixelization + Regularizaiton only - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - g0 = ag.Galaxy(redshift=0.5) - g1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) - - assert (fit.galaxy_model_image_dict[g0] == np.zeros(9)).all() - - assert fit.galaxy_model_image_dict[g1][4] == pytest.approx(1.25795063, 1.0e-4) - assert fit.galaxy_model_image_dict[g1].native.array == pytest.approx( - fit.inversion.mapped_reconstructed_operated_data.native.array, 1.0e-4 - ) - - assert fit.model_data.native.array == pytest.approx( - fit.galaxy_model_image_dict[g1].native.array, 1.0e-4 - ) - - # Linear Light PRofiles + Pixelization + Regularizaiton - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - masked_imaging_7x7.data[0] = 3.0 - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, - galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], - ) - - assert (fit.galaxy_model_image_dict[g3] == np.zeros(9)).all() - - assert fit.galaxy_model_image_dict[g0][4] == pytest.approx(8.2172158101, 1.0e-4) - assert fit.galaxy_model_image_dict[g1_linear][4] == pytest.approx( - -9.658085312, 1.0e-4 - ) - assert fit.galaxy_model_image_dict[galaxy_pix_0][4] == pytest.approx( - 1.10780906, 1.0e-4 - ) - assert fit.galaxy_model_image_dict[galaxy_pix_1][4] == pytest.approx( - 1.10780906, 1.0e-4 - ) - - mapped_reconstructed_operated_data = ( - fit.galaxy_model_image_dict[g1_linear] - + fit.galaxy_model_image_dict[galaxy_pix_0] - + fit.galaxy_model_image_dict[galaxy_pix_1] - ) - - assert mapped_reconstructed_operated_data == pytest.approx( - fit.inversion.mapped_reconstructed_operated_data.array, 1.0e-4 - ) - - assert fit.model_data == pytest.approx( - fit.galaxy_model_image_dict[g0].array - + fit.inversion.mapped_reconstructed_operated_data.array, - 1.0e-4, - ) - - -def test__model_images_of_galaxies_list(masked_imaging_7x7): - galaxy_light = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - galaxy_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic()) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, galaxies=[galaxy_light, galaxy_linear, galaxy_pix] - ) - - assert fit.model_images_of_galaxies_list[0] == pytest.approx( - fit.galaxy_model_image_dict[galaxy_light].array, 1.0e-4 - ) - assert fit.model_images_of_galaxies_list[1].array == pytest.approx( - fit.galaxy_model_image_dict[galaxy_linear].array, 1.0e-4 - ) - assert fit.model_images_of_galaxies_list[2] == pytest.approx( - fit.galaxy_model_image_dict[galaxy_pix].array, 1.0e-4 - ) - - -def test__subtracted_images_of_galaxies_dict(masked_imaging_7x7_no_blur): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - - g1 = ag.Galaxy(redshift=0.5) - - g2 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=3.0)) - - fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0, g1, g2]) - - assert fit.subtracted_images_of_galaxies_dict[g0].slim[0] == pytest.approx( - 0.520383, 1.0e-4 - ) - assert fit.subtracted_images_of_galaxies_dict[g1].slim[0] == pytest.approx( - 0.360511, 1.0e-4 - ) - assert fit.subtracted_images_of_galaxies_dict[g2].slim[0] == pytest.approx( - 0.840127, 1.0e-4 - ) - - -def test__subtracted_images_of_galaxies_list(masked_imaging_7x7_no_blur): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - - g1 = ag.Galaxy(redshift=0.5) - - g2 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=3.0)) - - fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0, g1, g2]) - - assert fit.subtracted_images_of_galaxies_list[0].slim[0] == pytest.approx( - 0.520383, 1.0e-4 - ) - assert fit.subtracted_images_of_galaxies_list[1].slim[0] == pytest.approx( - 0.360511, 1.0e-4 - ) - assert fit.subtracted_images_of_galaxies_list[2].slim[0] == pytest.approx( - 0.840127, 1.0e-4 - ) - - -def test___unmasked_blurred_images(masked_imaging_7x7): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - - galaxies = ag.Galaxies(galaxies=[g0, g1]) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) - - unmasked_blurred_image = galaxies.unmasked_blurred_image_2d_from( - grid=masked_imaging_7x7.grids.lp, psf=masked_imaging_7x7.psf - ) - - assert (fit.unmasked_blurred_image == unmasked_blurred_image).all() - - unmasked_blurred_image_of_galaxies_list = ( - galaxies.unmasked_blurred_image_2d_list_from( - grid=masked_imaging_7x7.grids.lp, psf=masked_imaging_7x7.psf - ) - ) - - assert ( - fit.unmasked_blurred_image_of_galaxies_list[0] - == unmasked_blurred_image_of_galaxies_list[0] - ).all() - assert ( - fit.unmasked_blurred_image_of_galaxies_list[1] - == unmasked_blurred_image_of_galaxies_list[1] - ).all() - - -def test__light_profile_linear__intensity_dict(masked_imaging_7x7): - linear_light_0 = ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) - linear_light_1 = ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) - - g0_linear_light = ag.Galaxy(redshift=0.5, bulge=linear_light_0) - - g1_linear_light = ag.Galaxy(redshift=0.5, bulge=linear_light_1) - - fit = ag.FitImaging( - dataset=masked_imaging_7x7, galaxies=[g0_linear_light, g1_linear_light] - ) - - assert fit.linear_light_profile_intensity_dict[linear_light_0] == pytest.approx( - 8.88030654536974, 1.0e-4 - ) - assert fit.linear_light_profile_intensity_dict[linear_light_1] == pytest.approx( - -1.665197975, 1.0e-4 - ) - - basis = ag.lp_basis.Basis(profile_list=[linear_light_0, linear_light_1]) - - g_basis = ag.Galaxy(redshift=0.5, bulge=basis) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g_basis]) - - assert fit.linear_light_profile_intensity_dict[linear_light_0] == pytest.approx( - 8.8803065453, 1.0e-4 - ) - assert fit.linear_light_profile_intensity_dict[linear_light_1] == pytest.approx( - -1.66519797593, 1.0e-4 - ) - - linear_light_2 = ag.lp_linear.Sersic(sersic_index=2.0, centre=(0.05, 0.05)) - linear_light_3 = ag.lp_linear.Sersic(sersic_index=3.0, centre=(0.05, 0.05)) - - basis = ag.lp_basis.Basis(profile_list=[linear_light_2, linear_light_3]) - - g_basis = ag.Galaxy(redshift=0.5, bulge=basis) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0_linear_light, g_basis]) - - assert fit.linear_light_profile_intensity_dict[linear_light_0] == pytest.approx( - -37.819608481, 1.0e-4 - ) - assert fit.linear_light_profile_intensity_dict[linear_light_2] == pytest.approx( - 81.76657216, 1.0e-4 - ) - assert fit.linear_light_profile_intensity_dict[linear_light_3] == pytest.approx( - -41.402749460449, 1.0e-4 - ) - - -def test__galaxies_linear_light_profiles_to_light_profiles(masked_imaging_7x7): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - - g0_linear = ag.Galaxy( - redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) - ) - g1_linear = ag.Galaxy( - redshift=1.0, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) - ) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g0_linear, g1_linear]) - - assert fit.galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) - - galaxies = fit.galaxies_linear_light_profiles_to_light_profiles - - assert galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) - assert galaxies[1].bulge.intensity == pytest.approx(8.8803030953, 1.0e-4) - assert galaxies[2].bulge.intensity == pytest.approx(-2.665197940, 1.0e-4) - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), - ag.lp.Sersic(intensity=0.1, sersic_index=2.0, centre=(0.05, 0.05)), - ag.lp_linear.Sersic(sersic_index=3.0, centre=(0.05, 0.05)), - ] - ) - - g0_linear = ag.Galaxy(redshift=0.5, bulge=basis) - g1_linear = ag.Galaxy( - redshift=1.0, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) - ) - - fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g0_linear, g1_linear]) - - assert fit.galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) - assert fit.galaxies[1].bulge.profile_list[0].intensity == pytest.approx(1.0, 1.0e-4) - assert fit.galaxies[1].bulge.profile_list[1].intensity == pytest.approx(0.1, 1.0e-4) - assert fit.galaxies[1].bulge.profile_list[2].intensity == pytest.approx(1.0, 1.0e-4) - assert fit.galaxies[2].bulge.intensity == pytest.approx(1.0, 1.0e-4) - - galaxies = fit.galaxies_linear_light_profiles_to_light_profiles - - assert galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) - assert galaxies[1].bulge.profile_list[0].intensity == pytest.approx( - -24.52668307515, 1.0e-4 - ) - assert galaxies[1].bulge.profile_list[1].intensity == pytest.approx(0.1, 1.0e-4) - assert galaxies[1].bulge.profile_list[2].intensity == pytest.approx( - 90.36651920, 1.0e-4 - ) - assert galaxies[2].bulge.intensity == pytest.approx(-64.44560420348, 1.0e-4) +import copy +import numpy as np +import pytest + +import autogalaxy as ag + + +def test__model_image__no_psf_blurring__correct_slim_values(masked_imaging_7x7_no_blur): + g0 = ag.Galaxy( + redshift=0.5, + bulge=ag.m.MockLightProfile(image_2d_value=1.0, image_2d_first_value=2.0), + ) + + fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0]) + + assert fit.model_data.slim == pytest.approx( + np.array([2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), 1.0e-4 + ) + + +def test__model_image__no_psf_blurring__correct_log_likelihood( + masked_imaging_7x7_no_blur, +): + g0 = ag.Galaxy( + redshift=0.5, + bulge=ag.m.MockLightProfile(image_2d_value=1.0, image_2d_first_value=2.0), + ) + + fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0]) + + assert fit.log_likelihood == pytest.approx(-14.63377, 1.0e-4) + + +def test__model_image__with_psf_blurring__correct_slim_values(masked_imaging_7x7): + g0 = ag.Galaxy( + redshift=0.5, + bulge=ag.m.MockLightProfile(image_2d_value=1.0, image_2d_first_value=2.0), + ) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0]) + + assert fit.model_data.slim == pytest.approx( + np.array([1.33, 1.16, 1.0, 1.16, 1.0, 1.0, 1.0, 1.0, 1.0]), 1.0e-1 + ) + + +def test__model_image__with_psf_blurring__correct_log_likelihood(masked_imaging_7x7): + g0 = ag.Galaxy( + redshift=0.5, + bulge=ag.m.MockLightProfile(image_2d_value=1.0, image_2d_first_value=2.0), + ) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0]) + + assert fit.log_likelihood == pytest.approx(-14.52960, 1.0e-4) + + +@pytest.mark.parametrize( + "galaxies_factory, expected_fom, expect_inversion", + [ + ("two_sersic_galaxies", -71.46911964, False), + ("basis_of_sersics", -71.46911964, False), + ("pixelization_only", -22.91411868616, True), + ("light_plus_pixelization", -29.235208518732776, True), + ("two_linear_light_profiles", -14.544339716, True), + ("basis_of_linear_light_profiles", -14.544339716, True), + ("basis_with_regularization", -25.83890655, True), + ("two_operated_light_profiles", -289.6050404, False), + ("two_linear_operated_light_profiles", -14.7635041, True), + ("linear_light_plus_pixelization", -22.8918119554022, True), + ], +) +def test__fit_figure_of_merit__various_galaxy_configs__correct_value_and_inversion_flag( + masked_imaging_7x7, galaxies_factory, expected_fom, expect_inversion +): + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + g0_linear_light = ag.Galaxy( + redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + ) + + factories = { + "two_sersic_galaxies": [ + ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))), + ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))), + ], + "basis_of_sersics": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_basis.Basis( + profile_list=[ + ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), + ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), + ] + ), + ) + ], + "pixelization_only": [ag.Galaxy(redshift=0.5), galaxy_pix], + "light_plus_pixelization": [ + ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)) + ), + galaxy_pix, + ], + "two_linear_light_profiles": [ + g0_linear_light, + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), + ), + ], + "basis_of_linear_light_profiles": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_basis.Basis( + profile_list=[ + ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), + ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), + ] + ), + ) + ], + "basis_with_regularization": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_basis.Basis( + profile_list=[ + ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), + ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), + ], + regularization=ag.reg.Constant(coefficient=1.0), + ), + ) + ], + "two_operated_light_profiles": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_operated.Sersic(intensity=1.0, centre=(0.05, 0.05)), + ), + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_operated.Sersic(intensity=1.0, centre=(0.05, 0.05)), + ), + ], + "two_linear_operated_light_profiles": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear_operated.Sersic( + sersic_index=1.0, centre=(0.05, 0.05) + ), + ), + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear_operated.Sersic( + sersic_index=4.0, centre=(0.05, 0.05) + ), + ), + ], + "linear_light_plus_pixelization": [g0_linear_light, galaxy_pix], + } + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, galaxies=factories[galaxies_factory] + ) + + assert fit.perform_inversion is expect_inversion + assert fit.figure_of_merit == pytest.approx(expected_fom, 1.0e-4) + + +def test__fit_figure_of_merit__covariance_noise_map__no_inversion__correct_value( + masked_imaging_covariance_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + + fit = ag.FitImaging(dataset=masked_imaging_covariance_7x7, galaxies=[g0, g1]) + + assert fit.perform_inversion is False + assert fit.figure_of_merit == pytest.approx(-107.62350171, 1.0e-4) + + +def test__fit__model_dataset__sky__perform_inversion_true__correct_figure_of_merit( + masked_imaging_7x7, +): + g0 = ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear.Sersic(sersic_index=1.0), + ) + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0], + dataset_model=ag.DatasetModel(background_sky_level=5.0), + ) + + assert fit.perform_inversion is True + assert fit.figure_of_merit == pytest.approx(-21.6970706693, 1.0e-4) + + +def test__fit__model_dataset__grid_offset__standard_grid__correct_figure_of_merit( + masked_imaging_7x7, +): + g0 = ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) + ) + g1 = ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) + ) + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0, g1], + dataset_model=ag.DatasetModel(grid_offset=(1.0, 2.0)), + ) + + assert fit.figure_of_merit == pytest.approx(-71.4691196459, 1.0e-4) + + +def test__fit__model_dataset__grid_offset__sub_2_grid__correct_figure_of_merit( + masked_imaging_7x7_sub_2, +): + g0 = ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) + ) + g1 = ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(centre=(-1.05, -2.05), intensity=1.0) + ) + + fit = ag.FitImaging( + dataset=masked_imaging_7x7_sub_2, + galaxies=[g0, g1], + dataset_model=ag.DatasetModel(grid_offset=(1.0, 2.0)), + ) + + assert fit.figure_of_merit == pytest.approx(-14.93272811, 1.0e-4) + + +def test__fit__model_dataset__grid_offset__with_pixelization__correct_figure_of_merit( + masked_imaging_7x7, +): + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[ag.Galaxy(redshift=0.5), galaxy_pix], + dataset_model=ag.DatasetModel(grid_offset=(1.0, 2.0)), + ) + + assert fit.figure_of_merit == pytest.approx(-22.914118686169, 1.0e-4) + + +def test__galaxy_image_dict__normal_light_profiles__individual_galaxies_match( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0)) + g2 = ag.Galaxy( + redshift=0.5, + light_profile_0=ag.lp.Sersic(intensity=1.0), + light_profile_1=ag.lp.Sersic(intensity=2.0), + ) + g3 = ag.Galaxy(redshift=0.5) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1, g2, g3]) + + g0_image_2d = g0.image_2d_from(grid=masked_imaging_7x7.grids.lp) + g1_image_2d = g1.image_2d_from(grid=masked_imaging_7x7.grids.lp) + + assert fit.galaxy_image_dict[g0] == pytest.approx(g0_image_2d.array, 1.0e-4) + assert fit.galaxy_image_dict[g1] == pytest.approx(g1_image_2d.array, 1.0e-4) + assert fit.galaxy_image_dict[g2] == pytest.approx( + g0_image_2d.array + g1_image_2d.array, 1.0e-4 + ) + assert (fit.galaxy_image_dict[g3].slim == np.zeros(9)).all() + + +def test__galaxy_image_dict__linear_and_pixelization__correct_pixel_values( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + masked_imaging_7x7.data[0] = 3.0 + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], + ) + + assert (fit.galaxy_image_dict[g3] == np.zeros(9)).all() + assert fit.galaxy_image_dict[g0][4] == pytest.approx(23.944378406, 1.0e-4) + assert fit.galaxy_image_dict[g1_linear][4] == pytest.approx(-28.1424200, 1.0e-4) + assert fit.galaxy_image_dict[galaxy_pix_0][4] == pytest.approx(1.107972830, 1.0e-4) + assert fit.galaxy_image_dict[galaxy_pix_1][4] == pytest.approx(1.1079728213, 1.0e-4) + + +def test__galaxy_image_dict__linear_and_pixelization__sum_matches_inversion_mapped_data( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + masked_imaging_7x7.data[0] = 3.0 + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], + ) + + mapped_reconstructed_data = ( + fit.galaxy_image_dict[g1_linear] + + fit.galaxy_image_dict[galaxy_pix_0] + + fit.galaxy_image_dict[galaxy_pix_1] + ) + + assert mapped_reconstructed_data == pytest.approx( + fit.inversion.mapped_reconstructed_data.array, 1.0e-4 + ) + + +def test__galaxy_model_image_dict__normal_light_profiles__match_blurred_images( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0)) + g2 = ag.Galaxy( + redshift=0.5, + light_profile_0=ag.lp.Sersic(intensity=1.0), + light_profile_1=ag.lp.Sersic(intensity=2.0), + ) + g3 = ag.Galaxy(redshift=0.5) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1, g2, g3]) + + g0_blurred_image_2d = g0.blurred_image_2d_from( + grid=masked_imaging_7x7.grids.lp, + blurring_grid=masked_imaging_7x7.grids.blurring, + psf=masked_imaging_7x7.psf, + ) + + g1_blurred_image_2d = g1.blurred_image_2d_from( + grid=masked_imaging_7x7.grids.lp, + blurring_grid=masked_imaging_7x7.grids.blurring, + psf=masked_imaging_7x7.psf, + ) + + assert fit.galaxy_model_image_dict[g0] == pytest.approx( + g0_blurred_image_2d.array, 1.0e-4 + ) + assert fit.galaxy_model_image_dict[g1] == pytest.approx( + g1_blurred_image_2d.array, 1.0e-4 + ) + assert fit.galaxy_model_image_dict[g2] == pytest.approx( + g0_blurred_image_2d.array + g1_blurred_image_2d.array, 1.0e-4 + ) + assert (fit.galaxy_model_image_dict[g3].slim == np.zeros(9)).all() + + +def test__galaxy_model_image_dict__normal_light_profiles__model_data_is_sum_of_galaxy_images( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0)) + g2 = ag.Galaxy( + redshift=0.5, + light_profile_0=ag.lp.Sersic(intensity=1.0), + light_profile_1=ag.lp.Sersic(intensity=2.0), + ) + g3 = ag.Galaxy(redshift=0.5) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1, g2, g3]) + + assert fit.model_data == pytest.approx( + fit.galaxy_model_image_dict[g0].array + + fit.galaxy_model_image_dict[g1].array + + fit.galaxy_model_image_dict[g2].array, + 1.0e-4, + ) + + +def test__galaxy_model_image_dict__linear_light_profile_only__correct_pixel_value( + masked_imaging_7x7, +): + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0_linear, g3]) + + assert fit.galaxy_model_image_dict[g0_linear][4] == pytest.approx( + 1.5355385003, 1.0e-4 + ) + assert (fit.galaxy_model_image_dict[g3] == np.zeros(9)).all() + + +def test__galaxy_model_image_dict__linear_light_profile_only__model_data_matches_galaxy_image( + masked_imaging_7x7, +): + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0_linear, g3]) + + assert fit.model_data.native.array == pytest.approx( + fit.galaxy_model_image_dict[g0_linear].native.array, 1.0e-4 + ) + + +def test__galaxy_model_image_dict__pixelization_only__correct_pixel_value( + masked_imaging_7x7, +): + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + g1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) + + assert (fit.galaxy_model_image_dict[g0] == np.zeros(9)).all() + assert fit.galaxy_model_image_dict[g1][4] == pytest.approx(1.25795063, 1.0e-4) + + +def test__galaxy_model_image_dict__pixelization_only__matches_inversion_reconstructed_operated_data( + masked_imaging_7x7, +): + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + g1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) + + assert fit.galaxy_model_image_dict[g1].native.array == pytest.approx( + fit.inversion.mapped_reconstructed_operated_data.native.array, 1.0e-4 + ) + + +def test__galaxy_model_image_dict__pixelization_only__model_data_matches_galaxy_image( + masked_imaging_7x7, +): + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + g1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) + + assert fit.model_data.native.array == pytest.approx( + fit.galaxy_model_image_dict[g1].native.array, 1.0e-4 + ) + + +def test__galaxy_model_image_dict__linear_and_pixelization__correct_pixel_values( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + masked_imaging_7x7.data[0] = 3.0 + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], + ) + + assert (fit.galaxy_model_image_dict[g3] == np.zeros(9)).all() + assert fit.galaxy_model_image_dict[g0][4] == pytest.approx(8.2172158101, 1.0e-4) + assert fit.galaxy_model_image_dict[g1_linear][4] == pytest.approx( + -9.658085312, 1.0e-4 + ) + assert fit.galaxy_model_image_dict[galaxy_pix_0][4] == pytest.approx( + 1.10780906, 1.0e-4 + ) + assert fit.galaxy_model_image_dict[galaxy_pix_1][4] == pytest.approx( + 1.10780906, 1.0e-4 + ) + + +def test__galaxy_model_image_dict__linear_and_pixelization__sum_matches_inversion_operated_data( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + masked_imaging_7x7.data[0] = 3.0 + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], + ) + + mapped_reconstructed_operated_data = ( + fit.galaxy_model_image_dict[g1_linear] + + fit.galaxy_model_image_dict[galaxy_pix_0] + + fit.galaxy_model_image_dict[galaxy_pix_1] + ) + + assert mapped_reconstructed_operated_data == pytest.approx( + fit.inversion.mapped_reconstructed_operated_data.array, 1.0e-4 + ) + + +def test__galaxy_model_image_dict__linear_and_pixelization__model_data_is_light_plus_inversion( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + g3 = ag.Galaxy(redshift=0.5) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + masked_imaging_7x7.data[0] = 3.0 + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, + galaxies=[g0, g1_linear, g3, galaxy_pix_0, galaxy_pix_1], + ) + + assert fit.model_data == pytest.approx( + fit.galaxy_model_image_dict[g0].array + + fit.inversion.mapped_reconstructed_operated_data.array, + 1.0e-4, + ) + + +def test__model_images_of_galaxies_list__matches_galaxy_model_image_dict( + masked_imaging_7x7, +): + galaxy_light = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + galaxy_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic()) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, galaxies=[galaxy_light, galaxy_linear, galaxy_pix] + ) + + assert fit.model_images_of_galaxies_list[0] == pytest.approx( + fit.galaxy_model_image_dict[galaxy_light].array, 1.0e-4 + ) + assert fit.model_images_of_galaxies_list[1].array == pytest.approx( + fit.galaxy_model_image_dict[galaxy_linear].array, 1.0e-4 + ) + assert fit.model_images_of_galaxies_list[2] == pytest.approx( + fit.galaxy_model_image_dict[galaxy_pix].array, 1.0e-4 + ) + + +def test__subtracted_images_of_galaxies_dict__three_galaxies__correct_first_pixel_values( + masked_imaging_7x7_no_blur, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5) + g2 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=3.0)) + + fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0, g1, g2]) + + assert fit.subtracted_images_of_galaxies_dict[g0].slim[0] == pytest.approx( + 0.520383, 1.0e-4 + ) + assert fit.subtracted_images_of_galaxies_dict[g1].slim[0] == pytest.approx( + 0.360511, 1.0e-4 + ) + assert fit.subtracted_images_of_galaxies_dict[g2].slim[0] == pytest.approx( + 0.840127, 1.0e-4 + ) + + +def test__subtracted_images_of_galaxies_list__three_galaxies__correct_first_pixel_values( + masked_imaging_7x7_no_blur, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5) + g2 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=3.0)) + + fit = ag.FitImaging(dataset=masked_imaging_7x7_no_blur, galaxies=[g0, g1, g2]) + + assert fit.subtracted_images_of_galaxies_list[0].slim[0] == pytest.approx( + 0.520383, 1.0e-4 + ) + assert fit.subtracted_images_of_galaxies_list[1].slim[0] == pytest.approx( + 0.360511, 1.0e-4 + ) + assert fit.subtracted_images_of_galaxies_list[2].slim[0] == pytest.approx( + 0.840127, 1.0e-4 + ) + + +def test__unmasked_blurred_image__matches_galaxies_unmasked_blurred_image( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + + galaxies = ag.Galaxies(galaxies=[g0, g1]) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) + + unmasked_blurred_image = galaxies.unmasked_blurred_image_2d_from( + grid=masked_imaging_7x7.grids.lp, psf=masked_imaging_7x7.psf + ) + + assert (fit.unmasked_blurred_image == unmasked_blurred_image).all() + + +def test__unmasked_blurred_image_of_galaxies_list__matches_galaxies_per_galaxy_computation( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + + galaxies = ag.Galaxies(galaxies=[g0, g1]) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g1]) + + unmasked_blurred_image_of_galaxies_list = ( + galaxies.unmasked_blurred_image_2d_list_from( + grid=masked_imaging_7x7.grids.lp, psf=masked_imaging_7x7.psf + ) + ) + + assert ( + fit.unmasked_blurred_image_of_galaxies_list[0] + == unmasked_blurred_image_of_galaxies_list[0] + ).all() + assert ( + fit.unmasked_blurred_image_of_galaxies_list[1] + == unmasked_blurred_image_of_galaxies_list[1] + ).all() + + +def test__linear_light_profile_intensity_dict__two_separate_galaxies__correct_intensities( + masked_imaging_7x7, +): + linear_light_0 = ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + linear_light_1 = ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) + + g0_linear_light = ag.Galaxy(redshift=0.5, bulge=linear_light_0) + g1_linear_light = ag.Galaxy(redshift=0.5, bulge=linear_light_1) + + fit = ag.FitImaging( + dataset=masked_imaging_7x7, galaxies=[g0_linear_light, g1_linear_light] + ) + + assert fit.linear_light_profile_intensity_dict[linear_light_0] == pytest.approx( + 8.88030654536974, 1.0e-4 + ) + assert fit.linear_light_profile_intensity_dict[linear_light_1] == pytest.approx( + -1.665197975, 1.0e-4 + ) + + +def test__linear_light_profile_intensity_dict__basis_galaxy__correct_intensities( + masked_imaging_7x7, +): + linear_light_0 = ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + linear_light_1 = ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) + + basis = ag.lp_basis.Basis(profile_list=[linear_light_0, linear_light_1]) + + g_basis = ag.Galaxy(redshift=0.5, bulge=basis) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g_basis]) + + assert fit.linear_light_profile_intensity_dict[linear_light_0] == pytest.approx( + 8.8803065453, 1.0e-4 + ) + assert fit.linear_light_profile_intensity_dict[linear_light_1] == pytest.approx( + -1.66519797593, 1.0e-4 + ) + + +def test__linear_light_profile_intensity_dict__mixed_galaxy_and_basis__correct_intensities( + masked_imaging_7x7, +): + linear_light_0 = ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + linear_light_2 = ag.lp_linear.Sersic(sersic_index=2.0, centre=(0.05, 0.05)) + linear_light_3 = ag.lp_linear.Sersic(sersic_index=3.0, centre=(0.05, 0.05)) + + g0_linear_light = ag.Galaxy(redshift=0.5, bulge=linear_light_0) + + basis = ag.lp_basis.Basis(profile_list=[linear_light_2, linear_light_3]) + + g_basis = ag.Galaxy(redshift=0.5, bulge=basis) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0_linear_light, g_basis]) + + assert fit.linear_light_profile_intensity_dict[linear_light_0] == pytest.approx( + -37.819608481, 1.0e-4 + ) + assert fit.linear_light_profile_intensity_dict[linear_light_2] == pytest.approx( + 81.76657216, 1.0e-4 + ) + assert fit.linear_light_profile_intensity_dict[linear_light_3] == pytest.approx( + -41.402749460449, 1.0e-4 + ) + + +def test__galaxies_linear_light_profiles_to_light_profiles__separate_galaxies__intensities_replaced( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + + g0_linear = ag.Galaxy( + redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + ) + g1_linear = ag.Galaxy( + redshift=1.0, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) + ) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g0_linear, g1_linear]) + + assert fit.galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) + + galaxies = fit.galaxies_linear_light_profiles_to_light_profiles + + assert galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) + assert galaxies[1].bulge.intensity == pytest.approx(8.8803030953, 1.0e-4) + assert galaxies[2].bulge.intensity == pytest.approx(-2.665197940, 1.0e-4) + + +def test__galaxies_linear_light_profiles_to_light_profiles__basis_with_mixed_profiles__intensities_replaced( + masked_imaging_7x7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + + basis = ag.lp_basis.Basis( + profile_list=[ + ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), + ag.lp.Sersic(intensity=0.1, sersic_index=2.0, centre=(0.05, 0.05)), + ag.lp_linear.Sersic(sersic_index=3.0, centre=(0.05, 0.05)), + ] + ) + + g0_linear = ag.Galaxy(redshift=0.5, bulge=basis) + g1_linear = ag.Galaxy( + redshift=1.0, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) + ) + + fit = ag.FitImaging(dataset=masked_imaging_7x7, galaxies=[g0, g0_linear, g1_linear]) + + assert fit.galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) + assert fit.galaxies[1].bulge.profile_list[0].intensity == pytest.approx(1.0, 1.0e-4) + assert fit.galaxies[1].bulge.profile_list[1].intensity == pytest.approx(0.1, 1.0e-4) + assert fit.galaxies[1].bulge.profile_list[2].intensity == pytest.approx(1.0, 1.0e-4) + assert fit.galaxies[2].bulge.intensity == pytest.approx(1.0, 1.0e-4) + + galaxies = fit.galaxies_linear_light_profiles_to_light_profiles + + assert galaxies[0].bulge.intensity == pytest.approx(1.0, 1.0e-4) + assert galaxies[1].bulge.profile_list[0].intensity == pytest.approx( + -24.52668307515, 1.0e-4 + ) + assert galaxies[1].bulge.profile_list[1].intensity == pytest.approx(0.1, 1.0e-4) + assert galaxies[1].bulge.profile_list[2].intensity == pytest.approx( + 90.36651920, 1.0e-4 + ) + assert galaxies[2].bulge.intensity == pytest.approx(-64.44560420348, 1.0e-4) diff --git a/test_autogalaxy/imaging/test_simulate_and_fit_imaging.py b/test_autogalaxy/imaging/test_simulate_and_fit_imaging.py index 9083cb5f6..f25f1f529 100644 --- a/test_autogalaxy/imaging/test_simulate_and_fit_imaging.py +++ b/test_autogalaxy/imaging/test_simulate_and_fit_imaging.py @@ -1,211 +1,370 @@ -import os -from os import path -import shutil - -import numpy as np -import pytest - -import autogalaxy as ag - - -def test__perfect_fit__chi_squared_0(): - grid = ag.Grid2D.uniform( - shape_native=(11, 11), - pixel_scales=0.2, - over_sample_size=1, - ) - - psf = ag.Convolver.from_gaussian( - shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True - ) - - galaxy_0 = ag.Galaxy( - redshift=0.5, light=ag.lp.Sersic(centre=(0.1, 0.1), intensity=0.1) - ) - galaxy_1 = ag.Galaxy( - redshift=0.5, light=ag.lp.Exponential(centre=(0.1, 0.1), intensity=0.5) - ) - - simulator = ag.SimulatorImaging( - exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False - ) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - dataset.noise_map = ag.Array2D.ones( - shape_native=dataset.data.shape_native, pixel_scales=0.2 - ) - - file_path = path.join( - "{}".format(path.dirname(path.realpath(__file__))), - "data_temp", - "simulate_and_fit", - ) - - try: - shutil.rmtree(file_path) - except FileNotFoundError: - pass - - if path.exists(file_path) is False: - os.makedirs(file_path) - - dataset.output_to_fits( - data_path=path.join(file_path, "data.fits"), - noise_map_path=path.join(file_path, "noise_map.fits"), - psf_path=path.join(file_path, "psf.fits"), - ) - - dataset = ag.Imaging.from_fits( - data_path=path.join(file_path, "data.fits"), - noise_map_path=path.join(file_path, "noise_map.fits"), - psf_path=path.join(file_path, "psf.fits"), - pixel_scales=0.2, - over_sample_size_lp=1, - ) - - mask = ag.Mask2D.circular( - shape_native=dataset.data.shape_native, - pixel_scales=0.2, - radius=0.8, - ) - - masked_dataset = dataset.apply_mask(mask=mask) - - fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy_0, galaxy_1]) - - assert fit.chi_squared == pytest.approx(0.0, 1e-4) - - file_path = path.join( - "{}".format(path.dirname(path.realpath(__file__))), "data_temp" - ) - - if path.exists(file_path) is True: - shutil.rmtree(file_path) - - -def test__simulate_imaging_data_and_fit__known_likelihood(): - grid = ag.Grid2D.uniform(shape_native=(31, 31), pixel_scales=0.2) - - psf = ag.Convolver.from_gaussian( - shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True - ) - - galaxy_0 = ag.Galaxy( - redshift=0.5, - bulge=ag.lp.Sersic(centre=(0.1, 0.1), intensity=0.1), - disk=ag.lp.Sersic(centre=(0.2, 0.2), intensity=0.2), - ) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(16, 16)), - regularization=ag.reg.Constant(coefficient=(1.0)), - ) - - galaxy_1 = ag.Galaxy(redshift=1.0, pixelization=pixelization) - - simulator = ag.SimulatorImaging(exposure_time=300.0, psf=psf, noise_seed=1) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - - mask = ag.Mask2D.circular( - shape_native=dataset.data.shape_native, pixel_scales=0.2, radius=2.005 - ) - - masked_dataset = dataset.apply_mask(mask=mask) - - fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy_0, galaxy_1]) - - assert fit.figure_of_merit == pytest.approx(579.015739085647, 1.0e-2) - - # Check that using a Basis gives the same result. - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp.Sersic(centre=(0.1, 0.1), intensity=0.1), - ag.lp.Sersic(centre=(0.2, 0.2), intensity=0.2), - ] - ) - - galaxy_0 = ag.Galaxy(redshift=0.5, bulge=basis) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - - masked_dataset = dataset.apply_mask(mask=mask) - - fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy_0, galaxy_1]) - - assert fit.figure_of_merit == pytest.approx(579.015739085647, 1.0e-2) - - -def test__simulate_imaging_data_and_fit__linear_light_profiles_agree_with_standard_light_profiles(): - grid = ag.Grid2D.uniform( - shape_native=(11, 11), - pixel_scales=0.2, - over_sample_size=1, - ) - - psf = ag.Convolver.from_gaussian( - shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True - ) - - galaxy = ag.Galaxy( - redshift=0.5, - bulge=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.1, sersic_index=1.0), - disk=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.2, sersic_index=4.0), - ) - - simulator = ag.SimulatorImaging( - exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False - ) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy], grid=grid) - dataset.noise_map = ag.Array2D.ones( - shape_native=dataset.data.shape_native, pixel_scales=0.2 - ) - - mask = ag.Mask2D.circular( - shape_native=dataset.data.shape_native, - pixel_scales=0.2, - radius=0.81, - ) - - masked_dataset = dataset.apply_mask(mask=mask) - - masked_dataset = masked_dataset.apply_over_sampling(over_sample_size_lp=1) - - fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy]) - - galaxy_linear = ag.Galaxy( - redshift=0.5, - bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=1.0), - disk=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=4.0), - ) - - fit_linear = ag.FitImaging( - dataset=masked_dataset, - galaxies=[galaxy_linear], - ) - - assert fit_linear.inversion.reconstruction == pytest.approx( - np.array([0.1, 0.2]), 1.0e-2 - ) - - assert fit_linear.linear_light_profile_intensity_dict[ - galaxy_linear.bulge - ] == pytest.approx(0.1, 1.0e-2) - assert fit_linear.linear_light_profile_intensity_dict[ - galaxy_linear.disk - ] == pytest.approx(0.2, 1.0e-2) - - assert fit.log_likelihood == fit_linear.figure_of_merit - assert fit_linear.figure_of_merit == pytest.approx(-45.02798, 1.0e-4) - - galaxy_image = galaxy.blurred_image_2d_from( - grid=masked_dataset.grids.lp, - psf=masked_dataset.psf, - blurring_grid=masked_dataset.grids.blurring, - ) - - assert fit_linear.galaxy_model_image_dict[galaxy_linear] == pytest.approx( - galaxy_image.array, 1.0e-4 - ) +import os +from os import path +import shutil + +import numpy as np +import pytest + +import autogalaxy as ag + + +def test__perfect_fit__simulate_and_reload__chi_squared_zero(): + grid = ag.Grid2D.uniform( + shape_native=(11, 11), + pixel_scales=0.2, + over_sample_size=1, + ) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + galaxy_0 = ag.Galaxy( + redshift=0.5, light=ag.lp.Sersic(centre=(0.1, 0.1), intensity=0.1) + ) + galaxy_1 = ag.Galaxy( + redshift=0.5, light=ag.lp.Exponential(centre=(0.1, 0.1), intensity=0.5) + ) + + simulator = ag.SimulatorImaging( + exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + dataset.noise_map = ag.Array2D.ones( + shape_native=dataset.data.shape_native, pixel_scales=0.2 + ) + + file_path = path.join( + "{}".format(path.dirname(path.realpath(__file__))), + "data_temp", + "simulate_and_fit", + ) + + try: + shutil.rmtree(file_path) + except FileNotFoundError: + pass + + if path.exists(file_path) is False: + os.makedirs(file_path) + + dataset.output_to_fits( + data_path=path.join(file_path, "data.fits"), + noise_map_path=path.join(file_path, "noise_map.fits"), + psf_path=path.join(file_path, "psf.fits"), + ) + + dataset = ag.Imaging.from_fits( + data_path=path.join(file_path, "data.fits"), + noise_map_path=path.join(file_path, "noise_map.fits"), + psf_path=path.join(file_path, "psf.fits"), + pixel_scales=0.2, + over_sample_size_lp=1, + ) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, + pixel_scales=0.2, + radius=0.8, + ) + + masked_dataset = dataset.apply_mask(mask=mask) + + fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy_0, galaxy_1]) + + assert fit.chi_squared == pytest.approx(0.0, 1e-4) + + file_path = path.join( + "{}".format(path.dirname(path.realpath(__file__))), "data_temp" + ) + + if path.exists(file_path) is True: + shutil.rmtree(file_path) + + +def test__simulate_imaging_data_and_fit__standard_galaxies__known_figure_of_merit(): + grid = ag.Grid2D.uniform(shape_native=(31, 31), pixel_scales=0.2) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + galaxy_0 = ag.Galaxy( + redshift=0.5, + bulge=ag.lp.Sersic(centre=(0.1, 0.1), intensity=0.1), + disk=ag.lp.Sersic(centre=(0.2, 0.2), intensity=0.2), + ) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(16, 16)), + regularization=ag.reg.Constant(coefficient=(1.0)), + ) + + galaxy_1 = ag.Galaxy(redshift=1.0, pixelization=pixelization) + + simulator = ag.SimulatorImaging(exposure_time=300.0, psf=psf, noise_seed=1) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, pixel_scales=0.2, radius=2.005 + ) + + masked_dataset = dataset.apply_mask(mask=mask) + + fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy_0, galaxy_1]) + + assert fit.figure_of_merit == pytest.approx(579.015739085647, 1.0e-2) + + +def test__simulate_imaging_data_and_fit__basis_galaxies__same_figure_of_merit_as_standard(): + grid = ag.Grid2D.uniform(shape_native=(31, 31), pixel_scales=0.2) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(16, 16)), + regularization=ag.reg.Constant(coefficient=(1.0)), + ) + + galaxy_1 = ag.Galaxy(redshift=1.0, pixelization=pixelization) + + simulator = ag.SimulatorImaging(exposure_time=300.0, psf=psf, noise_seed=1) + + basis = ag.lp_basis.Basis( + profile_list=[ + ag.lp.Sersic(centre=(0.1, 0.1), intensity=0.1), + ag.lp.Sersic(centre=(0.2, 0.2), intensity=0.2), + ] + ) + + galaxy_0 = ag.Galaxy(redshift=0.5, bulge=basis) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, pixel_scales=0.2, radius=2.005 + ) + + masked_dataset = dataset.apply_mask(mask=mask) + + fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy_0, galaxy_1]) + + assert fit.figure_of_merit == pytest.approx(579.015739085647, 1.0e-2) + + +def test__linear_light_profiles_agree_with_standard__reconstruction_recovers_intensities(): + grid = ag.Grid2D.uniform( + shape_native=(11, 11), + pixel_scales=0.2, + over_sample_size=1, + ) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + galaxy = ag.Galaxy( + redshift=0.5, + bulge=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.1, sersic_index=1.0), + disk=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.2, sersic_index=4.0), + ) + + simulator = ag.SimulatorImaging( + exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy], grid=grid) + dataset.noise_map = ag.Array2D.ones( + shape_native=dataset.data.shape_native, pixel_scales=0.2 + ) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, + pixel_scales=0.2, + radius=0.81, + ) + + masked_dataset = dataset.apply_mask(mask=mask) + masked_dataset = masked_dataset.apply_over_sampling(over_sample_size_lp=1) + + galaxy_linear = ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=1.0), + disk=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=4.0), + ) + + fit_linear = ag.FitImaging( + dataset=masked_dataset, + galaxies=[galaxy_linear], + ) + + assert fit_linear.inversion.reconstruction == pytest.approx( + np.array([0.1, 0.2]), 1.0e-2 + ) + + +def test__linear_light_profiles_agree_with_standard__intensity_dict_recovers_correct_values(): + grid = ag.Grid2D.uniform( + shape_native=(11, 11), + pixel_scales=0.2, + over_sample_size=1, + ) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + galaxy = ag.Galaxy( + redshift=0.5, + bulge=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.1, sersic_index=1.0), + disk=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.2, sersic_index=4.0), + ) + + simulator = ag.SimulatorImaging( + exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy], grid=grid) + dataset.noise_map = ag.Array2D.ones( + shape_native=dataset.data.shape_native, pixel_scales=0.2 + ) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, + pixel_scales=0.2, + radius=0.81, + ) + + masked_dataset = dataset.apply_mask(mask=mask) + masked_dataset = masked_dataset.apply_over_sampling(over_sample_size_lp=1) + + galaxy_linear = ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=1.0), + disk=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=4.0), + ) + + fit_linear = ag.FitImaging( + dataset=masked_dataset, + galaxies=[galaxy_linear], + ) + + assert fit_linear.linear_light_profile_intensity_dict[ + galaxy_linear.bulge + ] == pytest.approx(0.1, 1.0e-2) + assert fit_linear.linear_light_profile_intensity_dict[ + galaxy_linear.disk + ] == pytest.approx(0.2, 1.0e-2) + + +def test__linear_light_profiles_agree_with_standard__figure_of_merit_matches_standard_fit(): + grid = ag.Grid2D.uniform( + shape_native=(11, 11), + pixel_scales=0.2, + over_sample_size=1, + ) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + galaxy = ag.Galaxy( + redshift=0.5, + bulge=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.1, sersic_index=1.0), + disk=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.2, sersic_index=4.0), + ) + + simulator = ag.SimulatorImaging( + exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy], grid=grid) + dataset.noise_map = ag.Array2D.ones( + shape_native=dataset.data.shape_native, pixel_scales=0.2 + ) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, + pixel_scales=0.2, + radius=0.81, + ) + + masked_dataset = dataset.apply_mask(mask=mask) + masked_dataset = masked_dataset.apply_over_sampling(over_sample_size_lp=1) + + fit = ag.FitImaging(dataset=masked_dataset, galaxies=[galaxy]) + + galaxy_linear = ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=1.0), + disk=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=4.0), + ) + + fit_linear = ag.FitImaging( + dataset=masked_dataset, + galaxies=[galaxy_linear], + ) + + assert fit.log_likelihood == fit_linear.figure_of_merit + assert fit_linear.figure_of_merit == pytest.approx(-45.02798, 1.0e-4) + + +def test__linear_light_profiles_agree_with_standard__galaxy_model_image_matches_blurred_image(): + grid = ag.Grid2D.uniform( + shape_native=(11, 11), + pixel_scales=0.2, + over_sample_size=1, + ) + + psf = ag.Convolver.from_gaussian( + shape_native=(3, 3), pixel_scales=0.2, sigma=0.75, normalize=True + ) + + galaxy = ag.Galaxy( + redshift=0.5, + bulge=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.1, sersic_index=1.0), + disk=ag.lp.Sersic(centre=(0.05, 0.05), intensity=0.2, sersic_index=4.0), + ) + + simulator = ag.SimulatorImaging( + exposure_time=300.0, psf=psf, add_poisson_noise_to_data=False + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy], grid=grid) + dataset.noise_map = ag.Array2D.ones( + shape_native=dataset.data.shape_native, pixel_scales=0.2 + ) + + mask = ag.Mask2D.circular( + shape_native=dataset.data.shape_native, + pixel_scales=0.2, + radius=0.81, + ) + + masked_dataset = dataset.apply_mask(mask=mask) + masked_dataset = masked_dataset.apply_over_sampling(over_sample_size_lp=1) + + galaxy_linear = ag.Galaxy( + redshift=0.5, + bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=1.0), + disk=ag.lp_linear.Sersic(centre=(0.05, 0.05), sersic_index=4.0), + ) + + fit_linear = ag.FitImaging( + dataset=masked_dataset, + galaxies=[galaxy_linear], + ) + + galaxy_image = galaxy.blurred_image_2d_from( + grid=masked_dataset.grids.lp, + psf=masked_dataset.psf, + blurring_grid=masked_dataset.grids.blurring, + ) + + assert fit_linear.galaxy_model_image_dict[galaxy_linear] == pytest.approx( + galaxy_image.array, 1.0e-4 + ) diff --git a/test_autogalaxy/imaging/test_simulator.py b/test_autogalaxy/imaging/test_simulator.py index a074af016..e581cf6e8 100644 --- a/test_autogalaxy/imaging/test_simulator.py +++ b/test_autogalaxy/imaging/test_simulator.py @@ -1,112 +1,305 @@ -import numpy as np -import os -from os import path -import pytest -import shutil - -import autogalaxy as ag - - -def create_fits(fits_path, array): - - from astropy.io import fits - - file_dir = os.path.split(fits_path)[0] - - if not os.path.exists(file_dir): - os.makedirs(file_dir) - - if os.path.exists(fits_path): - os.remove(fits_path) - - hdu_list = fits.HDUList() - - hdu_list.append(fits.ImageHDU(array)) - - hdu_list.writeto(f"{fits_path}") - - -def clean_fits(fits_path): - if path.exists(fits_path): - shutil.rmtree(fits_path) - - - -def test__simulator__via_galaxies_from(): - psf = ag.Convolver.from_gaussian(shape_native=(7, 7), sigma=0.5, pixel_scales=0.05) - - grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) - - galaxy_0 = ag.Galaxy(redshift=0.5, light=ag.lp.Sersic(intensity=1.0)) - - galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) - - simulator = ag.SimulatorImaging( - psf=psf, - exposure_time=10000.0, - background_sky_level=100.0, - add_poisson_noise_to_data=False, - include_poisson_noise_in_noise_map=False, - ) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - - galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) - - imaging_via_image = simulator.via_image_from( - image=galaxies.image_2d_from(grid=grid) - ) - - assert dataset.shape_native == (20, 20) - assert dataset.data.native[0, 0] != imaging_via_image.data.native[0, 0] - assert dataset.data.native[10, 10] == pytest.approx( - imaging_via_image.data.native[10, 10], 1.0e-4 - ) - assert dataset.psf.kernel == pytest.approx(imaging_via_image.psf.kernel, 1.0e-4) - assert dataset.noise_map == pytest.approx(imaging_via_image.noise_map, 1.0e-4) - - -def test__simulator__simulate_imaging_from_galaxy__source_galaxy__compare_to_imaging(): - galaxy_0 = ag.Galaxy( - redshift=0.5, - mass=ag.mp.Isothermal( - centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) - ), - ) - - galaxy_1 = ag.Galaxy( - redshift=1.0, - light=ag.lp.Sersic( - centre=(0.1, 0.1), - ell_comps=(0.096225, -0.055555), - intensity=0.3, - effective_radius=1.0, - sersic_index=2.5, - ), - ) - - grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.2) - - kernel = ag.Array2D.no_mask(values=[[1.0]], pixel_scales=0.2) - psf = ag.Convolver(kernel=kernel) - - simulator = ag.SimulatorImaging( - psf=psf, - exposure_time=10000.0, - background_sky_level=100.0, - add_poisson_noise_to_data=True, - noise_seed=1, - ) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - - galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) - - imaging_via_image = simulator.via_image_from( - image=galaxies.image_2d_from(grid=grid) - ) - - assert dataset.shape_native == (11, 11) - assert dataset.data.array == pytest.approx(imaging_via_image.data.array, 1.0e-4) - assert (dataset.psf.kernel == imaging_via_image.psf.kernel).all() - assert dataset.noise_map == pytest.approx(imaging_via_image.noise_map, 1.0e-4) +import numpy as np +import os +from os import path +import pytest +import shutil + +import autogalaxy as ag + + +def test__simulator__via_galaxies_from__shape_native_correct(): + psf = ag.Convolver.from_gaussian(shape_native=(7, 7), sigma=0.5, pixel_scales=0.05) + + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=ag.lp.Sersic(intensity=1.0)) + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=False, + include_poisson_noise_in_noise_map=False, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + assert dataset.shape_native == (20, 20) + + +def test__simulator__via_galaxies_from__edge_pixel_differs_from_via_image( +): + psf = ag.Convolver.from_gaussian(shape_native=(7, 7), sigma=0.5, pixel_scales=0.05) + + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=ag.lp.Sersic(intensity=1.0)) + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=False, + include_poisson_noise_in_noise_map=False, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.data.native[0, 0] != imaging_via_image.data.native[0, 0] + + +def test__simulator__via_galaxies_from__centre_pixel_matches_via_image(): + psf = ag.Convolver.from_gaussian(shape_native=(7, 7), sigma=0.5, pixel_scales=0.05) + + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=ag.lp.Sersic(intensity=1.0)) + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=False, + include_poisson_noise_in_noise_map=False, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.data.native[10, 10] == pytest.approx( + imaging_via_image.data.native[10, 10], 1.0e-4 + ) + + +def test__simulator__via_galaxies_from__psf_matches_via_image(): + psf = ag.Convolver.from_gaussian(shape_native=(7, 7), sigma=0.5, pixel_scales=0.05) + + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=ag.lp.Sersic(intensity=1.0)) + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=False, + include_poisson_noise_in_noise_map=False, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.psf.kernel == pytest.approx(imaging_via_image.psf.kernel, 1.0e-4) + + +def test__simulator__via_galaxies_from__noise_map_matches_via_image(): + psf = ag.Convolver.from_gaussian(shape_native=(7, 7), sigma=0.5, pixel_scales=0.05) + + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy(redshift=0.5, light=ag.lp.Sersic(intensity=1.0)) + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=False, + include_poisson_noise_in_noise_map=False, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.noise_map == pytest.approx(imaging_via_image.noise_map, 1.0e-4) + + +def test__simulator__simulate_imaging_from_galaxy__shape_native_correct(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=1.0, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.2) + + kernel = ag.Array2D.no_mask(values=[[1.0]], pixel_scales=0.2) + psf = ag.Convolver(kernel=kernel) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=True, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + assert dataset.shape_native == (11, 11) + + +def test__simulator__simulate_imaging_from_galaxy__data_matches_via_image(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=1.0, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.2) + + kernel = ag.Array2D.no_mask(values=[[1.0]], pixel_scales=0.2) + psf = ag.Convolver(kernel=kernel) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=True, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.data.array == pytest.approx(imaging_via_image.data.array, 1.0e-4) + + +def test__simulator__simulate_imaging_from_galaxy__psf_matches_via_image(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=1.0, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.2) + + kernel = ag.Array2D.no_mask(values=[[1.0]], pixel_scales=0.2) + psf = ag.Convolver(kernel=kernel) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=True, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert (dataset.psf.kernel == imaging_via_image.psf.kernel).all() + + +def test__simulator__simulate_imaging_from_galaxy__noise_map_matches_via_image(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=1.0, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.2) + + kernel = ag.Array2D.no_mask(values=[[1.0]], pixel_scales=0.2) + psf = ag.Convolver(kernel=kernel) + + simulator = ag.SimulatorImaging( + psf=psf, + exposure_time=10000.0, + background_sky_level=100.0, + add_poisson_noise_to_data=True, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + imaging_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.noise_map == pytest.approx(imaging_via_image.noise_map, 1.0e-4) diff --git a/test_autogalaxy/interferometer/test_fit_interferometer.py b/test_autogalaxy/interferometer/test_fit_interferometer.py index e10d07529..68439a85a 100644 --- a/test_autogalaxy/interferometer/test_fit_interferometer.py +++ b/test_autogalaxy/interferometer/test_fit_interferometer.py @@ -1,364 +1,511 @@ -import numpy as np -import pytest - -import autogalaxy as ag - - -def test__model_visibilities(interferometer_7): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.m.MockLightProfile(image_2d=np.ones(9))) - - fit = ag.FitInterferometer(dataset=interferometer_7, galaxies=[g0]) - - assert fit.model_data.slim[0].real == pytest.approx(1.48496, abs=1.0e-4) - assert fit.model_data.slim[0].imag == pytest.approx(0.0, abs=1.0e-4) - assert fit.log_likelihood == pytest.approx(-34.1685958, abs=1.0e-4) - - -def test__fit_figure_of_merit(interferometer_7): - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - - fit = ag.FitInterferometer(dataset=interferometer_7, galaxies=[g0, g1]) - - assert fit.perform_inversion is False - assert fit.figure_of_merit == pytest.approx(-1994.35383952, 1.0e-4) - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), - ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), - ] - ) - - g0 = ag.Galaxy(redshift=0.5, bulge=basis) - - fit = ag.FitInterferometer(dataset=interferometer_7, galaxies=[g0]) - - assert fit.perform_inversion is False - assert fit.figure_of_merit == pytest.approx(-1994.3538395, 1.0e-4) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=0.01), - ) - - g0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[ag.Galaxy(redshift=0.5), g0], - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-71.770448724198, 1.0e-4) - - galaxy_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)) - ) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[galaxy_light, galaxy_pix], - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-196.15073725528504, 1.0e-4) - - g0_linear_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) - ) - - g1_linear_light = ag.Galaxy( - redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) - ) - - fit = ag.FitInterferometer( - dataset=interferometer_7, galaxies=[g0_linear_light, g1_linear_light] - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-23.44419, 1.0e-4) - - basis = ag.lp_basis.Basis( - profile_list=[ - ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), - ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), - ] - ) - - fit = ag.FitInterferometer( - dataset=interferometer_7, galaxies=[ag.Galaxy(redshift=0.5, bulge=basis)] - ) - - assert fit.perform_inversion is True - assert fit.figure_of_merit == pytest.approx(-23.44419235, 1.0e-4) - - fit = ag.FitInterferometer( - dataset=interferometer_7, galaxies=[g0_linear_light, galaxy_pix] - ) - - assert fit.log_evidence == pytest.approx(-37.4081355120388, 1e-4) - assert fit.figure_of_merit == pytest.approx(-37.4081355120388, 1.0e-4) - - -def test___galaxy_image_dict(interferometer_7): - # Normal Light Profiles Only - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) - g2 = ag.Galaxy( - redshift=0.5, - light_profile_0=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), - light_profile_1=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05)), - ) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0, g1, g2], - ) - - g0_image = g0.image_2d_from(grid=interferometer_7.grids.lp) - g1_image = g1.image_2d_from(grid=interferometer_7.grids.lp) - - assert fit.galaxy_image_dict[g0] == pytest.approx(g0_image.array, 1.0e-4) - assert fit.galaxy_image_dict[g1] == pytest.approx(g1_image.array, 1.0e-4) - assert fit.galaxy_image_dict[g2] == pytest.approx( - g0_image.array + g1_image.array, 1.0e-4 - ) - - # Linear Light Profiles Only - - g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0_linear], - ) - - assert fit.galaxy_image_dict[g0_linear][4] == pytest.approx(0.9876689631, 1.0e-4) - - # Pixelization + Regularizaiton only - mesh = ag.mesh.RectangularUniform(shape=(3, 3)) - - pixelization = ag.Pixelization( - mesh=mesh, - regularization=ag.reg.Constant(coefficient=1.0), - ) - - g0 = ag.Galaxy(redshift=0.5) - galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0, galaxy_pix_0], - settings=ag.Settings(use_border_relocator=True), - ) - - interpolator = mesh.interpolator_from( - source_plane_data_grid=interferometer_7.grids.lp, - border_relocator=interferometer_7.grids.border_relocator, - source_plane_mesh_grid=None, - ) - - mapper = ag.Mapper( - interpolator=interpolator, - regularization=pixelization.regularization, - ) - - inversion = ag.Inversion( - dataset=interferometer_7, - linear_obj_list=[mapper], - ) - - assert (fit.galaxy_image_dict[g0].native == 0.0 + 0.0j * np.zeros((7,))).all() - - assert fit.galaxy_image_dict[galaxy_pix_0].array == pytest.approx( - inversion.mapped_reconstructed_data.slim.array, 1.0e-4 - ) - - # Linear Light PRofiles + Pixelization + Regularizaiton - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=2.0), - ) - - galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0_linear, g1, galaxy_pix_0, galaxy_pix_1], - ) - - assert fit.galaxy_image_dict[g0_linear][4] == pytest.approx(-46.8820117, 1.0e-2) - assert fit.galaxy_image_dict[g1] == pytest.approx(g1_image.array, 1.0e-4) - assert fit.galaxy_image_dict[galaxy_pix_0][4] == pytest.approx(-0.00541699, 1.0e-2) - assert fit.galaxy_image_dict[galaxy_pix_1][4] == pytest.approx(-0.00563034, 1.0e-2) - - mapped_reconstructed_data = ( - fit.galaxy_image_dict[g0_linear] - + fit.galaxy_image_dict[galaxy_pix_0] - + fit.galaxy_image_dict[galaxy_pix_1] - ) - - assert mapped_reconstructed_data.array == pytest.approx( - fit.inversion.mapped_reconstructed_data.array, 1.0e-4 - ) - - -def test___galaxy_model_visibilities_dict(interferometer_7): - # Normal Light Profiles Only - - g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) - g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) - g2 = ag.Galaxy( - redshift=0.5, - light_profile_0=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), - light_profile_1=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05)), - ) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0, g1, g2], - ) - - g0_visibilities = g0.visibilities_from( - grid=interferometer_7.grids.lp, transformer=interferometer_7.transformer - ) - g1_visibilities = g1.visibilities_from( - grid=interferometer_7.grids.lp, transformer=interferometer_7.transformer - ) - - assert fit.galaxy_model_visibilities_dict[g0].array == pytest.approx( - g0_visibilities.array, 1.0e-4 - ) - assert fit.galaxy_model_visibilities_dict[g1].array == pytest.approx( - g1_visibilities.array, 1.0e-4 - ) - assert fit.galaxy_model_visibilities_dict[g2].array == pytest.approx( - g0_visibilities.array + g1_visibilities.array, 1.0e-4 - ) - - # Linear Light Profiles Only - - g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0_linear], - ) - - assert fit.galaxy_model_visibilities_dict[g0_linear][0] == pytest.approx( - 0.9965209248910107 + 0.00648675263899049j, 1.0e-4 - ) - - # Pixelization + Regularizaiton only - - mesh = ag.mesh.RectangularUniform(shape=(3, 3)) - - pixelization = ag.Pixelization( - mesh=mesh, - regularization=ag.reg.Constant(coefficient=1.0), - ) - - g0 = ag.Galaxy(redshift=0.5) - galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0, galaxy_pix_0], - settings=ag.Settings(use_border_relocator=True), - ) - - interpolator = mesh.interpolator_from( - source_plane_data_grid=interferometer_7.grids.lp, - border_relocator=interferometer_7.grids.border_relocator, - source_plane_mesh_grid=None, - ) - - mapper = ag.Mapper( - interpolator=interpolator, - regularization=pixelization.regularization, - ) - - inversion = ag.Inversion( - dataset=interferometer_7, - linear_obj_list=[mapper], - ) - - assert (fit.galaxy_model_visibilities_dict[g0] == 0.0 + 0.0j * np.zeros((7,))).all() - - assert fit.galaxy_model_visibilities_dict[galaxy_pix_0].array == pytest.approx( - inversion.mapped_reconstructed_operated_data.array, 1.0e-4 - ) - - # Linear Light PRofiles + Pixelization + Regularizaiton - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=2.0), - ) - - galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, - galaxies=[g0_linear, g1, galaxy_pix_0, galaxy_pix_1], - ) - - assert fit.galaxy_model_visibilities_dict[g0_linear][0] == pytest.approx( - -47.30219078770512 - 0.3079088489343429j, 1.0e-4 - ) - - assert fit.galaxy_model_visibilities_dict[g1].array == pytest.approx( - g1_visibilities.array, 1.0e-4 - ) - assert fit.galaxy_model_visibilities_dict[galaxy_pix_0][0] == pytest.approx( - -0.00889895 + 0.22151583j, 1.0e-4 - ) - assert fit.galaxy_model_visibilities_dict[galaxy_pix_1][0] == pytest.approx( - -0.00857457 + 0.05537896j, 1.0e-4 - ) - - mapped_reconstructed_visibilities = ( - fit.galaxy_model_visibilities_dict[g0_linear] - + fit.galaxy_model_visibilities_dict[galaxy_pix_0] - + fit.galaxy_model_visibilities_dict[galaxy_pix_1] - ) - - assert mapped_reconstructed_visibilities.array == pytest.approx( - fit.inversion.mapped_reconstructed_operated_data.array, 1.0e-4 - ) - - -def test__model_visibilities_of_galaxies_list(interferometer_7): - galaxy_light = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) - galaxy_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic()) - - pixelization = ag.Pixelization( - mesh=ag.mesh.RectangularUniform(shape=(3, 3)), - regularization=ag.reg.Constant(coefficient=1.0), - ) - - galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) - - fit = ag.FitInterferometer( - dataset=interferometer_7, galaxies=[galaxy_light, galaxy_linear, galaxy_pix] - ) - - assert fit.model_visibilities_of_galaxies_list[0].array == pytest.approx( - fit.galaxy_model_visibilities_dict[galaxy_light].array, 1.0e-4 - ) - assert fit.model_visibilities_of_galaxies_list[1].array == pytest.approx( - fit.galaxy_model_visibilities_dict[galaxy_linear].array, 1.0e-4 - ) - assert fit.model_visibilities_of_galaxies_list[2].array == pytest.approx( - fit.galaxy_model_visibilities_dict[galaxy_pix].array, 1.0e-4 - ) +import numpy as np +import pytest + +import autogalaxy as ag + + +def test__model_visibilities__real_component__correct_value(interferometer_7): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.m.MockLightProfile(image_2d=np.ones(9))) + + fit = ag.FitInterferometer(dataset=interferometer_7, galaxies=[g0]) + + assert fit.model_data.slim[0].real == pytest.approx(1.48496, abs=1.0e-4) + + +def test__model_visibilities__imaginary_component__correct_value(interferometer_7): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.m.MockLightProfile(image_2d=np.ones(9))) + + fit = ag.FitInterferometer(dataset=interferometer_7, galaxies=[g0]) + + assert fit.model_data.slim[0].imag == pytest.approx(0.0, abs=1.0e-4) + + +def test__model_visibilities__log_likelihood__correct_value(interferometer_7): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.m.MockLightProfile(image_2d=np.ones(9))) + + fit = ag.FitInterferometer(dataset=interferometer_7, galaxies=[g0]) + + assert fit.log_likelihood == pytest.approx(-34.1685958, abs=1.0e-4) + + +@pytest.mark.parametrize( + "galaxies_factory, expected_fom, expect_inversion", + [ + ("two_sersic_galaxies", -1994.35383952, False), + ("basis_of_sersics", -1994.3538395, False), + ("pixelization_only", -71.770448724198, True), + ("light_plus_pixelization", -196.15073725528504, True), + ("two_linear_light_profiles", -23.44419, True), + ("basis_of_linear_light_profiles", -23.44419235, True), + ], +) +def test__fit_figure_of_merit__various_galaxy_configs__correct_value_and_inversion_flag( + interferometer_7, galaxies_factory, expected_fom, expect_inversion +): + pixelization_01 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=0.01), + ) + pixelization_10 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + galaxy_pix_01 = ag.Galaxy(redshift=0.5, pixelization=pixelization_01) + galaxy_pix_10 = ag.Galaxy(redshift=0.5, pixelization=pixelization_10) + + g0_linear_light = ag.Galaxy( + redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + ) + g1_linear_light = ag.Galaxy( + redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)) + ) + + factories = { + "two_sersic_galaxies": [ + ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)) + ), + ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)) + ), + ], + "basis_of_sersics": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_basis.Basis( + profile_list=[ + ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), + ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), + ] + ), + ) + ], + "pixelization_only": [ag.Galaxy(redshift=0.5), galaxy_pix_01], + "light_plus_pixelization": [ + ag.Galaxy( + redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)) + ), + galaxy_pix_10, + ], + "two_linear_light_profiles": [g0_linear_light, g1_linear_light], + "basis_of_linear_light_profiles": [ + ag.Galaxy( + redshift=0.5, + bulge=ag.lp_basis.Basis( + profile_list=[ + ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)), + ag.lp_linear.Sersic(sersic_index=4.0, centre=(0.05, 0.05)), + ] + ), + ) + ], + } + + fit = ag.FitInterferometer( + dataset=interferometer_7, galaxies=factories[galaxies_factory] + ) + + assert fit.perform_inversion is expect_inversion + assert fit.figure_of_merit == pytest.approx(expected_fom, 1.0e-4) + + +def test__fit_figure_of_merit__linear_light_plus_pixelization__log_evidence_correct( + interferometer_7, +): + g0_linear_light = ag.Galaxy( + redshift=0.5, bulge=ag.lp_linear.Sersic(sersic_index=1.0, centre=(0.05, 0.05)) + ) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitInterferometer( + dataset=interferometer_7, galaxies=[g0_linear_light, galaxy_pix] + ) + + assert fit.log_evidence == pytest.approx(-37.4081355120388, 1e-4) + assert fit.figure_of_merit == pytest.approx(-37.4081355120388, 1.0e-4) + + +def test__galaxy_image_dict__normal_light_profiles__individual_galaxies_match( + interferometer_7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) + g2 = ag.Galaxy( + redshift=0.5, + light_profile_0=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), + light_profile_1=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05)), + ) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0, g1, g2], + ) + + g0_image = g0.image_2d_from(grid=interferometer_7.grids.lp) + g1_image = g1.image_2d_from(grid=interferometer_7.grids.lp) + + assert fit.galaxy_image_dict[g0] == pytest.approx(g0_image.array, 1.0e-4) + assert fit.galaxy_image_dict[g1] == pytest.approx(g1_image.array, 1.0e-4) + assert fit.galaxy_image_dict[g2] == pytest.approx( + g0_image.array + g1_image.array, 1.0e-4 + ) + + +def test__galaxy_image_dict__linear_light_profile_only__correct_pixel_value( + interferometer_7, +): + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0_linear], + ) + + assert fit.galaxy_image_dict[g0_linear][4] == pytest.approx(0.9876689631, 1.0e-4) + + +def test__galaxy_image_dict__pixelization_only__no_light_galaxy_returns_zeros( + interferometer_7, +): + mesh = ag.mesh.RectangularUniform(shape=(3, 3)) + + pixelization = ag.Pixelization( + mesh=mesh, + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0, galaxy_pix_0], + settings=ag.Settings(use_border_relocator=True), + ) + + assert (fit.galaxy_image_dict[g0].native == 0.0 + 0.0j * np.zeros((7,))).all() + + +def test__galaxy_image_dict__pixelization_only__matches_inversion_mapped_reconstructed_data( + interferometer_7, +): + mesh = ag.mesh.RectangularUniform(shape=(3, 3)) + + pixelization = ag.Pixelization( + mesh=mesh, + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0, galaxy_pix_0], + settings=ag.Settings(use_border_relocator=True), + ) + + interpolator = mesh.interpolator_from( + source_plane_data_grid=interferometer_7.grids.lp, + border_relocator=interferometer_7.grids.border_relocator, + source_plane_mesh_grid=None, + ) + + mapper = ag.Mapper( + interpolator=interpolator, + regularization=pixelization.regularization, + ) + + inversion = ag.Inversion( + dataset=interferometer_7, + linear_obj_list=[mapper], + ) + + assert fit.galaxy_image_dict[galaxy_pix_0].array == pytest.approx( + inversion.mapped_reconstructed_data.slim.array, 1.0e-4 + ) + + +def test__galaxy_image_dict__linear_and_pixelization__correct_pixel_values( + interferometer_7, +): + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + + pixelization_10 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + pixelization_20 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=2.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization_10) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization_20) + + g1_image = g1.image_2d_from(grid=interferometer_7.grids.lp) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0_linear, g1, galaxy_pix_0, galaxy_pix_1], + ) + + assert fit.galaxy_image_dict[g0_linear][4] == pytest.approx(-46.8820117, 1.0e-2) + assert fit.galaxy_image_dict[g1] == pytest.approx(g1_image.array, 1.0e-4) + assert fit.galaxy_image_dict[galaxy_pix_0][4] == pytest.approx(-0.00541699, 1.0e-2) + assert fit.galaxy_image_dict[galaxy_pix_1][4] == pytest.approx(-0.00563034, 1.0e-2) + + +def test__galaxy_image_dict__linear_and_pixelization__sum_matches_inversion_mapped_data( + interferometer_7, +): + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + + pixelization_10 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + pixelization_20 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=2.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization_10) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization_20) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0_linear, g1, galaxy_pix_0, galaxy_pix_1], + ) + + mapped_reconstructed_data = ( + fit.galaxy_image_dict[g0_linear] + + fit.galaxy_image_dict[galaxy_pix_0] + + fit.galaxy_image_dict[galaxy_pix_1] + ) + + assert mapped_reconstructed_data.array == pytest.approx( + fit.inversion.mapped_reconstructed_data.array, 1.0e-4 + ) + + +def test__galaxy_model_visibilities_dict__normal_light_profiles__individual_galaxies_match( + interferometer_7, +): + g0 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05))) + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) + g2 = ag.Galaxy( + redshift=0.5, + light_profile_0=ag.lp.Sersic(intensity=1.0, centre=(0.05, 0.05)), + light_profile_1=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05)), + ) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0, g1, g2], + ) + + g0_visibilities = g0.visibilities_from( + grid=interferometer_7.grids.lp, transformer=interferometer_7.transformer + ) + g1_visibilities = g1.visibilities_from( + grid=interferometer_7.grids.lp, transformer=interferometer_7.transformer + ) + + assert fit.galaxy_model_visibilities_dict[g0].array == pytest.approx( + g0_visibilities.array, 1.0e-4 + ) + assert fit.galaxy_model_visibilities_dict[g1].array == pytest.approx( + g1_visibilities.array, 1.0e-4 + ) + assert fit.galaxy_model_visibilities_dict[g2].array == pytest.approx( + g0_visibilities.array + g1_visibilities.array, 1.0e-4 + ) + + +def test__galaxy_model_visibilities_dict__linear_light_profile_only__correct_first_visibility( + interferometer_7, +): + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0_linear], + ) + + assert fit.galaxy_model_visibilities_dict[g0_linear][0] == pytest.approx( + 0.9965209248910107 + 0.00648675263899049j, 1.0e-4 + ) + + +def test__galaxy_model_visibilities_dict__pixelization_only__no_light_galaxy_returns_zeros( + interferometer_7, +): + mesh = ag.mesh.RectangularUniform(shape=(3, 3)) + + pixelization = ag.Pixelization( + mesh=mesh, + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0, galaxy_pix_0], + settings=ag.Settings(use_border_relocator=True), + ) + + assert (fit.galaxy_model_visibilities_dict[g0] == 0.0 + 0.0j * np.zeros((7,))).all() + + +def test__galaxy_model_visibilities_dict__pixelization_only__matches_inversion_reconstructed_operated_data( + interferometer_7, +): + mesh = ag.mesh.RectangularUniform(shape=(3, 3)) + + pixelization = ag.Pixelization( + mesh=mesh, + regularization=ag.reg.Constant(coefficient=1.0), + ) + + g0 = ag.Galaxy(redshift=0.5) + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0, galaxy_pix_0], + settings=ag.Settings(use_border_relocator=True), + ) + + interpolator = mesh.interpolator_from( + source_plane_data_grid=interferometer_7.grids.lp, + border_relocator=interferometer_7.grids.border_relocator, + source_plane_mesh_grid=None, + ) + + mapper = ag.Mapper( + interpolator=interpolator, + regularization=pixelization.regularization, + ) + + inversion = ag.Inversion( + dataset=interferometer_7, + linear_obj_list=[mapper], + ) + + assert fit.galaxy_model_visibilities_dict[galaxy_pix_0].array == pytest.approx( + inversion.mapped_reconstructed_operated_data.array, 1.0e-4 + ) + + +def test__galaxy_model_visibilities_dict__linear_and_pixelization__correct_first_visibility_values( + interferometer_7, +): + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + + pixelization_10 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + pixelization_20 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=2.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization_10) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization_20) + + g1_visibilities = g1.visibilities_from( + grid=interferometer_7.grids.lp, transformer=interferometer_7.transformer + ) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0_linear, g1, galaxy_pix_0, galaxy_pix_1], + ) + + assert fit.galaxy_model_visibilities_dict[g0_linear][0] == pytest.approx( + -47.30219078770512 - 0.3079088489343429j, 1.0e-4 + ) + assert fit.galaxy_model_visibilities_dict[g1].array == pytest.approx( + g1_visibilities.array, 1.0e-4 + ) + assert fit.galaxy_model_visibilities_dict[galaxy_pix_0][0] == pytest.approx( + -0.00889895 + 0.22151583j, 1.0e-4 + ) + assert fit.galaxy_model_visibilities_dict[galaxy_pix_1][0] == pytest.approx( + -0.00857457 + 0.05537896j, 1.0e-4 + ) + + +def test__galaxy_model_visibilities_dict__linear_and_pixelization__sum_matches_inversion_operated_data( + interferometer_7, +): + g1 = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=2.0, centre=(0.05, 0.05))) + g0_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic(centre=(0.05, 0.05))) + + pixelization_10 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + pixelization_20 = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=2.0), + ) + + galaxy_pix_0 = ag.Galaxy(redshift=0.5, pixelization=pixelization_10) + galaxy_pix_1 = ag.Galaxy(redshift=0.5, pixelization=pixelization_20) + + fit = ag.FitInterferometer( + dataset=interferometer_7, + galaxies=[g0_linear, g1, galaxy_pix_0, galaxy_pix_1], + ) + + mapped_reconstructed_visibilities = ( + fit.galaxy_model_visibilities_dict[g0_linear] + + fit.galaxy_model_visibilities_dict[galaxy_pix_0] + + fit.galaxy_model_visibilities_dict[galaxy_pix_1] + ) + + assert mapped_reconstructed_visibilities.array == pytest.approx( + fit.inversion.mapped_reconstructed_operated_data.array, 1.0e-4 + ) + + +def test__model_visibilities_of_galaxies_list__matches_galaxy_model_visibilities_dict( + interferometer_7, +): + galaxy_light = ag.Galaxy(redshift=0.5, bulge=ag.lp.Sersic(intensity=1.0)) + galaxy_linear = ag.Galaxy(redshift=0.5, bulge=ag.lp_linear.Sersic()) + + pixelization = ag.Pixelization( + mesh=ag.mesh.RectangularUniform(shape=(3, 3)), + regularization=ag.reg.Constant(coefficient=1.0), + ) + + galaxy_pix = ag.Galaxy(redshift=0.5, pixelization=pixelization) + + fit = ag.FitInterferometer( + dataset=interferometer_7, galaxies=[galaxy_light, galaxy_linear, galaxy_pix] + ) + + assert fit.model_visibilities_of_galaxies_list[0].array == pytest.approx( + fit.galaxy_model_visibilities_dict[galaxy_light].array, 1.0e-4 + ) + assert fit.model_visibilities_of_galaxies_list[1].array == pytest.approx( + fit.galaxy_model_visibilities_dict[galaxy_linear].array, 1.0e-4 + ) + assert fit.model_visibilities_of_galaxies_list[2].array == pytest.approx( + fit.galaxy_model_visibilities_dict[galaxy_pix].array, 1.0e-4 + ) diff --git a/test_autogalaxy/interferometer/test_simulator.py b/test_autogalaxy/interferometer/test_simulator.py index fa95a0a72..9532262bb 100644 --- a/test_autogalaxy/interferometer/test_simulator.py +++ b/test_autogalaxy/interferometer/test_simulator.py @@ -1,75 +1,207 @@ -import autogalaxy as ag -import numpy as np -import pytest - - -def test__from_plane__same_as_plane_input(): - grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) - - galaxy_0 = ag.Galaxy( - redshift=0.5, - light=ag.lp.Sersic(intensity=1.0), - mass=ag.mp.Isothermal(einstein_radius=1.6), - ) - - galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) - - galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) - - simulator = ag.SimulatorInterferometer( - uv_wavelengths=np.ones(shape=(7, 2)), - exposure_time=10000.0, - noise_sigma=0.1, - noise_seed=1, - ) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - - interferometer_via_image = simulator.via_image_from( - image=galaxies.image_2d_from(grid=grid) - ) - - assert (dataset.data == interferometer_via_image.data.array).all() - assert (dataset.uv_wavelengths == interferometer_via_image.uv_wavelengths).all() - assert (dataset.noise_map == interferometer_via_image.noise_map).all() - - -def test__simulate_interferometer_from_galaxy__source_galaxy__compare_to_interferometer(): - galaxy_0 = ag.Galaxy( - redshift=0.5, - mass=ag.mp.Isothermal( - centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) - ), - ) - - galaxy_1 = ag.Galaxy( - redshift=0.5, - light=ag.lp.Sersic( - centre=(0.1, 0.1), - ell_comps=(0.096225, -0.055555), - intensity=0.3, - effective_radius=1.0, - sersic_index=2.5, - ), - ) - - grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.05) - - simulator = ag.SimulatorInterferometer( - uv_wavelengths=np.ones(shape=(7, 2)), - exposure_time=10000.0, - noise_sigma=0.1, - noise_seed=1, - ) - - dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) - - galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) - - interferometer_via_image = simulator.via_image_from( - image=galaxies.image_2d_from(grid=grid) - ) - - assert dataset.data == pytest.approx(interferometer_via_image.data.array, 1.0e-4) - assert (dataset.uv_wavelengths == interferometer_via_image.uv_wavelengths).all() - assert (interferometer_via_image.noise_map == dataset.noise_map).all() +import autogalaxy as ag +import numpy as np +import pytest + + +def test__simulator__via_galaxies_from__data_matches_via_image(): + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy( + redshift=0.5, + light=ag.lp.Sersic(intensity=1.0), + mass=ag.mp.Isothermal(einstein_radius=1.6), + ) + + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + simulator = ag.SimulatorInterferometer( + uv_wavelengths=np.ones(shape=(7, 2)), + exposure_time=10000.0, + noise_sigma=0.1, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + interferometer_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert (dataset.data == interferometer_via_image.data.array).all() + + +def test__simulator__via_galaxies_from__uv_wavelengths_match_via_image(): + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy( + redshift=0.5, + light=ag.lp.Sersic(intensity=1.0), + mass=ag.mp.Isothermal(einstein_radius=1.6), + ) + + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + simulator = ag.SimulatorInterferometer( + uv_wavelengths=np.ones(shape=(7, 2)), + exposure_time=10000.0, + noise_sigma=0.1, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + interferometer_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert (dataset.uv_wavelengths == interferometer_via_image.uv_wavelengths).all() + + +def test__simulator__via_galaxies_from__noise_map_matches_via_image(): + grid = ag.Grid2D.uniform(shape_native=(20, 20), pixel_scales=0.05) + + galaxy_0 = ag.Galaxy( + redshift=0.5, + light=ag.lp.Sersic(intensity=1.0), + mass=ag.mp.Isothermal(einstein_radius=1.6), + ) + + galaxy_1 = ag.Galaxy(redshift=1.0, light=ag.lp.Sersic(intensity=0.3)) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + simulator = ag.SimulatorInterferometer( + uv_wavelengths=np.ones(shape=(7, 2)), + exposure_time=10000.0, + noise_sigma=0.1, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + interferometer_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert (dataset.noise_map == interferometer_via_image.noise_map).all() + + +def test__simulator__simulate_from_source_galaxy__data_matches_via_image(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=0.5, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.05) + + simulator = ag.SimulatorInterferometer( + uv_wavelengths=np.ones(shape=(7, 2)), + exposure_time=10000.0, + noise_sigma=0.1, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + interferometer_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert dataset.data == pytest.approx(interferometer_via_image.data.array, 1.0e-4) + + +def test__simulator__simulate_from_source_galaxy__uv_wavelengths_match_via_image(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=0.5, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.05) + + simulator = ag.SimulatorInterferometer( + uv_wavelengths=np.ones(shape=(7, 2)), + exposure_time=10000.0, + noise_sigma=0.1, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + interferometer_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert (dataset.uv_wavelengths == interferometer_via_image.uv_wavelengths).all() + + +def test__simulator__simulate_from_source_galaxy__noise_map_matches_via_image(): + galaxy_0 = ag.Galaxy( + redshift=0.5, + mass=ag.mp.Isothermal( + centre=(0.0, 0.0), einstein_radius=1.6, ell_comps=(0.17647, 0.0) + ), + ) + + galaxy_1 = ag.Galaxy( + redshift=0.5, + light=ag.lp.Sersic( + centre=(0.1, 0.1), + ell_comps=(0.096225, -0.055555), + intensity=0.3, + effective_radius=1.0, + sersic_index=2.5, + ), + ) + + grid = ag.Grid2D.uniform(shape_native=(11, 11), pixel_scales=0.05) + + simulator = ag.SimulatorInterferometer( + uv_wavelengths=np.ones(shape=(7, 2)), + exposure_time=10000.0, + noise_sigma=0.1, + noise_seed=1, + ) + + dataset = simulator.via_galaxies_from(galaxies=[galaxy_0, galaxy_1], grid=grid) + + galaxies = ag.Galaxies(galaxies=[galaxy_0, galaxy_1]) + + interferometer_via_image = simulator.via_image_from( + image=galaxies.image_2d_from(grid=grid) + ) + + assert (interferometer_via_image.noise_map == dataset.noise_map).all() diff --git a/test_autogalaxy/operate/test_image.py b/test_autogalaxy/operate/test_image.py index f7fa4ef8d..259ed2461 100644 --- a/test_autogalaxy/operate/test_image.py +++ b/test_autogalaxy/operate/test_image.py @@ -8,7 +8,7 @@ grid = np.array([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__blurred_image_2d_from( +def test__blurred_image_2d_from__single_light_profile__matches_manual_psf_convolution( grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3, @@ -30,14 +30,12 @@ def test__blurred_image_2d_from( lp_blurred_image_2d.native.array, 1.0e-4 ) - lp_blurred_image_2d = lp.blurred_image_2d_from( - grid=grid_2d_7x7, blurring_grid=blurring_grid_2d_7x7, psf=psf_3x3 - ) - - assert blurred_image_2d_manual.native == pytest.approx( - lp_blurred_image_2d.native.array, 1.0e-4 - ) +def test__blurred_image_2d_from__galaxy_with_operated_and_non_operated_profiles__non_operated_blurred_operated_unblurred( + grid_2d_7x7, + blurring_grid_2d_7x7, + psf_3x3, +): light_not_operated = ag.lp.Sersic(intensity=1.0) light_operated = ag.lp_operated.Gaussian(intensity=1.0) @@ -79,9 +77,7 @@ def test__x1_galaxies__padded_image__compare_to_galaxy_images_using_padded_grid_ g2 = ag.Galaxy(redshift=0.5, light_profile=ag.lp.Sersic(intensity=3.0)) padded_g0_image = g0.image_2d_from(grid=padded_grid) - padded_g1_image = g1.image_2d_from(grid=padded_grid) - padded_g2_image = g2.image_2d_from(grid=padded_grid) galaxies = ag.Galaxies(galaxies=[g0, g1, g2]) @@ -94,8 +90,7 @@ def test__x1_galaxies__padded_image__compare_to_galaxy_images_using_padded_grid_ ) -def test__unmasked_blurred_image_2d_from(): - +def test__unmasked_blurred_image_2d_from__single_light_profile__correct_unmasked_values(): kernel = ag.Array2D.no_mask( values=(np.array([[0.0, 3.0, 0.0], [0.0, 1.0, 2.0], [0.0, 0.0, 0.0]])), pixel_scales=1.0, @@ -126,6 +121,21 @@ def test__unmasked_blurred_image_2d_from(): 1.0e-4, ) + +def test__unmasked_blurred_image_2d_from__galaxy_with_operated_and_non_operated__sum_matches_manual(): + kernel = ag.Array2D.no_mask( + values=(np.array([[0.0, 3.0, 0.0], [0.0, 1.0, 2.0], [0.0, 0.0, 0.0]])), + pixel_scales=1.0, + ) + psf = ag.Convolver(kernel=kernel) + + mask = ag.Mask2D( + mask=[[True, True, True], [True, False, True], [True, True, True]], + pixel_scales=1.0, + ) + + grid = ag.Grid2D.from_mask(mask=mask) + light_not_operated = ag.lp.Gaussian(intensity=1.0) light_operated = ag.lp_operated.Gaussian(intensity=1.0) @@ -172,7 +182,7 @@ def test__visibilities_from_grid_and_transformer(grid_2d_7x7, transformer_7x7_7) assert visibilities.array == pytest.approx(lp_visibilities.array, 1.0e-4) -def test__blurred_image_2d_list_from( +def test__blurred_image_2d_list_from__two_non_operated_profiles__each_profile_correctly_blurred( grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3, @@ -201,33 +211,22 @@ def test__blurred_image_2d_list_from( lp_1_blurred_image_2d.native.array, 1.0e-4 ) - blurred_image_2d_list = gal.blurred_image_2d_list_from( - grid=grid_2d_7x7, blurring_grid=blurring_grid_2d_7x7, psf=psf_3x3 - ) - - assert blurred_image_2d_list[0].native == pytest.approx( - lp_0_blurred_image_2d.native.array, 1.0e-4 - ) - assert blurred_image_2d_list[1].native == pytest.approx( - lp_1_blurred_image_2d.native.array, 1.0e-4 - ) +def test__blurred_image_2d_list_from__non_operated_and_operated_profiles__operated_not_blurred( + grid_2d_7x7, + blurring_grid_2d_7x7, + psf_3x3, +): + lp_0 = ag.lp.Gaussian(intensity=1.0) lp_operated = ag.lp_operated.Gaussian(intensity=3.0) - image_2d_operated = lp_operated.image_2d_from(grid=grid_2d_7x7) - - gal = ag.Galaxy(redshift=0.5, lp_0=lp_0, lp_operated=lp_operated) - - blurred_image_2d_list = gal.blurred_image_2d_list_from( + lp_0_blurred_image_2d = lp_0.blurred_image_2d_from( grid=grid_2d_7x7, blurring_grid=blurring_grid_2d_7x7, psf=psf_3x3 ) - assert blurred_image_2d_list[0].native == pytest.approx( - lp_0_blurred_image_2d.native.array, 1.0e-4 - ) - assert blurred_image_2d_list[1].native == pytest.approx( - image_2d_operated.native.array, 1.0e-4 - ) + image_2d_operated = lp_operated.image_2d_from(grid=grid_2d_7x7) + + gal = ag.Galaxy(redshift=0.5, lp_0=lp_0, lp_operated=lp_operated) blurred_image_2d_list = gal.blurred_image_2d_list_from( grid=grid_2d_7x7, blurring_grid=blurring_grid_2d_7x7, psf=psf_3x3 diff --git a/test_autogalaxy/profiles/light/linear/test_abstract.py b/test_autogalaxy/profiles/light/linear/test_abstract.py index 72b949f0a..bbcdff0d4 100644 --- a/test_autogalaxy/profiles/light/linear/test_abstract.py +++ b/test_autogalaxy/profiles/light/linear/test_abstract.py @@ -9,7 +9,9 @@ ) -def test__mapping_matrix_from(grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3): +def test__params__two_light_profiles__equals_two( + grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3 +): lp_0 = ag.lp_linear.Sersic(effective_radius=1.0) lp_1 = ag.lp_linear.Sersic(effective_radius=2.0) @@ -22,6 +24,20 @@ def test__mapping_matrix_from(grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3): assert lp_linear_obj_func_list.params == 2 + +def test__mapping_matrix__columns_match_individual_profile_images( + grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3 +): + lp_0 = ag.lp_linear.Sersic(effective_radius=1.0) + lp_1 = ag.lp_linear.Sersic(effective_radius=2.0) + + lp_linear_obj_func_list = LightProfileLinearObjFuncList( + grid=grid_2d_7x7, + blurring_grid=blurring_grid_2d_7x7, + psf=psf_3x3, + light_profile_list=[lp_0, lp_1], + ) + lp_0_image = lp_0.image_2d_from(grid=grid_2d_7x7) lp_1_image = lp_1.image_2d_from(grid=grid_2d_7x7) @@ -32,6 +48,20 @@ def test__mapping_matrix_from(grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3): lp_1_image.array, 1.0e-4 ) + +def test__operated_mapping_matrix__columns_match_individual_blurred_images( + grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3 +): + lp_0 = ag.lp_linear.Sersic(effective_radius=1.0) + lp_1 = ag.lp_linear.Sersic(effective_radius=2.0) + + lp_linear_obj_func_list = LightProfileLinearObjFuncList( + grid=grid_2d_7x7, + blurring_grid=blurring_grid_2d_7x7, + psf=psf_3x3, + light_profile_list=[lp_0, lp_1], + ) + lp_0_blurred_image = lp_0.blurred_image_2d_from( grid=grid_2d_7x7, blurring_grid=blurring_grid_2d_7x7, psf=psf_3x3 ) @@ -48,7 +78,7 @@ def test__mapping_matrix_from(grid_2d_7x7, blurring_grid_2d_7x7, psf_3x3): ] == pytest.approx(lp_1_blurred_image.array, 1.0e-4) -def test__lp_from(): +def test__lp_instance_from__returns_non_linear_instance_with_correct_type_and_centre(): lp_linear = ag.lp_linear.Sersic(centre=(1.0, 2.0)) lp_non_linear = lp_linear.lp_instance_from( @@ -58,4 +88,13 @@ def test__lp_from(): assert not isinstance(lp_non_linear, LightProfileLinear) assert type(lp_non_linear) is ag.lp.Sersic assert lp_non_linear.centre == (1.0, 2.0) + + +def test__lp_instance_from__returns_instance_with_correct_intensity(): + lp_linear = ag.lp_linear.Sersic(centre=(1.0, 2.0)) + + lp_non_linear = lp_linear.lp_instance_from( + linear_light_profile_intensity_dict={lp_linear: 3.0} + ) + assert lp_non_linear.intensity == 3.0 diff --git a/test_autogalaxy/profiles/light/shapelets/test_cartesian.py b/test_autogalaxy/profiles/light/shapelets/test_cartesian.py index b6bb9b3fe..aceec09ee 100644 --- a/test_autogalaxy/profiles/light/shapelets/test_cartesian.py +++ b/test_autogalaxy/profiles/light/shapelets/test_cartesian.py @@ -5,7 +5,7 @@ import autogalaxy as ag -def test__image_2d_from(): +def test__image_2d_from__spherical__centred_at_origin__correct_values(): shapelet = ag.lp_linear.ShapeletCartesianSph( n_y=2, n_x=3, centre=(0.0, 0.0), beta=1.0 ) @@ -14,6 +14,8 @@ def test__image_2d_from(): assert image == pytest.approx(np.array([0.1397, 0.0708009]), 1e-4) + +def test__image_2d_from__spherical__offset_centre__correct_values(): shapelet = ag.lp_linear.ShapeletCartesianSph( n_y=2, n_x=3, centre=(0.2, 0.4), beta=1.0 ) @@ -23,7 +25,7 @@ def test__image_2d_from(): assert image == pytest.approx(np.array([0.23733, -0.07913]), 1e-4) -def test__elliptical__image_2d_from(): +def test__image_2d_from__elliptical__ell_comps_0p1_0p2__correct_values(): shapelet = ag.lp_linear.ShapeletCartesian( n_y=2, n_x=3, centre=(0.0, 0.0), ell_comps=(0.1, 0.2), beta=1.0 ) @@ -32,6 +34,8 @@ def test__elliptical__image_2d_from(): assert image == pytest.approx(np.array([0.1066423886714124, 0.014346163370]), 1e-4) + +def test__image_2d_from__elliptical__ell_comps_0p2_0p3__correct_values(): shapelet = ag.lp_linear.ShapeletCartesian( n_y=2, n_x=3, centre=(0.0, 0.0), ell_comps=(0.2, 0.3), beta=1.0 ) diff --git a/test_autogalaxy/profiles/light/shapelets/test_exponential.py b/test_autogalaxy/profiles/light/shapelets/test_exponential.py index 4965844ca..9dc7fa0e4 100644 --- a/test_autogalaxy/profiles/light/shapelets/test_exponential.py +++ b/test_autogalaxy/profiles/light/shapelets/test_exponential.py @@ -5,7 +5,7 @@ import autogalaxy as ag -def test__image_2d_from(): +def test__image_2d_from__spherical__centred_at_origin__correct_values(): shapelet = ag.lp_linear.ShapeletExponentialSph( n=2, m=0, centre=(0.0, 0.0), beta=1.0 ) @@ -14,6 +14,8 @@ def test__image_2d_from(): assert image == pytest.approx(np.array([0.05784, 0.17962]), 1e-4) + +def test__image_2d_from__spherical__offset_centre__correct_values(): shapelet = ag.lp_linear.ShapeletExponentialSph( n=2, m=0, centre=(0.2, 0.4), beta=1.0 ) @@ -23,7 +25,7 @@ def test__image_2d_from(): assert image == pytest.approx(np.array([0.16136, 0.22476]), 1e-4) -def test__elliptical__image_2d_from(): +def test__image_2d_from__elliptical__ell_comps_0p1_0p2__correct_values(): shapelet = ag.lp_linear.ShapeletExponential( n=2, m=0, centre=(0.0, 0.0), ell_comps=(0.1, 0.2), beta=1.0 ) @@ -32,6 +34,8 @@ def test__elliptical__image_2d_from(): assert image == pytest.approx(np.array([0.05784, 0.17961]), 1e-4) + +def test__image_2d_from__elliptical__ell_comps_0p5_0p7__correct_values(): shapelet = ag.lp_linear.ShapeletExponential( n=2, m=0, centre=(0.0, 0.0), ell_comps=(0.5, 0.7), beta=1.0 ) diff --git a/test_autogalaxy/profiles/light/shapelets/test_polar.py b/test_autogalaxy/profiles/light/shapelets/test_polar.py index f4f754514..32dbe3187 100644 --- a/test_autogalaxy/profiles/light/shapelets/test_polar.py +++ b/test_autogalaxy/profiles/light/shapelets/test_polar.py @@ -5,13 +5,15 @@ import autogalaxy as ag -def test__image_2d_from(): +def test__image_2d_from__spherical__centred_at_origin__correct_values(): shapelet = ag.lp_linear.ShapeletPolarSph(n=2, m=0, centre=(0.0, 0.0), beta=1.0) image = shapelet.image_2d_from(grid=ag.Grid2DIrregular([[0.0, 1.0], [0.5, 0.25]])) assert image == pytest.approx(np.array([0.0, -0.33177]), 1e-4) + +def test__image_2d_from__spherical__offset_centre__correct_values(): shapelet = ag.lp_linear.ShapeletPolarSph(n=2, m=0, centre=(0.2, 0.4), beta=1.0) image = shapelet.image_2d_from(grid=ag.Grid2DIrregular([[0.0, 1.0], [0.5, 0.25]])) @@ -19,7 +21,7 @@ def test__image_2d_from(): assert image == pytest.approx(np.array([-0.27715, -0.47333]), 1e-4) -def test__elliptical__image_2d_from(): +def test__image_2d_from__elliptical__ell_comps_0p1_0p2__correct_values(): shapelet = ag.lp_linear.ShapeletPolar( n=2, m=0, centre=(0.0, 0.0), ell_comps=(0.1, 0.2), beta=1.0 ) @@ -30,6 +32,8 @@ def test__elliptical__image_2d_from(): np.array([0.02577349206014249, -0.17434262753]), abs=1e-4 ) + +def test__image_2d_from__elliptical__ell_comps_0p5_0p7__correct_values(): shapelet = ag.lp_linear.ShapeletPolar( n=2, m=0, centre=(0.0, 0.0), ell_comps=(0.5, 0.7), beta=1.0 ) diff --git a/test_autogalaxy/profiles/light/standard/test_abstract.py b/test_autogalaxy/profiles/light/standard/test_abstract.py index 058c03677..37c095f0d 100644 --- a/test_autogalaxy/profiles/light/standard/test_abstract.py +++ b/test_autogalaxy/profiles/light/standard/test_abstract.py @@ -27,23 +27,25 @@ def luminosity_from_radius_and_profile(radius, profile): ) -def test__luminosity_within_centre__compare_to_gridded_calculations(): +def test__luminosity_within_circle__radius_0p5__matches_analytic_value(): sersic = ag.lp.SersicSph(intensity=3.0, effective_radius=2.0, sersic_index=2.0) luminosity_analytic = luminosity_from_radius_and_profile(radius=0.5, profile=sersic) - luminosity_integral = sersic.luminosity_within_circle_from(radius=0.5) assert luminosity_analytic == pytest.approx(luminosity_integral, 1e-3) - luminosity_grid = luminosity_from_radius_and_profile(radius=1.0, profile=sersic) +def test__luminosity_within_circle__radius_1p0__matches_gridded_calculation(): + sersic = ag.lp.SersicSph(intensity=3.0, effective_radius=2.0, sersic_index=2.0) + + luminosity_grid = luminosity_from_radius_and_profile(radius=1.0, profile=sersic) luminosity_integral = sersic.luminosity_within_circle_from(radius=1.0) assert luminosity_grid == pytest.approx(luminosity_integral, 0.02) -def test__decorator__oversample_uniform__numerical_values(gal_x1_lp): +def test__image_2d_from__over_sample_size_1__returns_expected_pixel_value(): mask = ag.Mask2D( mask=[ [True, True, True, True, True], @@ -56,45 +58,86 @@ def test__decorator__oversample_uniform__numerical_values(gal_x1_lp): ) lp = ag.lp.Sersic(intensity=1.0) - grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=1) - image = lp.image_2d_from(grid=grid) assert image[0] == pytest.approx(0.15987224303572964, 1.0e-6) - grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=2) +def test__image_2d_from__over_sample_size_2__returns_expected_pixel_values(): + mask = ag.Mask2D( + mask=[ + [True, True, True, True, True], + [True, False, False, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + ], + pixel_scales=(1.0, 1.0), + ) + + lp = ag.lp.Sersic(intensity=1.0) + grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=2) image = lp.image_2d_from(grid=grid) assert image[0] == pytest.approx(0.17481917, 1.0e-6) assert image[1] == pytest.approx(0.39116856, 1.0e-6) - lp = ag.lp.Sersic(centre=(3.0, 3.0), intensity=1.0) - grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=1) +def test__image_2d_from__over_sample_size_1__offset_centre__returns_expected_pixel_value(): + mask = ag.Mask2D( + mask=[ + [True, True, True, True, True], + [True, False, False, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + ], + pixel_scales=(1.0, 1.0), + ) + lp = ag.lp.Sersic(centre=(3.0, 3.0), intensity=1.0) + grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=1) image = lp.image_2d_from(grid=grid) assert image[0] == pytest.approx(0.006719704400094508, 1.0e-6) - grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=2) +def test__image_2d_from__over_sample_size_2__offset_centre__returns_expected_pixel_values(): + mask = ag.Mask2D( + mask=[ + [True, True, True, True, True], + [True, False, False, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + [True, True, True, True, True], + ], + pixel_scales=(1.0, 1.0), + ) + + lp = ag.lp.Sersic(centre=(3.0, 3.0), intensity=1.0) + grid = ag.Grid2D.from_mask(mask=mask, over_sample_size=2) image = lp.image_2d_from(grid=grid) assert image[0] == pytest.approx(0.00681791, 1.0e-6) assert image[1] == pytest.approx(0.01332332, 1.0e-6) -def test__regression__centre_of_profile_in_right_place(): +def test__image_2d_from__sersic__peak_is_at_profile_centre(): grid = ag.Grid2D.uniform(shape_native=(7, 7), pixel_scales=1.0) lp = ag.lp.Sersic(centre=(2.0, 1.0), intensity=1.0) image = lp.image_2d_from(grid=grid) max_indexes = np.unravel_index(image.native.argmax(), image.shape_native) + assert max_indexes == (1, 4) + +def test__image_2d_from__sersic_sph__peak_is_at_profile_centre(): + grid = ag.Grid2D.uniform(shape_native=(7, 7), pixel_scales=1.0) + lp = ag.lp.SersicSph(centre=(2.0, 1.0), intensity=1.0) image = lp.image_2d_from(grid=grid) max_indexes = np.unravel_index(image.native.argmax(), image.shape_native) + assert max_indexes == (1, 4) diff --git a/test_autogalaxy/profiles/light/standard/test_chameleon.py b/test_autogalaxy/profiles/light/standard/test_chameleon.py index 3cdd5ab0b..21e275136 100644 --- a/test_autogalaxy/profiles/light/standard/test_chameleon.py +++ b/test_autogalaxy/profiles/light/standard/test_chameleon.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__circular__correct_value(): lp = ag.lp.Chameleon( ell_comps=(0.0, 0.0), intensity=1.0, @@ -18,18 +18,21 @@ def test__image_2d_from(): assert image == pytest.approx(0.018605, 1e-3) + +def test__image_2d_from__ell_comps_0p5_0__intensity_3__correct_value(): lp = ag.lp.Chameleon( ell_comps=(0.5, 0.0), intensity=3.0, core_radius_0=0.2, core_radius_1=0.4, ) - # 3.0 * exp(-3.67206544592 * (1,5/2.0) ** (1.0 / 2.0)) - 1) = 0.351797 image = lp.image_2d_from(grid=ag.Grid2DIrregular([[0.0, 1.5]])) assert image == pytest.approx(0.0078149, 1e-3) + +def test__image_2d_from__ell_comps_0_333__intensity_3__correct_value(): lp = ag.lp.Chameleon( ell_comps=(0.0, 0.333333), intensity=3.0, @@ -41,6 +44,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.024993, 1e-3) + +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.Chameleon( ell_comps=(0.0, 0.0), intensity=3.0, @@ -51,7 +56,6 @@ def test__image_2d_from(): spherical = ag.lp.ChameleonSph(intensity=3.0, core_radius_0=0.2, core_radius_1=0.4) image_elliptical = elliptical.image_2d_from(grid=grid) - image_spherical = spherical.image_2d_from(grid=grid) assert image_elliptical.array == pytest.approx(image_spherical.array, 1.0e-4) diff --git a/test_autogalaxy/profiles/light/standard/test_dev_vaucouleurs.py b/test_autogalaxy/profiles/light/standard/test_dev_vaucouleurs.py index 7dfb54ddf..7f6df0fa5 100644 --- a/test_autogalaxy/profiles/light/standard/test_dev_vaucouleurs.py +++ b/test_autogalaxy/profiles/light/standard/test_dev_vaucouleurs.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__ell_comps_positive__correct_value(): lp = ag.lp.DevVaucouleurs( ell_comps=(0.0, 0.333333), intensity=3.0, effective_radius=2.0 ) @@ -15,6 +15,8 @@ def test__image_2d_from(): assert image == pytest.approx(5.6697, 1e-3) + +def test__image_2d_from__ell_comps_negative__correct_value(): lp = ag.lp.DevVaucouleurs( ell_comps=(0.0, -0.333333), intensity=2.0, effective_radius=3.0 ) @@ -23,6 +25,8 @@ def test__image_2d_from(): assert image == pytest.approx(7.4455, 1e-3) + +def test__image_2d_from__doubled_intensity__returns_double_the_value(): lp = ag.lp.DevVaucouleurs( ell_comps=(0.0, -0.333333), intensity=4.0, effective_radius=3.0 ) @@ -31,10 +35,8 @@ def test__image_2d_from(): assert image == pytest.approx(2.0 * 7.4455, 1e-3) - value = lp.image_2d_from(grid=ag.Grid2DIrregular([[0.0, 1.0]])) - - assert value == pytest.approx(2.0 * 7.4455, 1e-3) +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.DevVaucouleurs( ell_comps=(0.0, 0.0), intensity=3.0, effective_radius=2.0 ) @@ -42,7 +44,6 @@ def test__image_2d_from(): spherical = ag.lp.DevVaucouleursSph(intensity=3.0, effective_radius=2.0) image_elliptical = elliptical.image_2d_from(grid=grid) - image_spherical = spherical.image_2d_from(grid=grid) assert image_elliptical.array == pytest.approx(image_spherical.array, 1.0e-4) diff --git a/test_autogalaxy/profiles/light/standard/test_eff.py b/test_autogalaxy/profiles/light/standard/test_eff.py index 6100a9d77..20f235941 100644 --- a/test_autogalaxy/profiles/light/standard/test_eff.py +++ b/test_autogalaxy/profiles/light/standard/test_eff.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__effective_radius_1__grid_at_1__correct_value(): lp = ag.lp.ElsonFreeFall( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), @@ -18,6 +18,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.35355, 1e-2) + +def test__image_2d_from__intensity_2__scales_linearly_with_intensity(): lp = ag.lp.ElsonFreeFall( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), @@ -29,6 +31,8 @@ def test__image_2d_from(): assert image == pytest.approx(2.0 * 0.35355, 1e-2) + +def test__image_2d_from__effective_radius_2__grid_at_1__correct_value(): lp = ag.lp.ElsonFreeFall( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), @@ -40,6 +44,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.71554, 1e-2) + +def test__image_2d_from__effective_radius_2__grid_at_3__correct_value(): lp = ag.lp.ElsonFreeFall( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), @@ -51,6 +57,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.17067, 1e-2) + +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.ElsonFreeFall( ell_comps=(0.0, 0.0), intensity=3.0, effective_radius=2.0 ) @@ -62,7 +70,7 @@ def test__image_2d_from(): assert image_elliptical.array == pytest.approx(image_spherical.array, 1.0e-4) -def test__half_light_radius(): +def test__half_light_radius__eta_4__correct_value(): lp = ag.lp.ElsonFreeFall(effective_radius=2.0, eta=4.0) assert lp.half_light_radius == pytest.approx(1.01964, 1e-2) diff --git a/test_autogalaxy/profiles/light/standard/test_exponential.py b/test_autogalaxy/profiles/light/standard/test_exponential.py index 8eac22961..19f3c76d4 100644 --- a/test_autogalaxy/profiles/light/standard/test_exponential.py +++ b/test_autogalaxy/profiles/light/standard/test_exponential.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__ell_comps_positive__correct_value(): lp = ag.lp.Exponential( ell_comps=(0.0, 0.333333), intensity=3.0, effective_radius=2.0 ) @@ -15,6 +15,8 @@ def test__image_2d_from(): assert image == pytest.approx(4.9047, 1e-3) + +def test__image_2d_from__ell_comps_negative__correct_value(): lp = ag.lp.Exponential( ell_comps=(0.0, -0.333333), intensity=2.0, effective_radius=3.0 ) @@ -23,6 +25,8 @@ def test__image_2d_from(): assert image == pytest.approx(4.8566, 1e-3) + +def test__image_2d_from__doubled_intensity__returns_double_the_value(): lp = ag.lp.Exponential( ell_comps=(0.0, -0.333333), intensity=4.0, effective_radius=3.0 ) @@ -31,10 +35,8 @@ def test__image_2d_from(): assert image == pytest.approx(2.0 * 4.8566, 1e-3) - value = lp.image_2d_from(grid=ag.Grid2DIrregular([[0.0, 1.0]])) - - assert value == pytest.approx(2.0 * 4.8566, 1e-3) +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.Exponential( ell_comps=(0.0, 0.0), intensity=3.0, effective_radius=2.0 ) diff --git a/test_autogalaxy/profiles/light/standard/test_gaussian.py b/test_autogalaxy/profiles/light/standard/test_gaussian.py index 609827a5e..3fd141d9a 100644 --- a/test_autogalaxy/profiles/light/standard/test_gaussian.py +++ b/test_autogalaxy/profiles/light/standard/test_gaussian.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__sigma_1__intensity_1__correct_value(): lp = ag.lp.Gaussian( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), intensity=1.0, sigma=1.0 ) @@ -15,6 +15,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.60653, 1e-2) + +def test__image_2d_from__sigma_1__intensity_2__scales_linearly_with_intensity(): lp = ag.lp.Gaussian( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), intensity=2.0, sigma=1.0 ) @@ -23,6 +25,8 @@ def test__image_2d_from(): assert image == pytest.approx(2.0 * 0.60653, 1e-2) + +def test__image_2d_from__sigma_2__grid_at_1__correct_value(): lp = ag.lp.Gaussian( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), intensity=1.0, sigma=2.0 ) @@ -31,6 +35,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.88249, 1e-2) + +def test__image_2d_from__sigma_2__grid_at_3__correct_value(): lp = ag.lp.Gaussian( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), intensity=1.0, sigma=2.0 ) @@ -39,6 +45,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.3246, 1e-2) + +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.Gaussian(ell_comps=(0.0, 0.0), intensity=3.0, sigma=2.0) spherical = ag.lp.GaussianSph(intensity=3.0, sigma=2.0) diff --git a/test_autogalaxy/profiles/light/standard/test_moffat.py b/test_autogalaxy/profiles/light/standard/test_moffat.py index c92c5f42a..5a6793347 100644 --- a/test_autogalaxy/profiles/light/standard/test_moffat.py +++ b/test_autogalaxy/profiles/light/standard/test_moffat.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__circular__alpha_1_beta_1__correct_value(): lp = ag.lp.Moffat( centre=(0.0, 0.0), ell_comps=(0.0, 0.0), @@ -19,6 +19,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.5, 1e-4) + +def test__image_2d_from__elliptical__alpha_1p8_beta_0p75__correct_value(): lp = ag.lp.Moffat( centre=(0.0, 0.0), ell_comps=(0.2, 0.2), @@ -31,6 +33,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.7340746, 1e-4) + +def test__image_2d_from__spherical__alpha_1p8_beta_0p75__correct_value(): lp = ag.lp.MoffatSph(centre=(0.0, 0.0), intensity=1.0, alpha=1.8, beta=0.75) image = lp.image_2d_from(grid=ag.Grid2DIrregular([[0.0, 2.0]])) diff --git a/test_autogalaxy/profiles/light/standard/test_sersic.py b/test_autogalaxy/profiles/light/standard/test_sersic.py index be6ef75db..5c6f20897 100644 --- a/test_autogalaxy/profiles/light/standard/test_sersic.py +++ b/test_autogalaxy/profiles/light/standard/test_sersic.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__sersic_index_4__intensity_1__correct_value(): lp = ag.lp.Sersic( ell_comps=(0.0, 0.0), intensity=1.0, @@ -18,18 +18,21 @@ def test__image_2d_from(): assert image == pytest.approx(0.351797, 1e-3) + +def test__image_2d_from__sersic_index_2__intensity_3__correct_value(): lp = ag.lp.Sersic( ell_comps=(0.0, 0.0), intensity=3.0, effective_radius=2.0, sersic_index=2.0, ) - # 3.0 * exp(-3.67206544592 * (1,5/2.0) ** (1.0 / 2.0)) - 1) = 0.351797 image = lp.image_2d_from(grid=ag.Grid2DIrregular([[1.5, 0.0]])) assert image == pytest.approx(4.90657319276, 1e-3) + +def test__image_2d_from__elliptical__ell_comps_nonzero__correct_value(): lp = ag.lp.Sersic( ell_comps=(0.0, 0.333333), intensity=3.0, @@ -41,6 +44,8 @@ def test__image_2d_from(): assert image == pytest.approx(5.38066670129, 1e-3) + +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.Sersic( ell_comps=(0.0, 0.0), intensity=3.0, @@ -51,7 +56,6 @@ def test__image_2d_from(): spherical = ag.lp.SersicSph(intensity=3.0, effective_radius=2.0, sersic_index=2.0) image_elliptical = elliptical.image_2d_from(grid=grid) - image_spherical = spherical.image_2d_from(grid=grid) assert image_elliptical.array == pytest.approx(image_spherical.array, 1.0e-4) diff --git a/test_autogalaxy/profiles/light/standard/test_sersic_core.py b/test_autogalaxy/profiles/light/standard/test_sersic_core.py index 5aa66b3c1..de994c06c 100644 --- a/test_autogalaxy/profiles/light/standard/test_sersic_core.py +++ b/test_autogalaxy/profiles/light/standard/test_sersic_core.py @@ -6,7 +6,7 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__image_2d_from(): +def test__image_2d_from__elliptical__ell_comps_nonzero__correct_value(): lp = ag.lp.SersicCore( ell_comps=(0.0, 0.333333), effective_radius=5.0, @@ -21,6 +21,8 @@ def test__image_2d_from(): assert image == pytest.approx(0.0255173, 1.0e-4) + +def test__image_2d_from__spherical_profile__matches_elliptical_with_zero_ellipticity(): elliptical = ag.lp.SersicCore( ell_comps=(0.0, 0.0), effective_radius=5.0, @@ -41,7 +43,6 @@ def test__image_2d_from(): ) image_elliptical = elliptical.image_2d_from(grid=grid) - image_spherical = spherical.image_2d_from(grid=grid) assert image_elliptical.array == pytest.approx(image_spherical.array, 1.0e-4) diff --git a/test_autogalaxy/profiles/light/test_decorators.py b/test_autogalaxy/profiles/light/test_decorators.py index cf27648d1..8b1dec2d7 100644 --- a/test_autogalaxy/profiles/light/test_decorators.py +++ b/test_autogalaxy/profiles/light/test_decorators.py @@ -26,29 +26,67 @@ def image_2d_from( return np.ones(shape=(3, 3)) -def test__decorator_changes_behaviour_correctly(): +def test__image_2d_from__standard_profile__operated_only_none__returns_image(): grid = ag.Grid2D.uniform(shape_native=(3, 3), pixel_scales=1.0) lp = ag.lp.Gaussian() lp_image_2d = lp.image_2d_from(grid=grid) - image_2d = lp.image_2d_from(grid=grid) + assert image_2d == pytest.approx(lp_image_2d.array, 1.0e-4) + +def test__image_2d_from__standard_profile__operated_only_true__returns_zeros(): + grid = ag.Grid2D.uniform(shape_native=(3, 3), pixel_scales=1.0) + + lp = ag.lp.Gaussian() + image_2d = lp.image_2d_from(grid=grid, operated_only=True) + assert image_2d == pytest.approx(np.zeros(shape=(9,)), 1.0e-4) + +def test__image_2d_from__standard_profile__operated_only_false__returns_image(): + grid = ag.Grid2D.uniform(shape_native=(3, 3), pixel_scales=1.0) + + lp = ag.lp.Gaussian() + + lp_image_2d = lp.image_2d_from(grid=grid) image_2d = lp.image_2d_from(grid=grid, operated_only=False) + assert image_2d == pytest.approx(lp_image_2d.array, 1.0e-4) - lp = ag.lp_operated.Gaussian() +def test__image_2d_from__operated_profile__operated_only_none__returns_image(): + grid = ag.Grid2D.uniform(shape_native=(3, 3), pixel_scales=1.0) + + lp_standard = ag.lp.Gaussian() + lp_image_2d = lp_standard.image_2d_from(grid=grid) + + lp = ag.lp_operated.Gaussian() image_2d = lp.image_2d_from(grid=grid) + assert image_2d == pytest.approx(lp_image_2d.array, 1.0e-4) + +def test__image_2d_from__operated_profile__operated_only_true__returns_image(): + grid = ag.Grid2D.uniform(shape_native=(3, 3), pixel_scales=1.0) + + lp_standard = ag.lp.Gaussian() + lp_image_2d = lp_standard.image_2d_from(grid=grid) + + lp = ag.lp_operated.Gaussian() image_2d = lp.image_2d_from(grid=grid, operated_only=True) + assert image_2d == pytest.approx(lp_image_2d.array, 1.0e-4) + +def test__image_2d_from__operated_profile__operated_only_false__returns_zeros(): + grid = ag.Grid2D.uniform(shape_native=(3, 3), pixel_scales=1.0) + + lp = ag.lp_operated.Gaussian() + image_2d = lp.image_2d_from(grid=grid, operated_only=False) + assert image_2d == pytest.approx(np.zeros(shape=(9,)), 1.0e-4) diff --git a/test_autogalaxy/profiles/light/test_snr.py b/test_autogalaxy/profiles/light/test_snr.py index b60a3daf6..25abe2f48 100644 --- a/test_autogalaxy/profiles/light/test_snr.py +++ b/test_autogalaxy/profiles/light/test_snr.py @@ -1,7 +1,7 @@ import autogalaxy as ag -def test__signal_to_noise_via_simulator_correct(): +def test__signal_to_noise_via_simulator__no_psf__snr_within_expected_range(): background_sky_level = 10.0 exposure_time = 300.0 @@ -21,6 +21,15 @@ def test__signal_to_noise_via_simulator_correct(): assert 8.0 < dataset.signal_to_noise_max < 11.5 + +def test__signal_to_noise_via_simulator__with_psf__snr_within_expected_range(): + background_sky_level = 10.0 + exposure_time = 300.0 + + grid = ag.Grid2D.uniform(shape_native=(21, 21), pixel_scales=1.0) + + sersic = ag.lp_snr.Sersic(signal_to_noise_ratio=10.0) + psf = ag.Convolver.from_gaussian( shape_native=(3, 3), sigma=2.0, pixel_scales=0.2, normalize=True ) diff --git a/test_autogalaxy/profiles/test_basis.py b/test_autogalaxy/profiles/test_basis.py index 40a6250cd..f2ea3fce2 100644 --- a/test_autogalaxy/profiles/test_basis.py +++ b/test_autogalaxy/profiles/test_basis.py @@ -42,25 +42,44 @@ def test__image_2d_from__does_not_include_linear_light_profiles(grid_2d_7x7): assert (image == lp_image).all() -def test__image_2d_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): +def test__image_2d_from__operated_only_false__returns_only_non_operated_profile_image( + grid_2d_7x7, lp_0, lp_operated_0 +): image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) - image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) basis = ag.lp_basis.Basis(profile_list=[lp_0, lp_operated_0]) image_2d = basis.image_2d_from(grid=grid_2d_7x7, operated_only=False) assert (image_2d == image_2d_not_operated).all() + +def test__image_2d_from__operated_only_true__returns_only_operated_profile_image( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + basis = ag.lp_basis.Basis(profile_list=[lp_0, lp_operated_0]) + image_2d = basis.image_2d_from(grid=grid_2d_7x7, operated_only=True) assert (image_2d == image_2d_operated).all() + +def test__image_2d_from__operated_only_none__returns_sum_of_all_images( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + basis = ag.lp_basis.Basis(profile_list=[lp_0, lp_operated_0]) + image_2d = basis.image_2d_from(grid=grid_2d_7x7, operated_only=None) assert (image_2d == image_2d_not_operated + image_2d_operated).all() -def test__image_2d_list_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated_0): +def test__image_2d_list_from__operated_only_false__non_operated_image_returned_operated_image_zeros( + grid_2d_7x7, lp_0, lp_operated_0 +): image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) - image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) basis = ag.lp_basis.Basis(profile_list=[lp_0, lp_operated_0]) @@ -68,10 +87,27 @@ def test__image_2d_list_from__operated_only_input(grid_2d_7x7, lp_0, lp_operated assert (image_2d_list[0] == image_2d_not_operated).all() assert (image_2d_list[1] == np.zeros((9))).all() + +def test__image_2d_list_from__operated_only_true__non_operated_image_zeros_operated_image_returned( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + basis = ag.lp_basis.Basis(profile_list=[lp_0, lp_operated_0]) + image_2d_list = basis.image_2d_list_from(grid=grid_2d_7x7, operated_only=True) assert (image_2d_list[0] == np.zeros((9))).all() assert (image_2d_list[1] == image_2d_operated).all() + +def test__image_2d_list_from__operated_only_none__list_sums_to_total_image( + grid_2d_7x7, lp_0, lp_operated_0 +): + image_2d_not_operated = lp_0.image_2d_from(grid=grid_2d_7x7) + image_2d_operated = lp_operated_0.image_2d_from(grid=grid_2d_7x7) + + basis = ag.lp_basis.Basis(profile_list=[lp_0, lp_operated_0]) + image_2d_list = basis.image_2d_list_from(grid=grid_2d_7x7, operated_only=None) assert ( image_2d_list[0] + image_2d_list[1] == image_2d_not_operated + image_2d_operated diff --git a/test_autogalaxy/profiles/test_geometry_profiles.py b/test_autogalaxy/profiles/test_geometry_profiles.py index 923776aff..4918966f0 100644 --- a/test_autogalaxy/profiles/test_geometry_profiles.py +++ b/test_autogalaxy/profiles/test_geometry_profiles.py @@ -11,7 +11,7 @@ directory = path.dirname(path.realpath(__file__)) -def test__cos_and_sin_from_x(): +def test__cos_and_sin_from_x__zero_ell_comps__cos_1_sin_0(): elliptical_profile = geometry_profiles.EllProfile( centre=(1.0, 1.0), ell_comps=(0.0, 0.0) ) @@ -21,8 +21,9 @@ def test__cos_and_sin_from_x(): assert _cos_angle == 1.0 assert _sin_angle == 0.0 - # axis_ratio=0.1, angle=45.0 +def test__cos_and_sin_from_x__ell_comps_45_degrees__cos_and_sin_both_0p707(): + # axis_ratio=0.1, angle=45.0 elliptical_profile = geometry_profiles.EllProfile( centre=(1, 1), ell_comps=(0.8181, 0.0) ) @@ -32,8 +33,9 @@ def test__cos_and_sin_from_x(): assert _cos_angle == pytest.approx(0.707, 1e-3) assert _sin_angle == pytest.approx(0.707, 1e-3) - # axis_ratio=0.1, angle=60.0 +def test__cos_and_sin_from_x__ell_comps_60_degrees__cos_0p5_sin_0p866(): + # axis_ratio=0.1, angle=60.0 elliptical_profile = geometry_profiles.EllProfile( centre=(1, 1), ell_comps=(0.70856, -0.4090909) ) @@ -44,7 +46,7 @@ def test__cos_and_sin_from_x(): assert _sin_angle == pytest.approx(0.866, 1e-3) -def test__eccentric_radii_grid_from(): +def test__eccentric_radii_grid_from__circular_profile__returns_sqrt_2(): elliptical_profile = geometry_profiles.EllProfile(ell_comps=(0.0, 0.0)) eccentric_radius = elliptical_profile.eccentric_radii_grid_from( @@ -53,18 +55,12 @@ def test__eccentric_radii_grid_from(): assert eccentric_radius == pytest.approx(2.0**0.5, 1e-3) - eccentric_radius = elliptical_profile.eccentric_radii_grid_from( - grid=ag.Grid2DIrregular([[1.0, 1.0]]) - ) - - assert eccentric_radius == pytest.approx(2.0**0.5, 1e-3) +def test__eccentric_radii_grid_from__elliptical_profile__returns_correct_eccentric_radius(): # eccentric_radius = sqrt(axis_ratio) * sqrt( x**2 + (y**2 / axis_ratio**2)) # eccentric_radius = sqrt(0.5) * sqrt(1.0**2 + (1.0**2 / 0.5**2)) # eccentric radius = sqrt(0.5) * sqrt( 5 ) = 1.58113 - # axis_ratio=0.5, angle=0.0 - elliptical_profile = geometry_profiles.EllProfile(ell_comps=(0.0, 0.333333)) eccentric_radius = elliptical_profile.eccentric_radii_grid_from( @@ -74,7 +70,7 @@ def test__eccentric_radii_grid_from(): assert eccentric_radius == pytest.approx(1.58113, 1e-3) -def test__spherical__transform_to_reference_frame__coordinate_shifts_using_centre(): +def test__spherical__transform_to_reference_frame__zero_centre__grid_unchanged(): spherical_profile = geometry_profiles.SphProfile(centre=(0.0, 0.0)) transformed_grid = spherical_profile.transformed_from_reference_frame_grid_from( @@ -83,6 +79,8 @@ def test__spherical__transform_to_reference_frame__coordinate_shifts_using_centr assert (transformed_grid == ag.Grid2DIrregular([[1.0, 1.0]])).all() + +def test__spherical__transform_to_reference_frame__equivalent_grid_shift_via_centre(): spherical_profile1 = geometry_profiles.SphProfile(centre=(0, 0)) grid1 = spherical_profile1.transformed_to_reference_frame_grid_from( @@ -96,6 +94,8 @@ def test__spherical__transform_to_reference_frame__coordinate_shifts_using_centr assert (grid1 == grid2).all() + +def test__spherical__transform_to_reference_frame__two_centres_produce_equal_grids(): spherical_profile1 = geometry_profiles.SphProfile(centre=(1, 1)) grid1 = spherical_profile1.transformed_to_reference_frame_grid_from( grid=ag.Grid2DIrregular([[1.0, 1.0]]) @@ -109,7 +109,7 @@ def test__spherical__transform_to_reference_frame__coordinate_shifts_using_centr assert (grid1 == grid2).all() -def test__spherical__transform_to_and_from_reference_frame(): +def test__spherical__transform_to_and_from_reference_frame__zero_centre__grid_unchanged(): spherical_profile = geometry_profiles.SphProfile(centre=(0.0, 0.0)) grid = ag.Grid2DIrregular([[1.0, 1.0]]) @@ -118,6 +118,8 @@ def test__spherical__transform_to_and_from_reference_frame(): assert transformed_grid == pytest.approx(ag.Grid2DIrregular([[1.0, 1.0]]), 1e-3) + +def test__spherical__transform_to_and_from_reference_frame__roundtrip_recovers_original_grid(): spherical_profile = geometry_profiles.SphProfile(centre=(0.0, 0.0)) grid_original = ag.Grid2DIrregular([[5.2221, 2.6565]]) @@ -133,7 +135,7 @@ def test__spherical__transform_to_and_from_reference_frame(): assert transformed_grid == pytest.approx(grid_original, 1e-5) -def test__elliptical__transform_grid_to_and_from_reference_frame(): +def test__elliptical__transform_grid_to_reference_frame__zero_ell_comps__grid_unchanged(): elliptical_profile = geometry_profiles.EllProfile(ell_comps=(0.0, 0.0)) transformed_grid = elliptical_profile.transformed_to_reference_frame_grid_from( @@ -142,12 +144,12 @@ def test__elliptical__transform_grid_to_and_from_reference_frame(): assert transformed_grid == pytest.approx(ag.Grid2DIrregular([[1.0, 1.0]]), 1e-3) - transformed_back_grid = ( - elliptical_profile.transformed_from_reference_frame_grid_from(transformed_grid) - ) - assert transformed_back_grid == pytest.approx( - ag.Grid2DIrregular([[1.0, 1.0]]), 1e-3 +def test__elliptical__transform_grid_from_reference_frame__zero_ell_comps__grid_unchanged(): + elliptical_profile = geometry_profiles.EllProfile(ell_comps=(0.0, 0.0)) + + transformed_grid = elliptical_profile.transformed_to_reference_frame_grid_from( + grid=ag.Grid2DIrregular([[1.0, 1.0]]) ) transformed_back_grid = ( @@ -158,8 +160,9 @@ def test__elliptical__transform_grid_to_and_from_reference_frame(): ag.Grid2DIrregular([[1.0, 1.0]]), 1e-3 ) - # axis_ratio=0.1, angle=90.0 +def test__elliptical__transform_grid_to_reference_frame__90_degree_angle__correct_transformed_grid(): + # axis_ratio=0.1, angle=90.0 elliptical_profile = geometry_profiles.EllProfile( centre=(2.0, 3.0), ell_comps=(0.0, -0.81818181) ) @@ -170,6 +173,17 @@ def test__elliptical__transform_grid_to_and_from_reference_frame(): assert transformed_grid == pytest.approx(ag.Grid2DIrregular([[-1.0, 1.0]]), 1e-3) + +def test__elliptical__transform_grid_from_reference_frame__90_degree_angle__recovers_original_grid(): + # axis_ratio=0.1, angle=90.0 + elliptical_profile = geometry_profiles.EllProfile( + centre=(2.0, 3.0), ell_comps=(0.0, -0.81818181) + ) + + transformed_grid = elliptical_profile.transformed_to_reference_frame_grid_from( + grid=ag.Grid2DIrregular([[3.0, 4.0]]) + ) + transformed_back_grid = ( elliptical_profile.transformed_from_reference_frame_grid_from(transformed_grid) ) @@ -178,6 +192,8 @@ def test__elliptical__transform_grid_to_and_from_reference_frame(): ag.Grid2DIrregular([[3.0, 4.0]]), 1e-3 ) + +def test__elliptical__transform_grid_to_and_from_reference_frame__roundtrip_recovers_original_grid(): elliptical_profile = geometry_profiles.EllProfile(ell_comps=(0.818181, 0.0)) grid_original = ag.Grid2DIrregular([[5.2221, 2.6565]]) @@ -193,7 +209,7 @@ def test__elliptical__transform_grid_to_and_from_reference_frame(): assert transformed_grid == pytest.approx(grid_original, 1e-5) -def test__elliptical__transform_grids_with_mapped_centres(): +def test__elliptical__transform_grids_with_mapped_centres__zero_angle__equivalent_grid_shift_via_centre(): elliptical_profile1 = geometry_profiles.EllProfile( ell_comps=(0.0, 0.0), centre=(0, 0) ) @@ -210,8 +226,9 @@ def test__elliptical__transform_grids_with_mapped_centres(): assert (grid1 == grid2).all() - # axis_ratio=0.1, angle=55.0 +def test__elliptical__transform_grids_with_mapped_centres__55_degree_angle__equivalent_grid_shift_via_centre(): + # axis_ratio=0.1, angle=55.0 elliptical_profile1 = geometry_profiles.EllProfile( centre=(0, 0), ell_comps=(0.76883, -0.27983) ) @@ -228,6 +245,8 @@ def test__elliptical__transform_grids_with_mapped_centres(): assert (grid1 == grid2).all() + +def test__elliptical__transform_grids_with_mapped_centres__55_degree_angle__two_centres_produce_equal_grids(): elliptical_profile1 = geometry_profiles.EllProfile( centre=(1, 1), ell_comps=(0.76883, -0.27983) ) diff --git a/test_autogalaxy/profiles/test_light_and_mass_profiles.py b/test_autogalaxy/profiles/test_light_and_mass_profiles.py index 8f68fabab..f66ed108f 100644 --- a/test_autogalaxy/profiles/test_light_and_mass_profiles.py +++ b/test_autogalaxy/profiles/test_light_and_mass_profiles.py @@ -5,8 +5,21 @@ grid = ag.Grid2DIrregular([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [2.0, 4.0]]) -def test__gaussian(): +def test__gaussian__image_2d_from__matches_lmp(): lp = ag.lp.Gaussian(ell_comps=(0.1, 0.05), intensity=1.0, sigma=5.0) + lmp = ag.lmp.Gaussian( + ell_comps=(0.1, 0.05), + intensity=1.0, + sigma=5.0, + mass_to_light_ratio=2.0, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid).array, 1.0e-4 + ) + + +def test__gaussian__convergence_2d_from__matches_lmp(): mp = ag.mp.Gaussian( ell_comps=(0.1, 0.05), intensity=1.0, @@ -20,20 +33,48 @@ def test__gaussian(): mass_to_light_ratio=2.0, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid).array, 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid).array, 1.0e-4 ) + + +def test__gaussian__deflections_yx_2d_from__matches_lmp(): + mp = ag.mp.Gaussian( + ell_comps=(0.1, 0.05), + intensity=1.0, + sigma=5.0, + mass_to_light_ratio=2.0, + ) + lmp = ag.lmp.Gaussian( + ell_comps=(0.1, 0.05), + intensity=1.0, + sigma=5.0, + mass_to_light_ratio=2.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid).array, 1.0e-4 ) -def test__gaussian_gradient(): +def test__gaussian_gradient__image_2d_from__matches_lmp(): lp = ag.lp.Gaussian(ell_comps=(0.1, 0.05), intensity=1.0, sigma=5.0) + lmp = ag.lmp.GaussianGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + sigma=5.0, + mass_to_light_ratio_base=2.0, + mass_to_light_gradient=0.5, + mass_to_light_radius=1.0, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid).array, 1.0e-4 + ) + + +def test__gaussian_gradient__convergence_2d_from__matches_lmp(): mp = ag.mp.GaussianGradient( ell_comps=(0.1, 0.05), intensity=1.0, @@ -51,25 +92,56 @@ def test__gaussian_gradient(): mass_to_light_radius=1.0, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid).array, 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid).array, 1.0e-4 ) + + +def test__gaussian_gradient__deflections_yx_2d_from__matches_lmp(): + mp = ag.mp.GaussianGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + sigma=5.0, + mass_to_light_ratio_base=2.0, + mass_to_light_gradient=0.5, + mass_to_light_radius=1.0, + ) + lmp = ag.lmp.GaussianGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + sigma=5.0, + mass_to_light_ratio_base=2.0, + mass_to_light_gradient=0.5, + mass_to_light_radius=1.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid).array, 1.0e-4 ) -def test__sersic(): +def test__sersic__image_2d_from__matches_lmp(): lp = ag.lp.Sersic( ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=0.6, sersic_index=2.0, ) + lmp = ag.lmp.Sersic( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid).array, 1.0e-4 + ) + + +def test__sersic__convergence_2d_from__matches_lmp(): mp = ag.mp.Sersic( ell_comps=(0.1, 0.05), intensity=1.0, @@ -85,20 +157,48 @@ def test__sersic(): mass_to_light_ratio=2.0, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid).array, 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid).array, 1.0e-4 ) + + +def test__sersic__deflections_yx_2d_from__matches_lmp(): + mp = ag.mp.Sersic( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + ) + lmp = ag.lmp.Sersic( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid).array, 1.0e-4 ) -def test__exponential(): +def test__exponential__image_2d_from__matches_lmp(): lp = ag.lp.Exponential(ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=0.6) + lmp = ag.lmp.Exponential( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid).array, 1.0e-4 + ) + + +def test__exponential__convergence_2d_from__matches_lmp(): mp = ag.mp.Exponential( ell_comps=(0.1, 0.05), intensity=1.0, @@ -112,22 +212,48 @@ def test__exponential(): mass_to_light_ratio=2.0, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid).array, 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid).array, 1.0e-4 ) + + +def test__exponential__deflections_yx_2d_from__matches_lmp(): + mp = ag.mp.Exponential( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + ) + lmp = ag.lmp.Exponential( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid).array, 1.0e-4 ) -def test__dev_vaucouleurs(): +def test__dev_vaucouleurs__image_2d_from__matches_lmp(): lp = ag.lmp.DevVaucouleurs( ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=0.6 ) + lmp = ag.lmp.DevVaucouleurs( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid).array, 1.0e-4 + ) + + +def test__dev_vaucouleurs__convergence_2d_from__matches_lmp(): mp = ag.lmp.DevVaucouleurs( ell_comps=(0.1, 0.05), intensity=1.0, @@ -141,25 +267,53 @@ def test__dev_vaucouleurs(): mass_to_light_ratio=2.0, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid).array, 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid).array, 1.0e-4 ) + + +def test__dev_vaucouleurs__deflections_yx_2d_from__matches_lmp(): + mp = ag.lmp.DevVaucouleurs( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + ) + lmp = ag.lmp.DevVaucouleurs( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid).array, 1.0e-4 ) -def test__sersic_gradient(): +def test__sersic_gradient__image_2d_from__matches_lmp(): lp = ag.lmp.Sersic( ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=0.6, sersic_index=2.0, ) + lmp = ag.lmp.SersicGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + mass_to_light_gradient=0.5, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid), 1.0e-4 + ) + + +def test__sersic_gradient__convergence_2d_from__matches_lmp(): mp = ag.lmp.SersicGradient( ell_comps=(0.1, 0.05), intensity=1.0, @@ -177,20 +331,51 @@ def test__sersic_gradient(): mass_to_light_gradient=0.5, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid), 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid), 1.0e-4 ) + + +def test__sersic_gradient__deflections_yx_2d_from__matches_lmp(): + mp = ag.lmp.SersicGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + mass_to_light_gradient=0.5, + ) + lmp = ag.lmp.SersicGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + mass_to_light_gradient=0.5, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid), 1.0e-4 ) -def test__sersic_gradient(): +def test__exponential_gradient__image_2d_from__matches_lmp(): lp = ag.lmp.Exponential(ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=0.6) + lmp = ag.lmp.ExponentialGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + mass_to_light_gradient=0.5, + ) + + assert lp.image_2d_from(grid=grid) == pytest.approx( + lmp.image_2d_from(grid=grid).array, 1.0e-4 + ) + + +def test__exponential_gradient__convergence_2d_from__matches_lmp(): mp = ag.lmp.ExponentialGradient( ell_comps=(0.1, 0.05), intensity=1.0, @@ -206,22 +391,48 @@ def test__sersic_gradient(): mass_to_light_gradient=0.5, ) - assert lp.image_2d_from(grid=grid) == pytest.approx( - lmp.image_2d_from(grid=grid).array, 1.0e-4 - ) assert mp.convergence_2d_from(grid=grid) == pytest.approx( lmp.convergence_2d_from(grid=grid).array, 1.0e-4 ) + + +def test__exponential_gradient__deflections_yx_2d_from__matches_lmp(): + mp = ag.lmp.ExponentialGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + mass_to_light_gradient=0.5, + ) + lmp = ag.lmp.ExponentialGradient( + ell_comps=(0.1, 0.05), + intensity=1.0, + effective_radius=0.6, + mass_to_light_ratio=2.0, + mass_to_light_gradient=0.5, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert mp.deflections_yx_2d_from(grid=grid) == pytest.approx( lmp.deflections_yx_2d_from(grid=grid).array, 1.0e-4 ) -def test__core_sersic(): +def test__core_sersic__image_2d_from__matches_lmp(): lp = ag.lmp.SersicCore( ell_comps=(0.1, 0.05), effective_radius=0.6, sersic_index=2.0 ) + lmp = ag.lmp.SersicCore( + ell_comps=(0.1, 0.05), + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + ) + + assert (lp.image_2d_from(grid=grid) == lmp.image_2d_from(grid=grid)).all() + + +def test__core_sersic__convergence_2d_from__matches_lmp(): mp = ag.lmp.SersicCore( ell_comps=(0.1, 0.05), effective_radius=0.6, @@ -235,23 +446,50 @@ def test__core_sersic(): mass_to_light_ratio=2.0, ) - assert (lp.image_2d_from(grid=grid) == lmp.image_2d_from(grid=grid)).all() assert ( mp.convergence_2d_from(grid=grid) == lmp.convergence_2d_from(grid=grid) ).all() + + +def test__core_sersic__deflections_yx_2d_from__matches_lmp(): + mp = ag.lmp.SersicCore( + ell_comps=(0.1, 0.05), + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + ) + lmp = ag.lmp.SersicCore( + ell_comps=(0.1, 0.05), + effective_radius=0.6, + sersic_index=2.0, + mass_to_light_ratio=2.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert ( mp.deflections_yx_2d_from(grid=grid) == lmp.deflections_yx_2d_from(grid=grid) ).all() -def test__chameleon(): +def test__chameleon__image_2d_from__matches_lmp(): lp = ag.lmp.Chameleon( ell_comps=(0.1, 0.05), intensity=1.0, core_radius_0=0.1, core_radius_1=0.3, ) + lmp = ag.lmp.Chameleon( + ell_comps=(0.1, 0.05), + intensity=1.0, + core_radius_0=0.1, + core_radius_1=0.3, + mass_to_light_ratio=2.0, + ) + + assert (lp.image_2d_from(grid=grid) == lmp.image_2d_from(grid=grid)).all() + + +def test__chameleon__convergence_2d_from__matches_lmp(): mp = ag.lmp.Chameleon( ell_comps=(0.1, 0.05), intensity=1.0, @@ -267,10 +505,27 @@ def test__chameleon(): mass_to_light_ratio=2.0, ) - assert (lp.image_2d_from(grid=grid) == lmp.image_2d_from(grid=grid)).all() assert ( mp.convergence_2d_from(grid=grid) == lmp.convergence_2d_from(grid=grid) ).all() + + +def test__chameleon__deflections_yx_2d_from__matches_lmp(): + mp = ag.lmp.Chameleon( + ell_comps=(0.1, 0.05), + intensity=1.0, + core_radius_0=0.1, + core_radius_1=0.3, + mass_to_light_ratio=2.0, + ) + lmp = ag.lmp.Chameleon( + ell_comps=(0.1, 0.05), + intensity=1.0, + core_radius_0=0.1, + core_radius_1=0.3, + mass_to_light_ratio=2.0, + ) + # assert (mp.potential_2d_from(grid=grid) == lmp.potential_2d_from(grid=grid)).all() assert ( mp.deflections_yx_2d_from(grid=grid) == lmp.deflections_yx_2d_from(grid=grid) diff --git a/test_autogalaxy/quantity/test_dataset_quantity.py b/test_autogalaxy/quantity/test_dataset_quantity.py index 63af2b0d0..c5ab389c3 100644 --- a/test_autogalaxy/quantity/test_dataset_quantity.py +++ b/test_autogalaxy/quantity/test_dataset_quantity.py @@ -7,7 +7,9 @@ import autogalaxy as ag -def test_via_signal_to_noise_map(dataset_quantity_7x7_array_2d, mask_2d_7x7): +def test__via_signal_to_noise_map__array_2d_data__correct_noise_map( + dataset_quantity_7x7_array_2d, mask_2d_7x7 +): data = ag.Array2D.no_mask(values=[[1.0, 2.0], [3.0, 4.0]], pixel_scales=1.0) signal_to_noise_map = ag.Array2D.no_mask( values=[[1.0, 5.0], [15.0, 40.0]], pixel_scales=1.0 @@ -24,6 +26,10 @@ def test_via_signal_to_noise_map(dataset_quantity_7x7_array_2d, mask_2d_7x7): np.array([[1.0, 0.4], [0.2, 0.1]]), 1.0e-4 ) + +def test__via_signal_to_noise_map__vector_yx_2d_data__correct_noise_map( + dataset_quantity_7x7_array_2d, mask_2d_7x7 +): data = ag.VectorYX2D.no_mask( values=[[[1.0, 1.0], [2.0, 2.0]], [[3.0, 3.0], [4.0, 4.0]]], pixel_scales=1.0 ) @@ -43,8 +49,8 @@ def test_via_signal_to_noise_map(dataset_quantity_7x7_array_2d, mask_2d_7x7): ) -def test__apply_mask__masks_dataset( - dataset_quantity_7x7_array_2d, dataset_quantity_7x7_vector_yx_2d, mask_2d_7x7 +def test__apply_mask__array_2d_dataset__slim_and_native_values_correct( + dataset_quantity_7x7_array_2d, mask_2d_7x7 ): dataset_quantity_7x7 = dataset_quantity_7x7_array_2d.apply_mask(mask=mask_2d_7x7) @@ -59,6 +65,10 @@ def test__apply_mask__masks_dataset( == 2.0 * np.ones((7, 7)) * np.invert(mask_2d_7x7) ).all() + +def test__apply_mask__vector_yx_2d_dataset__slim_values_correct( + dataset_quantity_7x7_vector_yx_2d, mask_2d_7x7 +): dataset_quantity_7x7 = dataset_quantity_7x7_vector_yx_2d.apply_mask( mask=mask_2d_7x7 ) @@ -67,7 +77,7 @@ def test__apply_mask__masks_dataset( assert (dataset_quantity_7x7.noise_map.slim == 2.0 * np.ones((9, 2))).all() -def test__grid( +def test__grid__default_over_sample__matches_fixture_grid( dataset_quantity_7x7_array_2d, mask_2d_7x7, grid_2d_7x7, @@ -78,6 +88,11 @@ def test__grid( assert isinstance(dataset.grids.lp, ag.Grid2D) assert (dataset.grids.lp == grid_2d_7x7).all() + +def test__grid__custom_over_sample_size_4__matches_fixture_grid( + mask_2d_7x7, + grid_2d_7x7, +): dataset_quantity = ag.DatasetQuantity( data=ag.Array2D.ones(shape_native=(7, 7), pixel_scales=1.0), noise_map=ag.Array2D.full( @@ -134,7 +149,9 @@ def make_test_data_path(): return test_data_path -def test__output_to_fits(dataset_quantity_7x7_array_2d, test_data_path): +def test__output_to_fits__array_2d_data__data_and_noise_map_written_correctly( + dataset_quantity_7x7_array_2d, test_data_path +): dataset_quantity_7x7_array_2d.output_to_fits( data_path=path.join(test_data_path, "data.fits"), noise_map_path=path.join(test_data_path, "noise_map.fits"), @@ -151,6 +168,10 @@ def test__output_to_fits(dataset_quantity_7x7_array_2d, test_data_path): assert (data.native == np.ones((7, 7))).all() assert (noise_map.native == 2.0 * np.ones((7, 7))).all() + +def test__output_to_fits__vector_yx_2d_data__first_pixel_written_correctly( + test_data_path, +): data = ag.VectorYX2D.no_mask( values=[[[1.0, 5.0], [2.0, 6.0]], [[3.0, 7.0], [4.0, 8.0]]], pixel_scales=1.0, diff --git a/test_autogalaxy/quantity/test_fit_quantity.py b/test_autogalaxy/quantity/test_fit_quantity.py index 068fa0a9a..4a29e3bff 100644 --- a/test_autogalaxy/quantity/test_fit_quantity.py +++ b/test_autogalaxy/quantity/test_fit_quantity.py @@ -4,8 +4,8 @@ import autogalaxy as ag -def test__fit_via_mock_profile( - dataset_quantity_7x7_array_2d, dataset_quantity_7x7_vector_yx_2d +def test__fit_via_mock_profile__convergence__chi_squared_zero_and_correct_log_likelihood( + dataset_quantity_7x7_array_2d, ): mass = ag.m.MockMassProfile( convergence_2d=ag.Array2D.ones(shape_native=(7, 7), pixel_scales=1.0), @@ -30,6 +30,22 @@ def test__fit_via_mock_profile( -0.5 * 49.0 * np.log(2 * np.pi * 2.0**2.0), 1.0e-4 ) + +def test__fit_via_mock_profile__potential__nonzero_chi_squared_and_correct_log_likelihood( + dataset_quantity_7x7_array_2d, +): + mass = ag.m.MockMassProfile( + convergence_2d=ag.Array2D.ones(shape_native=(7, 7), pixel_scales=1.0), + potential_2d=ag.Array2D.full( + fill_value=2.0, shape_native=(7, 7), pixel_scales=1.0 + ), + deflections_yx_2d=ag.VectorYX2D.full( + fill_value=3.0, shape_native=(7, 7), pixel_scales=1.0 + ), + ) + + galaxies = ag.Galaxies(galaxies=[ag.Galaxy(redshift=0.5, mass=mass)]) + fit_quantity = ag.FitQuantity( dataset=dataset_quantity_7x7_array_2d, light_mass_obj=galaxies, @@ -39,6 +55,22 @@ def test__fit_via_mock_profile( assert fit_quantity.chi_squared == pytest.approx(12.25, 1.0e-4) assert fit_quantity.log_likelihood == pytest.approx(-85.1171999, 1.0e-4) + +def test__fit_via_mock_profile__deflections__vector_dataset__correct_chi_squared_and_log_likelihood( + dataset_quantity_7x7_vector_yx_2d, +): + mass = ag.m.MockMassProfile( + convergence_2d=ag.Array2D.ones(shape_native=(7, 7), pixel_scales=1.0), + potential_2d=ag.Array2D.full( + fill_value=2.0, shape_native=(7, 7), pixel_scales=1.0 + ), + deflections_yx_2d=ag.VectorYX2D.full( + fill_value=3.0, shape_native=(7, 7), pixel_scales=1.0 + ), + ) + + galaxies = ag.Galaxies(galaxies=[ag.Galaxy(redshift=0.5, mass=mass)]) + fit_quantity = ag.FitQuantity( dataset=dataset_quantity_7x7_vector_yx_2d, light_mass_obj=galaxies, From d8bd964ec9bbb9a815adaea911e8b9fea01e2387 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Wed, 25 Mar 2026 19:30:40 +0000 Subject: [PATCH 2/2] Overhaul plot styling and extract fits_* output functions - _resolve_colormap now delegates to _default_colormap() (autoarray) so the segmentdata colormap is used everywhere by default - subplot_galaxies: hide_unused_axes() fixes blank 6th panel - save_galaxy_images_fits() extracted to galaxies_plots.py - save_adapt_images_fits() extracted to adapt_plots.py - plotter.py: fits_* blocks replaced with one-liner delegate calls; unused imports (numpy, hdu_list_for_output_from) removed - inversion subplot_of_mapper() replaces manual scatter/colorbar code Co-Authored-By: Claude Sonnet 4.6 --- autogalaxy/analysis/plotter.py | 100 ++++------------------- autogalaxy/config/visualize/general.yaml | 12 ++- autogalaxy/galaxy/plot/adapt_plots.py | 51 ++++++++++++ autogalaxy/galaxy/plot/galaxies_plots.py | 35 ++++++++ autogalaxy/plot/plot_utils.py | 7 +- 5 files changed, 119 insertions(+), 86 deletions(-) diff --git a/autogalaxy/analysis/plotter.py b/autogalaxy/analysis/plotter.py index 704411dce..0e7fbf49b 100644 --- a/autogalaxy/analysis/plotter.py +++ b/autogalaxy/analysis/plotter.py @@ -1,7 +1,4 @@ from __future__ import annotations -import csv -import matplotlib.pyplot as plt -import numpy as np import os from typing import List, Union, TYPE_CHECKING @@ -9,7 +6,6 @@ from pathlib import Path from autoconf import conf -from autoconf.fitsable import hdu_list_for_output_from import autoarray as aa import autoarray.plot as aplt @@ -115,18 +111,10 @@ def should_plot(name): ) if should_plot("fits_galaxy_images"): - image_list = [ - galaxy.image_2d_from(grid=grid).native_for_fits for galaxy in galaxies - ] - - hdu_list = hdu_list_for_output_from( - values_list=[image_list[0].mask.astype("float")] + image_list, - ext_name_list=["mask"] + [f"galaxy_{i}" for i in range(len(galaxies))], - header_dict=grid.mask.header_dict, + galaxies_plots.save_galaxy_images_fits( + galaxies=galaxies, grid=grid, output_path=self.image_path ) - hdu_list.writeto(self.image_path / "galaxy_images.fits", overwrite=True) - def inversion(self, inversion: aa.Inversion): """ Output visualization of an ``Inversion``. @@ -146,48 +134,23 @@ def should_plot(name): output = self.output_from() if should_plot("subplot_inversion"): - from autogalaxy.plot.plot_utils import _save_subplot + from autoarray.inversion.plot.inversion_plots import subplot_of_mapper mapper_list = inversion.cls_list_from(cls=aa.Mapper) - - for i, mapper in enumerate(mapper_list): - suffix = f"_{i}" - reconstruction = inversion.reconstruction_dict[mapper] - grid = np.array(mapper.source_plane_mesh_grid) - - fig, ax = plt.subplots(1, 1, figsize=(7, 7)) - sc = ax.scatter(grid[:, 1], grid[:, 0], c=reconstruction, s=10) - plt.colorbar(sc, ax=ax) - ax.set_title("Reconstruction") - ax.set_aspect("equal") - _save_subplot(fig, output.path, f"subplot_inversion{suffix}", output.format_list[0] if output.format_list else "png") + fmt = output.format_list[0] if output.format_list else "png" + + for i in range(len(mapper_list)): + subplot_of_mapper( + inversion=inversion, + mapper_index=i, + output_path=output.path, + output_filename=f"subplot_inversion_{i}", + output_format=fmt, + ) if should_plot("csv_reconstruction"): - mapper_list = inversion.cls_list_from(cls=aa.Mapper) - - for i, mapper in enumerate(mapper_list): - y = mapper.source_plane_mesh_grid[:, 0] - x = mapper.source_plane_mesh_grid[:, 1] - reconstruction = inversion.reconstruction_dict[mapper] - noise_map = inversion.reconstruction_noise_map_dict[mapper] - - with open( - self.image_path / f"source_plane_reconstruction_{i}.csv", - mode="w", - newline="", - ) as file: - writer = csv.writer(file) - writer.writerow(["y", "x", "reconstruction", "noise_map"]) - - for i in range(len(x)): - writer.writerow( - [ - float(y[i]), - float(x[i]), - float(reconstruction[i]), - float(noise_map[i]), - ] - ) + from autoarray.inversion.plot.inversion_plots import save_reconstruction_csv + save_reconstruction_csv(inversion=inversion, output_path=self.image_path) def adapt_images(self, adapt_images: AdaptImages): """ @@ -215,33 +178,6 @@ def should_plot(name): ) if should_plot("fits_adapt_images"): - if adapt_images.galaxy_name_image_dict is not None: - image_list = [ - adapt_images.galaxy_name_image_dict[name].native_for_fits - for name in adapt_images.galaxy_name_image_dict.keys() - ] - - hdu_list = hdu_list_for_output_from( - values_list=[image_list[0].mask.astype("float")] + image_list, - ext_name_list=["mask"] + list(adapt_images.galaxy_name_image_dict.keys()), - header_dict=adapt_images.mask.header_dict, - ) - - hdu_list.writeto(self.image_path / "adapt_images.fits", overwrite=True) - - if adapt_images.galaxy_name_image_plane_mesh_grid_dict is not None: - image_plane_mesh_grid_list = [ - adapt_images.galaxy_name_image_plane_mesh_grid_dict[name].native - for name in adapt_images.galaxy_name_image_plane_mesh_grid_dict.keys() - ] - - hdu_list = hdu_list_for_output_from( - values_list=[np.array([1])] + image_plane_mesh_grid_list, - ext_name_list=[""] - + list(adapt_images.galaxy_name_image_plane_mesh_grid_dict.keys()), - ) - - hdu_list.writeto( - self.image_path / "adapt_image_plane_mesh_grids.fits", - overwrite=True, - ) + adapt_plots.save_adapt_images_fits( + adapt_images=adapt_images, output_path=self.image_path + ) diff --git a/autogalaxy/config/visualize/general.yaml b/autogalaxy/config/visualize/general.yaml index e022ac819..cad0f547c 100644 --- a/autogalaxy/config/visualize/general.yaml +++ b/autogalaxy/config/visualize/general.yaml @@ -6,4 +6,14 @@ inversion: reconstruction_vmax_factor: 0.5 zoom: plane_percent: 0.01 - inversion_percent: 0.01 \ No newline at end of file + inversion_percent: 0.01 +colormap: autoarray +ticks: + extent_factor_2d: 0.75 + number_of_ticks_2d: 3 +colorbar: + fraction: 0.047 + pad: 0.01 + labelrotation: 90 + labelsize: 22 + labelsize_subplot: 18 \ No newline at end of file diff --git a/autogalaxy/galaxy/plot/adapt_plots.py b/autogalaxy/galaxy/plot/adapt_plots.py index 4a672fa3b..708c09f55 100644 --- a/autogalaxy/galaxy/plot/adapt_plots.py +++ b/autogalaxy/galaxy/plot/adapt_plots.py @@ -59,3 +59,54 @@ def subplot_adapt_images( plt.tight_layout() _save_subplot(fig, output_path, "subplot_adapt_images", output_format) + + +def save_adapt_images_fits(adapt_images, output_path) -> None: + """Write FITS files for the adapt images and image-plane mesh grids. + + Writes up to two FITS files into *output_path*: + + * ``adapt_images.fits`` — one HDU per galaxy adapt image, plus a + ``mask`` extension, written when + ``adapt_images.galaxy_name_image_dict`` is not ``None``. + * ``adapt_image_plane_mesh_grids.fits`` — one HDU per galaxy + image-plane mesh grid, written when + ``adapt_images.galaxy_name_image_plane_mesh_grid_dict`` is not + ``None``. + + Parameters + ---------- + adapt_images : AdaptImages + The adapt images container holding per-galaxy image and mesh-grid + dictionaries. + output_path : str or Path + Directory in which to write the FITS files. + """ + import numpy as np + from pathlib import Path + from autoconf.fitsable import hdu_list_for_output_from + + output_path = Path(output_path) + + if adapt_images.galaxy_name_image_dict is not None: + image_list = [ + adapt_images.galaxy_name_image_dict[name].native_for_fits + for name in adapt_images.galaxy_name_image_dict + ] + hdu_list = hdu_list_for_output_from( + values_list=[image_list[0].mask.astype("float")] + image_list, + ext_name_list=["mask"] + list(adapt_images.galaxy_name_image_dict.keys()), + header_dict=adapt_images.mask.header_dict, + ) + hdu_list.writeto(output_path / "adapt_images.fits", overwrite=True) + + if adapt_images.galaxy_name_image_plane_mesh_grid_dict is not None: + mesh_grid_list = [ + adapt_images.galaxy_name_image_plane_mesh_grid_dict[name].native + for name in adapt_images.galaxy_name_image_plane_mesh_grid_dict + ] + hdu_list = hdu_list_for_output_from( + values_list=[np.array([1])] + mesh_grid_list, + ext_name_list=[""] + list(adapt_images.galaxy_name_image_plane_mesh_grid_dict.keys()), + ) + hdu_list.writeto(output_path / "adapt_image_plane_mesh_grids.fits", overwrite=True) diff --git a/autogalaxy/galaxy/plot/galaxies_plots.py b/autogalaxy/galaxy/plot/galaxies_plots.py index f25400136..f8f6adb76 100644 --- a/autogalaxy/galaxy/plot/galaxies_plots.py +++ b/autogalaxy/galaxy/plot/galaxies_plots.py @@ -5,6 +5,7 @@ from autogalaxy.galaxy.galaxies import Galaxies from autogalaxy.plot.plot_utils import _to_lines, _to_positions, plot_array, plot_grid, _save_subplot, _critical_curves_from +from autoarray.plot.utils import hide_unused_axes from autogalaxy import exc @@ -154,6 +155,7 @@ def _defl_x(): ax=axes_flat[i], ) + hide_unused_axes(axes_flat) plt.tight_layout() _save_subplot(fig, output_path, auto_filename, output_format) @@ -213,3 +215,36 @@ def subplot_galaxy_images( plt.tight_layout() _save_subplot(fig, output_path, "subplot_galaxy_images", output_format) + + +def save_galaxy_images_fits( + galaxies, + grid: aa.type.Grid1D2DLike, + output_path, +) -> None: + """Write a FITS file containing the 2D image of every galaxy. + + Produces ``galaxy_images.fits`` in *output_path*. The file contains one + HDU per galaxy, named ``galaxy_0``, ``galaxy_1``, …, plus a ``mask`` + extension as the first extension. + + Parameters + ---------- + galaxies : Galaxies + The galaxies whose images are evaluated. Must not contain + :class:`~autogalaxy.profiles.light.linear.LightProfileLinear` profiles. + grid : aa.type.Grid1D2DLike + The grid on which each galaxy image is evaluated. + output_path : str or Path + Directory in which to write ``galaxy_images.fits``. + """ + from pathlib import Path + from autoconf.fitsable import hdu_list_for_output_from + + image_list = [galaxy.image_2d_from(grid=grid).native_for_fits for galaxy in galaxies] + hdu_list = hdu_list_for_output_from( + values_list=[image_list[0].mask.astype("float")] + image_list, + ext_name_list=["mask"] + [f"galaxy_{i}" for i in range(len(galaxies))], + header_dict=grid.mask.header_dict, + ) + hdu_list.writeto(Path(output_path) / "galaxy_images.fits", overwrite=True) diff --git a/autogalaxy/plot/plot_utils.py b/autogalaxy/plot/plot_utils.py index c735bbc7f..a52384d7f 100644 --- a/autogalaxy/plot/plot_utils.py +++ b/autogalaxy/plot/plot_utils.py @@ -96,9 +96,10 @@ def _save_subplot(fig, output_path, output_filename, output_format="png", def _resolve_colormap(colormap): - """Resolve 'default' to the autoarray default colormap.""" - if colormap == "default": - return "jet" + """Resolve 'default' or None to the autoarray default colormap.""" + if colormap in ("default", None): + from autoarray.plot.utils import _default_colormap + return _default_colormap() return colormap