Esempio n. 1
0
class TestPointSource(object):

    def setup(self):
        lensModel = LensModel(lens_model_list=['SPEP'])
        solver = LensEquationSolver(lensModel=lensModel)
        self.kwargs_lens = [{'theta_E': 1., 'center_x': 0, 'center_y': 0, 'q': 0.7, 'phi_G': 0, 'gamma': 2}]
        self.sourcePos_x, self.sourcePos_y = 0.01, -0.01
        self.x_pos, self.y_pos = solver.image_position_from_source(sourcePos_x=self.sourcePos_x,
                                                                   sourcePos_y=self.sourcePos_y, kwargs_lens=self.kwargs_lens)
        self.PointSource = PointSource(point_source_type_list=['LENSED_POSITION', 'UNLENSED', 'SOURCE_POSITION', 'NONE'],
                                       lensModel=lensModel, fixed_magnification_list=[False]*4, additional_images_list=[False]*4)
        self.kwargs_ps = [{'ra_image': self.x_pos, 'dec_image': self.y_pos, 'point_amp': np.ones_like(self.x_pos)},
                          {'ra_image': [1.], 'dec_image': [1.], 'point_amp': [10]},
                          {'ra_source': self.sourcePos_x, 'dec_source': self.sourcePos_y, 'point_amp': np.ones_like(self.x_pos)}, {}]

    def test_image_position(self):
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], self.x_pos[0], decimal=8)
        npt.assert_almost_equal(x_image_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_image_list[2][0], self.x_pos[0], decimal=8)

    def test_source_position(self):
        x_source_list, y_source_list = self.PointSource.source_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_source_list[0], self.sourcePos_x, decimal=8)
        npt.assert_almost_equal(x_source_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_source_list[2], self.sourcePos_x, decimal=8)

    def test_num_basis(self):
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert num_basis == 9

    def test_linear_response_set(self):
        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens, with_amp=False, k=None)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]

    def test_point_source_list(self):
        ra_list, dec_list, amp_list = self.PointSource.point_source_list(self.kwargs_ps, self.kwargs_lens)
        assert ra_list[0] == self.x_pos[0]
        assert len(ra_list) == 9

    def test_point_source_amplitude(self):
        amp_list = self.PointSource.source_amplitude(self.kwargs_ps, self.kwargs_lens)
        assert len(amp_list) == 3

    def test_set_save_cache(self):
        self.PointSource.set_save_cache(True)
        assert self.PointSource._point_source_list[0]._save_cache == True

        self.PointSource.set_save_cache(False)
        assert self.PointSource._point_source_list[0]._save_cache == False

    def test_update_lens_model(self):
        lensModel = LensModel(lens_model_list=['SIS'])
        self.PointSource.update_lens_model(lens_model_class=lensModel)
        kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}]
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps,
                                                                     kwargs_lens=kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], -0.82654997748011705 , decimal=8)
    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)
Esempio n. 3
0
class TestPointSource_fixed_mag(object):

    def setup(self):
        lensModel = LensModel(lens_model_list=['SPEP'])
        solver = LensEquationSolver(lensModel=lensModel)
        e1, e2 = param_util.phi_q2_ellipticity(0, 0.7)
        self.kwargs_lens = [{'theta_E': 1., 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2, 'gamma': 2}]
        self.sourcePos_x, self.sourcePos_y = 0.01, -0.01
        self.x_pos, self.y_pos = solver.image_position_from_source(sourcePos_x=self.sourcePos_x,
                                                                   sourcePos_y=self.sourcePos_y, kwargs_lens=self.kwargs_lens)
        self.PointSource = PointSource(point_source_type_list=['LENSED_POSITION', 'UNLENSED', 'SOURCE_POSITION'],
                                       lensModel=lensModel, fixed_magnification_list=[True]*4, additional_images_list=[False]*4)
        self.kwargs_ps = [{'ra_image': self.x_pos, 'dec_image': self.y_pos, 'source_amp': 1},
                          {'ra_image': [1.], 'dec_image': [1.], 'point_amp': [10]},
                          {'ra_source': self.sourcePos_x, 'dec_source': self.sourcePos_y, 'source_amp': 1.}, {}]

    def test_image_position(self):
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], self.x_pos[0], decimal=8)
        npt.assert_almost_equal(x_image_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_image_list[2][0], self.x_pos[0], decimal=8)

    def test_source_position(self):
        x_source_list, y_source_list = self.PointSource.source_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_source_list[0], self.sourcePos_x, decimal=8)
        npt.assert_almost_equal(x_source_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_source_list[2], self.sourcePos_x, decimal=8)

    def test_num_basis(self):
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert num_basis == 3

    def test_linear_response_set(self):
        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens, with_amp=False, k=None)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]
        assert ra_pos[1][0] == 1
        npt.assert_almost_equal(ra_pos[2][0], self.x_pos[0], decimal=8)

    def test_point_source_list(self):
        ra_list, dec_list, amp_list = self.PointSource.point_source_list(self.kwargs_ps, self.kwargs_lens)
        assert ra_list[0] == self.x_pos[0]
        assert len(ra_list) == 9

    def test_check_image_positions(self):
        bool = self.PointSource.check_image_positions(self.kwargs_ps, self.kwargs_lens, tolerance=0.001)
        assert bool == True
Esempio n. 4
0
    def get_img_pos(self, ps_dict, kwargs_lens):
        """Sets the kwargs_ps class attribute as those coresponding to the point source model `LENSED_POSITION`

        Parameters
        ----------
        ps_dict : dict
            point source parameters definitions, either of `SOURCE_POSITION` or `LENSED_POSITION`

        """
        if 'ra_source' in ps_dict:
            # If the user provided ps_dict in terms of the source position, we precompute the corresponding image positions before we enter the sampling loop.
            lens_model_class = LensModel(self.kwargs_model['lens_model_list'])
            ps_class = PointSource(['SOURCE_POSITION'], lens_model_class)
            kwargs_ps_source = [ps_dict]
            ra_image, dec_image = ps_class.image_position(
                kwargs_ps_source, kwargs_lens)
            kwargs_image = [dict(ra_image=ra_image[0], dec_image=dec_image[0])]
            requires_reordering = True  # Since the ra_image is coming out of lenstronomy, we need to reorder it to agree with TDLMC
        else:
            kwargs_image = [ps_dict]
            requires_reordering = False  # If the user is providing `ra_image` inside `ps_dict`, the order is required to agree with `measured_time_delays`.
        return kwargs_image, requires_reordering
