def test_multinest(self):
        # Nested sampler tests
        # further decrease the parameter space for nested samplers to run faster

        fittingSequence = FittingSequence(self.kwargs_data_joint,
                                          self.kwargs_model,
                                          self.kwargs_constraints,
                                          self.kwargs_likelihood,
                                          self.kwargs_params)
        fitting_list = []
        kwargs_update = {
            'ps_add_fixed': [[0, ['ra_source', 'dec_source'], [0, 0]]],
            'lens_light_add_fixed': [[
                0, ['n_sersic', 'R_sersic', 'center_x', 'center_y'],
                [4, .1, 0, 0]
            ]],
            'source_add_fixed': [[
                0, ['R_sersic', 'e1', 'e2', 'center_x', 'center_y'],
                [.6, .1, .1, 0, 0]
            ]],
            'lens_add_fixed': [[
                0, ['gamma', 'theta_E', 'e1', 'e2', 'center_x', 'center_y'],
                [1.8, 1., .1, .1, 0, 0]
            ], [1, ['gamma1', 'gamma2'], [0.01, 0.01]]],
            'change_source_lower_limit': [[0, ['n_sersic'], [2.9]]],
            'change_source_upper_limit': [[0, ['n_sersic'], [3.1]]]
        }
        fitting_list.append(['update_settings', kwargs_update])
        kwargs_multinest = {
            'sampler_type': 'MULTINEST',
            'kwargs_run': {
                'n_live_points': 10,
                'evidence_tolerance': 0.5,
                'sampling_efficiency':
                0.8,  # 1 for posterior-only, 0 for evidence-only
                'importance_nested_sampling': False,
                'multimodal': True,
                'const_efficiency_mode':
                False,  # reduce sampling_efficiency to 5% when True
            },
            'remove_output_dir': True,
        }
        fitting_list.append(['nested_sampling', kwargs_multinest])

        chain_list2 = fittingSequence.fit_sequence(fitting_list)
        kwargs_fixed = fittingSequence._updateManager.fixed_kwargs
        npt.assert_almost_equal(kwargs_fixed[0][1]['gamma1'], 0.01, decimal=2)
        assert fittingSequence._updateManager._lower_kwargs[1][0][
            'n_sersic'] == 2.9
        assert fittingSequence._updateManager._upper_kwargs[1][0][
            'n_sersic'] == 3.1

        kwargs_test = {'kwargs_lens': 1}
        fittingSequence.update_state(kwargs_test)
        kwargs_out = fittingSequence.best_fit(bijective=True)
        assert kwargs_out['kwargs_lens'] == 1
