Ejemplo n.º 1
0
    def _subgrid_index(self, idex_mask, subgrid_res, nx, ny):
        """

        :param idex_mask: 1d array of mask of data
        :param subgrid_res: subgrid resolution
        :return: 1d array of equivalent mask in subgrid resolution
        """
        idex_sub = np.repeat(idex_mask, subgrid_res, axis=0)
        idex_sub = util.array2image(idex_sub, nx=nx, ny=ny * subgrid_res)
        idex_sub = np.repeat(idex_sub, subgrid_res, axis=0)
        idex_sub = util.image2array(idex_sub)
        return idex_sub
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    def cutout_psf(self, ra_image, dec_image, x, y, image_list, kernelsize, kernel_init, block_center_neighbour=0):
        """

        :param x_:
        :param y_:
        :param image_list: list of images (i.e. data - all models subtracted, except a single point source)
        :param kernelsize:
        :return:
        """
        mask = self._image_model_class.ImageNumerics.mask
        ra_grid, dec_grid = self._image_model_class.Data.coordinates
        ra_grid = util.image2array(ra_grid)
        dec_grid = util.image2array(dec_grid)
        radius = block_center_neighbour

        kernel_list = []
        for l in range(len(x)):
            mask_point_source = self.mask_point_source(ra_image, dec_image, ra_grid, dec_grid, radius, i=l)
            mask_i = mask * mask_point_source
            kernel_deshifted = self.cutout_psf_single(x[l], y[l], image_list[l], mask_i, kernelsize, kernel_init)
            kernel_list.append(kernel_deshifted)
        return kernel_list
Ejemplo n.º 5
0
 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_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[0][0], f_y_out[0][0]
     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)
             f_y_out = self.f_y_interp(x_, y_, grid_interp_x, grid_interp_y,
                                       f_y)
             f_x_out = util.image2array(f_x_out)
             f_y_out = util.image2array(f_y_out)
         else:
             #n = len(x)
             f_x_out, f_y_out = np.zeros(n), np.zeros(n)
             for i in range(n):
                 f_x_out[i] = self.f_x_interp(x[i], y[i], grid_interp_x,
                                              grid_interp_y, f_x)
                 f_y_out[i] = self.f_y_interp(x[i], y[i], grid_interp_x,
                                              grid_interp_y, f_y)
     return f_x_out, f_y_out
Ejemplo n.º 6
0
 def image2array(self, image):
     """
     returns 1d array of values in image in idex_mask
     :param image:
     :param idex_mask:
     :return:
     """
     idex_mask = self._idex_mask
     array = util.image2array(image)
     if self._idex_mask_bool is True:
         return array[idex_mask == 1]
     else:
         return array
Ejemplo n.º 7
0
    def __init__(self, multi_band_list, kwargs_model, model, error_map, cov_param, param, kwargs_params,
                 likelihood_mask_list=None, band_index=0, arrow_size=0.02, cmap_string="gist_heat"):

        self.bandmodel = SingleBandMultiModel(multi_band_list, kwargs_model,
                                                  likelihood_mask_list=likelihood_mask_list, band_index=band_index)
        self._kwargs_special_partial = kwargs_params.get('kwargs_special', None)
        kwarks_lens_partial, kwargs_source_partial, kwargs_lens_light_partial, kwargs_ps_partial, self._kwargs_extinction_partial = self.bandmodel.select_kwargs(**kwargs_params)
        self._kwargs_lens_partial, self._kwargs_source_partial, self._kwargs_lens_light_partial, self._kwargs_ps_partial = self.bandmodel.update_linear_kwargs(param, kwarks_lens_partial, kwargs_source_partial, kwargs_lens_light_partial, kwargs_ps_partial)
        self._norm_residuals = self.bandmodel.reduced_residuals(model, error_map=error_map)
        self._reduced_x2 = self.bandmodel.reduced_chi2(model, error_map=error_map)
        print("reduced chi^2 of data ", band_index, "= ", self._reduced_x2)

        self._model = model
        self._cov_param = cov_param
        self._param = param

        self._lensModel = self.bandmodel.LensModel
        self._lensModelExt = LensModelExtensions(self._lensModel)
        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)
        self._coords = self.bandmodel.Data
        self._data = self._coords.data
        self._deltaPix = self._coords.pixel_width
        self._frame_size = np.max(self._coords.width)
        x_grid, y_grid = self._coords.pixel_coordinates
        self._x_grid = util.image2array(x_grid)
        self._y_grid = util.image2array(y_grid)

        if isinstance(cmap_string, str):
            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
Ejemplo n.º 8
0
    def __init__(self,
                 data_class,
                 psf_class=None,
                 lens_model_class=None,
                 source_model_class=None,
                 lens_light_model_class=None,
                 point_source_class=None,
                 extinction_class=None,
                 kwargs_numerics=None,
                 likelihood_mask=None,
                 psf_error_map_bool_list=None,
                 kwargs_pixelbased=None):
        """

        :param data_class: ImageData() instance
        :param psf_class: PSF() instance
        :param lens_model_class: LensModel() instance
        :param source_model_class: LightModel() instance
        :param lens_light_model_class: LightModel() instance
        :param point_source_class: PointSource() instance
        :param kwargs_numerics: keyword arguments passed to the Numerics module
        :param likelihood_mask: 2d boolean array of pixels to be counted in the likelihood calculation/linear
         optimization
        :param psf_error_map_bool_list: list of boolean of length of point source models.
         Indicates whether PSF error map is used for the point source model stated as the index.
        :param kwargs_pixelbased: keyword arguments with various settings related to the pixel-based solver
         (see SLITronomy documentation) being applied to the point sources.
        """
        if likelihood_mask is None:
            likelihood_mask = np.ones_like(data_class.data)
        self.likelihood_mask = np.array(likelihood_mask, dtype=bool)
        self._mask1d = util.image2array(self.likelihood_mask)
        super(ImageLinearFit,
              self).__init__(data_class,
                             psf_class=psf_class,
                             lens_model_class=lens_model_class,
                             source_model_class=source_model_class,
                             lens_light_model_class=lens_light_model_class,
                             point_source_class=point_source_class,
                             extinction_class=extinction_class,
                             kwargs_numerics=kwargs_numerics,
                             kwargs_pixelbased=kwargs_pixelbased)
        if psf_error_map_bool_list is None:
            psf_error_map_bool_list = [True] * len(
                self.PointSource.point_source_type_list)
        self._psf_error_map_bool_list = psf_error_map_bool_list
        if self._pixelbased_bool is True:
            # update the pixel-based solver with the likelihood mask
            self.PixelSolver.set_likelihood_mask(self.likelihood_mask)