class TestPointSource(object):

    def setup(self):
        lensModel = LensModel(lens_model_list=['SPEP'])
        solver = LensEquationSolver(lensModel=lensModel)
        e1, e2 = param_util.phi_q2_ellipticity(0, 0.7)
        self.kwargs_lens = [{'theta_E': 1., 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2, 'gamma': 2}]
        self.sourcePos_x, self.sourcePos_y = 0.01, -0.01
        self.x_pos, self.y_pos = solver.image_position_from_source(sourcePos_x=self.sourcePos_x,
                                                                   sourcePos_y=self.sourcePos_y, kwargs_lens=self.kwargs_lens)
        self.PointSource = PointSource(point_source_type_list=['LENSED_POSITION', 'UNLENSED', 'SOURCE_POSITION'],
                                       lensModel=lensModel, fixed_magnification_list=[False]*3, additional_images_list=[False]*4)
        self.kwargs_ps = [{'ra_image': self.x_pos, 'dec_image': self.y_pos, 'point_amp': np.ones_like(self.x_pos)},
                          {'ra_image': [1.], 'dec_image': [1.], 'point_amp': [10]},
                          {'ra_source': self.sourcePos_x, 'dec_source': self.sourcePos_y, 'point_amp': np.ones_like(self.x_pos)}, {}]

    def test_image_position(self):
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], self.x_pos[0], decimal=8)
        npt.assert_almost_equal(x_image_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_image_list[2][0], self.x_pos[0], decimal=8)

    def test_source_position(self):
        x_source_list, y_source_list = self.PointSource.source_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_source_list[0], self.sourcePos_x, decimal=8)
        npt.assert_almost_equal(x_source_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_source_list[2], self.sourcePos_x, decimal=8)

    def test_num_basis(self):
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert num_basis == 9

    def test_linear_response_set(self):
        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens, with_amp=False, k=None)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]

    def test_point_source_list(self):
        ra_list, dec_list, amp_list = self.PointSource.point_source_list(self.kwargs_ps, self.kwargs_lens)
        assert ra_list[0] == self.x_pos[0]
        assert len(ra_list) == 9

    def test_point_source_amplitude(self):
        amp_list = self.PointSource.source_amplitude(self.kwargs_ps, self.kwargs_lens)
        assert len(amp_list) == 3

    def test_set_save_cache(self):
        self.PointSource.set_save_cache(True)
        assert self.PointSource._point_source_list[0]._save_cache == True

        self.PointSource.set_save_cache(False)
        assert self.PointSource._point_source_list[0]._save_cache == False

    def test_update_lens_model(self):
        lensModel = LensModel(lens_model_list=['SIS'])
        self.PointSource.update_lens_model(lens_model_class=lensModel)
        kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}]
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps,
                                                                     kwargs_lens=kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], -0.82654997748011705 , decimal=8)

    def test_re_normalize_flux(self):
        norm_factor = 10
        kwargs_input = copy.deepcopy(self.kwargs_ps)
        kwargs_ps = self.PointSource.re_normalize_flux(kwargs_input, norm_factor)
        npt.assert_almost_equal(kwargs_ps[0]['point_amp'][0] / self.kwargs_ps[0]['point_amp'][0], norm_factor, decimal=8)

    def test_set_amplitudes(self):
        amp_list = [np.ones_like(self.x_pos)*10, [100], np.ones_like(self.x_pos)*10]
        kwargs_out = self.PointSource.set_amplitudes(amp_list, self.kwargs_ps)
        assert kwargs_out[0]['point_amp'][0] == 10* self.kwargs_ps[0]['point_amp'][0]
        assert kwargs_out[1]['point_amp'][0] == 10 * self.kwargs_ps[1]['point_amp'][0]
        assert kwargs_out[2]['point_amp'][3] == 10 * self.kwargs_ps[2]['point_amp'][3]