Esempio n. 2
0
    def test_fitting_sequence(self):
        # kwargs_init = [self.kwargs_lens, self.kwargs_source, self.kwargs_lens_light, self.kwargs_ps]
        lens_sigma = [{
            'theta_E': 0.1,
            'gamma': 0.1,
            'e1': 0.1,
            'e2': 0.1,
            'center_x': 0.1,
            'center_y': 0.1
        }, {
            'e1': 0.1,
            'e2': 0.1
        }]
        lens_lower = [{
            'theta_E': 0.,
            'gamma': 1.5,
            'center_x': -2,
            'center_y': -2,
            'e1': -0.4,
            'e2': -0.4
        }, {
            'e1': -0.3,
            'e2': -0.3
        }]
        lens_upper = [{
            'theta_E': 10.,
            'gamma': 2.5,
            'center_x': 2,
            'center_y': 2,
            'e1': 0.4,
            'e2': 0.4
        }, {
            'e1': 0.3,
            'e2': 0.3
        }]
        source_sigma = [{
            'R_sersic': 0.05,
            'n_sersic': 0.5,
            'center_x': 0.1,
            'center_y': 0.1,
            'e1': 0.1,
            'e2': 0.1
        }]
        source_lower = [{
            'R_sersic': 0.01,
            'n_sersic': 0.5,
            'center_x': -2,
            'center_y': -2,
            'e1': -0.4,
            'e2': -0.4
        }]
        source_upper = [{
            'R_sersic': 10,
            'n_sersic': 5.5,
            'center_x': 2,
            'center_y': 2,
            'e1': 0.4,
            'e2': 0.4
        }]

        lens_light_sigma = [{
            'R_sersic': 0.05,
            'n_sersic': 0.5,
            'center_x': 0.1,
            'center_y': 0.1
        }]
        lens_light_lower = [{
            'R_sersic': 0.01,
            'n_sersic': 0.5,
            'center_x': -2,
            'center_y': -2
        }]
        lens_light_upper = [{
            'R_sersic': 10,
            'n_sersic': 5.5,
            'center_x': 2,
            'center_y': 2
        }]
        ps_sigma = [{'ra_source': 1, 'dec_source': 1, 'point_amp': 1}]

        lens_param = self.kwargs_lens, lens_sigma, [{}, {
            'ra_0': 0,
            'dec_0': 0
        }], lens_lower, lens_upper
        source_param = self.kwargs_source, source_sigma, [
            {}
        ], source_lower, source_upper
        lens_light_param = self.kwargs_lens_light, lens_light_sigma, [{
            'center_x':
            0
        }], lens_light_lower, lens_light_upper
        ps_param = self.kwargs_ps, ps_sigma, [{}
                                              ], self.kwargs_ps, self.kwargs_ps

        kwargs_params = {
            'lens_model': lens_param,
            'source_model': source_param,
            'lens_light_model': lens_light_param,
            'point_source_model': ps_param,
            # 'cosmography': cosmo_param
        }
        # kwargs_params = [kwargs_init, kwargs_sigma, kwargs_fixed, kwargs_init, kwargs_init]
        image_band = [self.kwargs_data, self.kwargs_psf, self.kwargs_numerics]
        multi_band_list = [image_band]
        kwargs_data_joint = {
            'multi_band_list': multi_band_list,
            'multi_band_type': 'multi-linear'
        }
        fittingSequence = FittingSequence(kwargs_data_joint, self.kwargs_model,
                                          self.kwargs_constraints,
                                          self.kwargs_likelihood,
                                          kwargs_params)

        kwargs_result = fittingSequence.best_fit(bijective=False)
        lens_temp = kwargs_result['kwargs_lens']
        npt.assert_almost_equal(lens_temp[0]['theta_E'],
                                self.kwargs_lens[0]['theta_E'],
                                decimal=2)

        logL = fittingSequence.best_fit_likelihood
        print(logL, 'test')
        #print(lens_temp, source_temp, lens_light_temp, ps_temp, cosmo_temp)
        assert logL < 0
        bic = fittingSequence.bic
        assert bic > 0
        #npt.assert_almost_equal(bic, 20000000220.29376, decimal=-4)

        #npt.assert_almost_equal(logL, -10000000061.792593, decimal=-4)

        n_p = 2
        n_i = 2
        fitting_list = []

        kwargs_pso = {
            'sigma_scale': 1,
            'n_particles': n_p,
            'n_iterations': n_i
        }
        fitting_list.append(['PSO', kwargs_pso])
        kwargs_mcmc = {
            'sigma_scale': 0.1,
            'n_burn': 1,
            'n_run': 1,
            'walkerRatio': 2
        }
        fitting_list.append(['MCMC', kwargs_mcmc])
        kwargs_mcmc['re_use_samples'] = True
        fitting_list.append(['MCMC', kwargs_mcmc])
        kwargs_mcmc['sampler_type'] = 'EMCEE'
        fitting_list.append(['MCMC', kwargs_mcmc])
        kwargs_align = {
            'lowerLimit': -0.1,
            'upperLimit': 0.1,
            'n_particles': 2,
            'n_iterations': 2
        }
        fitting_list.append(['align_images', kwargs_align])
        kwargs_psf_iter = {
            'num_iter': 2,
            'psf_iter_factor': 0.5,
            'stacking_method': 'mean'
        }
        fitting_list.append(['psf_iteration', kwargs_psf_iter])
        fitting_list.append(['restart', None])
        fitting_list.append(['fix_not_computed', {'free_bands': [True]}])
        n_sersic_overwrite = 4
        kwargs_update = {
            'lens_light_add_fixed': [[0, ['n_sersic'], [n_sersic_overwrite]]],
            'lens_light_remove_fixed': [[0, ['center_x']]],
            'change_source_lower_limit': [[0, ['n_sersic'], [0.1]]],
            'change_source_upper_limit': [[0, ['n_sersic'], [10]]]
        }
        fitting_list.append(['update_settings', kwargs_update])

        #kwargs_model = {}, kwargs_constraints = {}, kwargs_likelihood = {}, lens_add_fixed = [],
        #source_add_fixed = [], lens_light_add_fixed = [], ps_add_fixed = [], cosmo_add_fixed = [], lens_remove_fixed = [],
        #source_remove_fixed = [], lens_light_remove_fixed = [], ps_remove_fixed = [], cosmo_remove_fixed = []

        chain_list = fittingSequence.fit_sequence(fitting_list)
        lens_fixed, source_fixed, lens_light_fixed, ps_fixed, special_fixed, extinction_fixed = fittingSequence._updateManager._fixed_kwargs
        kwargs_result = fittingSequence.best_fit(bijective=False)
        npt.assert_almost_equal(kwargs_result['kwargs_lens'][0]['theta_E'],
                                self.kwargs_lens[0]['theta_E'],
                                decimal=1)
        npt.assert_almost_equal(
            fittingSequence._updateManager._lens_light_fixed[0]['n_sersic'],
            n_sersic_overwrite,
            decimal=8)
        npt.assert_almost_equal(lens_light_fixed[0]['n_sersic'], 4, decimal=-1)
        assert fittingSequence._updateManager._lower_kwargs[1][0][
            'n_sersic'] == 0.1
        assert fittingSequence._updateManager._upper_kwargs[1][0][
            'n_sersic'] == 10

        # Nested sampler tests
        # further decrease the parameter space for nested samplers to run faster
        fitting_list2 = []
        kwargs_update2 = {
            'ps_add_fixed': [[0, ['ra_source', 'dec_source'], [0, 0]]],
            'lens_light_add_fixed': [[
                0, ['n_sersic', 'R_sersic', 'center_x', 'center_y'],
                [4, .1, 0, 0]
            ]],
            'source_add_fixed': [[
                0, ['R_sersic', 'e1', 'e2', 'center_x', 'center_y'],
                [.6, .1, .1, 0, 0]
            ]],
            'lens_add_fixed': [[
                0, ['gamma', 'theta_E', 'e1', 'e2', 'center_x', 'center_y'],
                [1.8, 1., .1, .1, 0, 0]
            ], [1, ['e1', 'e2'], [0.01, 0.01]]],
            'change_source_lower_limit': [[0, ['n_sersic'], [2.9]]],
            'change_source_upper_limit': [[0, ['n_sersic'], [3.1]]]
        }
        fitting_list2.append(['update_settings', kwargs_update2])
        kwargs_multinest = {
            'sampler_type': 'MULTINEST',
            'kwargs_run': {
                'n_live_points': 10,
                'evidence_tolerance': 0.5,
                'sampling_efficiency':
                0.8,  # 1 for posterior-only, 0 for evidence-only
                'importance_nested_sampling': False,
                'multimodal': True,
                'const_efficiency_mode':
                False,  # reduce sampling_efficiency to 5% when True
            },
            'remove_output_dir': True,
        }
        fitting_list2.append(['nested_sampling', kwargs_multinest])
        kwargs_dynesty = {
            'sampler_type': 'DYNESTY',
            'kwargs_run': {
                'dlogz_init': 0.01,
                'nlive_init': 3,
                'nlive_batch': 3,
                'maxbatch': 1,
            },
        }
        fitting_list2.append(['nested_sampling', kwargs_dynesty])
        kwargs_dypolychord = {
            'sampler_type': 'DYPOLYCHORD',
            'kwargs_run': {
                'ninit': 8,
                'nlive_const': 10,
                #'seed_increment': 1,
                'resume_dyn_run': False,
                #'init_step': 10,
            },
            'polychord_settings': {
                'seed': 1,
                #'num_repeats': 20
            },
            'dypolychord_dynamic_goal':
            0.8,  # 1 for posterior-only, 0 for evidence-only
            'remove_output_dir': True,
        }
        fitting_list2.append(['nested_sampling', kwargs_dypolychord])

        chain_list2 = fittingSequence.fit_sequence(fitting_list2)
        kwargs_fixed = fittingSequence._updateManager._fixed_kwargs
        npt.assert_almost_equal(kwargs_fixed[0][1]['e1'], 0.01, decimal=2)
        assert fittingSequence._updateManager._lower_kwargs[1][0][
            'n_sersic'] == 2.9
        assert fittingSequence._updateManager._upper_kwargs[1][0][
            'n_sersic'] == 3.1

        kwargs_test = {'kwargs_lens': 1}
        fittingSequence.update_state(kwargs_test)
        kwargs_out = fittingSequence.best_fit(bijective=True)
        assert kwargs_out['kwargs_lens'] == 1