Ejemplo n.º 9
0
def convergence_plot(ax,
                     pixel_grid,
                     lens_model,
                     kwargs_lens,
                     extent=None,
                     vmin=-1,
                     vmax=1,
                     cmap='Greys',
                     **kwargs):
    """
    plot convergence

    :param ax: matplotlib axis instance
    :param pixel_grid: lenstronomy PixelGrid() instance (or class with inheritance of PixelGrid()
    :param lens_model: LensModel() class instance
    :param kwargs_lens: lens model keyword argument list
    :param extent: [[min, max] [min, max]] of frame
    :param vmin: matplotlib vmin
    :param vmax: matplotlib vmax
    :param cmap: matplotlib cmap
    :param kwargs: keyword arguments for matshow
    :return: matplotlib axis instance with convergence plot
    """
    x_grid, y_grid = pixel_grid.pixel_coordinates
    x_grid1d = util.image2array(x_grid)
    y_grid1d = util.image2array(y_grid)
    kappa_result = lens_model.kappa(x_grid1d, y_grid1d, kwargs_lens)
    kappa_result = util.array2image(kappa_result)
    _ = ax.matshow(np.log10(kappa_result),
                   origin='lower',
                   extent=extent,
                   cmap=cmap,
                   vmin=vmin,
                   vmax=vmax,
                   **kwargs)
    return ax
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
 def make_image_fixed_source(self,
                             param,
                             kwargs_options,
                             kwargs_data,
                             kwargs_lens,
                             kwargs_source,
                             kwargs_psf,
                             kwargs_lens_light,
                             kwargs_else,
                             add_noise=False):
     """
     make an image with fixed source parameters
     :param kwargs_lens:
     :param kwargs_source:
     :param kwargs_psf:
     :param kwargs_lens_light:
     :param kwargs_else:
     :return:
     """
     subgrid_res = kwargs_options['subgrid_res']
     num_order = kwargs_options.get('shapelet_order', 0)
     image = []
     residuals = []
     for i in range(self.num_bands(kwargs_data)):
         kwargs_data_i = kwargs_data[i]
         kwargs_psf_i = kwargs_psf["image" + str(i + 1)]
         param_i = param[i]
         deltaPix = kwargs_data_i['deltaPix']
         x_grid, y_grid = kwargs_data_i['x_coords'], kwargs_data_i[
             'y_coords']
         x_grid_sub, y_grid_sub = util.make_subgrid(x_grid, y_grid,
                                                    subgrid_res)
         numPix = len(kwargs_data_i['image_data'])
         makeImage = ImageModel(kwargs_options, kwargs_data_i)
         image_i, error_map = makeImage.make_image_with_params(
             x_grid_sub, y_grid_sub, kwargs_lens, kwargs_source,
             kwargs_psf_i, kwargs_lens_light, kwargs_else, numPix, deltaPix,
             subgrid_res, param_i, num_order)
         residuals_i = util.image2array(
             makeImage.reduced_residuals(image_i, error_map))
         residuals.append(residuals_i)
         if add_noise:
             image_i = makeImage.add_noise2image(image_i)
         image.append(image_i)
     return image, residuals
Ejemplo n.º 13
0
 def make_image_iteration(self, x_grid, y_grid, kwargs_lens, kwargs_source, kwargs_psf, kwargs_lens_light, kwargs_else, numPix, deltaPix, subgrid_res, inv_bool=False, no_lens=False):
     map_error = self.kwargs_options.get('error_map', False)
     num_order = self.kwargs_options.get('shapelet_order', 0)
     data = self.kwargs_data['image_data']
     mask = self.kwargs_options['mask']
     num_clumps = self.kwargs_options.get('num_clumps', 0)
     clump_scale = self.kwargs_options.get('clump_scale', 1)
     if no_lens is True:
         x_source, y_source = x_grid, y_grid
     else:
         x_source, y_source = self.mapping_IS(x_grid, y_grid, kwargs_else, **kwargs_lens)
     A, error_map, _ = self.get_response_matrix(x_grid, y_grid, x_source, y_source, kwargs_lens, kwargs_source, kwargs_psf, kwargs_lens_light, kwargs_else, numPix, deltaPix, subgrid_res, num_order, mask, map_error=map_error, shapelets_off=self.kwargs_options.get('shapelets_off', False))
     d = util.image2array(data*mask)
     param, cov_param, wls_model = self.DeLens.get_param_WLS(A.T, 1/(self.C_D+error_map), d, inv_bool=inv_bool)
     if num_clumps > 0:
         residuals = (wls_model-d)/np.sqrt(self.C_D+error_map)
         #ra_pos, dec_pos = self.find_max_residuals(residuals, self.ra_coords, self.dec_coords, num_clumps)
         #x_pos, y_pos, sigma = self.position_size_estimate(ra_pos, dec_pos, kwargs_lens, kwargs_else, deltaPix, clump_scale)
         x_pos, y_pos, sigma, ra_pos, dec_pos = self.find_clump_param(residuals, self.ra_coords, self.dec_coords, num_clumps, kwargs_lens, kwargs_else, deltaPix, clump_scale)
         if self.kwargs_options.get('source_clump_type', 'Gaussian') == 'Gaussian':
             A_clump = self.clump_response(x_source, y_source, x_pos, y_pos, sigma, deltaPix, numPix, subgrid_res, kwargs_psf, mask=mask)
         elif self.kwargs_options.get('source_clump_type', 'Gaussian') == 'Shapelets':
             A_clump = self.shapelet_response(x_source, y_source, x_pos, y_pos, sigma, deltaPix, numPix, subgrid_res, kwargs_psf, mask=mask, num_order=self.kwargs_options.get('num_order_clump', 1))
         else:
             raise ValueError("clump_type %s not valid." %(self.kwargs_options['source_clump_type']))
         A = np.append(A, A_clump, axis=0)
         param, cov_param, wls_model = self.DeLens.get_param_WLS(A.T, 1/(self.C_D+error_map), d, inv_bool=inv_bool)
     else:
         x_pos, y_pos, sigma, ra_pos, dec_pos = None, None, None, None, None
     grid_final = util.array2image(wls_model)
     if not self.kwargs_options['source_type'] == 'NONE':
         kwargs_source['I0_sersic'] = param[0]
         i = 1
     else:
         i = 0
     kwargs_lens_light['I0_sersic'] = param[i]
     if self.kwargs_options['lens_light_type'] == 'TRIPLE_SERSIC':
         kwargs_lens_light['I0_3'] = param[i+1]
         kwargs_lens_light['I0_2'] = param[i+2]
     if map_error is True:
          error_map = util.array2image(error_map)
     else:
         error_map = np.zeros_like(grid_final)
     return grid_final, error_map, cov_param, param,  x_pos, y_pos, sigma, ra_pos, dec_pos
