Пример #1
0
    def test_half_light_radius_source(self):
        phi, q = -0.37221683730659516, 0.70799587973181288
        e1, e2 = param_util.phi_q2_ellipticity(phi, q)

        phi2, q2 = 0.14944144075912402, 0.4105628122365978
        e12, e22 = param_util.phi_q2_ellipticity(phi2, q2)

        kwargs_profile = [{
            'Rs': 0.16350224766074103,
            'e1': e12,
            'e2': e22,
            'center_x': 0,
            'center_y': 0,
            'amp': 1.3168943578511678
        }, {
            'Rs': 0.29187068596715743,
            'e1': e1,
            'e2': e2,
            'center_x': 0,
            'center_y': 0,
            'Ra': 0.020000382843298824,
            'amp': 85.948773973262391
        }]
        kwargs_options = {
            'lens_model_list': [],
            'source_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        r_eff_true = 0.282786143932
        r_eff = lensAnalysis.half_light_radius_source(kwargs_profile,
                                                      numPix=1000,
                                                      deltaPix=0.05)
        npt.assert_almost_equal(r_eff / r_eff_true, 1, 2)
    def test_sersic_vs_hernquist_kinematics(self):
        """
        attention: this test only works for Sersic indices > \approx 2!
        Lower n_sersic will result in different predictions with the Hernquist assumptions
        replacing the correct Light model!
        :return:
        """
        # anisotropy profile
        anisotropy_type = 'OsipkovMerritt'
        r_ani = 2.
        kwargs_anisotropy = {'r_ani': r_ani}  # anisotropy radius [arcsec]

        # aperture as slit
        aperture_type = 'slit'
        length = 3.8
        width = 0.9
        kwargs_aperture = {'length': length, 'width': width, 'center_ra': 0, 'center_dec': 0, 'angle': 0}

        psf_fwhm = 0.7  # Gaussian FWHM psf
        kwargs_cosmo = {'D_d': 1000, 'D_s': 1500, 'D_ds': 800}

        # light profile
        light_profile_list = ['SERSIC']
        r_sersic = .3
        n_sersic = 2.8
        kwargs_light = [{'amp': 1., 'R_sersic':  r_sersic, 'n_sersic': n_sersic}]  # effective half light radius (2d projected) in arcsec

        # mass profile
        mass_profile_list = ['SPP']
        theta_E = 1.2
        gamma = 2.
        kwargs_profile = [{'theta_E': theta_E, 'gamma': gamma}]  # Einstein radius (arcsec) and power-law slope

        # Hernquist fit to Sersic profile
        lens_analysis = LensAnalysis({'lens_light_model_list': ['SERSIC'], 'lens_model_list': []})
        r_eff = lens_analysis.half_light_radius_lens(kwargs_light, deltaPix=0.1, numPix=100)
        print(r_eff)
        light_profile_list_hernquist = ['HERNQUIST']
        kwargs_light_hernquist = [{'Rs': r_eff*0.551, 'amp': 1.}]

        # mge of light profile
        lightModel = LightModel(light_profile_list)
        r_array = np.logspace(-3, 2, 100) * r_eff * 2
        print(r_sersic/r_eff, 'r_sersic/r_eff')
        flux_r = lightModel.surface_brightness(r_array, 0, kwargs_light)
        amps, sigmas, norm = mge.mge_1d(r_array, flux_r, N=20)
        light_profile_list_mge = ['MULTI_GAUSSIAN']
        kwargs_light_mge = [{'amp': amps, 'sigma': sigmas}]
        print(amps, sigmas, 'amp', 'sigma')

        galkin = Galkin(mass_profile_list, light_profile_list_hernquist, aperture_type=aperture_type, anisotropy_model=anisotropy_type, fwhm=psf_fwhm, kwargs_cosmo=kwargs_cosmo)
        sigma_v = galkin.vel_disp(kwargs_profile, kwargs_light_hernquist, kwargs_anisotropy, kwargs_aperture)

        galkin = Galkin(mass_profile_list, light_profile_list_mge, aperture_type=aperture_type, anisotropy_model=anisotropy_type, fwhm=psf_fwhm, kwargs_cosmo=kwargs_cosmo)
        sigma_v2 = galkin.vel_disp(kwargs_profile, kwargs_light_mge, kwargs_anisotropy, kwargs_aperture)

        print(sigma_v, sigma_v2, 'sigma_v Galkin, sigma_v MGEn')
        print((sigma_v/sigma_v2)**2)

        npt.assert_almost_equal((sigma_v-sigma_v2)/sigma_v2, 0, decimal=1)
Пример #3
0
 def test_ellipticity_in_profiles(self):
     lightProfile = ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
     kwargs_profile = [{
         'Rs': 0.16350224766074103,
         'q': 0.4105628122365978,
         'center_x': -0.019983826426838536,
         'center_y': 0.90000011282957304,
         'phi_G': 0.14944144075912402,
         'sigma0': 1.3168943578511678
     }, {
         'Rs': 0.29187068596715743,
         'q': 0.70799587973181288,
         'center_x': 0.020568531548241405,
         'center_y': 0.036038490364800925,
         'Ra': 0.020000382843298824,
         'phi_G': -0.37221683730659516,
         'sigma0': 85.948773973262391
     }]
     kwargs_options = {
         'lens_model_list': ['SPEMD'],
         'lens_model_internal_bool': [True],
         'lens_light_model_internal_bool': [True, True],
         'lens_light_model_list': lightProfile
     }
     lensAnalysis = LensAnalysis(kwargs_options, {})
     r_eff = lensAnalysis.half_light_radius(kwargs_profile)
     kwargs_profile[0]['q'] = 1
     kwargs_profile[1]['q'] = 1
     r_eff_spherical = lensAnalysis.half_light_radius(kwargs_profile)
     npt.assert_almost_equal(r_eff / r_eff_spherical, 1, decimal=2)
Пример #4
0
 def test_multi_gaussian_lens(self):
     kwargs_options = {'lens_model_list': ['SPEP']}
     e1, e2 = param_util.phi_q2_ellipticity(0, 0.9)
     kwargs_lens = [{
         'gamma': 1.8,
         'theta_E': 0.6,
         'e1': e1,
         'e2': e2,
         'center_x': 0.5,
         'center_y': -0.1
     }]
     lensAnalysis = LensAnalysis(kwargs_options)
     amplitudes, sigmas, center_x, center_y = lensAnalysis.multi_gaussian_lens(
         kwargs_lens, n_comp=20)
     model = MultiGaussianKappa()
     x = np.logspace(-2, 0.5, 10) + 0.5
     y = np.zeros_like(x) - 0.1
     f_xx, f_yy, fxy = model.hessian(x,
                                     y,
                                     amplitudes,
                                     sigmas,
                                     center_x=0.5,
                                     center_y=-0.1)
     kappa_mge = (f_xx + f_yy) / 2
     kappa_true = lensAnalysis.LensModel.kappa(x, y, kwargs_lens)
     print(kappa_true / kappa_mge)
     for i in range(len(x)):
         npt.assert_almost_equal(kappa_mge[i] / kappa_true[i], 1, decimal=1)
Пример #5
0
 def test_light2mass_mge_elliptical_sersic(self):
     # same test as above but with Sersic ellipticity definition
     lens_light_kwargs = [{
         'R_sersic': 1.3479852771734446,
         'center_x': -0.0014089381116285044,
         'n_sersic': 2.260502794737016,
         'amp': 0.08679965264978318,
         'center_y': 0.0573684892835563,
         'e1': 0.22781838418202335,
         'e2': 0.03841125245832406
     }, {
         'R_sersic': 0.20907637464009315,
         'center_x': -0.0014089381116285044,
         'n_sersic': 3.0930684763455156,
         'amp': 3.2534559112899633,
         'center_y': 0.0573684892835563,
         'e1': 0.0323604434989261,
         'e2': -0.12430547471424626
     }]
     light_model_list = ['SERSIC_ELLIPSE', 'SERSIC_ELLIPSE']
     lensAnalysis = LensAnalysis(
         {'lens_light_model_list': light_model_list})
     kwargs_mge = lensAnalysis.light2mass_mge(lens_light_kwargs,
                                              model_bool_list=None,
                                              elliptical=True,
                                              numPix=500,
                                              deltaPix=0.5)
     print(kwargs_mge)
     npt.assert_almost_equal(kwargs_mge['e1'], 0.22, decimal=2)
Пример #6
0
    def test_light2mass_mge(self):
        from lenstronomy.LightModel.Profiles.gaussian import MultiGaussianEllipse
        multiGaussianEllipse = MultiGaussianEllipse()
        x_grid, y_grid = util.make_grid(numPix=100, deltapix=0.05)
        kwargs_light = [{
            'amp': [2, 1],
            'sigma': [0.1, 1],
            'center_x': 0,
            'center_y': 0,
            'e1': 0.1,
            'e2': 0
        }]
        light_model_list = ['MULTI_GAUSSIAN_ELLIPSE']
        lensAnalysis = LensAnalysis(
            kwargs_model={'lens_light_model_list': light_model_list})
        kwargs_mge = lensAnalysis.light2mass_mge(
            kwargs_lens_light=kwargs_light,
            numPix=100,
            deltaPix=0.05,
            elliptical=True)
        npt.assert_almost_equal(kwargs_mge['e1'],
                                kwargs_light[0]['e1'],
                                decimal=2)

        del kwargs_light[0]['center_x']
        del kwargs_light[0]['center_y']
        kwargs_mge = lensAnalysis.light2mass_mge(
            kwargs_lens_light=kwargs_light,
            numPix=100,
            deltaPix=0.05,
            elliptical=False)
        npt.assert_almost_equal(kwargs_mge['center_x'], 0, decimal=2)
Пример #7
0
 def test_multi_gaussian_lens_light(self):
     kwargs_profile = [{
         'Rs': 0.16350224766074103,
         'q': 0.4105628122365978,
         'center_x': -0.019983826426838536,
         'center_y': 0.90000011282957304,
         'phi_G': 0.14944144075912402,
         'sigma0': 1.3168943578511678
     }, {
         'Rs': 0.29187068596715743,
         'q': 0.70799587973181288,
         'center_x': 0.020568531548241405,
         'center_y': 0.036038490364800925,
         'Ra': 0.020000382843298824,
         'phi_G': -0.37221683730659516,
         'sigma0': 85.948773973262391
     }]
     kwargs_options = {
         'lens_model_list': ['SPEP'],
         'lens_model_internal_bool': [True],
         'lens_light_model_internal_bool': [True, True],
         'lens_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
     }
     lensAnalysis = LensAnalysis(kwargs_options)
     amplitudes, sigma = lensAnalysis.multi_gaussian_lens_light(
         kwargs_profile, n_comp=20)
     mge = MultiGaussian()
     flux = mge.function(1., 1, amp=amplitudes, sigma=sigma)
     npt.assert_almost_equal(flux, 0.04531989512955493, decimal=8)
Пример #8
0
 def test_half_light_radius_source(self):
     kwargs_profile = [{
         'Rs': 0.16350224766074103,
         'q': 0.4105628122365978,
         'center_x': 0,
         'center_y': 0,
         'phi_G': 0.14944144075912402,
         'sigma0': 1.3168943578511678
     }, {
         'Rs': 0.29187068596715743,
         'q': 0.70799587973181288,
         'center_x': 0,
         'center_y': 0,
         'Ra': 0.020000382843298824,
         'phi_G': -0.37221683730659516,
         'sigma0': 85.948773973262391
     }]
     kwargs_options = {
         'lens_model_list': ['NONE'],
         'source_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
     }
     lensAnalysis = LensAnalysis(kwargs_options)
     r_eff_true = 0.282786143932
     r_eff = lensAnalysis.half_light_radius_source(kwargs_profile,
                                                   numPix=1000,
                                                   deltaPix=0.05)
     npt.assert_almost_equal(r_eff / r_eff_true, 1, 2)
Пример #9
0
 def test_mge_lens_light_elliptical(self):
     e1, e2 = 0.3, 0.
     kwargs_profile = [{
         'amp': 1.,
         'sigma': 2,
         'center_x': 0.,
         'center_y': 0,
         'e1': e1,
         'e2': e2
     }]
     kwargs_options = {'lens_light_model_list': ['GAUSSIAN_ELLIPSE']}
     lensAnalysis = LensAnalysis(kwargs_options)
     amplitudes, sigma, center_x, center_y = lensAnalysis.multi_gaussian_lens_light(
         kwargs_profile, n_comp=20, e1=e1, e2=e2, deltaPix=0.05, numPix=400)
     mge = MultiGaussianEllipse()
     flux = mge.function(1.,
                         1,
                         amp=amplitudes,
                         sigma=sigma,
                         center_x=center_x,
                         center_y=center_y,
                         e1=e1,
                         e2=e2)
     flux_true = lensAnalysis.LensLightModel.surface_brightness(
         1., 1., kwargs_profile)
     npt.assert_almost_equal(flux / flux_true, 1, decimal=1)
Пример #10
0
    def __init__(self, kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model, kwargs_lens, kwargs_source,
                 kwargs_lens_light, kwargs_ps, arrow_size=0.02, cmap_string="gist_heat"):
        """

        :param kwargs_options:
        :param kwargs_data:
        :param arrow_size:
        :param cmap_string:
        """
        self._kwargs_data = kwargs_data
        if isinstance(cmap_string, str) or isinstance(cmap_string, unicode):
            cmap = plt.get_cmap(cmap_string)
        else:
            cmap = cmap_string
        cmap.set_bad(color='k', alpha=1.)
        cmap.set_under('k')
        self._cmap = cmap
        self._arrow_size = arrow_size
        data = Data(kwargs_data)
        self._coords = data._coords
        nx, ny = np.shape(kwargs_data['image_data'])
        Mpix2coord = kwargs_data['transform_pix2angle']
        self._Mpix2coord = Mpix2coord

        self._deltaPix = self._coords.pixel_size
        self._frame_size = self._deltaPix * nx

        x_grid, y_grid = data.coordinates
        self._x_grid = util.image2array(x_grid)
        self._y_grid = util.image2array(y_grid)

        self._imageModel = class_creator.create_image_model(kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model)
        self._analysis = LensAnalysis(kwargs_model)
        self._lensModel = LensModel(lens_model_list=kwargs_model.get('lens_model_list', []),
                                 z_source=kwargs_model.get('z_source', None),
                                 redshift_list=kwargs_model.get('redshift_list', None),
                                 multi_plane=kwargs_model.get('multi_plane', False))
        self._lensModelExt = LensModelExtensions(self._lensModel)
        model, error_map, cov_param, param = self._imageModel.image_linear_solve(kwargs_lens, kwargs_source,
                                                                                 kwargs_lens_light, kwargs_ps, inv_bool=True)
        self._kwargs_lens = kwargs_lens
        self._kwargs_source = kwargs_source
        self._kwargs_lens_light = kwargs_lens_light
        self._kwargs_else = kwargs_ps
        self._model = model
        self._data = kwargs_data['image_data']
        self._cov_param = cov_param
        self._norm_residuals = self._imageModel.reduced_residuals(model, error_map=error_map)
        self._reduced_x2 = self._imageModel.reduced_chi2(model, error_map=error_map)
        log_model = np.log10(model)
        log_model[np.isnan(log_model)] = -5
        self._v_min_default = max(np.min(log_model), -5)
        self._v_max_default = min(np.max(log_model), 10)
        print("reduced chi^2 = ", self._reduced_x2)
Пример #11
0
 def __init__(self, z_lens, z_source, kwargs_model, cosmo=None):
     self.z_d = z_lens
     self.z_s = z_source
     self.lensCosmo = LensCosmo(z_lens, z_source, cosmo=cosmo)
     self.lens_analysis = LensAnalysis(kwargs_model)
     self.lens_model = LensModelExtensions(
         lens_model_list=kwargs_model['lens_model_list'])
     self.kwargs_options = kwargs_model
     kwargs_cosmo = {
         'D_d': self.lensCosmo.D_d,
         'D_s': self.lensCosmo.D_s,
         'D_ds': self.lensCosmo.D_ds
     }
     self.dispersion = Velocity_dispersion(kwargs_cosmo=kwargs_cosmo)
Пример #12
0
 def test_half_light_radius_hernquist(self):
     Rs = 1.
     kwargs_profile = [{'Rs': Rs, 'amp': 1.}]
     kwargs_options = {
         'lens_model_list': [],
         'lens_light_model_list': ['HERNQUIST']
     }
     lensAnalysis = LensAnalysis(kwargs_options)
     r_eff_true = Rs / 0.551
     r_eff = lensAnalysis.half_light_radius_lens(kwargs_profile,
                                                 numPix=500,
                                                 deltaPix=0.2)
     #r_eff_new = lensAnalysis.half_light_radius(kwargs_profile, numPix=1000, deltaPix=0.01)
     npt.assert_almost_equal(r_eff / r_eff_true, 1, 2)
Пример #13
0
 def test_mass_fraction_within_radius(self):
     center_x, center_y = 0.5, -1
     theta_E = 1.1
     kwargs_lens = [{
         'theta_E': 1.1,
         'center_x': center_x,
         'center_y': center_y
     }]
     lensAnalysis = LensAnalysis(kwargs_model={'lens_model_list': ['SIS']})
     kappa_mean_list = lensAnalysis.mass_fraction_within_radius(kwargs_lens,
                                                                center_x,
                                                                center_y,
                                                                theta_E,
                                                                numPix=100)
     npt.assert_almost_equal(kappa_mean_list[0], 1, 2)
Пример #14
0
    def test_ellipticity_in_profiles(self):
        np.random.seed(41)
        lightProfile = ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
        import lenstronomy.Util.param_util as param_util
        phi, q = 0.14944144075912402, 0.4105628122365978
        e1, e2 = param_util.phi_q2_ellipticity(phi, q)

        phi2, q2 = -0.37221683730659516, 0.70799587973181288
        e12, e22 = param_util.phi_q2_ellipticity(phi2, q2)
        center_x = -0.019983826426838536
        center_y = 0.90000011282957304
        kwargs_profile = [{
            'Rs': 0.16350224766074103,
            'e1': e1,
            'e2': e2,
            'center_x': center_x,
            'center_y': center_y,
            'amp': 1.3168943578511678
        }, {
            'Rs': 0.29187068596715743,
            'e1': e12,
            'e2': e22,
            'center_x': center_x,
            'center_y': center_y,
            'Ra': 0.020000382843298824,
            'amp': 85.948773973262391
        }]
        kwargs_options = {
            'lens_model_list': ['SPEP'],
            'lens_light_model_list': lightProfile
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        r_eff = lensAnalysis.half_light_radius_lens(kwargs_profile,
                                                    center_x=center_x,
                                                    center_y=center_y,
                                                    deltaPix=0.1,
                                                    numPix=100)
        kwargs_profile[0]['e1'], kwargs_profile[0]['e2'] = 0, 0
        kwargs_profile[1]['e1'], kwargs_profile[1]['e2'] = 0, 0
        r_eff_spherical = lensAnalysis.half_light_radius_lens(
            kwargs_profile,
            center_x=center_x,
            center_y=center_y,
            deltaPix=0.1,
            numPix=100)
        npt.assert_almost_equal(r_eff / r_eff_spherical, 1, decimal=2)
Пример #15
0
 def test_light2mass_conversion(self):
     numPix = 100
     deltaPix = 0.05
     kwargs_options = {
         'lens_light_model_internal_bool': [True, True],
         'lens_light_model_list': ['SERSIC_ELLIPSE', 'SERSIC']
     }
     kwargs_lens_light = [{
         'R_sersic': 0.5,
         'n_sersic': 4,
         'amp': 2,
         'e1': 0,
         'e2': 0.05
     }, {
         'R_sersic': 1.5,
         'n_sersic': 1,
         'amp': 2
     }]
     lensAnalysis = LensAnalysis(kwargs_options)
     kwargs_interpol = lensAnalysis.light2mass_interpol(
         lens_light_model_list=['SERSIC_ELLIPSE', 'SERSIC'],
         kwargs_lens_light=kwargs_lens_light,
         numPix=numPix,
         deltaPix=deltaPix,
         subgrid_res=1)
     from lenstronomy.LensModel.lens_model import LensModel
     lensModel = LensModel(lens_model_list=['INTERPOL_SCALED'])
     kwargs_lens = [kwargs_interpol]
     import lenstronomy.Util.util as util
     x_grid, y_grid = util.make_grid(numPix, deltapix=deltaPix)
     kappa = lensModel.kappa(x_grid, y_grid, kwargs=kwargs_lens)
     kappa = util.array2image(kappa)
     kappa /= np.mean(kappa)
     flux = lensAnalysis.LensLightModel.surface_brightness(
         x_grid, y_grid, kwargs_lens_light)
     flux = util.array2image(flux)
     flux /= np.mean(flux)
     #import matplotlib.pyplot as plt
     #plt.matshow(flux-kappa)
     #plt.colorbar()
     #plt.show()
     delta_kappa = (kappa - flux) / flux
     max_delta = np.max(np.abs(delta_kappa))
     assert max_delta < 1
     #assert max_diff < 0.01
     npt.assert_almost_equal(flux[0, 0], kappa[0, 0], decimal=2)
Пример #16
0
 def test_raise(self):
     with self.assertRaises(ValueError):
         analysis = LensAnalysis(kwargs_model={'lens_model_list': ['SIS']})
         analysis.multi_gaussian_lens(kwargs_lens=[{'theta_E'}])
     with self.assertRaises(ValueError):
         analysis = LensAnalysis(
             kwargs_model={'lens_light_model_list': ['GAUSSIAN']})
         analysis.flux_components(kwargs_light=[{}],
                                  n_grid=400,
                                  delta_grid=0.01,
                                  deltaPix=1.,
                                  type="wrong")
Пример #17
0
    def __init__(self, z_lens, z_source, kwargs_model, cosmo=None):
        """

        :param z_lens: redshift of lens
        :param z_source: redshift of source
        :param kwargs_model: model keyword arguments
        :param cosmo: astropy.cosmology instance
        """
        self.z_d = z_lens
        self.z_s = z_source
        self.lensCosmo = LensCosmo(z_lens, z_source, cosmo=cosmo)
        self.lens_analysis = LensAnalysis(kwargs_model)
        self._lensModelExt = LensModelExtensions(self.lens_analysis.LensModel)
        self.kwargs_options = kwargs_model
        self._kwargs_cosmo = {
            'D_d': self.lensCosmo.D_d,
            'D_s': self.lensCosmo.D_s,
            'D_ds': self.lensCosmo.D_ds
        }
Пример #18
0
    def test_point_source(self):
        kwargs_model = {
            'lens_model_list': ['SPEMD', 'SHEAR_GAMMA_PSI'],
            'point_source_model_list': ['SOURCE_POSITION']
        }
        lensAnalysis = LensAnalysis(kwargs_model=kwargs_model)
        source_x, source_y = 0.02, 0.1
        kwargs_ps = [{
            'dec_source': source_y,
            'ra_source': source_x,
            'point_amp': 75.155
        }]
        kwargs_lens = [{
            'e2': 0.1,
            'center_x': 0,
            'theta_E': 1.133,
            'e1': 0.1,
            'gamma': 2.063,
            'center_y': 0
        }, {
            'gamma_ext': 0.026,
            'psi_ext': 1.793
        }]
        x_image, y_image = lensAnalysis.PointSource.image_position(
            kwargs_ps=kwargs_ps, kwargs_lens=kwargs_lens)
        from lenstronomy.LensModel.Solver.lens_equation_solver import LensEquationSolver
        from lenstronomy.LensModel.lens_model import LensModel
        lensModel = LensModel(lens_model_list=['SPEMD', 'SHEAR_GAMMA_PSI'])
        from lenstronomy.PointSource.point_source import PointSource
        ps = PointSource(point_source_type_list=['SOURCE_POSITION'],
                         lensModel=lensModel)
        x_image_new, y_image_new = ps.image_position(kwargs_ps, kwargs_lens)
        npt.assert_almost_equal(x_image_new[0], x_image[0], decimal=7)

        solver = LensEquationSolver(lensModel=lensModel)

        x_image_true, y_image_true = solver.image_position_from_source(
            source_x,
            source_y,
            kwargs_lens,
            min_distance=0.01,
            search_window=5,
            precision_limit=10**(-10),
            num_iter_max=100,
            arrival_time_sort=True,
            initial_guess_cut=False,
            verbose=False,
            x_center=0,
            y_center=0,
            num_random=0,
            non_linear=False,
            magnification_limit=None)

        print(x_image[0], y_image[0], x_image_true, y_image_true)
        npt.assert_almost_equal(x_image_true, x_image[0], decimal=7)
Пример #19
0
 def test_multi_gaussian_lens_light(self):
     kwargs_profile = [{
         'Rs': 0.16350224766074103,
         'e1': 0,
         'e2': 0,
         'center_x': 0,
         'center_y': 0,
         'amp': 1.3168943578511678
     }, {
         'Rs': 0.29187068596715743,
         'e1': 0,
         'e2': 0,
         'center_x': 0,
         'center_y': 0,
         'Ra': 0.020000382843298824,
         'amp': 85.948773973262391
     }]
     kwargs_options = {
         'lens_model_list': ['SPEP'],
         'lens_model_internal_bool': [True],
         'lens_light_model_internal_bool': [True, True],
         'lens_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
     }
     lensAnalysis = LensAnalysis(kwargs_options)
     amplitudes, sigma, center_x, center_y = lensAnalysis.multi_gaussian_lens_light(
         kwargs_profile, n_comp=20)
     mge = MultiGaussian()
     flux = mge.function(1.,
                         1,
                         amp=amplitudes,
                         sigma=sigma,
                         center_x=center_x,
                         center_y=center_y)
     flux_true = lensAnalysis.LensLightModel.surface_brightness(
         1, 1, kwargs_profile)
     npt.assert_almost_equal(flux / flux_true, 1, decimal=2)
     del kwargs_profile[0]['center_x']
     del kwargs_profile[0]['center_y']
     amplitudes_new, sigma, center_x, center_y = lensAnalysis.multi_gaussian_lens_light(
         kwargs_profile, n_comp=20)
     npt.assert_almost_equal(amplitudes_new, amplitudes, decimal=2)
Пример #20
0
    def test_half_light_radius(self):
        phi, q = -0.37221683730659516, 0.70799587973181288
        e1, e2 = param_util.phi_q2_ellipticity(phi, q)

        phi2, q2 = 0.14944144075912402, 0.4105628122365978
        e12, e22 = param_util.phi_q2_ellipticity(phi2, q2)
        center_x = -0.019983826426838536
        center_y = 0.90000011282957304
        kwargs_profile = [{
            'Rs': 0.16350224766074103,
            'e1': e12,
            'e2': e22,
            'center_x': center_x,
            'center_y': center_y,
            'amp': 1.3168943578511678
        }, {
            'Rs': 0.29187068596715743,
            'center_x': center_x,
            'center_y': center_y,
            'Ra': 0.020000382843298824,
            'e1': e1,
            'e2': e2,
            'amp': 85.948773973262391
        }]
        kwargs_options = {
            'lens_model_list': ['SPEP'],
            'lens_model_internal_bool': [True],
            'lens_light_model_internal_bool': [True, True],
            'lens_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        r_eff_true = 0.25430388278592997
        r_eff = lensAnalysis.half_light_radius_lens(kwargs_profile,
                                                    center_x=center_x,
                                                    center_y=center_y,
                                                    numPix=1000,
                                                    deltaPix=0.01)
        #r_eff_new = lensAnalysis.half_light_radius(kwargs_profile, numPix=1000, deltaPix=0.01)
        npt.assert_almost_equal(r_eff, r_eff_true, 2)
Пример #21
0
 def test_buldge_disk_ratio(self):
     kwargs_buldge_disk = {
         'I0_b': 10,
         'R_b': 0.1,
         'phi_G_b': 0,
         'q_b': 1,
         'I0_d': 2,
         'R_d': 1,
         'phi_G_d': 0.5,
         'q_d': 0.7,
         'center_x': 0,
         'center_y': 0
     }
     light_tot, light_buldge = LensAnalysis.buldge_disk_ratio(
         kwargs_buldge_disk)
     npt.assert_almost_equal(light_buldge / light_tot, 0.108, decimal=2)
Пример #22
0
    def test_flux_components(self):
        phi, q = -0.37221683730659516, 0.70799587973181288
        e1, e2 = param_util.phi_q2_ellipticity(phi, q)

        phi2, q2 = 0.14944144075912402, 0.4105628122365978
        e12, e22 = param_util.phi_q2_ellipticity(phi2, q2)

        kwargs_profile = [{
            'Rs': 0.16350224766074103,
            'e1': e12,
            'e2': e22,
            'center_x': -0.019983826426838536,
            'center_y': 0.90000011282957304,
            'amp': 1.3168943578511678
        }, {
            'Rs': 0.29187068596715743,
            'e1': e1,
            'e2': e2,
            'center_x': 0.020568531548241405,
            'center_y': 0.036038490364800925,
            'Ra': 0.020000382843298824,
            'amp': 85.948773973262391
        }]
        kwargs_options = {
            'lens_model_list': ['SPEP'],
            'lens_model_internal_bool': [True],
            'lens_light_model_internal_bool': [True, True],
            'lens_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        flux_list, R_h_list = lensAnalysis.flux_components(kwargs_profile,
                                                           n_grid=400,
                                                           delta_grid=0.01,
                                                           deltaPix=1.,
                                                           type="lens")
        assert len(flux_list) == 2
        npt.assert_almost_equal(flux_list[0], 0.23898248741810812, decimal=8)
        npt.assert_almost_equal(flux_list[1], 3.0565768930826662, decimal=8)

        kwargs_profile = [{'amp': 1.}]
        kwargs_options = {
            'source_light_model_list': ['UNIFORM'],
            'lens_model_list': []
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        flux_list, R_h_list = lensAnalysis.flux_components(kwargs_profile,
                                                           n_grid=400,
                                                           delta_grid=0.01,
                                                           deltaPix=1.,
                                                           type="source")
        assert len(flux_list) == 1
        npt.assert_almost_equal(flux_list[0], 16, decimal=8)
Пример #23
0
    def test_ellipticity_lens_light(self):
        e1_in = 0.1
        e2_in = 0
        kwargs_light = [{
            'amp': 1,
            'sigma': 1.,
            'center_x': 0,
            'center_y': 0,
            'e1': e1_in,
            'e2': e2_in
        }]
        light_model_list = ['GAUSSIAN_ELLIPSE']
        lensAnalysis = LensAnalysis(
            kwargs_model={'lens_light_model_list': light_model_list})
        e1, e2 = lensAnalysis.ellipticity_lens_light(kwargs_light,
                                                     center_x=0,
                                                     center_y=0,
                                                     model_bool_list=None,
                                                     deltaPix=0.1,
                                                     numPix=200)
        npt.assert_almost_equal(e1, e1_in, decimal=4)
        npt.assert_almost_equal(e2, e2_in, decimal=4)

        #SERSIC
        e1_in = 0.1
        e2_in = 0
        kwargs_light = [{
            'amp': 1,
            'n_sersic': 2.,
            'R_sersic': 1,
            'center_x': 0,
            'center_y': 0,
            'e1': e1_in,
            'e2': e2_in
        }]
        light_model_list = ['SERSIC_ELLIPSE']
        lensAnalysis = LensAnalysis(
            kwargs_model={'lens_light_model_list': light_model_list})
        e1, e2 = lensAnalysis.ellipticity_lens_light(kwargs_light,
                                                     center_x=0,
                                                     center_y=0,
                                                     model_bool_list=None,
                                                     deltaPix=0.2,
                                                     numPix=400)
        print(e1, e2)
        npt.assert_almost_equal(e1, e1_in, decimal=3)
        npt.assert_almost_equal(e2, e2_in, decimal=3)
Пример #24
0
    def test_flux_components(self):
        kwargs_profile = [{
            'Rs': 0.16350224766074103,
            'q': 0.4105628122365978,
            'center_x': -0.019983826426838536,
            'center_y': 0.90000011282957304,
            'phi_G': 0.14944144075912402,
            'sigma0': 1.3168943578511678
        }, {
            'Rs': 0.29187068596715743,
            'q': 0.70799587973181288,
            'center_x': -0.01,
            'center_y': 0.9,
            'Ra': 0.020000382843298824,
            'phi_G': -0.37221683730659516,
            'sigma0': 85.948773973262391
        }]
        kwargs_options = {
            'lens_model_list': ['SPEP'],
            'lens_model_internal_bool': [True],
            'lens_light_model_internal_bool': [True, True],
            'lens_light_model_list': ['HERNQUIST_ELLIPSE', 'PJAFFE_ELLIPSE']
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        flux_list, R_h_list = lensAnalysis.flux_components(kwargs_profile,
                                                           n_grid=400,
                                                           delta_grid=0.01,
                                                           deltaPix=1.,
                                                           type="lens")
        assert len(flux_list) == 2
        npt.assert_almost_equal(flux_list[0], 0.23898248741810812, decimal=8)
        npt.assert_almost_equal(flux_list[1], 3.0565768930826662, decimal=8)

        kwargs_profile = [{'mean': 1.}]
        kwargs_options = {
            'lens_light_model_list': ['UNIFORM'],
            'lens_model_list': ['NONE']
        }
        lensAnalysis = LensAnalysis(kwargs_options)
        flux_list, R_h_list = lensAnalysis.flux_components(kwargs_profile,
                                                           n_grid=400,
                                                           delta_grid=0.01,
                                                           deltaPix=1.,
                                                           type="lens")
        assert len(flux_list) == 1
        npt.assert_almost_equal(flux_list[0], 16, decimal=8)
Пример #25
0
    def test_interpolated_sersic(self):
        from lenstronomy.Analysis.lens_analysis import LensAnalysis
        kwargs_light = [{'n_sersic': 2, 'R_sersic': 0.5, 'amp': 1, 'center_x': 0.01, 'center_y': 0.01}]
        kwargs_lens = [{'n_sersic': 2, 'R_sersic': 0.5, 'k_eff': 1, 'center_x': 0.01, 'center_y': 0.01}]
        deltaPix = 0.1
        numPix = 100

        kwargs_interp = LensAnalysis.light2mass_interpol(['SERSIC'], kwargs_lens_light=kwargs_light, numPix=numPix,
                                                                                          deltaPix=deltaPix, subgrid_res=5)
        kwargs_lens_interp = [kwargs_interp]
        from lenstronomy.Analysis.lens_properties import LensProp
        z_lens = 0.5
        z_source = 1.5
        r_ani = 0.62
        kwargs_anisotropy = {'r_ani': r_ani}
        R_slit = 3.8
        dR_slit = 1.
        kwargs_aperture = {'center_ra': 0, 'width': dR_slit, 'length': R_slit, 'angle': 0, 'center_dec': 0}
        aperture_type = 'slit'
        psf_fwhm = 0.7
        anisotropy_model = 'OsipkovMerritt'
        r_eff = 0.5
        kwargs_options = {'lens_model_list': ['SERSIC'],
                          'lens_light_model_list': ['SERSIC']}
        lensProp = LensProp(z_lens, z_source, kwargs_options)

        v_sigma = lensProp.velocity_dispersion_numerical(kwargs_lens, kwargs_light, kwargs_anisotropy,
                                                         kwargs_aperture, psf_fwhm, aperture_type, anisotropy_model,
                                                         MGE_light=True, MGE_mass=True, r_eff=r_eff)
        kwargs_options_interp = {'lens_model_list': ['INTERPOL'],
                                 'lens_light_model_list': ['SERSIC']}
        lensProp_interp = LensProp(z_lens, z_source, kwargs_options_interp)
        v_sigma_interp = lensProp_interp.velocity_dispersion_numerical(kwargs_lens_interp, kwargs_light, kwargs_anisotropy,
                                                         kwargs_aperture, psf_fwhm, aperture_type, anisotropy_model,
                                                         kwargs_numerics={}, MGE_light=True, MGE_mass=True, r_eff=r_eff)
        npt.assert_almost_equal(v_sigma / v_sigma_interp, 1, 1)
Пример #26
0
class LensModelPlot(object):
    """
    class that manages the summary plots of a lens model
    """
    def __init__(self,
                 kwargs_data,
                 kwargs_psf,
                 kwargs_numerics,
                 kwargs_model,
                 kwargs_lens,
                 kwargs_source,
                 kwargs_lens_light,
                 kwargs_ps,
                 arrow_size=0.1,
                 cmap_string="gist_heat",
                 high_res=5):
        """

        :param kwargs_options:
        :param kwargs_data:
        :param arrow_size:
        :param cmap_string:
        """
        self._kwargs_data = kwargs_data
        if isinstance(cmap_string, str) or isinstance(cmap_string, unicode):
            cmap = plt.get_cmap(cmap_string)
        else:
            cmap = cmap_string
        cmap.set_bad(color='k', alpha=1.)
        cmap.set_under('k')
        self._cmap = cmap
        self._arrow_size = arrow_size
        data = Data(kwargs_data)
        self._coords = data._coords
        nx, ny = np.shape(kwargs_data['image_data'])
        Mpix2coord = kwargs_data['transform_pix2angle']
        self._Mpix2coord = Mpix2coord

        self._deltaPix = self._coords.pixel_size
        self._frame_size = self._deltaPix * nx

        self._x_grid, self._y_grid = data.coordinates

        self._imageModel = class_creator.creat_image_model(
            kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model)
        self._analysis = LensAnalysis(kwargs_model)
        self._lensModel = LensModelExtensions(
            lens_model_list=kwargs_model.get('lens_model_list', ['NONE']),
            z_source=kwargs_model.get('z_source', None),
            redshift_list=kwargs_model.get('redshift_list', None),
            multi_plane=kwargs_model.get('multi_plane', False))
        self._ra_crit_list, self._dec_crit_list, self._ra_caustic_list, self._dec_caustic_list = self._lensModel.critical_curve_caustics(
            kwargs_lens, compute_window=self._frame_size, grid_scale=0.01)

        model, error_map, cov_param, param = self._imageModel.image_linear_solve(
            kwargs_lens,
            kwargs_source,
            kwargs_lens_light,
            kwargs_ps,
            inv_bool=True)
        self._kwargs_lens = kwargs_lens
        self._kwargs_source = kwargs_source
        self._kwargs_lens_light = kwargs_lens_light
        self._kwargs_else = kwargs_ps
        self._model = model
        self._data = kwargs_data['image_data']
        self._cov_param = cov_param
        self._norm_residuals = self._imageModel.reduced_residuals(
            model, error_map=error_map)
        self._reduced_x2 = self._imageModel.reduced_chi2(model,
                                                         error_map=error_map)
        log_model = np.log10(model)
        log_model[np.isnan(log_model)] = -5
        self._v_min_default = max(np.min(log_model), -5)
        self._v_max_default = min(np.max(log_model), 10)
        print("reduced chi^^ = ", self._reduced_x2)

    def data_plot(self, ax, v_min=None, v_max=None):
        """

        :param ax:
        :return:
        """
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(self._data),
                        origin='lower',
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap=self._cmap,
                        vmin=v_min,
                        vmax=v_max)  # , vmin=0, vmax=2

        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)

        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax,
                         self._frame_size,
                         text="Observed",
                         color="w",
                         backgroundcolor='k')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        return ax

    def model_plot(self, ax, v_min=None, v_max=None):
        """

        :param ax:
        :param model:
        :param v_min:
        :param v_max:
        :return:
        """
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(self._model),
                        origin='lower',
                        vmin=v_min,
                        vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap=self._cmap)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax,
                         self._frame_size,
                         text="Reconstructed",
                         color="w",
                         backgroundcolor='k')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)

        plot_line_set(ax,
                      self._coords,
                      self._ra_caustic_list,
                      self._dec_caustic_list,
                      color='b')
        plot_line_set(ax,
                      self._coords,
                      self._ra_crit_list,
                      self._dec_crit_list,
                      color='r')
        ra_image, dec_image = self._imageModel.image_positions(
            self._kwargs_else, self._kwargs_lens)
        image_position_plot(ax, self._coords, ra_image[0], dec_image[0])
        source_position_plot(ax, self._coords, self._kwargs_source)

    def convergence_plot(self, ax, v_min=None, v_max=None):
        """

        :param x_grid:
        :param y_grid:
        :param kwargs_lens:
        :param kwargs_else:
        :return:
        """
        kappa_result = util.array2image(
            self._lensModel.kappa(self._x_grid, self._y_grid,
                                  self._kwargs_lens))
        im = ax.matshow(np.log10(kappa_result),
                        origin='lower',
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap=self._cmap,
                        vmin=v_min,
                        vmax=v_max)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='w')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          color='w',
                          arrow_size=self._arrow_size)
        text_description(ax,
                         self._frame_size,
                         text="Convergence",
                         color="w",
                         backgroundcolor='k',
                         flipped=False)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ $\kappa$', fontsize=15)
        return ax

    def normalized_residual_plot(self, ax, v_min=-6, v_max=6):
        """

        :param ax:
        :param residuals:
        :return:
        """
        im = ax.matshow(self._norm_residuals,
                        vmin=v_min,
                        vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap='bwr',
                        origin='lower')
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        text_description(ax,
                         self._frame_size,
                         text="Normalized Residuals",
                         color="k",
                         backgroundcolor='w')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          color='k',
                          arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'(f$_{model}$-f$_{data}$)/$\sigma$', fontsize=15)
        return ax

    def absolute_residual_plot(self, ax, v_min=-1, v_max=1):
        """

        :param ax:
        :param residuals:
        :return:
        """
        im = ax.matshow(self._model - self._data,
                        vmin=v_min,
                        vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap='bwr',
                        origin='lower')
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        text_description(ax,
                         self._frame_size,
                         text="Residuals",
                         color="k",
                         backgroundcolor='w')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          color='k',
                          arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'(f$_{model}$-f$_{data}$)', fontsize=15)
        return ax

    def source_plot(self,
                    ax,
                    numPix,
                    deltaPix_source,
                    source_sigma=0.001,
                    convolution=False,
                    v_min=None,
                    v_max=None):
        """

        :param ax:
        :param coords_source:
        :param source:
        :return:
        """
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        d_s = numPix * deltaPix_source
        x_grid_source, y_grid_source = util.make_grid_transformed(
            numPix, self._Mpix2coord * deltaPix_source / self._deltaPix)
        x_center = self._kwargs_source[0]['center_x']
        y_center = self._kwargs_source[0]['center_y']
        x_grid_source += x_center
        y_grid_source += y_center
        coords_source = Coordinates(self._Mpix2coord * deltaPix_source /
                                    self._deltaPix,
                                    ra_at_xy_0=x_grid_source[0],
                                    dec_at_xy_0=y_grid_source[0])

        source = self._imageModel.SourceModel.surface_brightness(
            x_grid_source, y_grid_source, self._kwargs_source)
        source = util.array2image(source)
        if convolution:
            source = ndimage.filters.gaussian_filter(source,
                                                     sigma=source_sigma /
                                                     deltaPix_source,
                                                     mode='nearest',
                                                     truncate=20)

        im = ax.matshow(np.log10(source),
                        origin='lower',
                        extent=[0, d_s, 0, d_s],
                        cmap=self._cmap,
                        vmin=v_min,
                        vmax=v_max)  # source
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        plot_line_set(ax,
                      coords_source,
                      self._ra_caustic_list,
                      self._dec_caustic_list,
                      color='b')
        scale_bar(ax, d_s, dist=0.1, text='0.1"', color='w', flipped=False)
        coordinate_arrows(ax,
                          d_s,
                          coords_source,
                          arrow_size=self._arrow_size,
                          color='w')
        text_description(ax,
                         d_s,
                         text="Reconstructed source",
                         color="w",
                         backgroundcolor='k',
                         flipped=False)
        source_position_plot(ax, coords_source, self._kwargs_source)
        return ax

    def error_map_source_plot(self,
                              ax,
                              numPix,
                              deltaPix_source,
                              v_min=None,
                              v_max=None):
        x_grid_source, y_grid_source = util.make_grid_transformed(
            numPix, self._Mpix2coord * deltaPix_source / self._deltaPix)
        x_center = self._kwargs_source[0]['center_x']
        y_center = self._kwargs_source[0]['center_y']
        x_grid_source += x_center
        y_grid_source += y_center
        coords_source = Coordinates(self._Mpix2coord * deltaPix_source /
                                    self._deltaPix,
                                    ra_at_xy_0=x_grid_source[0],
                                    dec_at_xy_0=y_grid_source[0])
        error_map_source = self._analysis.error_map_source(
            self._kwargs_source, x_grid_source, y_grid_source, self._cov_param)
        error_map_source = util.array2image(error_map_source)
        d_s = numPix * deltaPix_source
        im = ax.matshow(error_map_source,
                        origin='lower',
                        extent=[0, d_s, 0, d_s],
                        cmap=self._cmap,
                        vmin=v_min,
                        vmax=v_max)  # source
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'error variance', fontsize=15)
        plot_line_set(ax,
                      coords_source,
                      self._ra_caustic_list,
                      self._dec_caustic_list,
                      color='b')
        scale_bar(ax, d_s, dist=0.1, text='0.1"', color='w', flipped=False)
        coordinate_arrows(ax,
                          d_s,
                          coords_source,
                          arrow_size=self._arrow_size,
                          color='w')
        text_description(ax,
                         d_s,
                         text="Error map in source",
                         color="w",
                         backgroundcolor='k',
                         flipped=False)
        source_position_plot(ax, coords_source, self._kwargs_source)
        return ax

    def magnification_plot(self, ax, v_min=-10, v_max=10):
        """

        :param ax:
        :return:
        """
        mag_result = util.array2image(
            self._lensModel.magnification(self._x_grid, self._y_grid,
                                          self._kwargs_lens))
        im = ax.matshow(mag_result,
                        origin='lower',
                        extent=[0, self._frame_size, 0, self._frame_size],
                        vmin=v_min,
                        vmax=v_max,
                        cmap=self._cmap,
                        alpha=0.5)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          color='k',
                          arrow_size=self._arrow_size)
        text_description(ax,
                         self._frame_size,
                         text="Magnification model",
                         color="k",
                         backgroundcolor='w')
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'det(A$^{-1}$)', fontsize=15)

        plot_line_set(ax,
                      self._coords,
                      self._ra_caustic_list,
                      self._dec_caustic_list,
                      color='b')
        plot_line_set(ax,
                      self._coords,
                      self._ra_crit_list,
                      self._dec_crit_list,
                      color='r')
        ra_image, dec_image = self._imageModel.image_positions(
            self._kwargs_else, self._kwargs_lens)
        image_position_plot(ax,
                            self._coords,
                            ra_image[0],
                            dec_image[0],
                            color='k')
        source_position_plot(ax, self._coords, self._kwargs_source)
        return ax

    def deflection_plot(self, ax, v_min=None, v_max=None, axis=0):
        """

        :param kwargs_lens:
        :param kwargs_else:
        :return:
        """

        alpha1, alpha2 = self._lensModel.alpha(self._x_grid, self._y_grid,
                                               self._kwargs_lens)
        alpha1 = util.array2image(alpha1)
        alpha2 = util.array2image(alpha2)
        if axis == 0:
            alpha = alpha1
        else:
            alpha = alpha2
        im = ax.matshow(alpha,
                        origin='lower',
                        extent=[0, self._frame_size, 0, self._frame_size],
                        vmin=v_min,
                        vmax=v_max,
                        cmap=self._cmap,
                        alpha=0.5)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          color='k',
                          arrow_size=self._arrow_size)
        text_description(ax,
                         self._frame_size,
                         text="Deflection model",
                         color="k",
                         backgroundcolor='w')
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'arcsec', fontsize=15)

        plot_line_set(ax,
                      self._coords,
                      self._ra_caustic_list,
                      self._dec_caustic_list,
                      color='b')
        plot_line_set(ax,
                      self._coords,
                      self._ra_crit_list,
                      self._dec_crit_list,
                      color='r')
        ra_image, dec_image = self._imageModel.image_positions(
            self._kwargs_else, self._kwargs_lens)
        image_position_plot(ax, self._coords, ra_image[0], dec_image[0])
        source_position_plot(ax, self._coords, self._kwargs_source)
        return ax

    def decomposition_plot(self,
                           ax,
                           text='Reconstructed',
                           v_min=None,
                           v_max=None,
                           unconvolved=False,
                           point_source_add=False,
                           source_add=False,
                           lens_light_add=False):

        model = self._imageModel.image(self._kwargs_lens,
                                       self._kwargs_source,
                                       self._kwargs_lens_light,
                                       self._kwargs_else,
                                       unconvolved=unconvolved,
                                       source_add=source_add,
                                       lens_light_add=lens_light_add,
                                       point_source_add=point_source_add)
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(model),
                        origin='lower',
                        vmin=v_min,
                        vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap=self._cmap)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax,
                         self._frame_size,
                         text=text,
                         color="w",
                         backgroundcolor='k')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        return ax

    def subtract_from_data_plot(self,
                                ax,
                                text='Subtracted',
                                v_min=None,
                                v_max=None,
                                point_source_add=False,
                                source_add=False,
                                lens_light_add=False):
        model = self._imageModel.image(self._kwargs_lens,
                                       self._kwargs_source,
                                       self._kwargs_lens_light,
                                       self._kwargs_else,
                                       unconvolved=False,
                                       source_add=source_add,
                                       lens_light_add=lens_light_add,
                                       point_source_add=point_source_add)
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(self._data - model),
                        origin='lower',
                        vmin=v_min,
                        vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size],
                        cmap=self._cmap)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax,
                         self._frame_size,
                         text=text,
                         color="w",
                         backgroundcolor='k')
        coordinate_arrows(ax,
                          self._frame_size,
                          self._coords,
                          arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        return ax
Пример #27
0
class LensModelPlot(object):
    """
    class that manages the summary plots of a lens model
    """
    def __init__(self, kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model, kwargs_lens, kwargs_source,
                 kwargs_lens_light, kwargs_ps, arrow_size=0.02, cmap_string="gist_heat"):
        """

        :param kwargs_options:
        :param kwargs_data:
        :param arrow_size:
        :param cmap_string:
        """
        self._kwargs_data = kwargs_data
        if isinstance(cmap_string, str) or isinstance(cmap_string, unicode):
            cmap = plt.get_cmap(cmap_string)
        else:
            cmap = cmap_string
        cmap.set_bad(color='k', alpha=1.)
        cmap.set_under('k')
        self._cmap = cmap
        self._arrow_size = arrow_size
        data = Data(kwargs_data)
        self._coords = data._coords
        nx, ny = np.shape(kwargs_data['image_data'])
        Mpix2coord = kwargs_data['transform_pix2angle']
        self._Mpix2coord = Mpix2coord

        self._deltaPix = self._coords.pixel_size
        self._frame_size = self._deltaPix * nx

        x_grid, y_grid = data.coordinates
        self._x_grid = util.image2array(x_grid)
        self._y_grid = util.image2array(y_grid)

        self._imageModel = class_creator.create_image_model(kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model)
        self._analysis = LensAnalysis(kwargs_model)
        self._lensModel = LensModel(lens_model_list=kwargs_model.get('lens_model_list', []),
                                 z_source=kwargs_model.get('z_source', None),
                                 redshift_list=kwargs_model.get('redshift_list', None),
                                 multi_plane=kwargs_model.get('multi_plane', False))
        self._lensModelExt = LensModelExtensions(self._lensModel)
        model, error_map, cov_param, param = self._imageModel.image_linear_solve(kwargs_lens, kwargs_source,
                                                                                 kwargs_lens_light, kwargs_ps, inv_bool=True)
        self._kwargs_lens = kwargs_lens
        self._kwargs_source = kwargs_source
        self._kwargs_lens_light = kwargs_lens_light
        self._kwargs_else = kwargs_ps
        self._model = model
        self._data = kwargs_data['image_data']
        self._cov_param = cov_param
        self._norm_residuals = self._imageModel.reduced_residuals(model, error_map=error_map)
        self._reduced_x2 = self._imageModel.reduced_chi2(model, error_map=error_map)
        log_model = np.log10(model)
        log_model[np.isnan(log_model)] = -5
        self._v_min_default = max(np.min(log_model), -5)
        self._v_max_default = min(np.max(log_model), 10)
        print("reduced chi^2 = ", self._reduced_x2)

    def _critical_curves(self):
        if not hasattr(self, '_ra_crit_list') or not hasattr(self, '_dec_crit_list'):
            self._ra_crit_list, self._dec_crit_list = self._lensModelExt.critical_curve_tiling(self._kwargs_lens,
                                                                                        compute_window=self._frame_size,
                                                                                        start_scale=self._deltaPix / 5.,
                                                                                        max_order=10)
        return self._ra_crit_list, self._dec_crit_list

    def _caustics(self):
        if not hasattr(self, '_ra_caustic_list') or not hasattr(self, '_dec_caustic_list'):
            ra_crit_list, dec_crit_list = self._critical_curves()
            self._ra_caustic_list, self._dec_caustic_list = self._lensModel.ray_shooting(ra_crit_list,
                                                                                     dec_crit_list, self._kwargs_lens)
        return self._ra_caustic_list, self._dec_caustic_list

    def data_plot(self, ax, v_min=None, v_max=None, text='Observed'):
        """

        :param ax:
        :return:
        """
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(self._data), origin='lower',
                        extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap, vmin=v_min, vmax=v_max)  # , vmin=0, vmax=2

        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)

        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax, self._frame_size, text=text, color="w", backgroundcolor='k')
        coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax, orientation='vertical')
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        return ax

    def model_plot(self, ax, v_min=None, v_max=None, image_names=False):
        """

        :param ax:
        :param model:
        :param v_min:
        :param v_max:
        :return:
        """
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(self._model), origin='lower', vmin=v_min, vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax, self._frame_size, text="Reconstructed", color="w", backgroundcolor='k')
        coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)

        #plot_line_set(ax, self._coords, self._ra_caustic_list, self._dec_caustic_list, color='b')
        #plot_line_set(ax, self._coords, self._ra_crit_list, self._dec_crit_list, color='r')
        if image_names is True:
            ra_image, dec_image = self._imageModel.image_positions(self._kwargs_else, self._kwargs_lens)
            image_position_plot(ax, self._coords, ra_image, dec_image)
        #source_position_plot(ax, self._coords, self._kwargs_source)

    def convergence_plot(self, ax, v_min=None, v_max=None):
        """

        :param x_grid:
        :param y_grid:
        :param kwargs_lens:
        :param kwargs_else:
        :return:
        """
        kappa_result = util.array2image(self._lensModel.kappa(self._x_grid, self._y_grid, self._kwargs_lens))
        im = ax.matshow(np.log10(kappa_result), origin='lower',
                        extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap, vmin=v_min, vmax=v_max)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='w')
        coordinate_arrows(ax, self._frame_size, self._coords, color='w', arrow_size=self._arrow_size)
        text_description(ax, self._frame_size, text="Convergence", color="w", backgroundcolor='k', flipped=False)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ $\kappa$', fontsize=15)
        return ax

    def normalized_residual_plot(self, ax, v_min=-6, v_max=6, **kwargs):
        """

        :param ax:
        :param v_min:
        :param v_max:
        :param kwargs: kwargs to send to matplotlib.pyplot.matshow()
        :return:
        """
        if not 'cmap' in kwargs:
            kwargs['cmap'] = 'bwr'
        im = ax.matshow(self._norm_residuals, vmin=v_min, vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size], origin='lower', **kwargs)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        text_description(ax, self._frame_size, text="Normalized Residuals", color="k", backgroundcolor='w')
        coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'(f$_{model}$-f$_{data}$)/$\sigma$', fontsize=15)
        return ax

    def absolute_residual_plot(self, ax, v_min=-1, v_max=1):
        """

        :param ax:
        :param residuals:
        :return:
        """
        im = ax.matshow(self._model - self._data, vmin=v_min, vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size], cmap='bwr', origin='lower')
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        text_description(ax, self._frame_size, text="Residuals", color="k", backgroundcolor='w')
        coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'(f$_{model}$-f$_{data}$)', fontsize=15)
        return ax

    def source_plot(self, ax, numPix, deltaPix_source, source_sigma=0.001, convolution=False, v_min=None, v_max=None, with_caustics=False):
        """

        :param ax:
        :param coords_source:
        :param source:
        :return:
        """
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        d_s = numPix * deltaPix_source
        x_grid_source, y_grid_source = util.make_grid_transformed(numPix,
                                                                  self._Mpix2coord * deltaPix_source / self._deltaPix)
        if len(self._kwargs_source) > 0:
            x_center = self._kwargs_source[0]['center_x']
            y_center = self._kwargs_source[0]['center_y']
            x_grid_source += x_center
            y_grid_source += y_center
        coords_source = Coordinates(self._Mpix2coord * deltaPix_source / self._deltaPix, ra_at_xy_0=x_grid_source[0],
                                    dec_at_xy_0=y_grid_source[0])

        source = self._imageModel.SourceModel.surface_brightness(x_grid_source, y_grid_source, self._kwargs_source)
        source = util.array2image(source)
        if convolution is True:
            source = ndimage.filters.gaussian_filter(source, sigma=source_sigma / deltaPix_source, mode='nearest',
                                                      truncate=20)

        im = ax.matshow(np.log10(source), origin='lower', extent=[0, d_s, 0, d_s],
                        cmap=self._cmap, vmin=v_min, vmax=v_max)  # source
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        if with_caustics:
            ra_caustic_list, dec_caustic_list = self._caustics()
            plot_line_set(ax, coords_source, ra_caustic_list, dec_caustic_list, color='b')
        scale_bar(ax, d_s, dist=0.1, text='0.1"', color='w', flipped=False)
        coordinate_arrows(ax, d_s, coords_source, arrow_size=self._arrow_size, color='w')
        text_description(ax, d_s, text="Reconstructed source", color="w", backgroundcolor='k', flipped=False)
        source_position_plot(ax, coords_source, self._kwargs_source)
        return ax

    def error_map_source_plot(self, ax, numPix, deltaPix_source, v_min=None, v_max=None, with_caustics=False):
        x_grid_source, y_grid_source = util.make_grid_transformed(numPix,
                                                                  self._Mpix2coord * deltaPix_source / self._deltaPix)
        x_center = self._kwargs_source[0]['center_x']
        y_center = self._kwargs_source[0]['center_y']
        x_grid_source += x_center
        y_grid_source += y_center
        coords_source = Coordinates(self._Mpix2coord * deltaPix_source / self._deltaPix, ra_at_xy_0=x_grid_source[0],
                                    dec_at_xy_0=y_grid_source[0])
        error_map_source = self._analysis.error_map_source(self._kwargs_source, x_grid_source, y_grid_source, self._cov_param)
        error_map_source = util.array2image(error_map_source)
        d_s = numPix * deltaPix_source
        im = ax.matshow(error_map_source, origin='lower', extent=[0, d_s, 0, d_s],
                        cmap=self._cmap, vmin=v_min, vmax=v_max)  # source
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'error variance', fontsize=15)
        if with_caustics:
            ra_caustic_list, dec_caustic_list = self._caustics()
            plot_line_set(ax, coords_source, ra_caustic_list, dec_caustic_list, color='b')
        scale_bar(ax, d_s, dist=0.1, text='0.1"', color='w', flipped=False)
        coordinate_arrows(ax, d_s, coords_source, arrow_size=self._arrow_size, color='w')
        text_description(ax, d_s, text="Error map in source", color="w", backgroundcolor='k', flipped=False)
        source_position_plot(ax, coords_source, self._kwargs_source)
        return ax

    def magnification_plot(self, ax, v_min=-10, v_max=10, with_caustics=False, image_name_list=None, **kwargs):
        """

        :param ax:
        :param v_min:
        :param v_max:
        :param with_caustics:
        :param kwargs: kwargs to send to matplotlib.pyplot.matshow()
        :return:
        """
        if not 'cmap' in kwargs:
            kwargs['cmap'] = self._cmap
        if not 'alpha' in kwargs:
            kwargs['alpha'] = 0.5
        mag_result = util.array2image(self._lensModel.magnification(self._x_grid, self._y_grid, self._kwargs_lens))
        im = ax.matshow(mag_result, origin='lower', extent=[0, self._frame_size, 0, self._frame_size],
                        vmin=v_min, vmax=v_max, **kwargs)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size)
        text_description(ax, self._frame_size, text="Magnification model", color="k", backgroundcolor='w')
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'det(A$^{-1}$)', fontsize=15)
        if with_caustics:
            ra_crit_list, dec_crit_list = self._critical_curves()
            ra_caustic_list, dec_caustic_list = self._caustics()
            plot_line_set(ax, self._coords, ra_caustic_list, dec_caustic_list, color='b')
            plot_line_set(ax, self._coords, ra_crit_list, dec_crit_list, color='r')
        ra_image, dec_image = self._imageModel.image_positions(self._kwargs_else, self._kwargs_lens)
        image_position_plot(ax, self._coords, ra_image, dec_image, color='k', image_name_list=image_name_list)
        source_position_plot(ax, self._coords, self._kwargs_source)
        return ax

    def deflection_plot(self, ax, v_min=None, v_max=None, axis=0, with_caustics=False, image_name_list=None):
        """

        :param kwargs_lens:
        :param kwargs_else:
        :return:
        """

        alpha1, alpha2 = self._lensModel.alpha(self._x_grid, self._y_grid, self._kwargs_lens)
        alpha1 = util.array2image(alpha1)
        alpha2 = util.array2image(alpha2)
        if axis == 0:
            alpha = alpha1
        else:
            alpha = alpha2
        im = ax.matshow(alpha, origin='lower', extent=[0, self._frame_size, 0, self._frame_size],
                        vmin=v_min, vmax=v_max, cmap=self._cmap, alpha=0.5)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"', color='k')
        coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size)
        text_description(ax, self._frame_size, text="Deflection model", color="k", backgroundcolor='w')
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'arcsec', fontsize=15)
        if with_caustics:
            ra_crit_list, dec_crit_list = self._critical_curves()
            ra_caustic_list, dec_caustic_list = self._caustics()
            plot_line_set(ax, self._coords, ra_caustic_list, dec_caustic_list, color='b')
            plot_line_set(ax, self._coords, ra_crit_list, dec_crit_list, color='r')
        ra_image, dec_image = self._imageModel.image_positions(self._kwargs_else, self._kwargs_lens)
        image_position_plot(ax, self._coords, ra_image, dec_image, image_name_list=image_name_list)
        source_position_plot(ax, self._coords, self._kwargs_source)
        return ax

    def decomposition_plot(self, ax, text='Reconstructed', v_min=None, v_max=None, unconvolved=False, point_source_add=False, source_add=False, lens_light_add=False, **kwargs):
        """

        :param ax:
        :param text:
        :param v_min:
        :param v_max:
        :param unconvolved:
        :param point_source_add:
        :param source_add:
        :param lens_light_add:
        :param kwargs: kwargs to send matplotlib.pyplot.matshow()
        :return:
        """
        model = self._imageModel.image(self._kwargs_lens, self._kwargs_source, self._kwargs_lens_light,
                                          self._kwargs_else, unconvolved=unconvolved, source_add=source_add,
                                          lens_light_add=lens_light_add, point_source_add=point_source_add)
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        if not 'cmap' in kwargs:
            kwargs['cmap'] = self._cmap
        im = ax.matshow(np.log10(model), origin='lower', vmin=v_min, vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size], **kwargs)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax, self._frame_size, text=text, color="w", backgroundcolor='k')
        coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        return ax

    def subtract_from_data_plot(self, ax, text='Subtracted', v_min=None, v_max=None, point_source_add=False, source_add=False, lens_light_add=False):
        model = self._imageModel.image(self._kwargs_lens, self._kwargs_source, self._kwargs_lens_light,
                                          self._kwargs_else, unconvolved=False, source_add=source_add,
                                          lens_light_add=lens_light_add, point_source_add=point_source_add)
        if v_min is None:
            v_min = self._v_min_default
        if v_max is None:
            v_max = self._v_max_default
        im = ax.matshow(np.log10(self._data - model), origin='lower', vmin=v_min, vmax=v_max,
                        extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.autoscale(False)
        scale_bar(ax, self._frame_size, dist=1, text='1"')
        text_description(ax, self._frame_size, text=text, color="w", backgroundcolor='k')
        coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = plt.colorbar(im, cax=cax)
        cb.set_label(r'log$_{10}$ flux', fontsize=15)
        return ax

    def plot_main(self):
        """
        print the main plots together in a joint frame

        :return:
        """

        f, axes = plt.subplots(2, 3, figsize=(16, 8))
        self.data_plot(ax=axes[0, 0])
        self.model_plot(ax=axes[0, 1])
        self.normalized_residual_plot(ax=axes[0, 2], v_min=-6, v_max=6)
        self.source_plot(ax=axes[1, 0], convolution=False, deltaPix_source=0.01, numPix=100)
        self.convergence_plot(ax=axes[1, 1], v_max=1)
        self.magnification_plot(ax=axes[1, 2])
        f.tight_layout()
        f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05)
        return f, axes

    def plot_separate(self):
        """
        plot the different model components separately

        :return:
        """
        f, axes = plt.subplots(2, 3, figsize=(16, 8))

        self.decomposition_plot(ax=axes[0, 0], text='Lens light', lens_light_add=True, unconvolved=True)
        self.decomposition_plot(ax=axes[1, 0], text='Lens light convolved', lens_light_add=True)
        self.decomposition_plot(ax=axes[0, 1], text='Source light', source_add=True, unconvolved=True)
        self.decomposition_plot(ax=axes[1, 1], text='Source light convolved', source_add=True)
        self.decomposition_plot(ax=axes[0, 2], text='All components', source_add=True, lens_light_add=True,
                                    unconvolved=True)
        self.decomposition_plot(ax=axes[1, 2], text='All components convolved', source_add=True,
                                    lens_light_add=True, point_source_add=True)
        f.tight_layout()
        f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05)
        return f, axes

    def plot_subtract_from_data_all(self):
        """
        subtract model components from data

        :return:
        """
        f, axes = plt.subplots(2, 3, figsize=(16, 8))

        self.subtract_from_data_plot(ax=axes[0, 0], text='Data')
        self.subtract_from_data_plot(ax=axes[0, 1], text='Data - Point Source', point_source_add=True)
        self.subtract_from_data_plot(ax=axes[0, 2], text='Data - Lens Light', lens_light_add=True)
        self.subtract_from_data_plot(ax=axes[1, 0], text='Data - Source Light', source_add=True)
        self.subtract_from_data_plot(ax=axes[1, 1], text='Data - Source Light - Point Source', source_add=True,
                                         point_source_add=True)
        self.subtract_from_data_plot(ax=axes[1, 2], text='Data - Lens Light - Point Source', lens_light_add=True,
                                         point_source_add=True)
        f.tight_layout()
        f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05)
        return f, axes
