def test_re_size(): grid = np.zeros((200, 100)) grid[100, 50] = 4 grid_small = image_util.re_size(grid, factor=2) assert grid_small[50][25] == 1 grid_same = image_util.re_size(grid, factor=1) npt.assert_equal(grid_same, grid)
def potential_from_kappa_grid_adaptive(kappa_high_res, grid_spacing, low_res_factor, high_res_kernel_size): """ lensing potential on the convergence grid the computation is performed as a convolution of the Green's function with the convergence map using FFT :param kappa_high_res: 2d grid of convergence values :param grid_spacing: scale of an individual pixel (per axis) of grid :param low_res_factor: lower resolution factor of larger scale kernel. :param high_res_kernel_size: int, size of high resolution kernel in units of degraded pixels :return: lensing potential in a 2d grid at positions x_grid, y_grid """ kappa_low_res = image_util.re_size(kappa_high_res, factor=low_res_factor) num_pix = len(kappa_high_res) * 2 if num_pix % 2 == 0: num_pix += 1 grid_spacing_low_res = grid_spacing * low_res_factor kernel = potential_kernel(num_pix, grid_spacing) kernel_low_res, kernel_high_res = kernel_util.split_kernel( kernel, high_res_kernel_size, low_res_factor, normalized=False) f_high_res = scp.fftconvolve(kappa_high_res, kernel_high_res, mode='same') / np.pi * grid_spacing**2 f_high_res = image_util.re_size(f_high_res, low_res_factor) f_low_res = scp.fftconvolve(kappa_low_res, kernel_low_res, mode='same') / np.pi * grid_spacing_low_res**2 return f_high_res + f_low_res
def test_psf_convolution(self): deltaPix = 0.05 fwhm = 0.2 fwhm_object = 0.1 kwargs_gaussian = {'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncate': 5, 'pixel_size': deltaPix} psf_gaussian = PSF(kwargs_psf=kwargs_gaussian) kernel_point_source = kernel_util.kernel_gaussian(kernel_numPix=21, deltaPix=deltaPix, fwhm=fwhm) kwargs_pixel = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source} psf_pixel = PSF(kwargs_psf=kwargs_pixel) subgrid_res_input = 15 grid = kernel_util.kernel_gaussian(kernel_numPix=11*subgrid_res_input, deltaPix=deltaPix / float(subgrid_res_input), fwhm=fwhm_object) grid_true = image_util.re_size(grid, subgrid_res_input) grid_conv = psf_gaussian.psf_convolution(grid, deltaPix / float(subgrid_res_input)) grid_conv_true = image_util.re_size(grid_conv, subgrid_res_input) # subgrid resoluton Gaussian convolution for i in range(1, subgrid_res_input+1): subgrid_res = i grid = kernel_util.kernel_gaussian(kernel_numPix=11*subgrid_res, deltaPix=deltaPix / float(subgrid_res), fwhm=fwhm_object) grid_conv = psf_gaussian.psf_convolution(grid, deltaPix / float(subgrid_res)) grid_conv_finite = image_util.re_size(grid_conv, subgrid_res) min_diff = np.min(grid_conv_true-grid_conv_finite) max_diff = np.max(grid_conv_true-grid_conv_finite) print(min_diff, max_diff) npt.assert_almost_equal(min_diff, 0, decimal=7) npt.assert_almost_equal(max_diff, 0, decimal=7) # subgrid resoluton Pixel convolution for i in range(1,subgrid_res_input+1): subgrid_res = i grid = kernel_util.kernel_gaussian(kernel_numPix=11*subgrid_res, deltaPix=deltaPix / float(subgrid_res), fwhm=fwhm_object) grid_conv = psf_pixel.psf_convolution(grid, deltaPix / float(subgrid_res), subgrid_res=subgrid_res, psf_subgrid=True) grid_conv_finite = image_util.re_size(grid_conv, subgrid_res) min_diff = np.min(grid_conv_true-grid_conv_finite) max_diff = np.max(grid_conv_true-grid_conv_finite) print(min_diff, max_diff) npt.assert_almost_equal(min_diff, 0, decimal=3) npt.assert_almost_equal(max_diff, 0, decimal=3) # subgrid ray-tracing but pixel convolution on normal grid for i in range(1,subgrid_res_input+1): subgrid_res = i grid = kernel_util.kernel_gaussian(kernel_numPix=11*subgrid_res, deltaPix=deltaPix / float(subgrid_res), fwhm=0.2) grid_finite = image_util.re_size(grid, subgrid_res) grid_conv_finite = psf_pixel.psf_convolution(grid_finite, deltaPix, subgrid_res=1) min_diff = np.min(grid_conv_true-grid_conv_finite) max_diff = np.max(grid_conv_true-grid_conv_finite) print(min_diff, max_diff) npt.assert_almost_equal(min_diff, 0, decimal=3) npt.assert_almost_equal(max_diff, 0, decimal=3)
def psf_convolution_new(self, unconvolved_image, subgrid_res=1, subsampling_size=11, psf_subgrid=True): """ :param unconvolved_image: 2d image with subsampled pixels with subgrid_res :param subgrid_res: subsampling resolution :param subsampling_size: size of the subsampling convolution in units of image pixels :param psf_subgrid: bool, if False, the convolution is performed on the pixel size of the data :return: convolved 2d image in units of the pixels """ unconvolved_image_resized = image_util.re_size(unconvolved_image, subgrid_res) if self.psf_type == 'NONE': image_conv_resized = unconvolved_image_resized elif self.psf_type == 'GAUSSIAN': if psf_subgrid is True: grid_scale = self._pixel_size / float(subgrid_res) sigma = self._sigma_gaussian / grid_scale image_conv = ndimage.filters.gaussian_filter( unconvolved_image, sigma, mode='nearest', truncate=self._truncation) image_conv_resized = image_util.re_size( image_conv, subgrid_res) else: sigma = self._sigma_gaussian / self._pixel_size image_conv_resized = ndimage.filters.gaussian_filter( unconvolved_image_resized, sigma, mode='nearest', truncate=self._truncation) elif self.psf_type == 'PIXEL': kernel = self._kernel_pixel if subgrid_res > 1 and psf_subgrid is True: kernel_subgrid = self.subgrid_pixel_kernel(subgrid_res) kernel, kernel_subgrid = kernel_util.split_kernel( kernel, kernel_subgrid, subsampling_size, subgrid_res) image_conv_subgrid = signal.fftconvolve(unconvolved_image, kernel_subgrid, mode='same') image_conv_resized_1 = image_util.re_size( image_conv_subgrid, subgrid_res) image_conv_resized_2 = signal.fftconvolve( unconvolved_image_resized, kernel, mode='same') image_conv_resized = image_conv_resized_1 + image_conv_resized_2 else: image_conv_resized = signal.fftconvolve( unconvolved_image_resized, kernel, mode='same') else: raise ValueError('PSF type %s not valid!' % self.psf_type) return image_conv_resized
def convolution2d(self, image): """ :param image: 2d array (high resoluton image) to be convolved and re-sized :return: convolved image """ image_high_res_conv = self._high_res_conv.convolution2d(image) image_resized_conv = image_util.re_size(image_high_res_conv, self._supersampling_factor) if self._low_res_convolution is True: image_resized = image_util.re_size(image, self._supersampling_factor) image_resized_conv += self._low_res_conv.convolution2d(image_resized) return image_resized_conv
def point_source_rendering(self, ra_pos, dec_pos, amp): """ :param ra_pos: list of RA positions of point source(s) :param dec_pos: list of DEC positions of point source(s) :param amp: list of amplitudes of point source(s) :return: 2d numpy array of size of the image with the point source(s) rendered """ subgrid = self._supersampling_factor x_pos, y_pos = self._pixel_grid.map_coord2pix(ra_pos, dec_pos) # translate coordinates to higher resolution grid x_pos_subgird = x_pos * subgrid + (subgrid - 1) / 2. y_pos_subgrid = y_pos * subgrid + (subgrid - 1) / 2. kernel_point_source_subgrid = self._kernel_supersampled # initialize grid with higher resolution subgrid2d = np.zeros((self._nx * subgrid, self._ny * subgrid)) # add_layer2image if len(x_pos) > len(amp): raise ValueError( 'there are %s images appearing but only %s amplitudes provided!' % (len(x_pos), len(amp))) for i in range(len(x_pos)): subgrid2d = image_util.add_layer2image( subgrid2d, x_pos_subgird[i], y_pos_subgrid[i], amp[i] * kernel_point_source_subgrid) # re-size grid to data resolution grid2d = image_util.re_size(subgrid2d, factor=subgrid) return grid2d * subgrid**2
def test_kernel_subsampled(self): deltaPix = 0.05 # pixel size of image numPix = 40 # number of pixels per axis subsampling_res = 3 # subsampling scale factor (in each dimension) fwhm = 0.3 # FWHM of the PSF kernel fwhm_object = 0.2 # FWHM of the Gaussian source to be convolved # create Gaussian/Pixelized kernels # first we create the sub-sampled kernel kernel_point_source_subsampled = kernel_util.kernel_gaussian(kernel_numPix=11*subsampling_res, deltaPix=deltaPix/subsampling_res, fwhm=fwhm) # to have the same consistent kernel, we re-size (average over the sub-sampled pixels) the sub-sampled kernel kernel_point_source = image_util.re_size(kernel_point_source_subsampled, subsampling_res) # here we create the two PSF() classes kwargs_pixel_subsampled = {'psf_type': 'PIXEL', 'kernel_point_source_subsampled': kernel_point_source_subsampled, 'point_source_subsampling_factor': subsampling_res} psf_pixel_subsampled = PSF(kwargs_psf=kwargs_pixel_subsampled) kwargs_pixel = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source} psf_pixel = PSF(kwargs_psf=kwargs_pixel) # here we create the image of the Gaussian source and convolve it with the regular kernel image_unconvolved = kernel_util.kernel_gaussian(kernel_numPix=numPix, deltaPix=deltaPix, fwhm=fwhm_object) image_convolved_regular = psf_pixel.psf_convolution_new(image_unconvolved, subgrid_res=1, subsampling_size=None) # here we create the image by computing the sub-sampled Gaussian source and convolve it with the sub-sampled PSF kernel image_unconvolved_highres = kernel_util.kernel_gaussian(kernel_numPix=numPix*subsampling_res, deltaPix=deltaPix/subsampling_res, fwhm=fwhm_object) * subsampling_res**2 image_convolved_subsampled = psf_pixel_subsampled.psf_convolution_new(image_unconvolved_highres, subgrid_res=subsampling_res, subsampling_size=5) # We demand the two procedures to be the same up to the numerics affecting the finite resolution npt.assert_almost_equal(np.sum(image_convolved_regular), np.sum(image_convolved_subsampled), decimal=8) npt.assert_almost_equal((image_convolved_subsampled - image_convolved_regular) / (np.max(image_convolved_subsampled)), 0, decimal=2)
def point_source_rendering(self, ra_pos, dec_pos, amp): """ :param ra_pos: :param dec_pos: :param amp: :param subgrid: :return: """ subgrid = self._supersampling_factor x_pos, y_pos = self._pixel_grid.map_coord2pix(ra_pos, dec_pos) # translate coordinates to higher resolution grid x_pos_subgird = x_pos * subgrid + (subgrid - 1) / 2. y_pos_subgrid = y_pos * subgrid + (subgrid - 1) / 2. kernel_point_source_subgrid = self._kernel_supersampled # initialize grid with higher resolution subgrid2d = np.zeros((self._nx * subgrid, self._ny * subgrid)) # add_layer2image for i in range(len(x_pos)): subgrid2d = image_util.add_layer2image( subgrid2d, x_pos_subgird[i], y_pos_subgrid[i], amp[i] * kernel_point_source_subgrid) # re-size grid to data resolution grid2d = image_util.re_size(subgrid2d, factor=subgrid) return grid2d * subgrid**2
def convolve2d(self, image_high_res): """ :param image_high_res: supersampled image/model to be convolved on a regular pixel grid :return: convolved and re-sized image """ image_low_res = image_util.re_size(image_high_res, factor=self._supersampling_factor) return self.re_size_convolve(image_low_res, image_high_res)
def deflection_from_kappa_grid_adaptive(kappa_high_res, grid_spacing, low_res_factor, high_res_kernel_size): """ deflection angles on the convergence grid with adaptive FFT the computation is performed as a convolution of the Green's function with the convergence map using FFT The grid is returned in the lower resolution grid :param kappa_high_res: convergence values for each pixel (2-d array) :param grid_spacing: pixel size of high resolution grid :param low_res_factor: lower resolution factor of larger scale kernel. :param high_res_kernel_size: int, size of high resolution kernel in units of degraded pixels :return: numerical deflection angles in x- and y- direction """ kappa_low_res = image_util.re_size(kappa_high_res, factor=low_res_factor) num_pix = len(kappa_high_res) * 2 if num_pix % 2 == 0: num_pix += 1 #if high_res_kernel_size % low_res_factor != 0: # assert ValueError('fine grid kernel size needs to be a multiplicative factor of low_res_factor! Settings used: ' # 'fine_grid_kernel_size=%s, low_res_factor=%s' % (high_res_kernel_size, low_res_factor)) kernel_x, kernel_y = deflection_kernel(num_pix, grid_spacing) grid_spacing_low_res = grid_spacing * low_res_factor kernel_low_res_x, kernel_high_res_x = kernel_util.split_kernel( kernel_x, high_res_kernel_size, low_res_factor, normalized=False) f_x_high_res = scp.fftconvolve(kappa_high_res, kernel_high_res_x, mode='same') / np.pi * grid_spacing**2 f_x_high_res = image_util.re_size(f_x_high_res, low_res_factor) f_x_low_res = scp.fftconvolve( kappa_low_res, kernel_low_res_x, mode='same') / np.pi * grid_spacing_low_res**2 f_x = f_x_high_res + f_x_low_res kernel_low_res_y, kernel_high_res_y = kernel_util.split_kernel( kernel_y, high_res_kernel_size, low_res_factor, normalized=False) f_y_high_res = scp.fftconvolve(kappa_high_res, kernel_high_res_y, mode='same') / np.pi * grid_spacing**2 f_y_high_res = image_util.re_size(f_y_high_res, low_res_factor) f_y_low_res = scp.fftconvolve( kappa_low_res, kernel_low_res_y, mode='same') / np.pi * grid_spacing_low_res**2 f_y = f_y_high_res + f_y_low_res return f_x, f_y
def re_size_convolve(self, image_low_res, image_high_res): """ :param image_high_res: supersampled image/model to be convolved on a regular pixel grid :return: convolved and re-sized image """ image_high_res_conv = self._high_res_conv.convolution2d(image_high_res) image_resized_conv = image_util.re_size(image_high_res_conv, self._supersampling_factor) if self._low_res_convolution is True: image_resized_conv += self._low_res_conv.convolution2d(image_low_res) return image_resized_conv
def test_convolve2d(self): conv_pixels = np.ones_like(self.model) conv_pixels = np.array(conv_pixels, dtype=bool) numba_conv = SubgridNumbaConvolution(kernel_super=self.kernel_super, conv_pixels=conv_pixels, compute_pixels=conv_pixels, supersampling_factor=self.supersampling_factor) model_conv_numba = numba_conv.convolve2d(self.model_super) pixel_conv = PixelKernelConvolution(kernel=self.kernel_super) image_convolved = pixel_conv.convolution2d(self.model_super) image_convolved = image_util.re_size(image_convolved, factor=self.supersampling_factor) npt.assert_almost_equal(model_conv_numba, image_convolved, decimal=10)
def test_kernel_subsampled(self): deltaPix = 0.05 # pixel size of image numPix = 40 # number of pixels per axis subsampling_res = 3 # subsampling scale factor (in each dimension) fwhm = 0.3 # FWHM of the PSF kernel fwhm_object = 0.2 # FWHM of the Gaussian source to be convolved # create Gaussian/Pixelized kernels # first we create the sub-sampled kernel kernel_point_source_subsampled = kernel_util.kernel_gaussian(kernel_numPix=11*subsampling_res, deltaPix=deltaPix/subsampling_res, fwhm=fwhm) # to have the same consistent kernel, we re-size (average over the sub-sampled pixels) the sub-sampled kernel kernel_point_source = image_util.re_size(kernel_point_source_subsampled, subsampling_res) # here we create the two PSF() classes kwargs_pixel_subsampled = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source_subsampled, 'point_source_supersampling_factor': subsampling_res} psf_pixel_subsampled = PSF(**kwargs_pixel_subsampled) psf_pixel_subsampled.kernel_point_source_supersampled(supersampling_factor=subsampling_res+1) kernel_point_source /= np.sum(kernel_point_source) kwargs_pixel = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source} psf_pixel = PSF(**kwargs_pixel) kernel_point_source = psf_pixel.kernel_point_source kernel_super = psf_pixel.kernel_point_source_supersampled(supersampling_factor=3) npt.assert_almost_equal(np.sum(kernel_point_source), np.sum(kernel_super), decimal=8) npt.assert_almost_equal(np.sum(kernel_point_source), 1, decimal=8) deltaPix = 0.05 # pixel size of image numPix = 40 # number of pixels per axis subsampling_res = 4 # subsampling scale factor (in each dimension) fwhm = 0.3 # FWHM of the PSF kernel fwhm_object = 0.2 # FWHM of the Gaussian source to be convolved # create Gaussian/Pixelized kernels # first we create the sub-sampled kernel kernel_point_source_subsampled = kernel_util.kernel_gaussian(kernel_numPix=11 * subsampling_res + 1, deltaPix=deltaPix / subsampling_res, fwhm=fwhm) kwargs_pixel_subsampled = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source_subsampled, 'point_source_supersampling_factor': subsampling_res} psf_pixel_subsampled = PSF(**kwargs_pixel_subsampled) kernel_point_source /= np.sum(kernel_point_source) kwargs_pixel = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source} psf_pixel = PSF(**kwargs_pixel) kernel_point_source = psf_pixel.kernel_point_source kernel_point_source_new = psf_pixel_subsampled.kernel_point_source npt.assert_almost_equal(np.sum(kernel_point_source), np.sum(kernel_point_source_new), decimal=8) npt.assert_almost_equal(np.sum(kernel_point_source), 1, decimal=8) psf_none = PSF(psf_type='NONE') kernel_super = psf_none.kernel_point_source_supersampled(supersampling_factor=5) npt.assert_almost_equal(kernel_super, psf_none.kernel_point_source, decimal=9)
def test_raise(self): with self.assertRaises(ValueError): grid2d = np.zeros((7, 7)) x_pos, y_pos = 4, 1 kernel = np.ones((2, 2)) added = image_util.add_layer2image_int(grid2d, x_pos, y_pos, kernel) with self.assertRaises(ValueError): image = np.ones((5, 5)) image_util.re_size(image, factor=2) with self.assertRaises(ValueError): image = np.ones((5, 5)) image_util.re_size(image, factor=0.5) with self.assertRaises(ValueError): image = np.ones((5, 5)) image_util.cut_edges(image, numPix=7) with self.assertRaises(ValueError): image = np.ones((5, 6)) image_util.cut_edges(image, numPix=3) with self.assertRaises(ValueError): image = np.ones((5, 5)) image_util.cut_edges(image, numPix=2)
def flux_array2image_low_high(self, flux_array, **kwargs): """ :param flux_array: 1d array of low and high resolution flux values corresponding to the coordinates_evaluate order :return: 2d array, 2d array, corresponding to (partial) images in low and high resolution (to be convolved) """ image = self._array2image(flux_array) if self._supersampling_factor > 1: image_high_res = image image_low_res = image_util.re_size(image, self._supersampling_factor) else: image_high_res = None image_low_res = image return image_low_res, image_high_res
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]
def re_size_convolve(self, array, unconvolved=False): """ :param array: 1d data vector (can also be higher resolution binned) :param kwargs_psf: kwargs of psf modelling :param unconvolved: bool, if True, no convlolution performed, only re-binning :return: array with convolved and re-binned data/model """ image = self.array2image(array, self._subgrid_res) image = self._cutout_psf(image, self._subgrid_res) if unconvolved is True: image_convolved = image_util.re_size(image, self._subgrid_res) else: image_convolved = self._PSF.psf_convolution_new( image, subgrid_res=self._subgrid_res, subsampling_size=self._subsampling_size, psf_subgrid=self._psf_subgrid) image_full = self._add_psf(image_convolved) return image_full
def _partial_kernel(self, kernel_super, i, j): """ :param kernel_super: supersampled kernel :param i: index of super-sampled position in first axis :param j: index of super-sampled position in second axis :return: effective kernel rebinned to regular grid resulting from the subpersampled position (i,j) """ n = len(kernel_super) kernel_size = int(round(n / float(self._supersampling_factor) + 1.5)) if kernel_size % 2 == 0: kernel_size += 1 n_match = kernel_size * self._supersampling_factor kernel_super_match = np.zeros((n_match, n_match)) delta = int((n_match - n - self._supersampling_factor) / 2) + 1 i0 = delta # index where to start kernel for i=0 j0 = delta # index where to start kernel for j=0 (should be symmetric) kernel_super_match[i0 + i:i0 + i + n, j0 + j:j0 + j + n] = kernel_super #kernel_super_match = image_util.cut_edges(kernel_super_match, numPix=n) kernel = image_util.re_size(kernel_super_match, factor=self._supersampling_factor) return kernel
def setup(self): lightModel = LightModel(light_model_list=['GAUSSIAN']) self.supersampling_factor = 3 self.delta_pix = 1 self.num_pix = 10 self.num_pix_kernel = 7 x, y = util.make_grid(numPix=self.num_pix_kernel, deltapix=self.delta_pix) kwargs_kernel = [{'amp': 1, 'sigma': 3, 'center_x': 0, 'center_y': 0}] kernel = lightModel.surface_brightness(x, y, kwargs_kernel) self.kernel = util.array2image(kernel) self.kernel /= np.sum(self.kernel) x_sub, y_sub = util.make_grid(numPix=self.num_pix_kernel, deltapix=self.delta_pix, subgrid_res=self.supersampling_factor) kernel_super = lightModel.surface_brightness(x_sub, y_sub, kwargs_kernel) self.kernel_super = util.array2image(kernel_super) self.kernel_super /= np.sum(self.kernel_super) x_sub, y_sub = util.make_grid(numPix=self.num_pix, deltapix=self.delta_pix, subgrid_res=self.supersampling_factor) kwargs = [{'amp': 1, 'sigma': 2, 'center_x': 0, 'center_y': 0}] flux = lightModel.surface_brightness(x_sub, y_sub, kwargs) self.model_super = util.array2image(flux) self.model = image_util.re_size(self.model_super, factor=self.supersampling_factor)
lensModel = LensModel(lens_model_list) x_grid, y_grid = util.make_grid(numPix=500, deltapix=0.05) kappa = lensModel.kappa(x_grid, y_grid, kwargs_lens_list) kappa = util.array2image(kappa) loc = "P_0_"+str(i)+'_'+str(j)+'_'+str(k)+"_("+str(ii) ngc_data = PIL.Image.open(<loc>) ngc_data = np.asarray(ngc_data)/255 ngc_conv = scipy.ndimage.filters.gaussian_filter(ngc_data, sigma, mode='nearest', truncate=6) 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) ngc_data_resized = image_util.re_size(ngc_cut, factor) image_1d = util.image2array(ngc_data_resized) shapeletSet = ShapeletSet() coeff_ngc = shapeletSet.decomposition(image_1d, x, y, n_max, beta, 1., center_x=0, center_y=0) image_reconstructed = shapeletSet.function(x, y, coeff_ngc, n_max, beta, center_x=0, center_y=0) image_reconstructed_2d = util.array2image(image_reconstructed) theta_x_high_res, theta_y_high_res = util.make_grid(numPix=numPix*high_res_factor, deltapix=deltaPix/high_res_factor) beta_x_high_res, beta_y_high_res = lensModel.ray_shooting(theta_x_high_res, theta_y_high_res, kwargs=kwargs_lens_list) source_lensed = shapeletSet.function(beta_x_high_res, beta_y_high_res, coeff_ngc, n_max, beta=.05, center_x=cen[ii], center_y=0)
# we slightly convolve the image with a Gaussian convolution kernel of a few pixels (optional) sigma = 5 ngc_conv = scipy.ndimage.filters.gaussian_filter(ngc_square, sigma, mode='nearest', 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,
# deltaPix = 0.27 # pixel size (low res of data) high_res_factor = 5 # higher resolution factor (per axis) # make the high resolution grid theta_x_high_res, theta_y_high_res = util.make_grid(numPix=numPix*high_res_factor, deltapix=deltaPix/high_res_factor) # ray-shoot the image plane coordinates (angles) to the source plane (angles) beta_x_high_res, beta_y_high_res = lensModel.ray_shooting(theta_x_high_res, theta_y_high_res, kwargs=kwargs_lens_list) # now we do the same as in Section 2, we just evaluate the shapelet functions in the new coordinate system of the source plane # Attention, now the units are not pixels but angles! So we have to define the size and position. # This is simply by chosing a beta (Gaussian width of the Shapelets) and a new center source_lensed = shapeletSet.function(beta_x_high_res, beta_y_high_res, coeff_ngc, n_max, beta=.05, center_x=0.1, center_y=0) # and turn the 1d vector back into a 2d array source_lensed_HR = util.array2image(source_lensed) # map 1d data vector in 2d image source_lensed = image_util.re_size(source_lensed_HR, high_res_factor) bkg_cut=cat[i][0:20,0:20] bkgmed=np.median(bkg_cut) sigma=0.985 source_lensed_conv = scipy.ndimage.filters.gaussian_filter(source_lensed, sigma, mode='nearest', truncate=6) exp_time = 90 # exposure time to quantify the Poisson noise level background_rms = 0.9# np.sqrt(bkgmed) # background rms value poisson = image_util.add_poisson(source_lensed_conv, exp_time=exp_time) bkg = image_util.add_background(source_lensed_conv, sigma_bkd=background_rms) noisy_source_lensed = source_lensed_conv + bkg + poisson f, axes = plt.subplots(1, 4, figsize=(24, 6), sharex=False, sharey=False) axes[0].imshow(np.log10(source_ALL), cmap='gist_heat', origin="lower")
def test_re_size(): grid = np.zeros((200, 100)) grid[100, 50] = 4 grid_small = image_util.re_size(grid, factor=2) assert grid_small[50][25] == 1
def test_supersampling_simple(): """ :return: """ from lenstronomy.Data.psf import PSF from lenstronomy.SimulationAPI.data_api import DataAPI detector_pixel_scale = 0.04 numpix = 64 supersampling_factor = 2 # generate a Gaussian image x, y = util.make_grid(numPix=numpix * supersampling_factor, deltapix=detector_pixel_scale / supersampling_factor) from lenstronomy.LightModel.Profiles.gaussian import Gaussian gaussian = Gaussian() image_1d = gaussian.function(x, y, amp=1, sigma=0.1) image = util.array2image(image_1d) # generate psf kernal supersampled kernel_super = kernel_util.kernel_gaussian( kernel_numPix=21 * supersampling_factor + 1, deltaPix=detector_pixel_scale / supersampling_factor, fwhm=0.2) psf_parameters = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel_super, 'point_source_supersampling_factor': supersampling_factor } kwargs_detector = { 'pixel_scale': detector_pixel_scale, 'ccd_gain': 2.5, 'read_noise': 4.0, 'magnitude_zero_point': 25.0, 'exposure_time': 5400.0, 'sky_brightness': 22, 'num_exposures': 1, 'background_noise': None } kwargs_numerics = { 'supersampling_factor': 2, 'supersampling_convolution': True, 'point_source_supersampling_factor': 2, 'supersampling_kernel_size': 21 } psf_model = PSF(**psf_parameters) data_class = DataAPI(numpix=numpix, **kwargs_detector).data_class from lenstronomy.ImSim.Numerics.numerics_subframe import NumericsSubFrame image_numerics = NumericsSubFrame(pixel_grid=data_class, psf=psf_model, **kwargs_numerics) conv_class = image_numerics.convolution_class conv_flat = conv_class.convolution2d(image) print(np.shape(conv_flat), 'shape of output') # psf_helper = lenstronomy_utils.PSFHelper(data_class, psf_model, kwargs_numerics) # Convolve with lenstronomy and with scipy # helper_image = psf_helper.psf_model(image) from scipy import signal scipy_image = signal.fftconvolve(image, kernel_super, mode='same') from lenstronomy.Util import image_util image_scipy_resized = image_util.re_size(scipy_image, supersampling_factor) image_unconvolved = image_util.re_size(image, supersampling_factor) # Compare the outputs # low res convolution as comparison kwargs_numerics_low_res = { 'supersampling_factor': 2, 'supersampling_convolution': False, 'point_source_supersampling_factor': 2, } image_numerics_low_res = NumericsSubFrame(pixel_grid=data_class, psf=psf_model, **kwargs_numerics_low_res) conv_class_low_res = image_numerics_low_res.convolution_class conv_flat_low_res = conv_class_low_res.convolution2d(image_unconvolved) #import matplotlib.pyplot as plt #plt.matshow(image_scipy_resized - image_unconvolved) #plt.colorbar() #plt.show() #plt.matshow(image_scipy_resized - conv_flat) #plt.colorbar() #plt.show() #plt.matshow(image_scipy_resized - conv_flat_low_res) #plt.colorbar() #plt.show() np.testing.assert_almost_equal(conv_flat, image_scipy_resized)