Esempio n. 6
0
class LensAnalysis(object):
    """
    class to compute flux ratio anomalies, inherited from standard MakeImage
    """
    def __init__(self, kwargs_model):
        self.LensLightModel = LightModel(
            kwargs_model.get('lens_light_model_list', []))
        self.SourceModel = LightModel(
            kwargs_model.get('source_light_model_list', []))
        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._lensModelExtensions = LensModelExtensions(self.LensModel)
        self.PointSource = PointSource(point_source_type_list=kwargs_model.get(
            'point_source_model_list', []))
        self.kwargs_model = kwargs_model
        self.NumLensModel = NumericLens(
            lens_model_list=kwargs_model.get('lens_model_list', []))

    def fermat_potential(self, kwargs_lens, kwargs_ps):
        ra_pos, dec_pos = self.PointSource.image_position(
            kwargs_ps, kwargs_lens)
        ra_pos = ra_pos[0]
        dec_pos = dec_pos[0]
        ra_source, dec_source = self.LensModel.ray_shooting(
            ra_pos, dec_pos, kwargs_lens)
        ra_source = np.mean(ra_source)
        dec_source = np.mean(dec_source)
        fermat_pot = self.LensModel.fermat_potential(ra_pos, dec_pos,
                                                     ra_source, dec_source,
                                                     kwargs_lens)
        return fermat_pot

    def ellipticity_lens_light(self,
                               kwargs_lens_light,
                               center_x=0,
                               center_y=0,
                               model_bool_list=None,
                               deltaPix=None,
                               numPix=None):
        """
        make sure that the window covers all the light, otherwise the moments may give to low answers.

        :param kwargs_lens_light:
        :param center_x:
        :param center_y:
        :param model_bool_list:
        :param deltaPix:
        :param numPix:
        :return:
        """
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens_light)
        if numPix is None:
            numPix = 100
        if deltaPix is None:
            deltaPix = 0.05
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        I_xy = self._lens_light_internal(x_grid,
                                         y_grid,
                                         kwargs_lens_light,
                                         model_bool_list=model_bool_list)
        e1, e2 = analysis_util.ellipticities(I_xy, x_grid, y_grid)
        return e1, e2

    def half_light_radius_lens(self,
                               kwargs_lens_light,
                               center_x=0,
                               center_y=0,
                               model_bool_list=None,
                               deltaPix=None,
                               numPix=None):
        """
        computes numerically the half-light-radius of the deflector light and the total photon flux

        :param kwargs_lens_light:
        :return:
        """
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens_light)
        if numPix is None:
            numPix = 1000
        if deltaPix is None:
            deltaPix = 0.05
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        lens_light = self._lens_light_internal(x_grid,
                                               y_grid,
                                               kwargs_lens_light,
                                               model_bool_list=model_bool_list)
        R_h = analysis_util.half_light_radius(lens_light, x_grid, y_grid,
                                              center_x, center_y)
        return R_h

    def half_light_radius_source(self,
                                 kwargs_source,
                                 center_x=0,
                                 center_y=0,
                                 deltaPix=None,
                                 numPix=None):
        """
        computes numerically the half-light-radius of the deflector light and the total photon flux

        :param kwargs_source:
        :return:
        """
        if numPix is None:
            numPix = 1000
        if deltaPix is None:
            deltaPix = 0.005
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        source_light = self.SourceModel.surface_brightness(
            x_grid, y_grid, kwargs_source)
        R_h = analysis_util.half_light_radius(source_light,
                                              x_grid,
                                              y_grid,
                                              center_x=center_x,
                                              center_y=center_y)
        return R_h

    def _lens_light_internal(self,
                             x_grid,
                             y_grid,
                             kwargs_lens_light,
                             model_bool_list=None):
        """
        evaluates only part of the light profiles

        :param x_grid:
        :param y_grid:
        :param kwargs_lens_light:
        :return:
        """
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens_light)
        lens_light = np.zeros_like(x_grid)
        for i, bool in enumerate(model_bool_list):
            if bool is True:
                lens_light_i = self.LensLightModel.surface_brightness(
                    x_grid, y_grid, kwargs_lens_light, k=i)
                lens_light += lens_light_i
        return lens_light

    def multi_gaussian_lens_light(self,
                                  kwargs_lens_light,
                                  model_bool_list=None,
                                  e1=0,
                                  e2=0,
                                  n_comp=20,
                                  deltaPix=None,
                                  numPix=None):
        """
        multi-gaussian decomposition of the lens light profile (in 1-dimension)

        :param kwargs_lens_light:
        :param n_comp:
        :return:
        """
        if 'center_x' in kwargs_lens_light[0]:
            center_x = kwargs_lens_light[0]['center_x']
            center_y = kwargs_lens_light[0]['center_y']
        else:
            center_x, center_y = 0, 0
        r_h = self.half_light_radius_lens(kwargs_lens_light,
                                          center_x=center_x,
                                          center_y=center_y,
                                          model_bool_list=model_bool_list,
                                          deltaPix=deltaPix,
                                          numPix=numPix)
        r_array = np.logspace(-3, 2, 200) * r_h * 2
        x_coords, y_coords = param_util.transform_e1e2(r_array,
                                                       np.zeros_like(r_array),
                                                       e1=-e1,
                                                       e2=-e2)
        x_coords += center_x
        y_coords += center_y
        #r_array = np.logspace(-2, 1, 50) * r_h
        flux_r = self._lens_light_internal(x_coords,
                                           y_coords,
                                           kwargs_lens_light,
                                           model_bool_list=model_bool_list)
        amplitudes, sigmas, norm = mge.mge_1d(r_array, flux_r, N=n_comp)
        return amplitudes, sigmas, center_x, center_y

    def multi_gaussian_lens(self,
                            kwargs_lens,
                            model_bool_list=None,
                            e1=0,
                            e2=0,
                            n_comp=20):
        """
        multi-gaussian lens model in convergence space

        :param kwargs_lens:
        :param n_comp:
        :return:
        """
        if 'center_x' in kwargs_lens[0]:
            center_x = kwargs_lens[0]['center_x']
            center_y = kwargs_lens[0]['center_y']
        else:
            raise ValueError('no keyword center_x defined!')
        theta_E = self._lensModelExtensions.effective_einstein_radius(
            kwargs_lens)
        r_array = np.logspace(-4, 2, 200) * theta_E
        x_coords, y_coords = param_util.transform_e1e2(r_array,
                                                       np.zeros_like(r_array),
                                                       e1=-e1,
                                                       e2=-e2)
        x_coords += center_x
        y_coords += center_y
        #r_array = np.logspace(-2, 1, 50) * theta_E
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens)
        kappa_s = np.zeros_like(r_array)
        for i in range(len(kwargs_lens)):
            if model_bool_list[i] is True:
                kappa_s += self.LensModel.kappa(x_coords,
                                                y_coords,
                                                kwargs_lens,
                                                k=i)
        amplitudes, sigmas, norm = mge.mge_1d(r_array, kappa_s, N=n_comp)
        return amplitudes, sigmas, center_x, center_y

    def flux_components(self,
                        kwargs_light,
                        n_grid=400,
                        delta_grid=0.01,
                        deltaPix=0.05,
                        type="lens"):
        """
        computes the total flux in each component of the model

        :param kwargs_light:
        :param n_grid:
        :param delta_grid:
        :return:
        """
        flux_list = []
        R_h_list = []
        x_grid, y_grid = util.make_grid(numPix=n_grid, deltapix=delta_grid)
        kwargs_copy = copy.deepcopy(kwargs_light)
        for k, kwargs in enumerate(kwargs_light):
            if 'center_x' in kwargs_copy[k]:
                kwargs_copy[k]['center_x'] = 0
                kwargs_copy[k]['center_y'] = 0
            if type == 'lens':
                light = self.LensLightModel.surface_brightness(x_grid,
                                                               y_grid,
                                                               kwargs_copy,
                                                               k=k)
            elif type == 'source':
                light = self.SourceModel.surface_brightness(x_grid,
                                                            y_grid,
                                                            kwargs_copy,
                                                            k=k)
            else:
                raise ValueError("type %s not supported!" % type)
            flux = np.sum(light) * delta_grid**2 / deltaPix**2
            R_h = analysis_util.half_light_radius(light, x_grid, y_grid)
            flux_list.append(flux)
            R_h_list.append(R_h)
        return flux_list, R_h_list

    def error_map_source(self, kwargs_source, x_grid, y_grid, cov_param):
        """
        variance of the linear source reconstruction in the source plane coordinates,
        computed by the diagonal elements of the covariance matrix of the source reconstruction as a sum of the errors
        of the basis set.

        :param kwargs_source: keyword arguments of source model
        :param x_grid: x-axis of positions to compute error map
        :param y_grid: y-axis of positions to compute error map
        :param cov_param: covariance matrix of liner inversion parameters
        :return: diagonal covariance errors at the positions (x_grid, y_grid)
        """

        error_map = np.zeros_like(x_grid)
        basis_functions, n_source = self.SourceModel.functions_split(
            x_grid, y_grid, kwargs_source)
        basis_functions = np.array(basis_functions)

        if cov_param is not None:
            for i in range(len(error_map)):
                error_map[i] = basis_functions[:, i].T.dot(
                    cov_param[:n_source, :n_source]).dot(basis_functions[:, i])
        return error_map

    def light2mass_mge(self,
                       kwargs_lens_light,
                       model_bool_list=None,
                       elliptical=False,
                       numPix=100,
                       deltaPix=0.05):
        # estimate center
        if 'center_x' in kwargs_lens_light[0]:
            center_x, center_y = kwargs_lens_light[0][
                'center_x'], kwargs_lens_light[0]['center_y']
        else:
            center_x, center_y = 0, 0
        # estimate half-light radius
        r_h = self.half_light_radius_lens(kwargs_lens_light,
                                          center_x=center_x,
                                          center_y=center_y,
                                          model_bool_list=model_bool_list,
                                          numPix=numPix,
                                          deltaPix=deltaPix)
        # estimate ellipticity at half-light radius
        if elliptical is True:
            e1, e2 = self.ellipticity_lens_light(
                kwargs_lens_light,
                center_x=center_x,
                center_y=center_y,
                model_bool_list=model_bool_list,
                deltaPix=deltaPix * 2,
                numPix=numPix)
        else:
            e1, e2 = 0, 0
        # MGE around major axis
        amplitudes, sigmas, center_x, center_y = self.multi_gaussian_lens_light(
            kwargs_lens_light,
            model_bool_list=model_bool_list,
            e1=e1,
            e2=e2,
            n_comp=20)
        kwargs_mge = {
            'amp': amplitudes,
            'sigma': sigmas,
            'center_x': center_x,
            'center_y': center_y
        }
        if elliptical:
            kwargs_mge['e1'] = e1
            kwargs_mge['e2'] = e2
        # rotate axes and add ellipticity to model kwargs
        return kwargs_mge

    @staticmethod
    def light2mass_interpol(lens_light_model_list,
                            kwargs_lens_light,
                            numPix=100,
                            deltaPix=0.05,
                            subgrid_res=5,
                            center_x=0,
                            center_y=0):
        """
        takes a lens light model and turns it numerically in a lens model
        (with all lensmodel quantities computed on a grid). Then provides an interpolated grid for the quantities.

        :param kwargs_lens_light: lens light keyword argument list
        :param numPix: number of pixels per axis for the return interpolation
        :param deltaPix: interpolation/pixel size
        :param center_x: center of the grid
        :param center_y: center of the grid
        :param subgrid: subgrid for the numerical integrals
        :return:
        """
        # make sugrid
        x_grid_sub, y_grid_sub = util.make_grid(numPix=numPix * 5,
                                                deltapix=deltaPix,
                                                subgrid_res=subgrid_res)
        import lenstronomy.Util.mask as mask_util
        mask = mask_util.mask_sphere(x_grid_sub,
                                     y_grid_sub,
                                     center_x,
                                     center_y,
                                     r=1)
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        # compute light on the subgrid
        lightModel = LightModel(light_model_list=lens_light_model_list)
        flux = lightModel.surface_brightness(x_grid_sub, y_grid_sub,
                                             kwargs_lens_light)
        flux_norm = np.sum(flux[mask == 1]) / np.sum(mask)
        flux /= flux_norm
        from lenstronomy.LensModel.numerical_profile_integrals import ConvergenceIntegrals
        integral = ConvergenceIntegrals()

        # compute lensing quantities with subgrid
        convergence_sub = flux
        f_x_sub, f_y_sub = integral.deflection_from_kappa(convergence_sub,
                                                          x_grid_sub,
                                                          y_grid_sub,
                                                          deltaPix=deltaPix /
                                                          float(subgrid_res))
        f_sub = integral.potential_from_kappa(convergence_sub,
                                              x_grid_sub,
                                              y_grid_sub,
                                              deltaPix=deltaPix /
                                              float(subgrid_res))
        # interpolation function on lensing quantities
        x_axes_sub, y_axes_sub = util.get_axes(x_grid_sub, y_grid_sub)
        from lenstronomy.LensModel.Profiles.interpol import Interpol_func
        interp_func = Interpol_func()
        interp_func.do_interp(x_axes_sub, y_axes_sub, f_sub, f_x_sub, f_y_sub)
        # compute lensing quantities on sparser grid
        x_axes, y_axes = util.get_axes(x_grid, y_grid)
        f_ = interp_func.function(x_grid, y_grid)
        f_x, f_y = interp_func.derivatives(x_grid, y_grid)
        # numerical differentials for second order differentials
        from lenstronomy.LensModel.numeric_lens_differentials import NumericLens
        lens_differential = NumericLens(lens_model_list=['INTERPOL'])
        kwargs = [{
            'grid_interp_x': x_axes_sub,
            'grid_interp_y': y_axes_sub,
            'f_': f_sub,
            'f_x': f_x_sub,
            'f_y': f_y_sub
        }]
        f_xx, f_xy, f_yx, f_yy = lens_differential.hessian(
            x_grid, y_grid, kwargs)
        kwargs_interpol = {
            'grid_interp_x': x_axes,
            'grid_interp_y': y_axes,
            'f_': util.array2image(f_),
            'f_x': util.array2image(f_x),
            'f_y': util.array2image(f_y),
            'f_xx': util.array2image(f_xx),
            'f_xy': util.array2image(f_xy),
            'f_yy': util.array2image(f_yy)
        }
        return kwargs_interpol

    def mass_fraction_within_radius(self,
                                    kwargs_lens,
                                    center_x,
                                    center_y,
                                    theta_E,
                                    numPix=100):
        """
        computes the mean convergence of all the different lens model components within a spherical aperture

        :param kwargs_lens: lens model keyword argument list
        :param center_x: center of the aperture
        :param center_y: center of the aperture
        :param theta_E: radius of aperture
        :return: list of average convergences for all the model components
        """
        x_grid, y_grid = util.make_grid(numPix=numPix,
                                        deltapix=2. * theta_E / numPix)
        x_grid += center_x
        y_grid += center_y
        mask = mask_util.mask_sphere(x_grid, y_grid, center_x, center_y,
                                     theta_E)
        kappa_list = []
        for i in range(len(kwargs_lens)):
            kappa = self.LensModel.kappa(x_grid, y_grid, kwargs_lens, k=i)
            kappa_mean = np.sum(kappa * mask) / np.sum(mask)
            kappa_list.append(kappa_mean)
        return kappa_list