Esempio n. 3
0
class ClsrWorkflow(object):
    def __init__(self, kwargs_data_joint, kwargs_model,lens_params,source_params,
                 lenslight_params=None, kwargs_constraints=None, kwargs_likelihood=None):
        """
        class to  manage cluster source reconstruction.
        This class inherited the FittingSequence class in Workflow module of lenstronomy.
        :param kwargs_data_joint: keywords arguments of [data, psf, numericals] in lenstronomy convention.
        :param kwargs_model: name of model list
        :param lens_params: lens model keywords arguments [kwargs_lens_init, kwargs_lens_sigma, kwargs_fixed_lens, kwargs_lower_lens, kwargs_upper_lens]
        :param source_params: source model keywords arguments [kwargs_source_init, kwargs_source_sigma, kwargs_fixed_source, kwargs_lower_source, kwargs_upper_source]
        :param kwargs_constraints: contraints on models
        :param kwargs_likelihood: options of calculating likelihood, see more: LikelihoodModule class in Sampling module of lenstronomy.
        """
        self.kwargs_data_joint =kwargs_data_joint
        self.multi_band_list = kwargs_data_joint.get('multi_band_list', [])
        self.kwargs_model =kwargs_model
        kwargs_params = {'lens_model': lens_params, 'source_model': source_params, 'lens_light_model': lenslight_params}
        self.kwargs_params= kwargs_params
        if kwargs_constraints is None:
            kwargs_constraints ={}
        if kwargs_likelihood is None:
            kwargs_likelihood = {'source_marg': False, 'check_positive_flux': True}
        self.fitting_seq_src = FittingSequence(kwargs_data_joint, kwargs_model, kwargs_constraints, kwargs_likelihood, kwargs_params)

    def run_fit_sequence(self,fitting_kwargs_list):
        """
        :param fitting_kwargs_list: list of [['string', {kwargs}], ..] with 'string being the specific fitting option and kwargs being the arguments passed to this option
        :return: fitting results
        """
        chain_list = self.fitting_seq_src.fit_sequence(fitting_kwargs_list)
        kwargs_result = self.fitting_seq_src.best_fit(bijective=False)
        bic_model = self.fitting_seq_src.bic
        return bic_model,chain_list, kwargs_result


    def lensmodel_comp(self, num_img, n_particles,n_iterations,sigma_scale, num_lens_model,fixed_index =0,flexion_option=True):
        """
        function to figure out the necessary of increasing lens model complexity. Currently, we only consider up to flexion term.
        :param n_particles: particles numbers of PSO
        :param n_iterations: iteration numbers of PSO
        :param sigma_scale: sigma scale for PSO
        :param num_img: int, numbers of lensed image
        :param fixed_index: int, index of fixed lensed image
        :param num_lens_model: numbers of strings contained in lens model list
        :param flexion_option: bool, default is taking flexion into consideration
        :return: pso results, fitting results of necessary lens model complexity, bic values
        """
        lens_remove_fixed_list = []
        lens_add_fixed_list = []
        for i in range(num_img):
            if i == fixed_index:
                print ("lens model keep fixed in frame:", i+1)
            else:
                lens_flexion_index = (i + 1) * num_lens_model - 1
                lens_remove_fixed_list.append([lens_flexion_index, ['G1', 'G2', 'F1', 'F2'], [0, 0, 0, 0]])
                G1_fix = self.kwargs_params['lens_model'][2][lens_flexion_index]['G1']
                G2_fix = self.kwargs_params['lens_model'][2][lens_flexion_index]['G2']
                F1_fix = self.kwargs_params['lens_model'][2][lens_flexion_index]['F1']
                F2_fix = self.kwargs_params['lens_model'][2][lens_flexion_index]['F2']
                lens_add_fixed_list.append([lens_flexion_index, ['G1', 'G2', 'F1', 'F2'], [G1_fix, G2_fix, F1_fix, F2_fix]])
        flexion_add_fixed = [['update_settings', {'lens_add_fixed': lens_add_fixed_list}]]
        print("flexion_fixed:", flexion_add_fixed)
        kwargs_pso = [['PSO', {'sigma_scale': sigma_scale, 'n_particles': n_particles, 'n_iterations': n_iterations}]]
        fitting_kwargs_fix =  flexion_add_fixed+ kwargs_pso
        bic_model_fix, chain_list_fix, kwargs_result_fix = self.run_fit_sequence(fitting_kwargs_fix)
        if flexion_option:
            flexion_remove_fixed = [['update_settings', {'lens_remove_fixed': lens_remove_fixed_list}]]
            print ("flexion_remove_fixed:", flexion_remove_fixed)
            fitting_kwargs_free = flexion_remove_fixed + kwargs_pso
            bic_model_free, chain_list_free, kwargs_result_free = self.run_fit_sequence(fitting_kwargs_free)
        else:
            bic_model_free = 10000000
        if bic_model_free > bic_model_fix:
            print ("No necessary to add flexion!")
            bic_list = [bic_model_fix]
            chain_list = [chain_list_fix]
            kwargs_result_list = [kwargs_result_fix]
            self._update_kwargs(kwargs_result_fix)
            _, _, _ = self.run_fit_sequence(flexion_add_fixed)
        elif bic_model_free < bic_model_fix:
            print("Flexion is needed!")
            bic_list = [bic_model_fix, bic_model_free]
            chain_list = [chain_list_fix]
            kwargs_result_list = [kwargs_result_fix]
        return chain_list, kwargs_result_list, bic_list


    def sourcemodel_comp(self, n_max_range=[0], sr = 0, n_particles=10, n_iterations=10,sigma_scale =1.0,
                         bic_model_in = [100000], chain_list_in = [0], kwargs_results_in = [0], bic_option=True) :
        """
        function to found the best fitting results among source models related to numbers of shapelets basis
        :param n_max_range: shapelets basis selection range
        :param sr: typical scale (") in source plane
        :param n_particles: particles numbers of PSO
        :param n_iterations: iteration numbers of PSO
        :param sigma_scale: sigma scale for PSO
        :param bic_model_in: BIC value of models before adding shapelets to source model
        :param chain_list_in: PSO chain results of models before adding shapelets to source model
        :param kwargs_results_in: fitting results of models before adding shapelets to source model
        :return: best-fit PSO results, best-fits results, PSO results for n_max_range, fitting results for n_max_range,
                bic values for all models
        """
        bic_model_list = bic_model_in
        chain_list_list = chain_list_in
        kwargs_result_list = kwargs_results_in
        bic_in_len = len(bic_model_in)
        bic_run = True
        beta0 = sr
        kwargs_pso = [['PSO', {'sigma_scale': sigma_scale, 'n_particles': n_particles, 'n_iterations': n_iterations}]]
        for nmax in n_max_range:
            if nmax < 0:
                raise ValueError("nmax can not be negative!",nmax)
            else:
                if nmax == n_max_range[0]:
                    start_kwargs_shapelet = [['update_settings', {'source_remove_fixed': [  [1, ['beta'], [beta0]] ]}]]
                else:
                    start_kwargs_shapelet = []
                beta_nmax = ((nmax + 1)) ** 0.5 * beta0
                fit_kwargs_shapelet = [['update_settings',
                                        {'source_add_fixed': [[1, ['n_max'], [nmax]]],
                                        'change_source_lower_limit': [[1, ['beta'], [beta_nmax]]]
                                         }
                                         ]]
                fitting_kwargs = start_kwargs_shapelet + fit_kwargs_shapelet + kwargs_pso
            if bic_run:
                print ("nmax",nmax,"fitting_kwargs",fitting_kwargs)
                bic_model,chain_list, kwargs_result = self.run_fit_sequence(fitting_kwargs)
                if bic_model >  bic_model_list[-1]:
                    if bic_option:
                        bic_run = False
                        if bic_model > bic_model_in[bic_in_len-1]:
                            print ("bic_model_in",bic_model_in)
                            print ("no necessary to add SHAPELETS !")
                            fix_kwargs_shapelet=[['update_settings', {'source_add_fixed': [[1, ['beta'], [sr]]]}]]
                            _, _, _ = self.run_fit_sequence(fix_kwargs_shapelet)
                    elif not bic_option:
                        chain_list_list.append(chain_list)
                        kwargs_result_list.append(kwargs_result)
                        bic_model_list.append(bic_model)
                    print ("no necessary to increase model complexity!")
                elif bic_model < bic_model_list[-1]:
                    chain_list_list.append(chain_list)
                    kwargs_result_list.append(kwargs_result)
                    bic_model_list.append(bic_model)
                    print (bic_model, "currently is the lowest BIC value in bic_model_list=", bic_model_list)
        bic_sourcemodel = bic_model_list[bic_in_len:]
        if bic_sourcemodel ==[]:
            chain_list_lowest = chain_list_in[-1]
            kwargs_result_lowest = kwargs_results_in[-1]
        else:
            index_bic_minima = np.where(bic_model_list == np.min(bic_model_list))[0][0]
            chain_list_lowest = chain_list_list[index_bic_minima]
            kwargs_result_lowest = kwargs_result_list[index_bic_minima]
        return  chain_list_lowest, kwargs_result_lowest, chain_list_list, kwargs_result_list, bic_model_list


    def _update_kwargs(self,kwargs_result):
        """
        :param kwargs_result: fitting results of a specific state
        :return: go back to a specific state
        """
        self.fitting_seq_src.update_state(kwargs_result)