Ejemplo n.º 14
0
 def clump_response(self, x_source, y_source, x_pos, y_pos, sigma, deltaPix, numPix, subgrid_res, kwargs_psf, mask=1):
     """
     response matrix of gaussian clumps
     :param x_source:
     :param y_source:
     :param x_pos:
     :param y_pos:
     :param sigma:
     :return:
     """
     num_param = len(sigma)
     A = np.zeros((num_param, numPix**2))
     for i in range(num_param):
         image = self.gaussian.function(x_source, y_source, amp=1, sigma_x=sigma[i], sigma_y=sigma[i], center_x=x_pos[i], center_y=y_pos[i])
         image = util.array2image(image)
         image = self.re_size_convolve(image, subgrid_res, kwargs_psf)
         response = util.image2array(image*mask)
         A[i, :] = response
     return A
Ejemplo n.º 15
0
    def __init__(self,
                 data_class,
                 psf_class=None,
                 lens_model_class=None,
                 source_model_class=None,
                 lens_light_model_class=None,
                 point_source_class=None,
                 extinction_class=None,
                 kwargs_numerics={},
                 likelihood_mask=None,
                 psf_error_map_bool_list=None):
        """

        :param data_class: ImageData() instance
        :param psf_class: PSF() instance
        :param lens_model_class: LensModel() instance
        :param source_model_class: LightModel() instance
        :param lens_light_model_class: LightModel() instance
        :param point_source_class: PointSource() instance
        :param kwargs_numerics: keyword arguments passed to the Numerics module
        :param likelihood_mask: 2d boolean array of pixels to be counted in the likelihood calculation/linear optimization
        :param psf_error_map_bool_list: list of boolean of length of point source models. Indicates whether PSF error map
        being applied to the point sources.
        """
        if likelihood_mask is None:
            likelihood_mask = np.ones_like(data_class.data)
        self.likelihood_mask = np.array(likelihood_mask, dtype=bool)
        self._mask1d = util.image2array(self.likelihood_mask)
        #kwargs_numerics['compute_indexes'] = self.likelihood_mask  # here we overwrite the indexes to be computed with the likelihood mask
        super(ImageLinearFit,
              self).__init__(data_class,
                             psf_class=psf_class,
                             lens_model_class=lens_model_class,
                             source_model_class=source_model_class,
                             lens_light_model_class=lens_light_model_class,
                             point_source_class=point_source_class,
                             extinction_class=extinction_class,
                             kwargs_numerics=kwargs_numerics)
        if psf_error_map_bool_list is None:
            psf_error_map_bool_list = [True] * len(
                self.PointSource.point_source_type_list)
        self._psf_error_map_bool_list = psf_error_map_bool_list
Ejemplo n.º 16
0
    def __init__(self, data_class, psf_class=None, lens_model_class=None, source_model_class=None,
                 lens_light_model_class=None, point_source_class=None, kwargs_numerics={}, likelihood_mask=None):
        """

        :param data_class:
        :param psf_class:
        :param lens_model_class:
        :param source_model_class:
        :param lens_light_model_class:
        :param point_source_class:
        :param kwargs_numerics:
        :param likelihood_mask: 2d boolean array of pixels to be counted in the likelihood calculation/linear optimization
        """
        super(ImageLinearFit, self).__init__(data_class, psf_class=psf_class, lens_model_class=lens_model_class,
                                             source_model_class=source_model_class,
                                             lens_light_model_class=lens_light_model_class,
                                             point_source_class=point_source_class, kwargs_numerics=kwargs_numerics)
        if likelihood_mask is None:
            likelihood_mask = np.ones_like(self.Data.data)
        self.likelihood_mask = np.array(likelihood_mask, dtype=bool)
        self._mask1d = util.image2array(self.likelihood_mask)
Ejemplo n.º 17
0
 def shapelet_response(self, x_source, y_source, x_pos, y_pos, sigma, deltaPix, numPix, subgrid_res, kwargs_psf, num_order=1, mask=1):
     """
     returns response matrix for general inputs
     :param x_grid:
     :param y_grid:
     :param kwargs_lens:
     :param kwargs_source:
     :param kwargs_psf:
     :param kwargs_lens_light:
     :param kwargs_else:
     :param numPix:
     :param deltaPix:
     :param subgrid_res:
     :return:
     """
     num_clump = len(x_pos)
     numShapelets = (num_order+2)*(num_order+1)/2
     num_param = numShapelets*num_clump
     A = np.zeros((num_param, numPix**2))
     k = 0
     for j in range(0, num_clump):
         H_x, H_y = self.shapelets.pre_calc(x_source, y_source, sigma[j], num_order, x_pos[j], y_pos[j])
         n1 = 0
         n2 = 0
         for i in range(0, numShapelets):
             kwargs_source_shapelet = {'center_x': x_pos[j], 'center_y': y_pos[j], 'n1': n1, 'n2': n2, 'beta': sigma[j], 'amp': 1}
             image = self.shapelets.function(H_x, H_y, **kwargs_source_shapelet)
             image = util.array2image(image)
             image = self.re_size_convolve(image, numPix, deltaPix, subgrid_res, kwargs_psf)
             response = util.image2array(image*mask)
             A[k, :] = response
             if n1 == 0:
                 n1 = n2 + 1
                 n2 = 0
             else:
                 n1 -= 1
                 n2 += 1
             k += 1
     return A
