import autolens as al
import numpy as np
import pytest

import autofit as af
from test.unit.mock.model.mock_profiles import MockLightProfile


class TestFitProperties:
    def test__total_inversions(self, lens_uv_plane_data_7):

        g0 = al.Galaxy(redshift=0.5)

        g1 = al.Galaxy(redshift=1.0)

        g2 = al.Galaxy(redshift=2.0)

        tracer = al.Tracer.from_galaxies(galaxies=[g0, g1, g2])

        fit = al.LensUVPlaneFit.from_lens_data_and_tracer(
            lens_data=lens_uv_plane_data_7, tracer=tracer
        )

        assert fit.total_inversions == 0

        g2 = al.Galaxy(
            redshift=2.0,
            pixelization=al.pixelizations.Rectangular(),
            regularization=al.regularization.Constant(),
        )

        tracer = al.Tracer.from_galaxies(galaxies=[g0, g1, g2])

        fit = al.LensUVPlaneFit.from_lens_data_and_tracer(
            lens_data=lens_uv_plane_data_7, tracer=tracer
        )

        assert fit.total_inversions == 1

        g0 = al.Galaxy(
            redshift=0.5,
            pixelization=al.pixelizations.Rectangular(),
            regularization=al.regularization.Constant(),
        )

        g1 = al.Galaxy(
            redshift=1.0,
            pixelization=al.pixelizations.Rectangular(),
            regularization=al.regularization.Constant(),
        )

        g2 = al.Galaxy(
            redshift=2.0,
            pixelization=al.pixelizations.Rectangular(),
            regularization=al.regularization.Constant(),
        )

        tracer = al.Tracer.from_galaxies(galaxies=[g0, g1, g2])

        fit = al.LensUVPlaneFit.from_lens_data_and_tracer(
            lens_data=lens_uv_plane_data_7, tracer=tracer
        )

        assert fit.total_inversions == 3