Пример #28
0
class LensProp(object):
    """
    this class contains routines to compute time delays, magnification ratios, line of sight velocity dispersions etc
    for a given lens model
    """
    def __init__(self, z_lens, z_source, kwargs_model, cosmo=None):
        """

        :param z_lens: redshift of lens
        :param z_source: redshift of source
        :param kwargs_model: model keyword arguments
        :param cosmo: astropy.cosmology instance
        """
        self.z_d = z_lens
        self.z_s = z_source
        self.lensCosmo = LensCosmo(z_lens, z_source, cosmo=cosmo)
        self.lens_analysis = LensAnalysis(kwargs_model)
        self._lensModelExt = LensModelExtensions(self.lens_analysis.LensModel)
        self.kwargs_options = kwargs_model
        self._kwargs_cosmo = {
            'D_d': self.lensCosmo.D_d,
            'D_s': self.lensCosmo.D_s,
            'D_ds': self.lensCosmo.D_ds
        }

    def time_delays(self, kwargs_lens, kwargs_ps, kappa_ext=0):
        """
        predicts the time delays of the image positions

        :param kwargs_lens: lens model parameters
        :param kwargs_ps: point source parameters
        :param kappa_ext: external convergence (optional)
        :return: time delays at image positions for the fixed cosmology
        """
        fermat_pot = self.lens_analysis.fermat_potential(
            kwargs_lens, kwargs_ps)
        time_delay = self.lensCosmo.time_delay_units(fermat_pot, kappa_ext)
        return time_delay

    def velocity_dispersion(self,
                            kwargs_lens,
                            r_eff,
                            R_slit,
                            dR_slit,
                            psf_fwhm,
                            aniso_param=1,
                            psf_type='GAUSSIAN',
                            moffat_beta=2.6,
                            num_evaluate=1000,
                            kappa_ext=0):
        """
        computes the LOS velocity dispersion of the lens within a slit of size R_slit x dR_slit and seeing psf_fwhm.
        The assumptions are a Hernquist light profile and the spherical power-law lens model at the first position.

        Further information can be found in the AnalyticKinematics() class.

        :param kwargs_lens: lens model parameters
        :param kwargs_lens_light: deflector light parameters
        :param aniso_param: scaled r_ani with respect to the half light radius
        :param r_eff: half light radius, if not provided, will be computed from the lens light model
        :param R_slit: width of the slit
        :param dR_slit: length of the slit
        :param psf_fwhm: full width at half maximum of the seeing (Gaussian form)
        :param psf_type: string, point spread functino type, current support for 'GAUSSIAN' and 'MOFFAT'
        :param moffat_beta: float, beta parameter of Moffat profile
        :param num_evaluate: number of spectral rendering of the light distribution that end up on the slit
        :param kappa_ext: external convergence not accounted in the lens models
        :return: velocity dispersion in units [km/s]
        """
        gamma = kwargs_lens[0]['gamma']
        theta_E = kwargs_lens[0]['theta_E']
        r_ani = aniso_param * r_eff
        analytic_kinematics = AnalyticKinematics(fwhm=psf_fwhm,
                                                 moffat_beta=moffat_beta,
                                                 psf_type=psf_type,
                                                 **self._kwargs_cosmo)
        sigma = analytic_kinematics.vel_disp(gamma,
                                             theta_E,
                                             r_eff,
                                             r_ani,
                                             R_slit,
                                             dR_slit,
                                             rendering_number=num_evaluate)
        sigma *= np.sqrt(1 - kappa_ext)
        return sigma

    def velocity_dispersion_numerical(self,
                                      kwargs_lens,
                                      kwargs_lens_light,
                                      kwargs_anisotropy,
                                      kwargs_aperture,
                                      psf_fwhm,
                                      aperture_type,
                                      anisotropy_model,
                                      r_eff,
                                      psf_type='GAUSSIAN',
                                      moffat_beta=2.6,
                                      kwargs_numerics={},
                                      MGE_light=False,
                                      MGE_mass=False,
                                      lens_model_kinematics_bool=None,
                                      light_model_kinematics_bool=None,
                                      Hernquist_approx=False,
                                      kappa_ext=0):
        """
        Computes the LOS velocity dispersion of the deflector galaxy with arbitrary combinations of light and mass models.
        For a detailed description, visit the description of the Galkin() class.
        Additionaly to executing the Galkin routine, it has an optional Multi-Gaussian-Expansion decomposition of lens
        and light models that do not have a three-dimensional distribution built in, such as Sersic profiles etc.

        The center of all the lens and lens light models that are part of the kinematic estimate must be centered on the
        same point.

        :param kwargs_lens: lens model parameters
        :param kwargs_lens_light: lens light parameters
        :param kwargs_anisotropy: anisotropy parameters (see Galkin module)
        :param kwargs_aperture: aperture parameters (see Galkin module)
        :param psf_fwhm: full width at half maximum of the seeing (Gaussian form)
        :param psf_type: string, point spread functino type, current support for 'GAUSSIAN' and 'MOFFAT'
        :param moffat_beta: float, beta parameter of Moffat profile
        :param aperture_type: type of aperture (see Galkin module
        :param anisotropy_model: stellar anisotropy model (see Galkin module)
        :param r_eff: a rough estimate of the half light radius of the lens light in case of computing the MGE of the
         light profile
        :param kwargs_numerics: keyword arguments that contain numerical options (see Galkin module)
        :param MGE_light: bool, if true performs the MGE for the light distribution
        :param MGE_mass: bool, if true performs the MGE for the mass distribution
        :param lens_model_kinematics_bool: bool list of length of the lens model. Only takes a subset of all the models
            as part of the kinematics computation (can be used to ignore substructure, shear etc that do not describe the
            main deflector potential
        :param light_model_kinematics_bool: bool list of length of the light model. Only takes a subset of all the models
            as part of the kinematics computation (can be used to ignore light components that do not describe the main
            deflector
        :param Hernquist_approx: bool, if True, uses a Hernquist light profile matched to the half light radius of the deflector light profile to compute the kinematics
        :param kappa_ext: external convergence not accounted in the lens models
        :return: LOS velocity dispersion [km/s]
        """

        kwargs_cosmo = {
            'D_d': self.lensCosmo.D_d,
            'D_s': self.lensCosmo.D_s,
            'D_ds': self.lensCosmo.D_ds
        }

        mass_profile_list, kwargs_profile, light_profile_list, kwargs_light = self.kinematic_profiles(
            kwargs_lens,
            kwargs_lens_light,
            r_eff=r_eff,
            MGE_light=MGE_light,
            MGE_mass=MGE_mass,
            lens_model_kinematics_bool=lens_model_kinematics_bool,
            light_model_kinematics_bool=light_model_kinematics_bool,
            Hernquist_approx=Hernquist_approx)
        galkin = Galkin(mass_profile_list,
                        light_profile_list,
                        aperture_type=aperture_type,
                        anisotropy_model=anisotropy_model,
                        fwhm=psf_fwhm,
                        psf_type=psf_type,
                        moffat_beta=moffat_beta,
                        kwargs_cosmo=kwargs_cosmo,
                        **kwargs_numerics)
        sigma = galkin.vel_disp(kwargs_profile, kwargs_light,
                                kwargs_anisotropy, kwargs_aperture)
        sigma *= np.sqrt(1 - kappa_ext)
        return sigma

    def kinematic_profiles(self,
                           kwargs_lens,
                           kwargs_lens_light,
                           r_eff,
                           MGE_light=False,
                           MGE_mass=False,
                           lens_model_kinematics_bool=None,
                           light_model_kinematics_bool=None,
                           Hernquist_approx=False):
        """
        translates the lenstronomy lens and mass profiles into a (sub) set of profiles that are compatible with the GalKin module to compute the kinematics thereof.

        :param kwargs_lens: lens model parameters
        :param kwargs_lens_light: lens light parameters
        :param r_eff: a rough estimate of the half light radius of the lens light in case of computing the MGE of the
         light profile
        :param MGE_light: bool, if true performs the MGE for the light distribution
        :param MGE_mass: bool, if true performs the MGE for the mass distribution
        :param lens_model_kinematics_bool: bool list of length of the lens model. Only takes a subset of all the models
            as part of the kinematics computation (can be used to ignore substructure, shear etc that do not describe the
            main deflector potential
        :param light_model_kinematics_bool: bool list of length of the light model. Only takes a subset of all the models
            as part of the kinematics computation (can be used to ignore light components that do not describe the main
            deflector
        :param Hernquist_approx: bool, if True, uses a Hernquist light profile matched to the half light radius of the deflector light profile to compute the kinematics
        :return: mass_profile_list, kwargs_profile, light_profile_list, kwargs_light
        """

        mass_profile_list = []
        kwargs_profile = []
        if lens_model_kinematics_bool is None:
            lens_model_kinematics_bool = [True] * len(kwargs_lens)
        for i, lens_model in enumerate(self.kwargs_options['lens_model_list']):
            if lens_model_kinematics_bool[i] is True:
                mass_profile_list.append(lens_model)
                if lens_model in ['INTERPOL', 'INTERPOL_SCLAED']:
                    center_x, center_y = self._lensModelExt.lens_center(
                        kwargs_lens, k=i)
                    kwargs_lens_i = copy.deepcopy(kwargs_lens[i])
                    kwargs_lens_i['grid_interp_x'] -= center_x
                    kwargs_lens_i['grid_interp_y'] -= center_y
                else:
                    kwargs_lens_i = {
                        k: v
                        for k, v in kwargs_lens[i].items()
                        if not k in ['center_x', 'center_y']
                    }
                kwargs_profile.append(kwargs_lens_i)

        if MGE_mass is True:
            lensModel = LensModel(lens_model_list=mass_profile_list)
            massModel = LensModelExtensions(lensModel)
            theta_E = massModel.effective_einstein_radius(kwargs_profile)
            r_array = np.logspace(-4, 2, 200) * theta_E
            mass_r = lensModel.kappa(r_array, np.zeros_like(r_array),
                                     kwargs_profile)
            amps, sigmas, norm = mge.mge_1d(r_array, mass_r, N=20)
            mass_profile_list = ['MULTI_GAUSSIAN_KAPPA']
            kwargs_profile = [{'amp': amps, 'sigma': sigmas}]

        light_profile_list = []
        kwargs_light = []
        if light_model_kinematics_bool is None:
            light_model_kinematics_bool = [True] * len(kwargs_lens_light)
        for i, light_model in enumerate(
                self.kwargs_options['lens_light_model_list']):
            if light_model_kinematics_bool[i]:
                light_profile_list.append(light_model)
                kwargs_lens_light_i = {
                    k: v
                    for k, v in kwargs_lens_light[i].items()
                    if not k in ['center_x', 'center_y']
                }
                if 'e1' in kwargs_lens_light_i:
                    kwargs_lens_light_i['e1'] = 0
                    kwargs_lens_light_i['e2'] = 0
                kwargs_light.append(kwargs_lens_light_i)
        if Hernquist_approx is True:
            light_profile_list = ['HERNQUIST']
            kwargs_light = [{'Rs': r_eff, 'amp': 1.}]
        else:
            if MGE_light is True:
                lightModel = LightModel(light_profile_list)
                r_array = np.logspace(-3, 2, 200) * r_eff * 2
                flux_r = lightModel.surface_brightness(r_array, 0,
                                                       kwargs_light)
                amps, sigmas, norm = mge.mge_1d(r_array, flux_r, N=20)
                light_profile_list = ['MULTI_GAUSSIAN']
                kwargs_light = [{'amp': amps, 'sigma': sigmas}]
        return mass_profile_list, kwargs_profile, light_profile_list, kwargs_light

    def angular_diameter_relations(self, sigma_v_model, sigma_v, kappa_ext,
                                   D_dt_model):
        """

        :return:
        """
        sigma_v2_model = sigma_v_model**2
        Ds_Dds = sigma_v**2 / (1 - kappa_ext) / (
            sigma_v2_model * self.lensCosmo.D_ds / self.lensCosmo.D_s)
        D_d = D_dt_model / (1 + self.lensCosmo.z_lens) / Ds_Dds / (1 -
                                                                   kappa_ext)
        return D_d, Ds_Dds

    def angular_distances(self, sigma_v_measured, time_delay_measured,
                          kappa_ext, sigma_v_modeled, fermat_pot):
        """

        :param sigma_v_measured: velocity dispersion measured [km/s]
        :param time_delay_measured: time delay measured [d]
        :param kappa_ext: external convergence estimated []
        :param sigma_v_modeled: lens model velocity dispersion with default cosmology and without external convergence [km/s]
        :param fermat_pot: fermat potential of lens model, modulo MSD of kappa_ext [arcsec^2]
        :return: D_d and D_d*D_s/D_ds, units in Mpc physical
        """

        Ds_Dds = (sigma_v_measured / float(sigma_v_modeled))**2 / (
            self.lensCosmo.D_ds / self.lensCosmo.D_s) / (1. - kappa_ext)
        DdDs_Dds = 1. / (1 + self.lensCosmo.z_lens) / (1. - kappa_ext) * (
            const.c * time_delay_measured *
            const.day_s) / (fermat_pot * const.arcsec**2) / const.Mpc
        return Ds_Dds, DdDs_Dds