Ejemplo n.º 18
0
    def __init__(self,
                 nx,
                 ny,
                 transform_pix2angle,
                 ra_at_xy_0,
                 dec_at_xy_0,
                 supersampling_indexes,
                 supersampling_factor,
                 flux_evaluate_indexes=None):
        """

        :param nx: number of pixels in x-axis
        :param ny: number of pixels in y-axis
        :param transform_pix2angle: 2x2 matrix, mapping of pixel to coordinate
        :param ra_at_xy_0: ra coordinate at pixel (0,0)
        :param dec_at_xy_0: dec coordinate at pixel (0,0)
        :param supersampling_indexes: bool array of shape nx x ny, corresponding to pixels being super_sampled
        :param supersampling_factor: int, factor (per axis) of super-sampling
        :param flux_evaluate_indexes: bool array of shape nx x ny, corresponding to pixels being evaluated
        (for both low and high res). Default is None, replaced by setting all pixels to being evaluated.
        """
        super(AdaptiveGrid, self).__init__(transform_pix2angle, ra_at_xy_0,
                                           dec_at_xy_0)
        self._nx = nx
        self._ny = ny
        self._x_grid, self._y_grid = self.coordinate_grid(nx, ny)
        if flux_evaluate_indexes is None:
            flux_evaluate_indexes = np.ones_like(self._x_grid, dtype=bool)
        supersampled_indexes1d = util.image2array(supersampling_indexes)
        self._high_res_indexes1d = (supersampled_indexes1d) & (
            flux_evaluate_indexes)
        self._low_res_indexes1d = (np.invert(supersampled_indexes1d)) & (
            flux_evaluate_indexes)
        self._supersampling_factor = supersampling_factor
        self._num_sub = supersampling_factor * supersampling_factor
        self._x_low_res = self._x_grid[self._low_res_indexes1d]
        self._y_low_res = self._y_grid[self._low_res_indexes1d]
        self._num_low_res = len(self._x_low_res)
Ejemplo n.º 19
0
    def __init__(self,
                 nx,
                 ny,
                 transform_pix2angle,
                 ra_at_xy_0,
                 dec_at_xy_0,
                 supersampling_factor=1,
                 flux_evaluate_indexes=None):
        """

        :param nx: number of pixels in x-axis
        :param ny: number of pixels in y-axis
        :param transform_pix2angle: 2x2 matrix, mapping of pixel to coordinate
        :param ra_at_xy_0: ra coordinate at pixel (0,0)
        :param dec_at_xy_0: dec coordinate at pixel (0,0)
        :param supersampling_indexes: bool array of shape nx x ny, corresponding to pixels being super_sampled
        :param supersampling_factor: int, factor (per axis) of super-sampling
        :param flux_evaluate_indexes: bool array of shape nx x ny, corresponding to pixels being evaluated
        (for both low and high res). Default is None, replaced by setting all pixels to being evaluated.
        """
        super(RegularGrid, self).__init__(transform_pix2angle, ra_at_xy_0,
                                          dec_at_xy_0)
        self._supersampling_factor = supersampling_factor
        self._nx = nx
        self._ny = ny
        self._x_grid, self._y_grid = self.coordinate_grid(nx, ny)
        if flux_evaluate_indexes is None:
            flux_evaluate_indexes = np.ones_like(self._x_grid, dtype=bool)
        else:
            flux_evaluate_indexes = util.image2array(flux_evaluate_indexes)
        self._compute_indexes = self._subgrid_index(flux_evaluate_indexes,
                                                    self._supersampling_factor,
                                                    self._nx, self._ny)

        x_grid_sub, y_grid_sub = util.make_subgrid(self._x_grid, self._y_grid,
                                                   self._supersampling_factor)
        self._ra_subgrid = x_grid_sub[self._compute_indexes]
        self._dec_subgrid = y_grid_sub[self._compute_indexes]
Ejemplo n.º 20
0
    def error_map_estimate(self,
                           kernel,
                           star_cutout_list,
                           amp,
                           x_pos,
                           y_pos,
                           error_map_radius=None,
                           block_center_neighbour=0):
        """
        provides a psf_error_map based on the goodness of fit of the given PSF kernel on the point source cutouts,
        their estimated amplitudes and positions

        :param kernel: PSF kernel
        :param star_cutout_list: list of 2d arrays of cutouts of the point sources with all other model components subtracted
        :param amp: list of amplitudes of the estimated PSF kernel
        :param x_pos: pixel position (in original data unit, not in cutout) of the point sources (same order as amp and star cutouts)
        :param y_pos: pixel position (in original data unit, not in cutout) of the point sources (same order as amp and star cutouts)
        :param error_map_radius: float, radius (in arc seconds) of the outermost error in the PSF estimate (e.g. to avoid double counting of overlapping PSF erros)
        :param block_center_neighbour: angle, radius of neighbouring point sources around their centers the estimates
         is ignored. Default is zero, meaning a not optimal subtraction of the neighbouring point sources might
         contaminate the estimate.
        :return: relative uncertainty in the psf model (in quadrature) per pixel based on residuals achieved in the image
        """
        error_map_list = np.zeros(
            (len(star_cutout_list), len(kernel), len(kernel)))
        mask_list = np.zeros((len(star_cutout_list), len(kernel), len(kernel)))
        ra_grid, dec_grid = self._image_model_class.Data.pixel_coordinates
        ra_grid = util.image2array(ra_grid)
        dec_grid = util.image2array(dec_grid)
        mask = self._image_model_class.likelihood_mask
        for i, star in enumerate(star_cutout_list):
            x, y, amp_i = x_pos[i], y_pos[i], amp[i]
            # shift kernel
            x_int = int(round(x))
            y_int = int(round(y))
            shift_x = x_int - x
            shift_y = y_int - y
            kernel_shifted = interp.shift(kernel, [-shift_y, -shift_x],
                                          order=1)
            # multiply kernel with amplitude
            model = kernel_shifted * amp_i
            # compute residuals
            residual = np.abs(star - model)
            # subtract background and Poisson noise residuals
            C_D_cutout = kernel_util.cutout_source(
                x_int,
                y_int,
                self._image_model_class.Data.C_D,
                len(star),
                shift=False)
            # block neighbor points in error estimate
            mask_point_source = self.mask_point_source(
                x_pos,
                y_pos,
                ra_grid,
                dec_grid,
                radius=block_center_neighbour,
                i=i)
            mask_i = mask * mask_point_source
            mask_i = kernel_util.cutout_source(x_int,
                                               y_int,
                                               mask_i,
                                               len(star),
                                               shift=False)
            residual -= np.sqrt(C_D_cutout)
            residual[residual < 0] = 0
            # estimate relative error per star
            residual /= amp_i
            error_map_list[i, :, :] = residual**2 * mask_i
            mask_list[i, :, :] = mask_i
        # take median absolute error for each pixel
        # TODO: only for pixels that are not masked
        error_map = np.median(error_map_list, axis=0)
        error_map[kernel > 0] /= kernel[kernel > 0]**2
        error_map = np.nan_to_num(error_map)
        error_map[error_map > 1] = 1  # cap on error to be the same

        # mask the error map outside a certain radius (can avoid double counting of errors when map is overlapping
        if error_map_radius is not None:
            pixel_scale = self._image_model_class.Data.pixel_width
            x_grid, y_grid = util.make_grid(numPix=len(error_map),
                                            deltapix=pixel_scale)
            mask = mask_util.mask_azimuthal(x_grid,
                                            y_grid,
                                            center_x=0,
                                            center_y=0,
                                            r=error_map_radius)
            error_map *= util.array2image(mask)
        return error_map