class TestLikelihood:
    def test__1x2_image__1x2_visibilities__simple_fourier_transform(self):
        # The image plane image generated by the galaxy is [1.0, 1.0]

        # Thus the chi squared is 4.0**2.0 + 3.0**2.0 = 25.0

        uv_wavelengths = np.array([[0.0, 0.0]])

        uv_plane_data = al.UVPlaneData(
            shape=(1, 2),
            visibilities=5.0 * np.ones((1, 2)),
            pixel_scale=1.0,
            noise_map=np.ones((1,)),
            uv_wavelengths=uv_wavelengths,
            primary_beam=None,
        )
        uv_plane_data.visibilities[0, 1] = 4.0

        mask = al.Mask(
            array=np.array(
                [
                    [True, True, True, True],
                    [True, False, False, True],
                    [True, True, True, True],
                ]
            ),
            pixel_scale=1.0,
            sub_size=1,
        )

        lens_uv_plane_data_7 = al.LensUVPlaneData(
            uv_plane_data=uv_plane_data, mask=mask
        )

        # Setup as a ray trace instance, using a light profile for the lens

        g0 = al.Galaxy(redshift=0.5, light_profile=MockLightProfile(value=1.0, size=2))
        tracer = al.Tracer.from_galaxies(galaxies=[g0])

        fit = al.LensUVPlaneFit.from_lens_data_and_tracer(
            lens_data=lens_uv_plane_data_7, tracer=tracer
        )

        assert (fit._mask == np.array([False, False])).all()

        assert (fit._data == np.array([5.0, 4.0])).all()
        assert (fit.visibilities() == np.array([[5.0, 4.0]])).all()
        assert (fit._noise_map == np.array([[1.0, 1.0]])).all()
        assert (fit.noise_map() == np.array([[1.0, 1.0]])).all()
        assert (fit._model_data == np.array([2.0, 0.0])).all()
        assert (fit.model_visibilities() == np.array([2.0, 0.0])).all()
        assert (fit._residual_map == np.array([3.0, 4.0])).all()
        assert (fit.residual_map() == np.array([3.0, 4.0])).all()
        assert (fit._normalized_residual_map == np.array([3.0, 4.0])).all()
        assert (fit.normalized_residual_map() == np.array([3.0, 4.0])).all()
        assert (fit._chi_squared_map == np.array([9.0, 16.0])).all()
        assert (fit.chi_squared_map() == np.array([9.0, 16.0])).all()

        assert fit.chi_squared == 25.0
        assert fit.reduced_chi_squared == 25.0 / 2.0
        assert fit.noise_normalization == (2.0 * np.log(2 * np.pi * 1.0 ** 2.0))
        assert fit.likelihood == -0.5 * (25.0 + 2.0 * np.log(2 * np.pi * 1.0 ** 2.0))

    def test__3x2_image__2x2_visibilities__use_transformer_for_likelihood(self):

        uv_wavelengths = np.array([[1.0, 0.0], [1.0, 1.0], [2.0, 2.0]])

        transformer = al.Transformer(
            uv_wavelengths=uv_wavelengths,
            grid_radians=np.array([[0.0, -1.0], [0.0, 1.0], [1.0, 1.0]]),
        )

        # This PSF changes the blurred image plane image from [1.0, 1.0] to [1.0, 5.0]

        # Thus, the chi squared is 4.0**2.0 + 0.0**2.0 = 16.0

        uv_plane_data = al.UVPlaneData(
            shape=(1, 2),
            visibilities=5.0 * np.ones((3, 2)),
            pixel_scale=1.0,
            noise_map=2.0 * np.ones((3,)),
            uv_wavelengths=uv_wavelengths,
            primary_beam=None,
        )

        mask = al.Mask(
            array=np.array(
                [
                    [True, True, True, True, True],
                    [True, False, False, False, True],
                    [True, True, True, True, True],
                ]
            ),
            pixel_scale=1.0,
            sub_size=1,
        )

        lens_uv_plane_data_7 = al.LensUVPlaneData(
            uv_plane_data=uv_plane_data, mask=mask
        )

        # Setup as a ray trace instance, using a light profile for the lens

        g0 = al.Galaxy(
            redshift=0.5,
            light_profile=al.light_profiles.EllipticalSersic(intensity=0.001),
        )

        profile_image = g0.profile_image_from_grid(
            grid=lens_uv_plane_data_7.grid, return_in_2d=False, return_binned=True
        )
        model_visibilities_manual = transformer.visibilities_from_image_1d(
            image_1d=profile_image
        )

        tracer = al.Tracer.from_galaxies(galaxies=[g0])

        fit = al.LensUVPlaneFit.from_lens_data_and_tracer(
            lens_data=lens_uv_plane_data_7, tracer=tracer
        )

        assert (fit._mask == np.array([False, False])).all()

        assert (fit._data == np.array([[5.0, 5.0], [5.0, 5.0], [5.0, 5.0]])).all()
        assert (
            fit.visibilities() == np.array([[[5.0, 5.0], [5.0, 5.0], [5.0, 5.0]]])
        ).all()
        assert (
            fit._noise_map == np.array([[[2.0, 2.0], [2.0, 2.0], [2.0, 2.0]]])
        ).all()
        assert (
            fit.noise_map() == np.array([[[2.0, 2.0], [2.0, 2.0], [2.0, 2.0]]])
        ).all()

        assert fit._model_data == pytest.approx(model_visibilities_manual, 1.0e-4)
        assert fit.model_visibilities() == pytest.approx(
            model_visibilities_manual, 1.0e-4
        )

        # moddel visibilities are all [1.94805, 0.0]

        assert fit._residual_map == pytest.approx(
            np.array([[3.0519, 5.0], [3.0519, 5.0], [3.0519, 5.0]]), 1.0e-4
        )
        assert fit.residual_map() == pytest.approx(
            np.array([[3.0519, 5.0], [3.0519, 5.0], [3.0519, 5.0]]), 1.0e-4
        )
        assert fit._normalized_residual_map == pytest.approx(
            np.array(
                [
                    [3.0519 / 2.0, 5.0 / 2.0],
                    [3.0519 / 2.0, 5.0 / 2.0],
                    [3.0519 / 2.0, 5.0 / 2.0],
                ]
            ),
            1.0e-4,
        )
        assert fit.normalized_residual_map() == pytest.approx(
            np.array(
                [
                    [3.0519 / 2.0, 5.0 / 2.0],
                    [3.0519 / 2.0, 5.0 / 2.0],
                    [3.0519 / 2.0, 5.0 / 2.0],
                ]
            ),
            1.0e-4,
        )
        assert fit._chi_squared_map == pytest.approx(
            np.array(
                [
                    [(3.0519 / 2.0) ** 2.0, (5.0 / 2.0) ** 2.0],
                    [(3.0519 / 2.0) ** 2.0, (5.0 / 2.0) ** 2.0],
                    [(3.0519 / 2.0) ** 2.0, (5.0 / 2.0) ** 2.0],
                ]
            ),
            1.0e-4,
        )
        assert fit.chi_squared_map() == pytest.approx(
            np.array(
                [
                    [(3.0519 / 2.0) ** 2.0, (5.0 / 2.0) ** 2.0],
                    [(3.0519 / 2.0) ** 2.0, (5.0 / 2.0) ** 2.0],
                    [(3.0519 / 2.0) ** 2.0, (5.0 / 2.0) ** 2.0],
                ]
            ),
            1.0e-4,
        )

        assert fit.chi_squared == pytest.approx(25.73579, 1.0e-4)
        assert fit.reduced_chi_squared == pytest.approx(25.73579 / 6.0)
        assert fit.noise_normalization == pytest.approx(
            (6.0 * np.log(2 * np.pi * 2.0 ** 2.0)), 1.0e-4
        )
        assert fit.likelihood == pytest.approx(
            -0.5 * (25.73579 + 6.0 * np.log(2 * np.pi * 2.0 ** 2.0)), 1.0e-4
        )


