lens_light_model_list = ['SERSIC_ELLIPSE'] kwargs_lens_light = { 'amp': lens_light_para['amp_sersic'], 'R_sersic': lens_light_tran_Reff, 'n_sersic': lens_light_para['n_sersic'], 'center_x': 0.0, 'center_y': 0.0, 'e1': lens_light_para['e1'], 'e2': lens_light_para['e2'] } kwargs_lens_light_copy = copy.deepcopy(kwargs_lens_light) kwargs_lens_light_copy['phi_G'] = lens_light_para['phi_G'] kwargs_lens_light_copy['q'] = lens_light_para['q'] kwargs_lens_light_list = [kwargs_lens_light] lens_light_model_class = LightModel(light_model_list=lens_light_model_list) #============================================================================== # ##### lens mass model #============================================================================== from lenstronomy.LensModel.lens_model import LensModel kwargs_spemd = para.spemd() kwargs_spemd['q'] = 0.9 + np.random.normal(0, 0.01) kwargs_spemd['e1'], kwargs_spemd['e2'] = param_util.phi_q2_ellipticity( phi=kwargs_spemd['phi_G'], q=kwargs_spemd['q']) lens_model_list = ['PEMD', 'SHEAR'] #kwargs_spemd['gamma'] = 2. kwargs_mass_copy = copy.deepcopy([kwargs_spemd]) del kwargs_spemd['phi_G'] del kwargs_spemd['q']
def __init__(self, lens_model_list=[], z_lens=None, z_source=None, lens_redshift_list=None, source_light_model_list=[], lens_light_model_list=[], point_source_model_list=[], source_redshift_list=None, cosmo=None, z_source_convention=None): """ :param lens_model_list: list of strings with lens model names :param z_lens: redshift of the deflector (only considered when operating in single plane mode). Is only needed for specific functions that require a cosmology. :param z_source: redshift of the source: Needed in multi_plane option only, not required for the core functionalities in the single plane mode. This will be the redshift of the source plane (if not further specified the 'source_redshift_list') and the point source redshift (regardless of 'source_redshift_list') :param lens_redshift_list: list of deflector redshift (corresponding to the lens model list), only applicable in multi_plane mode. :param source_light_model_list: list of strings with source light model names (lensed light profiles) :param lens_light_model_list: list of strings with lens light model names (not lensed light profiles) :param point_source_model_list: list of strings with point source model names :param source_redshift_list: list of redshifts of the source profiles (optional) :param cosmo: instance of the astropy cosmology class. If not specified, uses the default cosmology. :param z_source_convention: float, redshift of a source to define the reduced deflection angles of the lens models. If None, 'z_source' is used. """ if cosmo is None: cosmo = default_cosmology.get() if lens_redshift_list is not None or source_redshift_list is not None: multi_plane = True else: multi_plane = False if z_source_convention is None: z_source_convention = z_source self._lens_model_class = LensModel( lens_model_list=lens_model_list, z_source=z_source, z_lens=z_lens, lens_redshift_list=lens_redshift_list, multi_plane=multi_plane, cosmo=cosmo, z_source_convention=z_source_convention) self._source_model_class = LightModel( light_model_list=source_light_model_list, source_redshift_list=source_redshift_list) self._lens_light_model_class = LightModel( light_model_list=lens_light_model_list) fixed_magnification = [False] * len(point_source_model_list) for i, ps_type in enumerate(point_source_model_list): if ps_type == 'SOURCE_POSITION': fixed_magnification[i] = True self._point_source_model_class = PointSource( point_source_type_list=point_source_model_list, lensModel=self._lens_model_class, fixed_magnification_list=fixed_magnification) self._cosmo = cosmo self._z_source_convention = z_source_convention self._lens_redshift_list = lens_redshift_list self._z_lens = z_lens
def create_class_instances(lens_model_list=[], z_lens=None, z_source=None, lens_redshift_list=None, kwargs_interp=None, multi_plane=False, observed_convention_index=None, source_light_model_list=[], lens_light_model_list=[], point_source_model_list=[], fixed_magnification_list=None, flux_from_point_source_list=None, additional_images_list=None, kwargs_lens_eqn_solver=None, source_deflection_scaling_list=None, source_redshift_list=None, cosmo=None, index_lens_model_list=None, index_source_light_model_list=None, index_lens_light_model_list=None, index_point_source_model_list=None, optical_depth_model_list=None, index_optical_depth_model_list=None, band_index=0, tau0_index_list=None, all_models=False, point_source_magnification_limit=None, surface_brightness_smoothing=0.001, sersic_major_axis=None): """ :param lens_model_list: list of strings indicating the type of lens models :param z_lens: redshift of the deflector (for single lens plane mode, but only relevant when computing physical quantities) :param z_source: redshift of source (for single source plane mode, or for multiple source planes the redshift of the point source). In regard to this redshift the reduced deflection angles are defined in the lens model. :param lens_redshift_list: :param multi_plane: :param kwargs_interp: interpolation keyword arguments specifying the numerics. See description in the Interpolate() class. Only applicable for 'INTERPOL' and 'INTERPOL_SCALED' models. :param observed_convention_index: :param source_light_model_list: :param lens_light_model_list: :param point_source_model_list: :param fixed_magnification_list: :param flux_from_point_source_list: list of bools (optional), if set, will only return image positions (for imaging modeling) for the subset of the point source lists that =True. This option enables to model :param additional_images_list: :param kwargs_lens_eqn_solver: keyword arguments specifying the numerical settings for the lens equation solver see LensEquationSolver() class for details :param source_deflection_scaling_list: List of floats for each source ligth model (optional, and only applicable for single-plane lensing. The factors re-scale the reduced deflection angles described from the lens model. =1 means identical source position as without this option. This option enables multiple source planes. The geometric difference between the different source planes needs to be pre-computed and is cosmology dependent. :param source_redshift_list: :param cosmo: astropy.cosmology instance :param index_lens_model_list: :param index_source_light_model_list: :param index_lens_light_model_list: :param index_point_source_model_list: :param optical_depth_model_list: list of strings indicating the optical depth model to compute (differential) extinctions from the source :param index_optical_depth_model_list: :param band_index: int, index of band to consider. Has an effect if only partial models are considered for a specific band :param tau0_index_list: list of integers of the specific extinction scaling parameter tau0 for each band :param all_models: bool, if True, will make class instances of all models ignoring potential keywords that are excluding specific models as indicated. :param point_source_magnification_limit: float >0 or None, if set and additional images are computed, then it will cut the point sources computed to the limiting (absolute) magnification :param surface_brightness_smoothing: float, smoothing scale of light profile (minimal distance to the center of a profile) this can help to avoid inaccuracies in the very center of a cuspy light profile :param sersic_major_axis: boolean or None, if True, uses the semi-major axis as the definition of the Sersic half-light radius, if False, uses the product average of semi-major and semi-minor axis. If None, uses the convention in the lenstronomy yaml setting (which by default is =False) :return: """ if index_lens_model_list is None or all_models is True: lens_model_list_i = lens_model_list lens_redshift_list_i = lens_redshift_list observed_convention_index_i = observed_convention_index else: lens_model_list_i = [ lens_model_list[k] for k in index_lens_model_list[band_index] ] if lens_redshift_list is not None: lens_redshift_list_i = [ lens_redshift_list[k] for k in index_lens_model_list[band_index] ] else: lens_redshift_list_i = lens_redshift_list if observed_convention_index is not None: counter = 0 observed_convention_index_i = [] for k in index_lens_model_list[band_index]: if k in observed_convention_index: observed_convention_index_i.append(counter) counter += 1 else: observed_convention_index_i = observed_convention_index lens_model_class = LensModel( lens_model_list=lens_model_list_i, z_lens=z_lens, z_source=z_source, lens_redshift_list=lens_redshift_list_i, multi_plane=multi_plane, cosmo=cosmo, observed_convention_index=observed_convention_index_i, kwargs_interp=kwargs_interp) if index_source_light_model_list is None or all_models is True: source_light_model_list_i = source_light_model_list source_deflection_scaling_list_i = source_deflection_scaling_list source_redshift_list_i = source_redshift_list else: source_light_model_list_i = [ source_light_model_list[k] for k in index_source_light_model_list[band_index] ] if source_deflection_scaling_list is None: source_deflection_scaling_list_i = source_deflection_scaling_list else: source_deflection_scaling_list_i = [ source_deflection_scaling_list[k] for k in index_source_light_model_list[band_index] ] if source_redshift_list is None: source_redshift_list_i = source_redshift_list else: source_redshift_list_i = [ source_redshift_list[k] for k in index_source_light_model_list[band_index] ] source_model_class = LightModel( light_model_list=source_light_model_list_i, deflection_scaling_list=source_deflection_scaling_list_i, source_redshift_list=source_redshift_list_i, smoothing=surface_brightness_smoothing, sersic_major_axis=sersic_major_axis) if index_lens_light_model_list is None or all_models is True: lens_light_model_list_i = lens_light_model_list else: lens_light_model_list_i = [ lens_light_model_list[k] for k in index_lens_light_model_list[band_index] ] lens_light_model_class = LightModel( light_model_list=lens_light_model_list_i, smoothing=surface_brightness_smoothing, sersic_major_axis=sersic_major_axis) point_source_model_list_i = point_source_model_list fixed_magnification_list_i = fixed_magnification_list additional_images_list_i = additional_images_list if index_point_source_model_list is not None and not all_models: point_source_model_list_i = [ point_source_model_list[k] for k in index_point_source_model_list[band_index] ] if fixed_magnification_list is not None: fixed_magnification_list_i = [ fixed_magnification_list[k] for k in index_point_source_model_list[band_index] ] if additional_images_list is not None: additional_images_list_i = [ additional_images_list[k] for k in index_point_source_model_list[band_index] ] point_source_class = PointSource( point_source_type_list=point_source_model_list_i, lensModel=lens_model_class, fixed_magnification_list=fixed_magnification_list_i, flux_from_point_source_list=flux_from_point_source_list, additional_images_list=additional_images_list_i, magnification_limit=point_source_magnification_limit, kwargs_lens_eqn_solver=kwargs_lens_eqn_solver) if tau0_index_list is None: tau0_index = 0 else: tau0_index = tau0_index_list[band_index] if index_optical_depth_model_list is not None: optical_depth_model_list_i = [ optical_depth_model_list[k] for k in index_optical_depth_model_list[band_index] ] else: optical_depth_model_list_i = optical_depth_model_list extinction_class = DifferentialExtinction( optical_depth_model=optical_depth_model_list_i, tau0_index=tau0_index) return lens_model_class, source_model_class, lens_light_model_class, point_source_class, extinction_class
class TestLightModel(object): """ tests the source model routines """ def setup(self): self.light_model_list = ['GAUSSIAN', 'MULTI_GAUSSIAN', 'SERSIC', 'SERSIC_ELLIPSE', 'CORE_SERSIC', 'SHAPELETS', 'HERNQUIST', 'HERNQUIST_ELLIPSE', 'PJAFFE', 'PJAFFE_ELLIPSE', 'UNIFORM', 'POWER_LAW', 'NIE', 'INTERPOL', 'SHAPELETS_POLAR_EXP', 'ELLIPSOID' ] phi_G, q = 0.5, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) self.kwargs = [ {'amp': 1., 'sigma': 1., 'center_x': 0, 'center_y': 0}, # 'GAUSSIAN' {'amp': [1., 2], 'sigma': [1, 3], 'center_x': 0, 'center_y': 0}, # 'MULTI_GAUSSIAN' {'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'center_x': 0, 'center_y': 0}, # 'SERSIC' {'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0}, # 'SERSIC_ELLIPSE' {'amp': 1, 'R_sersic': 0.5, 'Re': 0.1, 'gamma': 2., 'n_sersic': 1, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0}, # 'CORE_SERSIC' {'amp': [1, 1, 1], 'beta': 0.5, 'n_max': 1, 'center_x': 0, 'center_y': 0}, # 'SHAPELETS' {'amp': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0}, # 'HERNQUIST' {'amp': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2}, # 'HERNQUIST_ELLIPSE' {'amp': 1, 'Ra': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0}, # 'PJAFFE' {'amp': 1, 'Ra': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2}, # 'PJAFFE_ELLIPSE' {'amp': 1}, # 'UNIFORM' {'amp': 1., 'gamma': 2., 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0}, # 'POWER_LAW' {'amp': .001, 'e1': 0, 'e2': 1., 'center_x': 0, 'center_y': 0, 's_scale': 1.}, # 'NIE' {'image': np.zeros((10, 10)), 'scale': 1, 'phi_G': 0, 'center_x': 0, 'center_y': 0}, {'amp': [1], 'n_max': 0, 'beta': 1, 'center_x': 0, 'center_y': 0}, {'amp': 1, 'radius': 1., 'e1': 0, 'e2': 0.1, 'center_x': 0, 'center_y': 0} # 'ELLIPSOID' ] self.LightModel = LightModel(light_model_list=self.light_model_list) def test_init(self): model_list = ['CORE_SERSIC', 'SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP', 'UNIFORM', 'CHAMELEON', 'DOUBLE_CHAMELEON', 'TRIPLE_CHAMELEON'] lightModel = LightModel(light_model_list=model_list) assert len(lightModel.profile_type_list) == len(model_list) def test_surface_brightness(self): output = self.LightModel.surface_brightness(x=1., y=1., kwargs_list=self.kwargs) npt.assert_almost_equal(output, 2.5886852663397137, decimal=6) def test_surface_brightness_array(self): output = self.LightModel.surface_brightness(x=[1], y=[1], kwargs_list=self.kwargs) npt.assert_almost_equal(output[0], 2.5886852663397137, decimal=6) def test_functions_split(self): output = self.LightModel.functions_split(x=1., y=1., kwargs_list=self.kwargs) npt.assert_almost_equal(output[0][0], 0.058549831524319168, decimal=6) def test_param_name_list(self): param_name_list = self.LightModel.param_name_list assert len(self.light_model_list) == len(param_name_list) def test_num_param_linear(self): num = self.LightModel.num_param_linear(self.kwargs, list_return=False) assert num == 19 num_list = self.LightModel.num_param_linear(self.kwargs, list_return=True) assert num_list[0] == 1 def test_update_linear(self): response, n = self.LightModel.functions_split(1, 1, self.kwargs) param = np.ones(n) * 2 kwargs_out, i = self.LightModel.update_linear(param, i=0, kwargs_list=self.kwargs) assert i == n assert kwargs_out[0]['amp'] == 2 def test_total_flux(self): light_model_list = ['SERSIC', 'SERSIC_ELLIPSE', 'INTERPOL', 'GAUSSIAN', 'GAUSSIAN_ELLIPSE', 'MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE'] kwargs_list = [{'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'center_x': 0, 'center_y': 0}, # 'SERSIC' {'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'e1': 0.1, 'e2': 0, 'center_x': 0, 'center_y': 0}, # 'SERSIC_ELLIPSE' {'image': np.ones((10, 10)), 'scale': 1, 'phi_G': 0, 'center_x': 0, 'center_y': 0}, # 'INTERPOL' {'amp': 2, 'sigma': 2, 'center_x': 0, 'center_y': 0}, # 'GAUSSIAN' {'amp': 2, 'sigma': 2, 'e1': 0.1, 'e2': 0, 'center_x': 0, 'center_y': 0}, # 'GAUSSIAN_ELLIPSE' {'amp': [1,1], 'sigma': [2, 1], 'center_x': 0, 'center_y': 0}, # 'MULTI_GAUSSIAN' {'amp': [1, 1], 'sigma': [2, 1], 'e1': 0.1, 'e2': 0, 'center_x': 0, 'center_y': 0} # 'MULTI_GAUSSIAN_ELLIPSE' ] lightModel = LightModel(light_model_list=light_model_list) total_flux_list = lightModel.total_flux(kwargs_list) assert total_flux_list[2] == 100 assert total_flux_list[3] == 2 assert total_flux_list[4] == 2 assert total_flux_list[5] == 2 assert total_flux_list[6] == 2 total_flux_list = lightModel.total_flux(kwargs_list, norm=True) assert total_flux_list[2] == 100 assert total_flux_list[3] == 1 assert total_flux_list[4] == 1 assert total_flux_list[5] == 2 assert total_flux_list[6] == 2 def test_delete_interpol_caches(self): x, y = util.make_grid(numPix=20, deltapix=1.) gauss = Gaussian() flux = gauss.function(x, y, amp=1., center_x=0., center_y=0., sigma=1.) image = util.array2image(flux) light_model_list = ['INTERPOL', 'INTERPOL'] kwargs_list = [ {'image': image, 'scale': 1, 'phi_G': 0, 'center_x': 0, 'center_y': 0}, {'image': image, 'scale': 1, 'phi_G': 0, 'center_x': 0, 'center_y': 0} ] lightModel = LightModel(light_model_list=light_model_list) output = lightModel.surface_brightness(x, y, kwargs_list) for func in lightModel.func_list: assert hasattr(func, '_image_interp') lightModel.delete_interpol_caches() for func in lightModel.func_list: assert not hasattr(func, '_image_interp') def test_check_positive_flux_profile(self): ligthModel = LightModel(light_model_list=['GAUSSIAN']) kwargs_list = [{'amp': 0, 'sigma': 1}] bool = ligthModel.check_positive_flux_profile(kwargs_list) assert bool kwargs_list = [{'amp': -1, 'sigma': 1}] bool = ligthModel.check_positive_flux_profile(kwargs_list) assert not bool
def test_init(self): model_list = ['CORE_SERSIC', 'SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP', 'UNIFORM', 'CHAMELEON', 'DOUBLE_CHAMELEON', 'TRIPLE_CHAMELEON'] lightModel = LightModel(light_model_list=model_list) assert len(lightModel.profile_type_list) == len(model_list)
def test_total_flux(self): light_model_list = [ 'SERSIC', 'SERSIC_ELLIPSE', 'INTERPOL', 'GAUSSIAN', 'GAUSSIAN_ELLIPSE', 'MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE' ] kwargs_list = [ { 'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'center_x': 0, 'center_y': 0 }, # 'SERSIC' { 'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'e1': 0.1, 'e2': 0, 'center_x': 0, 'center_y': 0 }, # 'SERSIC_ELLIPSE' { 'image': np.ones((20, 5)), 'scale': 1, 'phi_G': 0, 'center_x': 0, 'center_y': 0 }, # 'INTERPOL' { 'amp': 2, 'sigma': 2, 'center_x': 0, 'center_y': 0 }, # 'GAUSSIAN' { 'amp': 2, 'sigma': 2, 'e1': 0.1, 'e2': 0, 'center_x': 0, 'center_y': 0 }, # 'GAUSSIAN_ELLIPSE' { 'amp': [1, 1], 'sigma': [2, 1], 'center_x': 0, 'center_y': 0 }, # 'MULTI_GAUSSIAN' { 'amp': [1, 1], 'sigma': [2, 1], 'e1': 0.1, 'e2': 0, 'center_x': 0, 'center_y': 0 } # 'MULTI_GAUSSIAN_ELLIPSE' ] lightModel = LightModel(light_model_list=light_model_list) total_flux_list = lightModel.total_flux(kwargs_list) assert total_flux_list[2] == 100 assert total_flux_list[3] == 2 assert total_flux_list[4] == 2 assert total_flux_list[5] == 2 assert total_flux_list[6] == 2 total_flux_list = lightModel.total_flux(kwargs_list, norm=True) assert total_flux_list[2] == 100 assert total_flux_list[3] == 1 assert total_flux_list[4] == 1 assert total_flux_list[5] == 2 assert total_flux_list[6] == 2
def setup(self): # data specifics sigma_bkg = 0.05 # background noise per pixel exp_time = 100 # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = 10 # cutout pixel size deltaPix = 0.1 # 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) data_class = Data(kwargs_data) kwargs_psf = sim_util.psf_configure_simple(psf_type='GAUSSIAN', fwhm=fwhm, kernelsize=11, deltaPix=deltaPix, truncate=3, kernel=None) kwargs_psf = sim_util.psf_configure_simple(psf_type='PIXEL', fwhm=fwhm, kernelsize=11, deltaPix=deltaPix, truncate=6, kernel=kwargs_psf['kernel_point_source']) psf_class = PSF(kwargs_psf) kwargs_spemd = {'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'e1': 0.1, 'e2': 0.1} lens_model_list = ['SPEP'] self.kwargs_lens = [kwargs_spemd] lens_model_class = LensModel(lens_model_list=lens_model_list) 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': 3, 'center_x': 0, 'center_y': 0, 'e1': 0.1, 'e2': 0.1} 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) kwargs_numerics = {'subgrid_res': 1, 'psf_subgrid': False} imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, kwargs_numerics=kwargs_numerics) image_sim = sim_util.simulate_simple(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light) data_class.update_data(image_sim) self.data_class = data_class self.psf_class = psf_class kwargs_model = {'lens_model_list': lens_model_list, 'source_light_model_list': source_model_list, 'lens_light_model_list': lens_light_model_list, 'fixed_magnification_list': [False], } self.kwargs_numerics = { 'subgrid_res': 1, 'psf_subgrid': False} num_source_model = len(source_model_list) kwargs_constraints = { 'image_plane_source_list': [False] * num_source_model, } kwargs_likelihood = { 'source_marg': True, 'point_source_likelihood': False, 'position_uncertainty': 0.004, 'check_solver': False, 'solver_tolerance': 0.001, } self.param_class = Param(kwargs_model, **kwargs_constraints) self.Likelihood = LikelihoodModule(imSim_class=imageModel, param_class=self.param_class, **kwargs_likelihood) self.sampler = Sampler(likelihoodModule=self.Likelihood)
def __init__(self, data_class, psf_class, lens_model_class=None, source_model_class=None, lens_light_model_class=None, point_source_class=None, extinction_class=None, kwargs_numerics=None, kwargs_pixelbased=None): """ :param data_class: instance of ImageData() or PixelGrid() class :param psf_class: instance of PSF() class :param lens_model_class: instance of LensModel() class :param source_model_class: instance of LightModel() class describing the source parameters :param lens_light_model_class: instance of LightModel() class describing the lens light parameters :param point_source_class: instance of PointSource() class describing the point sources :param kwargs_numerics: keyword arguments with various numeric description (see ImageNumerics class for options) :param kwargs_pixelbased: keyword arguments with various settings related to the pixel-based solver (see SLITronomy documentation) """ self.type = 'single-band' self.num_bands = 1 self.PSF = psf_class self.Data = data_class self.PSF.set_pixel_size(self.Data.pixel_width) if kwargs_numerics is None: kwargs_numerics = {} self.ImageNumerics = NumericsSubFrame(pixel_grid=self.Data, psf=self.PSF, **kwargs_numerics) if lens_model_class is None: lens_model_class = LensModel(lens_model_list=[]) self.LensModel = lens_model_class if point_source_class is None: point_source_class = PointSource(point_source_type_list=[]) self.PointSource = point_source_class self.PointSource.update_lens_model(lens_model_class=lens_model_class) x_center, y_center = self.Data.center self.PointSource.update_search_window( search_window=np.max(self.Data.width), x_center=x_center, y_center=y_center, min_distance=self.Data.pixel_width, only_from_unspecified=True) self._psf_error_map = self.PSF.psf_error_map_bool if source_model_class is None: source_model_class = LightModel(light_model_list=[]) self.SourceModel = source_model_class if lens_light_model_class is None: lens_light_model_class = LightModel(light_model_list=[]) self.LensLightModel = lens_light_model_class self._kwargs_numerics = kwargs_numerics if extinction_class is None: extinction_class = DifferentialExtinction(optical_depth_model=[]) self._extinction = extinction_class if kwargs_pixelbased is None: kwargs_pixelbased = {} else: kwargs_pixelbased = kwargs_pixelbased.copy() self._pixelbased_bool = self._detect_pixelbased_models() if self._pixelbased_bool is True: from slitronomy.Util.class_util import create_solver_class # requirement on SLITronomy is exclusively here self.SourceNumerics = self._setup_pixelbased_source_numerics( kwargs_numerics, kwargs_pixelbased) self.PixelSolver = create_solver_class( self.Data, self.PSF, self.ImageNumerics, self.SourceNumerics, self.LensModel, self.SourceModel, self.LensLightModel, self.PointSource, self._extinction, kwargs_pixelbased) self.source_mapping = None # handled with pixelated operator else: self.source_mapping = Image2SourceMapping( lensModel=lens_model_class, sourceModel=source_model_class)
class LightProfile(object): """ class to deal with the light distribution """ def __init__(self, profile_list, interpol_grid_num=1000, max_interpolate=100, min_interpolate=0.001): """ :param profile_list: """ self.light_model = LightModel(light_model_list=profile_list) self._interp_grid_num = interpol_grid_num self._max_interpolate = max_interpolate self._min_interpolate = min_interpolate def light_3d(self, r, kwargs_list): """ :param kwargs_list: :return: """ light_3d = self.light_model.light_3d(r, kwargs_list) return light_3d def light_3d_interp(self, r, kwargs_list, new_compute=False): """ :param kwargs_list: :return: """ if not hasattr(self, '_f_light_3d') or new_compute is True: r_array = np.logspace(np.log10(self._min_interpolate), np.log10(self._max_interpolate), self._interp_grid_num) light_3d_array = self.light_model.light_3d(r_array, kwargs_list) light_3d_array[light_3d_array < 10**(-100)] = 10**(-100) f = interp1d(np.log(r_array), np.log(light_3d_array), fill_value="extrapolate") self._f_light_3d = f return np.exp(self._f_light_3d(np.log(r))) def light_2d(self, R, kwargs_list): """ :param R: :param kwargs_list: :return: """ #TODO make sure averaging is done azimuthally kwargs_list_copy = copy.deepcopy(kwargs_list) kwargs_list_new = [] for kwargs in kwargs_list_copy: if 'e1' in kwargs: kwargs['e1'] = 0 if 'e2' in kwargs: kwargs['e2'] = 0 kwargs_list_new.append({ k: v for k, v in kwargs.items() if not k in ['center_x', 'center_y'] }) return self.light_model.surface_brightness(R, 0, kwargs_list_new) def draw_light_2d_linear(self, kwargs_list, n=1, new_compute=False, r_eff=1.): """ constructs the CDF and draws from it random realizations of projected radii R :param kwargs_list: :return: """ if not hasattr(self, '_light_cdf') or new_compute is True: r_array = np.linspace(self._min_interpolate, self._max_interpolate, self._interp_grid_num) cum_sum = np.zeros_like(r_array) sum = 0 for i, r in enumerate(r_array): if i == 0: cum_sum[i] = 0 else: sum += self.light_2d(r, kwargs_list) * r cum_sum[i] = copy.deepcopy(sum) cum_sum_norm = cum_sum / cum_sum[-1] f = interp1d(cum_sum_norm, r_array) self._light_cdf = f cdf_draw = np.random.uniform(0., 1, n) r_draw = self._light_cdf(cdf_draw) return r_draw def draw_light_2d(self, kwargs_list, n=1, new_compute=False): """ constructs the CDF and draws from it random realizations of projected radii R :param kwargs_list: :return: """ if not hasattr(self, '_light_cdf_log') or new_compute is True: r_array = np.logspace(np.log10(self._min_interpolate), np.log10(self._max_interpolate), self._interp_grid_num) cum_sum = np.zeros_like(r_array) sum = 0 for i, r in enumerate(r_array): if i == 0: cum_sum[i] = 0 else: sum += self.light_2d(r, kwargs_list) * r * r cum_sum[i] = copy.deepcopy(sum) cum_sum_norm = cum_sum / cum_sum[-1] f = interp1d(cum_sum_norm, np.log(r_array)) self._light_cdf_log = f cdf_draw = np.random.uniform(0., 1, n) r_log_draw = self._light_cdf_log(cdf_draw) return np.exp(r_log_draw) def delete_cache(self): """ deletes cached interpolation function of the CDF for a specific light profile :return: None """ if hasattr(self, '_light_cdf_log'): del self._light_cdf_log if hasattr(self, '_light_cdf'): del self._light_cdf if hasattr(self, '_f_light_3d'): del self._f_light_3d
def setup(self): # we define a model consisting of a singe Sersric profile from lenstronomy.LightModel.light_model import LightModel light_model_list = ['SERSIC_ELLIPSE'] self.lightModel = LightModel(light_model_list=light_model_list) self.kwargs_light = [{ 'amp': 100, 'R_sersic': 0.5, 'n_sersic': 3, 'e1': 0, 'e2': 0, 'center_x': 0.02, 'center_y': 0 }] # we define a pixel grid and a higher resolution super sampling factor self._supersampling_factor = 5 numPix = 61 # cutout pixel size deltaPix = 0.05 # pixel size in arcsec (area per pixel = deltaPix**2) x, y, ra_at_xy_0, dec_at_xy_0, x_at_radec_0, y_at_radec_0, Mpix2coord, Mcoord2pix = util.make_grid_with_coordtransform( numPix=numPix, deltapix=deltaPix, subgrid_res=1, left_lower=False, inverse=False) flux = self.lightModel.surface_brightness( x, y, kwargs_list=self.kwargs_light) flux = util.array2image(flux) flux_max = np.max(flux) conv_pixels_partial = np.zeros((numPix, numPix), dtype=bool) conv_pixels_partial[flux >= flux_max / 20] = True self._conv_pixels_partial = conv_pixels_partial # high resolution ray-tracing and high resolution convolution, the full calculation self.kwargs_numerics_true = { 'supersampling_factor': self._supersampling_factor, # super sampling factor of (partial) high resolution ray-tracing 'compute_mode': 'regular', # 'regular' or 'adaptive' 'supersampling_convolution': True, # bool, if True, performs the supersampled convolution (either on regular or adaptive grid) 'supersampling_kernel_size': None, # size of the higher resolution kernel region (can be smaller than the original kernel). None leads to use the full size 'flux_evaluate_indexes': None, # bool mask, if None, it will evaluate all (sub) pixels 'supersampled_indexes': None, # bool mask of pixels to be computed in supersampled grid (only for adaptive mode) 'compute_indexes': None, # bool mask of pixels to be computed the PSF response (flux being added to). Only used for adaptive mode and can be set =likelihood mask. 'point_source_supersampling_factor': 1, # int, supersampling factor when rendering a point source (not used in this script) } # high resolution convolution on a smaller PSF with low resolution convolution on the edges of the PSF and high resolution ray tracing self.kwargs_numerics_high_res_narrow = { 'supersampling_factor': self._supersampling_factor, 'compute_mode': 'regular', 'supersampling_convolution': True, 'supersampling_kernel_size': 5, } # low resolution convolution based on high resolution ray-tracing grid self.kwargs_numerics_low_conv_high_grid = { 'supersampling_factor': self._supersampling_factor, 'compute_mode': 'regular', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 } # low resolution convolution with a subset of pixels with high resolution ray-tracing self.kwargs_numerics_low_conv_high_adaptive = { 'supersampling_factor': self._supersampling_factor, 'compute_mode': 'adaptive', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 'supersampled_indexes': self._conv_pixels_partial, 'convolution_kernel_size': 9, } # low resolution convolution with a subset of pixels with high resolution ray-tracing and high resoluton convolution on smaller kernel size self.kwargs_numerics_high_adaptive = { 'supersampling_factor': self._supersampling_factor, 'compute_mode': 'adaptive', 'supersampling_convolution': True, # does not matter for supersampling_factor=1 'supersampling_kernel_size': 5, # does not matter for supersampling_factor=1 'supersampled_indexes': self._conv_pixels_partial, 'convolution_kernel_size': 9, } # low resolution convolution and low resolution ray tracing, the simplest calculation self.kwargs_numerics_low_res = { 'supersampling_factor': 1, 'compute_mode': 'regular', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 'convolution_kernel_size': 9, } flux_evaluate_indexes = np.zeros((numPix, numPix), dtype=bool) flux_evaluate_indexes[flux >= flux_max / 1000] = True # low resolution convolution on subframe self.kwargs_numerics_partial = { 'supersampling_factor': 1, 'compute_mode': 'regular', 'supersampling_convolution': False, # does not matter for supersampling_factor=1 'supersampling_kernel_size': None, # does not matter for supersampling_factor=1 'flux_evaluate_indexes': flux_evaluate_indexes, 'convolution_kernel_size': 9 } # import PSF file kernel_super = kernel_util.kernel_gaussian( kernel_numPix=11 * self._supersampling_factor, deltaPix=deltaPix / self._supersampling_factor, fwhm=0.1) kernel_size = 9 kernel_super = kernel_util.cut_psf(psf_data=kernel_super, psf_size=kernel_size * self._supersampling_factor) # make instance of the PixelGrid class from lenstronomy.Data.pixel_grid import PixelGrid kwargs_grid = { 'nx': numPix, 'ny': numPix, 'transform_pix2angle': Mpix2coord, 'ra_at_xy_0': ra_at_xy_0, 'dec_at_xy_0': dec_at_xy_0 } self.pixel_grid = PixelGrid(**kwargs_grid) # make instance of the PSF class from lenstronomy.Data.psf import PSF kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel_super, 'point_source_supersampling_factor': self._supersampling_factor } self.psf_class = PSF(**kwargs_psf) # without convolution image_model_true = ImageModel( self.pixel_grid, self.psf_class, lens_light_model_class=self.lightModel, kwargs_numerics=self.kwargs_numerics_true) self.image_true = image_model_true.image( kwargs_lens_light=self.kwargs_light)
def test_magnification_finite_adaptive(self): lens_model_list = ['EPL', 'SHEAR'] z_source = 1.5 kwargs_lens = [{ 'theta_E': 1., 'gamma': 2., 'e1': 0.02, 'e2': -0.09, 'center_x': 0, 'center_y': 0 }, { 'gamma1': 0.01, 'gamma2': 0.03 }] lensmodel = LensModel(lens_model_list) extension = LensModelExtensions(lensmodel) solver = LensEquationSolver(lensmodel) source_x, source_y = 0.07, 0.03 x_image, y_image = solver.findBrightImage(source_x, source_y, kwargs_lens) source_fwhm_parsec = 40. pc_per_arcsec = 1000 / self.cosmo.arcsec_per_kpc_proper(z_source).value source_sigma = source_fwhm_parsec / pc_per_arcsec / 2.355 grid_size = auto_raytracing_grid_size(source_fwhm_parsec) grid_resolution = auto_raytracing_grid_resolution(source_fwhm_parsec) # make this even higher resolution to show convergence grid_number = int(2 * grid_size / grid_resolution) window_size = 2 * grid_size mag_square_grid = extension.magnification_finite( x_image, y_image, kwargs_lens, source_sigma=source_sigma, grid_number=grid_number, window_size=window_size) flux_ratios_square_grid = mag_square_grid / max(mag_square_grid) mag_adaptive_grid = extension.magnification_finite_adaptive( x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=self.cosmo) flux_ratios_adaptive_grid = mag_adaptive_grid / max(mag_adaptive_grid) mag_adaptive_grid_fixed_aperture_size = extension.magnification_finite_adaptive( x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=self.cosmo, fixed_aperture_size=True, grid_radius_arcsec=0.2) flux_ratios_fixed_aperture_size = mag_adaptive_grid_fixed_aperture_size / max( mag_adaptive_grid_fixed_aperture_size) mag_adaptive_grid_2 = extension.magnification_finite_adaptive( x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=self.cosmo, axis_ratio=0) mag_adaptive_grid_3 = extension.magnification_finite_adaptive( x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=self.cosmo, axis_ratio=1) flux_ratios_adaptive_grid_2 = mag_adaptive_grid_2 / max( mag_adaptive_grid_2) flux_ratios_adaptive_grid_3 = mag_adaptive_grid_3 / max( mag_adaptive_grid_3) # tests the default cosmology _ = extension.magnification_finite_adaptive(x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=None, tol=0.0001) # test smallest eigenvalue _ = extension.magnification_finite_adaptive( x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=None, tol=0.0001, use_largest_eigenvalue=False) # tests the r_max > sqrt(2) * grid_radius stop criterion _ = extension.magnification_finite_adaptive(x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=None, tol=0.0001, step_size=1000) mag_point_source = abs( lensmodel.magnification(x_image, y_image, kwargs_lens)) quarter_precent_precision = [0.0025] * 4 npt.assert_array_less( flux_ratios_square_grid / flux_ratios_adaptive_grid - 1, quarter_precent_precision) npt.assert_array_less( flux_ratios_fixed_aperture_size / flux_ratios_adaptive_grid - 1, quarter_precent_precision) npt.assert_array_less( flux_ratios_square_grid / flux_ratios_adaptive_grid_2 - 1, quarter_precent_precision) npt.assert_array_less( flux_ratios_adaptive_grid_3 / flux_ratios_adaptive_grid_2 - 1, quarter_precent_precision) half_percent_precision = [0.005] * 4 npt.assert_array_less(mag_square_grid / mag_adaptive_grid - 1, half_percent_precision) npt.assert_array_less(mag_square_grid / mag_adaptive_grid_2 - 1, half_percent_precision) npt.assert_array_less(mag_adaptive_grid / mag_point_source - 1, half_percent_precision) flux_array = np.array([0., 0.]) grid_x = np.array([0., source_sigma]) grid_y = np.array([0., 0.]) grid_r = np.hypot(grid_x, grid_y) # test that the double gaussian profile has 2x the flux when dx, dy = 0 magnification_double_gaussian = extension.magnification_finite_adaptive( x_image, y_image, source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=self.cosmo, source_light_model='DOUBLE_GAUSSIAN', dx=0., dy=0., amp_scale=1., size_scale=1.) npt.assert_almost_equal(magnification_double_gaussian, 2 * mag_adaptive_grid) grid_radius = 0.3 npix = 400 _x = _y = np.linspace(-grid_radius, grid_radius, npix) resolution = 2 * grid_radius / npix xx, yy = np.meshgrid(_x, _y) for i in range(0, 4): beta_x, beta_y = lensmodel.ray_shooting(x_image[i] + xx.ravel(), y_image[i] + yy.ravel(), kwargs_lens) source_light_model = LightModel(['GAUSSIAN'] * 2) amp_scale, dx, dy, size_scale = 0.2, 0.005, -0.005, 1. kwargs_source = [{ 'amp': 1., 'center_x': source_x, 'center_y': source_y, 'sigma': source_sigma }, { 'amp': amp_scale, 'center_x': source_x + dx, 'center_y': source_y + dy, 'sigma': source_sigma * size_scale }] sb = source_light_model.surface_brightness(beta_x, beta_y, kwargs_source) magnification_double_gaussian_reference = np.sum( sb) * resolution**2 magnification_double_gaussian = extension.magnification_finite_adaptive( [x_image[i]], [y_image[i]], source_x, source_y, kwargs_lens, source_fwhm_parsec, z_source, cosmo=self.cosmo, source_light_model='DOUBLE_GAUSSIAN', dx=dx, dy=dy, amp_scale=amp_scale, size_scale=size_scale, grid_resolution=resolution, grid_radius_arcsec=grid_radius, axis_ratio=1.) npt.assert_almost_equal( magnification_double_gaussian / magnification_double_gaussian_reference, 1., 3) source_model = LightModel(['GAUSSIAN']) kwargs_source = [{ 'amp': 1., 'center_x': source_x, 'center_y': source_y, 'sigma': source_sigma }] r_min = 0. r_max = source_sigma * 0.9 flux_array = extension._magnification_adaptive_iteration( flux_array, x_image[0], y_image[0], grid_x, grid_y, grid_r, r_min, r_max, lensmodel, kwargs_lens, source_model, kwargs_source) bx, by = lensmodel.ray_shooting(x_image[0], y_image[0], kwargs_lens) sb_true = source_model.surface_brightness(bx, by, kwargs_source) npt.assert_equal(True, flux_array[0] == sb_true) npt.assert_equal(True, flux_array[1] == 0.) r_min = source_sigma * 0.9 r_max = 2 * source_sigma flux_array = extension._magnification_adaptive_iteration( flux_array, x_image[0], y_image[0], grid_x, grid_y, grid_r, r_min, r_max, lensmodel, kwargs_lens, source_model, kwargs_source) bx, by = lensmodel.ray_shooting(x_image[0] + source_sigma, y_image[0], kwargs_lens) sb_true = source_model.surface_brightness(bx, by, kwargs_source) npt.assert_equal(True, flux_array[1] == sb_true)
class LightParam(object): """ class manages the parameters corresponding to the LightModel() module. Also manages linear parameter handling. """ def __init__(self, light_model_list, kwargs_fixed, kwargs_lower=None, kwargs_upper=None, type='light', linear_solver=True): """ :param light_model_list: list of light models :param kwargs_fixed: list of keyword arguments corresponding to parameters held fixed during sampling :param kwargs_lower: list of keyword arguments indicating hard lower limit of the parameter space :param kwargs_upper: list of keyword arguments indicating hard upper limit of the parameter space :param type: string (optional), adding specifications in the output strings (such as lens light or source light) :param linear_solver: bool, if True fixes the linear amplitude parameters 'amp' (avoid sampling) such that they get overwritten by the linear solver solution. """ self._lightModel = LightModel(light_model_list=light_model_list) self._param_name_list = self._lightModel.param_name_list self._type = type self.model_list = light_model_list self.kwargs_fixed = kwargs_fixed if linear_solver: self.kwargs_fixed = self._lightModel.add_fixed_linear( self.kwargs_fixed) self._linear_solve = linear_solver if kwargs_lower is None: kwargs_lower = [] for func in self._lightModel.func_list: kwargs_lower.append(func.lower_limit_default) if kwargs_upper is None: kwargs_upper = [] for func in self._lightModel.func_list: kwargs_upper.append(func.upper_limit_default) self.lower_limit = kwargs_lower self.upper_limit = kwargs_upper @property def param_name_list(self): return self._param_name_list def getParams(self, args, i): """ :param args: list of floats corresponding ot the arguments being sampled :param i: int, index of the first argument that is managed/read-out by this class :return: keyword argument list of the light profile, index after reading out the arguments corresponding to this class """ kwargs_list = [] for k, model in enumerate(self.model_list): kwargs = {} kwargs_fixed = self.kwargs_fixed[k] param_names = self._param_name_list[k] for name in param_names: if not name in kwargs_fixed: if model in [ 'SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP' ] and name == 'amp': if 'n_max' in kwargs_fixed: n_max = kwargs_fixed['n_max'] else: raise ValueError('n_max needs to be fixed in %s.' % model) if model in ['SHAPELETS_POLAR_EXP']: num_param = int((n_max + 1)**2) else: num_param = int((n_max + 1) * (n_max + 2) / 2) kwargs['amp'] = args[i:i + num_param] i += num_param elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE' ] and name == 'amp': if 'sigma' in kwargs_fixed: num_param = len(kwargs_fixed['sigma']) else: raise ValueError('sigma needs to be fixed in %s.' % model) kwargs['amp'] = args[i:i + num_param] i += num_param elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2' ] and name == 'amp': if 'n_scales' in kwargs_fixed and 'n_pixels' in kwargs_fixed: n_scales = kwargs_fixed['n_scales'] n_pixels = kwargs_fixed['n_pixels'] else: raise ValueError( "'n_scales' and 'n_pixels' both need to be fixed in %s." % model) num_param = n_scales * n_pixels kwargs['amp'] = args[i:i + num_param] i += num_param else: kwargs[name] = args[i] i += 1 else: kwargs[name] = kwargs_fixed[name] kwargs_list.append(kwargs) return kwargs_list, i def setParams(self, kwargs_list): """ :param kwargs_list: list of keyword arguments of the light profile (free parameter as well as optionally the fixed ones) :return: list of floats corresponding to the free parameters """ args = [] for k, model in enumerate(self.model_list): kwargs = kwargs_list[k] kwargs_fixed = self.kwargs_fixed[k] param_names = self._param_name_list[k] for name in param_names: if not name in kwargs_fixed: if model in [ 'SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP' ] and name == 'amp': n_max = kwargs_fixed.get('n_max', kwargs['n_max']) if model in ['SHAPELETS_POLAR_EXP']: num_param = int((n_max + 1)**2) else: num_param = int((n_max + 1) * (n_max + 2) / 2) for i in range(num_param): args.append(kwargs[name][i]) elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2' ] and name == 'amp': if 'n_scales' in kwargs_fixed: n_scales = kwargs_fixed['n_scales'] else: raise ValueError( "'n_scales' for SLIT_STARLETS not found in kwargs_fixed" ) if 'n_pixels' in kwargs_fixed: n_pixels = kwargs_fixed['n_pixels'] else: raise ValueError( "'n_pixels' for SLIT_STARLETS not found in kwargs_fixed" ) num_param = n_scales * n_pixels for i in range(num_param): args.append(kwargs[name][i]) elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2' ] and name in [ 'n_scales', 'n_pixels', 'scale', 'center_x', 'center_y' ]: raise ValueError( "'{}' must be a fixed keyword argument for STARLETS-like models" .format(name)) elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE' ] and name == 'amp': num_param = len(kwargs['sigma']) for i in range(num_param): args.append(kwargs[name][i]) elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE' ] and name == 'sigma': raise ValueError( "'sigma' must be a fixed keyword argument for MULTI_GAUSSIAN" ) else: args.append(kwargs[name]) return args def num_param(self): """ :return: int, list of strings with param names """ num = 0 list = [] for k, model in enumerate(self.model_list): kwargs_fixed = self.kwargs_fixed[k] param_names = self._param_name_list[k] for name in param_names: if not name in kwargs_fixed: if model in [ 'SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP' ] and name == 'amp': if 'n_max' not in kwargs_fixed: raise ValueError( "n_max needs to be fixed in this configuration!" ) n_max = kwargs_fixed['n_max'] if model in ['SHAPELETS_POLAR_EXP']: num_param = int((n_max + 1)**2) else: num_param = int((n_max + 1) * (n_max + 2) / 2) num += num_param for i in range(num_param): list.append(str(name + '_' + self._type + str(k))) elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2' ] and name == 'amp': if 'n_scales' not in kwargs_fixed or 'n_pixels' not in kwargs_fixed: raise ValueError( "n_scales and n_pixels need to be fixed when using STARLETS-like models!" ) n_scales = kwargs_fixed['n_scales'] n_pixels = kwargs_fixed['n_pixels'] num_param = n_scales * n_pixels num += num_param for i in range(num_param): list.append(str(name + '_' + self._type + str(k))) elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE' ] and name == 'amp': num_param = len(kwargs_fixed['sigma']) num += num_param for i in range(num_param): list.append(str(name + '_' + self._type + str(k))) else: num += 1 list.append(str(name + '_' + self._type + str(k))) return num, list def num_param_linear(self): """ :return: number of linear basis set coefficients """ return self._lightModel.num_param_linear(kwargs_list=self.kwargs_fixed)
def setup(self): # data specifics sigma_bkg = 0.05 # background noise per pixel exp_time = 100 # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = 10 # cutout pixel size deltaPix = 0.1 # pixel size in arcsec (area per pixel = deltaPix**2) fwhm = 0.5 # full width half max of PSF # PSF specification kwargs_data = simulation_util.data_configure_simple( numPix, deltaPix, exp_time, sigma_bkg) data_class = ImageData(**kwargs_data) kwargs_psf = { 'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'pixel_size': deltaPix } psf_class = PSF(**kwargs_psf) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'e1': 0.1, 'e2': 0.1 } lens_model_list = ['SPEP'] kwargs_lens = [kwargs_spemd] lens_model_class = LensModel(lens_model_list=lens_model_list) 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': 3, 'center_x': 0, 'center_y': 0, 'e1': 0.1, 'e2': 0.1 } lens_light_model_list = ['SERSIC'] kwargs_lens_light = [kwargs_sersic] lens_light_model_class = LightModel( light_model_list=lens_light_model_list) source_model_list = ['SERSIC_ELLIPSE'] kwargs_source = [kwargs_sersic_ellipse] source_model_class = LightModel(light_model_list=source_model_list) # Point Source point_source_model_list = ['UNLENSED'] kwargs_ps = [{ 'ra_image': [0.4], 'dec_image': [-0.2], 'point_amp': [2] }] point_source_class = PointSource( point_source_type_list=point_source_model_list) kwargs_numerics = { 'supersampling_factor': 1, 'supersampling_convolution': False, 'compute_mode': 'regular' } imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class=point_source_class, kwargs_numerics=kwargs_numerics) image_sim = simulation_util.simulate_simple(imageModel, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps) data_class.update_data(image_sim) kwargs_data['image_data'] = image_sim self.multi_band_list = [[kwargs_data, kwargs_psf, kwargs_numerics]] self.kwargs_model = { 'lens_model_list': lens_model_list, 'source_light_model_list': source_model_list, 'lens_light_model_list': lens_light_model_list, 'point_source_model_list': point_source_model_list, 'fixed_magnification_list': [False], 'index_lens_model_list': [[0]], 'index_lens_light_model_list': [[0]], 'index_source_light_model_list': [[0]], 'index_point_source_model_list': [[0]], } self.kwargs_params = { 'kwargs_lens': kwargs_lens, 'kwargs_source': kwargs_source, 'kwargs_lens_light': kwargs_lens_light, 'kwargs_ps': kwargs_ps } self.single_band = SingleBandMultiModel( multi_band_list=self.multi_band_list, kwargs_model=self.kwargs_model, linear_solver=True) self.single_band_no_linear = SingleBandMultiModel( multi_band_list=self.multi_band_list, kwargs_model=self.kwargs_model, linear_solver=False)
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', ['NONE'])) sourceModel = LightModel( kwargs_options.get('source_light_model_list', ['NONE'])) lensModel = LensModel( lens_model_list=kwargs_options.get('lens_model_list', ['NONE'])) pointSource = PointSource( point_source_type_list=kwargs_options.get('point_source_list', ['NONE']), 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
class LightParam(object): """ """ def __init__(self, light_model_list, kwargs_fixed, kwargs_lower=None, kwargs_upper=None, type='light', linear_solver=True): self._lightModel = LightModel(light_model_list=light_model_list) self._param_name_list = self._lightModel.param_name_list self._type = type self.model_list = light_model_list self.kwargs_fixed = kwargs_fixed if linear_solver: self.kwargs_fixed = self._lightModel.add_fixed_linear(self.kwargs_fixed) self._linear_solve = linear_solver if kwargs_lower is None: kwargs_lower = [] for func in self._lightModel.func_list: kwargs_lower.append(func.lower_limit_default) if kwargs_upper is None: kwargs_upper = [] for func in self._lightModel.func_list: kwargs_upper.append(func.upper_limit_default) self.lower_limit = kwargs_lower self.upper_limit = kwargs_upper @property def param_name_list(self): return self._param_name_list def getParams(self, args, i): """ :param args: :param i: :return: """ kwargs_list = [] for k, model in enumerate(self.model_list): kwargs = {} kwargs_fixed = self.kwargs_fixed[k] param_names = self._param_name_list[k] for name in param_names: if not name in kwargs_fixed: if model in ['SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP'] and name == 'amp': if 'n_max' in kwargs_fixed: n_max = kwargs_fixed['n_max'] else: raise ValueError('n_max needs to be fixed in %s.' % model) if model in ['SHAPELETS_POLAR_EXP']: num_param = int((n_max + 1) ** 2) else: num_param = int((n_max + 1) * (n_max + 2) / 2) kwargs['amp'] = args[i:i + num_param] i += num_param elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE'] and name == 'amp': if 'sigma' in kwargs_fixed: num_param = len(kwargs_fixed['sigma']) else: raise ValueError('sigma needs to be fixed in %s.' % model) kwargs['amp'] = args[i:i + num_param] i += num_param elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2'] and name == 'amp': if 'n_scales' in kwargs_fixed and 'n_pixels' in kwargs_fixed: n_scales = kwargs_fixed['n_scales'] n_pixels = kwargs_fixed['n_pixels'] else: raise ValueError("'n_scales' and 'n_pixels' both need to be fixed in %s." % model) num_param = n_scales * n_pixels kwargs['amp'] = args[i:i + num_param] i += num_param else: kwargs[name] = args[i] i += 1 else: kwargs[name] = kwargs_fixed[name] kwargs_list.append(kwargs) return kwargs_list, i def setParams(self, kwargs_list): """ :param kwargs_list: :param bounds: bool, if True, ellitpicity of min/max :return: """ args = [] for k, model in enumerate(self.model_list): kwargs = kwargs_list[k] kwargs_fixed = self.kwargs_fixed[k] param_names = self._param_name_list[k] for name in param_names: if not name in kwargs_fixed: if model in ['SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP'] and name == 'amp': n_max = kwargs_fixed.get('n_max', kwargs['n_max']) if model in ['SHAPELETS_POLAR_EXP']: num_param = int((n_max + 1) ** 2) else: num_param = int((n_max + 1) * (n_max + 2) / 2) for i in range(num_param): args.append(kwargs[name][i]) elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2'] and name == 'amp': if 'n_scales' in kwargs_fixed: n_scales = kwargs_fixed['n_scales'] else: raise ValueError("'n_scakes' for SLIT_STARLETS not found in kwargs_fixed") if 'n_pixels' in kwargs_fixed: n_pixels = kwargs_fixed['n_pixels'] else: raise ValueError("'n_pixels' for SLIT_STARLETS not found in kwargs_fixed") num_param = n_scales * n_pixels for i in range(num_param): args.append(kwargs[name][i]) elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2'] and name in ['n_scales', 'n_pixels', 'scale', 'center_x', 'center_y']: raise ValueError("'{}' must be a fixed keyword argument for STARLETS-like models".format(name)) elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE'] and name == 'amp': num_param = len(kwargs['sigma']) for i in range(num_param): args.append(kwargs[name][i]) elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE'] and name == 'sigma': raise ValueError("'sigma' must be a fixed keyword argument for MULTI_GAUSSIAN") else: args.append(kwargs[name]) return args def num_param(self): """ :return: """ num = 0 list = [] for k, model in enumerate(self.model_list): kwargs_fixed = self.kwargs_fixed[k] param_names = self._param_name_list[k] for name in param_names: if not name in kwargs_fixed: if model in ['SHAPELETS', 'SHAPELETS_POLAR', 'SHAPELETS_POLAR_EXP'] and name == 'amp': if 'n_max' not in kwargs_fixed: raise ValueError("n_max needs to be fixed in this configuration!") n_max = kwargs_fixed['n_max'] if model in ['SHAPELETS_POLAR_EXP']: num_param = int((n_max + 1) ** 2) else: num_param = int((n_max + 1) * (n_max + 2) / 2) num += num_param for i in range(num_param): list.append(str(name + '_' + self._type + str(k))) elif model in ['SLIT_STARLETS', 'SLIT_STARLETS_GEN2'] and name == 'amp': if 'n_scales' not in kwargs_fixed or 'n_pixels' not in kwargs_fixed: raise ValueError("n_scales and n_pixels need to be fixed when using STARLETS-like models!") n_scales = kwargs_fixed['n_scales'] n_pixels = kwargs_fixed['n_pixels'] num_param = n_scales * n_pixels num += num_param for i in range(num_param): list.append(str(name + '_' + self._type + str(k))) elif model in ['MULTI_GAUSSIAN', 'MULTI_GAUSSIAN_ELLIPSE'] and name == 'amp': num_param = len(kwargs_fixed['sigma']) num += num_param for i in range(num_param): list.append(str(name + '_' + self._type + str(k))) else: num += 1 list.append(str(name + '_' + self._type + str(k))) return num, list def num_param_linear(self): """ :return: number of linear basis set coefficients """ return self._lightModel.num_param_linear(kwargs_list=self.kwargs_fixed)
def light2mass_interpol(lens_light_model_list, kwargs_lens_light, numPix=100, deltaPix=0.05, subgrid_res=5, center_x=0, center_y=0): """ takes a lens light model and turns it numerically in a lens model (with all lensmodel quantities computed on a grid). Then provides an interpolated grid for the quantities. :param kwargs_lens_light: lens light keyword argument list :param numPix: number of pixels per axis for the return interpolation :param deltaPix: interpolation/pixel size :param center_x: center of the grid :param center_y: center of the grid :param subgrid_res: subgrid for the numerical integrals :return: keyword arguments for 'INTERPOL' lens model """ # make super-sampled grid x_grid_sub, y_grid_sub = util.make_grid(numPix=numPix * 5, deltapix=deltaPix, subgrid_res=subgrid_res) import lenstronomy.Util.mask_util as mask_util mask = mask_util.mask_sphere(x_grid_sub, y_grid_sub, center_x, center_y, r=1) x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix) # compute light on the subgrid lightModel = LightModel(light_model_list=lens_light_model_list) flux = lightModel.surface_brightness(x_grid_sub, y_grid_sub, kwargs_lens_light) flux_norm = np.sum(flux[mask == 1]) / np.sum(mask) flux /= flux_norm from lenstronomy.LensModel import convergence_integrals as integral # compute lensing quantities with subgrid convergence_sub = util.array2image(flux) f_x_sub, f_y_sub = integral.deflection_from_kappa_grid( convergence_sub, grid_spacing=deltaPix / float(subgrid_res)) f_sub = integral.potential_from_kappa_grid(convergence_sub, grid_spacing=deltaPix / float(subgrid_res)) # interpolation function on lensing quantities x_axes_sub, y_axes_sub = util.get_axes(x_grid_sub, y_grid_sub) from lenstronomy.LensModel.Profiles.interpol import Interpol interp_func = Interpol() interp_func.do_interp(x_axes_sub, y_axes_sub, f_sub, f_x_sub, f_y_sub) # compute lensing quantities on sparser grid x_axes, y_axes = util.get_axes(x_grid, y_grid) f_ = interp_func.function(x_grid, y_grid) f_x, f_y = interp_func.derivatives(x_grid, y_grid) # numerical differentials for second order differentials from lenstronomy.LensModel.lens_model import LensModel lens_model = LensModel(lens_model_list=['INTERPOL']) kwargs = [{ 'grid_interp_x': x_axes_sub, 'grid_interp_y': y_axes_sub, 'f_': f_sub, 'f_x': f_x_sub, 'f_y': f_y_sub }] f_xx, f_xy, f_yx, f_yy = lens_model.hessian(x_grid, y_grid, kwargs, diff=0.00001) kwargs_interpol = { 'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': util.array2image(f_), 'f_x': util.array2image(f_x), 'f_y': util.array2image(f_y), 'f_xx': util.array2image(f_xx), 'f_xy': util.array2image(f_xy), 'f_yy': util.array2image(f_yy) } return kwargs_interpol
def setup(self): self.light_model_list = [ 'GAUSSIAN', 'MULTI_GAUSSIAN', 'SERSIC', 'SERSIC_ELLIPSE', 'CORE_SERSIC', 'SHAPELETS', 'HERNQUIST', 'HERNQUIST_ELLIPSE', 'PJAFFE', 'PJAFFE_ELLIPSE', 'UNIFORM', 'POWER_LAW', 'NIE', 'INTERPOL', 'SHAPELETS_POLAR_EXP', 'ELLIPSOID' ] phi_G, q = 0.5, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) self.kwargs = [ { 'amp': 1., 'sigma': 1., 'center_x': 0, 'center_y': 0 }, # 'GAUSSIAN' { 'amp': [1., 2], 'sigma': [1, 3], 'center_x': 0, 'center_y': 0 }, # 'MULTI_GAUSSIAN' { 'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'center_x': 0, 'center_y': 0 }, # 'SERSIC' { 'amp': 1, 'R_sersic': 0.5, 'n_sersic': 1, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0 }, # 'SERSIC_ELLIPSE' { 'amp': 1, 'R_sersic': 0.5, 'Re': 0.1, 'gamma': 2., 'n_sersic': 1, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0 }, # 'CORE_SERSIC' { 'amp': [1, 1, 1], 'beta': 0.5, 'n_max': 1, 'center_x': 0, 'center_y': 0 }, # 'SHAPELETS' { 'amp': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0 }, # 'HERNQUIST' { 'amp': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 }, # 'HERNQUIST_ELLIPSE' { 'amp': 1, 'Ra': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0 }, # 'PJAFFE' { 'amp': 1, 'Ra': 1, 'Rs': 0.5, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2 }, # 'PJAFFE_ELLIPSE' { 'amp': 1 }, # 'UNIFORM' { 'amp': 1., 'gamma': 2., 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0 }, # 'POWER_LAW' { 'amp': .001, 'e1': 0, 'e2': 1., 'center_x': 0, 'center_y': 0, 's_scale': 1. }, # 'NIE' { 'image': np.zeros((20, 5)), 'scale': 1, 'phi_G': 0, 'center_x': 0, 'center_y': 0 }, { 'amp': [1], 'n_max': 0, 'beta': 1, 'center_x': 0, 'center_y': 0 }, { 'amp': 1, 'radius': 1., 'e1': 0, 'e2': 0.1, 'center_x': 0, 'center_y': 0 } # 'ELLIPSOID' ] self.LightModel = LightModel(light_model_list=self.light_model_list)
def setup(self): self.SimAPI = Simulation() # 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 = self.SimAPI.data_configure(numPix, deltaPix, exp_time, sigma_bkg) data_class = Data(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_x=sigma, sigma_y=sigma, center_x=0, center_y=0) kernel_point_source /= np.sum(kernel_point_source) kernel_point_source = util.array2image(kernel_point_source) self.kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': kernel_point_source } psf_class = PSF(kwargs_psf=self.kwargs_psf) # 'EXERNAL_SHEAR': external shear kwargs_shear = { 'e1': 0.01, 'e2': 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 = {'subgrid_res': 3, 'psf_subgrid': True} 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 = self.SimAPI.simulate(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) data_class.update_data(image_sim) self.imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) kwargs_psf_iter = {'stacking_option': 'median'} self.psf_fitting = PsfFitting(self.imageModel, kwargs_psf_iter=kwargs_psf_iter)
def setup(self): self.SimAPI = Simulation() # data specifics sigma_bkg = 0.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 data_class = self.SimAPI.data_configure(numPix, deltaPix, exp_time, sigma_bkg) psf_class = self.SimAPI.psf_configure(psf_type='GAUSSIAN', fwhm=fwhm, kernelsize=31, deltaPix=deltaPix, truncate=3, kernel=None) psf_class = self.SimAPI.psf_configure( psf_type='PIXEL', fwhm=fwhm, kernelsize=31, deltaPix=deltaPix, truncate=6, kernel=psf_class.kernel_point_source) # '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_list = ['SOURCE_POSITION'] point_source_class = PointSource( point_source_type_list=point_source_list, fixed_magnification_list=[True]) kwargs_numerics = {'subgrid_res': 1, 'psf_subgrid': 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 = self.SimAPI.simulate(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps) data_class.update_data(image_sim) self.data_class = data_class self.psf_class = psf_class self.kwargs_data = data_class.constructor_kwargs() self.kwargs_psf = psf_class.constructor_kwargs() self.kwargs_model = { 'lens_model_list': lens_model_list, 'source_light_model_list': source_model_list, 'lens_light_model_list': lens_light_model_list, 'point_source_model_list': point_source_list, 'fixed_magnification_list': [False], } self.kwargs_numerics = {'subgrid_res': 2, 'psf_subgrid': True} num_source_model = len(source_model_list) self.kwargs_constraints = { 'joint_center_lens_light': False, 'joint_center_source_light': False, 'num_point_source_list': [4], 'additional_images_list': [False], 'fix_to_point_source_list': [False] * num_source_model, 'image_plane_source_list': [False] * num_source_model, 'solver': False, 'solver_type': 'PROFILE_SHEAR', # 'PROFILE', 'PROFILE_SHEAR', 'ELLIPSE', 'CENTER' } self.kwargs_likelihood = { 'force_no_add_image': True, 'source_marg': True, 'point_source_likelihood': False, 'position_uncertainty': 0.004, 'check_solver': True, 'solver_tolerance': 0.001 }
class LightProfile(object): """ class to deal with the light distribution """ def __init__(self, profile_list=['HERNQUIST'], kwargs_numerics={}): """ :param profile_list: """ self.light_model = LightModel(profile_type_list=profile_list, smoothing=0.001) self._interp_grid_num = kwargs_numerics.get('interpol_grid_num', 1000) self._max_interpolate = kwargs_numerics.get('max_interpolate', 100) self._min_interpolate = kwargs_numerics.get('min_interpolate', 0.0002) def light_3d(self, r, kwargs_list): """ :param kwargs_list: :return: """ light_3d = self.light_model.light_3d(r, kwargs_list) return light_3d def light_3d_interp(self, r, kwargs_list, new_compute=False): """ :param kwargs_list: :return: """ if not hasattr(self, '_f_light_3d') or new_compute is True: r_array = np.logspace(np.log10(self._min_interpolate), np.log10(self._max_interpolate), self._interp_grid_num) light_3d_array = self.light_model.light_3d(r_array, kwargs_list) light_3d_array[light_3d_array < 10**(-100)] = 10**(-100) f = interp1d(np.log(r_array), np.log(light_3d_array), fill_value="extrapolate") self._f_light_3d = f return np.exp(self._f_light_3d(np.log(r))) def light_2d(self, R, kwargs_list): """ :param R: :param kwargs_list: :return: """ kwargs_list_copy = copy.deepcopy(kwargs_list) kwargs_list_new = [] for kwargs in kwargs_list_copy: if 'q' in kwargs: kwargs['q'] = 1. kwargs_list_new.append({ k: v for k, v in kwargs.items() if not k in ['center_x', 'center_y'] }) return self.light_model.surface_brightness(R, 0, kwargs_list_new) def _integrand_light(self, R, kwargs_light): """ :param r: :param R: :param kwargs_light: :return: """ min_log = np.log10(self._min_interpolate) max_log = np.log10(self._max_interpolate) num = self._interp_grid_num r_array = np.logspace(min_log, max_log, num) dlogr = float(max_log - min_log) / num * np.log(10) r_ = np.sqrt(r_array**2 + R**2) return np.sum( self.light_3d_interp(r_, kwargs_light) * r_array) * 2 * dlogr def draw_light_2d_linear(self, kwargs_list, n=1, new_compute=False, r_eff=1.): """ constructs the CDF and draws from it random realizations of projected radii R :param kwargs_list: :return: """ if not hasattr(self, '_light_cdf') or new_compute is True: r_array = np.linspace(0., self._max_interpolate, self._interp_grid_num) cum_sum = np.zeros_like(r_array) sum = 0 for i, r in enumerate(r_array): if i == 0: cum_sum[i] = 0 else: sum += self.light_2d(r, kwargs_list) * r cum_sum[i] = copy.deepcopy(sum) cum_sum_norm = cum_sum / cum_sum[-1] f = interp1d(cum_sum_norm, r_array) self._light_cdf = f cdf_draw = np.random.uniform(0., 1, n) r_draw = self._light_cdf(cdf_draw) return r_draw def draw_light_2d(self, kwargs_list, n=1, new_compute=False, r_eff=1.): """ constructs the CDF and draws from it random realizations of projected radii R :param kwargs_list: :return: """ if not hasattr(self, '_light_cdf_log') or new_compute is True: r_array = np.logspace(np.log10(self._min_interpolate), np.log10(self._max_interpolate), self._interp_grid_num) cum_sum = np.zeros_like(r_array) sum = 0 for i, r in enumerate(r_array): if i == 0: cum_sum[i] = 0 else: sum += self.light_2d(r, kwargs_list) * r * r cum_sum[i] = copy.deepcopy(sum) cum_sum_norm = cum_sum / cum_sum[-1] f = interp1d(cum_sum_norm, np.log(r_array)) self._light_cdf_log = f cdf_draw = np.random.uniform(0., 1, n) r_log_draw = self._light_cdf_log(cdf_draw) return np.exp(r_log_draw)
def create_class_instances(lens_model_list=[], z_lens=None, z_source=None, lens_redshift_list=None, multi_plane=False, observed_convention_index=None, source_light_model_list=[], lens_light_model_list=[], point_source_model_list=[], fixed_magnification_list=None, additional_images_list=None, min_distance=0.01, search_window=5, precision_limit=10**(-10), num_iter_max=100, source_deflection_scaling_list=None, source_redshift_list=None, cosmo=None, index_lens_model_list=None, index_source_light_model_list=None, index_lens_light_model_list=None, index_point_source_model_list=None, optical_depth_model_list=[], index_optical_depth_model_list=None, band_index=0, tau0_index_list=None, all_models=False, point_source_magnification_limit=None): """ :param lens_model_list: list of strings indicating the type of lens models :param z_lens: redshift of the deflector (for single lens plane mode, but only relevant when computing physical quantities) :param z_source: redshift of source (for single source plane mode, or for multiple source planes the redshift of the point source). In regard to this redshift the reduced deflection angles are defined in the lens model. :param lens_redshift_list: :param multi_plane: :param observed_convention_index: :param source_light_model_list: :param lens_light_model_list: :param point_source_model_list: :param fixed_magnification_list: :param additional_images_list: :param min_distance: :param search_window: :param precision_limit: :param num_iter_max: :param source_deflection_scaling_list: :param source_redshift_list: :param cosmo: :param index_lens_model_list: :param index_source_light_model_list: :param index_lens_light_model_list: :param index_point_source_model_list: :param optical_depth_model_list: list of strings indicating the optical depth model to compute (differential) extinctions from the source :param band_index: int, index of band to consider. Has an effect if only partial models are considered for a specific band :param tau0_index_list: list of integers of the specific extinction scaling parameter tau0 for each band :param all_models: bool, if True, will make class instances of all models ignoring potential keywords that are excluding specific models as indicated. :param point_source_magnification_limit: float >0 or None, if set and additional images are computed, then it will cut the point sources computed to the limiting (absolute) magnification :return: """ if index_lens_model_list is None or all_models is True: lens_model_list_i = lens_model_list lens_redshift_list_i = lens_redshift_list observed_convention_index_i = observed_convention_index else: lens_model_list_i = [lens_model_list[k] for k in index_lens_model_list[band_index]] if lens_redshift_list is not None: lens_redshift_list_i = [lens_redshift_list[k] for k in index_lens_model_list[band_index]] else: lens_redshift_list_i = lens_redshift_list if observed_convention_index is not None: counter = 0 observed_convention_index_i = [] for k in index_lens_model_list[band_index]: if k in observed_convention_index: observed_convention_index_i.append(counter) counter += 1 else: observed_convention_index_i = observed_convention_index lens_model_class = LensModel(lens_model_list=lens_model_list_i, z_lens=z_lens, z_source=z_source, lens_redshift_list=lens_redshift_list_i, multi_plane=multi_plane, cosmo=cosmo, observed_convention_index=observed_convention_index_i) if index_source_light_model_list is None or all_models is True: source_light_model_list_i = source_light_model_list source_deflection_scaling_list_i = source_deflection_scaling_list source_redshift_list_i = source_redshift_list else: source_light_model_list_i = [source_light_model_list[k] for k in index_source_light_model_list[band_index]] if source_deflection_scaling_list is None: source_deflection_scaling_list_i = source_deflection_scaling_list else: source_deflection_scaling_list_i = [source_deflection_scaling_list[k] for k in index_source_light_model_list[band_index]] if source_redshift_list is None: source_redshift_list_i = source_redshift_list else: source_redshift_list_i = [source_redshift_list[k] for k in index_source_light_model_list[band_index]] source_model_class = LightModel(light_model_list=source_light_model_list_i, deflection_scaling_list=source_deflection_scaling_list_i, source_redshift_list=source_redshift_list_i) if index_lens_light_model_list is None or all_models is True: lens_light_model_list_i = lens_light_model_list else: lens_light_model_list_i = [lens_light_model_list[k] for k in index_lens_light_model_list[band_index]] lens_light_model_class = LightModel(light_model_list=lens_light_model_list_i) point_source_model_list_i = point_source_model_list fixed_magnification_list_i = fixed_magnification_list additional_images_list_i = additional_images_list if index_point_source_model_list is not None and not all_models: point_source_model_list_i = [point_source_model_list[k] for k in index_point_source_model_list[band_index]] if fixed_magnification_list is not None: fixed_magnification_list_i = [fixed_magnification_list[k] for k in index_point_source_model_list[band_index]] if additional_images_list is not None: additional_images_list_i = [additional_images_list[k] for k in index_point_source_model_list[band_index]] point_source_class = PointSource(point_source_type_list=point_source_model_list_i, lensModel=lens_model_class, fixed_magnification_list=fixed_magnification_list_i, additional_images_list=additional_images_list_i, min_distance=min_distance, search_window=search_window, precision_limit=precision_limit, num_iter_max=num_iter_max, magnification_limit=point_source_magnification_limit) if tau0_index_list is None: tau0_index = 0 else: tau0_index = tau0_index_list[band_index] if index_optical_depth_model_list is not None: optical_depth_model_list_i = [optical_depth_model_list[k] for k in index_optical_depth_model_list[band_index]] else: optical_depth_model_list_i = optical_depth_model_list extinction_class = DifferentialExtinction(optical_depth_model=optical_depth_model_list_i, tau0_index=tau0_index) return lens_model_class, source_model_class, lens_light_model_class, point_source_class, extinction_class
def test_init(self): model_list = ['CORE_SERSIC', 'DOUBLE_CORE_SERSIC', 'BULDGE_DISK', 'SHAPELETS', 'UNIFORM'] lightModel = LightModel(light_model_list=model_list) assert len(lightModel.profile_type_list) == len(model_list)
def test_raise(self): with self.assertRaises(ValueError): lighModel = LightModel(light_model_list=['WRONG']) with self.assertRaises(ValueError): lighModel = LightModel(light_model_list=['UNIFORM']) lighModel.light_3d(r=1, kwargs_list=[{'amp': 1}]) with self.assertRaises(ValueError): lighModel = LightModel(light_model_list=['UNIFORM']) lighModel.profile_type_list = ['WRONG'] lighModel.functions_split(x=0, y=0, kwargs_list=[{}]) with self.assertRaises(ValueError): lighModel = LightModel(light_model_list=['UNIFORM']) lighModel.profile_type_list = ['WRONG'] lighModel.num_param_linear(kwargs_list=[{}]) with self.assertRaises(ValueError): lighModel = LightModel(light_model_list=['UNIFORM']) lighModel.profile_type_list = ['WRONG'] lighModel.update_linear(param=[1], i=0, kwargs_list=[{}]) with self.assertRaises(ValueError): lighModel = LightModel(light_model_list=['UNIFORM']) lighModel.profile_type_list = ['WRONG'] lighModel.total_flux(kwargs_list=[{}])
def create_class_instances(lens_model_list=[], z_lens=None, z_source=None, lens_redshift_list=None, multi_plane=False, source_light_model_list=[], lens_light_model_list=[], point_source_model_list=[], fixed_magnification_list=None, additional_images_list=None, min_distance=0.01, search_window=5, precision_limit=10**(-10), num_iter_max=100, source_deflection_scaling_list=None, source_redshift_list=None, cosmo=None, index_lens_model_list=None, index_source_light_model_list=None, index_lens_light_model_list=None, index_point_source_model_list=None, band_index=0): """ :param lens_model_list: :param z_lens: :param z_source: :param lens_redshift_list: :param multi_plane: :param source_light_model_list: :param lens_light_model_list: :param point_source_model_list: :param fixed_magnification_list: :param additional_images_list: :param min_distance: :param search_window: :param precision_limit: :param num_iter_max: :param source_deflection_scaling_list: :param source_redshift_list: :param cosmo: :param index_lens_model_list: :param index_source_light_model_list: :param index_lens_light_model_list: :param index_point_source_model_list: :return: """ if index_lens_model_list is None: lens_model_list_i = lens_model_list lens_redshift_list_i = lens_redshift_list else: lens_model_list_i = [ lens_model_list[k] for k in index_lens_model_list[band_index] ] if lens_redshift_list is not None: lens_redshift_list_i = [ lens_redshift_list[k] for k in index_lens_model_list[band_index] ] else: lens_redshift_list_i = lens_redshift_list lens_model_class = LensModel(lens_model_list=lens_model_list_i, z_lens=z_lens, z_source=z_source, lens_redshift_list=lens_redshift_list_i, multi_plane=multi_plane, cosmo=cosmo) if index_source_light_model_list is None: source_light_model_list_i = source_light_model_list source_deflection_scaling_list_i = source_deflection_scaling_list source_redshift_list_i = source_redshift_list else: source_light_model_list_i = [ source_light_model_list[k] for k in index_source_light_model_list[band_index] ] if source_deflection_scaling_list is None: source_deflection_scaling_list_i = source_deflection_scaling_list else: source_deflection_scaling_list_i = [ source_deflection_scaling_list[k] for k in index_source_light_model_list[band_index] ] if source_redshift_list is None: source_redshift_list_i = source_redshift_list else: source_redshift_list_i = [ source_redshift_list[k] for k in index_source_light_model_list[band_index] ] source_model_class = LightModel( light_model_list=source_light_model_list_i, deflection_scaling_list=source_deflection_scaling_list_i, source_redshift_list=source_redshift_list_i) if index_lens_light_model_list is None: lens_light_model_list_i = lens_light_model_list else: lens_light_model_list_i = [ lens_light_model_list[k] for k in index_lens_light_model_list[band_index] ] lens_light_model_class = LightModel( light_model_list=lens_light_model_list_i) point_source_model_list_i = point_source_model_list fixed_magnification_list_i = fixed_magnification_list additional_images_list_i = additional_images_list if index_point_source_model_list is not None: point_source_model_list_i = [ point_source_model_list[k] for k in index_point_source_model_list[band_index] ] if fixed_magnification_list is not None: fixed_magnification_list_i = [ fixed_magnification_list[k] for k in index_point_source_model_list[band_index] ] if additional_images_list is not None: additional_images_list_i = [ additional_images_list[k] for k in index_point_source_model_list[band_index] ] point_source_class = PointSource( point_source_type_list=point_source_model_list_i, lensModel=lens_model_class, fixed_magnification_list=fixed_magnification_list_i, additional_images_list=additional_images_list_i, min_distance=min_distance, search_window=search_window, precision_limit=precision_limit, num_iter_max=num_iter_max) return lens_model_class, source_model_class, lens_light_model_class, point_source_class
def setup(self): # data specifics sigma_bkg = 0.05 # background noise per pixel exp_time = 100 # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = 10 # cutout pixel size deltaPix = 0.1 # 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) data_class = ImageData(**kwargs_data) kwargs_psf_gaussian = { 'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'pixel_size': deltaPix } psf = PSF(**kwargs_psf_gaussian) kwargs_psf = { 'psf_type': 'PIXEL', 'kernel_point_source': psf.kernel_point_source } psf_class = PSF(**kwargs_psf) kwargs_spemd = { 'theta_E': 1., 'gamma': 1.8, 'center_x': 0, 'center_y': 0, 'e1': 0.1, 'e2': 0.1 } lens_model_list = ['SPEP'] self.kwargs_lens = [kwargs_spemd] lens_model_class = LensModel(lens_model_list=lens_model_list) 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': 3, 'center_x': 0, 'center_y': 0, 'e1': 0.1, 'e2': 0.1 } 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) kwargs_numerics = { 'supersampling_factor': 1, 'supersampling_convolution': False, 'compute_mode': 'regular' } imageModel = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, kwargs_numerics=kwargs_numerics) image_sim = sim_util.simulate_simple(imageModel, self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light) data_class.update_data(image_sim) kwargs_data['image_data'] = image_sim kwargs_data_joint = { 'multi_band_list': [[kwargs_data, kwargs_psf, kwargs_numerics]], 'multi_band_type': 'single-band' } self.data_class = data_class self.psf_class = psf_class kwargs_model = { 'lens_model_list': lens_model_list, 'source_light_model_list': source_model_list, 'lens_light_model_list': lens_light_model_list, 'fixed_magnification_list': [False], } self.kwargs_numerics = {'subgrid_res': 1, 'psf_subgrid': False} kwargs_constraints = { 'image_plane_source_list': [False] * len(source_model_list) } kwargs_likelihood = { 'source_marg': True, 'position_uncertainty': 0.004, 'check_solver': False, 'solver_tolerance': 0.001, } self.param_class = Param(kwargs_model, **kwargs_constraints) self.Likelihood = LikelihoodModule(kwargs_data_joint=kwargs_data_joint, kwargs_model=kwargs_model, param_class=self.param_class, **kwargs_likelihood) self.sampler = Sampler(likelihoodModule=self.Likelihood)
def setup(self): self.num_pix = 25 # cutout pixel size delta_pix = 0.24 _, _, ra_at_xy_0, dec_at_xy_0, _, _, Mpix2coord, _ \ = l_util.make_grid_with_coordtransform(numPix=self.num_pix, deltapix=delta_pix, subgrid_res=1, inverse=False, left_lower=False) kwargs_data = { #'background_rms': background_rms, #'exposure_time': np.ones((self.num_pix, self.num_pix)) * exp_time, # individual exposure time/weight per pixel 'ra_at_xy_0': ra_at_xy_0, 'dec_at_xy_0': dec_at_xy_0, 'transform_pix2angle': Mpix2coord, 'image_data': np.zeros((self.num_pix, self.num_pix)) } self.data = ImageData(**kwargs_data) self.lens_model = LensModel(['SPEP']) self.kwargs_lens = [{ 'theta_E': 1, 'gamma': 2, 'center_x': 0, 'center_y': 0, 'e1': -0.05, 'e2': 0.05 }] self.kwargs_lens_null = [{ 'theta_E': 0, 'gamma': 2, 'center_x': 0, 'center_y': 0, 'e1': 0, 'e2': 0 }] # PSF specification kwargs_psf = {'psf_type': 'NONE'} self.psf = PSF(**kwargs_psf) # list of source light profiles source_model_list = ['SERSIC_ELLIPSE'] kwargs_sersic_ellipse_source = { 'amp': 2000, 'R_sersic': 0.6, 'n_sersic': 1, 'e1': 0.1, 'e2': 0.1, 'center_x': 0.3, 'center_y': 0.3 } kwargs_source = [kwargs_sersic_ellipse_source] source_model = LightModel(light_model_list=source_model_list) # list of lens light profiles lens_light_model_list = [] kwargs_lens_light = [{}] lens_light_model = LightModel(light_model_list=lens_light_model_list) kwargs_numerics = { 'supersampling_factor': 1, 'supersampling_convolution': False } self.image_model = ImageModel(self.data, self.psf, self.lens_model, source_model, lens_light_model, point_source_class=None, kwargs_numerics=kwargs_numerics) self.image_grid_class = self.image_model.ImageNumerics.grid_class self.source_grid_class_default = NumericsSubFrame(self.data, self.psf).grid_class # create simulated image image_sim_no_noise = self.image_model.image(self.kwargs_lens, kwargs_source, kwargs_lens_light) self.source_light_lensed = image_sim_no_noise self.data.update_data(image_sim_no_noise) # source only, in source plane, on same grid as data self.source_light_delensed = self.image_model.source_surface_brightness( kwargs_source, unconvolved=False, de_lensed=True) # define some auto mask for tests self.likelihood_mask = np.zeros_like(self.source_light_lensed) self.likelihood_mask[self.source_light_lensed > 0.1 * self.source_light_lensed.max()] = 1
def __init__(self, kwargs_model, kwargs_fixed_lens=None, kwargs_fixed_source=None, kwargs_fixed_lens_light=None, kwargs_fixed_ps=None, kwargs_fixed_cosmo=None, kwargs_lower_lens=None, kwargs_lower_source=None, kwargs_lower_lens_light=None, kwargs_lower_ps=None, kwargs_lower_cosmo=None, kwargs_upper_lens=None, kwargs_upper_source=None, kwargs_upper_lens_light=None, kwargs_upper_ps=None, kwargs_upper_cosmo=None, kwargs_lens_init=None, linear_solver=True, joint_lens_with_lens=[], joint_lens_light_with_lens_light=[], joint_source_with_source=[], joint_lens_with_light=[], joint_source_with_point_source=[], joint_lens_light_with_point_source=[], mass_scaling_list=None, point_source_offset=False, num_point_source_list=None, image_plane_source_list=None, solver_type='NONE', cosmo_type=None): """ :return: """ self._lens_model_list = kwargs_model.get('lens_model_list', []) self._source_light_model_list = kwargs_model.get('source_light_model_list', []) self._lens_light_model_list = kwargs_model.get('lens_light_model_list', []) self._point_source_model_list = kwargs_model.get('point_source_model_list', []) lensModel = LensModel(lens_model_list=self._lens_model_list, z_source=kwargs_model.get('z_source', None), lens_redshift_list=kwargs_model.get('redshift_list', None), multi_plane=kwargs_model.get('multi_plane', False)) sourceModel = LightModel(light_model_list=self._source_light_model_list, deflection_scaling_list=kwargs_model.get('source_deflection_scaling_list', None), source_redshift_list=kwargs_model.get('source_redshift_list', None)) self._image2SourceMapping = Image2SourceMapping(lensModel=lensModel, sourceModel=sourceModel) if kwargs_fixed_lens is None: kwargs_fixed_lens = [{} for i in range(len(self._lens_model_list))] if kwargs_fixed_source is None: kwargs_fixed_source = [{} for i in range(len(self._source_light_model_list))] if kwargs_fixed_lens_light is None: kwargs_fixed_lens_light = [{} for i in range(len(self._lens_light_model_list))] if kwargs_fixed_ps is None: kwargs_fixed_ps = [{} for i in range(len(self._point_source_model_list))] if kwargs_fixed_cosmo is None: kwargs_fixed_cosmo = {} self._joint_lens_with_lens = joint_lens_with_lens self._joint_lens_light_with_lens_light = joint_lens_light_with_lens_light self._joint_source_with_source = joint_source_with_source self._joint_lens_with_light = joint_lens_with_light self._joint_source_with_point_source = copy.deepcopy(joint_source_with_point_source) for param_list in self._joint_source_with_point_source: if len(param_list) == 2: param_list.append(['center_x', 'center_y']) self._joint_lens_light_with_point_source = copy.deepcopy(joint_lens_light_with_point_source) for param_list in self._joint_lens_light_with_point_source: if len(param_list) == 2: param_list.append(['center_x', 'center_y']) if mass_scaling_list is None: mass_scaling_list = [False] * len(self._lens_model_list) self._mass_scaling_list = mass_scaling_list if 1 in self._mass_scaling_list: self._num_scale_factor = np.max(self._mass_scaling_list) self._mass_scaling = True else: self._num_scale_factor = 0 self._mass_scaling = False self._point_source_offset = point_source_offset if num_point_source_list is None: num_point_source_list = [1] * len(self._point_source_model_list) # Attention: if joint coordinates with other source profiles, only indicate one as bool if image_plane_source_list is None: image_plane_source_list = [False] * len(self._source_light_model_list) self._image_plane_source_list = image_plane_source_list try: self._num_images = num_point_source_list[0] except: self._num_images = 0 self._solver_type = solver_type if self._solver_type == 'NONE': self._solver = False else: self._solver = True self._solver_module = Solver(solver_type=self._solver_type, lensModel=lensModel, num_images=self._num_images) # fix parameters joint within the same model types kwargs_fixed_lens_updated = self._add_fixed_lens(kwargs_fixed_lens, kwargs_lens_init) kwargs_fixed_lens_updated = self._fix_joint_param(kwargs_fixed_lens_updated, self._joint_lens_with_lens) kwargs_fixed_lens_light_updated = self._fix_joint_param(kwargs_fixed_lens_light, self._joint_lens_light_with_lens_light) kwargs_fixed_source_updated = self._fix_joint_param(kwargs_fixed_source, self._joint_source_with_source) kwargs_fixed_ps_updated = copy.deepcopy(kwargs_fixed_ps) # fix parameters joint with other model types kwargs_fixed_lens_updated = self._fix_joint_param(kwargs_fixed_lens_updated, self._joint_lens_with_light) kwargs_fixed_source_updated = self._fix_joint_param(kwargs_fixed_source_updated, self._joint_source_with_point_source) kwargs_fixed_lens_light_updated = self._fix_joint_param(kwargs_fixed_lens_light_updated, self._joint_lens_light_with_point_source) self.lensParams = LensParam(self._lens_model_list, kwargs_fixed_lens_updated, num_images=self._num_images, solver_type=self._solver_type, kwargs_lower=kwargs_lower_lens, kwargs_upper=kwargs_upper_lens) self.lensLightParams = LightParam(self._lens_light_model_list, kwargs_fixed_lens_light_updated, type='lens_light', linear_solver=linear_solver, kwargs_lower=kwargs_lower_lens_light, kwargs_upper=kwargs_upper_lens_light) self.souceParams = LightParam(self._source_light_model_list, kwargs_fixed_source_updated, type='source_light', linear_solver=linear_solver, kwargs_lower=kwargs_lower_source, kwargs_upper=kwargs_upper_source) self.pointSourceParams = PointSourceParam(self._point_source_model_list, kwargs_fixed_ps_updated, num_point_source_list=num_point_source_list, linear_solver=linear_solver, kwargs_lower=kwargs_lower_ps, kwargs_upper=kwargs_upper_ps) self.cosmoParams = CosmoParam(cosmo_type=cosmo_type, mass_scaling=self._mass_scaling, kwargs_fixed=kwargs_fixed_cosmo, num_scale_factor=self._num_scale_factor, kwargs_lower=kwargs_lower_cosmo, kwargs_upper=kwargs_upper_cosmo, point_source_offset=self._point_source_offset, num_images=self._num_images)
def setup(self): # data specifics sigma_bkg = 0.05 # background noise per pixel exp_time = 100 # exposure time (arbitrary units, flux per pixel is in units #photons/exp_time unit) numPix = 10 # cutout pixel size deltaPix = 0.5 # pixel size in arcsec (area per pixel = deltaPix**2) fwhm = 0.5 # full width half max of PSF # PSF specification self.kwargs_data = sim_util.data_configure_simple( numPix, deltaPix, exp_time, sigma_bkg) data_class = ImageData(**self.kwargs_data) self.kwargs_psf = { 'psf_type': 'GAUSSIAN', 'fwhm': fwhm, 'truncation': 5, 'pixel_size': deltaPix } 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) 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) self.LensModel = lens_model_class # 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': 1. } ] # quasar point source position in the source plane and intrinsic brightness point_source_list = ['SOURCE_POSITION'] point_source_class = PointSource( point_source_type_list=point_source_list, fixed_magnification_list=[True]) kwargs_numerics = {'supersampling_factor': 1} 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, no_noise=True) data_class.update_data(image_sim) self.kwargs_data['image_data'] = image_sim self.kwargs_model = { 'lens_model_list': lens_model_list, 'source_light_model_list': source_model_list, 'lens_light_model_list': lens_light_model_list, 'point_source_model_list': point_source_list, 'fixed_magnification_list': [False], } self.kwargs_numerics = kwargs_numerics self.data_class = ImageData(**self.kwargs_data) 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_mge_hernquist_light(self): """ compare power-law profiles analytical vs. numerical :return: """ # anisotropy profile anisotropy_type = 'OsipkovMerritt' r_ani = 2. kwargs_anisotropy = {'r_ani': r_ani} # anisotropy radius [arcsec] # aperture as slit aperture_type = 'slit' length = 3.8 width = 0.9 kwargs_aperture = { 'length': length, 'width': width, 'center_ra': 0, 'center_dec': 0, 'angle': 0 } psf_fwhm = 0.7 # Gaussian FWHM psf kwargs_cosmo = {'D_d': 1000, 'D_s': 1500, 'D_ds': 800} # light profile light_profile_list = ['HERNQUIST'] r_eff = 1.8 kwargs_light = [{ 'Rs': r_eff, 'sigma0': 1. }] # effective half light radius (2d projected) in arcsec # mge of light profile lightModel = LightModel(light_profile_list) r_array = np.logspace(-2, 2, 100) flux_r = lightModel.surface_brightness(r_array, 0, kwargs_light) amps, sigmas, norm = mge.mge_1d(r_array, flux_r, N=20) light_profile_list_mge = ['MULTI_GAUSSIAN'] kwargs_light_mge = [{'amp': amps, 'sigma': sigmas}] # mass profile mass_profile_list = ['SPP'] theta_E = 1.2 gamma = 2. kwargs_profile = [{ 'theta_E': theta_E, 'gamma': gamma }] # Einstein radius (arcsec) and power-law slope galkin = Galkin(mass_profile_list, light_profile_list, aperture_type=aperture_type, anisotropy_model=anisotropy_type, fwhm=psf_fwhm, kwargs_cosmo=kwargs_cosmo) sigma_v = galkin.vel_disp(kwargs_profile, kwargs_light, kwargs_anisotropy, kwargs_aperture) galkin = Galkin(mass_profile_list, light_profile_list_mge, aperture_type=aperture_type, anisotropy_model=anisotropy_type, fwhm=psf_fwhm, kwargs_cosmo=kwargs_cosmo) sigma_v2 = galkin.vel_disp(kwargs_profile, kwargs_light_mge, kwargs_anisotropy, kwargs_aperture) print(sigma_v, sigma_v2, 'sigma_v Galkin, sigma_v MGEn') print((sigma_v / sigma_v2)**2) npt.assert_almost_equal((sigma_v - sigma_v2) / sigma_v2, 0, decimal=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) data_class = Data(kwargs_data) kwargs_psf = sim_util.psf_configure_simple(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) 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.0001, '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} 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) kwargs_data['image_data'] = image_sim self.solver = LensEquationSolver(lensModel=lens_model_class) idex_lens_1 = [0, 1] idex_lens_2 = [2, 3] multi_band_list = [[ kwargs_data, kwargs_psf, kwargs_numerics, { 'index_lens_model_list': idex_lens_1 } ], [ kwargs_data, kwargs_psf, kwargs_numerics, { 'index_lens_model_list': idex_lens_2 } ]] lens_model_list_joint = lens_model_list + lens_model_list self.kwargs_lens_joint = self.kwargs_lens + self.kwargs_lens self.imageModel = MultiFrame(multi_band_list, lens_model_list_joint, source_model_class, lens_light_model_class, point_source_class)