def test_sis_travel_time_new(self): z_source = 1.5 z_lens = 0.5 lens_model_list = ['SIS', 'SIS'] redshift_list = [z_lens, 0.2] 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 }, { 'theta_E': 0., 'center_x': 0, 'center_y': 0 }] dt = lensModelMutli.arrival_time(1., 0., kwargs_lens) Dt = lensModelMutli._multi_plane_base._cosmo_bkg.ddt(z_lens=z_lens, z_source=z_source) fermat_pot = lensModel.fermat_potential(1, 0., kwargs_lens) dt_simple = const.delay_arcsec2days(fermat_pot, Dt) print(dt, dt_simple) npt.assert_almost_equal(dt, dt_simple, decimal=8)
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_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)
bkg_noise=(1/2.*stddlong**2)**0.5 noiz[i]=np.random.normal(0, bkg_noise, size=rms[i].shape) image_data_noz[i]=noiz[i]+np.random.poisson(lam=bf_noz[i]*2*explong)/(2*explong) pyfits.PrimaryHDU(image_data_noz[i]).writeto(sim_folder_name+'/non_drizzled-image-{0}.fits'.format(i+1),overwrite=False) # pyfits.PrimaryHDU(rms[i]).writeto(sim_folder_name + '/non_drizzled-noise_map-{0}.fits'.format(i+1),overwrite=False) pyfits.PrimaryHDU(rms[i]**2).writeto(sim_folder_name+'/rmsSQ-{0}.fits'.format(i+1),overwrite=False) plt.matshow(np.log10(image_data_noz[0]),origin='lower') plt.colorbar() plt.show() #%% #============================================================================== # Time delay #============================================================================== TD_distance=(1+para.z_lens)*para.D_l*para.D_s/para.D_ls fermat_po=lens_model_class.fermat_potential(x_image, y_image, x_source=source_pos[0], y_source=source_pos[1], kwargs_lens=kwargs_lens_list) pix_ra, pix_dec= x_image/deltaPix+numPix/2., y_image/deltaPix+numPix/2. abc_list = ['A', 'B', 'C', 'D'] fig = plt.figure() ax = fig.add_subplot(111) for i in range(len(pix_ra)): x_, y_ =pix_ra[i], pix_dec[i] ax.plot(x_, y_, 'or') ax.text(x_, y_, abc_list[i], fontsize=20, color='k') ax.matshow(np.log10(image_highres),origin='lower') fig.savefig(sim_folder_name+'/ABCD.png') plt.show() TD = TD_distance/const.c * fermat_po / const.day_s * const.arcsec**2 * const.Mpc print("Time delay of ABCD - A :\n\t", TD-TD[0]) #%%Save infor
# ##### lens mass model #============================================================================== from lenstronomy.LensModel.lens_model import LensModel lens_model_list = ['PEMD','SHEAR'] lens_model_class = LensModel(lens_model_list) # print(folder) #Load the true parameter: model_lists, para_s, lens_info= pickle.load(open(folder+'/sim_kwargs.pkl','rb')) kwargs_lens_list = para_s[0] if len(para_s[-1]['ra_image']) < 4: # print(para_s[-1]['ra_image']) para_s[-1]['ra_image'], para_s[-1]['dec_image'] = para_s[-1]['ra_image'][:2], para_s[-1]['dec_image'][:2] x_image, y_image = para_s[-1]['ra_image'], para_s[-1]['dec_image'] source_pos = [para_s[2][0]['center_x'], para_s[2][0]['center_y']] potential = lens_model_class.potential(x_image, y_image, kwargs=kwargs_lens_list) fer_pot = lens_model_class.fermat_potential(x_image, y_image, kwargs_lens_list) geometry = potential + fer_pot # geometry = ((x_image - source_pos[0])**2 + (y_image - source_pos[1])**2) / 2. # print("potential:", potential, "geometry:", geometry) # #Load the inferred parameter: multi_band_list, kwargs_model, kwargs_result, chain_list, fix_setting, mcmc_new_list = pickle.load(open(folder+'/'+file_type,'rb')) # print(kwargs_result['kwargs_lens'][0]) # x_image_infe, y_image_infe = x_image, y_image # kwargs_lens_list_infe = kwargs_lens_list kwargs_lens_list_infe = kwargs_result['kwargs_lens'] if kwargs_result['kwargs_ps'] != []: x_image_infe, y_image_infe = kwargs_result['kwargs_ps'][0]['ra_image'], kwargs_result['kwargs_ps'][0]['dec_image'] else:
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
truth_dic = {} truth_dic['kwargs_lens'] =kwargs_lens_list truth_dic['kwargs_source'] =kwargs_source_list truth_dic['kwargs_lens_light'] =kwargs_lens_light_list truth_dic['kwargs_ps'] = kwargs_ps truth_dic['D_dt'] = TD_distance result_dic[folder+file_type] = [truth_dic, kwargs_result, chisq] #Take QSO postiion: qso_folder = folder_type[:-16] + 'ID_subg30_{0}/'.format(ID) _, _, kwargs_result_withQSO, _, _, _ = pickle.load(open(qso_folder+with_qso_savename,'rb')) lens_model_list = ['PEMD','SHEAR'] lens_model_class = LensModel(lens_model_list) #Calculate the Fermat potential using QSO position and inferred len parameter # x_image, y_image = kwargs_result_withQSO['kwargs_ps'][0]['ra_image'], kwargs_result_withQSO['kwargs_ps'][0]['dec_image'] x_image, y_image = kwargs_ps['ra_image'], kwargs_ps['dec_image'] f_potential = lens_model_class.fermat_potential(x_image, y_image, kwargs_lens=kwargs_result['kwargs_lens']) # TD = TD_distance/const.c * f_potential / const.day_s * const.arcsec**2 * const.Mpc result = op.minimize(nll, [TD_distance], args=(TD_obs, TD_err_l)) print(TD_distance, result["x"]) H0 = cal_h0(z_l ,z_s, result["x"]) H0_list.append(H0[0]) #%% H0_true = 73.907 fig, ax = plt.subplots(figsize=(11,8)) for i in range(len(folder_list)): folder = folder_list[i] H0 = H0_list[i] ID = int(folder[-3:]) key = folder_type + '{0}/'.format(ID) + file_type plt.scatter(ID, H0,
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 TestTDCosmography(object): def setup(self): kwargs_model = { 'lens_light_model_list': ['HERNQUIST'], 'lens_model_list': ['SIE'], 'point_source_model_list': ['LENSED_POSITION'] } z_lens = 0.5 z_source = 2.5 R_slit = 3.8 dR_slit = 1. aperture_type = 'slit' kwargs_aperture = { 'aperture_type': aperture_type, 'center_ra': 0, 'width': dR_slit, 'length': R_slit, 'angle': 0, 'center_dec': 0 } psf_fwhm = 0.7 kwargs_seeing = {'psf_type': 'GAUSSIAN', 'fwhm': psf_fwhm} TDCosmography(z_lens, z_source, kwargs_model) from astropy.cosmology import FlatLambdaCDM cosmo = FlatLambdaCDM(H0=70, Om0=0.3, Ob0=0.05) self.td_cosmo = TDCosmography(z_lens, z_source, kwargs_model, cosmo_fiducial=cosmo, lens_model_kinematics_bool=None, kwargs_aperture=kwargs_aperture, kwargs_seeing=kwargs_seeing, light_model_kinematics_bool=None) self.lens = LensModel(lens_model_list=['SIE'], cosmo=cosmo, z_lens=z_lens, z_source=z_source) self.solver = LensEquationSolver(lensModel=self.lens) self.kwargs_lens = [{ 'theta_E': 1, 'e1': 0.1, 'e2': -0.2, 'center_x': 0, 'center_y': 0 }] source_x, source_y = 0, 0.05 image_x, image_y = self.solver.image_position_from_source( source_x, source_y, self.kwargs_lens, min_distance=0.1, search_window=10) self.kwargs_ps = [{'ra_image': image_x, 'dec_image': image_y}] self.image_x, self.image_y = image_x, image_y def test_time_delays(self): dt = self.td_cosmo.time_delays(self.kwargs_lens, self.kwargs_ps, kappa_ext=0) dt_true = self.lens.arrival_time(self.image_x, self.image_y, self.kwargs_lens) npt.assert_almost_equal(dt, dt_true, decimal=6) def test_fermat_potential(self): fermat_pot = self.td_cosmo.fermat_potential(self.kwargs_lens, self.kwargs_ps) fermat_pot_true = self.lens.fermat_potential(self.image_x, self.image_y, self.kwargs_lens) npt.assert_almost_equal(fermat_pot, fermat_pot_true, decimal=6) diff = 0.1 kwargs_ps = [{ 'ra_image': self.image_x + diff, 'dec_image': self.image_y }] fermat_pot = self.td_cosmo.fermat_potential(self.kwargs_lens, kwargs_ps) fermat_pot_true = self.lens.fermat_potential(self.image_x + diff, self.image_y, self.kwargs_lens) ratio = fermat_pot / fermat_pot_true assert np.max(np.abs(ratio)) > 1.05 def test_cosmo_inference(self): # set up a cosmology # compute image postions # compute J and velocity dispersion D_dt = self.td_cosmo._lens_cosmo.ddt D_d = self.td_cosmo._lens_cosmo.dd D_s = self.td_cosmo._lens_cosmo.ds D_ds = self.td_cosmo._lens_cosmo.dds fermat_potential_list = self.td_cosmo.fermat_potential( self.kwargs_lens, self.kwargs_ps) dt_list = self.td_cosmo.time_delays(self.kwargs_lens, self.kwargs_ps, kappa_ext=0) dt = dt_list[0] - dt_list[1] d_fermat = fermat_potential_list[0] - fermat_potential_list[1] D_dt_infered = self.td_cosmo.ddt_from_time_delay( d_fermat_model=d_fermat, dt_measured=dt) npt.assert_almost_equal(D_dt_infered, D_dt, decimal=5) r_eff = 0.5 kwargs_lens_light = [{ 'Rs': r_eff * 0.551, 'center_x': 0, 'center_y': 0 }] kwargs_anisotropy = {'r_ani': 1} anisotropy_model = 'OM' kwargs_numerics_galkin = { 'interpol_grid_num': 500, 'log_integration': True, 'max_integrate': 10, 'min_integrate': 0.001 } self.td_cosmo.kinematics_modeling_settings(anisotropy_model, kwargs_numerics_galkin, analytic_kinematics=True, Hernquist_approx=False, MGE_light=False, MGE_mass=False) J = self.td_cosmo.velocity_dispersion_dimension_less( self.kwargs_lens, kwargs_lens_light, kwargs_anisotropy, r_eff=r_eff, theta_E=self.kwargs_lens[0]['theta_E'], gamma=2) J_map = self.td_cosmo.velocity_dispersion_map_dimension_less( self.kwargs_lens, kwargs_lens_light, kwargs_anisotropy, r_eff=r_eff, theta_E=self.kwargs_lens[0]['theta_E'], gamma=2) assert len(J_map) == 1 npt.assert_almost_equal(J_map[0] / J, 1, decimal=1) sigma_v2 = J * D_s / D_ds * const.c**2 sigma_v = np.sqrt(sigma_v2) / 1000. # convert to [km/s] print(sigma_v, 'test sigma_v') Ds_Dds = self.td_cosmo.ds_dds_from_kinematics(sigma_v, J, kappa_s=0, kappa_ds=0) npt.assert_almost_equal(Ds_Dds, D_s / D_ds) # now we perform a mass-sheet transform in the observables but leave the models identical with a convergence correction kappa_s = 0.5 dt_list = self.td_cosmo.time_delays(self.kwargs_lens, self.kwargs_ps, kappa_ext=kappa_s) sigma_v_kappa = sigma_v * np.sqrt(1 - kappa_s) dt = dt_list[0] - dt_list[1] D_dt_infered, D_d_infered = self.td_cosmo.ddt_dd_from_time_delay_and_kinematics( d_fermat_model=d_fermat, dt_measured=dt, sigma_v_measured=sigma_v_kappa, J=J, kappa_s=kappa_s, kappa_ds=0, kappa_d=0) npt.assert_almost_equal(D_dt_infered, D_dt, decimal=6) npt.assert_almost_equal(D_d_infered, D_d, decimal=6)