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)
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
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]
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
) # 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")
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
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)
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