Esempio n. 7
0
        )

# lensed image positions (solution of the lens equation) #
point_source_model_list = ['LENSED_POSITION']
pointSource = PointSource(
    point_source_type_list=point_source_model_list,
    lensModel=lensModel,
    fixed_magnification_list=[False])
kwargs_ps = [{
    'ra_image': theta_ra,
    'dec_image': theta_dec,
    'point_amp': np.abs(mag)*30 # the magnification of the point source images
    }]
# return image positions and amplitudes #
x_pos, y_pos = pointSource.image_position(
    kwargs_ps=kwargs_ps,
    kwargs_lens=kwargs_lens)
point_amp = pointSource.image_amplitude(
    kwargs_ps=kwargs_ps, kwargs_lens=kwargs_lens)


# MCMC parameters --------------------------------------------------------------------
compute_individual_samples = True  # if true the cosmo. posteriors are sampled for each lens
saveresults = True  # if true MCMC chains computed with emcee are saved
outdir = "samples"  # output directory
nwalkers = 6  #32
nsamples = 7000  #20000
cosmology = "FLCDM"

# MCMC sampling -----------------------------------------------------------------
display("Sampling cosmological parameters")
Esempio n. 8
0
class TestPointSourceFixedMag(object):

    def setup(self):
        lensModel = LensModel(lens_model_list=['SPEP'])
        solver = LensEquationSolver(lensModel=lensModel)
        e1, e2 = param_util.phi_q2_ellipticity(0, 0.7)
        self.kwargs_lens = [{'theta_E': 1., 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2, 'gamma': 2}]
        self.sourcePos_x, self.sourcePos_y = 0.01, -0.01
        self.x_pos, self.y_pos = solver.image_position_from_source(sourcePos_x=self.sourcePos_x,
                                                                   sourcePos_y=self.sourcePos_y, kwargs_lens=self.kwargs_lens)
        self.PointSource = PointSource(point_source_type_list=['LENSED_POSITION', 'UNLENSED', 'SOURCE_POSITION'],
                                       lensModel=lensModel, fixed_magnification_list=[True]*4, additional_images_list=[False]*4)
        self.kwargs_ps = [{'ra_image': self.x_pos, 'dec_image': self.y_pos, 'source_amp': 1},
                          {'ra_image': [1.], 'dec_image': [1.], 'point_amp': [10]},
                          {'ra_source': self.sourcePos_x, 'dec_source': self.sourcePos_y, 'source_amp': 1.}, {}]

    def test_image_position(self):
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], self.x_pos[0], decimal=8)
        npt.assert_almost_equal(x_image_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_image_list[2][0], self.x_pos[0], decimal=8)

    def test_source_position(self):
        x_source_list, y_source_list = self.PointSource.source_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_source_list[0], self.sourcePos_x, decimal=8)
        npt.assert_almost_equal(x_source_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_source_list[2], self.sourcePos_x, decimal=8)

    def test_num_basis(self):
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert num_basis == 3

    def test_linear_response_set(self):
        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens,
                                                                       with_amp=False)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]
        assert ra_pos[1][0] == 1
        assert np.all(amp != 1)
        npt.assert_almost_equal(ra_pos[2][0], self.x_pos[0], decimal=8)

        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens,
                                                                       with_amp=True)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]
        assert ra_pos[1][0] == 1
        assert np.all(amp != 1)
        npt.assert_almost_equal(ra_pos[2][0], self.x_pos[0], decimal=8)

    def test_point_source_list(self):
        ra_list, dec_list, amp_list = self.PointSource.point_source_list(self.kwargs_ps, self.kwargs_lens)
        assert ra_list[0] == self.x_pos[0]
        assert len(ra_list) == 9

    def test_check_image_positions(self):
        bool = self.PointSource.check_image_positions(self.kwargs_ps, self.kwargs_lens, tolerance=0.001)
        assert bool is True

        # now we change the lens model to make the test fail
        kwargs_lens = [{'theta_E': 2., 'center_x': 0, 'center_y': 0, 'e1': 0, 'e2': 0, 'gamma': 2}]
        bool = self.PointSource.check_image_positions(self.kwargs_ps, kwargs_lens, tolerance=0.001)
        assert bool is False

    def test_set_amplitudes(self):
        amp_list = [10, [100], 10]
        kwargs_out = self.PointSource.set_amplitudes(amp_list, self.kwargs_ps)
        assert kwargs_out[0]['source_amp'] == 10 * self.kwargs_ps[0]['source_amp']
        assert kwargs_out[1]['point_amp'][0] == 10 * self.kwargs_ps[1]['point_amp'][0]
        assert kwargs_out[2]['source_amp'] == 10 * self.kwargs_ps[2]['source_amp']

    def test_positive_flux(self):
        bool = PointSource.check_positive_flux(kwargs_ps=[{'point_amp': np.array([1, -1])}])
        assert bool is False
        bool = PointSource.check_positive_flux(kwargs_ps=[{'point_amp': -1}])
        assert bool is False

        bool = PointSource.check_positive_flux(kwargs_ps=[{'point_amp': np.array([0, 1])}])
        assert bool is True
        bool = PointSource.check_positive_flux(kwargs_ps=[{'point_amp': 1}])
        assert bool is True

        bool = PointSource.check_positive_flux(kwargs_ps=[{'point_amp': np.array([0, 1]), 'source_amp': 1}])
        assert bool is True
        bool = PointSource.check_positive_flux(kwargs_ps=[{'point_amp': 1, 'source_amp': -1}])
        assert bool is False
