def test_raise(self): with self.assertRaises(ValueError): array = np.ones(5) util.array2image(array) with self.assertRaises(ValueError): array = np.ones((2, 2)) util.array2cube(array, 2, 2) with self.assertRaises(ValueError): x, y = np.ones(6), np.ones(6) util.get_axes(x, y) with self.assertRaises(ValueError): util.selectBest(array=np.ones(6), criteria=np.ones(5), numSelect=1, highest=True) with self.assertRaises(ValueError): util.select_best(array=np.ones(6), criteria=np.ones(5), num_select=1, highest=True) with self.assertRaises(ValueError): util.convert_bool_list(n=2, k=[3, 7]) with self.assertRaises(ValueError): util.convert_bool_list(n=3, k=[True, True]) with self.assertRaises(ValueError): util.convert_bool_list(n=2, k=[0.1, True])
def test_raise(self): with self.assertRaises(ValueError): array = np.ones(5) util.array2image(array) with self.assertRaises(ValueError): x, y = np.ones(6), np.ones(6) util.get_axes(x, y) with self.assertRaises(ValueError): util.selectBest(array=np.ones(6), criteria=np.ones(5), numSelect=1, highest=True)
def test_get_axes(): numPix = 11 deltapix = 0.1 x_grid, y_grid = Util.make_grid(numPix, deltapix) x_axes, y_axes = Util.get_axes(x_grid, y_grid) assert x_axes[0] == -0.5 assert y_axes[0] == -0.5 assert x_axes[1] == -0.4 assert y_axes[1] == -0.4 x_grid += 1 x_axes, y_axes = Util.get_axes(x_grid, y_grid) assert x_axes[0] == 0.5 assert y_axes[0] == -0.5
def test_get_axes(): numPix = 11 deltapix = 0.1 x_grid, y_grid = util.make_grid(numPix, deltapix) x_axes, y_axes = util.get_axes(x_grid, y_grid) npt.assert_almost_equal(x_axes[0], -0.5, decimal=12) npt.assert_almost_equal(y_axes[0], -0.5, decimal=12) npt.assert_almost_equal(x_axes[1], -0.4, decimal=12) npt.assert_almost_equal(y_axes[1], -0.4, decimal=12) x_grid += 1 x_axes, y_axes = util.get_axes(x_grid, y_grid) npt.assert_almost_equal(x_axes[0], 0.5, decimal=12) npt.assert_almost_equal(y_axes[0], -0.5, decimal=12)
def test_do_interpol(self): numPix = 101 deltaPix = 0.1 x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) sis = SIS() kwargs_SIS = {'theta_E': 1., 'center_x': 0.5, 'center_y': -0.5} f_sis = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x_sis, f_y_sis = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) f_xx_sis, f_yy_sis, f_xy_sis = sis.hessian(x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) interp_func = Interpol_func() interp_func_loop = Interpol_func(grid=False) interp_func.do_interp(x_axes, y_axes, util.array2image(f_sis), util.array2image(f_x_sis), util.array2image(f_y_sis), util.array2image(f_xx_sis), util.array2image(f_yy_sis), util.array2image(f_xy_sis)) interp_func_loop.do_interp(x_axes, y_axes, util.array2image(f_sis), util.array2image(f_x_sis), util.array2image(f_y_sis), util.array2image(f_xx_sis), util.array2image(f_yy_sis), util.array2image(f_xy_sis)) # test derivatives assert interp_func.derivatives(1, 0) == sis.derivatives( 1, 0, **kwargs_SIS) assert interp_func.derivatives(1, 0) == interp_func_loop.derivatives( 1, 0) alpha1_interp, alpha2_interp = interp_func.derivatives( np.array([0, 1, 0, 1]), np.array([1, 1, 2, 2])) alpha1_interp_loop, alpha2_interp_loop = interp_func_loop.derivatives( np.array([0, 1, 0, 1]), np.array([1, 1, 2, 2])) alpha1_true, alpha2_true = sis.derivatives(np.array([0, 1, 0, 1]), np.array([1, 1, 2, 2]), **kwargs_SIS) assert alpha1_interp[0] == alpha1_true[0] assert alpha1_interp[1] == alpha1_true[1] assert alpha1_interp[0] == alpha1_interp_loop[0] assert alpha1_interp[1] == alpha1_interp_loop[1] # test hessian assert interp_func.hessian(1, 0) == sis.hessian(1, 0, **kwargs_SIS) f_xx_interp, f_yy_interp, f_xy_interp = interp_func.hessian( np.array([0, 1, 0, 1]), np.array([1, 1, 2, 2])) f_xx_interp_loop, f_yy_interp_loop, f_xy_interp_loop = interp_func_loop.hessian( np.array([0, 1, 0, 1]), np.array([1, 1, 2, 2])) f_xx_true, f_yy_true, f_xy_true = sis.hessian(np.array([0, 1, 0, 1]), np.array([1, 1, 2, 2]), **kwargs_SIS) assert f_xx_interp[0] == f_xx_true[0] assert f_xx_interp[1] == f_xx_true[1] assert f_xy_interp[0] == f_xy_true[0] assert f_xy_interp[1] == f_xy_true[1] assert f_xx_interp[0] == f_xx_interp_loop[0] assert f_xx_interp[1] == f_xx_interp_loop[1] assert f_xy_interp[0] == f_xy_interp_loop[0] assert f_xy_interp[1] == f_xy_interp_loop[1]
def function(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): self._check_interp(grid_interp_x, grid_interp_y, f_, f_x, f_y, f_xx, f_yy, f_xy) n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_ = self.f_interp(y, x) return f_[0][0] else: if self._grid: x_axes, y_axes = util.get_axes(x, y) f_ = self.f_interp(y_axes, x_axes) f_ = util.image2array(f_) else: n = len(x) f_ = np.zeros(n) for i in range(n): f_[i] = self.f_interp(y[i], x[i]) return f_
def derivatives(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ returns df/dx and df/dy of the function :param x: x-coordinate (angular position), float or numpy array :param y: y-coordinate (angular position), float or numpy array :param grid_interp_x: numpy array (ascending) to mark the x-direction of the interpolation grid :param grid_interp_y: numpy array (ascending) to mark the y-direction of the interpolation grid :param f_: 2d numpy array of lensing potential, matching the grids in grid_interp_x and grid_interp_y :param f_x: 2d numpy array of deflection in x-direction, matching the grids in grid_interp_x and grid_interp_y :param f_y: 2d numpy array of deflection in y-direction, matching the grids in grid_interp_x and grid_interp_y :param f_xx: 2d numpy array of df/dxx, matching the grids in grid_interp_x and grid_interp_y :param f_yy: 2d numpy array of df/dyy, matching the grids in grid_interp_x and grid_interp_y :param f_xy: 2d numpy array of df/dxy, matching the grids in grid_interp_x and grid_interp_y :return: f_x, f_y at interpolated positions (x, y) """ n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_x_out = self.f_x_interp(x, y, grid_interp_x, grid_interp_y, f_x) f_y_out = self.f_y_interp(x, y, grid_interp_x, grid_interp_y, f_y) return f_x_out, f_y_out else: if self._grid and n >= self._min_grid_number: x_, y_ = util.get_axes(x, y) f_x_out = self.f_x_interp(x_, y_, grid_interp_x, grid_interp_y, f_x, grid=self._grid) f_y_out = self.f_y_interp(x_, y_, grid_interp_x, grid_interp_y, f_y, grid=self._grid) f_x_out = util.image2array(f_x_out) f_y_out = util.image2array(f_y_out) else: #n = len(x) f_x_out = self.f_x_interp(x, y, grid_interp_x, grid_interp_y, f_x) f_y_out = self.f_y_interp(x, y, grid_interp_x, grid_interp_y, f_y) return f_x_out, f_y_out
def function(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ :param x: x-coordinate (angular position), float or numpy array :param y: y-coordinate (angular position), float or numpy array :param grid_interp_x: numpy array (ascending) to mark the x-direction of the interpolation grid :param grid_interp_y: numpy array (ascending) to mark the y-direction of the interpolation grid :param f_: 2d numpy array of lensing potential, matching the grids in grid_interp_x and grid_interp_y :param f_x: 2d numpy array of deflection in x-direction, matching the grids in grid_interp_x and grid_interp_y :param f_y: 2d numpy array of deflection in y-direction, matching the grids in grid_interp_x and grid_interp_y :param f_xx: 2d numpy array of df/dxx, matching the grids in grid_interp_x and grid_interp_y :param f_yy: 2d numpy array of df/dyy, matching the grids in grid_interp_x and grid_interp_y :param f_xy: 2d numpy array of df/dxy, matching the grids in grid_interp_x and grid_interp_y :return: potential at interpolated positions (x, y) """ #self._check_interp(grid_interp_x, grid_interp_y, f_, f_x, f_y, f_xx, f_yy, f_xy) n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_out = self.f_interp(x, y, grid_interp_x, grid_interp_y, f_) return f_out else: if self._grid and n >= self._min_grid_number: x_axes, y_axes = util.get_axes(x, y) f_out = self.f_interp(x_axes, y_axes, grid_interp_x, grid_interp_y, f_, grid=self._grid) f_out = util.image2array(f_out) else: #n = len(x) f_out = np.zeros(n) for i in range(n): f_out[i] = self.f_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_) return f_out
def test_kwargs_interpolation(self): numPix = 101 deltaPix = 0.1 x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) sis = SIS() kwargs_SIS = {'theta_E': 1., 'center_x': 0.5, 'center_y': -0.5} f_sis = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x_sis, f_y_sis = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) f_xx_sis, f_yy_sis, f_xy_sis = sis.hessian(x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) interp_func = Interpol_func() kwargs_interp = { 'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': util.array2image(f_sis), 'f_x': util.array2image(f_x_sis), 'f_y': util.array2image(f_y_sis), 'f_xx': util.array2image(f_xx_sis), 'f_yy': util.array2image(f_yy_sis), 'f_xy': util.array2image(f_xy_sis) } x, y = 1., 1. alpha_x, alpha_y = interp_func.derivatives(x, y, **kwargs_interp) assert alpha_x == 0.31622776601683794 f_ = interp_func.function(x, y, **kwargs_interp) npt.assert_almost_equal(f_, 1.5811388300841898)
def hessian(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy :param x: x-coordinate (angular position), float or numpy array :param y: y-coordinate (angular position), float or numpy array :param grid_interp_x: numpy array (ascending) to mark the x-direction of the interpolation grid :param grid_interp_y: numpy array (ascending) to mark the y-direction of the interpolation grid :param f_: 2d numpy array of lensing potential, matching the grids in grid_interp_x and grid_interp_y :param f_x: 2d numpy array of deflection in x-direction, matching the grids in grid_interp_x and grid_interp_y :param f_y: 2d numpy array of deflection in y-direction, matching the grids in grid_interp_x and grid_interp_y :param f_xx: 2d numpy array of df/dxx, matching the grids in grid_interp_x and grid_interp_y :param f_yy: 2d numpy array of df/dyy, matching the grids in grid_interp_x and grid_interp_y :param f_xy: 2d numpy array of df/dxy, matching the grids in grid_interp_x and grid_interp_y :return: f_xx, f_yy, f_xy at interpolated positions (x, y) """ n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_xx_out = self.f_xx_interp(x, y, grid_interp_x, grid_interp_y, f_xx) f_yy_out = self.f_yy_interp(x, y, grid_interp_x, grid_interp_y, f_yy) f_xy_out = self.f_xy_interp(x, y, grid_interp_x, grid_interp_y, f_xy) return f_xx_out[0][0], f_yy_out[0][0], f_xy_out[0][0] else: if self._grid and n >= self._min_grid_number: x_, y_ = util.get_axes(x, y) f_xx_out = self.f_xx_interp(x_, y_, grid_interp_x, grid_interp_y, f_xx) f_yy_out = self.f_yy_interp(x_, y_, grid_interp_x, grid_interp_y, f_yy) f_xy_out = self.f_xy_interp(x_, y_, grid_interp_x, grid_interp_y, f_xy) f_xx_out = util.image2array(f_xx_out) f_yy_out = util.image2array(f_yy_out) f_xy_out = util.image2array(f_xy_out) else: #n = len(x) f_xx_out, f_yy_out, f_xy_out = np.zeros(n), np.zeros( n), np.zeros(n) for i in range(n): f_xx_out[i] = self.f_xx_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_xx) f_yy_out[i] = self.f_yy_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_yy) f_xy_out[i] = self.f_xy_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_xy) return f_xx_out, f_yy_out, f_xy_out
def test_hessian_finite_differential(self): numPix = 101 deltaPix = 0.1 x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) sis = SIS() kwargs_SIS = {'theta_E': 1., 'center_x': 0.5, 'center_y': -0.5} f_sis = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x_sis, f_y_sis = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) interp_func = Interpol() kwargs_interp = { 'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': util.array2image(f_sis), 'f_x': util.array2image(f_x_sis), 'f_y': util.array2image(f_y_sis) } x, y = 1., 0. f_xx, f_xy, f_yx, f_yy = interp_func.hessian(x, y, **kwargs_interp) f_xx_true, f_xy_true, f_yx_true, f_yy_true = sis.hessian( x, y, **kwargs_SIS) npt.assert_almost_equal(f_xx, f_xx_true, decimal=1) npt.assert_almost_equal(f_xy, f_xy_true, decimal=1) npt.assert_almost_equal(f_yx, f_yx_true, decimal=1) npt.assert_almost_equal(f_yy, f_yy_true, decimal=1)
def function(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): #self._check_interp(grid_interp_x, grid_interp_y, f_, f_x, f_y, f_xx, f_yy, f_xy) n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_out = self.f_interp(x, y, grid_interp_x, grid_interp_y, f_) return f_out[0][0] else: if self._grid and n >= self._min_grid_number: x_axes, y_axes = util.get_axes(x, y) f_out = self.f_interp(x_axes, y_axes, grid_interp_x, grid_interp_y, f_) f_out = util.image2array(f_out) else: #n = len(x) f_out = np.zeros(n) for i in range(n): f_out[i] = self.f_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_) return f_out
def hessian(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ returns Hessian matrix of function d^2f/dx^2, d^2/dxdy, d^2/dydx, d^f/dy^2 :param x: x-coordinate (angular position), float or numpy array :param y: y-coordinate (angular position), float or numpy array :param grid_interp_x: numpy array (ascending) to mark the x-direction of the interpolation grid :param grid_interp_y: numpy array (ascending) to mark the y-direction of the interpolation grid :param f_: 2d numpy array of lensing potential, matching the grids in grid_interp_x and grid_interp_y :param f_x: 2d numpy array of deflection in x-direction, matching the grids in grid_interp_x and grid_interp_y :param f_y: 2d numpy array of deflection in y-direction, matching the grids in grid_interp_x and grid_interp_y :param f_xx: 2d numpy array of df/dxx, matching the grids in grid_interp_x and grid_interp_y :param f_yy: 2d numpy array of df/dyy, matching the grids in grid_interp_x and grid_interp_y :param f_xy: 2d numpy array of df/dxy, matching the grids in grid_interp_x and grid_interp_y :return: f_xx, f_xy, f_yx, f_yy at interpolated positions (x, y) """ if not (hasattr(self, '_f_xx_interp')) and (f_xx is None or f_yy is None or f_xy is None): diff = 0.000001 alpha_ra_pp, alpha_dec_pp = self.derivatives(x + diff / 2, y + diff / 2, grid_interp_x=grid_interp_x, grid_interp_y=grid_interp_y, f_=f_, f_x=f_x, f_y=f_y) alpha_ra_pn, alpha_dec_pn = self.derivatives(x + diff / 2, y - diff / 2, grid_interp_x=grid_interp_x, grid_interp_y=grid_interp_y, f_=f_, f_x=f_x, f_y=f_y) alpha_ra_np, alpha_dec_np = self.derivatives(x - diff / 2, y + diff / 2, grid_interp_x=grid_interp_x, grid_interp_y=grid_interp_y, f_=f_, f_x=f_x, f_y=f_y) alpha_ra_nn, alpha_dec_nn = self.derivatives(x - diff / 2, y - diff / 2, grid_interp_x=grid_interp_x, grid_interp_y=grid_interp_y, f_=f_, f_x=f_x, f_y=f_y) f_xx_out = (alpha_ra_pp - alpha_ra_np + alpha_ra_pn - alpha_ra_nn) / diff / 2 f_xy_out = (alpha_ra_pp - alpha_ra_pn + alpha_ra_np - alpha_ra_nn) / diff / 2 f_yx_out = (alpha_dec_pp - alpha_dec_np + alpha_dec_pn - alpha_dec_nn) / diff / 2 f_yy_out = (alpha_dec_pp - alpha_dec_pn + alpha_dec_np - alpha_dec_nn) / diff / 2 return f_xx_out, f_xy_out, f_yx_out, f_yy_out n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_xx_out = self.f_xx_interp(x, y, grid_interp_x, grid_interp_y, f_xx) f_yy_out = self.f_yy_interp(x, y, grid_interp_x, grid_interp_y, f_yy) f_xy_out = self.f_xy_interp(x, y, grid_interp_x, grid_interp_y, f_xy) return f_xx_out, f_xy_out, f_xy_out, f_yy_out else: if self._grid and n >= self._min_grid_number: x_, y_ = util.get_axes(x, y) f_xx_out = self.f_xx_interp(x_, y_, grid_interp_x, grid_interp_y, f_xx, grid=self._grid) f_yy_out = self.f_yy_interp(x_, y_, grid_interp_x, grid_interp_y, f_yy, grid=self._grid) f_xy_out = self.f_xy_interp(x_, y_, grid_interp_x, grid_interp_y, f_xy, grid=self._grid) f_xx_out = util.image2array(f_xx_out) f_yy_out = util.image2array(f_yy_out) f_xy_out = util.image2array(f_xy_out) else: #n = len(x) f_xx_out, f_yy_out, f_xy_out = np.zeros(n), np.zeros(n), np.zeros(n) for i in range(n): f_xx_out[i] = self.f_xx_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_xx) f_yy_out[i] = self.f_yy_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_yy) f_xy_out[i] = self.f_xy_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_xy) return f_xx_out, f_xy_out, f_xy_out, f_yy_out
def test_effective_einstein_radius(self): kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}] lensModel = LensProfileAnalysis(LensModel(lens_model_list=['SIS'])) ret = lensModel.effective_einstein_radius(kwargs_lens, get_precision=True) assert len(ret) == 2 npt.assert_almost_equal(ret[0], 1., decimal=2) kwargs_lens_bad = [{'theta_E': 100, 'center_x': 0, 'center_y': 0}] ret_nan = lensModel.effective_einstein_radius(kwargs_lens_bad, get_precision=True, verbose=True) assert np.isnan(ret_nan) # test interpolated profile numPix = 101 deltaPix = 0.02 from lenstronomy.Util import util x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) from lenstronomy.LensModel.Profiles.sis import SIS sis = SIS() center_x, center_y = 0., -0. kwargs_SIS = { 'theta_E': 1., 'center_x': center_x, 'center_y': center_y } f_ = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x, f_y = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) f_xx, f_yy, f_xy = sis.hessian(x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) 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) }] lensModel = LensProfileAnalysis( LensModel(lens_model_list=['INTERPOL'])) theta_E_return = lensModel.effective_einstein_radius( kwargs_interpol, get_precision=False, verbose=True, center_x=center_x, center_y=center_y) npt.assert_almost_equal(theta_E_return, 1, decimal=2)
def hessian(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy """ #self._check_interp(grid_interp_x, grid_interp_y, f_, f_x, f_y, f_xx, f_yy, f_xy) n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_xx_out = self.f_xx_interp(x, y, grid_interp_x, grid_interp_y, f_xx) f_yy_out = self.f_yy_interp(x, y, grid_interp_x, grid_interp_y, f_yy) f_xy_out = self.f_xy_interp(x, y, grid_interp_x, grid_interp_y, f_xy) return f_xx_out[0][0], f_yy_out[0][0], f_xy_out[0][0] else: if self._grid and n >= self._min_grid_number: x_, y_ = util.get_axes(x, y) f_xx_out = self.f_xx_interp(x_, y_, grid_interp_x, grid_interp_y, f_xx) f_yy_out = self.f_yy_interp(x_, y_, grid_interp_x, grid_interp_y, f_yy) f_xy_out = self.f_xy_interp(x_, y_, grid_interp_x, grid_interp_y, f_xy) f_xx_out = util.image2array(f_xx_out) f_yy_out = util.image2array(f_yy_out) f_xy_out = util.image2array(f_xy_out) else: #n = len(x) f_xx_out, f_yy_out, f_xy_out = np.zeros(n), np.zeros( n), np.zeros(n) for i in range(n): f_xx_out[i] = self.f_xx_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_xx) f_yy_out[i] = self.f_yy_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_yy) f_xy_out[i] = self.f_xy_interp(x[i], y[i], grid_interp_x, grid_interp_y, f_xy) return f_xx_out, f_yy_out, f_xy_out
def test_interp_func_scaled(self): numPix = 101 deltaPix = 0.1 x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) sis = SIS() kwargs_SIS = {'theta_E': 1., 'center_x': 0.5, 'center_y': -0.5} f_sis = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x_sis, f_y_sis = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) f_xx_sis, f_xy_sis, f_yx_sis, f_yy_sis = sis.hessian( x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) kwargs_interp = { 'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': util.array2image(f_sis), 'f_x': util.array2image(f_x_sis), 'f_y': util.array2image(f_y_sis), 'f_xx': util.array2image(f_xx_sis), 'f_yy': util.array2image(f_yy_sis), 'f_xy': util.array2image(f_xy_sis) } interp_func = InterpolScaled(grid=False) x, y = 1., 1. alpha_x, alpha_y = interp_func.derivatives(x, y, scale_factor=1, **kwargs_interp) assert alpha_x == 0.31622776601683794 f_ = interp_func.function(x, y, scale_factor=1., **kwargs_interp) npt.assert_almost_equal(f_, 1.5811388300841898) f_xx, f_xy, f_yx, f_yy = interp_func.hessian(x, y, scale_factor=1., **kwargs_interp) npt.assert_almost_equal(f_xx, 0.56920997883030822, decimal=8) npt.assert_almost_equal(f_yy, 0.063245553203367583, decimal=8) npt.assert_almost_equal(f_xy, -0.18973665961010275, decimal=8) npt.assert_almost_equal(f_xy, f_yx, decimal=8) x_grid, y_grid = util.make_grid(10, deltaPix) f_xx, f_xy, f_yx, f_yy = interp_func.hessian(x_grid, y_grid, scale_factor=1., **kwargs_interp) npt.assert_almost_equal(f_xx[0], 0, decimal=2)
def __init__(self, mass_map, grid_spacing, redshift): """ :param mass_map: 2d numpy array of mass map (in units physical Msol) :param grid_spacing: grid spacing of the mass map (in units physical Mpc) :param redshift: redshift """ nx, ny = np.shape(mass_map) if nx != ny: raise ValueError('Shape of mass map needs to be square!, set as %s %s' % (nx, ny)) self._mass_map = mass_map self._grid_spacing = grid_spacing self._redshift = redshift self._f_x_mass, self._f_y_mass = convergence_integrals.deflection_from_kappa_grid(self._mass_map, self._grid_spacing) self._f_mass = convergence_integrals.potential_from_kappa_grid(self._mass_map, self._grid_spacing) x_grid, y_grid = util.make_grid(numPix=len(self._mass_map), deltapix=self._grid_spacing) self._x_axes_mpc, self._y_axes_mpc = util.get_axes(x_grid, y_grid)
def test_shift(self): numPix = 101 deltaPix = 0.1 x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) sis = SIS() kwargs_SIS = {'theta_E': 1., 'center_x': 0.5, 'center_y': -0.5} f_sis = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x_sis, f_y_sis = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) f_xx_sis, f_yy_sis, f_xy_sis = sis.hessian(x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) kwargs_interp = { 'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': util.array2image(f_sis), 'f_x': util.array2image(f_x_sis), 'f_y': util.array2image(f_y_sis), 'f_xx': util.array2image(f_xx_sis), 'f_yy': util.array2image(f_yy_sis), 'f_xy': util.array2image(f_xy_sis) } interp_func = Interpol(grid=False) x, y = 1., 1. alpha_x, alpha_y = interp_func.derivatives(x, y, **kwargs_interp) assert alpha_x == 0.31622776601683794 interp_func = Interpol(grid=False) x_shift = 1. kwargs_shift = { 'grid_interp_x': x_axes + x_shift, 'grid_interp_y': y_axes, 'f_': util.array2image(f_sis), 'f_x': util.array2image(f_x_sis), 'f_y': util.array2image(f_y_sis), 'f_xx': util.array2image(f_xx_sis), 'f_yy': util.array2image(f_yy_sis), 'f_xy': util.array2image(f_xy_sis) } alpha_x_shift, alpha_y_shift = interp_func.derivatives( x + x_shift, y, **kwargs_shift) npt.assert_almost_equal(alpha_x_shift, alpha_x, decimal=10)
def hessian(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy """ self._check_interp(grid_interp_x, grid_interp_y, f_, f_x, f_y, f_xx, f_yy, f_xy) n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_xx = self.f_xx_interp(y, x) f_yy = self.f_yy_interp(y, x) f_xy = self.f_xy_interp(y, x) return f_xx[0][0], f_yy[0][0], f_xy[0][0] else: if self._grid: x_, y_ = util.get_axes(x, y) f_xx = self.f_xx_interp(y_, x_) f_yy = self.f_yy_interp(y_, x_) f_xy = self.f_xy_interp(y_, x_) f_xx = util.image2array(f_xx) f_yy = util.image2array(f_yy) f_xy = util.image2array(f_xy) else: n = len(x) f_xx, f_yy, f_xy = np.zeros(n), np.zeros(n), np.zeros(n) for i in range(n): f_xx[i] = self.f_xx_interp(y[i], x[i]) f_yy[i] = self.f_yy_interp(y[i], x[i]) f_xy[i] = self.f_xy_interp(y[i], x[i]) return f_xx, f_yy, f_xy
def test_call(self): numPix = 101 deltaPix = 0.1 x_grid_interp, y_grid_interp = util.make_grid(numPix, deltaPix) sis = SIS() kwargs_SIS = {'theta_E': 1., 'center_x': 0.5, 'center_y': -0.5} f_sis = sis.function(x_grid_interp, y_grid_interp, **kwargs_SIS) f_x_sis, f_y_sis = sis.derivatives(x_grid_interp, y_grid_interp, **kwargs_SIS) f_xx_sis, f_yy_sis, f_xy_sis = sis.hessian(x_grid_interp, y_grid_interp, **kwargs_SIS) x_axes, y_axes = util.get_axes(x_grid_interp, y_grid_interp) interp_func = Interpol(grid=True) interp_func.do_interp(x_axes, y_axes, util.array2image(f_sis), util.array2image(f_x_sis), util.array2image(f_y_sis), util.array2image(f_xx_sis), util.array2image(f_yy_sis), util.array2image(f_xy_sis)) x, y = 1., 1. alpha_x, alpha_y = interp_func.derivatives(x, y, **{}) assert alpha_x == 0.31622776601683794
def derivatives(self, x, y, grid_interp_x=None, grid_interp_y=None, f_=None, f_x=None, f_y=None, f_xx=None, f_yy=None, f_xy=None): """ returns df/dx and df/dy of the function """ self._check_interp(grid_interp_x, grid_interp_y, f_, f_x, f_y, f_xx, f_yy, f_xy) n = len(np.atleast_1d(x)) if n <= 1 and np.shape(x) == (): #if type(x) == float or type(x) == int or type(x) == type(np.float64(1)) or len(x) <= 1: f_x = self.f_x_interp(y, x) f_y = self.f_y_interp(y, x) return f_x[0][0], f_y[0][0] else: if self._grid: x_, y_ = util.get_axes(x, y) f_x = self.f_x_interp(y_, x_) f_y = self.f_y_interp(y_, x_) f_x = util.image2array(f_x) f_y = util.image2array(f_y) else: n = len(x) f_x, f_y = np.zeros(n), np.zeros(n) for i in range(n): f_x[i] = self.f_x_interp(y[i], x[i]) f_y[i] = self.f_y_interp(y[i], x[i]) return f_x, f_y
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_res: subgrid for the numerical integrals :return: """ # make super-sampled grid x_grid_sub, y_grid_sub = util.make_grid(numPix=numPix * 5, deltapix=deltaPix, subgrid_res=subgrid_res) import lenstronomy.Util.mask_util 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 import convergence_integrals as integral # compute lensing quantities with subgrid convergence_sub = util.array2image(flux) f_x_sub, f_y_sub = integral.deflection_from_kappa_grid( convergence_sub, grid_spacing=deltaPix / float(subgrid_res)) f_sub = integral.potential_from_kappa_grid(convergence_sub, grid_spacing=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 interp_func = Interpol() 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.lens_model import LensModel lens_model = LensModel(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_model.hessian(x_grid, y_grid, kwargs, diff=0.00001) 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 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.