def __init__(self, multi_band_list, kwargs_model, likelihood_mask_list=None, band_index=0): self.type = 'single-band-multi-model' if likelihood_mask_list is None: likelihood_mask_list = [None for i in range(len(multi_band_list))] lens_model_class, source_model_class, lens_light_model_class, point_source_class = class_creator.create_class_instances(band_index=band_index, **kwargs_model) kwargs_data = multi_band_list[band_index][0] kwargs_psf = multi_band_list[band_index][1] kwargs_numerics = multi_band_list[band_index][2] data_i = ImageData(**kwargs_data) psf_i = PSF(kwargs_psf=kwargs_psf) index_lens_model_list = kwargs_model.get('index_lens_model_list', [None for i in range(len(multi_band_list))]) self._index_lens_model = index_lens_model_list[band_index] index_source_list = kwargs_model.get('index_source_light_model_list', [None for i in range(len(multi_band_list))]) self._index_source = index_source_list[band_index] index_lens_light_list = kwargs_model.get('index_lens_light_model_list', [None for i in range(len(multi_band_list))]) self._index_lens_light = index_lens_light_list[band_index] index_point_source_list = kwargs_model.get('index_point_source_model_list', [None for i in range(len(multi_band_list))]) self._index_point_source = index_point_source_list[band_index] super(SingleBandMultiModel, self).__init__(data_i, psf_i, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics, likelihood_mask=likelihood_mask_list[band_index]) self._imageModel = ImageLinearFit(data_i, psf_i, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics, likelihood_mask=likelihood_mask_list[band_index])
def test_error_map_source(self): sourceModel = LightModel(light_model_list=['UNIFORM', 'UNIFORM']) kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) psf_type = "GAUSSIAN" fwhm = 0.9 kwargs_psf = {'psf_type': psf_type, 'fwhm': fwhm} psf_class = PSF(**kwargs_psf) imageModel = ImageLinearFit(data_class=data_class, psf_class=psf_class, lens_model_class=None, point_source_class=None, source_model_class=sourceModel) x_grid, y_grid = util.make_grid(numPix=10, deltapix=1) error_map = imageModel.error_map_source(kwargs_source=[{ 'amp': 1 }, { 'amp': 1 }], x_grid=x_grid, y_grid=y_grid, cov_param=np.array([[1, 0], [0, 1]])) assert error_map[0] == 2
def setup(self): # data specifics sigma_bkg = .05 # background noise per pixel exp_time = 100 # 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 = sim_util.data_configure_simple(numPix, deltaPix, exp_time, sigma_bkg, inverse=True) data_class = ImageData(**kwargs_data) kwargs_psf = {'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': deltaPix} psf_class = PSF(**kwargs_psf) kernel = psf_class.kernel_point_source kwargs_psf = {'psf_type': 'PIXEL', 'kernel_point_source': kernel, 'psf_error_map': np.ones_like(kernel) * 0.001} psf_class = PSF(**kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = {'gamma1': 0.01, 'gamma2': 0.01} # gamma_ext: shear strength, psi_ext: shear angel (in radian) phi, q = 0.2, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi, q) 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 phi, q = 0.2, 0.9 e1, e2 = param_util.phi_q2_ellipticity(phi, q) kwargs_sersic_ellipse = {'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2} 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.01, '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 = {'supersampling_factor': 2, 'supersampling_convolution': False} imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) image_sim = sim_util.simulate_simple(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) data_class.update_data(image_sim) self.imageModel = ImageLinearFit(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) self.solver = LensEquationSolver(lensModel=self.imageModel.LensModel)
def create_image_model(kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model, likelihood_mask=None): """ :param kwargs_data: :param kwargs_psf: :param kwargs_model: :param kwargs_model_indexes: :return: """ data_class = ImageData(**kwargs_data) psf_class = PSF(**kwargs_psf) lens_model_class, source_model_class, lens_light_model_class, point_source_class, extinction_class = create_class_instances( **kwargs_model) imageModel = ImageLinearFit(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, extinction_class, kwargs_numerics, likelihood_mask=likelihood_mask) return imageModel
def create_image_model(kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model, image_likelihood_mask=None): """ :param kwargs_data: ImageData keyword arguments :param kwargs_psf: PSF keyword arguments :param kwargs_numerics: numerics keyword arguments for Numerics() class :param kwargs_model: model keyword arguments :param image_likelihood_mask: image likelihood mask (same size as image_data with 1 indicating being evaluated and 0 being left out) :return: ImageLinearFit() instance """ data_class = ImageData(**kwargs_data) psf_class = PSF(**kwargs_psf) lens_model_class, source_model_class, lens_light_model_class, point_source_class, extinction_class = create_class_instances( **kwargs_model) imageModel = ImageLinearFit(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, extinction_class, kwargs_numerics, likelihood_mask=image_likelihood_mask) return imageModel
def setup(self): # data specifics sigma_bkg = 0.01 # background noise per pixel exp_time = 100 # 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.3 # full width half max of PSF # PSF specification kwargs_data = sim_util.data_configure_simple(numPix, deltaPix, exp_time, sigma_bkg) data_class = ImageData(**kwargs_data) sigma = util.fwhm2sigma(fwhm) x_grid, y_grid = util.make_grid(numPix=31, deltapix=0.05) from lenstronomy.LightModel.Profiles.gaussian import Gaussian gaussian = Gaussian() kernel_point_source = gaussian.function(x_grid, y_grid, amp=1., sigma=sigma, center_x=0, center_y=0) kernel_point_source /= np.sum(kernel_point_source) kernel_point_source = util.array2image(kernel_point_source) psf_error_map = np.zeros_like(kernel_point_source) self.kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source, 'psf_error_map': psf_error_map } psf_class = PSF(**self.kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'gamma1': 0.01, 'gamma2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) phi, q = 0.2, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi, q) 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 phi, q = 0.2, 0.9 e1, e2 = param_util.phi_q2_ellipticity(phi, q) kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 } 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': 10. } ] # 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 = { 'supersampling_factor': 3, 'supersampling_convolution': False, 'compute_mode': 'regular', 'point_source_supersampling_factor': 3 } imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) image_sim = sim_util.simulate_simple(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) data_class.update_data(image_sim) self.imageModel = ImageLinearFit(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) self.psf_fitting = PsfFitting(self.imageModel) self.kwargs_params = { 'kwargs_lens': self.kwargs_lens, 'kwargs_source': self.kwargs_source, 'kwargs_lens_light': self.kwargs_lens_light, 'kwargs_ps': self.kwargs_ps }
def test_raise(self): with self.assertRaises(ValueError): # test various numerics that are not supported by the pixelbased solver kwargs_numerics = { 'supersampling_factor': 2, 'supersampling_convolution': True } imageModel = ImageLinearFit( self.data_class, self.psf_class, self.lens_model_class, source_model_class=self.source_model_class, lens_light_model_class=self.lens_light_model_class, kwargs_numerics=kwargs_numerics, kwargs_pixelbased=self.kwargs_pixelbased) with self.assertRaises(ValueError): # test various numerics that are not supported by the pixelbased solver kwargs_numerics = {'compute_mode': 'adaptive'} imageModel = ImageLinearFit( self.data_class, self.psf_class, self.lens_model_class, source_model_class=self.source_model_class, lens_light_model_class=self.lens_light_model_class, kwargs_numerics=kwargs_numerics, kwargs_pixelbased=self.kwargs_pixelbased) with self.assertRaises(ValueError): # test unsupported gaussian PSF type kwargs_psf = { 'psf_type': 'GAUSSIAN', 'fwhm': 0.5, 'truncation': 5, 'pixel_size': 0.05 } psf_class = PSF(**kwargs_psf) imageModel = ImageLinearFit( self.data_class, psf_class, self.lens_model_class, source_model_class=self.source_model_class, lens_light_model_class=self.lens_light_model_class, kwargs_numerics=self.kwargs_numerics, kwargs_pixelbased=self.kwargs_pixelbased) with self.assertRaises(ValueError): kwargs_numerics = {'supersampling_factor': 1} # test more than a single pixel-based light profile source_model_class = LightModel(['SLIT_STARLETS', 'SLIT_STARLETS']) imageModel = ImageLinearFit( self.data_class, self.psf_class, self.lens_model_class, source_model_class=source_model_class, lens_light_model_class=self.lens_light_model_class, kwargs_numerics=self.kwargs_numerics, kwargs_pixelbased=self.kwargs_pixelbased) with self.assertRaises(ValueError): # test access to unconvolved lens light surface brightness imageModel = ImageLinearFit( self.data_class, self.psf_class, self.lens_model_class, source_model_class=self.source_model_class, lens_light_model_class=self.lens_light_model_class, kwargs_numerics=self.kwargs_numerics, kwargs_pixelbased=self.kwargs_pixelbased) imageModel.lens_surface_brightness(self.kwargs_lens_light, unconvolved=True)
def setup(self): # data specifics sigma_bkg = .05 # background noise per pixel exp_time = 100 # 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 = sim_util.data_configure_simple(numPix, deltaPix, exp_time, sigma_bkg, inverse=True) data_class = ImageData(**kwargs_data) kwargs_psf = { 'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': deltaPix } psf_class = PSF(**kwargs_psf) kernel = psf_class.kernel_point_source kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel, 'psf_error_map': np.ones_like(kernel) * 0.001 } psf_class = PSF(**kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'gamma1': 0.01, 'gamma2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) phi, q = 0.2, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi, q) 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 phi, q = 0.2, 0.9 e1, e2 = param_util.phi_q2_ellipticity(phi, q) kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 } lens_light_model_list = ['SERSIC'] kwargs_lens_light_base = [kwargs_sersic] lens_light_model_class_base = LightModel( light_model_list=lens_light_model_list) source_model_list = ['SERSIC_ELLIPSE'] kwargs_source_base = [kwargs_sersic_ellipse] source_model_class_base = LightModel( light_model_list=source_model_list) self.kwargs_ps = [ { 'ra_source': 0.01, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness point_source_class_base = PointSource( point_source_type_list=['SOURCE_POSITION'], fixed_magnification_list=[True]) kwargs_numerics_base = { 'supersampling_factor': 2, 'supersampling_convolution': False } imageModel_base = ImageModel(data_class, psf_class, lens_model_class, source_model_class_base, lens_light_model_class_base, point_source_class_base, kwargs_numerics=kwargs_numerics_base) image_sim = sim_util.simulate_simple(imageModel_base, self.kwargs_lens, kwargs_source_base, kwargs_lens_light_base, self.kwargs_ps) data_class.update_data(image_sim) # create a starlet light distributions n_scales = 6 source_map = imageModel_base.source_surface_brightness( kwargs_source_base, de_lensed=True, unconvolved=True) starlets_class = SLIT_Starlets(force_no_pysap=_force_no_pysap) source_map_starlets = starlets_class.decomposition_2d( source_map, n_scales) self.kwargs_source = [{ 'amp': source_map_starlets, 'n_scales': n_scales, 'n_pixels': numPix, 'scale': deltaPix, 'center_x': 0, 'center_y': 0 }] source_model_class = LightModel(light_model_list=['SLIT_STARLETS']) lens_light_map = imageModel_base.lens_surface_brightness( kwargs_lens_light_base, unconvolved=True) starlets_class = SLIT_Starlets(force_no_pysap=_force_no_pysap, second_gen=True) lens_light_starlets = starlets_class.decomposition_2d( lens_light_map, n_scales) self.kwargs_lens_light = [{ 'amp': lens_light_starlets, 'n_scales': n_scales, 'n_pixels': numPix, 'scale': deltaPix, 'center_x': 0, 'center_y': 0 }] lens_light_model_class = LightModel( light_model_list=['SLIT_STARLETS_GEN2']) kwargs_numerics = {'supersampling_factor': 1} kwargs_pixelbased = { 'supersampling_factor_source': 2, # supersampling of pixelated source grid # following choices are to minimize pixel solver runtime (not to get accurate reconstruction!) 'threshold_decrease_type': 'none', 'num_iter_source': 2, 'num_iter_lens': 2, 'num_iter_global': 2, 'num_iter_weights': 2, } self.imageModel = ImageLinearFit( data_class, psf_class, lens_model_class, source_model_class=source_model_class, lens_light_model_class=lens_light_model_class, point_source_class=None, kwargs_numerics=kwargs_numerics, kwargs_pixelbased=kwargs_pixelbased) self.imageModel_source = ImageLinearFit( data_class, psf_class, lens_model_class, source_model_class=source_model_class, lens_light_model_class=None, point_source_class=None, kwargs_numerics=kwargs_numerics, kwargs_pixelbased=kwargs_pixelbased) self.solver = LensEquationSolver(lensModel=self.imageModel.LensModel)
class TestImageModel(object): """ tests the source model routines """ def setup(self): # data specifics sigma_bkg = .05 # background noise per pixel exp_time = 100 # 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 = sim_util.data_configure_simple(numPix, deltaPix, exp_time, sigma_bkg, inverse=True) data_class = ImageData(**kwargs_data) kwargs_psf = { 'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': deltaPix } psf_class = PSF(**kwargs_psf) kernel = psf_class.kernel_point_source kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel, 'psf_error_map': np.ones_like(kernel) * 0.001 } psf_class = PSF(**kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'gamma1': 0.01, 'gamma2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) phi, q = 0.2, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi, q) 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 phi, q = 0.2, 0.9 e1, e2 = param_util.phi_q2_ellipticity(phi, q) kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 } lens_light_model_list = ['SERSIC'] kwargs_lens_light_base = [kwargs_sersic] lens_light_model_class_base = LightModel( light_model_list=lens_light_model_list) source_model_list = ['SERSIC_ELLIPSE'] kwargs_source_base = [kwargs_sersic_ellipse] source_model_class_base = LightModel( light_model_list=source_model_list) self.kwargs_ps = [ { 'ra_source': 0.01, 'dec_source': 0.0, 'source_amp': 1. } ] # quasar point source position in the source plane and intrinsic brightness point_source_class_base = PointSource( point_source_type_list=['SOURCE_POSITION'], fixed_magnification_list=[True]) kwargs_numerics_base = { 'supersampling_factor': 2, 'supersampling_convolution': False } imageModel_base = ImageModel(data_class, psf_class, lens_model_class, source_model_class_base, lens_light_model_class_base, point_source_class_base, kwargs_numerics=kwargs_numerics_base) image_sim = sim_util.simulate_simple(imageModel_base, self.kwargs_lens, kwargs_source_base, kwargs_lens_light_base, self.kwargs_ps) data_class.update_data(image_sim) # create a starlet light distributions n_scales = 6 source_map = imageModel_base.source_surface_brightness( kwargs_source_base, de_lensed=True, unconvolved=True) starlets_class = SLIT_Starlets(force_no_pysap=_force_no_pysap) source_map_starlets = starlets_class.decomposition_2d( source_map, n_scales) self.kwargs_source = [{ 'amp': source_map_starlets, 'n_scales': n_scales, 'n_pixels': numPix, 'scale': deltaPix, 'center_x': 0, 'center_y': 0 }] source_model_class = LightModel(light_model_list=['SLIT_STARLETS']) lens_light_map = imageModel_base.lens_surface_brightness( kwargs_lens_light_base, unconvolved=True) starlets_class = SLIT_Starlets(force_no_pysap=_force_no_pysap, second_gen=True) lens_light_starlets = starlets_class.decomposition_2d( lens_light_map, n_scales) self.kwargs_lens_light = [{ 'amp': lens_light_starlets, 'n_scales': n_scales, 'n_pixels': numPix, 'scale': deltaPix, 'center_x': 0, 'center_y': 0 }] lens_light_model_class = LightModel( light_model_list=['SLIT_STARLETS_GEN2']) kwargs_numerics = {'supersampling_factor': 1} kwargs_pixelbased = { 'supersampling_factor_source': 2, # supersampling of pixelated source grid # following choices are to minimize pixel solver runtime (not to get accurate reconstruction!) 'threshold_decrease_type': 'none', 'num_iter_source': 2, 'num_iter_lens': 2, 'num_iter_global': 2, 'num_iter_weights': 2, } self.imageModel = ImageLinearFit( data_class, psf_class, lens_model_class, source_model_class=source_model_class, lens_light_model_class=lens_light_model_class, point_source_class=None, kwargs_numerics=kwargs_numerics, kwargs_pixelbased=kwargs_pixelbased) self.imageModel_source = ImageLinearFit( data_class, psf_class, lens_model_class, source_model_class=source_model_class, lens_light_model_class=None, point_source_class=None, kwargs_numerics=kwargs_numerics, kwargs_pixelbased=kwargs_pixelbased) self.solver = LensEquationSolver(lensModel=self.imageModel.LensModel) def test_source_surface_brightness(self): source_model = self.imageModel.source_surface_brightness( self.kwargs_source, self.kwargs_lens, unconvolved=False, de_lensed=True) assert len(source_model) == 100 source_model = self.imageModel.source_surface_brightness( self.kwargs_source, self.kwargs_lens, unconvolved=False, de_lensed=False) assert len(source_model) == 100 npt.assert_almost_equal(source_model[10, 10], 0.13939841209844345 * 0.05**2, decimal=4) source_model = self.imageModel.source_surface_brightness( self.kwargs_source, self.kwargs_lens, unconvolved=True, de_lensed=False) assert len(source_model) == 100 npt.assert_almost_equal(source_model[10, 10], 0.13536114618182182 * 0.05**2, decimal=4) def test_lens_surface_brightness(self): lens_flux = self.imageModel.lens_surface_brightness( self.kwargs_lens_light, unconvolved=False) npt.assert_almost_equal(lens_flux[50, 50], 0.011827638016863616, decimal=4) # the following should raise an error: no deconvolution is performed when pixel-based modelling lens light # lens_flux = self.imageModel.lens_surface_brightness(self.kwargs_lens_light, unconvolved=True) def test_image_linear_solve(self): model, error_map, cov_param, param = self.imageModel.image_linear_solve( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) chi2_reduced = self.imageModel.reduced_chi2(model, error_map) npt.assert_almost_equal(chi2_reduced, 1, decimal=1) model, error_map, cov_param, param = self.imageModel_source.image_linear_solve( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) chi2_reduced = self.imageModel.reduced_chi2(model, error_map) npt.assert_almost_equal(chi2_reduced, 1, decimal=1) def test_image_with_params(self): model = self.imageModel.image(self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, unconvolved=False, source_add=True, lens_light_add=True, point_source_add=True) error_map = self.imageModel._error_map_psf(self.kwargs_lens, self.kwargs_ps) chi2_reduced = self.imageModel.reduced_chi2(model, error_map) npt.assert_almost_equal(chi2_reduced, 1, decimal=1) def test_likelihood_data_given_model(self): logL = self.imageModel.likelihood_data_given_model( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, source_marg=False) npt.assert_almost_equal(logL, -5000, decimal=-3) def test_reduced_residuals(self): model = sim_util.simulate_simple(self.imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, no_noise=True) residuals = self.imageModel.reduced_residuals(model, error_map=0) npt.assert_almost_equal(np.std(residuals), 1.01, decimal=1) chi2 = self.imageModel.reduced_chi2(model, error_map=0) npt.assert_almost_equal(chi2, 1, decimal=1) def test_numData_evaluate(self): numData = self.imageModel.num_data_evaluate assert numData == 10000 def test_num_param_linear(self): num_param_linear = self.imageModel.num_param_linear( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) assert num_param_linear == 0 # pixels of pixel-based profiles not counted as linear param num_param_linear = self.imageModel_source.num_param_linear( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) assert num_param_linear == 0 # pixels of pixel-based profiles not counted as linear param def test_update_data(self): kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1, inverse=True) data_class = ImageData(**kwargs_data) self.imageModel.update_data(data_class) assert self.imageModel.Data.num_pixel == 100 def test_create_empty(self): kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) imageModel_empty = ImageModel(data_class, PSF()) assert imageModel_empty._psf_error_map == False flux = imageModel_empty.lens_surface_brightness(kwargs_lens_light=None) assert flux.all() == 0 def test_extinction_map(self): kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) extinction_class = DifferentialExtinction( optical_depth_model=['UNIFORM'], tau0_index=0) imageModel = ImageModel(data_class, PSF(), extinction_class=extinction_class) extinction = imageModel.extinction_map( kwargs_extinction=[{ 'amp': 1 }], kwargs_special={'tau0_list': [1, 0, 0]}) npt.assert_almost_equal(extinction, np.exp(-1)) def test_error_response(self): C_D_response, psf_model_error = self.imageModel._error_response( self.kwargs_lens, self.kwargs_ps, kwargs_special=None) assert len(psf_model_error) == 100 print(np.sum(psf_model_error)) npt.assert_almost_equal(np.sum(psf_model_error), 0, decimal=3) C_D_response, psf_model_error = self.imageModel_source._error_response( self.kwargs_lens, self.kwargs_ps, kwargs_special=None) assert len(psf_model_error) == 100 print(np.sum(psf_model_error)) npt.assert_almost_equal(np.sum(psf_model_error), 0, decimal=3)
def run(self, algorithm_list=['PSO', 'MCMC'], setting_list=[None, None]): """ Run the fitting. The algorithm_list and setting_list will be pass to 'fitting_kwargs()' """ self.fitting_kwargs(algorithm_list=algorithm_list, setting_list=setting_list) fitting_specify_class = self.fitting_specify_class start_time = time.time() chain_list = self.fitting_seq.fit_sequence(self.fitting_kwargs_list) kwargs_result = self.fitting_seq.best_fit() ps_result = kwargs_result['kwargs_ps'] source_result = kwargs_result['kwargs_lens_light'] if self.fitting_kwargs_list[-1][0] == 'MCMC': self.sampler_type, self.samples_mcmc, self.param_mcmc, self.dist_mcmc = chain_list[ -1] end_time = time.time() print(round(end_time - start_time, 3), 'total time taken for the overall fitting (s)') print( '============ CONGRATULATION, YOUR JOB WAS SUCCESSFUL ================ ' ) from lenstronomy.ImSim.image_linear_solve import ImageLinearFit imageLinearFit = ImageLinearFit( data_class=fitting_specify_class.data_class, psf_class=fitting_specify_class.psf_class, source_model_class=fitting_specify_class.lightModel, point_source_class=fitting_specify_class.pointSource, kwargs_numerics=fitting_specify_class.kwargs_numerics) image_reconstructed, error_map, _, _ = imageLinearFit.image_linear_solve( kwargs_source=source_result, kwargs_ps=ps_result) imageModel = fitting_specify_class.imageModel image_host_list = [ ] #The linear_solver before and after LensModelPlot could have different result for very faint sources. for i in range(len(source_result)): image_host_list.append( imageModel.source_surface_brightness(source_result, de_lensed=True, unconvolved=False, k=i)) image_ps_list = [] for i in range(len(ps_result)): image_ps_list.append(imageModel.point_source(ps_result, k=i)) if self.fitting_kwargs_list[-1][0] == 'MCMC': from lenstronomy.Sampling.parameters import Param try: kwargs_fixed_source = fitting_specify_class.kwargs_params[ 'lens_light_model'][2] except: kwargs_fixed_source = None try: kwargs_fixed_ps = fitting_specify_class.kwargs_params[ 'point_source_model'][2] except: kwargs_fixed_ps = None param = Param(fitting_specify_class.kwargs_model, kwargs_fixed_lens_light=kwargs_fixed_source, kwargs_fixed_ps=kwargs_fixed_ps, **fitting_specify_class.kwargs_constraints) mcmc_flux_list = [] if len(fitting_specify_class.point_source_list) > 0: qso_labels_new = [ "Quasar_{0} flux".format(i) for i in range( len(fitting_specify_class.point_source_list)) ] galaxy_labels_new = [ "Galaxy_{0} flux".format(i) for i in range(len(fitting_specify_class.light_model_list)) ] labels_flux = qso_labels_new + galaxy_labels_new else: labels_flux = [ "Galaxy_{0} flux".format(i) for i in range(len(fitting_specify_class.light_model_list)) ] if len(self.samples_mcmc ) > 10000: #Only save maximum 10000 chain results. trans_steps = [ len(self.samples_mcmc) - 10000, len(self.samples_mcmc) ] else: trans_steps = [0, len(self.samples_mcmc)] print("Start transfering the Params to fluxs...") for i in range(trans_steps[0], trans_steps[1]): kwargs_out = param.args2kwargs(self.samples_mcmc[i]) kwargs_light_source_out = kwargs_out['kwargs_lens_light'] kwargs_ps_out = kwargs_out['kwargs_ps'] image_reconstructed, _, _, _ = imageLinearFit.image_linear_solve( kwargs_source=kwargs_light_source_out, kwargs_ps=kwargs_ps_out) flux_list_quasar = [] if len(fitting_specify_class.point_source_list) > 0: for j in range(len( fitting_specify_class.point_source_list)): image_ps_j = fitting_specify_class.imageModel.point_source( kwargs_ps_out, k=j) flux_list_quasar.append(np.sum(image_ps_j)) flux_list_galaxy = [] for j in range(len(fitting_specify_class.light_model_list)): image_j = fitting_specify_class.imageModel.source_surface_brightness( kwargs_light_source_out, unconvolved=False, k=j) flux_list_galaxy.append(np.sum(image_j)) mcmc_flux_list.append(flux_list_quasar + flux_list_galaxy) if int(i / 1000) > int((i - 1) / 1000): print(trans_steps[1] - trans_steps[0], "MCMC samplers in total, finished translate:", i - trans_steps[0]) self.mcmc_flux_list = np.array(mcmc_flux_list) self.labels_flux = labels_flux self.chain_list = chain_list self.kwargs_result = kwargs_result self.ps_result = ps_result self.source_result = source_result self.imageLinearFit = imageLinearFit self.reduced_Chisq = imageLinearFit.reduced_chi2( image_reconstructed, error_map) self.image_host_list = image_host_list self.image_ps_list = image_ps_list self.translate_result()
class TestImageModel(object): """ tests the source model routines """ def setup(self): # data specifics sigma_bkg = .05 # background noise per pixel exp_time = 100 # 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 = sim_util.data_configure_simple(numPix, deltaPix, exp_time, sigma_bkg, inverse=True) data_class = ImageData(**kwargs_data) kwargs_psf = { 'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': deltaPix } psf_class = PSF(**kwargs_psf) kernel = psf_class.kernel_point_source kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel, 'psf_error_map': np.ones_like(kernel) * 0.001 } psf_class = PSF(**kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'gamma1': 0.01, 'gamma2': 0.01 } # gamma_ext: shear strength, psi_ext: shear angel (in radian) phi, q = 0.2, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi, q) 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 phi, q = 0.2, 0.9 e1, e2 = param_util.phi_q2_ellipticity(phi, q) kwargs_sersic_ellipse = { 'amp': 1., 'R_sersic': .6, 'n_sersic': 7, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 } 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.01, '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 = { 'supersampling_factor': 2, 'supersampling_convolution': False, 'compute_mode': 'gaussian' } imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) image_sim = sim_util.simulate_simple(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) data_class.update_data(image_sim) self.imageModel = ImageLinearFit(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) self.solver = LensEquationSolver(lensModel=self.imageModel.LensModel) def test_source_surface_brightness(self): source_model = self.imageModel.source_surface_brightness( self.kwargs_source, self.kwargs_lens, unconvolved=False, de_lensed=True) assert len(source_model) == 100 source_model = self.imageModel.source_surface_brightness( self.kwargs_source, self.kwargs_lens, unconvolved=False, de_lensed=False) assert len(source_model) == 100 npt.assert_almost_equal(source_model[10, 10], 0.13939841209844345 * 0.05**2, decimal=4) source_model = self.imageModel.source_surface_brightness( self.kwargs_source, self.kwargs_lens, unconvolved=True, de_lensed=False) assert len(source_model) == 100 npt.assert_almost_equal(source_model[10, 10], 0.13536114618182182 * 0.05**2, decimal=4) def test_lens_surface_brightness(self): lens_flux = self.imageModel.lens_surface_brightness( self.kwargs_lens_light, unconvolved=False) print(np.sum(lens_flux), 'test lens flux') npt.assert_almost_equal(lens_flux[50, 50], 0.0010788981265391802, decimal=4) #npt.assert_almost_equal(lens_flux[50, 50], 0.54214440654021534 * 0.05 ** 2, decimal=4) lens_flux = self.imageModel.lens_surface_brightness( self.kwargs_lens_light, unconvolved=True) npt.assert_almost_equal(lens_flux[50, 50], 4.7310552067454452 * 0.05**2, decimal=4) def test_image_linear_solve(self): model, error_map, cov_param, param = self.imageModel.image_linear_solve( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, inv_bool=False) chi2_reduced = self.imageModel.reduced_chi2(model, error_map) npt.assert_almost_equal(chi2_reduced, 1, decimal=1) def test_image_with_params(self): model = self.imageModel.image(self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, unconvolved=False, source_add=True, lens_light_add=True, point_source_add=True) error_map = self.imageModel._error_map_psf(self.kwargs_lens, self.kwargs_ps) chi2_reduced = self.imageModel.reduced_chi2(model, error_map) npt.assert_almost_equal(chi2_reduced, 1, decimal=1) def test_likelihood_data_given_model(self): logL = self.imageModel.likelihood_data_given_model( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, source_marg=False) npt.assert_almost_equal(logL, -5000, decimal=-3) logLmarg = self.imageModel.likelihood_data_given_model( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, source_marg=True) npt.assert_almost_equal(logL - logLmarg, 0, decimal=-3) assert logLmarg < logL def test_reduced_residuals(self): model = sim_util.simulate_simple(self.imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps, no_noise=True) residuals = self.imageModel.reduced_residuals(model, error_map=0) npt.assert_almost_equal(np.std(residuals), 1.01, decimal=1) chi2 = self.imageModel.reduced_chi2(model, error_map=0) npt.assert_almost_equal(chi2, 1, decimal=1) def test_numData_evaluate(self): numData = self.imageModel.num_data_evaluate assert numData == 10000 def test_num_param_linear(self): num_param_linear = self.imageModel.num_param_linear( self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) assert num_param_linear == 3 def test_update_data(self): kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1, inverse=True) data_class = ImageData(**kwargs_data) self.imageModel.update_data(data_class) assert self.imageModel.Data.num_pixel == 100 def test_point_source_rendering(self): # initialize data numPix = 100 deltaPix = 0.05 kwargs_data = sim_util.data_configure_simple(numPix, deltaPix, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) kernel = np.zeros((5, 5)) kernel[2, 2] = 1 kwargs_psf = { 'kernel_point_source': kernel, 'psf_type': 'PIXEL', 'psf_error_map': np.ones_like(kernel) * 0.001 } psf_class = PSF(**kwargs_psf) lens_model_class = LensModel(['SPEP']) source_model_class = LightModel([]) lens_light_model_class = LightModel([]) kwargs_numerics = { 'supersampling_factor': 2, 'supersampling_convolution': True, 'point_source_supersampling_factor': 1 } point_source_class = PointSource( point_source_type_list=['LENSED_POSITION'], fixed_magnification_list=[False]) makeImage = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) # chose point source positions x_pix = np.array([10, 5, 10, 90]) y_pix = np.array([40, 50, 60, 50]) ra_pos, dec_pos = makeImage.Data.map_pix2coord(x_pix, y_pix) e1, e2 = param_util.phi_q2_ellipticity(0, 0.8) kwargs_lens_init = [{ 'theta_E': 1, 'gamma': 2, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0 }] kwargs_else = [{ 'ra_image': ra_pos, 'dec_image': dec_pos, 'point_amp': np.ones_like(ra_pos) }] image = makeImage.image(kwargs_lens_init, kwargs_source={}, kwargs_lens_light={}, kwargs_ps=kwargs_else) #print(np.shape(model), 'test') #image = makeImage.ImageNumerics.array2image(model) for i in range(len(x_pix)): npt.assert_almost_equal(image[y_pix[i], x_pix[i]], 1, decimal=2) x_pix = np.array([10.5, 5.5, 10.5, 90.5]) y_pix = np.array([40, 50, 60, 50]) ra_pos, dec_pos = makeImage.Data.map_pix2coord(x_pix, y_pix) phi, q = 0., 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi, q) kwargs_lens_init = [{ 'theta_E': 1, 'gamma': 2, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0 }] kwargs_else = [{ 'ra_image': ra_pos, 'dec_image': dec_pos, 'point_amp': np.ones_like(ra_pos) }] image = makeImage.image(kwargs_lens_init, kwargs_source={}, kwargs_lens_light={}, kwargs_ps=kwargs_else) #image = makeImage.ImageNumerics.array2image(model) for i in range(len(x_pix)): print(int(y_pix[i]), int(x_pix[i] + 0.5)) npt.assert_almost_equal(image[int(y_pix[i]), int(x_pix[i])], 0.5, decimal=1) npt.assert_almost_equal(image[int(y_pix[i]), int(x_pix[i] + 0.5)], 0.5, decimal=1) def test_point_source(self): pointSource = PointSource(point_source_type_list=['SOURCE_POSITION'], fixed_magnification_list=[True]) kwargs_ps = [{'source_amp': 1000, 'ra_source': 0.1, 'dec_source': 0.1}] lensModel = LensModel(lens_model_list=['SIS']) kwargs_lens = [{'theta_E': 1, 'center_x': 0, 'center_y': 0}] numPix = 64 deltaPix = 0.13 kwargs_data = sim_util.data_configure_simple(numPix, deltaPix, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) psf_type = "GAUSSIAN" fwhm = 0.9 kwargs_psf = {'psf_type': psf_type, 'fwhm': fwhm} psf_class = PSF(**kwargs_psf) imageModel = ImageModel(data_class=data_class, psf_class=psf_class, lens_model_class=lensModel, point_source_class=pointSource) image = imageModel.image(kwargs_lens=kwargs_lens, kwargs_ps=kwargs_ps) assert np.sum(image) > 0 def test_error_map_source(self): sourceModel = LightModel(light_model_list=['UNIFORM', 'UNIFORM']) kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) psf_type = "GAUSSIAN" fwhm = 0.9 kwargs_psf = {'psf_type': psf_type, 'fwhm': fwhm} psf_class = PSF(**kwargs_psf) imageModel = ImageLinearFit(data_class=data_class, psf_class=psf_class, lens_model_class=None, point_source_class=None, source_model_class=sourceModel) x_grid, y_grid = util.make_grid(numPix=10, deltapix=1) error_map = imageModel.error_map_source(kwargs_source=[{ 'amp': 1 }, { 'amp': 1 }], x_grid=x_grid, y_grid=y_grid, cov_param=np.array([[1, 0], [0, 1]])) assert error_map[0] == 2 def test_create_empty(self): kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) imageModel_empty = ImageModel(data_class, PSF()) assert imageModel_empty._psf_error_map == False flux = imageModel_empty.lens_surface_brightness(kwargs_lens_light=None) assert flux.all() == 0 def test_extinction_map(self): kwargs_data = sim_util.data_configure_simple(numPix=10, deltaPix=1, exposure_time=1, background_rms=1) data_class = ImageData(**kwargs_data) extinction_class = DifferentialExtinction( optical_depth_model=['UNIFORM'], tau0_index=0) imageModel = ImageModel(data_class, PSF(), extinction_class=extinction_class) extinction = imageModel.extinction_map( kwargs_extinction=[{ 'amp': 1 }], kwargs_special={'tau0_list': [1, 0, 0]}) npt.assert_almost_equal(extinction, np.exp(-1)) def test_error_response(self): C_D_response, model_error = self.imageModel._error_response( self.kwargs_lens, self.kwargs_ps, kwargs_special=None) assert len(model_error) == 100 print(np.sum(model_error)) npt.assert_almost_equal(np.sum(model_error), 0.0019271126921470687, decimal=3) def test_point_source_linear_response_set(self): kwargs_special = { 'delta_x_image': [0.1, 0.1], 'delta_y_image': [-0.1, -0.1] } ra_pos, dec_pos, amp, num_point = self.imageModel.point_source_linear_response_set( self.kwargs_ps, self.kwargs_lens, kwargs_special, with_amp=True) ra, dec = self.imageModel.PointSource.image_position( self.kwargs_ps, self.kwargs_lens) npt.assert_almost_equal(ra[0][0], ra_pos[0][0] - 0.1, decimal=5) def test_displace_astrometry(self): kwargs_special = { 'delta_x_image': np.array([0.1, 0.1]), 'delta_y_image': np.array([-0.1, -0.1]) } x_pos, y_pos = np.array([0, 0]), np.array([0, 0]) x_shift, y_shift = self.imageModel._displace_astrometry( x_pos, y_pos, kwargs_special=kwargs_special) assert x_pos[0] == 0 assert x_shift[0] == kwargs_special['delta_x_image'][0] assert y_pos[0] == 0 assert y_shift[0] == kwargs_special['delta_y_image'][0]
class SingleBandMultiModel(ImageLinearFit): """ class to simulate/reconstruct images in multi-band option. This class calls functions of image_model.py with different bands with decoupled linear parameters and the option to pass/select different light models for the different bands the class instance needs to have a forth row in the multi_band_list with keyword arguments 'source_light_model_index' and 'lens_light_model_index' as bool arrays of the size of the total source model types and lens light model types, specifying which model is evaluated for which band. """ def __init__(self, multi_band_list, kwargs_model, likelihood_mask_list=None, band_index=0): self.type = 'single-band-multi-model' if likelihood_mask_list is None: likelihood_mask_list = [None for i in range(len(multi_band_list))] lens_model_class, source_model_class, lens_light_model_class, point_source_class = class_creator.create_class_instances(band_index=band_index, **kwargs_model) kwargs_data = multi_band_list[band_index][0] kwargs_psf = multi_band_list[band_index][1] kwargs_numerics = multi_band_list[band_index][2] data_i = ImageData(**kwargs_data) psf_i = PSF(kwargs_psf=kwargs_psf) index_lens_model_list = kwargs_model.get('index_lens_model_list', [None for i in range(len(multi_band_list))]) self._index_lens_model = index_lens_model_list[band_index] index_source_list = kwargs_model.get('index_source_light_model_list', [None for i in range(len(multi_band_list))]) self._index_source = index_source_list[band_index] index_lens_light_list = kwargs_model.get('index_lens_light_model_list', [None for i in range(len(multi_band_list))]) self._index_lens_light = index_lens_light_list[band_index] index_point_source_list = kwargs_model.get('index_point_source_model_list', [None for i in range(len(multi_band_list))]) self._index_point_source = index_point_source_list[band_index] super(SingleBandMultiModel, self).__init__(data_i, psf_i, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics, likelihood_mask=likelihood_mask_list[band_index]) self._imageModel = ImageLinearFit(data_i, psf_i, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics, likelihood_mask=likelihood_mask_list[band_index]) def image_linear_solve(self, kwargs_lens=None, kwargs_source=None, kwargs_lens_light=None, kwargs_ps=None, inv_bool=False): """ computes the image (lens and source surface brightness with a given lens model). The linear parameters are computed with a weighted linear least square optimization (i.e. flux normalization of the brightness profiles) :param kwargs_lens: list of keyword arguments corresponding to the superposition of different lens profiles :param kwargs_source: list of keyword arguments corresponding to the superposition of different source light profiles :param kwargs_lens_light: list of keyword arguments corresponding to different lens light surface brightness profiles :param kwargs_ps: keyword arguments corresponding to "other" parameters, such as external shear and point source image positions :param inv_bool: if True, invert the full linear solver Matrix Ax = y for the purpose of the covariance matrix. :return: 1d array of surface brightness pixels of the optimal solution of the linear parameters to match the data """ kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i = self._select_kwargs(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps) wls_model, error_map, cov_param, param = self._imageModel.image_linear_solve(kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i, inv_bool=inv_bool) return wls_model, error_map, cov_param, param def likelihood_data_given_model(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, source_marg=False): """ computes the likelihood of the data given a model This is specified with the non-linear parameters and a linear inversion and prior marginalisation. :param kwargs_lens: :param kwargs_source: :param kwargs_lens_light: :param kwargs_ps: :return: log likelihood (natural logarithm) (sum of the log likelihoods of the individual images) """ # generate image kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i = self._select_kwargs(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps) logL = self._imageModel.likelihood_data_given_model(kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i, source_marg=source_marg) return logL def num_param_linear(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps): """ :param compute_bool: :return: number of linear coefficients to be solved for in the linear inversion """ kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i = self._select_kwargs(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps) num = self._imageModel.num_param_linear(kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i) return num def linear_response_matrix(self, kwargs_lens=None, kwargs_source=None, kwargs_lens_light=None, kwargs_ps=None): """ computes the linear response matrix (m x n), with n beeing the data size and m being the coefficients :param kwargs_lens: :param kwargs_source: :param kwargs_lens_light: :param kwargs_ps: :return: """ kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i = self._select_kwargs(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps) A = self._imageModel.linear_response_matrix(kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i) return A def _select_kwargs(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps): """ select subset of kwargs lists referenced to this imaging band :param kwargs_lens: :param kwargs_source: :param kwargs_lens_light: :param kwargs_ps: :return: """ if self._index_lens_model is None: kwargs_lens_i = kwargs_lens else: kwargs_lens_i = [kwargs_lens[k] for k in self._index_lens_model] if self._index_source is None: kwargs_source_i = kwargs_source else: kwargs_source_i = [kwargs_source[k] for k in self._index_source] if self._index_lens_light is None: kwargs_lens_light_i = kwargs_lens_light else: kwargs_lens_light_i = [kwargs_lens_light[k] for k in self._index_lens_light] if self._index_point_source is None: kwargs_ps_i = kwargs_ps else: kwargs_ps_i = [kwargs_ps[k] for k in self._index_point_source] return kwargs_lens_i, kwargs_source_i, kwargs_lens_light_i, kwargs_ps_i
def fit_qso_multiband(QSO_im_list, psf_ave_list, psf_std_list=None, source_params=None,ps_param=None, background_rms_list=[0.04]*5, pix_sz = 0.168, exp_time = 300., fix_n=None, image_plot = True, corner_plot=True, flux_ratio_plot=True, deep_seed = False, fixcenter = False, QSO_msk_list=None, QSO_std_list=None, tag = None, no_MCMC= False, pltshow = 1, new_band_seq=None): ''' A quick fit for the QSO image with (so far) single sersice + one PSF. The input psf noise is optional. Parameter -------- QSO_im: An array of the QSO image. psf_ave: The psf image. psf_std: The psf noise, optional. source_params: The prior for the source. Default is given. background_rms: default as 0.04 exp_time: default at 2400. deep_seed: if Ture, more mcmc steps will be performed. tag: The name tag for save the plot Return -------- Will output the fitted image (Set image_plot = True), the corner_plot and the flux_ratio_plot. source_result, ps_result, image_ps, image_host To do -------- ''' # data specifics need to set up based on the data situation background_rms_list = background_rms_list # background noise per pixel (Gaussian) exp_time = exp_time # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = len(QSO_im_list[0]) # cutout pixel size deltaPix = pix_sz psf_type = 'PIXEL' # 'gaussian', 'pixel', 'NONE' kernel_list = psf_ave_list if new_band_seq == None: new_band_seq= range(len(QSO_im_list)) # if psf_std_list is not None: # kwargs_numerics_list = [{'subgrid_res': 1, 'psf_subgrid': False, 'psf_error_map': True}] * len(QSO_im_list) #Turn on the PSF error map # else: kwargs_numerics_list = [{'supersampling_factor': 1, 'supersampling_convolution': False}] * len(QSO_im_list) if source_params is None: # here are the options for the host galaxy fitting fixed_source = [] kwargs_source_init = [] kwargs_source_sigma = [] kwargs_lower_source = [] kwargs_upper_source = [] # Disk component, as modelled by an elliptical Sersic profile if fix_n == None: fixed_source.append({}) # we fix the Sersic index to n=1 (exponential) kwargs_source_init.append({'R_sersic': 0.3, 'n_sersic': 2., 'e1': 0., 'e2': 0., 'center_x': 0., 'center_y': 0.}) kwargs_source_sigma.append({'n_sersic': 0.5, 'R_sersic': 0.5, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.1, 'center_y': 0.1}) kwargs_lower_source.append({'e1': -0.5, 'e2': -0.5, 'R_sersic': 0.1, 'n_sersic': 0.3, 'center_x': -10, 'center_y': -10}) kwargs_upper_source.append({'e1': 0.5, 'e2': 0.5, 'R_sersic': 3., 'n_sersic': 7., 'center_x': 10, 'center_y': 10}) elif fix_n is not None: fixed_source.append({'n_sersic': fix_n}) kwargs_source_init.append({'R_sersic': 0.3, 'n_sersic': fix_n, 'e1': 0., 'e2': 0., 'center_x': 0., 'center_y': 0.}) kwargs_source_sigma.append({'n_sersic': 0.001, 'R_sersic': 0.5, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.1, 'center_y': 0.1}) kwargs_lower_source.append({'e1': -0.5, 'e2': -0.5, 'R_sersic': 0.1, 'n_sersic': fix_n, 'center_x': -10, 'center_y': -10}) kwargs_upper_source.append({'e1': 0.5, 'e2': 0.5, 'R_sersic': 3, 'n_sersic': fix_n, 'center_x': 10, 'center_y': 10}) source_params = [kwargs_source_init, kwargs_source_sigma, fixed_source, kwargs_lower_source, kwargs_upper_source] else: source_params = source_params if ps_param is None: center_x = 0.0 center_y = 0.0 point_amp = QSO_im_list[0].sum()/2. fixed_ps = [{}] kwargs_ps = [{'ra_image': [center_x], 'dec_image': [center_y], 'point_amp': [point_amp]}] kwargs_ps_init = kwargs_ps kwargs_ps_sigma = [{'ra_image': [0.01], 'dec_image': [0.01]}] kwargs_lower_ps = [{'ra_image': [-10], 'dec_image': [-10]}] kwargs_upper_ps = [{'ra_image': [10], 'dec_image': [10]}] ps_param = [kwargs_ps_init, kwargs_ps_sigma, fixed_ps, kwargs_lower_ps, kwargs_upper_ps] else: ps_param = ps_param kwargs_params = {'source_model': source_params, 'point_source_model': ps_param} #============================================================================== #Doing the QSO fitting #============================================================================== kwargs_data_list, data_class_list = [], [] for i in range(len(QSO_im_list)): kwargs_data_i = sim_util.data_configure_simple(numPix, deltaPix, exp_time, background_rms_list[i], inverse=True) kwargs_data_list.append(kwargs_data_i) data_class_list.append(ImageData(**kwargs_data_i)) kwargs_psf_list = [] psf_class_list = [] for i in range(len(QSO_im_list)): kwargs_psf_i = {'psf_type': psf_type, 'kernel_point_source': kernel_list[i]} kwargs_psf_list.append(kwargs_psf_i) psf_class_list.append(PSF(**kwargs_psf_i)) data_class_list[i].update_data(QSO_im_list[i]) light_model_list = ['SERSIC_ELLIPSE'] * len(source_params[0]) lightModel = LightModel(light_model_list=light_model_list) point_source_list = ['UNLENSED'] pointSource = PointSource(point_source_type_list=point_source_list) imageModel_list = [] for i in range(len(QSO_im_list)): kwargs_data_list[i]['image_data'] = QSO_im_list[i] # if QSO_msk_list is not None: # kwargs_numerics_list[i]['mask'] = QSO_msk_list[i] if QSO_std_list is not None: kwargs_data_list[i]['noise_map'] = QSO_std_list[i] # if psf_std_list is not None: # kwargs_psf_list[i]['psf_error_map'] = psf_std_list[i] image_band_list = [] for i in range(len(QSO_im_list)): imageModel_list.append(ImageModel(data_class_list[i], psf_class_list[i], source_model_class=lightModel, point_source_class=pointSource, kwargs_numerics=kwargs_numerics_list[i])) image_band_list.append([kwargs_data_list[i], kwargs_psf_list[i], kwargs_numerics_list[i]]) multi_band_list = [image_band_list[i] for i in range(len(QSO_im_list))] # numerical options and fitting sequences kwargs_model = { 'source_light_model_list': light_model_list, 'point_source_model_list': point_source_list } if fixcenter == False: kwargs_constraints = {'num_point_source_list': [1] } elif fixcenter == True: kwargs_constraints = {'joint_source_with_point_source': [[0, 0]], 'num_point_source_list': [1] } kwargs_likelihood = {'check_bounds': True, #Set the bonds, if exceed, reutrn "penalty" 'source_marg': False, #In likelihood_module.LikelihoodModule -- whether to fully invert the covariance matrix for marginalization 'check_positive_flux': True, 'image_likelihood_mask_list': [QSO_msk_list] } # mpi = False # MPI possible, but not supported through that notebook. # The Params for the fitting. kwargs_init: initial input. kwargs_sigma: The parameter uncertainty. kwargs_fixed: fixed parameters; #kwargs_lower,kwargs_upper: Lower and upper limits. kwargs_data_joint = {'multi_band_list': multi_band_list, 'multi_band_type': 'multi-linear'} # 'single-band', 'multi-linear', 'joint-linear' fitting_seq = FittingSequence(kwargs_data_joint, kwargs_model, kwargs_constraints, kwargs_likelihood, kwargs_params) if deep_seed == False: fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 80, 'n_iterations': 60, 'compute_bands': [True]+[False]*(len(QSO_im_list)-1)}], ['align_images', {'n_particles': 10, 'n_iterations': 10, 'compute_bands': [False]+[True]*(len(QSO_im_list)-1)}], ['PSO', {'sigma_scale': 0.8, 'n_particles': 100, 'n_iterations': 200, 'compute_bands': [True]*len(QSO_im_list)}], ['MCMC', {'n_burn': 10, 'n_run': 20, 'walkerRatio': 50, 'sigma_scale': .1}] ] elif deep_seed == True: fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 150, 'n_iterations': 60, 'compute_bands': [True]+[False]*(len(QSO_im_list)-1)}], ['align_images', {'n_particles': 20, 'n_iterations': 20, 'compute_bands': [False]+[True]*(len(QSO_im_list)-1)}], ['PSO', {'sigma_scale': 0.8, 'n_particles': 150, 'n_iterations': 200, 'compute_bands': [True]*len(QSO_im_list)}], ['MCMC', {'n_burn': 20, 'n_run': 40, 'walkerRatio': 50, 'sigma_scale': .1}] ] if no_MCMC == True: del fitting_kwargs_list[-1] start_time = time.time() # lens_result, source_result, lens_light_result, ps_result, cosmo_temp, chain_list, param_list, samples_mcmc, param_mcmc, dist_mcmc = fitting_seq.fit_sequence(fitting_kwargs_list) chain_list, param_list, samples_mcmc, param_mcmc, dist_mcmc = fitting_seq.fit_sequence(fitting_kwargs_list) lens_result, source_result, lens_light_result, ps_result, cosmo_temp = fitting_seq.best_fit() end_time = time.time() print(end_time - start_time, 'total time needed for computation') print('============ CONGRATULATION, YOUR JOB WAS SUCCESSFUL ================ ') source_result_list, ps_result_list = [], [] image_reconstructed_list, error_map_list, image_ps_list, image_host_list, shift_RADEC_list=[], [], [], [],[] imageLinearFit_list = [] for k in range(len(QSO_im_list)): # this is the linear inversion. The kwargs will be updated afterwards imageLinearFit_k = ImageLinearFit(data_class_list[k], psf_class_list[k], source_model_class=lightModel, point_source_class=pointSource, kwargs_numerics=kwargs_numerics_list[k]) image_reconstructed_k, error_map_k, _, _ = imageLinearFit_k.image_linear_solve(kwargs_source=source_result, kwargs_ps=ps_result) imageLinearFit_list.append(imageLinearFit_k) [kwargs_data_k, kwargs_psf_k, kwargs_numerics_k] = fitting_seq.multi_band_list[k] # data_class_k = data_class_list[k] #ImageData(**kwargs_data_k) # psf_class_k = psf_class_list[k] #PSF(**kwargs_psf_k) # imageModel_k = ImageModel(data_class_k, psf_class_k, source_model_class=lightModel, # point_source_class=pointSource, kwargs_numerics=kwargs_numerics_list[k]) imageModel_k = imageModel_list[k] modelPlot = ModelPlot(multi_band_list[k], kwargs_model, lens_result, source_result, lens_light_result, ps_result, arrow_size=0.02, cmap_string="gist_heat", likelihood_mask=QSO_im_list[k]) print("source_result", 'for', "k", source_result) image_host_k = [] for i in range(len(source_result)): image_host_k.append(imageModel_list[k].source_surface_brightness(source_result,de_lensed=True,unconvolved=False, k=i)) image_ps_k = imageModel_k.point_source(ps_result) # let's plot the output of the PSO minimizer image_reconstructed_list.append(image_reconstructed_k) source_result_list.append(source_result) ps_result_list.append(ps_result) error_map_list.append(error_map_k) image_ps_list.append(image_ps_k) image_host_list.append(image_host_k) if 'ra_shift' in fitting_seq.multi_band_list[k][0].keys(): shift_RADEC_list.append([fitting_seq.multi_band_list[k][0]['ra_shift'], fitting_seq.multi_band_list[k][0]['dec_shift']]) else: shift_RADEC_list.append([0,0]) if image_plot: f, axes = plt.subplots(3, 3, figsize=(16, 16), sharex=False, sharey=False) modelPlot.data_plot(ax=axes[0,0], text="Data") modelPlot.model_plot(ax=axes[0,1]) modelPlot.normalized_residual_plot(ax=axes[0,2], v_min=-6, v_max=6) modelPlot.decomposition_plot(ax=axes[1,0], text='Host galaxy', source_add=True, unconvolved=True) modelPlot.decomposition_plot(ax=axes[1,1], text='Host galaxy convolved', source_add=True) modelPlot.decomposition_plot(ax=axes[1,2], text='All components convolved', source_add=True, lens_light_add=True, point_source_add=True) modelPlot.subtract_from_data_plot(ax=axes[2,0], text='Data - Point Source', point_source_add=True) modelPlot.subtract_from_data_plot(ax=axes[2,1], text='Data - host galaxy', source_add=True) modelPlot.subtract_from_data_plot(ax=axes[2,2], text='Data - host galaxy - Point Source', source_add=True, point_source_add=True) f.tight_layout() if tag is not None: f.savefig('{0}_fitted_image_band{1}.pdf'.format(tag,new_band_seq[k])) if pltshow == 0: plt.close() else: plt.show() if corner_plot==True and no_MCMC==False and k ==0: # here the (non-converged) MCMC chain of the non-linear parameters if not samples_mcmc == []: n, num_param = np.shape(samples_mcmc) plot = corner.corner(samples_mcmc, labels=param_mcmc, show_titles=True) if tag is not None: plot.savefig('{0}_para_corner.pdf'.format(tag)) if pltshow == 0: plt.close() else: plt.show() if flux_ratio_plot==True and no_MCMC==False: param = Param(kwargs_model, kwargs_fixed_source=source_params[2], kwargs_fixed_ps=fixed_ps, **kwargs_constraints) mcmc_new_list = [] labels_new = [r"Quasar flux", r"host_flux", r"source_x", r"source_y"] # transform the parameter position of the MCMC chain in a lenstronomy convention with keyword arguments # for i in range(len(samples_mcmc)/10): kwargs_lens_out, kwargs_light_source_out, kwargs_light_lens_out, kwargs_ps_out, kwargs_cosmo = param.getParams(samples_mcmc[i+ len(samples_mcmc)/10*9]) image_reconstructed, _, _, _ = imageLinearFit_list[k].image_linear_solve(kwargs_source=kwargs_light_source_out, kwargs_ps=kwargs_ps_out) image_ps = imageModel_list[k].point_source(kwargs_ps_out) flux_quasar = np.sum(image_ps) image_disk = imageModel_list[k].source_surface_brightness(kwargs_light_source_out,de_lensed=True,unconvolved=False, k=0) flux_disk = np.sum(image_disk) source_x = kwargs_ps_out[0]['ra_image'] source_y = kwargs_ps_out[0]['dec_image'] if flux_disk>0: mcmc_new_list.append([flux_quasar, flux_disk, source_x, source_y]) plot = corner.corner(mcmc_new_list, labels=labels_new, show_titles=True) if tag is not None: plot.savefig('{0}_HOSTvsQSO_corner_band{1}.pdf'.format(tag,new_band_seq[k])) if pltshow == 0: plt.close() else: plt.show() errp_list = [] for k in range(len(QSO_im_list)): if QSO_std_list is None: errp_list.append(np.sqrt(data_class_list[k].C_D+np.abs(error_map_list[k]))) else: errp_list.append(np.sqrt(QSO_std_list[k]**2+np.abs(error_map_list[k]))) return source_result_list, ps_result_list, image_ps_list, image_host_list, errp_list, shift_RADEC_list, fitting_seq #fitting_seq.multi_band_list
def fit_qso(QSO_im, psf_ave, psf_std=None, source_params=None,ps_param=None, background_rms=0.04, pix_sz = 0.168, exp_time = 300., fix_n=None, image_plot = True, corner_plot=True, supersampling_factor = 2, flux_ratio_plot=False, deep_seed = False, fixcenter = False, QSO_msk=None, QSO_std=None, tag = None, no_MCMC= False, pltshow = 1, return_Chisq = False, dump_result = False, pso_diag=False): ''' A quick fit for the QSO image with (so far) single sersice + one PSF. The input psf noise is optional. Parameter -------- QSO_im: An array of the QSO image. psf_ave: The psf image. psf_std: The psf noise, optional. source_params: The prior for the source. Default is given. If [], means no Sersic light. background_rms: default as 0.04 exp_time: default at 2400. deep_seed: if Ture, more mcmc steps will be performed. tag: The name tag for save the plot Return -------- Will output the fitted image (Set image_plot = True), the corner_plot and the flux_ratio_plot. source_result, ps_result, image_ps, image_host To do -------- ''' # data specifics need to set up based on the data situation background_rms = background_rms # background noise per pixel (Gaussian) exp_time = exp_time # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = len(QSO_im) # cutout pixel size deltaPix = pix_sz psf_type = 'PIXEL' # 'gaussian', 'pixel', 'NONE' kernel = psf_ave kwargs_numerics = {'supersampling_factor': supersampling_factor, 'supersampling_convolution': False} if source_params is None: # here are the options for the host galaxy fitting fixed_source = [] kwargs_source_init = [] kwargs_source_sigma = [] kwargs_lower_source = [] kwargs_upper_source = [] if fix_n == None: fixed_source.append({}) # we fix the Sersic index to n=1 (exponential) kwargs_source_init.append({'R_sersic': 0.3, 'n_sersic': 2., 'e1': 0., 'e2': 0., 'center_x': 0., 'center_y': 0.}) kwargs_source_sigma.append({'n_sersic': 0.5, 'R_sersic': 0.5, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.1, 'center_y': 0.1}) kwargs_lower_source.append({'e1': -0.5, 'e2': -0.5, 'R_sersic': 0.1, 'n_sersic': 0.3, 'center_x': -10, 'center_y': -10}) kwargs_upper_source.append({'e1': 0.5, 'e2': 0.5, 'R_sersic': 3., 'n_sersic': 7., 'center_x': 10, 'center_y': 10}) elif fix_n is not None: fixed_source.append({'n_sersic': fix_n}) kwargs_source_init.append({'R_sersic': 0.3, 'n_sersic': fix_n, 'e1': 0., 'e2': 0., 'center_x': 0., 'center_y': 0.}) kwargs_source_sigma.append({'n_sersic': 0.001, 'R_sersic': 0.5, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.1, 'center_y': 0.1}) kwargs_lower_source.append({'e1': -0.5, 'e2': -0.5, 'R_sersic': 0.1, 'n_sersic': fix_n, 'center_x': -10, 'center_y': -10}) kwargs_upper_source.append({'e1': 0.5, 'e2': 0.5, 'R_sersic': 3, 'n_sersic': fix_n, 'center_x': 10, 'center_y': 10}) source_params = [kwargs_source_init, kwargs_source_sigma, fixed_source, kwargs_lower_source, kwargs_upper_source] else: source_params = source_params if ps_param is None: center_x = 0.0 center_y = 0.0 point_amp = QSO_im.sum()/2. fixed_ps = [{}] kwargs_ps = [{'ra_image': [center_x], 'dec_image': [center_y], 'point_amp': [point_amp]}] kwargs_ps_init = kwargs_ps kwargs_ps_sigma = [{'ra_image': [0.05], 'dec_image': [0.05]}] kwargs_lower_ps = [{'ra_image': [-0.6], 'dec_image': [-0.6]}] kwargs_upper_ps = [{'ra_image': [0.6], 'dec_image': [0.6]}] ps_param = [kwargs_ps_init, kwargs_ps_sigma, fixed_ps, kwargs_lower_ps, kwargs_upper_ps] else: ps_param = ps_param #============================================================================== #Doing the QSO fitting #============================================================================== kwargs_data = sim_util.data_configure_simple(numPix, deltaPix, exp_time, background_rms, inverse=True) data_class = ImageData(**kwargs_data) kwargs_psf = {'psf_type': psf_type, 'kernel_point_source': kernel} psf_class = PSF(**kwargs_psf) data_class.update_data(QSO_im) point_source_list = ['UNLENSED'] * len(ps_param[0]) pointSource = PointSource(point_source_type_list=point_source_list) if fixcenter == False: kwargs_constraints = {'num_point_source_list': [1] * len(ps_param[0]) } elif fixcenter == True: kwargs_constraints = {'joint_source_with_point_source': [[i, i] for i in range(len(ps_param[0]))], 'num_point_source_list': [1] * len(ps_param[0]) } if source_params == []: #fitting image as Point source only. kwargs_params = {'point_source_model': ps_param} lightModel = None kwargs_model = {'point_source_model_list': point_source_list } imageModel = ImageModel(data_class, psf_class, point_source_class=pointSource, kwargs_numerics=kwargs_numerics) kwargs_likelihood = {'check_bounds': True, #Set the bonds, if exceed, reutrn "penalty" 'image_likelihood_mask_list': [QSO_msk] } elif source_params != []: kwargs_params = {'source_model': source_params, 'point_source_model': ps_param} light_model_list = ['SERSIC_ELLIPSE'] * len(source_params[0]) lightModel = LightModel(light_model_list=light_model_list) kwargs_model = { 'source_light_model_list': light_model_list, 'point_source_model_list': point_source_list } imageModel = ImageModel(data_class, psf_class, source_model_class=lightModel, point_source_class=pointSource, kwargs_numerics=kwargs_numerics) # numerical options and fitting sequences kwargs_likelihood = {'check_bounds': True, #Set the bonds, if exceed, reutrn "penalty" 'source_marg': False, #In likelihood_module.LikelihoodModule -- whether to fully invert the covariance matrix for marginalization 'check_positive_flux': True, 'image_likelihood_mask_list': [QSO_msk] } kwargs_data['image_data'] = QSO_im if QSO_std is not None: kwargs_data['noise_map'] = QSO_std if psf_std is not None: kwargs_psf['psf_error_map'] = psf_std image_band = [kwargs_data, kwargs_psf, kwargs_numerics] multi_band_list = [image_band] kwargs_data_joint = {'multi_band_list': multi_band_list, 'multi_band_type': 'multi-linear'} # 'single-band', 'multi-linear', 'joint-linear' fitting_seq = FittingSequence(kwargs_data_joint, kwargs_model, kwargs_constraints, kwargs_likelihood, kwargs_params) if deep_seed == False: fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 100, 'n_iterations': 60}], ['MCMC', {'n_burn': 10, 'n_run': 10, 'walkerRatio': 50, 'sigma_scale': .1}] ] elif deep_seed == True: fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 250, 'n_iterations': 250}], ['MCMC', {'n_burn': 100, 'n_run': 200, 'walkerRatio': 10, 'sigma_scale': .1}] ] if no_MCMC == True: fitting_kwargs_list = [fitting_kwargs_list[0], ] start_time = time.time() chain_list = fitting_seq.fit_sequence(fitting_kwargs_list) kwargs_result = fitting_seq.best_fit() ps_result = kwargs_result['kwargs_ps'] source_result = kwargs_result['kwargs_source'] if no_MCMC == False: sampler_type, samples_mcmc, param_mcmc, dist_mcmc = chain_list[1] end_time = time.time() print(end_time - start_time, 'total time needed for computation') print('============ CONGRATULATION, YOUR JOB WAS SUCCESSFUL ================ ') imageLinearFit = ImageLinearFit(data_class=data_class, psf_class=psf_class, source_model_class=lightModel, point_source_class=pointSource, kwargs_numerics=kwargs_numerics) image_reconstructed, error_map, _, _ = imageLinearFit.image_linear_solve(kwargs_source=source_result, kwargs_ps=ps_result) # this is the linear inversion. The kwargs will be updated afterwards modelPlot = ModelPlot(multi_band_list, kwargs_model, kwargs_result, arrow_size=0.02, cmap_string="gist_heat", likelihood_mask_list=[QSO_msk]) image_host = [] #!!! The linear_solver before and after LensModelPlot could have different result for very faint sources. for i in range(len(source_result)): image_host.append(imageModel.source_surface_brightness(source_result, de_lensed=True,unconvolved=False,k=i)) image_ps = [] for i in range(len(ps_result)): image_ps.append(imageModel.point_source(ps_result, k = i)) if pso_diag == True: f, axes = chain_plot.plot_chain_list(chain_list,0) if pltshow == 0: plt.close() else: plt.show() # let's plot the output of the PSO minimizer reduced_Chisq = imageLinearFit.reduced_chi2(image_reconstructed, error_map) if image_plot: f, axes = plt.subplots(3, 3, figsize=(16, 16), sharex=False, sharey=False) modelPlot.data_plot(ax=axes[0,0], text="Data") modelPlot.model_plot(ax=axes[0,1]) modelPlot.normalized_residual_plot(ax=axes[0,2], v_min=-6, v_max=6) modelPlot.decomposition_plot(ax=axes[1,0], text='Host galaxy', source_add=True, unconvolved=True) modelPlot.decomposition_plot(ax=axes[1,1], text='Host galaxy convolved', source_add=True) modelPlot.decomposition_plot(ax=axes[1,2], text='All components convolved', source_add=True, lens_light_add=True, point_source_add=True) modelPlot.subtract_from_data_plot(ax=axes[2,0], text='Data - Point Source', point_source_add=True) modelPlot.subtract_from_data_plot(ax=axes[2,1], text='Data - host galaxy', source_add=True) modelPlot.subtract_from_data_plot(ax=axes[2,2], text='Data - host galaxy - Point Source', source_add=True, point_source_add=True) f.tight_layout() #f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05) if tag is not None: f.savefig('{0}_fitted_image.pdf'.format(tag)) if pltshow == 0: plt.close() else: plt.show() if corner_plot==True and no_MCMC==False: # here the (non-converged) MCMC chain of the non-linear parameters if not samples_mcmc == []: n, num_param = np.shape(samples_mcmc) plot = corner.corner(samples_mcmc, labels=param_mcmc, show_titles=True) if tag is not None: plot.savefig('{0}_para_corner.pdf'.format(tag)) plt.close() # if pltshow == 0: # plt.close() # else: # plt.show() if flux_ratio_plot==True and no_MCMC==False: param = Param(kwargs_model, kwargs_fixed_source=source_params[2], kwargs_fixed_ps=ps_param[2], **kwargs_constraints) mcmc_new_list = [] if len(ps_param[2]) == 1: labels_new = ["Quasar flux"] + ["host{0} flux".format(i) for i in range(len(source_params[0]))] else: labels_new = ["Quasar{0} flux".format(i) for i in range(len(ps_param[2]))] + ["host{0} flux".format(i) for i in range(len(source_params[0]))] if len(samples_mcmc) > 10000: trans_steps = [len(samples_mcmc)-10000, len(samples_mcmc)] else: trans_steps = [0, len(samples_mcmc)] for i in range(trans_steps[0], trans_steps[1]): kwargs_out = param.args2kwargs(samples_mcmc[i]) kwargs_light_source_out = kwargs_out['kwargs_source'] kwargs_ps_out = kwargs_out['kwargs_ps'] image_reconstructed, _, _, _ = imageLinearFit.image_linear_solve(kwargs_source=kwargs_light_source_out, kwargs_ps=kwargs_ps_out) flux_quasar = [] if len(ps_param[0]) == 1: image_ps_j = imageModel.point_source(kwargs_ps_out) flux_quasar.append(np.sum(image_ps_j)) else: for j in range(len(ps_param[0])): image_ps_j = imageModel.point_source(kwargs_ps_out, k=j) flux_quasar.append(np.sum(image_ps_j)) fluxs = [] for j in range(len(source_params[0])): image_j = imageModel.source_surface_brightness(kwargs_light_source_out,unconvolved= False, k=j) fluxs.append(np.sum(image_j)) mcmc_new_list.append(flux_quasar + fluxs ) if int(i/1000) > int((i-1)/1000) : print(len(samples_mcmc), "MCMC samplers in total, finished translate:", i ) plot = corner.corner(mcmc_new_list, labels=labels_new, show_titles=True) if tag is not None: plot.savefig('{0}_HOSTvsQSO_corner.pdf'.format(tag)) if pltshow == 0: plt.close() else: plt.show() if QSO_std is None: noise_map = np.sqrt(data_class.C_D+np.abs(error_map)) else: noise_map = np.sqrt(QSO_std**2+np.abs(error_map)) if dump_result == True: if flux_ratio_plot==True and no_MCMC==False: trans_paras = [mcmc_new_list, labels_new, 'mcmc_new_list, labels_new'] else: trans_paras = [] picklename= tag + '.pkl' best_fit = [source_result, image_host, ps_result, image_ps,'source_result, image_host, ps_result, image_ps'] chain_list_result = [chain_list, 'chain_list'] kwargs_fixed_source=source_params[2] kwargs_fixed_ps=ps_param[2] classes = data_class, psf_class, lightModel, pointSource material = multi_band_list, kwargs_model, kwargs_result, QSO_msk, kwargs_fixed_source, kwargs_fixed_ps, kwargs_constraints, kwargs_numerics, classes pickle.dump([best_fit, chain_list_result, trans_paras, material], open(picklename, 'wb')) if return_Chisq == False: return source_result, ps_result, image_ps, image_host, noise_map elif return_Chisq == True: return source_result, ps_result, image_ps, image_host, noise_map, reduced_Chisq
def fit_galaxy(galaxy_im, psf_ave, psf_std=None, source_params=None, background_rms=0.04, pix_sz = 0.08, exp_time = 300., fix_n=None, image_plot = True, corner_plot=True, deep_seed = False, galaxy_msk=None, galaxy_std=None, flux_corner_plot = False, tag = None, no_MCMC= False, pltshow = 1, return_Chisq = False, dump_result = False, pso_diag=False): ''' A quick fit for the QSO image with (so far) single sersice + one PSF. The input psf noise is optional. Parameter -------- galaxy_im: An array of the QSO image. psf_ave: The psf image. psf_std: The psf noise, optional. source_params: The prior for the source. Default is given. background_rms: default as 0.04 exp_time: default at 2400. deep_seed: if Ture, more mcmc steps will be performed. tag: The name tag for save the plot Return -------- Will output the fitted image (Set image_plot = True), the corner_plot and the flux_ratio_plot. source_result, ps_result, image_ps, image_host To do -------- ''' # data specifics need to set up based on the data situation background_rms = background_rms # background noise per pixel (Gaussian) exp_time = exp_time # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = len(galaxy_im) # cutout pixel size deltaPix = pix_sz if psf_ave is not None: psf_type = 'PIXEL' # 'gaussian', 'pixel', 'NONE' kernel = psf_ave # if psf_std is not None: # kwargs_numerics = {'subgrid_res': 1, 'psf_error_map': True} #Turn on the PSF error map # else: kwargs_numerics = {'supersampling_factor': 1, 'supersampling_convolution': False} if source_params is None: # here are the options for the host galaxy fitting fixed_source = [] kwargs_source_init = [] kwargs_source_sigma = [] kwargs_lower_source = [] kwargs_upper_source = [] # Disk component, as modelled by an elliptical Sersic profile if fix_n == None: fixed_source.append({}) # we fix the Sersic index to n=1 (exponential) kwargs_source_init.append({'R_sersic': 0.3, 'n_sersic': 2., 'e1': 0., 'e2': 0., 'center_x': 0., 'center_y': 0.}) kwargs_source_sigma.append({'n_sersic': 0.5, 'R_sersic': 0.1, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.1, 'center_y': 0.1}) kwargs_lower_source.append({'e1': -0.5, 'e2': -0.5, 'R_sersic': 0.01, 'n_sersic': 0.3, 'center_x': -10, 'center_y': -10}) kwargs_upper_source.append({'e1': 0.5, 'e2': 0.5, 'R_sersic': 3., 'n_sersic': 7., 'center_x': 10, 'center_y': 10}) elif fix_n is not None: fixed_source.append({'n_sersic': fix_n}) kwargs_source_init.append({'R_sersic': 0.3, 'n_sersic': fix_n, 'e1': 0., 'e2': 0., 'center_x': 0., 'center_y': 0.}) kwargs_source_sigma.append({'n_sersic': 0.001, 'R_sersic': 0.1, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.1, 'center_y': 0.1}) kwargs_lower_source.append({'e1': -0.5, 'e2': -0.5, 'R_sersic': 0.01, 'n_sersic': fix_n, 'center_x': -10, 'center_y': -10}) kwargs_upper_source.append({'e1': 0.5, 'e2': 0.5, 'R_sersic': 3, 'n_sersic': fix_n, 'center_x': 10, 'center_y': 10}) source_params = [kwargs_source_init, kwargs_source_sigma, fixed_source, kwargs_lower_source, kwargs_upper_source] else: source_params = source_params kwargs_params = {'source_model': source_params} #============================================================================== #Doing the QSO fitting #============================================================================== kwargs_data = sim_util.data_configure_simple(numPix, deltaPix, exp_time, background_rms, inverse=True) data_class = ImageData(**kwargs_data) if psf_ave is not None: kwargs_psf = {'psf_type': psf_type, 'kernel_point_source': kernel} else: kwargs_psf = {'psf_type': 'NONE'} psf_class = PSF(**kwargs_psf) data_class.update_data(galaxy_im) light_model_list = ['SERSIC_ELLIPSE'] * len(source_params[0]) lightModel = LightModel(light_model_list=light_model_list) kwargs_model = { 'source_light_model_list': light_model_list} # numerical options and fitting sequences kwargs_constraints = {} kwargs_likelihood = {'check_bounds': True, #Set the bonds, if exceed, reutrn "penalty" 'source_marg': False, #In likelihood_module.LikelihoodModule -- whether to fully invert the covariance matrix for marginalization 'check_positive_flux': True, 'image_likelihood_mask_list': [galaxy_msk] } kwargs_data['image_data'] = galaxy_im if galaxy_std is not None: kwargs_data['noise_map'] = galaxy_std if psf_std is not None: kwargs_psf['psf_error_map'] = psf_std image_band = [kwargs_data, kwargs_psf, kwargs_numerics] multi_band_list = [image_band] kwargs_data_joint = {'multi_band_list': multi_band_list, 'multi_band_type': 'multi-linear'} # 'single-band', 'multi-linear', 'joint-linear' fitting_seq = FittingSequence(kwargs_data_joint, kwargs_model, kwargs_constraints, kwargs_likelihood, kwargs_params) if deep_seed == False: fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 50, 'n_iterations': 50}], ['MCMC', {'n_burn': 10, 'n_run': 10, 'walkerRatio': 50, 'sigma_scale': .1}] ] elif deep_seed == True: fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 100, 'n_iterations': 80}], ['MCMC', {'n_burn': 10, 'n_run': 15, 'walkerRatio': 50, 'sigma_scale': .1}] ] elif deep_seed == 'very_deep': fitting_kwargs_list = [ ['PSO', {'sigma_scale': 0.8, 'n_particles': 150, 'n_iterations': 150}], ['MCMC', {'n_burn': 10, 'n_run': 20, 'walkerRatio': 50, 'sigma_scale': .1}] ] if no_MCMC == True: fitting_kwargs_list = [fitting_kwargs_list[0], ] start_time = time.time() chain_list = fitting_seq.fit_sequence(fitting_kwargs_list) kwargs_result = fitting_seq.best_fit() ps_result = kwargs_result['kwargs_ps'] source_result = kwargs_result['kwargs_source'] if no_MCMC == False: sampler_type, samples_mcmc, param_mcmc, dist_mcmc = chain_list[1] # chain_list, param_list, samples_mcmc, param_mcmc, dist_mcmc = fitting_seq.fit_sequence(fitting_kwargs_list) # lens_result, source_result, lens_light_result, ps_result, cosmo_temp = fitting_seq.best_fit() end_time = time.time() print(end_time - start_time, 'total time needed for computation') print('============ CONGRATULATION, YOUR JOB WAS SUCCESSFUL ================ ') # this is the linear inversion. The kwargs will be updated afterwards imageModel = ImageModel(data_class, psf_class, source_model_class=lightModel,kwargs_numerics=kwargs_numerics) imageLinearFit = ImageLinearFit(data_class=data_class, psf_class=psf_class, source_model_class=lightModel, kwargs_numerics=kwargs_numerics) image_reconstructed, error_map, _, _ = imageLinearFit.image_linear_solve(kwargs_source=source_result, kwargs_ps=ps_result) # image_host = [] #!!! The linear_solver before and after could have different result for very faint sources. # for i in range(len(source_result)): # image_host_i = imageModel.source_surface_brightness(source_result,de_lensed=True,unconvolved=False, k=i) # print("image_host_i", source_result[i]) # print("total flux", image_host_i.sum()) # image_host.append(image_host_i) # let's plot the output of the PSO minimizer modelPlot = ModelPlot(multi_band_list, kwargs_model, kwargs_result, arrow_size=0.02, cmap_string="gist_heat", likelihood_mask_list=[galaxy_msk]) if pso_diag == True: f, axes = chain_plot.plot_chain_list(chain_list,0) if pltshow == 0: plt.close() else: plt.show() reduced_Chisq = imageLinearFit.reduced_chi2(image_reconstructed, error_map) if image_plot: f, axes = plt.subplots(1, 3, figsize=(16, 16), sharex=False, sharey=False) modelPlot.data_plot(ax=axes[0]) modelPlot.model_plot(ax=axes[1]) modelPlot.normalized_residual_plot(ax=axes[2], v_min=-6, v_max=6) f.tight_layout() #f.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0., hspace=0.05) if tag is not None: f.savefig('{0}_fitted_image.pdf'.format(tag)) if pltshow == 0: plt.close() else: plt.show() image_host = [] for i in range(len(source_result)): image_host_i = imageModel.source_surface_brightness(source_result,de_lensed=True,unconvolved=False, k=i) # print("image_host_i", source_result[i]) # print("total flux", image_host_i.sum()) image_host.append(image_host_i) if corner_plot==True and no_MCMC==False: # here the (non-converged) MCMC chain of the non-linear parameters if not samples_mcmc == []: n, num_param = np.shape(samples_mcmc) plot = corner.corner(samples_mcmc, labels=param_mcmc, show_titles=True) if tag is not None: plot.savefig('{0}_para_corner.pdf'.format(tag)) if pltshow == 0: plt.close() else: plt.show() if flux_corner_plot ==True and no_MCMC==False: param = Param(kwargs_model, kwargs_fixed_source=source_params[2], **kwargs_constraints) mcmc_new_list = [] labels_new = ["host{0} flux".format(i) for i in range(len(source_params[0]))] for i in range(len(samples_mcmc)): kwargs_out = param.args2kwargs(samples_mcmc[i]) kwargs_light_source_out = kwargs_out['kwargs_source'] kwargs_ps_out = kwargs_out['kwargs_ps'] image_reconstructed, _, _, _ = imageLinearFit.image_linear_solve(kwargs_source=kwargs_light_source_out, kwargs_ps=kwargs_ps_out) fluxs = [] for j in range(len(source_params[0])): image_j = imageModel.source_surface_brightness(kwargs_light_source_out,unconvolved= False, k=j) fluxs.append(np.sum(image_j)) mcmc_new_list.append( fluxs ) if int(i/1000) > int((i-1)/1000) : print(len(samples_mcmc), "MCMC samplers in total, finished translate:", i ) plot = corner.corner(mcmc_new_list, labels=labels_new, show_titles=True) if tag is not None: plot.savefig('{0}_HOSTvsQSO_corner.pdf'.format(tag)) if pltshow == 0: plt.close() else: plt.show() if galaxy_std is None: noise_map = np.sqrt(data_class.C_D+np.abs(error_map)) else: noise_map = np.sqrt(galaxy_std**2+np.abs(error_map)) if dump_result == True: if flux_corner_plot==True and no_MCMC==False: trans_paras = [source_params[2], mcmc_new_list, labels_new, 'source_params[2], mcmc_new_list, labels_new'] else: trans_paras = [] picklename= tag + '.pkl' best_fit = [source_result, image_host, 'source_result, image_host'] # pso_fit = [chain_list, param_list, 'chain_list, param_list'] # mcmc_fit = [samples_mcmc, param_mcmc, dist_mcmc, 'samples_mcmc, param_mcmc, dist_mcmc'] chain_list_result = [chain_list, 'chain_list'] pickle.dump([best_fit, chain_list_result, trans_paras], open(picklename, 'wb')) if return_Chisq == False: return source_result, image_host, noise_map elif return_Chisq == True: return source_result, image_host, noise_map, reduced_Chisq