Esempio n. 9
0
class TestPointSource(object):

    def setup(self):
        lensModel = LensModel(lens_model_list=['SPEP'])
        solver = LensEquationSolver(lensModel=lensModel)
        e1, e2 = param_util.phi_q2_ellipticity(0, 0.7)
        self.kwargs_lens = [{'theta_E': 1., 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2, 'gamma': 2}]
        self.sourcePos_x, self.sourcePos_y = 0.01, -0.01
        self.x_pos, self.y_pos = solver.image_position_from_source(sourcePos_x=self.sourcePos_x,
                                                                   sourcePos_y=self.sourcePos_y, kwargs_lens=self.kwargs_lens)
        self.PointSource = PointSource(point_source_type_list=['LENSED_POSITION', 'UNLENSED', 'SOURCE_POSITION'],
                                       lensModel=lensModel, fixed_magnification_list=[False]*3,
                                       additional_images_list=[False]*4, flux_from_point_source_list=[True, True, True])
        self.kwargs_ps = [{'ra_image': self.x_pos, 'dec_image': self.y_pos, 'point_amp': np.ones_like(self.x_pos) * 2},
                          {'ra_image': [1.], 'dec_image': [1.], 'point_amp': [10]},
                          {'ra_source': self.sourcePos_x, 'dec_source': self.sourcePos_y, 'point_amp': np.ones_like(self.x_pos)}, {}]

    def test_image_position(self):
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][0], self.x_pos[0], decimal=8)
        npt.assert_almost_equal(x_image_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_image_list[2][0], self.x_pos[0], decimal=8)

    def test_source_position(self):
        x_source_list, y_source_list = self.PointSource.source_position(kwargs_ps=self.kwargs_ps, kwargs_lens=self.kwargs_lens)
        npt.assert_almost_equal(x_source_list[0], self.sourcePos_x, decimal=8)
        npt.assert_almost_equal(x_source_list[1], 1, decimal=8)
        npt.assert_almost_equal(x_source_list[2], self.sourcePos_x, decimal=8)

    def test_num_basis(self):
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert num_basis == 9

    def test_linear_response_set(self):
        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens, with_amp=False)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert amp[0][0] == 1
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]

        ra_pos, dec_pos, amp, n = self.PointSource.linear_response_set(self.kwargs_ps, kwargs_lens=self.kwargs_lens,
                                                                       with_amp=True)
        num_basis = self.PointSource.num_basis(self.kwargs_ps, self.kwargs_lens)
        assert amp[0][0] != 1
        assert n == num_basis
        assert ra_pos[0][0] == self.x_pos[0]

    def test_point_source_list(self):
        ra_list, dec_list, amp_list = self.PointSource.point_source_list(self.kwargs_ps, self.kwargs_lens)
        assert ra_list[0] == self.x_pos[0]
        assert len(ra_list) == 9

        ra_list, dec_list, amp_list = self.PointSource.point_source_list(self.kwargs_ps, self.kwargs_lens, k=0)
        assert ra_list[0] == self.x_pos[0]
        assert len(ra_list) == 4
        assert len(dec_list) == 4
        assert len(amp_list) == 4

    def test_point_source_amplitude(self):
        amp_list = self.PointSource.source_amplitude(self.kwargs_ps, self.kwargs_lens)
        assert len(amp_list) == 3

    def test_set_save_cache(self):
        self.PointSource.set_save_cache(True)
        assert self.PointSource._point_source_list[0]._save_cache == True

        self.PointSource.set_save_cache(False)
        assert self.PointSource._point_source_list[0]._save_cache == False

    def test_update_lens_model(self):
        lensModel = LensModel(lens_model_list=['SIS'])
        self.PointSource.update_lens_model(lens_model_class=lensModel)
        kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}]
        x_image_list, y_image_list = self.PointSource.image_position(kwargs_ps=self.kwargs_ps,
                                                                     kwargs_lens=kwargs_lens)
        npt.assert_almost_equal(x_image_list[0][-1], -0.82654997748011705 , decimal=8)

    def test_set_amplitudes(self):
        amp_list = [np.ones_like(self.x_pos)*20, [100], np.ones_like(self.x_pos)*10]
        kwargs_out = self.PointSource.set_amplitudes(amp_list, self.kwargs_ps)
        assert kwargs_out[0]['point_amp'][0] == 10 * self.kwargs_ps[0]['point_amp'][0]
        assert kwargs_out[1]['point_amp'][0] == 10 * self.kwargs_ps[1]['point_amp'][0]
        assert kwargs_out[2]['point_amp'][3] == 10 * self.kwargs_ps[2]['point_amp'][3]

    def test_update_search_window(self):
        search_window = 5
        x_center, y_center = 1, 1
        min_distance = 0.01

        point_source = PointSource(point_source_type_list=['LENSED_POSITION'],
                                   lensModel=None, kwargs_lens_eqn_solver={})

        point_source.update_search_window(search_window, x_center, y_center, min_distance=min_distance, only_from_unspecified=False)
        assert point_source._kwargs_lens_eqn_solver['search_window'] == search_window
        assert point_source._kwargs_lens_eqn_solver['x_center'] == x_center
        assert point_source._kwargs_lens_eqn_solver['x_center'] == y_center

        point_source = PointSource(point_source_type_list=['LENSED_POSITION'],
                                   lensModel=None, kwargs_lens_eqn_solver={})

        point_source.update_search_window(search_window, x_center, y_center, min_distance=min_distance,
                                          only_from_unspecified=True)
        assert point_source._kwargs_lens_eqn_solver['search_window'] == search_window
        assert point_source._kwargs_lens_eqn_solver['x_center'] == x_center
        assert point_source._kwargs_lens_eqn_solver['x_center'] == y_center

        kwargs_lens_eqn_solver = {'search_window': search_window,
                                  'min_distance': min_distance, 'x_center': x_center, 'y_center': y_center}
        point_source = PointSource(point_source_type_list=['LENSED_POSITION'],
                                   lensModel=None, kwargs_lens_eqn_solver=kwargs_lens_eqn_solver)
        point_source.update_search_window(search_window=-10, x_center=-10, y_center=-10,
                                          min_distance=10, only_from_unspecified = True)
        assert point_source._kwargs_lens_eqn_solver['search_window'] == search_window
        assert point_source._kwargs_lens_eqn_solver['x_center'] == x_center
        assert point_source._kwargs_lens_eqn_solver['x_center'] == y_center

    def test__sort_position_by_original(self):
        from lenstronomy.PointSource.point_source import _sort_position_by_original
        x_o, y_o = np.array([1, 2]), np.array([0, 0])
        x_solved, y_solved = np.array([2]), np.array([0])
        x_new, y_new = _sort_position_by_original(x_o, y_o, x_solved, y_solved)
        npt.assert_almost_equal(x_new, x_o, decimal=7)
        npt.assert_almost_equal(y_new, y_o, decimal=7)

        x_solved, y_solved = np.array([2, 1]), np.array([0, 0.01])
        x_new, y_new = _sort_position_by_original(x_o, y_o, x_solved, y_solved)
        npt.assert_almost_equal(x_new, x_o, decimal=7)
        npt.assert_almost_equal(y_new, np.array([0.01, 0]), decimal=7)
