def test_derivatives(self): Rs = 10. theta_Rs = 10 x = np.linspace(Rs, Rs, 1000) y = np.linspace(0.2 * Rs, 2 * Rs, 1000) center_x, center_y = -1.2, 0.46 zlist_single = [0.5, 0.5] zlist_multi = [0.5, 0.8] zlist = [zlist_single, zlist_multi] numerical_alpha_class = [TestClass(), None] for i, flag in enumerate([False, True]): lensmodel = LensModel(lens_model_list=['NumericalAlpha', 'NFW'], z_source=1.5, z_lens=0.5, lens_redshift_list=zlist[i], multi_plane=flag, numerical_alpha_class=numerical_alpha_class) lensmodel_nfw = LensModel( lens_model_list=['NFW', 'NFW'], z_source=1.5, z_lens=0.5, lens_redshift_list=zlist[i], multi_plane=flag, numerical_alpha_class=numerical_alpha_class) keywords_num = [{ 'norm': theta_Rs, 'Rs': Rs, 'center_x': center_x, 'center_y': center_y }, { 'theta_Rs': 0.7 * theta_Rs, 'Rs': 2 * Rs, 'center_x': center_x, 'center_y': center_y }] keywords_nfw = [{ 'theta_Rs': theta_Rs, 'Rs': Rs, 'center_x': center_x, 'center_y': center_y }, { 'theta_Rs': 0.7 * theta_Rs, 'Rs': 2 * Rs, 'center_x': center_x, 'center_y': center_y }] dx, dy = lensmodel.alpha(x, y, keywords_num) dxnfw, dynfw = lensmodel_nfw.alpha(x, y, keywords_nfw) npt.assert_almost_equal(dx, dxnfw) npt.assert_almost_equal(dy, dynfw)
def test_raise(self): with self.assertRaises(ValueError): kwargs = [{'alpha_Rs': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0}] lensModel = LensModel(['NFW'], multi_plane=True, lens_redshift_list=[1], z_source=2) f_x, f_y = lensModel.alpha(1, 1, kwargs, diff=0.0001) with self.assertRaises(ValueError): lensModel = LensModel(['NFW'], multi_plane=True, lens_redshift_list=[1]) with self.assertRaises(ValueError): kwargs = [{'alpha_Rs': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0}] lensModel = LensModel(['NFW'], multi_plane=False) t_arrival = lensModel.arrival_time(1, 1, kwargs) with self.assertRaises(ValueError): z_lens = 0.5 z_source = 1.5 x_image, y_image = 1., 0. lensModel = LensModel(lens_model_list=['SIS'], multi_plane=True, lens_redshift_list=[z_lens], z_source=z_source) kwargs = [{'theta_E': 1., 'center_x': 0., 'center_y': 0.}] fermat_pot = lensModel.fermat_potential(x_image, y_image, kwargs)
def test_curved_arc_estimate(self): lens_model_list = ['SPP'] lens = LensModel(lens_model_list=lens_model_list) arc = LensModel(lens_model_list=['CURVED_ARC_SPP']) theta_E = 4 gamma = 2. kwargs_lens = [{ 'theta_E': theta_E, 'gamma': gamma, 'center_x': 0, 'center_y': 0 }] ext = LensModelExtensions(lensModel=lens) x_0, y_0 = 5, 0 kwargs_arc = ext.curved_arc_estimate(x_0, y_0, kwargs_lens) theta_E_arc, gamma_arc, center_x_spp_arc, center_y_spp_arc = CurvedArcSPP.stretch2spp( **kwargs_arc) npt.assert_almost_equal(theta_E_arc, theta_E, decimal=4) npt.assert_almost_equal(gamma_arc, gamma, decimal=3) npt.assert_almost_equal(center_x_spp_arc, 0, decimal=3) npt.assert_almost_equal(center_y_spp_arc, 0, decimal=3) x, y = util.make_grid(numPix=10, deltapix=1) alpha_x, alpha_y = lens.alpha(x, y, kwargs_lens) alpha0_x, alpha0_y = lens.alpha(x_0, y_0, kwargs_lens) alpha_x_arc, alpha_y_arc = arc.alpha(x, y, [kwargs_arc]) npt.assert_almost_equal(alpha_x_arc, alpha_x - alpha0_x, decimal=3) npt.assert_almost_equal(alpha_y_arc, alpha_y - alpha0_y, decimal=3) x_0, y_0 = 0., 3 kwargs_arc = ext.curved_arc_estimate(x_0, y_0, kwargs_lens) theta_E_arc, gamma_arc, center_x_spp_arc, center_y_spp_arc = CurvedArcSPP.stretch2spp( **kwargs_arc) print(kwargs_arc) print(theta_E_arc, gamma_arc, center_x_spp_arc, center_y_spp_arc) npt.assert_almost_equal(theta_E_arc, theta_E, decimal=4) npt.assert_almost_equal(gamma_arc, gamma, decimal=3) npt.assert_almost_equal(center_x_spp_arc, 0, decimal=3) npt.assert_almost_equal(center_y_spp_arc, 0, decimal=3) x_0, y_0 = -2, -3 kwargs_arc = ext.curved_arc_estimate(x_0, y_0, kwargs_lens) theta_E_arc, gamma_arc, center_x_spp_arc, center_y_spp_arc = CurvedArcSPP.stretch2spp( **kwargs_arc) npt.assert_almost_equal(theta_E_arc, theta_E, decimal=4) npt.assert_almost_equal(gamma_arc, gamma, decimal=3) npt.assert_almost_equal(center_x_spp_arc, 0, decimal=3) npt.assert_almost_equal(center_y_spp_arc, 0, decimal=3)
def assert_differentials(self, lens_model, kwargs, potential=True): #lensModelNum = NumericLens(lens_model) diff = 0.000001 #x, y = 1., 2. x = np.linspace(start=0.1, stop=5.5, num=10) y = np.zeros_like(x) lensModel = LensModel(lens_model) f_xx, f_xy, f_yx, f_yy = lensModel.hessian(x, y, [kwargs]) f_xx_num, f_xy_num, f_yx_num, f_yy_num = lensModel.hessian(x, y, [kwargs], diff=diff) npt.assert_almost_equal(f_xx, f_xx_num, decimal=3) npt.assert_almost_equal(f_yy, f_yy_num, decimal=3) npt.assert_almost_equal(f_xy, f_xy_num, decimal=3) if potential is True: f_x, f_y = lensModel.alpha(x, y, [kwargs]) f_x_num, f_y_num = lensModel.alpha(x, y, [kwargs], diff=diff) npt.assert_almost_equal(f_x, f_x_num, decimal=3) npt.assert_almost_equal(f_y, f_y_num, decimal=3) y = np.linspace(start=0.1, stop=5.5, num=10) x = np.zeros_like(y) lensModel = LensModel(lens_model) f_xx, f_xy, f_yx, f_yy = lensModel.hessian(x, y, [kwargs]) f_xx_num, f_xy_num, f_yx_num, f_yy_num = lensModel.hessian(x, y, [kwargs], diff=diff) npt.assert_almost_equal(f_xx, f_xx_num, decimal=3) npt.assert_almost_equal(f_yy, f_yy_num, decimal=3) npt.assert_almost_equal(f_xy, f_xy_num, decimal=3) if potential is True: f_x, f_y = lensModel.alpha(x, y, [kwargs]) f_x_num, f_y_num = lensModel.alpha(x, y, [kwargs], diff=diff) npt.assert_almost_equal(f_x, f_x_num, decimal=3) npt.assert_almost_equal(f_y, f_y_num, decimal=3)
def test_arcs_at_image_position(self): # lensing quantities kwargs_spp = { 'theta_E': 1.26, 'gamma': 2., 'e1': 0.1, 'e2': -0.1, 'center_x': 0.0, 'center_y': 0.0 } # parameters of the deflector lens model # the lens model is a supperposition of an elliptical lens model with external shear lens_model_list = ['SPEP'] #, 'SHEAR'] kwargs_lens = [kwargs_spp] #, kwargs_shear] lens_model_class = LensModel(lens_model_list=lens_model_list) lensEquationSolver = LensEquationSolver(lens_model_class) source_x = 0. source_y = 0.05 x_image, y_image = lensEquationSolver.findBrightImage( source_x, source_y, kwargs_lens, numImages=4, min_distance=0.05, search_window=5) arc_model = LensModel(lens_model_list=['CURVED_ARC_SPP', 'SHIFT']) for i in range(len(x_image)): x0, y0 = x_image[i], y_image[i] print(x0, y0, i) ext = LensModelExtensions(lensModel=lens_model_class) kwargs_arc_i = ext.curved_arc_estimate(x0, y0, kwargs_lens) alpha_x, alpha_y = lens_model_class.alpha(x0, y0, kwargs_lens) kwargs_arc = [ kwargs_arc_i, { 'alpha_x': alpha_x, 'alpha_y': alpha_y } ] print(kwargs_arc_i) direction = kwargs_arc_i['direction'] print(np.cos(direction), np.sin(direction)) x, y = util.make_grid(numPix=5, deltapix=0.01) x = x0 y = y0 gamma1_arc, gamma2_arc = arc_model.gamma(x, y, kwargs_arc) gamma1, gamma2 = lens_model_class.gamma(x, y, kwargs_lens) print(gamma1, gamma2) npt.assert_almost_equal(gamma1_arc, gamma1, decimal=3) npt.assert_almost_equal(gamma2_arc, gamma2, decimal=3) theta_E_arc, gamma_arc, center_x_spp_arc, center_y_spp_arc = CurvedArcSPP.stretch2spp( **kwargs_arc_i) print(theta_E_arc, gamma_arc, center_x_spp_arc, center_y_spp_arc) npt.assert_almost_equal(center_x_spp_arc, 0, decimal=3) npt.assert_almost_equal(center_y_spp_arc, 0, decimal=3)
def test_sis_alpha(self): z_source = 1.5 lens_model_list = ['SIS'] redshift_list = [0.5] lensModelMutli = MultiLens(z_source=z_source, lens_model_list=lens_model_list, redshift_list=redshift_list) lensModel = LensModel(lens_model_list=lens_model_list) kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}] alpha_x_simple, alpha_y_simple = lensModel.alpha(1, 0, kwargs_lens) alpha_x_multi, alpha_y_multi = lensModelMutli.alpha(1, 0, kwargs_lens) assert alpha_x_simple == alpha_x_multi assert alpha_y_simple == alpha_y_multi
def test_sis_alpha(self): z_source = 1.5 lens_model_list = ['SIS'] redshift_list = [0.5] lensModelMutli = MultiPlane(z_source=z_source, lens_model_list=lens_model_list, lens_redshift_list=redshift_list) lensModel = LensModel(lens_model_list=lens_model_list) kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}] alpha_x_simple, alpha_y_simple = lensModel.alpha(1, 0, kwargs_lens) alpha_x_multi, alpha_y_multi = lensModelMutli.alpha(1, 0, kwargs_lens) npt.assert_almost_equal(alpha_x_simple, alpha_x_multi, decimal=8) npt.assert_almost_equal(alpha_y_simple, alpha_y_multi, decimal=8) sum_partial = np.sum(lensModelMutli._multi_plane_base._T_ij_list) + lensModelMutli._T_ij_stop T_z_true = lensModelMutli._T_z_source npt.assert_almost_equal(sum_partial, T_z_true, decimal=5)
def test_lensing_quantities(self): lensmodel = LensModel(['GNFW']) f_x, f_y = self.gnfw.derivatives(1.0, 1.5, **self.kwargs_lens) f_x_, f_y_ = lensmodel.alpha(1.0, 1.5, [self.kwargs_lens]) npt.assert_almost_equal(f_x, f_x_, 5) npt.assert_almost_equal(f_y, f_y_, 5) f_xx, f_xy, f_yx, f_yy = self.gnfw.hessian(1.0, 1.5, **self.kwargs_lens) f_xx_, f_xy_, f_yx_, f_yy_ = lensmodel.hessian(1.0, 1.5, [self.kwargs_lens]) npt.assert_almost_equal(f_xx, f_xx_, 5) npt.assert_almost_equal(f_yy, f_yy_, 5) npt.assert_almost_equal(f_xy, f_xy_, 5)
class LensModelPlot(object): """ class that manages the summary plots of a lens model """ def __init__(self, kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, arrow_size=0.02, cmap_string="gist_heat"): """ :param kwargs_options: :param kwargs_data: :param arrow_size: :param cmap_string: """ self._kwargs_data = kwargs_data if isinstance(cmap_string, str) or isinstance(cmap_string, unicode): cmap = plt.get_cmap(cmap_string) else: cmap = cmap_string cmap.set_bad(color='k', alpha=1.) cmap.set_under('k') self._cmap = cmap self._arrow_size = arrow_size data = Data(kwargs_data) self._coords = data._coords nx, ny = np.shape(kwargs_data['image_data']) Mpix2coord = kwargs_data['transform_pix2angle'] self._Mpix2coord = Mpix2coord self._deltaPix = self._coords.pixel_size self._frame_size = self._deltaPix * nx x_grid, y_grid = data.coordinates self._x_grid = util.image2array(x_grid) self._y_grid = util.image2array(y_grid) self._imageModel = class_creator.create_image_model(kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model) self._analysis = LensAnalysis(kwargs_model) self._lensModel = LensModel(lens_model_list=kwargs_model.get('lens_model_list', []), z_source=kwargs_model.get('z_source', None), redshift_list=kwargs_model.get('redshift_list', None), multi_plane=kwargs_model.get('multi_plane', False)) self._lensModelExt = LensModelExtensions(self._lensModel) model, error_map, cov_param, param = self._imageModel.image_linear_solve(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, inv_bool=True) self._kwargs_lens = kwargs_lens self._kwargs_source = kwargs_source self._kwargs_lens_light = kwargs_lens_light self._kwargs_else = kwargs_ps self._model = model self._data = kwargs_data['image_data'] self._cov_param = cov_param self._norm_residuals = self._imageModel.reduced_residuals(model, error_map=error_map) self._reduced_x2 = self._imageModel.reduced_chi2(model, error_map=error_map) log_model = np.log10(model) log_model[np.isnan(log_model)] = -5 self._v_min_default = max(np.min(log_model), -5) self._v_max_default = min(np.max(log_model), 10) print("reduced chi^2 = ", self._reduced_x2) def _critical_curves(self): if not hasattr(self, '_ra_crit_list') or not hasattr(self, '_dec_crit_list'): self._ra_crit_list, self._dec_crit_list = self._lensModelExt.critical_curve_tiling(self._kwargs_lens, compute_window=self._frame_size, start_scale=self._deltaPix / 5., max_order=10) return self._ra_crit_list, self._dec_crit_list def _caustics(self): if not hasattr(self, '_ra_caustic_list') or not hasattr(self, '_dec_caustic_list'): ra_crit_list, dec_crit_list = self._critical_curves() self._ra_caustic_list, self._dec_caustic_list = self._lensModel.ray_shooting(ra_crit_list, dec_crit_list, self._kwargs_lens) return self._ra_caustic_list, self._dec_caustic_list def data_plot(self, ax, v_min=None, v_max=None, text='Observed'): """ :param ax: :return: """ if v_min is None: v_min = self._v_min_default if v_max is None: v_max = self._v_max_default im = ax.matshow(np.log10(self._data), origin='lower', extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap, vmin=v_min, vmax=v_max) # , vmin=0, vmax=2 ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"') text_description(ax, self._frame_size, text=text, color="w", backgroundcolor='k') coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax, orientation='vertical') cb.set_label(r'log$_{10}$ flux', fontsize=15) return ax def model_plot(self, ax, v_min=None, v_max=None, image_names=False): """ :param ax: :param model: :param v_min: :param v_max: :return: """ if v_min is None: v_min = self._v_min_default if v_max is None: v_max = self._v_max_default im = ax.matshow(np.log10(self._model), origin='lower', vmin=v_min, vmax=v_max, extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"') text_description(ax, self._frame_size, text="Reconstructed", color="w", backgroundcolor='k') coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'log$_{10}$ flux', fontsize=15) #plot_line_set(ax, self._coords, self._ra_caustic_list, self._dec_caustic_list, color='b') #plot_line_set(ax, self._coords, self._ra_crit_list, self._dec_crit_list, color='r') if image_names is True: ra_image, dec_image = self._imageModel.image_positions(self._kwargs_else, self._kwargs_lens) image_position_plot(ax, self._coords, ra_image, dec_image) #source_position_plot(ax, self._coords, self._kwargs_source) def convergence_plot(self, ax, v_min=None, v_max=None): """ :param x_grid: :param y_grid: :param kwargs_lens: :param kwargs_else: :return: """ kappa_result = util.array2image(self._lensModel.kappa(self._x_grid, self._y_grid, self._kwargs_lens)) im = ax.matshow(np.log10(kappa_result), origin='lower', extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap, vmin=v_min, vmax=v_max) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"', color='w') coordinate_arrows(ax, self._frame_size, self._coords, color='w', arrow_size=self._arrow_size) text_description(ax, self._frame_size, text="Convergence", color="w", backgroundcolor='k', flipped=False) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'log$_{10}$ $\kappa$', fontsize=15) return ax def normalized_residual_plot(self, ax, v_min=-6, v_max=6, **kwargs): """ :param ax: :param v_min: :param v_max: :param kwargs: kwargs to send to matplotlib.pyplot.matshow() :return: """ if not 'cmap' in kwargs: kwargs['cmap'] = 'bwr' im = ax.matshow(self._norm_residuals, vmin=v_min, vmax=v_max, extent=[0, self._frame_size, 0, self._frame_size], origin='lower', **kwargs) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"', color='k') text_description(ax, self._frame_size, text="Normalized Residuals", color="k", backgroundcolor='w') coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'(f$_{model}$-f$_{data}$)/$\sigma$', fontsize=15) return ax def absolute_residual_plot(self, ax, v_min=-1, v_max=1): """ :param ax: :param residuals: :return: """ im = ax.matshow(self._model - self._data, vmin=v_min, vmax=v_max, extent=[0, self._frame_size, 0, self._frame_size], cmap='bwr', origin='lower') ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"', color='k') text_description(ax, self._frame_size, text="Residuals", color="k", backgroundcolor='w') coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'(f$_{model}$-f$_{data}$)', fontsize=15) return ax def source_plot(self, ax, numPix, deltaPix_source, source_sigma=0.001, convolution=False, v_min=None, v_max=None, with_caustics=False): """ :param ax: :param coords_source: :param source: :return: """ if v_min is None: v_min = self._v_min_default if v_max is None: v_max = self._v_max_default d_s = numPix * deltaPix_source x_grid_source, y_grid_source = util.make_grid_transformed(numPix, self._Mpix2coord * deltaPix_source / self._deltaPix) if len(self._kwargs_source) > 0: x_center = self._kwargs_source[0]['center_x'] y_center = self._kwargs_source[0]['center_y'] x_grid_source += x_center y_grid_source += y_center coords_source = Coordinates(self._Mpix2coord * deltaPix_source / self._deltaPix, ra_at_xy_0=x_grid_source[0], dec_at_xy_0=y_grid_source[0]) source = self._imageModel.SourceModel.surface_brightness(x_grid_source, y_grid_source, self._kwargs_source) source = util.array2image(source) if convolution is True: source = ndimage.filters.gaussian_filter(source, sigma=source_sigma / deltaPix_source, mode='nearest', truncate=20) im = ax.matshow(np.log10(source), origin='lower', extent=[0, d_s, 0, d_s], cmap=self._cmap, vmin=v_min, vmax=v_max) # source ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'log$_{10}$ flux', fontsize=15) if with_caustics: ra_caustic_list, dec_caustic_list = self._caustics() plot_line_set(ax, coords_source, ra_caustic_list, dec_caustic_list, color='b') scale_bar(ax, d_s, dist=0.1, text='0.1"', color='w', flipped=False) coordinate_arrows(ax, d_s, coords_source, arrow_size=self._arrow_size, color='w') text_description(ax, d_s, text="Reconstructed source", color="w", backgroundcolor='k', flipped=False) source_position_plot(ax, coords_source, self._kwargs_source) return ax def error_map_source_plot(self, ax, numPix, deltaPix_source, v_min=None, v_max=None, with_caustics=False): x_grid_source, y_grid_source = util.make_grid_transformed(numPix, self._Mpix2coord * deltaPix_source / self._deltaPix) x_center = self._kwargs_source[0]['center_x'] y_center = self._kwargs_source[0]['center_y'] x_grid_source += x_center y_grid_source += y_center coords_source = Coordinates(self._Mpix2coord * deltaPix_source / self._deltaPix, ra_at_xy_0=x_grid_source[0], dec_at_xy_0=y_grid_source[0]) error_map_source = self._analysis.error_map_source(self._kwargs_source, x_grid_source, y_grid_source, self._cov_param) error_map_source = util.array2image(error_map_source) d_s = numPix * deltaPix_source im = ax.matshow(error_map_source, origin='lower', extent=[0, d_s, 0, d_s], cmap=self._cmap, vmin=v_min, vmax=v_max) # source ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'error variance', fontsize=15) if with_caustics: ra_caustic_list, dec_caustic_list = self._caustics() plot_line_set(ax, coords_source, ra_caustic_list, dec_caustic_list, color='b') scale_bar(ax, d_s, dist=0.1, text='0.1"', color='w', flipped=False) coordinate_arrows(ax, d_s, coords_source, arrow_size=self._arrow_size, color='w') text_description(ax, d_s, text="Error map in source", color="w", backgroundcolor='k', flipped=False) source_position_plot(ax, coords_source, self._kwargs_source) return ax def magnification_plot(self, ax, v_min=-10, v_max=10, with_caustics=False, image_name_list=None, **kwargs): """ :param ax: :param v_min: :param v_max: :param with_caustics: :param kwargs: kwargs to send to matplotlib.pyplot.matshow() :return: """ if not 'cmap' in kwargs: kwargs['cmap'] = self._cmap if not 'alpha' in kwargs: kwargs['alpha'] = 0.5 mag_result = util.array2image(self._lensModel.magnification(self._x_grid, self._y_grid, self._kwargs_lens)) im = ax.matshow(mag_result, origin='lower', extent=[0, self._frame_size, 0, self._frame_size], vmin=v_min, vmax=v_max, **kwargs) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"', color='k') coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size) text_description(ax, self._frame_size, text="Magnification model", color="k", backgroundcolor='w') divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'det(A$^{-1}$)', fontsize=15) if with_caustics: ra_crit_list, dec_crit_list = self._critical_curves() ra_caustic_list, dec_caustic_list = self._caustics() plot_line_set(ax, self._coords, ra_caustic_list, dec_caustic_list, color='b') plot_line_set(ax, self._coords, ra_crit_list, dec_crit_list, color='r') ra_image, dec_image = self._imageModel.image_positions(self._kwargs_else, self._kwargs_lens) image_position_plot(ax, self._coords, ra_image, dec_image, color='k', image_name_list=image_name_list) source_position_plot(ax, self._coords, self._kwargs_source) return ax def deflection_plot(self, ax, v_min=None, v_max=None, axis=0, with_caustics=False, image_name_list=None): """ :param kwargs_lens: :param kwargs_else: :return: """ alpha1, alpha2 = self._lensModel.alpha(self._x_grid, self._y_grid, self._kwargs_lens) alpha1 = util.array2image(alpha1) alpha2 = util.array2image(alpha2) if axis == 0: alpha = alpha1 else: alpha = alpha2 im = ax.matshow(alpha, origin='lower', extent=[0, self._frame_size, 0, self._frame_size], vmin=v_min, vmax=v_max, cmap=self._cmap, alpha=0.5) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"', color='k') coordinate_arrows(ax, self._frame_size, self._coords, color='k', arrow_size=self._arrow_size) text_description(ax, self._frame_size, text="Deflection model", color="k", backgroundcolor='w') divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'arcsec', fontsize=15) if with_caustics: ra_crit_list, dec_crit_list = self._critical_curves() ra_caustic_list, dec_caustic_list = self._caustics() plot_line_set(ax, self._coords, ra_caustic_list, dec_caustic_list, color='b') plot_line_set(ax, self._coords, ra_crit_list, dec_crit_list, color='r') ra_image, dec_image = self._imageModel.image_positions(self._kwargs_else, self._kwargs_lens) image_position_plot(ax, self._coords, ra_image, dec_image, image_name_list=image_name_list) source_position_plot(ax, self._coords, self._kwargs_source) return ax def decomposition_plot(self, ax, text='Reconstructed', v_min=None, v_max=None, unconvolved=False, point_source_add=False, source_add=False, lens_light_add=False, **kwargs): """ :param ax: :param text: :param v_min: :param v_max: :param unconvolved: :param point_source_add: :param source_add: :param lens_light_add: :param kwargs: kwargs to send matplotlib.pyplot.matshow() :return: """ model = self._imageModel.image(self._kwargs_lens, self._kwargs_source, self._kwargs_lens_light, self._kwargs_else, unconvolved=unconvolved, source_add=source_add, lens_light_add=lens_light_add, point_source_add=point_source_add) if v_min is None: v_min = self._v_min_default if v_max is None: v_max = self._v_max_default if not 'cmap' in kwargs: kwargs['cmap'] = self._cmap im = ax.matshow(np.log10(model), origin='lower', vmin=v_min, vmax=v_max, extent=[0, self._frame_size, 0, self._frame_size], **kwargs) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"') text_description(ax, self._frame_size, text=text, color="w", backgroundcolor='k') coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'log$_{10}$ flux', fontsize=15) return ax def subtract_from_data_plot(self, ax, text='Subtracted', v_min=None, v_max=None, point_source_add=False, source_add=False, lens_light_add=False): model = self._imageModel.image(self._kwargs_lens, self._kwargs_source, self._kwargs_lens_light, self._kwargs_else, unconvolved=False, source_add=source_add, lens_light_add=lens_light_add, point_source_add=point_source_add) if v_min is None: v_min = self._v_min_default if v_max is None: v_max = self._v_max_default im = ax.matshow(np.log10(self._data - model), origin='lower', vmin=v_min, vmax=v_max, extent=[0, self._frame_size, 0, self._frame_size], cmap=self._cmap) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.autoscale(False) scale_bar(ax, self._frame_size, dist=1, text='1"') text_description(ax, self._frame_size, text=text, color="w", backgroundcolor='k') coordinate_arrows(ax, self._frame_size, self._coords, arrow_size=self._arrow_size) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cb = plt.colorbar(im, cax=cax) cb.set_label(r'log$_{10}$ flux', fontsize=15) return ax def plot_main(self): """ print the main plots together in a joint frame :return: """ f, axes = plt.subplots(2, 3, figsize=(16, 8)) self.data_plot(ax=axes[0, 0]) self.model_plot(ax=axes[0, 1]) self.normalized_residual_plot(ax=axes[0, 2], v_min=-6, v_max=6) self.source_plot(ax=axes[1, 0], convolution=False, deltaPix_source=0.01, numPix=100) self.convergence_plot(ax=axes[1, 1], v_max=1) self.magnification_plot(ax=axes[1, 2]) f.tight_layout() f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05) return f, axes def plot_separate(self): """ plot the different model components separately :return: """ f, axes = plt.subplots(2, 3, figsize=(16, 8)) self.decomposition_plot(ax=axes[0, 0], text='Lens light', lens_light_add=True, unconvolved=True) self.decomposition_plot(ax=axes[1, 0], text='Lens light convolved', lens_light_add=True) self.decomposition_plot(ax=axes[0, 1], text='Source light', source_add=True, unconvolved=True) self.decomposition_plot(ax=axes[1, 1], text='Source light convolved', source_add=True) self.decomposition_plot(ax=axes[0, 2], text='All components', source_add=True, lens_light_add=True, unconvolved=True) self.decomposition_plot(ax=axes[1, 2], text='All components convolved', source_add=True, lens_light_add=True, point_source_add=True) f.tight_layout() f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05) return f, axes def plot_subtract_from_data_all(self): """ subtract model components from data :return: """ f, axes = plt.subplots(2, 3, figsize=(16, 8)) self.subtract_from_data_plot(ax=axes[0, 0], text='Data') self.subtract_from_data_plot(ax=axes[0, 1], text='Data - Point Source', point_source_add=True) self.subtract_from_data_plot(ax=axes[0, 2], text='Data - Lens Light', lens_light_add=True) self.subtract_from_data_plot(ax=axes[1, 0], text='Data - Source Light', source_add=True) self.subtract_from_data_plot(ax=axes[1, 1], text='Data - Source Light - Point Source', source_add=True, point_source_add=True) self.subtract_from_data_plot(ax=axes[1, 2], text='Data - Lens Light - Point Source', lens_light_add=True, point_source_add=True) f.tight_layout() f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05) return f, axes
class TestLensModel(object): """ tests the source model routines """ def setup(self): self.lensModel = LensModel(['GAUSSIAN']) self.kwargs = [{ 'amp': 1., 'sigma_x': 2., 'sigma_y': 2., 'center_x': 0., 'center_y': 0. }] def test_init(self): lens_model_list = [ 'FLEXION', 'SIS_TRUNCATED', 'SERSIC', 'SERSIC_ELLIPSE_KAPPA', 'SERSIC_ELLIPSE_GAUSS_DEC', 'NFW_ELLIPSE_GAUSS_DEC', 'SERSIC_ELLIPSE_POTENTIAL', 'CTNFW_GAUSS_DEC', 'PJAFFE', 'PJAFFE_ELLIPSE', 'HERNQUIST_ELLIPSE', 'INTERPOL', 'INTERPOL_SCALED', 'SHAPELETS_POLAR', 'DIPOLE', 'GAUSSIAN_ELLIPSE_KAPPA', 'GAUSSIAN_ELLIPSE_POTENTIAL', 'MULTI_GAUSSIAN_KAPPA', 'MULTI_GAUSSIAN_KAPPA_ELLIPSE', 'CHAMELEON', 'DOUBLE_CHAMELEON' ] lensModel = LensModel(lens_model_list) assert len(lensModel.lens_model_list) == len(lens_model_list) lens_model_list = ['NFW'] lensModel = LensModel(lens_model_list) x, y = 0.2, 1 kwargs = [{'alpha_Rs': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0}] value = lensModel.potential(x, y, kwargs) nfw_interp = NFW(interpol=True, lookup=True) value_interp_lookup = nfw_interp.function(x, y, **kwargs[0]) npt.assert_almost_equal(value, value_interp_lookup, decimal=4) def test_kappa(self): lensModel = LensModel(lens_model_list=['CONVERGENCE']) kappa_ext = 0.5 kwargs = [{'kappa_ext': kappa_ext}] output = lensModel.kappa(x=1., y=1., kwargs=kwargs) assert output == kappa_ext def test_potential(self): output = self.lensModel.potential(x=1., y=1., kwargs=self.kwargs) npt.assert_almost_equal(output, 0.77880078307140488 / (8 * np.pi), decimal=8) #assert output == 0.77880078307140488/(8*np.pi) def test_alpha(self): output1, output2 = self.lensModel.alpha(x=1., y=1., kwargs=self.kwargs) npt.assert_almost_equal(output1, -0.19470019576785122 / (8 * np.pi), decimal=8) npt.assert_almost_equal(output2, -0.19470019576785122 / (8 * np.pi), decimal=8) #assert output1 == -0.19470019576785122/(8*np.pi) #assert output2 == -0.19470019576785122/(8*np.pi) output1_diff, output2_diff = self.lensModel.alpha(x=1., y=1., kwargs=self.kwargs, diff=0.00001) npt.assert_almost_equal(output1_diff, output1, decimal=5) npt.assert_almost_equal(output2_diff, output2, decimal=5) def test_gamma(self): lensModel = LensModel(lens_model_list=['SHEAR']) gamma1, gamm2 = 0.1, -0.1 kwargs = [{'gamma1': gamma1, 'gamma2': gamm2}] e1_out, e2_out = lensModel.gamma(x=1., y=1., kwargs=kwargs) assert e1_out == gamma1 assert e2_out == gamm2 output1, output2 = self.lensModel.gamma(x=1., y=1., kwargs=self.kwargs) assert output1 == 0 assert output2 == 0.048675048941962805 / (8 * np.pi) def test_magnification(self): output = self.lensModel.magnification(x=1., y=1., kwargs=self.kwargs) assert output == 0.98848384784633392 def test_flexion(self): lensModel = LensModel(lens_model_list=['FLEXION']) g1, g2, g3, g4 = 0.01, 0.02, 0.03, 0.04 kwargs = [{'g1': g1, 'g2': g2, 'g3': g3, 'g4': g4}] f_xxx, f_xxy, f_xyy, f_yyy = lensModel.flexion(x=1., y=1., kwargs=kwargs) npt.assert_almost_equal(f_xxx, g1, decimal=8) npt.assert_almost_equal(f_xxy, g2, decimal=8) npt.assert_almost_equal(f_xyy, g3, decimal=8) npt.assert_almost_equal(f_yyy, g4, decimal=8) def test_ray_shooting(self): delta_x, delta_y = self.lensModel.ray_shooting(x=1., y=1., kwargs=self.kwargs) npt.assert_almost_equal(delta_x, 1 + 0.19470019576785122 / (8 * np.pi), decimal=8) npt.assert_almost_equal(delta_y, 1 + 0.19470019576785122 / (8 * np.pi), decimal=8) #assert delta_x == 1 + 0.19470019576785122/(8*np.pi) #assert delta_y == 1 + 0.19470019576785122/(8*np.pi) def test_arrival_time(self): z_lens = 0.5 z_source = 1.5 x_image, y_image = 1., 0. lensModel = LensModel(lens_model_list=['SIS'], multi_plane=True, lens_redshift_list=[z_lens], z_source=z_source) kwargs = [{'theta_E': 1., 'center_x': 0., 'center_y': 0.}] arrival_time_mp = lensModel.arrival_time(x_image, y_image, kwargs) lensModel_sp = LensModel(lens_model_list=['SIS'], z_source=z_source, z_lens=z_lens) arrival_time_sp = lensModel_sp.arrival_time(x_image, y_image, kwargs) npt.assert_almost_equal(arrival_time_sp, arrival_time_mp, decimal=8) def test_fermat_potential(self): z_lens = 0.5 z_source = 1.5 x_image, y_image = 1., 0. lensModel = LensModel(lens_model_list=['SIS'], multi_plane=True, lens_redshift_list=[z_lens], z_lens=z_lens, z_source=z_source) kwargs = [{'theta_E': 1., 'center_x': 0., 'center_y': 0.}] fermat_pot = lensModel.fermat_potential(x_image, y_image, kwargs) arrival_time = lensModel.arrival_time(x_image, y_image, kwargs) arrival_time_from_fermat_pot = lensModel._lensCosmo.time_delay_units( fermat_pot) npt.assert_almost_equal(arrival_time_from_fermat_pot, arrival_time, decimal=8) def test_curl(self): z_lens_list = [0.2, 0.8] z_source = 1.5 lensModel = LensModel(lens_model_list=['SIS', 'SIS'], multi_plane=True, lens_redshift_list=z_lens_list, z_source=z_source) kwargs = [{ 'theta_E': 1., 'center_x': 0., 'center_y': 0. }, { 'theta_E': 0., 'center_x': 0., 'center_y': 0.2 }] curl = lensModel.curl(x=1, y=1, kwargs=kwargs) assert curl == 0 kwargs = [{ 'theta_E': 1., 'center_x': 0., 'center_y': 0. }, { 'theta_E': 1., 'center_x': 0., 'center_y': 0.2 }] curl = lensModel.curl(x=1, y=1, kwargs=kwargs) assert curl != 0
class TestLightCone(object): def setup(self): # define a cosmology cosmo = FlatLambdaCDM(H0=70, Om0=0.3, Ob0=0.05) self._cosmo = cosmo redshift_list = [0.1, 0.3, 0.8] # list of redshift of the deflectors z_source = 2 # source redshift self._z_source = z_source # analytic profile class in multi plane self._lensmodel = LensModel(lens_model_list=['NFW', 'NFW', 'NFW'], lens_redshift_list=redshift_list, multi_plane=True, z_source_convention=z_source, cosmo=cosmo, z_source=z_source) # a single plane class from which the convergence/mass maps are computeded single_plane = LensModel(lens_model_list=['NFW'], multi_plane=False) # multi-plane class with three interpolation grids self._lens_model_interp = LensModel( lens_model_list=['INTERPOL', 'INTERPOL', 'INTERPOL'], lens_redshift_list=redshift_list, multi_plane=True, z_source_convention=z_source, cosmo=cosmo, z_source=z_source) # deflector parameterisation in units of reduced deflection angles to the source convention redshift logM_200_list = [8, 9, 10] # log 10 halo masses of the three deflectors c_list = [20, 10, 8] # concentrations of the three halos kwargs_lens = [] kwargs_lens_interp = [] grid_spacing = 0.01 # spacing of the convergence grid in units arc seconds x_grid, y_grid = util.make_grid( numPix=500, deltapix=grid_spacing ) # we create the grid coordinates centered at zero x_axes, y_axes = util.get_axes( x_grid, y_grid) # we need the axes only for the interpolation mass_map_list = [] grid_spacing_list_mpc = [] for i, z in enumerate( redshift_list): # loop through the three deflectors lens_cosmo = LensCosmo( z_lens=z, z_source=z_source, cosmo=cosmo ) # instance of LensCosmo, a class that manages cosmology relevant quantities of a lens alpha_Rs, Rs = lens_cosmo.nfw_physical2angle( M=10**(logM_200_list[i]), c=c_list[i] ) # we turn the halo mass and concentration in reduced deflection angles and angles on the sky kwargs_nfw = { 'Rs': Rs, 'alpha_Rs': alpha_Rs, 'center_x': 0, 'center_y': 0 } # lensing parameters of the NFW profile in lenstronomy conventions kwargs_lens.append(kwargs_nfw) kappa_map = single_plane.kappa( x_grid, y_grid, [kwargs_nfw]) # convergence map of a single NFW profile kappa_map = util.array2image(kappa_map) mass_map = lens_cosmo.epsilon_crit_angle * kappa_map * grid_spacing**2 # projected mass per pixel on the gird mass_map_list.append(mass_map) npt.assert_almost_equal( np.log10(np.sum(mass_map)), logM_200_list[i], decimal=0 ) # check whether the sum of mass roughtly correspoonds the mass definition grid_spacing_mpc = lens_cosmo.arcsec2phys_lens( grid_spacing) # turn grid spacing from arcseconds into Mpc grid_spacing_list_mpc.append(grid_spacing_mpc) f_x, f_y = convergence_integrals.deflection_from_kappa_grid( kappa_map, grid_spacing ) # perform the deflection calculation from the convergence map f_ = convergence_integrals.potential_from_kappa_grid( kappa_map, grid_spacing ) # perform the lensing potential calculation from the convergence map (attention: arbitrary normalization) kwargs_interp = { 'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': f_, 'f_x': f_x, 'f_y': f_y } # keyword arguments of the interpolation model kwargs_lens_interp.append(kwargs_interp) self.kwargs_lens = kwargs_lens self.kwargs_lens_interp = kwargs_lens_interp self.lightCone = LightCone( mass_map_list, grid_spacing_list_mpc, redshift_list ) # here we make the instance of the LightCone class based on the mass map, physical grid spacing and redshifts. def test_ray_shooting(self): beta_x, beta_y = self._lensmodel.ray_shooting(2., 1., self.kwargs_lens) beta_x_num, beta_y_num = self._lens_model_interp.ray_shooting( 2., 1., self.kwargs_lens_interp) npt.assert_almost_equal(beta_x_num, beta_x, decimal=1) npt.assert_almost_equal(beta_y_num, beta_y, decimal=1) lens_model, kwargs_lens = self.lightCone.cone_instance( z_source=self._z_source, cosmo=self._cosmo, multi_plane=True) assert len(lens_model.lens_model_list) == 3 beta_x_cone, beta_y_cone = lens_model.ray_shooting(2., 1., kwargs_lens) npt.assert_almost_equal(kwargs_lens[0]['grid_interp_x'], self.kwargs_lens_interp[0]['grid_interp_x'], decimal=5) npt.assert_almost_equal(kwargs_lens[0]['grid_interp_y'], self.kwargs_lens_interp[0]['grid_interp_y'], decimal=5) npt.assert_almost_equal(kwargs_lens[0]['f_x'], self.kwargs_lens_interp[0]['f_x'], decimal=5) npt.assert_almost_equal(kwargs_lens[0]['f_y'], self.kwargs_lens_interp[0]['f_y'], decimal=5) npt.assert_almost_equal(beta_x_cone, beta_x_num, decimal=5) npt.assert_almost_equal(beta_y_cone, beta_y_num, decimal=5) def test_deflection(self): alpha_x, alpha_y = self._lensmodel.alpha(2, 1, self.kwargs_lens) alpha_x_num, alpha_y_num = self._lens_model_interp.alpha( 2, 1, self.kwargs_lens_interp) npt.assert_almost_equal(alpha_x_num, alpha_x, decimal=3) npt.assert_almost_equal(alpha_y_num, alpha_y, decimal=3) lens_model, kwargs_lens = self.lightCone.cone_instance( z_source=self._z_source, cosmo=self._cosmo, multi_plane=True) alpha_x_cone, alpha_y_cone = lens_model.alpha(2, 1, kwargs_lens) npt.assert_almost_equal(alpha_x_cone, alpha_x, decimal=3) npt.assert_almost_equal(alpha_y_cone, alpha_y, decimal=3) def test_arrival_time(self): x = np.array([1, 1]) y = np.array([0, 1]) f_ = self._lensmodel.arrival_time(x, y, self.kwargs_lens) f_num = self._lens_model_interp.arrival_time(x, y, self.kwargs_lens_interp) npt.assert_almost_equal(f_num[0] - f_num[1], f_[0] - f_[1], decimal=1) lens_model, kwargs_lens = self.lightCone.cone_instance( z_source=self._z_source, cosmo=self._cosmo, multi_plane=True) f_cone = lens_model.arrival_time(x, y, kwargs_lens) npt.assert_almost_equal(f_cone[0] - f_cone[1], f_[0] - f_[1], decimal=1)
class TestLensModel(object): """ tests the source model routines """ def setup(self): self.lensModel = LensModel(['GAUSSIAN']) self.kwargs = [{ 'amp': 1., 'sigma_x': 2., 'sigma_y': 2., 'center_x': 0., 'center_y': 0. }] def test_init(self): lens_model_list = [ 'FLEXION', 'SIS_TRUNCATED', 'SERSIC', 'SERSIC_ELLIPSE', 'PJAFFE', 'PJAFFE_ELLIPSE', 'HERNQUIST_ELLIPSE', 'INTERPOL', 'INTERPOL_SCALED', 'SHAPELETS_POLAR', 'DIPOLE', 'GAUSSIAN_KAPPA_ELLIPSE', 'MULTI_GAUSSIAN_KAPPA', 'MULTI_GAUSSIAN_KAPPA_ELLIPSE', 'CHAMELEON', 'DOUBLE_CHAMELEON' ] lensModel = LensModel(lens_model_list) assert len(lensModel.lens_model_list) == len(lens_model_list) lens_model_list = ['NFW'] lensModel = LensModel(lens_model_list, interpol=True, lookup=True) x, y = 0.2, 1 kwargs = [{'theta_Rs': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0}] value = lensModel.potential(x, y, kwargs) nfw_interp = NFW(interpol=True, lookup=True) value_interp_lookup = nfw_interp.function(x, y, **kwargs[0]) npt.assert_almost_equal(value, value_interp_lookup, decimal=4) def test_kappa(self): output = self.lensModel.kappa(x=1., y=1., kwargs=self.kwargs) assert output == -0.0058101559832649833 def test_potential(self): output = self.lensModel.potential(x=1., y=1., kwargs=self.kwargs) assert output == 0.77880078307140488 / (8 * np.pi) def test_alpha(self): output1, output2 = self.lensModel.alpha(x=1., y=1., kwargs=self.kwargs) assert output1 == -0.19470019576785122 / (8 * np.pi) assert output2 == -0.19470019576785122 / (8 * np.pi) def test_gamma(self): output1, output2 = self.lensModel.gamma(x=1., y=1., kwargs=self.kwargs) assert output1 == 0 assert output2 == 0.048675048941962805 / (8 * np.pi) def test_magnification(self): output = self.lensModel.magnification(x=1., y=1., kwargs=self.kwargs) assert output == 0.98848384784633392 def test_ray_shooting(self): delta_x, delta_y = self.lensModel.ray_shooting(x=1., y=1., kwargs=self.kwargs) assert delta_x == 1 + 0.19470019576785122 / (8 * np.pi) assert delta_y == 1 + 0.19470019576785122 / (8 * np.pi) def test_arrival_time(self): z_lens = 0.5 z_source = 1.5 x_image, y_image = 1., 0 lensModel = LensModel(lens_model_list=['SIS'], multi_plane=True, redshift_list=[z_lens], z_source=z_source) kwargs = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}] arrival_time_mp = lensModel.arrival_time(x_image, y_image, kwargs) lensModel_sp = LensModel(lens_model_list=['SIS'], z_source=z_source, z_lens=z_lens) arrival_time_sp = lensModel_sp.arrival_time(x_image, y_image, kwargs) npt.assert_almost_equal(arrival_time_sp, arrival_time_mp, decimal=8)
def test_foreground_shear(self): """ scenario: a shear field in the foreground of the main deflector is placed we compute the expected shear on the lens plain and effectively model the same system in a single plane configuration We check for consistency of the two approaches and whether the specific redshift of the foreground shear field has an impact on the arrival time surface :return: """ z_source = 1.5 z_lens = 0.5 z_shear = 0.2 x, y = np.array([1., 0.]), np.array([0., 2.]) from astropy.cosmology import default_cosmology from lenstronomy.Cosmo.background import Background cosmo = default_cosmology.get() cosmo_bkg = Background(cosmo) e1, e2 = 0.01, 0.01 # shear terms caused by z_shear on z_source lens_model_list = ['SIS', 'SHEAR'] redshift_list = [z_lens, z_shear] lensModelMutli = MultiPlane(z_source=z_source, lens_model_list=lens_model_list, lens_redshift_list=redshift_list) kwargs_lens_multi = [{ 'theta_E': 1, 'center_x': 0, 'center_y': 0 }, { 'e1': e1, 'e2': e2 }] alpha_x_multi, alpha_y_multi = lensModelMutli.alpha( x, y, kwargs_lens_multi) t_multi = lensModelMutli.arrival_time(x, y, kwargs_lens_multi) dt_multi = t_multi[0] - t_multi[1] physical_shear = cosmo_bkg.D_xy(0, z_source) / cosmo_bkg.D_xy( z_shear, z_source) foreground_factor = cosmo_bkg.D_xy(z_shear, z_lens) / cosmo_bkg.D_xy( 0, z_lens) * physical_shear print(foreground_factor) lens_model_simple_list = ['SIS', 'FOREGROUND_SHEAR', 'SHEAR'] kwargs_lens_single = [{ 'theta_E': 1, 'center_x': 0, 'center_y': 0 }, { 'e1': e1 * foreground_factor, 'e2': e2 * foreground_factor }, { 'e1': e1, 'e2': e2 }] lensModel = LensModel(lens_model_list=lens_model_simple_list) alpha_x_simple, alpha_y_simple = lensModel.alpha( x, y, kwargs_lens_single) npt.assert_almost_equal(alpha_x_simple, alpha_x_multi, decimal=8) npt.assert_almost_equal(alpha_y_simple, alpha_y_multi, decimal=8) ra_source, dec_source = lensModel.ray_shooting(x, y, kwargs_lens_single) ra_source_multi, dec_source_multi = lensModelMutli.ray_shooting( x, y, kwargs_lens_multi) npt.assert_almost_equal(ra_source, ra_source_multi, decimal=8) npt.assert_almost_equal(dec_source, dec_source_multi, decimal=8) fermat_pot = lensModel.fermat_potential(x, y, ra_source, dec_source, kwargs_lens_single) from lenstronomy.Cosmo.lens_cosmo import LensCosmo lensCosmo = LensCosmo(z_lens, z_source, cosmo=cosmo) Dt = lensCosmo.D_dt print(lensCosmo.D_dt) #t_simple = const.delay_arcsec2days(fermat_pot, Dt) t_simple = lensCosmo.time_delay_units(fermat_pot) dt_simple = t_simple[0] - t_simple[1] print(t_simple, t_multi) npt.assert_almost_equal(dt_simple / dt_multi, 1, decimal=2)
class TestLensModel(object): """ tests the source model routines """ def setup(self): self.lensModel = LensModel(['GAUSSIAN']) self.kwargs = [{ 'amp': 1., 'sigma_x': 2., 'sigma_y': 2., 'center_x': 0., 'center_y': 0. }] def test_init(self): lens_model_list = [ 'FLEXION', 'SIS_TRUNCATED', 'SERSIC', 'SERSIC_ELLIPSE', 'SERSIC_DOUBLE', 'COMPOSITE', 'PJAFFE', 'PJAFFE_ELLIPSE', 'HERNQUIST_ELLIPSE', 'INTERPOL', 'INTERPOL_SCALED', 'SHAPELETS_POLAR', 'DIPOLE' ] lensModel = LensModel(lens_model_list) assert len(lensModel.lens_model_list) == len(lens_model_list) def test_mass(self): output = self.lensModel.mass(x=1., y=1., epsilon_crit=1.9e+15, kwargs=self.kwargs) npt.assert_almost_equal(output, -11039296368203.469, decimal=5) def test_kappa(self): output = self.lensModel.kappa(x=1., y=1., kwargs=self.kwargs) assert output == -0.0058101559832649833 def test_potential(self): output = self.lensModel.potential(x=1., y=1., kwargs=self.kwargs) assert output == 0.77880078307140488 / (8 * np.pi) def test_alpha(self): output1, output2 = self.lensModel.alpha(x=1., y=1., kwargs=self.kwargs) assert output1 == -0.19470019576785122 / (8 * np.pi) assert output2 == -0.19470019576785122 / (8 * np.pi) def test_gamma(self): output1, output2 = self.lensModel.gamma(x=1., y=1., kwargs=self.kwargs) assert output1 == 0 assert output2 == 0.048675048941962805 / (8 * np.pi) def test_magnification(self): output = self.lensModel.magnification(x=1., y=1., kwargs=self.kwargs) assert output == 0.98848384784633392 def test_ray_shooting(self): delta_x, delta_y = self.lensModel.ray_shooting(x=1., y=1., kwargs=self.kwargs) assert delta_x == 1 + 0.19470019576785122 / (8 * np.pi) assert delta_y == 1 + 0.19470019576785122 / (8 * np.pi) def test_mass_2d(self): lensModel = LensModel(['GAUSSIAN_KAPPA']) output = lensModel.mass_2d(r=1, kwargs=self.kwargs) assert output == 0.11750309741540453