示例#1
0
def test_deshift_subgrid():
    # test the de-shifting with a sharpened subgrid kernel
    kernel_size = 5
    subgrid = 3
    fwhm = 1
    kernel_subgrid_size = kernel_size * subgrid
    kernel_subgrid = np.zeros((kernel_subgrid_size, kernel_subgrid_size))
    kernel_subgrid[7, 7] = 2
    kernel_subgrid = kernel_util.kernel_gaussian(kernel_subgrid_size,
                                                 1. / subgrid,
                                                 fwhm=fwhm)

    kernel = util.averaging(kernel_subgrid, kernel_subgrid_size, kernel_size)

    shift_x = 0.18
    shift_y = 0.2
    shift_x_subgird = shift_x * subgrid
    shift_y_subgrid = shift_y * subgrid
    kernel_shifted_subgrid = interp.shift(kernel_subgrid,
                                          [-shift_y_subgrid, -shift_x_subgird],
                                          order=1)
    kernel_shifted = util.averaging(kernel_shifted_subgrid,
                                    kernel_subgrid_size, kernel_size)
    kernel_shifted_highres = kernel_util.subgrid_kernel(kernel_shifted,
                                                        subgrid_res=subgrid,
                                                        num_iter=1)
    """
示例#2
0
    def kernel_point_source_supersampled(self,
                                         supersampling_factor,
                                         updata_cache=True):
        """
        generates (if not already available) a supersampled PSF with ood numbers of pixels centered

        :param supersampling_factor: int >=1, supersampling factor relative to pixel resolution
        :param updata_cache: boolean, if True, updates the cached supersampling PSF if generated.
         Attention, this will overwrite a previously used supersampled PSF if the resolution is changing.
        :return: super-sampled PSF as 2d numpy array
        """
        if hasattr(
                self, '_kernel_point_source_supersampled'
        ) and self._point_source_supersampling_factor == supersampling_factor:
            kernel_point_source_supersampled = self._kernel_point_source_supersampled
        else:
            if self.psf_type == 'GAUSSIAN':
                kernel_numPix = self._truncation / self._pixel_size * supersampling_factor
                kernel_numPix = int(round(kernel_numPix))
                if kernel_numPix > 10000:
                    raise ValueError(
                        'The pixelized Gaussian kernel has a grid of %s pixels with a truncation at '
                        '%s times the sigma of the Gaussian, exceeding the limit allowed.'
                        % (kernel_numPix, self._truncation))
                if kernel_numPix % 2 == 0:
                    kernel_numPix += 1
                kernel_point_source_supersampled = kernel_util.kernel_gaussian(
                    kernel_numPix, self._pixel_size / supersampling_factor,
                    self._fwhm)

            elif self.psf_type == 'PIXEL':

                kernel = kernel_util.subgrid_kernel(self.kernel_point_source,
                                                    supersampling_factor,
                                                    odd=True,
                                                    num_iter=5)
                n = len(self.kernel_point_source)
                n_new = n * supersampling_factor
                if n_new % 2 == 0:
                    n_new -= 1
                if hasattr(self, '_kernel_point_source_supersampled'):
                    warnings.warn(
                        "Super-sampled point source kernel over-written due to different subsampling"
                        " size requested.", Warning)
                kernel_point_source_supersampled = kernel_util.cut_psf(
                    kernel, psf_size=n_new)
            elif self.psf_type == 'NONE':
                kernel_point_source_supersampled = self._kernel_point_source
            else:
                raise ValueError('psf_type %s not valid!' % self.psf_type)
            if updata_cache is True:
                self._kernel_point_source_supersampled = kernel_point_source_supersampled
                self._point_source_supersampling_factor = supersampling_factor
        return kernel_point_source_supersampled
示例#3
0
def test_split_kernel():
    kernel = np.zeros((9, 9))
    kernel[4, 4] = 1
    subgrid_res = 3
    subgrid_kernel = kernel_util.subgrid_kernel(kernel, subgrid_res=subgrid_res, odd=True)
    subsampling_size = 3
    kernel_hole, kernel_cutout = kernel_util.split_kernel(subgrid_kernel, supersampling_kernel_size=subsampling_size,
                                                          supersampling_factor=subgrid_res)

    assert kernel_hole[4, 4] == 0
    assert len(kernel_cutout) == subgrid_res*subsampling_size
    npt.assert_almost_equal(np.sum(kernel_hole) + np.sum(kernel_cutout), 1, decimal=4)

    subgrid_res = 2
    subgrid_kernel = kernel_util.subgrid_kernel(kernel, subgrid_res=subgrid_res, odd=True)
    subsampling_size = 3
    kernel_hole, kernel_cutout = kernel_util.split_kernel(subgrid_kernel, supersampling_kernel_size=subsampling_size,
                                                          supersampling_factor=subgrid_res)

    assert kernel_hole[4, 4] == 0
    assert len(kernel_cutout) == subgrid_res * subsampling_size + 1
    npt.assert_almost_equal(np.sum(kernel_hole) + np.sum(kernel_cutout), 1, decimal=4)
示例#4
0
    def _subgrid_kernel(self, subgrid_res):
        """

        :return:
        """
        if not hasattr(self, '_subgrid_kernel_out'):
            kernel = kernel_util.subgrid_kernel(self.kernel_point_source, subgrid_res, odd=True)
            n = len(self._kernel_pixel)
            n_new = n * subgrid_res
            if n_new % 2 == 0:
                n_new -= 1
            self._subgrid_kernel_out = kernel_util.cut_psf(kernel, psf_size=n_new)
        return self._subgrid_kernel_out
示例#5
0
def test_subgrid_kernel():

    kernel = np.zeros((9, 9))
    kernel[4, 4] = 1
    subgrid_res = 3
    subgrid_kernel = kernel_util.subgrid_kernel(kernel, subgrid_res=subgrid_res, odd=True)
    kernel_re_sized = image_util.re_size(subgrid_kernel, factor=subgrid_res) *subgrid_res**2
    #import matplotlib.pyplot as plt
    #plt.matshow(kernel); plt.show()
    #plt.matshow(subgrid_kernel); plt.show()
    #plt.matshow(kernel_re_sized);plt.show()
    #plt.matshow(kernel_re_sized- kernel);plt.show()
    npt.assert_almost_equal(kernel_re_sized[4, 4], 1, decimal=2)
    assert np.max(subgrid_kernel) == subgrid_kernel[13, 13]
示例#6
0
def test_subgrid_rebin():
    kernel_size = 11
    subgrid_res = 3

    sigma = 1
    x_grid, y_gird = Util.make_grid(kernel_size, 1./subgrid_res, subgrid_res)
    flux = gaussian.function(x_grid, y_gird, amp=1, sigma=sigma)
    kernel = Util.array2image(flux)
    print(np.shape(kernel))
    kernel = util.averaging(kernel, numGrid=kernel_size * subgrid_res, numPix=kernel_size)
    kernel = kernel_util.kernel_norm(kernel)

    subgrid_kernel = kernel_util.subgrid_kernel(kernel, subgrid_res=subgrid_res, odd=True)
    kernel_pixel = util.averaging(subgrid_kernel, numGrid=kernel_size * subgrid_res, numPix=kernel_size)
    kernel_pixel = kernel_util.kernel_norm(kernel_pixel)
    assert np.sum((kernel_pixel - kernel)**2) < 0.1
示例#7
0
    def kernel_point_source_supersampled(self,
                                         supersampling_factor,
                                         updata_cache=True):
        """

        :return:
        """
        if hasattr(
                self, '_kernel_point_source_supersampled'
        ) and self._point_source_supersampling_factor == supersampling_factor:
            kernel_point_source_supersampled = self._kernel_point_source_supersampled
        else:
            if self.psf_type == 'GAUSSIAN':
                kernel_numPix = self._truncation / self._pixel_size * supersampling_factor
                kernel_numPix = int(round(kernel_numPix))
                if kernel_numPix % 2 == 0:
                    kernel_numPix += 1
                kernel_point_source_supersampled = kernel_util.kernel_gaussian(
                    kernel_numPix, self._pixel_size / supersampling_factor,
                    self._fwhm)

            elif self.psf_type == 'PIXEL':

                kernel = kernel_util.subgrid_kernel(self.kernel_point_source,
                                                    supersampling_factor,
                                                    odd=True,
                                                    num_iter=5)
                n = len(self.kernel_point_source)
                n_new = n * supersampling_factor
                if n_new % 2 == 0:
                    n_new -= 1
                if hasattr(self, '_kernel_point_source_supersampled'):
                    warnings.warn(
                        "Super-sampled point source kernel over-written due to different subsampling"
                        " size requested.", Warning)
                kernel_point_source_supersampled = kernel_util.cut_psf(
                    kernel, psf_size=n_new)
            elif self.psf_type == 'NONE':
                kernel_point_source_supersampled = self._kernel_point_source
            else:
                raise ValueError('psf_type %s not valid!' % self.psf_type)
            if updata_cache is True:
                self._kernel_point_source_supersampled = kernel_point_source_supersampled
                self._point_source_supersampling_factor = supersampling_factor
        return kernel_point_source_supersampled
示例#8
0
    def subgrid_pixel_kernel(self, subgrid_res):
        """

        :return:
        """
        if hasattr(self, '_kernel_pixel_subsampled') and self._pixel_subsampling_factor == subgrid_res:
            pass
        elif hasattr(self, '_kernel_point_source_subsampled'):
            # if the subsampling scale matches the one from the point source - take it!
            if self._point_source_subsampling_factor == subgrid_res:
                self._kernel_pixel_subsampled = self._kernel_point_source_subsampled
                self._pixel_subsampling_factor = self._point_source_subsampling_factor
        else:
            kernel = kernel_util.subgrid_kernel(self.kernel_point_source, subgrid_res, odd=True, num_iter=5)
            n = len(self.kernel_pixel)
            n_new = n * subgrid_res
            if n_new % 2 == 0:
                n_new -= 1
            self._kernel_pixel_subsampled = kernel_util.cut_psf(kernel, psf_size=n_new)
            self._pixel_subsampling_factor = subgrid_res
        return self._kernel_pixel_subsampled
示例#9
0
    def update_psf(self,
                   kwargs_psf,
                   kwargs_params,
                   stacking_method='median',
                   psf_symmetry=1,
                   psf_iter_factor=.2,
                   block_center_neighbour=0,
                   error_map_radius=None,
                   block_center_neighbour_error_map=None,
                   new_procedure=True):
        """

        :param kwargs_psf: keyword arguments to construct the PSF() class
        :param kwargs_params: keyword arguments of the parameters of the model components (e.g. 'kwargs_lens' etc)
        :param stacking_method: 'median', 'mean'; the different estimates of the PSF are stacked and combined together.
         The choices are:
         'mean': mean of pixel values as the estimator (not robust to outliers)
         'median': median of pixel values as the estimator (outlier rejection robust but needs >2 point sources in the
         data
        :param psf_symmetry: number of rotational invariant symmetries in the estimated PSF.
         =1 mean no additional symmetries. =4 means 90 deg symmetry. This is enforced by a rotatioanl stack according to
         the symmetry specified. These additional imposed symmetries can help stabelize the PSF estimate when there are
         limited constraints/number of point sources in the image.
        :param psf_iter_factor: factor in (0, 1] of ratio of old vs new PSF in the update in the iteration.
        :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.
        :param block_center_neighbour_error_map: angle, radius of neighbouring point sources around their centers the
         estimates of the ERROR MAP is ignored. If None, then the value of block_center_neighbour is used (recommended)
        :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 errors), if None, all of the pixels are considered
         (unless blocked through other means)
        :param new_procedure: boolean, uses post lenstronomy 1.9.2 procedure which is more optimal for super-sampled
         PSF's
        :return: kwargs_psf_new, logL_after, error_map
        """
        if block_center_neighbour_error_map is None:
            block_center_neighbour_error_map = block_center_neighbour
        psf_class = PSF(**kwargs_psf)
        kwargs_psf_copy = copy.deepcopy(kwargs_psf)

        point_source_supersampling_factor = kwargs_psf_copy.get(
            'point_source_supersampling_factor', 1)
        kwargs_psf_new = {
            'psf_type': 'PIXEL',
            'kernel_point_source': kwargs_psf_copy['kernel_point_source'],
            'point_source_supersampling_factor':
            point_source_supersampling_factor,
            'psf_error_map': kwargs_psf_copy.get('psf_error_map', None)
        }
        # if 'psf_error_map' in kwargs_psf_copy:
        #    kwargs_psf_new['psf_error_map'] = kwargs_psf_copy['psf_error_map'] / 10
        self._image_model_class.update_psf(PSF(**kwargs_psf_new))

        model, error_map_image, cov_param, param = self._image_model_class.image_linear_solve(
            **kwargs_params)
        kwargs_ps = kwargs_params.get('kwargs_ps', None)
        kwargs_lens = kwargs_params.get('kwargs_lens', None)
        ra_image, dec_image, point_amp = self._image_model_class.PointSource.point_source_list(
            kwargs_ps, kwargs_lens)
        x_, y_ = self._image_model_class.Data.map_coord2pix(
            ra_image, dec_image)
        kernel_old = psf_class.kernel_point_source
        kernel_size = len(kernel_old)

        if not new_procedure:
            image_single_point_source_list = self.image_single_point_source(
                self._image_model_class, kwargs_params)
            star_cutout_list = self.point_like_source_cutouts(
                x_pos=x_,
                y_pos=y_,
                image_list=image_single_point_source_list,
                cutout_size=kernel_size)
            psf_kernel_list = self.cutout_psf(
                ra_image,
                dec_image,
                x_,
                y_,
                image_single_point_source_list,
                kernel_size,
                kernel_old,
                block_center_neighbour=block_center_neighbour)

            kernel_new = self.combine_psf(psf_kernel_list,
                                          kernel_old,
                                          factor=psf_iter_factor,
                                          stacking_option=stacking_method,
                                          symmetry=psf_symmetry)
            kernel_new = kernel_util.cut_psf(kernel_new, psf_size=kernel_size)
            error_map = self.error_map_estimate(
                kernel_new,
                star_cutout_list,
                point_amp,
                x_,
                y_,
                error_map_radius=error_map_radius,
                block_center_neighbour=block_center_neighbour_error_map)

            if point_source_supersampling_factor > 1:
                # The current version of using a super-sampled PSF in the iterative reconstruction is to first
                # constrain a down-sampled version and then in a second step perform a super-sampling of it. This is not
                # optimal and should be changed in the future that the corrections of the super-sampled version is done
                # rather than constraining a totally new PSF first
                kernel_new = kernel_util.subgrid_kernel(
                    kernel_new,
                    subgrid_res=point_source_supersampling_factor,
                    odd=True,
                    num_iter=10)
                # chop edges
                n_kernel = len(kwargs_psf['kernel_point_source'])
                kernel_new = kernel_util.cut_psf(kernel_new, psf_size=n_kernel)

        else:
            kernel_old_high_res = psf_class.kernel_point_source_supersampled(
                supersampling_factor=point_source_supersampling_factor)
            kernel_size_high = len(kernel_old_high_res)
            data = self._image_model_class.Data.data
            residuals = data - model

            psf_kernel_list = self.psf_estimate_individual(
                ra_image,
                dec_image,
                point_amp,
                residuals,
                cutout_size=kernel_size,
                kernel_guess=kernel_old_high_res,
                supersampling_factor=point_source_supersampling_factor,
                block_center_neighbour=block_center_neighbour)

            kernel_new = self.combine_psf(psf_kernel_list,
                                          kernel_old_high_res,
                                          factor=psf_iter_factor,
                                          stacking_option=stacking_method,
                                          symmetry=psf_symmetry)
            kernel_new = kernel_util.cut_psf(kernel_new,
                                             psf_size=kernel_size_high)

            # resize kernel for error_map estimate
            # kernel_new_low = kernel_util.degrade_kernel(kernel_new, point_source_supersampling_factor)
            # compute error map on pixel level
            error_map = self.error_map_estimate_new(
                kernel_new,
                psf_kernel_list,
                ra_image,
                dec_image,
                point_amp,
                point_source_supersampling_factor,
                error_map_radius=error_map_radius)

        kwargs_psf_new['kernel_point_source'] = kernel_new
        # if 'psf_error_map' in kwargs_psf_new:
        #    kwargs_psf_new['psf_error_map'] *= 10
        self._image_model_class.update_psf(PSF(**kwargs_psf_new))
        logL_after = self._image_model_class.likelihood_data_given_model(
            **kwargs_params)
        return kwargs_psf_new, logL_after, error_map
示例#10
0
def test_subgrid_kernel():
    kernel = np.ones((3, 3))
    subgrid_kernel = kernel_util.subgrid_kernel(kernel, subgrid_res=4, odd=2)
    assert subgrid_kernel[0, 0] == 0.0069444444444444441