Ejemplo n.º 21
0
def test_symmetry():
    array = np.linspace(0, 10, 100)
    image = util.array2image(array)
    array_new = util.image2array(image)
    assert array_new[42] == array[42]
Ejemplo n.º 22
0
def test_image2array():
    image = np.zeros((10, 10))
    image[1, 2] = 1
    array = util.image2array(image)
    assert array[12] == 1
Ejemplo n.º 23
0
def ext_shear_direction(data_class,
                        lens_model_class,
                        kwargs_lens,
                        strength_multiply=10):
    """

    :param kwargs_data:
    :param kwargs_psf:
    :param kwargs_options:
    :param lens_result:
    :param source_result:
    :param lens_light_result:
    :param else_result:
    :return:
    """
    x_grid, y_grid = data_class.pixel_coordinates
    x_grid = util.image2array(x_grid)
    y_grid = util.image2array(y_grid)
    shear = Shear()

    f_x_shear, f_y_shear = 0, 0
    for i, lens_model in enumerate(lens_model_class.lens_model_list):
        if lens_model == 'SHEAR':
            kwargs = kwargs_lens[i]
            f_x_shear, f_y_shear = shear.derivatives(
                x_grid,
                y_grid,
                e1=kwargs['e1'] * strength_multiply,
                e2=kwargs['e2'] * strength_multiply)
    x_shear = x_grid - f_x_shear
    y_shear = y_grid - f_y_shear

    f_x_foreground, f_y_foreground = 0, 0
    for i, lens_model in enumerate(lens_model_class.lens_model_list):
        if lens_model == 'FOREGROUND_SHEAR':
            kwargs = kwargs_lens[i]
            f_x_foreground, f_y_foreground = shear.derivatives(
                x_grid,
                y_grid,
                e1=kwargs['e1'] * strength_multiply,
                e2=kwargs['e2'] * strength_multiply)
    x_foreground = x_grid - f_x_foreground
    y_foreground = y_grid - f_y_foreground

    center_x = np.mean(x_grid)
    center_y = np.mean(y_grid)
    radius = (np.max(x_grid) - np.min(x_grid)) / 4
    circle_shear = util_mask.mask_sphere(x_shear, y_shear, center_x, center_y,
                                         radius)
    circle_foreground = util_mask.mask_sphere(x_foreground, y_foreground,
                                              center_x, center_y, radius)
    f, ax = plt.subplots(1, 1, figsize=(16, 8))
    im = ax.matshow(np.log10(data_class.data), origin='lower', alpha=0.5)
    im = ax.matshow(util.array2image(circle_shear),
                    origin='lower',
                    alpha=0.5,
                    cmap="jet")
    im = ax.matshow(util.array2image(circle_foreground),
                    origin='lower',
                    alpha=0.5)
    #f.show()
    return f, ax
Ejemplo n.º 24
0
    def psf_estimate_individual(self, ra_image, dec_image, point_amp,
                                residuals, cutout_size, kernel_guess,
                                supersampling_factor, block_center_neighbour):
        """

        :param ra_image: list; position in angular units of the image
        :param dec_image: list; position in angular units of the image
        :param point_amp: list of model amplitudes of point sources
        :param residuals: data - model
        :param cutout_size: pixel size of cutout around single star/quasar to be considered for the psf reconstruction
        :param kernel_guess: initial guess of super-sampled PSF
        :param supersampling_factor: int, super-sampling factor
        :param block_center_neighbour:
        :return: list of best-guess PSF's for each star based on the residual patterns
        """
        mask = self._image_model_class.likelihood_mask
        ra_grid, dec_grid = self._image_model_class.Data.pixel_coordinates
        ra_grid = util.image2array(ra_grid)
        dec_grid = util.image2array(dec_grid)
        radius = block_center_neighbour
        x_, y_ = self._image_model_class.Data.map_coord2pix(
            ra_image, dec_image)

        kernel_list = []
        for l in range(len(ra_image)):
            mask_point_source = self.mask_point_source(ra_image,
                                                       dec_image,
                                                       ra_grid,
                                                       dec_grid,
                                                       radius,
                                                       i=l)
            mask_i = mask * mask_point_source

            # cutout residuals
            x_int = int(round(x_[l]))
            y_int = int(round(y_[l]))
            residual_cutout = kernel_util.cutout_source(x_int,
                                                        y_int,
                                                        residuals,
                                                        cutout_size + 2,
                                                        shift=False)
            # cutout the mask
            mask_cutout = kernel_util.cutout_source(x_int,
                                                    y_int,
                                                    mask_i,
                                                    cutout_size + 2,
                                                    shift=False)
            # apply mask
            residual_cutout_mask = residual_cutout * mask_cutout
            # re-scale residuals with point source brightness
            residual_cutout_mask /= point_amp[l]
            # enlarge residuals by super-sampling factor
            residual_cutout_mask = residual_cutout_mask.repeat(
                supersampling_factor, axis=0).repeat(supersampling_factor,
                                                     axis=1)

            # inverse shift residuals
            shift_x = (x_int - x_[l]) * supersampling_factor
            shift_y = (y_int - y_[l]) * supersampling_factor
            # for odd number super-sampling
            if supersampling_factor % 2 == 1:
                residuals_shifted = ndimage.shift(residual_cutout_mask,
                                                  shift=[shift_y, shift_x],
                                                  order=1)

            else:
                # for even number super-sampling half a super-sampled pixel offset needs to be performed
                residuals_shifted = ndimage.shift(
                    residual_cutout_mask,
                    shift=[shift_y - 0.5, shift_x - 0.5],
                    order=1)
                # and the last column and row need to be removed
                residuals_shifted = residuals_shifted[:-1, :-1]

            # re-size shift residuals
            psf_size = len(kernel_guess)
            residuals_shifted = image_util.cut_edges(residuals_shifted,
                                                     psf_size)

            # normalize residuals
            correction = residuals_shifted - np.mean(residuals_shifted)
            # correct old PSF with inverse shifted residuals
            kernel_new = kernel_guess + correction
            kernel_list.append(kernel_new)
        return kernel_list