Пример #29
0
# import the parameter handling class #
from lenstronomy.Sampling.parameters import Param
# make instance of parameter class with given model options, constraints and fixed parameters #

param = Param(kwargs_model,
              fixed_lens,
              kwargs_fixed_ps=fixed_ps,
              kwargs_fixed_cosmo=fixed_cosmo,
              kwargs_lens_init=lens_result,
              **kwargs_constraints)
# the number of non-linear parameters and their names #
num_param, param_list = param.num_param()

from lenstronomy.Analysis.lens_analysis import LensAnalysis
lensAnalysis = LensAnalysis(kwargs_model)

mcmc_new_list = []
labels_new = [
    r"$\gamma$", r"$\phi_{ext}$", r"$\gamma_{ext}$", r"$D_{\Delta t}$"
]
for i in range(len(samples_mcmc)):
    # transform the parameter position of the MCMC chain in a lenstronomy convention with keyword arguments #
    kwargs_lens_out, kwargs_light_source_out, kwargs_light_lens_out, kwargs_ps_out, kwargs_cosmo = param.args2kwargs(
        samples_mcmc[i])
    D_dt = kwargs_cosmo['D_dt']
    gamma = kwargs_lens_out[0]['gamma']
    phi_ext, gamma_ext = lensAnalysis._lensModelExtensions.external_shear(
        kwargs_lens_out)
    mcmc_new_list.append([gamma, phi_ext, gamma_ext, D_dt])
