def kernel_average_pixel(kernel_super, supersampling_factor): """ computes the effective convolution kernel assuming a uniform surface brightness on the scale of a pixel :param kernel_super: supersampled PSF of a point source (odd number per axis :param supersampling_factor: supersampling factor (int) :return: """ kernel_sum = np.sum(kernel_super) kernel_size = int( round(len(kernel_super) / float(supersampling_factor) + 0.5)) if kernel_size % 2 == 0: kernel_size += 1 n_high = kernel_size * supersampling_factor if n_high % 2 == 0: n_high += 1 kernel_pixel = np.zeros((n_high, n_high)) for i in range(supersampling_factor): k_x = int((kernel_size - 1) / 2 * supersampling_factor + i) for j in range(supersampling_factor): k_y = int((kernel_size - 1) / 2 * supersampling_factor + j) kernel_pixel = image_util.add_layer2image(kernel_pixel, k_x, k_y, kernel_super) if supersampling_factor % 2 == 0: kernel_pixel = averaging_even_kernel(kernel_pixel, supersampling_factor) else: kernel_pixel = util.averaging(kernel_pixel, numGrid=n_high, numPix=kernel_size) kernel_pixel /= np.sum(kernel_pixel) return kernel_pixel * kernel_sum
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 psf_error_map(self, ra_pos, dec_pos, amp, data, fix_psf_error_map=False): """ :param ra_pos: image positions of point sources :param dec_pos: image positions of point sources :param amp: amplitude of modeled point sources :param data: 2d numpy array of the data :param fix_psf_error_map: bool, if True, estimates the error based on the imput (modeled) amplitude, else uses the data to do so. :return: 2d array of size of the image with error terms (sigma**2) expected from inaccuracies in the PSF modeling """ x_pos, y_pos = self._pixel_grid.map_coord2pix(ra_pos, dec_pos) psf_kernel = self._psf.kernel_point_source psf_error_map = self._psf.psf_error_map error_map = np.zeros_like(data) for i in range(len(x_pos)): if fix_psf_error_map is True: amp_estimated = amp else: amp_estimated = kernel_util.estimate_amp( data, x_pos[i], y_pos[i], psf_kernel) error_map = image_util.add_layer2image( error_map, x_pos[i], y_pos[i], psf_error_map * (psf_kernel * amp_estimated)**2) return error_map
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 psf_error_map(self, ra_pos, dec_pos, amp, data): x_pos, y_pos = self._pixel_grid.map_coord2pix(ra_pos, dec_pos) psf_kernel = self._psf.kernel_point_source psf_error_map = self._psf.psf_error_map error_map = np.zeros_like(data) for i in range(len(x_pos)): if self._fix_psf_error_map: amp_estimated = amp else: amp_estimated = kernel_util.estimate_amp( data, x_pos[i], y_pos[i], psf_kernel) error_map = image_util.add_layer2image( error_map, x_pos[i], y_pos[i], psf_error_map * (psf_kernel * amp_estimated)**2) return error_map
def point_source_rendering_old(self, ra_pos, dec_pos, amp): """ :param n_points: :param x_pos: :param y_pos: :param psf_large: :return: response matrix of point sources """ x_pos, y_pos = self._Data.map_coord2pix(ra_pos, dec_pos) psf_point_source = self._PSF.kernel_point_source grid2d = np.zeros_like(self._Data.data) for i in range(len(x_pos)): grid2d = image_util.add_layer2image(grid2d, x_pos[i], y_pos[i], amp[i] * psf_point_source) return grid2d
def test_cutout_source_border(): kernel_size = 7 image = np.zeros((10, 10)) kernel = np.zeros((kernel_size, kernel_size)) kernel[2, 2] = 1 shift_x = +0.1 shift_y = 0 x_c, y_c = 2, 5 x_pos = x_c + shift_x y_pos = y_c + shift_y #kernel_shifted = interp.shift(kernel, [shift_y, shift_x], order=1) image = image_util.add_layer2image(image, x_pos, y_pos, kernel, order=1) kernel_new = kernel_util.cutout_source(x_pos=x_pos, y_pos=y_pos, image=image, kernelsize=kernel_size) nx_new, ny_new = np.shape(kernel_new) print(kernel_new) assert nx_new == kernel_size assert ny_new == kernel_size npt.assert_almost_equal(kernel_new[2, 2], kernel[2, 2], decimal=2)
def pixel_kernel(point_source_kernel, subgrid_res=7): """ converts a pixelised kernel of a point source to a kernel representing a uniform extended pixel :param point_source_kernel: :param subgrid_res: :return: convolution kernel for an extended pixel """ kernel_subgrid = subgrid_kernel(point_source_kernel, subgrid_res, num_iter=10) kernel_size = len(point_source_kernel) kernel_pixel = np.zeros((kernel_size*subgrid_res, kernel_size*subgrid_res)) for i in range(subgrid_res): k_x = int((kernel_size-1) / 2 * subgrid_res + i) for j in range(subgrid_res): k_y = int((kernel_size-1) / 2 * subgrid_res + j) kernel_pixel = image_util.add_layer2image(kernel_pixel, k_x, k_y, kernel_subgrid) kernel_pixel = util.averaging(kernel_pixel, numGrid=kernel_size*subgrid_res, numPix=kernel_size) return kernel_norm(kernel_pixel)
def test_cutout_source(): """ test whether a shifted psf can be reproduced sufficiently well :return: """ kernel_size = 5 image = np.zeros((10, 10)) kernel = np.zeros((kernel_size, kernel_size)) kernel[2, 2] = 1 shift_x = 0.5 shift_y = 0 x_c, y_c = 5, 5 x_pos = x_c + shift_x y_pos = y_c + shift_y #kernel_shifted = interp.shift(kernel, [shift_y, shift_x], order=1) image = image_util.add_layer2image(image, x_pos, y_pos, kernel, order=1) print(image) kernel_new = kernel_util.cutout_source(x_pos=x_pos, y_pos=y_pos, image=image, kernelsize=kernel_size) npt.assert_almost_equal(kernel_new[2, 2], kernel[2, 2], decimal=2)
def test_add_layer2image_odd_odd(): grid2d = np.zeros((101, 101)) kernel = np.zeros((21, 21)) kernel[10, 10] = 1 x_pos = 50 y_pos = 50 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=0) assert added[50, 50] == 1 assert added[49, 49] == 0 x_pos = 70 y_pos = 95 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=0) assert added[95, 70] == 1 x_pos = 20 y_pos = 45 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=0) assert added[45, 20] == 1 x_pos = 45 y_pos = 20 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=0) assert added[20, 45] == 1 x_pos = 20 y_pos = 55 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=0) assert added[55, 20] == 1 x_pos = 20 y_pos = 100 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=0) assert added[100, 20] == 1 x_pos = 20.5 y_pos = 100 added = image_util.add_layer2image(grid2d, x_pos, y_pos, kernel, order=1) assert added[100, 20] == 0.5 assert added[100, 21] == 0.5