Ejemplo n.º 25
0
def lens_model_plot(ax,
                    lensModel,
                    kwargs_lens,
                    numPix=500,
                    deltaPix=0.01,
                    sourcePos_x=0,
                    sourcePos_y=0,
                    point_source=False,
                    with_caustics=False,
                    with_convergence=True,
                    coord_center_ra=0,
                    coord_center_dec=0,
                    coord_inverse=False,
                    fast_caustic=False):
    """
    plots a lens model (convergence) and the critical curves and caustics

    :param ax:
    :param kwargs_lens:
    :param numPix:
    :param deltaPix:
    :param fast_caustic: boolean, if True, uses faster but less precise caustic calculation
     (might have troubles for the outer caustic (inner critical curve)
    :param with_convergence: boolean, if True, plots the convergence of the deflector
    :return:
    """
    kwargs_data = sim_util.data_configure_simple(numPix,
                                                 deltaPix,
                                                 center_ra=coord_center_ra,
                                                 center_dec=coord_center_dec,
                                                 inverse=coord_inverse)
    data = ImageData(**kwargs_data)
    _coords = data
    _frame_size = numPix * deltaPix
    x_grid, y_grid = data.pixel_coordinates
    lensModelExt = LensModelExtensions(lensModel)
    x_grid1d = util.image2array(x_grid)
    y_grid1d = util.image2array(y_grid)
    if with_convergence:
        kappa_result = lensModel.kappa(x_grid1d, y_grid1d, kwargs_lens)
        kappa_result = util.array2image(kappa_result)
        im = ax.matshow(np.log10(kappa_result),
                        origin='lower',
                        extent=[0, _frame_size, 0, _frame_size],
                        cmap='Greys',
                        vmin=-1,
                        vmax=1)  #, cmap=self._cmap, vmin=v_min, vmax=v_max)
    if with_caustics is True:
        if fast_caustic:
            ra_crit_list, dec_crit_list, ra_caustic_list, dec_caustic_list = lensModelExt.critical_curve_caustics(
                kwargs_lens, compute_window=_frame_size, grid_scale=deltaPix)
            plot_util.plot_line_set_list(ax,
                                         _coords,
                                         ra_caustic_list,
                                         dec_caustic_list,
                                         color='g')
            plot_util.plot_line_set_list(ax,
                                         _coords,
                                         ra_crit_list,
                                         dec_crit_list,
                                         color='r')
        else:
            ra_crit_list, dec_crit_list = lensModelExt.critical_curve_tiling(
                kwargs_lens,
                compute_window=_frame_size,
                start_scale=deltaPix,
                max_order=10)
            ra_caustic_list, dec_caustic_list = lensModel.ray_shooting(
                ra_crit_list, dec_crit_list, kwargs_lens)
            plot_util.plot_line_set(ax,
                                    _coords,
                                    ra_caustic_list,
                                    dec_caustic_list,
                                    color='g')
            plot_util.plot_line_set(ax,
                                    _coords,
                                    ra_crit_list,
                                    dec_crit_list,
                                    color='r')
    if point_source:
        from lenstronomy.LensModel.Solver.lens_equation_solver import LensEquationSolver
        solver = LensEquationSolver(lensModel)
        theta_x, theta_y = solver.image_position_from_source(
            sourcePos_x,
            sourcePos_y,
            kwargs_lens,
            min_distance=deltaPix,
            search_window=deltaPix * numPix)
        mag_images = lensModel.magnification(theta_x, theta_y, kwargs_lens)
        x_image, y_image = _coords.map_coord2pix(theta_x, theta_y)
        abc_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
        for i in range(len(x_image)):
            x_ = (x_image[i] + 0.5) * deltaPix
            y_ = (y_image[i] + 0.5) * deltaPix
            ax.plot(x_,
                    y_,
                    'dk',
                    markersize=4 * (1 + np.log(np.abs(mag_images[i]))),
                    alpha=0.5)
            ax.text(x_, y_, abc_list[i], fontsize=20, color='k')
        x_source, y_source = _coords.map_coord2pix(sourcePos_x, sourcePos_y)
        ax.plot((x_source + 0.5) * deltaPix, (y_source + 0.5) * deltaPix,
                '*k',
                markersize=10)
    ax.set_xlim([0, _frame_size])
    ax.set_ylim([0, _frame_size])
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    ax.autoscale(False)
    return ax
Ejemplo n.º 26
0
    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