Пример #30
0
class LensProp(object):
    """
    this class contains routines to compute time delays, magnification ratios, line of sight velocity dispersions etc for a given lens model
    """
    def __init__(self, z_lens, z_source, kwargs_model, cosmo=None):
        self.z_d = z_lens
        self.z_s = z_source
        self.lensCosmo = LensCosmo(z_lens, z_source, cosmo=cosmo)
        self.lens_analysis = LensAnalysis(kwargs_model)
        self.lens_model = LensModelExtensions(
            lens_model_list=kwargs_model['lens_model_list'])
        self.kwargs_options = kwargs_model
        kwargs_cosmo = {
            'D_d': self.lensCosmo.D_d,
            'D_s': self.lensCosmo.D_s,
            'D_ds': self.lensCosmo.D_ds
        }
        self.dispersion = Velocity_dispersion(kwargs_cosmo=kwargs_cosmo)

    def time_delays(self, kwargs_lens, kwargs_ps, kappa_ext=0):
        fermat_pot = self.lens_analysis.fermat_potential(
            kwargs_lens, kwargs_ps)
        time_delay = self.lensCosmo.time_delay_units(fermat_pot, kappa_ext)
        return time_delay

    def velocity_dispersion(self,
                            kwargs_lens,
                            kwargs_lens_light,
                            aniso_param=1,
                            r_eff=None,
                            R_slit=0.81,
                            dR_slit=0.1,
                            psf_fwhm=0.7,
                            num_evaluate=100):
        gamma = kwargs_lens[0]['gamma']
        if r_eff is None:
            r_eff = self.lens_analysis.half_light_radius_lens(
                kwargs_lens_light)
        theta_E = kwargs_lens[0]['theta_E']
        if self.dispersion.beta_const is False:
            aniso_param *= r_eff
        sigma2 = self.dispersion.vel_disp(gamma,
                                          theta_E,
                                          r_eff,
                                          aniso_param,
                                          R_slit,
                                          dR_slit,
                                          FWHM=psf_fwhm,
                                          num=num_evaluate)
        return sigma2

    def velocity_disperson_numerical(self,
                                     kwargs_lens,
                                     kwargs_lens_light,
                                     kwargs_anisotropy,
                                     kwargs_aperture,
                                     psf_fwhm,
                                     aperture_type,
                                     anisotropy_model,
                                     r_eff=1.,
                                     kwargs_numerics={},
                                     MGE_light=False,
                                     MGE_mass=False):
        """

        :param kwargs_lens:
        :param kwargs_lens_light:
        :param kwargs_anisotropy:
        :param kwargs_aperature:
        :return:
        """
        kwargs_cosmo = {
            'D_d': self.lensCosmo.D_d,
            'D_s': self.lensCosmo.D_s,
            'D_ds': self.lensCosmo.D_ds
        }
        mass_profile_list = []
        kwargs_profile = []
        lens_model_internal_bool = self.kwargs_options.get(
            'lens_model_deflector_bool', [True] * len(kwargs_lens))
        for i, lens_model in enumerate(self.kwargs_options['lens_model_list']):
            if lens_model_internal_bool[i]:
                mass_profile_list.append(lens_model)
                kwargs_lens_i = {
                    k: v
                    for k, v in kwargs_lens[i].items()
                    if not k in ['center_x', 'center_y']
                }
                kwargs_profile.append(kwargs_lens_i)

        if MGE_mass is True:
            massModel = LensModelExtensions(lens_model_list=mass_profile_list)
            theta_E = massModel.effective_einstein_radius(kwargs_lens)
            r_array = np.logspace(-4, 2, 200) * theta_E
            mass_r = massModel.kappa(r_array, 0, kwargs_profile)
            amps, sigmas, norm = mge.mge_1d(r_array, mass_r, N=20)
            mass_profile_list = ['MULTI_GAUSSIAN_KAPPA']
            kwargs_profile = [{'amp': amps, 'sigma': sigmas}]

        light_profile_list = []
        kwargs_light = []
        lens_light_model_internal_bool = self.kwargs_options.get(
            'light_model_deflector_bool', [True] * len(kwargs_lens_light))
        for i, light_model in enumerate(
                self.kwargs_options['lens_light_model_list']):
            if lens_light_model_internal_bool[i]:
                light_profile_list.append(light_model)
                kwargs_Lens_light_i = {
                    k: v
                    for k, v in kwargs_lens_light[i].items()
                    if not k in ['center_x', 'center_y']
                }
                if 'q' in kwargs_Lens_light_i:
                    kwargs_Lens_light_i['q'] = 1
                kwargs_light.append(kwargs_Lens_light_i)

        if MGE_light is True:
            lightModel = LightModel(light_profile_list)
            r_array = np.logspace(-3, 2, 200) * r_eff * 2
            flux_r = lightModel.surface_brightness(r_array, 0, kwargs_light)
            amps, sigmas, norm = mge.mge_1d(r_array, flux_r, N=20)
            light_profile_list = ['MULTI_GAUSSIAN']
            kwargs_light = [{'amp': amps, 'sigma': sigmas}]

        galkin = Galkin(mass_profile_list,
                        light_profile_list,
                        aperture_type=aperture_type,
                        anisotropy_model=anisotropy_model,
                        fwhm=psf_fwhm,
                        kwargs_cosmo=kwargs_cosmo,
                        kwargs_numerics=kwargs_numerics)
        sigma_v = galkin.vel_disp(kwargs_profile,
                                  kwargs_light,
                                  kwargs_anisotropy,
                                  kwargs_aperture,
                                  r_eff=r_eff)
        return sigma_v

    def angular_diameter_relations(self, sigma_v_model, sigma_v, kappa_ext,
                                   D_dt_model, z_d):
        """

        :return:
        """
        sigma_v2_model = sigma_v_model**2
        Ds_Dds = sigma_v**2 / (1 - kappa_ext) / (
            sigma_v2_model * self.lensCosmo.D_ds / self.lensCosmo.D_s)
        D_d = D_dt_model / (1 + z_d) / Ds_Dds / (1 - kappa_ext)
        return D_d, Ds_Dds

    def angular_distances(self, sigma_v_measured, time_delay_measured,
                          kappa_ext, sigma_v_modeled, fermat_pot):
        """

        :param sigma_v_measured: velocity dispersion measured [km/s]
        :param time_delay_measured: time delay measured [d]
        :param kappa_ext: external convergence estimated []
        :param sigma_v_modeled: lens model velocity dispersion with default cosmology and without external convergence [km/s]
        :param fermat_pot: fermat potential of lens model, modulo MSD of kappa_ext [arcsec^2]
        :return: D_d and D_d*D_s/D_ds, units in Mpc physical
        """

        Ds_Dds = (sigma_v_measured / sigma_v_modeled)**2 / (
            self.lensCosmo.D_ds / self.lensCosmo.D_s) / (1 - kappa_ext)
        DdDs_Dds = 1. / (1 + self.lensCosmo.z_lens) / (1 - kappa_ext) * (
            const.c * time_delay_measured *
            const.day_s) / (fermat_pot * const.arcsec**2) / const.Mpc
        return Ds_Dds, DdDs_Dds