class TestCompareToManualProfilesOnly:
    def test___all_lens_fit_quantities__no_hyper_methods(self, lens_uv_plane_data_7):

        g0 = al.Galaxy(
            redshift=0.5,
            light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
            mass_profile=al.mass_profiles.SphericalIsothermal(einstein_radius=1.0),
        )

        g1 = al.Galaxy(
            redshift=1.0,
            light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
        )

        tracer = al.Tracer.from_galaxies(galaxies=[g0, g1])

        fit = al.LensUVPlaneFit.from_lens_data_and_tracer(
            lens_data=lens_uv_plane_data_7, tracer=tracer
        )

        assert lens_uv_plane_data_7.noise_map(return_x2=True) == pytest.approx(
            fit.noise_map()
        )

        model_visibilities = tracer.profile_visibilities_from_grid_and_transformer(
            grid=lens_uv_plane_data_7.grid, transformer=lens_uv_plane_data_7.transformer
        )

        assert model_visibilities == pytest.approx(fit._model_data, 1e-4)
        assert model_visibilities == pytest.approx(fit.model_visibilities(), 1e-4)

        residual_map = af.fit_util.residual_map_from_data_mask_and_model_data(
            data=lens_uv_plane_data_7.visibilities(),
            mask=lens_uv_plane_data_7.visibilities_mask,
            model_data=model_visibilities,
        )

        assert residual_map == pytest.approx(fit._residual_map, 1e-4)
        assert residual_map == pytest.approx(fit.residual_map(), 1e-4)

        normalized_residual_map = af.fit_util.normalized_residual_map_from_residual_map_noise_map_and_mask(
            residual_map=residual_map,
            mask=lens_uv_plane_data_7.visibilities_mask,
            noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
        )

        assert normalized_residual_map == pytest.approx(
            fit._normalized_residual_map, 1e-4
        )
        assert normalized_residual_map == pytest.approx(
            fit.normalized_residual_map(), 1e-4
        )

        chi_squared_map = af.fit_util.chi_squared_map_from_residual_map_noise_map_and_mask(
            residual_map=residual_map,
            mask=lens_uv_plane_data_7.visibilities_mask,
            noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
        )

        assert chi_squared_map == pytest.approx(fit._chi_squared_map, 1e-4)
        assert chi_squared_map == pytest.approx(fit.chi_squared_map(), 1e-4)

        chi_squared = af.fit_util.chi_squared_from_chi_squared_map_and_mask(
            chi_squared_map=fit._chi_squared_map,
            mask=lens_uv_plane_data_7.visibilities_mask,
        )

        noise_normalization = af.fit_util.noise_normalization_from_noise_map_and_mask(
            noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
            mask=lens_uv_plane_data_7.visibilities_mask,
        )

        likelihood = af.fit_util.likelihood_from_chi_squared_and_noise_normalization(
            chi_squared=chi_squared, noise_normalization=noise_normalization
        )

        assert likelihood == pytest.approx(fit.likelihood, 1e-4)
        assert likelihood == fit.figure_of_merit

    # def test___lens_fit_galaxy_image_dict__corresponds_to_galaxy_images(
    #     self, lens_uv_plane_data_7
    # ):
    #     g0 = al.Galaxy(
    #         redshift=0.5,
    #         light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
    #         mass_profile=al.mass_profiles.SphericalIsothermal(einstein_radius=1.0),
    #     )
    #     g1 = al.Galaxy(
    #         redshift=1.0,
    #         light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
    #     )
    #     g2 = al.Galaxy(redshift=1.0)
    #
    #     tracer = al.Tracer.from_galaxies(galaxies=[g0, g1, g2])
    #
    #     fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
    #         lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
    #     )
    #
    #     traced_grids_of_planes = tracer.traced_grids_of_planes_from_grid(
    #         grid=lens_uv_plane_data_7.grid, return_in_2d=False
    #     )
    #     traced_blurring_grids_of_planes = tracer.traced_grids_of_planes_from_grid(
    #         grid=lens_uv_plane_data_7.blurring_grid, return_in_2d=False
    #     )
    #
    #     g0_profile_image_1d = g0.profile_image_from_grid(
    #         grid=traced_grids_of_planes[0], return_in_2d=False, return_binned=True
    #     )
    #     g0_blurring_image_1d = g0.profile_image_from_grid(
    #         grid=traced_blurring_grids_of_planes[0],
    #         return_in_2d=False,
    #         return_binned=True,
    #     )
    #
    #     g0_blurred_profile_image_1d = lens_uv_plane_data_7.convolver.convolve_image(
    #         image_array=g0_profile_image_1d,
    #         blurring_array=g0_blurring_image_1d,
    #     )
    #
    #     g1_profile_image_1d = g1.profile_image_from_grid(
    #         grid=traced_grids_of_planes[1], return_in_2d=False, return_binned=True
    #     )
    #     g1_blurring_image_1d = g1.profile_image_from_grid(
    #         grid=traced_blurring_grids_of_planes[1],
    #         return_in_2d=False,
    #         return_binned=True,
    #     )
    #
    #     g1_blurred_profile_image_1d = lens_uv_plane_data_7.convolver.convolve_image(
    #         image_array=g1_profile_image_1d,
    #         blurring_array=g1_blurring_image_1d,
    #     )
    #
    #     assert fit.galaxy_model_visibilities_dict[g0] == pytest.approx(
    #         g0_blurred_profile_image_1d, 1.0e-4
    #     )
    #     assert fit.galaxy_model_visibilities_dict[g1] == pytest.approx(
    #         g1_blurred_profile_image_1d, 1.0e-4
    #     )
    #     assert (fit.galaxy_model_visibilities_dict[g2] == np.zeros(9)).all()
    #
    #     assert fit._model_data == pytest.approx(
    #         fit.galaxy_model_visibilities_dict[g0] + fit.galaxy_model_visibilities_dict[g1], 1.0e-4
    #     )
    #
    #     g0_blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
    #         array_1d=g0_blurred_profile_image_1d
    #     )
    #     g1_blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
    #         array_1d=g1_blurred_profile_image_1d
    #     )
    #
    #     assert fit.galaxy_model_visibilities_2d_dict[g0] == pytest.approx(
    #         g0_blurred_profile_image_2d, 1.0e-4
    #     )
    #     assert fit.galaxy_model_visibilities_2d_dict[g1] == pytest.approx(
    #         g1_blurred_profile_image_2d, 1.0e-4
    #     )
    #
    #     assert fit.model_visibilities(return_x2=True) == pytest.approx(
    #         fit.galaxy_model_visibilities_2d_dict[g0] + fit.galaxy_model_visibilities_2d_dict[g1], 1.0e-4
    #     )
    #
    # def test___model_image_and_model_visibilitiess_of_planes_and_unmasked_blurred_profile_image_properties(
    #     self, lens_uv_plane_data_7
    # ):
    #
    #     g0 = al.Galaxy(
    #         redshift=0.5,
    #         light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
    #         mass_profile=al.mass_profiles.SphericalIsothermal(einstein_radius=1.0),
    #     )
    #
    #     g1 = al.Galaxy(
    #         redshift=1.0,
    #         light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
    #     )
    #
    #     tracer = al.Tracer.from_galaxies(galaxies=[g0, g1])
    #
    #     fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
    #         lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
    #     )
    #
    #     blurred_profile_image_2d_of_planes = tracer.blurred_profile_images_of_planes_from_grid_and_convolver(
    #         grid=lens_uv_plane_data_7.grid,
    #         convolver=lens_uv_plane_data_7.convolver,
    #         return_x2=True,
    #     )
    #
    #     model_visibilitiess_of_planes = fit.model_visibilitiess_of_planes(return_x2=True)
    #
    #     assert blurred_profile_image_2d_of_planes[0] == pytest.approx(
    #         model_visibilitiess_of_planes[0], 1.0e-4
    #     )
    #     assert blurred_profile_image_2d_of_planes[1] == pytest.approx(
    #         model_visibilitiess_of_planes[1], 1.0e-4
    #     )
    #
    #     unmasked_blurred_profile_image = tracer.unmasked_blurred_profile_image_from_grid_and_psf(
    #         grid=lens_uv_plane_data_7.grid, psf=lens_uv_plane_data_7.psf
    #     )
    #
    #     assert (
    #         unmasked_blurred_profile_image == fit.unmasked_blurred_profile_image
    #     ).all()
    #
    #     unmasked_blurred_profile_image_of_planes = tracer.unmasked_blurred_profile_image_of_planes_from_grid_and_psf(
    #         grid=lens_uv_plane_data_7.grid, psf=lens_uv_plane_data_7.psf
    #     )
    #
    #     assert (
    #         unmasked_blurred_profile_image_of_planes[0]
    #         == fit.unmasked_blurred_profile_image_of_planes[0]
    #     ).all()
    #     assert (
    #         unmasked_blurred_profile_image_of_planes[1]
    #         == fit.unmasked_blurred_profile_image_of_planes[1]
    #     ).all()
    #
    #     unmasked_blurred_profile_image_of_galaxies = tracer.unmasked_blurred_profile_image_of_planes_and_galaxies_from_grid_and_psf(
    #         grid=lens_uv_plane_data_7.grid, psf=lens_uv_plane_data_7.psf
    #     )
    #
    #     assert (
    #         unmasked_blurred_profile_image_of_galaxies[0][0]
    #         == fit.unmasked_blurred_profile_image_of_planes_and_galaxies[0][0]
    #     ).all()
    #     assert (
    #         unmasked_blurred_profile_image_of_galaxies[1][0]
    #         == fit.unmasked_blurred_profile_image_of_planes_and_galaxies[1][0]
    #     ).all()


