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 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 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 subgrid_point_source_kernel(self, subgrid_res): """ :return: """ if hasattr(self, '_kernel_point_source_subsampled') and self._point_source_subsampling_factor == subgrid_res: pass else: if self.psf_type == 'GAUSSIAN': kernel_numPix = self._truncation / self._pixel_size * subgrid_res kernel_numPix = int(round(kernel_numPix)) if kernel_numPix % 2 == 0: kernel_numPix += 1 self._kernel_point_source_subsampled = kernel_util.kernel_gaussian(kernel_numPix, self._pixel_size/subgrid_res, self._fwhm) elif self.psf_type == 'PIXEL': kernel = kernel_util.subgrid_kernel(self.kernel_point_source, subgrid_res, odd=True, num_iter=5) n = len(self.kernel_point_source) n_new = n * subgrid_res if n_new % 2 == 0: n_new -= 1 if hasattr(self, '_kernel_point_source_subsampled'): print("Warning: subsampled point source kernel overwritten due to different subsampling size requested.") self._kernel_point_source_subsampled = kernel_util.cut_psf(kernel, psf_size=n_new) self._point_source_subsampling_factor = subgrid_res return self._kernel_point_source_subsampled
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) """
def setup(self): self.deltaPix = 0.05 fwhm = 0.2 kwargs_gaussian = {'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': self.deltaPix} self.psf_gaussian = PSF(**kwargs_gaussian) kernel_point_source = kernel_util.kernel_gaussian(kernel_numPix=21, deltaPix=self.deltaPix, fwhm=fwhm) kwargs_pixel = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source} self.psf_pixel = PSF(**kwargs_pixel)
def kernel_point_source(self): if not hasattr(self, '_kernel_point_source'): if self.psf_type == 'GAUSSIAN': kernel_num_pix = min(round(self._truncation * self._fwhm / self._pixel_size), 201) if kernel_num_pix % 2 == 0: kernel_num_pix += 1 self._kernel_point_source = kernel_util.kernel_gaussian(kernel_num_pix, self._pixel_size, self._fwhm) return self._kernel_point_source
def kernel_point_source(self): if not hasattr(self, '_kernel_point_source'): if self.psf_type == 'GAUSSIAN': kernel_numPix = self._truncation / self._pixel_size if kernel_numPix % 2 == 0: kernel_numPix += 1 self._kernel_point_source = kernel_util.kernel_gaussian(kernel_numPix, self._pixel_size, self._fwhm) else: raise ValueError("kernel_point_source could not be created. Please follow the guidelines of the PSF class!") return self._kernel_point_source
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
def test_fwhm(self): deltaPix = 0.05 fwhm = 0.1 kwargs = {'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncate': 5, 'pixel_size': deltaPix} fwhm_compute = self.psf_gaussian.psf_fwhm(kwargs=kwargs, deltaPix=deltaPix) assert fwhm_compute == fwhm kernel = kernel_util.kernel_gaussian(kernel_numPix=11, deltaPix=deltaPix, fwhm=fwhm) kwargs = {'psf_type': 'PIXEL', 'truncate': 5, 'pixel_size': deltaPix, 'kernel_point_source': kernel} fwhm_compute = self.psf_gaussian.psf_fwhm(kwargs=kwargs, deltaPix=deltaPix) npt.assert_almost_equal(fwhm_compute, fwhm, decimal=6) kwargs = {'psf_type': 'PIXEL', 'truncate': 5, 'pixel_size': deltaPix, 'kernel_point_source_subsampled': kernel} fwhm_compute = self.psf_gaussian.psf_fwhm(kwargs=kwargs, deltaPix=deltaPix) npt.assert_almost_equal(fwhm_compute, fwhm, decimal=6)
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
def test_fwhm(self): deltaPix = 1. fwhm = 5.6 kwargs = {'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': deltaPix} psf_kernel = PSF(**kwargs) fwhm_compute = psf_kernel.fwhm assert fwhm_compute == fwhm kernel = kernel_util.kernel_gaussian(kernel_numPix=31, deltaPix=deltaPix, fwhm=fwhm) kwargs = {'psf_type': 'PIXEL', 'truncation': 5, 'pixel_size': deltaPix, 'kernel_point_source': kernel} psf_kernel = PSF(**kwargs) fwhm_compute = psf_kernel.fwhm npt.assert_almost_equal(fwhm_compute, fwhm, decimal=1) kwargs = {'psf_type': 'PIXEL', 'truncation': 5, 'pixel_size': deltaPix, 'kernel_point_source': kernel, 'point_source_supersampling_factor': 1} psf_kernel = PSF(**kwargs) fwhm_compute = psf_kernel.fwhm npt.assert_almost_equal(fwhm_compute, fwhm, decimal=1)
def test_warning(self): deltaPix = 0.05 # pixel size of image subsampling_res = 4 # subsampling scale factor (in each dimension) fwhm = 0.3 # FWHM of the PSF kernel # 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) print(len(kernel_point_source_subsampled), 'test') kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source_subsampled, 'point_source_supersampling_factor': subsampling_res, 'psf_error_map': np.ones_like(kernel_point_source_subsampled) } psf_kernel = PSF(**kwargs_psf) n = len(psf_kernel.kernel_point_source) error_map = psf_kernel.psf_error_map assert len(error_map) == n
def setup(self): # we define a model consisting of a singe Sersric profile from lenstronomy.LightModel.light_model import LightModel light_model_list = ['SERSIC_ELLIPSE'] self.lightModel = LightModel(light_model_list=light_model_list) self.kwargs_light = [ {'amp': 100, 'R_sersic': 0.5, 'n_sersic': 3, 'e1': 0, 'e2': 0, 'center_x': 0.02, 'center_y': 0}] # we define a pixel grid and a higher resolution super sampling factor self._supersampling_factor = 5 numPix = 61 # cutout pixel size deltaPix = 0.05 # pixel size in arcsec (area per pixel = deltaPix**2) x, y, ra_at_xy_0, dec_at_xy_0, x_at_radec_0, y_at_radec_0, Mpix2coord, Mcoord2pix = util.make_grid_with_coordtransform( numPix=numPix, deltapix=deltaPix, subgrid_res=1, left_lower=False, inverse=False) flux = self.lightModel.surface_brightness(x, y, kwargs_list=self.kwargs_light) flux = util.array2image(flux) flux_max = np.max(flux) conv_pixels_partial = np.zeros((numPix, numPix), dtype=bool) conv_pixels_partial[flux >= flux_max / 20] = True self._conv_pixels_partial = conv_pixels_partial # high resolution ray-tracing and high resolution convolution, the full calculation self.kwargs_numerics_true = {'supersampling_factor': self._supersampling_factor, # super sampling factor of (partial) high resolution ray-tracing 'compute_mode': 'regular', # 'regular' or 'adaptive' 'supersampling_convolution': True, # bool, if True, performs the supersampled convolution (either on regular or adaptive grid) 'supersampling_kernel_size': None, # size of the higher resolution kernel region (can be smaller than the original kernel). None leads to use the full size 'flux_evaluate_indexes': None, # bool mask, if None, it will evaluate all (sub) pixels 'supersampled_indexes': None, # bool mask of pixels to be computed in supersampled grid (only for adaptive mode) 'compute_indexes': None, # bool mask of pixels to be computed the PSF response (flux being added to). Only used for adaptive mode and can be set =likelihood mask. 'point_source_supersampling_factor': 1, # int, supersampling factor when rendering a point source (not used in this script) } # high resolution convolution on a smaller PSF with low resolution convolution on the edges of the PSF and high resolution ray tracing self.kwargs_numerics_high_res_narrow = {'supersampling_factor': self._supersampling_factor, 'compute_mode': 'regular', 'supersampling_convolution': True, 'supersampling_kernel_size': 5, } # low resolution convolution based on high resolution ray-tracing grid self.kwargs_numerics_low_conv_high_grid = {'supersampling_factor': self._supersampling_factor, 'compute_mode': 'regular', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 } # low resolution convolution with a subset of pixels with high resolution ray-tracing self.kwargs_numerics_low_conv_high_adaptive = {'supersampling_factor': self._supersampling_factor, 'compute_mode': 'adaptive', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 'supersampled_indexes': self._conv_pixels_partial, 'convolution_kernel_size': 9, } # low resolution convolution with a subset of pixels with high resolution ray-tracing and high resoluton convolution on smaller kernel size self.kwargs_numerics_high_adaptive = {'supersampling_factor': self._supersampling_factor, 'compute_mode': 'adaptive', 'supersampling_convolution': True, # does not matter for supersampling_factor=1 'supersampling_kernel_size': 5, # does not matter for supersampling_factor=1 'supersampled_indexes': self._conv_pixels_partial, 'convolution_kernel_size': 9, } # low resolution convolution and low resolution ray tracing, the simplest calculation self.kwargs_numerics_low_res = {'supersampling_factor': 1, 'compute_mode': 'regular', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 'convolution_kernel_size': 9, } flux_evaluate_indexes = np.zeros((numPix, numPix), dtype=bool) flux_evaluate_indexes[flux >= flux_max / 1000] = True # low resolution convolution on subframe self.kwargs_numerics_partial = {'supersampling_factor': 1, 'compute_mode': 'regular', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 'flux_evaluate_indexes': flux_evaluate_indexes, 'convolution_kernel_size': 9 } # import PSF file kernel_super = kernel_util.kernel_gaussian(kernel_numPix=11 * self._supersampling_factor, deltaPix=deltaPix / self._supersampling_factor, fwhm=0.1) kernel_size = 9 kernel_super = kernel_util.cut_psf(psf_data=kernel_super, psf_size=kernel_size * self._supersampling_factor) # make instance of the PixelGrid class from lenstronomy.Data.pixel_grid import PixelGrid kwargs_grid = {'nx': numPix, 'ny': numPix, 'transform_pix2angle': Mpix2coord, 'ra_at_xy_0': ra_at_xy_0, 'dec_at_xy_0': dec_at_xy_0} self.pixel_grid = PixelGrid(**kwargs_grid) # make instance of the PSF class from lenstronomy.Data.psf import PSF kwargs_psf = {'psf_type': 'PIXEL', 'kernel_point_source': kernel_super, 'point_source_supersampling_factor': self._supersampling_factor} self.psf_class = PSF(**kwargs_psf) # without convolution image_model_true = ImageModel(self.pixel_grid, self.psf_class, lens_light_model_class=self.lightModel, kwargs_numerics=self.kwargs_numerics_true) self.image_true = image_model_true.image(kwargs_lens_light=self.kwargs_light)
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)