Esempio n. 10
0
class LensAnalysis(object):
    """
    class to compute flux ratio anomalies, inherited from standard MakeImage
    """
    def __init__(self, kwargs_model):
        self.LensLightModel = LightModel(kwargs_model.get('lens_light_model_list', ['NONE']))
        self.SourceModel = LightModel(kwargs_model.get('source_light_model_list', ['NONE']))
        self.LensModel = LensModelExtensions(lens_model_list=kwargs_model['lens_model_list'])
        self.PointSource = PointSource(point_source_type_list=kwargs_model.get('point_source_model_list', ['NONE']))
        self.kwargs_model = kwargs_model
        self.NumLensModel = NumericLens(lens_model_list=kwargs_model['lens_model_list'])
        self.gaussian = Gaussian()

    def fermat_potential(self, kwargs_lens, kwargs_ps):
        ra_pos, dec_pos = self.PointSource.image_position(kwargs_ps, kwargs_lens)
        ra_pos = ra_pos[0]
        dec_pos = dec_pos[0]
        ra_source, dec_source = self.LensModel.ray_shooting(ra_pos, dec_pos, kwargs_lens)
        ra_source = np.mean(ra_source)
        dec_source = np.mean(dec_source)
        fermat_pot = self.LensModel.fermat_potential(ra_pos, dec_pos, ra_source, dec_source, kwargs_lens)
        return fermat_pot

    def half_light_radius_lens(self, kwargs_lens_light, deltaPix=None, numPix=None):
        """
        computes numerically the half-light-radius of the deflector light and the total photon flux

        :param kwargs_lens_light:
        :return:
        """
        if numPix is None:
            numPix = 1000
        if deltaPix is None:
            deltaPix = 0.05
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        lens_light = self._lens_light_internal(x_grid, y_grid, kwargs_lens_light)
        R_h = analysis_util.half_light_radius(lens_light, x_grid, y_grid)
        return R_h

    def half_light_radius_source(self, kwargs_source, deltaPix=None, numPix=None):
        """
        computes numerically the half-light-radius of the deflector light and the total photon flux

        :param kwargs_lens_light:
        :return:
        """
        if numPix is None:
            numPix = 1000
        if deltaPix is None:
            deltaPix = 0.005
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        source_light = self.SourceModel.surface_brightness(x_grid, y_grid, kwargs_source)
        R_h = analysis_util.half_light_radius(source_light, x_grid, y_grid, center_x=kwargs_source[0]['center_x'], center_y=kwargs_source[0]['center_y'])
        return R_h

    def _lens_light_internal(self, x_grid, y_grid, kwargs_lens_light):
        """

        :param x_grid:
        :param y_grid:
        :param kwargs_lens_light:
        :return:
        """
        kwargs_lens_light_copy = copy.deepcopy(kwargs_lens_light)
        lens_light_model_internal_bool = self.kwargs_model.get('light_model_deflector_bool', [True] * len(kwargs_lens_light))
        lens_light = np.zeros_like(x_grid)
        for i, bool in enumerate(lens_light_model_internal_bool):
            if bool is True:
                kwargs_lens_light_copy[i]['center_x'] = 0
                kwargs_lens_light_copy[i]['center_y'] = 0
                lens_light_i = self.LensLightModel.surface_brightness(x_grid, y_grid, kwargs_lens_light_copy, k=i)
                lens_light += lens_light_i
        return lens_light

    def multi_gaussian_lens_light(self, kwargs_lens_light, n_comp=20):
        """
        multi-gaussian decomposition of the lens light profile (in 1-dimension)

        :param kwargs_lens_light:
        :param n_comp:
        :return:
        """
        r_h = self.half_light_radius_lens(kwargs_lens_light)
        r_array = np.logspace(-3, 2, 200) * r_h * 2
        #r_array = np.logspace(-2, 1, 50) * r_h
        flux_r = self._lens_light_internal(r_array, np.zeros_like(r_array), kwargs_lens_light)
        amplitudes, sigmas, norm = mge.mge_1d(r_array, flux_r, N=n_comp)
        return amplitudes, sigmas

    def multi_gaussian_lens(self, kwargs_lens, n_comp=20):
        """
        multi-gaussian lens model in convergence space

        :param kwargs_lens:
        :param n_comp:
        :return:
        """
        kwargs_lens_copy = copy.deepcopy(kwargs_lens)
        if 'center_x' in kwargs_lens_copy[0]:
            center_x = kwargs_lens_copy[0]['center_x']
            center_y = kwargs_lens_copy[0]['center_y']
        else:
            raise ValueError('no keyword center_x defined!')
        theta_E = self.LensModel.effective_einstein_radius(kwargs_lens)
        r_array = np.logspace(-4, 2, 200) * theta_E
        #r_array = np.logspace(-2, 1, 50) * theta_E
        lens_model_internal_bool = self.kwargs_model.get('lens_model_internal_bool', [True] * len(kwargs_lens))
        kappa_s = np.zeros_like(r_array)
        for i in range(len(kwargs_lens_copy)):
            if lens_model_internal_bool[i]:
                if 'center_x' in kwargs_lens_copy[0]:
                    kwargs_lens_copy[i]['center_x'] -= center_x
                    kwargs_lens_copy[i]['center_y'] -= center_y
                kappa_s += self.LensModel.kappa(r_array, np.zeros_like(r_array), kwargs_lens_copy, k=i)
        amplitudes, sigmas, norm = mge.mge_1d(r_array, kappa_s, N=n_comp)
        return amplitudes, sigmas, center_x, center_y

    def flux_components(self, kwargs_light, n_grid=400, delta_grid=0.01, deltaPix=0.05, type="lens"):
        """
        computes the total flux in each component of the model

        :param kwargs_light:
        :param n_grid:
        :param delta_grid:
        :return:
        """
        flux_list = []
        R_h_list = []
        x_grid, y_grid = util.make_grid(numPix=n_grid, deltapix=delta_grid)
        kwargs_copy = copy.deepcopy(kwargs_light)
        for k, kwargs in enumerate(kwargs_light):
            if 'center_x' in kwargs_copy[k]:
                kwargs_copy[k]['center_x'] = 0
                kwargs_copy[k]['center_y'] = 0
            if type == 'lens':
                light = self.LensLightModel.surface_brightness(x_grid, y_grid, kwargs_copy, k=k)
            elif type == 'source':
                light = self.SourceModel.surface_brightness(x_grid, y_grid, kwargs_copy, k=k)
            else:
                raise ValueError("type %s not supported!" % type)
            flux = np.sum(light)*delta_grid**2/ deltaPix**2
            R_h = analysis_util.half_light_radius(light, x_grid, y_grid)
            flux_list.append(flux)
            R_h_list.append(R_h)
        return flux_list, R_h_list

    @staticmethod
    def buldge_disk_ratio(kwargs_buldge_disk):
        """
        computes the buldge-to-disk ratio of the

        :param kwargs_buldge_disk: kwargs of the buldge2disk function
        :return:
        """
        kwargs_bd = copy.deepcopy(kwargs_buldge_disk)
        kwargs_bd['center_x'] = 0
        kwargs_bd['center_y'] = 0
        deltaPix = 0.05
        numPix = 200
        x_grid, y_grid = util.make_grid(numPix, deltaPix)
        from lenstronomy.LightModel.Profiles.sersic import BuldgeDisk
        bd_class = BuldgeDisk()
        light_grid = bd_class.function(x_grid, y_grid, **kwargs_bd)
        light_tot = np.sum(light_grid)
        kwargs_bd['I0_d'] = 0
        light_grid = bd_class.function(x_grid, y_grid, **kwargs_bd)
        light_buldge = np.sum(light_grid)
        return light_tot, light_buldge

    def error_map_source(self, kwargs_source, x_grid, y_grid, cov_param):
        """
        variance of the linear source reconstruction in the source plane coordinates,
        computed by the diagonal elements of the covariance matrix of the source reconstruction as a sum of the errors
        of the basis set.

        :param kwargs_source: keyword arguments of source model
        :param x_grid: x-axis of positions to compute error map
        :param y_grid: y-axis of positions to compute error map
        :param cov_param: covariance matrix of liner inversion parameters
        :return: diagonal covariance errors at the positions (x_grid, y_grid)
        """

        error_map = np.zeros_like(x_grid)
        basis_functions, n_source = self.SourceModel.functions_split(x_grid, y_grid, kwargs_source)
        basis_functions = np.array(basis_functions)

        if cov_param is not None:
            for i in range(len(error_map)):
                error_map[i] = basis_functions[:, i].T.dot(cov_param[:n_source, :n_source]).dot(basis_functions[:, i])
        return error_map