#
# class TestCompareToManualInversionOnly:
#     def test___all_lens_fit_quantities__no_hyper_methods(self, lens_uv_plane_data_7):
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#
#         g0 = al.Galaxy(redshift=0.5, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[al.Galaxy(redshift=0.5), g0])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
#         )
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, pixelization_grid=None
#         )
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             mapper=mapper,
#             regularization=reg,
#             image_1d=lens_uv_plane_data_7.visibilities(),
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#             convolver=lens_uv_plane_data_7.convolver,
#         )
#
#         assert inversion.reconstructed_data_1d == pytest.approx(
#             fit._model_data, 1e-4
#         )
#         assert inversion.reconstructed_data_2d == fit.model_visibilities(return_x2=True)
#
#         residual_map = af.fit_util.residual_map_from_data_mask_and_model_data(
#             data=lens_uv_plane_data_7.visibilities(),
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             model_data=inversion.reconstructed_data_1d,
#         )
#         residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=residual_map
#         )
#
#         assert residual_map == pytest.approx(fit._residual_map, 1e-4)
#         assert residual_map_2d == pytest.approx(fit.residual_map(return_x2=True))
#
#         normalized_residual_map = af.fit_util.normalized_residual_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#         )
#
#         normalized_residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=normalized_residual_map
#         )
#
#         assert normalized_residual_map == pytest.approx(
#             fit._normalized_residual_map, 1e-4
#         )
#         assert normalized_residual_map_2d == pytest.approx(
#             fit.normalized_residual_map(return_x2=True)
#         )
#
#         chi_squared_map = af.fit_util.chi_squared_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#         )
#         chi_squared_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=chi_squared_map
#         )
#
#         assert chi_squared_map == pytest.approx(fit._chi_squared_map, 1e-4)
#         assert chi_squared_map_2d == pytest.approx(
#             fit.chi_squared_map(return_x2=True)
#         )
#
#         chi_squared = af.fit_util.chi_squared_from_chi_squared_map_and_mask(
#             chi_squared_map=chi_squared_map_2d, mask=lens_uv_plane_data_7.visibilities_mask
#         )
#
#         noise_normalization = af.fit_util.noise_normalization_from_noise_map_and_mask(
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#         )
#
#         likelihood = af.fit_util.likelihood_from_chi_squared_and_noise_normalization(
#             chi_squared=chi_squared, noise_normalization=noise_normalization
#         )
#
#         assert likelihood == pytest.approx(fit.likelihood, 1e-4)
#
#         likelihood_with_regularization = likelihood_with_regularization_from_chi_squared_regularization_term_and_noise_normalization(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert likelihood_with_regularization == pytest.approx(
#             fit.likelihood_with_regularization, 1e-4
#         )
#
#         evidence = evidence_from_inversion_terms(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             log_curvature_regularization_term=inversion.log_det_curvature_reg_matrix_term,
#             log_regularization_term=inversion.log_det_regularization_matrix_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert evidence == fit.evidence
#         assert evidence == fit.figure_of_merit
#
#     def test___lens_fit_galaxy_image_dict__has_inversion_reconstructed_data(
#         self, lens_uv_plane_data_7
#     ):
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#
#         g0 = al.Galaxy(redshift=0.5)
#         g1 = al.Galaxy(redshift=1.0, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[g0, g1])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
#         )
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, pixelization_grid=None
#         )
#
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             mapper=mapper,
#             regularization=reg,
#             image_1d=lens_uv_plane_data_7.visibilities(),
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#             convolver=lens_uv_plane_data_7.convolver,
#         )
#
#         assert (fit.galaxy_image_1d_dict[g0] == np.zeros(9)).all()
#
#         assert fit.galaxy_image_1d_dict[g1] == pytest.approx(
#             inversion.reconstructed_data_1d, 1.0e-4
#         )
#
#         assert fit._model_data == pytest.approx(
#             fit.galaxy_image_1d_dict[g1], 1.0e-4
#         )
#
#         assert fit.galaxy_image_2d_dict[g1] == pytest.approx(
#             inversion.reconstructed_data_2d, 1.0e-4
#         )
#
#         assert fit.model_visibilities(return_x2=True) == pytest.approx(
#             fit.galaxy_image_2d_dict[g1], 1.0e-4
#         )
#
#     def test___all_lens_fit_quantities__include_hyper_methods(self, lens_uv_plane_data_7):
#
#         hyper_noise_map_max = 0.2
#         lens_uv_plane_data_7.hyper_noise_map_max = hyper_noise_map_max
#
#         hyper_image_sky = al.HyperImageSky(sky_scale=1.0)
#
#         hyper_background_noise = al.HyperBackgroundNoise(noise_scale=1.0)
#
#         image_1d = hyper_image_sky.image_scaled_sky_from_image(
#             image=lens_uv_plane_data_7.visibilities()
#         )
#
#         hyper_noise_map_background_1d = hyper_background_noise.noise_map_scaled_noise_from_noise_map(
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True)
#         )
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#
#         g0 = al.Galaxy(
#             redshift=0.5,
#             pixelization=pix,
#             regularization=reg,
#             hyper_galaxy=al.HyperGalaxy(
#                 contribution_factor=1.0, noise_factor=1.0, noise_power=1.0
#             ),
#             hyper_model_visibilities=np.ones(9),
#             hyper_galaxy_image_1d=np.ones(9),
#             hyper_minimum_value=0.0,
#         )
#
#         tracer = al.Tracer.from_galaxies(galaxies=[al.Galaxy(redshift=0.5), g0])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7,
#             tracer=tracer,
#             hyper_image_sky=hyper_image_sky,
#             hyper_background_noise=hyper_background_noise,
#         )
#
#         hyper_noise_1d = tracer.hyper_noise_map_from_noise_map(
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True)
#         )
#         hyper_noise_map = hyper_noise_map_background_1d + hyper_noise_1d
#         hyper_noise_map[
#             hyper_noise_map > hyper_noise_map_max
#         ] = hyper_noise_map_max
#
#         hyper_noise_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=hyper_noise_map
#         )
#         assert hyper_noise_map == pytest.approx(fit._noise_map, 1e-4)
#         assert hyper_noise_map_2d == pytest.approx(fit.noise_map(return_x2=True, return_masked=True))
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, inversion_uses_border=False
#         )
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             mapper=mapper,
#             regularization=reg,
#             image_1d=image_1d,
#             noise_map=hyper_noise_map,
#             convolver=lens_uv_plane_data_7.convolver,
#         )
#
#         assert inversion.reconstructed_data_1d == pytest.approx(
#             fit._model_data, 1e-4
#         )
#         assert inversion.reconstructed_data_2d == fit.model_visibilities(return_x2=True)
#
#         residual_map = af.fit_util.residual_map_from_data_mask_and_model_data(
#             data=image_1d,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             model_data=inversion.reconstructed_data_1d,
#         )
#         residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=residual_map
#         )
#
#         assert residual_map == pytest.approx(fit._residual_map, 1e-4)
#         assert residual_map_2d == pytest.approx(fit.residual_map(return_x2=True))
#
#         normalized_residual_map = af.fit_util.normalized_residual_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=hyper_noise_map,
#         )
#
#         normalized_residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=normalized_residual_map
#         )
#
#         assert normalized_residual_map == pytest.approx(
#             fit._normalized_residual_map, 1e-4
#         )
#         assert normalized_residual_map_2d == pytest.approx(
#             fit.normalized_residual_map(return_x2=True)
#         )
#
#         chi_squared_map = af.fit_util.chi_squared_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=hyper_noise_map,
#         )
#         chi_squared_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=chi_squared_map
#         )
#
#         assert chi_squared_map == pytest.approx(fit._chi_squared_map, 1e-4)
#         assert chi_squared_map_2d == pytest.approx(
#             fit.chi_squared_map(return_x2=True)
#         )
#
#         chi_squared = af.fit_util.chi_squared_from_chi_squared_map_and_mask(
#             chi_squared_map=chi_squared_map_2d, mask=lens_uv_plane_data_7.visibilities_mask
#         )
#
#         noise_normalization = af.fit_util.noise_normalization_from_noise_map_and_mask(
#             mask=lens_uv_plane_data_7.visibilities_mask, noise_map=hyper_noise_map_2d
#         )
#
#         likelihood = af.fit_util.likelihood_from_chi_squared_and_noise_normalization(
#             chi_squared=chi_squared, noise_normalization=noise_normalization
#         )
#
#         assert likelihood == pytest.approx(fit.likelihood, 1e-4)
#
#         likelihood_with_regularization = likelihood_with_regularization_from_chi_squared_regularization_term_and_noise_normalization(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert likelihood_with_regularization == pytest.approx(
#             fit.likelihood_with_regularization, 1e-4
#         )
#
#         evidence = evidence_from_inversion_terms(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             log_curvature_regularization_term=inversion.log_det_curvature_reg_matrix_term,
#             log_regularization_term=inversion.log_det_regularization_matrix_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert evidence == fit.evidence
#         assert evidence == fit.figure_of_merit
#
#     def test___blurred_and_model_visibilitiess_of_planes_and_unmasked_blurred_profile_image_properties(
#         self, lens_uv_plane_data_7
#     ):
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#
#         g0 = al.Galaxy(redshift=1.0, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[al.Galaxy(redshift=0.5), g0])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
#         )
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, inversion_uses_border=False
#         )
#
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             mapper=mapper,
#             regularization=reg,
#             image_1d=lens_uv_plane_data_7.visibilities(),
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#             convolver=lens_uv_plane_data_7.convolver,
#         )
#
#         model_visibilitiess_of_planes = fit.model_visibilitiess_of_planes(return_x2=True)
#
#         assert (model_visibilitiess_of_planes[0] == np.zeros((7, 7))).all()
#         assert inversion.reconstructed_data_2d == pytest.approx(
#             model_visibilitiess_of_planes[1], 1.0e-4
#         )
#
#
# class TestCompareToManualProfilesAndInversion:
#     def test___all_lens_fit_quantities__no_hyper_methods(self, lens_uv_plane_data_7):
#         galaxy_light = al.Galaxy(
#             redshift=0.5,
#             light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
#         )
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#         galaxy_pix = al.Galaxy(redshift=1.0, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[galaxy_light, galaxy_pix])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
#         )
#
#         blurred_profile_image_1d = tracer.blurred_profile_image_from_grid_and_convolver(
#             grid=lens_uv_plane_data_7.grid,
#             convolver=lens_uv_plane_data_7.convolver,
#             return_in_2d=False,
#         )
#
#         blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=blurred_profile_image_1d
#         )
#
#         assert blurred_profile_image_1d == pytest.approx(
#             fit.blurred_profile_image(return_in_2d=False), 1e-4
#         )
#         assert blurred_profile_image_2d == pytest.approx(
#             fit.blurred_profile_image(return_x2=True)
#         )
#
#         profile_subtracted_image_1d = (
#             lens_uv_plane_data_7.visibilities() - blurred_profile_image_1d
#         )
#         profile_subtracted_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=profile_subtracted_image_1d
#         )
#
#         assert profile_subtracted_image_1d == pytest.approx(
#             fit.profile_subtracted_image(return_in_2d=False)
#         )
#         assert profile_subtracted_image_2d == pytest.approx(
#             fit.profile_subtracted_image(return_x2=True)
#         )
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, inversion_uses_border=False
#         )
#
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             image_1d=profile_subtracted_image_1d,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#             convolver=lens_uv_plane_data_7.convolver,
#             mapper=mapper,
#             regularization=reg,
#         )
#
#         model_visibilities = blurred_profile_image_1d + inversion.reconstructed_data_1d
#         model_visibilities_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=model_visibilities
#         )
#
#         assert model_visibilities == pytest.approx(fit._model_data, 1e-4)
#         assert model_visibilities_2d == pytest.approx(fit.model_visibilities(return_x2=True))
#
#         residual_map = af.fit_util.residual_map_from_data_mask_and_model_data(
#             data=lens_uv_plane_data_7.visibilities(),
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             model_data=model_visibilities,
#         )
#         residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=residual_map
#         )
#
#         assert residual_map == pytest.approx(fit._residual_map, 1e-4)
#         assert residual_map_2d == pytest.approx(fit.residual_map(return_x2=True))
#
#         normalized_residual_map = af.fit_util.normalized_residual_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#         )
#
#         normalized_residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=normalized_residual_map
#         )
#
#         assert normalized_residual_map == pytest.approx(
#             fit._normalized_residual_map, 1e-4
#         )
#         assert normalized_residual_map_2d == pytest.approx(
#             fit.normalized_residual_map(return_x2=True)
#         )
#
#         chi_squared_map = af.fit_util.chi_squared_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#         )
#         chi_squared_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=chi_squared_map
#         )
#
#         assert chi_squared_map == pytest.approx(fit._chi_squared_map, 1e-4)
#         assert chi_squared_map_2d == pytest.approx(
#             fit.chi_squared_map(return_x2=True)
#         )
#
#         chi_squared = af.fit_util.chi_squared_from_chi_squared_map_and_mask(
#             chi_squared_map=chi_squared_map_2d, mask=lens_uv_plane_data_7.visibilities_mask
#         )
#
#         noise_normalization = af.fit_util.noise_normalization_from_noise_map_and_mask(
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#         )
#
#         likelihood = af.fit_util.likelihood_from_chi_squared_and_noise_normalization(
#             chi_squared=chi_squared, noise_normalization=noise_normalization
#         )
#
#         assert likelihood == pytest.approx(fit.likelihood, 1e-4)
#
#         likelihood_with_regularization = likelihood_with_regularization_from_chi_squared_regularization_term_and_noise_normalization(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert likelihood_with_regularization == pytest.approx(
#             fit.likelihood_with_regularization, 1e-4
#         )
#
#         evidence = evidence_from_inversion_terms(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             log_curvature_regularization_term=inversion.log_det_curvature_reg_matrix_term,
#             log_regularization_term=inversion.log_det_regularization_matrix_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert evidence == fit.evidence
#         assert evidence == fit.figure_of_merit
#
#     def test___lens_fit_galaxy_image_dict__has_blurred_profile_images_and_inversion_reconstructed_data(
#         self, lens_uv_plane_data_7
#     ):
#
#         g0 = al.Galaxy(
#             redshift=0.5,
#             light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
#         )
#         g1 = al.Galaxy(
#             redshift=0.5,
#             light_profile=al.light_profiles.EllipticalSersic(intensity=2.0),
#         )
#         g2 = al.Galaxy(redshift=0.5)
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#         galaxy_pix = al.Galaxy(redshift=1.0, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[g0, g1, g2, galaxy_pix])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
#         )
#
#         traced_grids = tracer.traced_grids_of_planes_from_grid(
#             grid=lens_uv_plane_data_7.grid
#         )
#         traced_blurring_grids = tracer.traced_grids_of_planes_from_grid(
#             grid=lens_uv_plane_data_7.blurring_grid
#         )
#
#         g0_profile_image_1d = g0.profile_image_from_grid(
#             grid=traced_grids[0], return_in_2d=False, return_binned=True
#         )
#         g0_blurring_image_1d = g0.profile_image_from_grid(
#             grid=traced_blurring_grids[0], return_in_2d=False, return_binned=False
#         )
#
#         g0_blurred_profile_image_1d = lens_uv_plane_data_7.convolver.convolve_image(
#             image_array=g0_profile_image_1d,
#             blurring_array=g0_blurring_image_1d,
#         )
#
#         g1_profile_image_1d = g1.profile_image_from_grid(
#             grid=traced_grids[1], return_in_2d=False, return_binned=True
#         )
#         g1_blurring_image_1d = g1.profile_image_from_grid(
#             grid=traced_blurring_grids[1], return_in_2d=False, return_binned=False
#         )
#
#         g1_blurred_profile_image_1d = lens_uv_plane_data_7.convolver.convolve_image(
#             image_array=g1_profile_image_1d,
#             blurring_array=g1_blurring_image_1d,
#         )
#
#         blurred_profile_image_1d = (
#             g0_blurred_profile_image_1d + g1_blurred_profile_image_1d
#         )
#
#         profile_subtracted_image_1d = (
#             lens_uv_plane_data_7.visibilities() - blurred_profile_image_1d
#         )
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, inversion_uses_border=False
#         )
#
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             image_1d=profile_subtracted_image_1d,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#             convolver=lens_uv_plane_data_7.convolver,
#             mapper=mapper,
#             regularization=reg,
#         )
#
#         assert fit.galaxy_image_1d_dict[g0] == pytest.approx(
#             g0_blurred_profile_image_1d, 1.0e-4
#         )
#         assert fit.galaxy_image_1d_dict[g1] == pytest.approx(
#             g1_blurred_profile_image_1d, 1.0e-4
#         )
#         assert (fit.galaxy_image_1d_dict[g2] == np.zeros(9)).all()
#         assert fit.galaxy_image_1d_dict[galaxy_pix] == pytest.approx(
#             inversion.reconstructed_data_1d, 1.0e-4
#         )
#
#         assert fit._model_data == pytest.approx(
#             fit.galaxy_image_1d_dict[g0]
#             + fit.galaxy_image_1d_dict[g1]
#             + fit.galaxy_image_1d_dict[galaxy_pix],
#             1.0e-4,
#         )
#
#         g0_blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=g0_blurred_profile_image_1d
#         )
#         g1_blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=g1_blurred_profile_image_1d
#         )
#
#         assert fit.galaxy_image_2d_dict[g0] == pytest.approx(
#             g0_blurred_profile_image_2d, 1.0e-4
#         )
#         assert fit.galaxy_image_2d_dict[g1] == pytest.approx(
#             g1_blurred_profile_image_2d, 1.0e-4
#         )
#         assert fit.galaxy_image_2d_dict[galaxy_pix] == pytest.approx(
#             inversion.reconstructed_data_2d, 1.0e-4
#         )
#
#         assert fit.model_visibilities(return_x2=True) == pytest.approx(
#             fit.galaxy_image_2d_dict[g0]
#             + fit.galaxy_image_2d_dict[g1]
#             + inversion.reconstructed_data_2d,
#             1.0e-4,
#         )
#
#     def test___all_lens_fit_quantities__include_hyper_methods(self, lens_uv_plane_data_7):
#
#         hyper_noise_map_max = 0.2
#         lens_uv_plane_data_7.hyper_noise_map_max = hyper_noise_map_max
#
#         hyper_image_sky = al.HyperImageSky(sky_scale=1.0)
#
#         hyper_background_noise = al.HyperBackgroundNoise(noise_scale=1.0)
#
#         image_1d = hyper_image_sky.image_scaled_sky_from_image(
#             image=lens_uv_plane_data_7.visibilities()
#         )
#
#         hyper_noise_map_background_1d = hyper_background_noise.noise_map_scaled_noise_from_noise_map(
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True)
#         )
#
#         galaxy_light = al.Galaxy(
#             redshift=0.5,
#             light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
#             hyper_galaxy=al.HyperGalaxy(
#                 contribution_factor=1.0, noise_factor=1.0, noise_power=1.0
#             ),
#             hyper_model_visibilities=np.ones(9),
#             hyper_galaxy_image_1d=np.ones(9),
#             hyper_minimum_value=0.0,
#         )
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#         galaxy_pix = al.Galaxy(redshift=1.0, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[galaxy_light, galaxy_pix])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7,
#             tracer=tracer,
#             hyper_image_sky=hyper_image_sky,
#             hyper_background_noise=hyper_background_noise,
#         )
#
#         hyper_noise_1d = tracer.hyper_noise_map_from_noise_map(
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True)
#         )
#         hyper_noise_map = hyper_noise_map_background_1d + hyper_noise_1d
#         hyper_noise_map[
#             hyper_noise_map > hyper_noise_map_max
#         ] = hyper_noise_map_max
#
#         hyper_noise_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=hyper_noise_map
#         )
#
#         assert hyper_noise_map == pytest.approx(fit._noise_map, 1e-4)
#         assert hyper_noise_map_2d == pytest.approx(fit.noise_map(return_x2=True, return_masked=True))
#
#         blurred_profile_image_1d = tracer.blurred_profile_image_from_grid_and_convolver(
#             grid=lens_uv_plane_data_7.grid,
#             convolver=lens_uv_plane_data_7.convolver,
#             return_in_2d=False,
#         )
#
#         blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=blurred_profile_image_1d
#         )
#
#         assert blurred_profile_image_1d == pytest.approx(
#             fit.blurred_profile_image(return_in_2d=False), 1e-4
#         )
#         assert blurred_profile_image_2d == pytest.approx(
#             fit.blurred_profile_image(return_x2=True)
#         )
#
#         profile_subtracted_image_1d = image_1d - blurred_profile_image_1d
#         profile_subtracted_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=profile_subtracted_image_1d
#         )
#
#         assert profile_subtracted_image_1d == pytest.approx(
#             fit.profile_subtracted_image(return_in_2d=False)
#         )
#         assert profile_subtracted_image_2d == pytest.approx(
#             fit.profile_subtracted_image(return_x2=True)
#         )
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, inversion_uses_border=False
#         )
#
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             image_1d=profile_subtracted_image_1d,
#             noise_map=hyper_noise_map,
#             convolver=lens_uv_plane_data_7.convolver,
#             mapper=mapper,
#             regularization=reg,
#         )
#
#         model_visibilities = blurred_profile_image_1d + inversion.reconstructed_data_1d
#         model_visibilities_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=model_visibilities
#         )
#
#         assert model_visibilities == pytest.approx(fit._model_data, 1e-4)
#         assert model_visibilities_2d == pytest.approx(fit.model_visibilities(return_x2=True))
#
#         residual_map = af.fit_util.residual_map_from_data_mask_and_model_data(
#             data=image_1d, mask=lens_uv_plane_data_7.visibilities_mask, model_data=model_visibilities
#         )
#
#         residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=residual_map
#         )
#
#         assert residual_map == pytest.approx(fit._residual_map, 1e-4)
#         assert residual_map_2d == pytest.approx(fit.residual_map(return_x2=True))
#
#         normalized_residual_map = af.fit_util.normalized_residual_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=hyper_noise_map,
#         )
#
#         normalized_residual_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=normalized_residual_map
#         )
#
#         assert normalized_residual_map == pytest.approx(
#             fit._normalized_residual_map, 1e-4
#         )
#         assert normalized_residual_map_2d == pytest.approx(
#             fit.normalized_residual_map(return_x2=True)
#         )
#
#         chi_squared_map = af.fit_util.chi_squared_map_from_residual_map_noise_map_and_mask(
#             residual_map=residual_map,
#             mask=lens_uv_plane_data_7.visibilities_mask,
#             noise_map=hyper_noise_map,
#         )
#
#         chi_squared_map_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=chi_squared_map
#         )
#
#         assert chi_squared_map == pytest.approx(fit._chi_squared_map, 1e-4)
#         assert chi_squared_map_2d == pytest.approx(
#             fit.chi_squared_map(return_x2=True)
#         )
#
#         chi_squared = af.fit_util.chi_squared_from_chi_squared_map_and_mask(
#             chi_squared_map=chi_squared_map_2d, mask=lens_uv_plane_data_7.visibilities_mask
#         )
#
#         noise_normalization = af.fit_util.noise_normalization_from_noise_map_and_mask(
#             mask=lens_uv_plane_data_7.visibilities_mask, noise_map=hyper_noise_map_2d
#         )
#
#         likelihood = af.fit_util.likelihood_from_chi_squared_and_noise_normalization(
#             chi_squared=chi_squared, noise_normalization=noise_normalization
#         )
#
#         assert likelihood == pytest.approx(fit.likelihood, 1e-4)
#
#         likelihood_with_regularization = likelihood_with_regularization_from_chi_squared_regularization_term_and_noise_normalization(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert likelihood_with_regularization == pytest.approx(
#             fit.likelihood_with_regularization, 1e-4
#         )
#
#         evidence = evidence_from_inversion_terms(
#             chi_squared=chi_squared,
#             regularization_term=inversion.regularization_term,
#             log_curvature_regularization_term=inversion.log_det_curvature_reg_matrix_term,
#             log_regularization_term=inversion.log_det_regularization_matrix_term,
#             noise_normalization=noise_normalization,
#         )
#
#         assert evidence == fit.evidence
#         assert evidence == fit.figure_of_merit
#
#     def test___blurred_and_model_visibilitiess_of_planes_and_unmasked_blurred_profile_image_properties(
#         self, lens_uv_plane_data_7
#     ):
#         galaxy_light = al.Galaxy(
#             redshift=0.5,
#             light_profile=al.light_profiles.EllipticalSersic(intensity=1.0),
#         )
#
#         pix = al.pixelizations.Rectangular(shape=(3, 3))
#         reg = al.regularization.Constant(coefficient=1.0)
#         galaxy_pix = al.Galaxy(redshift=1.0, pixelization=pix, regularization=reg)
#
#         tracer = al.Tracer.from_galaxies(galaxies=[galaxy_light, galaxy_pix])
#
#         fit = al.LensUVPlaneFit.from_lens_uv_plane_data_and_tracer(
#             lens_uv_plane_data=lens_uv_plane_data_7, tracer=tracer
#         )
#
#         blurred_profile_image_1d = tracer.blurred_profile_image_from_grid_and_convolver(
#             grid=lens_uv_plane_data_7.grid,
#             convolver=lens_uv_plane_data_7.convolver,
#             return_in_2d=False,
#         )
#
#         blurred_profile_image_2d = lens_uv_plane_data_7.mapping.scaled_array_2d_from_array_1d(
#             array_1d=blurred_profile_image_1d
#         )
#
#         profile_subtracted_image_1d = (
#             lens_uv_plane_data_7.visibilities() - blurred_profile_image_1d
#         )
#
#         mapper = pix.mapper_from_grid_and_pixelization_grid(
#             grid=lens_uv_plane_data_7.grid, inversion_uses_border=False
#         )
#
#         inversion = al.Inversion.from_data_1d_mapper_and_regularization(
#             image_1d=profile_subtracted_image_1d,
#             noise_map=lens_uv_plane_data_7.noise_map(return_x2=True),
#             convolver=lens_uv_plane_data_7.convolver,
#             mapper=mapper,
#             regularization=reg,
#         )
#
#         model_visibilitiess_of_planes = fit.model_visibilitiess_of_planes(return_x2=True)
#
#         assert blurred_profile_image_2d == pytest.approx(
#             model_visibilitiess_of_planes[0], 1.0e-4
#         )
#         assert inversion.reconstructed_data_2d == pytest.approx(
#             model_visibilitiess_of_planes[1], 1.0e-4
#        )
