class TestSimulation(object): def setup(self): self.SimAPI = Simulation() # data specifics sigma_bkg = 1. # background noise per pixel exp_time = 10 # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = 100 # cutout pixel size deltaPix = 0.05 # pixel size in arcsec (area per pixel = deltaPix**2) fwhm = 0.5 # full width half max of PSF # PSF specification kwargs_data = self.SimAPI.data_configure(numPix, deltaPix, exp_time, sigma_bkg) data_class = Data(kwargs_data) kwargs_psf = self.SimAPI.psf_configure(psf_type='GAUSSIAN', fwhm=fwhm, kernelsize=31, deltaPix=deltaPix, truncate=5) psf_class = PSF(kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) e1, e2 = param_util.phi_q2_ellipticity(0.2, 0.8) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 } lens_model_list = ['SPEP', 'SHEAR'] self.kwargs_lens = [kwargs_spemd, kwargs_shear] lens_model_class = LensModel(lens_model_list=lens_model_list) # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'amp': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': 0.2, 'e2': 0.3 } lens_light_model_list = ['SERSIC'] self.kwargs_lens_light = [kwargs_sersic] lens_light_model_class = LightModel( light_model_list=lens_light_model_list) source_model_list = ['SERSIC_ELLIPSE'] self.kwargs_source = [kwargs_sersic_ellipse] source_model_class = LightModel(light_model_list=source_model_list) self.kwargs_ps = [ { 'ra_source': 0.0, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness point_source_class = PointSource( point_source_type_list=['SOURCE_POSITION'], fixed_magnification_list=[True]) kwargs_numerics = {'subgrid_res': 2, 'psf_subgrid': True} self.imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) def test_im_sim(self): # model specifics # list of lens models, supports: # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) e1, e2 = param_util.phi_q2_ellipticity(0.2, 0.8) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 } kwargs_lens_list = [kwargs_spemd, kwargs_shear] # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'amp': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': 0.2, 'e2': 0.3 } kwargs_lens_light_list = [kwargs_sersic] kwargs_source_list = [kwargs_sersic_ellipse] kwargs_ps = [ { 'ra_source': 0.0, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness image_sim = self.SimAPI.simulate(self.imageModel, kwargs_lens_list, kwargs_source_list, kwargs_lens_light_list, kwargs_ps) assert len(image_sim) == 100 npt.assert_almost_equal(np.sum(image_sim), 14894.805448596271, decimal=-3) def test_normalize_flux(self): kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'q': 0.8, 'phi_G': 0.2 } lens_model_list = ['SPEP', 'SHEAR'] kwargs_lens_list = [kwargs_spemd, kwargs_shear] # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'amp': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': 0.2, 'e2': 0.3 } lens_light_model_list = ['SERSIC'] kwargs_lens_light_list = [kwargs_sersic] source_model_list = ['SERSIC_ELLIPSE'] kwargs_source_list = [kwargs_sersic_ellipse] kwargs_ps = [ { 'ra_source': 0.0, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness kwargs_options = { 'lens_model_list': lens_model_list, 'lens_light_model_list': lens_light_model_list, 'source_light_model_list': source_model_list, 'psf_type': 'PIXEL', 'point_source_list': ['SOURCE_POSITION'], 'fixed_magnification': True # if True, simulates point source at source position of 'sourcePos_xy' in kwargs_ps } #image_sim = self.SimAPI.simulate(self.imageModel, kwargs_lens_list, kwargs_source_list, # kwargs_lens_light_list, kwargs_ps) kwargs_source_updated, kwargs_lens_light_updated, kwargs_else_updated = self.SimAPI.normalize_flux( kwargs_options, kwargs_source_list, kwargs_lens_light_list, kwargs_ps, norm_factor_source=3, norm_factor_lens_light=2, norm_factor_point_source=0.) print(kwargs_else_updated, 'test') assert kwargs_else_updated[0]['source_amp'] == 0 def test_normalize_flux_source(self): # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'q': 0.8, 'phi_G': 0.2 } lens_model_list = ['SPEP', 'SHEAR'] kwargs_lens_list = [kwargs_spemd, kwargs_shear] # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'amp': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': 0.2, 'e2': 0.3 } lens_light_model_list = ['SERSIC'] kwargs_lens_light_list = [kwargs_sersic] source_model_list = ['SERSIC_ELLIPSE'] kwargs_source_list = [kwargs_sersic_ellipse] kwargs_options = { 'lens_model_list': lens_model_list, 'lens_light_model_list': lens_light_model_list, 'source_light_model_list': source_model_list, 'psf_type': 'PIXEL', 'point_source': True # if True, simulates point source at source position of 'sourcePos_xy' in kwargs_else } kwargs_source_updated = self.SimAPI.normalize_flux_source( kwargs_options, kwargs_source_list, norm_factor_source=10) assert kwargs_source_updated[0][ 'amp'] == kwargs_source_list[0]['amp'] * 10 def test_source_plane(self): numPix = 10 deltaPix = 0.1 kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': 0.2, 'e2': 0.3 } lens_light_model_list = ['SERSIC'] source_model_list = ['SERSIC_ELLIPSE'] kwargs_source = [kwargs_sersic_ellipse] kwargs_options = { 'lens_light_model_list': lens_light_model_list, 'source_light_model_list': source_model_list, 'psf_type': 'pixel', 'point_source': True # if True, simulates point source at source position of 'sourcePos_xy' in kwargs_else } source = self.SimAPI.source_plane(kwargs_options, kwargs_source, numPix, deltaPix) assert len(source) == numPix
class SingleBand(object): """ class to operate on single exposure """ def __init__(self, collector_area, numPix, deltaPix, readout_noise, sky_brightness, extinction, exposure_time, psf_type, fwhm, *args, **kwargs): """ :param collector_area: area of collector in m^2 :param numPix: number of pixels :param deltaPix: FoV per pixel in units of arcsec :param readout_noise: rms value of readout per pixel in units of photons :param sky_brightness: number of photons of sky per area (arcsec) per time (second) for a collector area (1 m^2) :param extinction: exctinction (galactic and atmosphere combined). Only use this if magnitude calibration is done without it. :param exposure_time: exposure time (seconds) :param psf_type: :param fwhm: :param args: :param kwargs: """ self.simulation = Simulation() sky_per_pixel = sky_brightness * collector_area * deltaPix**2 # time independent noise term per pixel per second sigma_bkg = np.sqrt( readout_noise**2 + exposure_time * sky_per_pixel**2 ) / exposure_time # total Gaussian noise term per pixel in full exposure (in units of counts per second) kwargs_data = self.simulation.data_configure(numPix, deltaPix, exposure_time, sigma_bkg) self._data = Data(kwargs_data) kwargs_psf = self.simulation.psf_configure(psf_type, fwhm) self._psf = PSF(kwargs_psf) self._flux_calibration_factor = collector_area / extinction * deltaPix**2 # transforms intrinsic surface brightness per angular area into the flux normalizations per pixel def simulate(self, kwargs_options, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_else, lens_colour, source_colour, quasar_colour, no_noise=False, source_add=True, lens_light_add=True, point_source_add=True): """ :param kwargs_options: :param kwargs_lens: :param kwargs_source: :param kwargs_lens_light: :param kwargs_else: :param no_noise: :return: """ lensLightModel = LightModel( kwargs_options.get('lens_light_model_list', [])) sourceModel = LightModel( kwargs_options.get('source_light_model_list', [])) lensModel = LensModel( lens_model_list=kwargs_options.get('lens_model_list', [])) pointSource = PointSource( point_source_type_list=kwargs_options.get('point_source_list', []), lensModel=lensModel, fixed_magnification_list=kwargs_options.get( 'fixed_magnification_list', None), additional_images_list=kwargs_options.get('additional_images', None)) norm_factor_source = self._flux_calibration_factor * source_colour norm_factor_lens_light = self._flux_calibration_factor * lens_colour norm_factor_point_source = self._flux_calibration_factor * quasar_colour kwargs_source_updated, kwargs_lens_light_updated, kwargs_else_updated = self.simulation.normalize_flux( kwargs_options, kwargs_source, kwargs_lens_light, kwargs_else, norm_factor_source, norm_factor_lens_light, norm_factor_point_source) imageModel = ImageModel(self._data, self._psf, lensModel, sourceModel, lensLightModel, pointSource, kwargs_numerics={}) image = self.simulation.simulate(imageModel, kwargs_lens, kwargs_source_updated, kwargs_lens_light_updated, kwargs_else_updated, no_noise=no_noise, source_add=source_add, lens_light_add=lens_light_add, point_source_add=point_source_add) return image def source_plane(self, kwargs_options, kwargs_source, source_colour, numPix=100, deltaPix=0.01): """ :param kwargs_options: :param kwargs_source: :param kwargs_else: :param source_colour: :param numPix: :param deltaPix: :return: """ norm_factor_source = self._flux_calibration_factor * source_colour kwargs_source_updated = self.simulation.normalize_flux_source( kwargs_options, kwargs_source, norm_factor_source) image = self.simulation.source_plane(kwargs_options, kwargs_source_updated, numPix, deltaPix) return image
class TestSimulation(object): def setup(self): self.SimAPI = Simulation() # data specifics sigma_bkg = 1. # background noise per pixel exp_time = 10 # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = 100 # cutout pixel size deltaPix = 0.05 # pixel size in arcsec (area per pixel = deltaPix**2) fwhm = 0.5 # full width half max of PSF # PSF specification data_class = self.SimAPI.data_configure(numPix, deltaPix, exp_time, sigma_bkg) self.kwargs_data = data_class.constructor_kwargs() psf_class = self.SimAPI.psf_configure(psf_type='GAUSSIAN', fwhm=fwhm, kernelsize=31, deltaPix=deltaPix, truncate=5) self.kwargs_psf = psf_class.constructor_kwargs() # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'q': 0.8, 'phi_G': 0.2 } lens_model_list = ['SPEP', 'SHEAR'] self.kwargs_lens = [kwargs_spemd, kwargs_shear] lens_model_class = LensModel(lens_model_list=lens_model_list) # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'I0_sersic': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'I0_sersic': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'phi_G': 0.2, 'q': 0.9 } lens_light_model_list = ['SERSIC'] self.kwargs_lens_light = [kwargs_sersic] lens_light_model_class = LightModel( light_model_list=lens_light_model_list) source_model_list = ['SERSIC_ELLIPSE'] self.kwargs_source = [kwargs_sersic_ellipse] source_model_class = LightModel(light_model_list=source_model_list) self.kwargs_ps = [ { 'ra_source': 0.0, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness point_source_class = PointSource( point_source_type_list=['SOURCE_POSITION'], fixed_magnification_list=[True]) kwargs_numerics = {'subgrid_res': 2, 'psf_subgrid': True} self.imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) def test_im_sim(self): # model specifics # list of lens models, supports: # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'q': 0.8, 'phi_G': 0.2 } kwargs_lens_list = [kwargs_spemd, kwargs_shear] # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'I0_sersic': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'I0_sersic': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'phi_G': 0.2, 'q': 0.9 } kwargs_lens_light_list = [kwargs_sersic] kwargs_source_list = [kwargs_sersic_ellipse] kwargs_ps = [ { 'ra_source': 0.0, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness image_sim = self.SimAPI.simulate(self.imageModel, kwargs_lens_list, kwargs_source_list, kwargs_lens_light_list, kwargs_ps) assert len(image_sim) == 100 npt.assert_almost_equal(np.sum(image_sim), 24476.280571230454, decimal=-3) def test_normalize_flux(self): kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'q': 0.8, 'phi_G': 0.2 } lens_model_list = ['SPEP', 'SHEAR'] kwargs_lens_list = [kwargs_spemd, kwargs_shear] # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'I0_sersic': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'I0_sersic': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'phi_G': 0.2, 'q': 0.9 } lens_light_model_list = ['SERSIC'] kwargs_lens_light_list = [kwargs_sersic] source_model_list = ['SERSIC_ELLIPSE'] kwargs_source_list = [kwargs_sersic_ellipse] kwargs_ps = [ { 'ra_source': 0.0, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness kwargs_options = { 'lens_model_list': lens_model_list, 'lens_light_model_list': lens_light_model_list, 'source_light_model_list': source_model_list, 'psf_type': 'PIXEL', 'point_source_list': ['SOURCE_POSITION'], 'fixed_magnification': True # if True, simulates point source at source position of 'sourcePos_xy' in kwargs_ps } #image_sim = self.SimAPI.simulate(self.imageModel, kwargs_lens_list, kwargs_source_list, # kwargs_lens_light_list, kwargs_ps) kwargs_source_updated, kwargs_lens_light_updated, kwargs_else_updated = self.SimAPI.normalize_flux( kwargs_options, kwargs_source_list, kwargs_lens_light_list, kwargs_ps, norm_factor_source=3, norm_factor_lens_light=2, norm_factor_point_source=0.) print(kwargs_else_updated, 'test') assert kwargs_else_updated[0]['source_amp'] == 0 def test_normalize_flux_source(self): # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'q': 0.8, 'phi_G': 0.2 } lens_model_list = ['SPEP', 'SHEAR'] kwargs_lens_list = [kwargs_spemd, kwargs_shear] # list of light profiles (for lens and source) # 'SERSIC': spherical Sersic profile kwargs_sersic = { 'I0_sersic': 1., 'R_sersic': 0.1, 'n_sersic': 2, 'center_x': 0, 'center_y': 0 } # 'SERSIC_ELLIPSE': elliptical Sersic profile kwargs_sersic_ellipse = { 'I0_sersic': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'phi_G': 0.2, 'q': 0.9 } lens_light_model_list = ['SERSIC'] kwargs_lens_light_list = [kwargs_sersic] source_model_list = ['SERSIC_ELLIPSE'] kwargs_source_list = [kwargs_sersic_ellipse] kwargs_options = { 'lens_model_list': lens_model_list, 'lens_light_model_list': lens_light_model_list, 'source_light_model_list': source_model_list, 'psf_type': 'PIXEL', 'point_source': True # if True, simulates point source at source position of 'sourcePos_xy' in kwargs_else } kwargs_source_updated = self.SimAPI.normalize_flux_source( kwargs_options, kwargs_source_list, norm_factor_source=10) assert kwargs_source_updated[0][ 'I0_sersic'] == kwargs_source_list[0]['I0_sersic'] * 10 def test_source_plane(self): numPix = 10 deltaPix = 0.1 kwargs_sersic_ellipse = { 'I0_sersic': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'phi_G': 0.2, 'q': 0.9 } lens_light_model_list = ['SERSIC'] source_model_list = ['SERSIC_ELLIPSE'] kwargs_source = [kwargs_sersic_ellipse] kwargs_options = { 'lens_light_model_list': lens_light_model_list, 'source_light_model_list': source_model_list, 'psf_type': 'pixel', 'point_source': True # if True, simulates point source at source position of 'sourcePos_xy' in kwargs_else } source = self.SimAPI.source_plane(kwargs_options, kwargs_source, numPix, deltaPix) assert len(source) == numPix def test_shift_coordinate_grid(self): x_shift = 0.05 y_shift = 0 kwargs_data_shifted = self.SimAPI.shift_coordinate_grid( self.kwargs_data, x_shift, y_shift, pixel_units=False) kwargs_data_new = copy.deepcopy(self.kwargs_data) kwargs_data_new['ra_shift'] = x_shift kwargs_data_new['dec_shift'] = y_shift data = Data(kwargs_data=kwargs_data_shifted) data_new = Data(kwargs_data=kwargs_data_new) ra, dec = 0, 0 x, y = data.map_coord2pix(ra, dec) x_new, y_new = data_new.map_coord2pix(ra, dec) npt.assert_almost_equal(x, x_new, decimal=10) npt.assert_almost_equal(y, y_new, decimal=10) ra, dec = data.map_pix2coord(x, y) ra_new, dec_new = data_new.map_pix2coord(x, y) npt.assert_almost_equal(ra, ra_new, decimal=10) npt.assert_almost_equal(dec, dec_new, decimal=10) x_coords, y_coords = data.coordinates x_coords_new, y_coords_new = data_new.coordinates npt.assert_almost_equal(x_coords[0], x_coords_new[0], decimal=10) npt.assert_almost_equal(y_coords[0], y_coords_new[0], decimal=10)