Ejemplo n.º 27
0
def distortions(lensModel,
                kwargs_lens,
                num_pix=100,
                delta_pix=0.05,
                center_ra=0,
                center_dec=0,
                differential_scale=0.0001,
                smoothing_scale=None,
                **kwargs):
    """

    :param lensModel: LensModel instance
    :param kwargs_lens: lens model keyword argument list
    :param num_pix: number of pixels per axis
    :param delta_pix: pixel scale per axis
    :param center_ra: center of the grid
    :param center_dec: center of the grid
    :param differential_scale: scale of the finite derivative length in units of angles
    :param smoothing_scale: float or None, Gaussian FWHM of a smoothing kernel applied before plotting
    :return: matplotlib instance with different panels
    """
    kwargs_grid = sim_util.data_configure_simple(num_pix,
                                                 delta_pix,
                                                 center_ra=center_ra,
                                                 center_dec=center_dec)
    _coords = ImageData(**kwargs_grid)
    _frame_size = num_pix * delta_pix
    ra_grid, dec_grid = _coords.pixel_coordinates

    extensions = LensModelExtensions(lensModel=lensModel)
    ra_grid1d = util.image2array(ra_grid)
    dec_grid1d = util.image2array(dec_grid)
    lambda_rad, lambda_tan, orientation_angle, dlambda_tan_dtan, dlambda_tan_drad, dlambda_rad_drad, dlambda_rad_dtan, dphi_tan_dtan, dphi_tan_drad, dphi_rad_drad, dphi_rad_dtan = extensions.radial_tangential_differentials(
        ra_grid1d,
        dec_grid1d,
        kwargs_lens=kwargs_lens,
        center_x=center_ra,
        center_y=center_dec,
        smoothing_3rd=differential_scale,
        smoothing_2nd=None)

    lambda_rad2d, lambda_tan2d, orientation_angle2d, dlambda_tan_dtan2d, dlambda_tan_drad2d, dlambda_rad_drad2d, dlambda_rad_dtan2d, dphi_tan_dtan2d, dphi_tan_drad2d, dphi_rad_drad2d, dphi_rad_dtan2d = util.array2image(lambda_rad), \
                                            util.array2image(lambda_tan), util.array2image(orientation_angle), util.array2image(dlambda_tan_dtan), util.array2image(dlambda_tan_drad), util.array2image(dlambda_rad_drad), util.array2image(dlambda_rad_dtan), \
                                            util.array2image(dphi_tan_dtan), util.array2image(dphi_tan_drad), util.array2image(dphi_rad_drad), util.array2image(dphi_rad_dtan)

    if smoothing_scale is not None:
        lambda_rad2d = ndimage.gaussian_filter(lambda_rad2d,
                                               sigma=smoothing_scale /
                                               delta_pix)
        dlambda_rad_drad2d = ndimage.gaussian_filter(dlambda_rad_drad2d,
                                                     sigma=smoothing_scale /
                                                     delta_pix)
        lambda_tan2d = np.abs(lambda_tan2d)
        # the magnification cut is made to make a stable integral/convolution
        lambda_tan2d[lambda_tan2d > 100] = 100
        lambda_tan2d = ndimage.gaussian_filter(lambda_tan2d,
                                               sigma=smoothing_scale /
                                               delta_pix)
        # the magnification cut is made to make a stable integral/convolution
        dlambda_tan_dtan2d[dlambda_tan_dtan2d > 100] = 100
        dlambda_tan_dtan2d[dlambda_tan_dtan2d < -100] = -100
        dlambda_tan_dtan2d = ndimage.gaussian_filter(dlambda_tan_dtan2d,
                                                     sigma=smoothing_scale /
                                                     delta_pix)
        orientation_angle2d = ndimage.gaussian_filter(orientation_angle2d,
                                                      sigma=smoothing_scale /
                                                      delta_pix)
        dphi_tan_dtan2d = ndimage.gaussian_filter(dphi_tan_dtan2d,
                                                  sigma=smoothing_scale /
                                                  delta_pix)

    def _plot_frame(ax, map, vmin, vmax, text_string):
        """

        :param ax: matplotlib.axis instance
        :param map: 2d array
        :param vmin: minimum plotting scale
        :param vmax: maximum plotting scale
        :param text_string: string to describe the label
        :return:
        """
        font_size = 10
        _arrow_size = 0.02
        im = ax.matshow(map,
                        extent=[0, _frame_size, 0, _frame_size],
                        vmin=vmin,
                        vmax=vmax)
        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, orientation='vertical')
        #cb.set_label(text_string, fontsize=10)
        #plot_util.scale_bar(ax, _frame_size, dist=1, text='1"', font_size=font_size)
        plot_util.text_description(ax,
                                   _frame_size,
                                   text=text_string,
                                   color="k",
                                   backgroundcolor='w',
                                   font_size=font_size)
        #if 'no_arrow' not in kwargs or not kwargs['no_arrow']:
        #    plot_util.coordinate_arrows(ax, _frame_size, _coords,
        #                                color='w', arrow_size=_arrow_size,
        #                                font_size=font_size)

    f, axes = plt.subplots(3, 4, figsize=(12, 8))
    _plot_frame(axes[0, 0],
                lambda_rad2d,
                vmin=0.6,
                vmax=1.4,
                text_string=r"$\lambda_{rad}$")
    _plot_frame(axes[0, 1],
                lambda_tan2d,
                vmin=-20,
                vmax=20,
                text_string=r"$\lambda_{tan}$")
    _plot_frame(axes[0, 2],
                orientation_angle2d,
                vmin=-np.pi / 10,
                vmax=np.pi / 10,
                text_string=r"$\phi$")
    _plot_frame(axes[0, 3],
                util.array2image(lambda_tan * lambda_rad),
                vmin=-20,
                vmax=20,
                text_string='magnification')
    _plot_frame(axes[1, 0],
                dlambda_rad_drad2d / lambda_rad2d,
                vmin=-.1,
                vmax=.1,
                text_string='dlambda_rad_drad')
    _plot_frame(axes[1, 1],
                dlambda_tan_dtan2d / lambda_tan2d,
                vmin=-20,
                vmax=20,
                text_string='dlambda_tan_dtan')
    _plot_frame(axes[1, 2],
                dlambda_tan_drad2d / lambda_tan2d,
                vmin=-20,
                vmax=20,
                text_string='dlambda_tan_drad')
    _plot_frame(axes[1, 3],
                dlambda_rad_dtan2d / lambda_rad2d,
                vmin=-.1,
                vmax=.1,
                text_string='dlambda_rad_dtan')

    _plot_frame(axes[2, 0],
                dphi_rad_drad2d,
                vmin=-.1,
                vmax=.1,
                text_string='dphi_rad_drad')
    _plot_frame(axes[2, 1],
                dphi_tan_dtan2d,
                vmin=0,
                vmax=20,
                text_string='dphi_tan_dtan: curvature radius')
    _plot_frame(axes[2, 2],
                dphi_tan_drad2d,
                vmin=-.1,
                vmax=.1,
                text_string='dphi_tan_drad')
    _plot_frame(axes[2, 3],
                dphi_rad_dtan2d,
                vmin=0,
                vmax=20,
                text_string='dphi_rad_dtan')

    return f, axes
Ejemplo n.º 28
0
    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):
            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 = ImageData(**kwargs_data)
        self._coords = data
        nx, ny = np.shape(kwargs_data['image_data'])
        Mpix2coord = kwargs_data['transform_pix2angle']
        self._Mpix2coord = Mpix2coord

        self._deltaPix = self._coords.pixel_width
        self._frame_size = self._deltaPix * nx

        x_grid, y_grid = data.pixel_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),
            lens_redshift_list=kwargs_model.get('lens_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)
Ejemplo n.º 29
0
def arrival_time_surface(ax,
                         lensModel,
                         kwargs_lens,
                         numPix=500,
                         deltaPix=0.01,
                         sourcePos_x=0,
                         sourcePos_y=0,
                         with_caustics=False,
                         point_source=False,
                         n_levels=10,
                         kwargs_contours={},
                         image_color_list=None,
                         letter_font_size=20):
    """

    :param ax:
    :param lensModel:
    :param kwargs_lens:
    :param numPix:
    :param deltaPix:
    :param sourcePos_x:
    :param sourcePos_y:
    :param with_caustics:
    :return:
    """
    kwargs_data = sim_util.data_configure_simple(numPix, deltaPix)
    data = ImageData(**kwargs_data)
    _frame_size = numPix * deltaPix
    _coords = data
    x_grid, y_grid = data.pixel_coordinates
    lensModelExt = LensModelExtensions(lensModel)
    #ra_crit_list, dec_crit_list, ra_caustic_list, dec_caustic_list = lensModelExt.critical_curve_caustics(
    #    kwargs_lens, compute_window=_frame_size, grid_scale=deltaPix/2.)
    x_grid1d = util.image2array(x_grid)
    y_grid1d = util.image2array(y_grid)
    fermat_surface = lensModel.fermat_potential(x_grid1d, y_grid1d,
                                                kwargs_lens, sourcePos_x,
                                                sourcePos_y)
    fermat_surface = util.array2image(fermat_surface)

    #, cmap='Greys', vmin=-1, vmax=1) #, cmap=self._cmap, vmin=v_min, vmax=v_max)
    if with_caustics is True:
        ra_crit_list, dec_crit_list = lensModelExt.critical_curve_tiling(
            kwargs_lens,
            compute_window=_frame_size,
            start_scale=deltaPix / 5,
            max_order=10)
        ra_caustic_list, dec_caustic_list = lensModel.ray_shooting(
            ra_crit_list, dec_crit_list, kwargs_lens)
        plot_util.plot_line_set(ax,
                                _coords,
                                ra_caustic_list,
                                dec_caustic_list,
                                shift=_frame_size / 2.,
                                color='g')
        plot_util.plot_line_set(ax,
                                _coords,
                                ra_crit_list,
                                dec_crit_list,
                                shift=_frame_size / 2.,
                                color='r')
    if point_source is True:
        from lenstronomy.LensModel.Solver.lens_equation_solver import LensEquationSolver
        solver = LensEquationSolver(lensModel)
        theta_x, theta_y = solver.image_position_from_source(
            sourcePos_x,
            sourcePos_y,
            kwargs_lens,
            min_distance=deltaPix,
            search_window=deltaPix * numPix)

        fermat_pot_images = lensModel.fermat_potential(theta_x, theta_y,
                                                       kwargs_lens)
        im = ax.contour(
            x_grid,
            y_grid,
            fermat_surface,
            origin='lower',  # extent=[0, _frame_size, 0, _frame_size],
            levels=np.sort(fermat_pot_images),
            **kwargs_contours)
        mag_images = lensModel.magnification(theta_x, theta_y, kwargs_lens)
        x_image, y_image = _coords.map_coord2pix(theta_x, theta_y)
        abc_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']

        for i in range(len(x_image)):
            x_ = (x_image[i] + 0.5) * deltaPix - _frame_size / 2
            y_ = (y_image[i] + 0.5) * deltaPix - _frame_size / 2
            if image_color_list is None:
                color = 'k'
            else:
                color = image_color_list[i]
            ax.plot(x_, y_, 'x', markersize=10, alpha=1, color=color
                    )  # markersize=8*(1 + np.log(np.abs(mag_images[i])))
            ax.text(x_ + deltaPix,
                    y_ + deltaPix,
                    abc_list[i],
                    fontsize=letter_font_size,
                    color='k')
        x_source, y_source = _coords.map_coord2pix(sourcePos_x, sourcePos_y)
        ax.plot((x_source + 0.5) * deltaPix - _frame_size / 2,
                (y_source + 0.5) * deltaPix - _frame_size / 2,
                '*k',
                markersize=20)
    else:
        vmin = np.min(fermat_surface)
        vmax = np.max(fermat_surface)
        levels = np.linspace(start=vmin, stop=vmax, num=n_levels)
        im = ax.contour(
            x_grid,
            y_grid,
            fermat_surface,
            origin='lower',  # extent=[0, _frame_size, 0, _frame_size],
            levels=levels,
            **kwargs_contours)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    ax.autoscale(False)
    return ax
Ejemplo n.º 30
0
                                                 truncate=6)

# we now degrate the pixel resoluton by a factor.
# This reduces the data volume and increases the spead of the Shapelet decomposition
factor = 1  # lower resolution of image with a given factor
numPix_large = int(len(ngc_conv) / factor)
n_new = int((numPix_large - 1) * factor)
ngc_cut = ngc_conv[0:n_new, 0:n_new]
x, y = util.make_grid(numPix=numPix_large - 1,
                      deltapix=1)  # make a coordinate grid
ngc_data_resized = image_util.re_size(
    ngc_cut, factor)  # re-size image to lower resolution

# now we come to the Shapelet decomposition
# we turn the image in a single 1d array
image_1d = util.image2array(ngc_data_resized)  # map 2d image in 1d data array

# we define the shapelet basis set we want the image to decompose in
n_max = 150  # choice of number of shapelet basis functions, 150 is a high resolution number, but takes long
beta = 10  # shapelet scale parameter (in units of resized pixels)

# import the ShapeletSet class
from lenstronomy.LightModel.Profiles.shapelets import ShapeletSet
shapeletSet = ShapeletSet()

# decompose image and return the shapelet coefficients
coeff_ngc = shapeletSet.decomposition(image_1d,
                                      x,
                                      y,
                                      n_max,
                                      beta,