Exemplo n.º 1
0
 def __init__(self,
              z_d,
              z_s,
              D_d_sample,
              D_delta_t_sample,
              sampling_option="H0_only",
              omega_m_fixed=0.3,
              omega_lambda_fixed=0.7,
              omega_mh2_fixed=0.14157,
              kde_type='scipy_gaussian',
              bandwidth=1,
              flat=True):
     """
     initializes all the classes needed for the chain (i.e. redshifts of lens and source)
     """
     self.z_d = z_d
     self.z_s = z_s
     self.cosmoProp = LCDM(z_lens=z_d, z_source=z_s, flat=flat)
     self._kde_likelihood = KDELikelihood(D_d_sample,
                                          D_delta_t_sample,
                                          kde_type=kde_type,
                                          bandwidth=bandwidth)
     self.sampling_option = sampling_option
     self.omega_m_fixed = omega_m_fixed
     self.omega_mh2_fixed = omega_mh2_fixed
     self._omega_lambda_fixed = omega_lambda_fixed
    def test_kde_likelihood(self):
        # define redshift of lens and source
        z_L = 0.8
        z_S = 3.0

        # define the "truth"
        H0_true = 70
        omega_m_true = 0.3
        # setup the true cosmology
        cosmo = FlatLambdaCDM(H0_true, Om0=omega_m_true)
        lensCosmo = LensCosmo(z_L, z_S, cosmo=cosmo)
        # compute the true angular diameter distances
        Dd_true = lensCosmo.D_d
        D_dt_true = lensCosmo.D_dt

        # define a measurement uncertainty/spread in the posteriors
        # the example contains uncorrelated Gaussians
        sigma_Dd = 100
        sigma_Ddt = 100

        # make a realization of the posterior sample, centered around the "truth" with given uncertainties
        num_samples = 50000
        D_dt_samples = np.random.normal(D_dt_true, sigma_Ddt, num_samples)
        D_d_samples = np.random.normal(Dd_true, sigma_Dd, num_samples)

        # initialize a KDELikelihood class with the posterior sample
        kdeLikelihood = KDELikelihood(D_d_samples,
                                      D_dt_samples,
                                      kde_type='scipy_gaussian',
                                      bandwidth=2)
        # evaluate the maximum likelihood (arbitrary normalization!)
        logL_max = kdeLikelihood.logLikelihood(Dd_true, D_dt_true)
        # evaluate the likelihood 1-sigma away from Dd
        logL_sigma = kdeLikelihood.logLikelihood(Dd_true + sigma_Dd, D_dt_true)
        # compute likelihood ratio
        delta_log = logL_max - logL_sigma
        # check whether likelihood ratio is consistent with input distribution
        # (in relative percent level in the likelihoods)
        npt.assert_almost_equal(delta_log, 0.5, decimal=2)

        # test the same in D_dt dimension
        logL_sigma = kdeLikelihood.logLikelihood(Dd_true,
                                                 D_dt_true + sigma_Ddt)
        # compute likelihood ratio
        delta_log = logL_max - logL_sigma
        # check whether likelihood ratio is consistent with input distribution
        npt.assert_almost_equal(delta_log, 0.5, decimal=2)
Exemplo n.º 3
0
 def kdelikelihood(self, kde_type, bandwidth=20):
     """
     Evaluates the likelihood of a angular diameter distance to the deflector Dd (in Mpc) versus its time-delay distance Ddt (in Mpc) against the model predictions, using a loglikelihood sampled from a Kernel Density Estimator.
     """
     self.ddt = self.ddt_vs_dd["ddt"]
     self.dd = self.ddt_vs_dd["dd"]
     KDEl = KDELikelihood(self.dd.values, self.ddt.values, kde_type=kde_type, bandwidth=bandwidth)
     return KDEl.logLikelihood
Exemplo n.º 4
0
    def __init__(self,
                 z_lens,
                 z_source,
                 dd_samples,
                 ddt_samples,
                 kde_type='scipy_gaussian',
                 bandwidth=1,
                 interpol=False,
                 num_interp_grid=100):
        """

        :param z_lens: lens redshift
        :param z_source: source redshift
        :param dd_samples: angular diameter to the lens posteriors (in physical Mpc)
        :param ddt_samples: time-delay distance posteriors (in physical Mpc)
        :param kde_type: kernel density estimator type (see KDELikelihood class)
        :param bandwidth: width of kernel (in same units as the angular diameter quantities)
        :param interpol: bool, if True pre-computes an interpolation likelihood in 2d on a grid
        :param num_interp_grid: int, number of interpolations per axis
        """
        self._kde_likelihood = KDELikelihood(dd_samples,
                                             ddt_samples,
                                             kde_type=kde_type,
                                             bandwidth=bandwidth)

        if interpol is True:
            dd_grid = np.linspace(start=max(np.min(dd_samples), 0),
                                  stop=min(np.max(dd_samples), 10000),
                                  num=num_interp_grid)
            ddt_grid = np.linspace(np.min(ddt_samples),
                                   np.max(ddt_samples),
                                   num=num_interp_grid)
            z = np.zeros((num_interp_grid, num_interp_grid))
            for i, dd in enumerate(dd_grid):
                for j, ddt in enumerate(ddt_grid):
                    z[j, i] = self._kde_likelihood.logLikelihood(dd, ddt)[0]
            self._interp_log_likelihood = interpolate.interp2d(dd_grid,
                                                               ddt_grid,
                                                               z,
                                                               kind='cubic')
        self._interpol = interpol
        self.num_data = 2
Exemplo n.º 5
0
class CosmoLikelihood(object):
    """
    this class contains the likelihood function of the Strong lensing analysis
    """
    def __init__(self,
                 z_d,
                 z_s,
                 D_d_sample,
                 D_delta_t_sample,
                 sampling_option="H0_only",
                 omega_m_fixed=0.3,
                 omega_lambda_fixed=0.7,
                 omega_mh2_fixed=0.14157,
                 kde_type='scipy_gaussian',
                 bandwidth=1,
                 flat=True):
        """
        initializes all the classes needed for the chain (i.e. redshifts of lens and source)
        """
        self.z_d = z_d
        self.z_s = z_s
        self.cosmoProp = LCDM(z_lens=z_d, z_source=z_s, flat=flat)
        self._kde_likelihood = KDELikelihood(D_d_sample,
                                             D_delta_t_sample,
                                             kde_type=kde_type,
                                             bandwidth=bandwidth)
        self.sampling_option = sampling_option
        self.omega_m_fixed = omega_m_fixed
        self.omega_mh2_fixed = omega_mh2_fixed
        self._omega_lambda_fixed = omega_lambda_fixed

    def X2_chain_H0(self, args):
        """
        routine to compute X2 given variable parameters for a MCMC/PSO chain
        """
        #extract parameters
        H0 = args[0]
        omega_m = self.omega_m_fixed
        Ode0 = self._omega_lambda_fixed
        logL, bool = self.prior_H0(H0)
        if bool is True:
            logL += self.LCDM_lensLikelihood(H0, omega_m, Ode0)
        return logL, None

    def X2_chain_omega_mh2(self, args):
        """
        routine to compute the log likelihood given a omega_m h**2 prior fixed
        :param args:
        :return:
        """
        H0 = args[0]
        h = H0 / 100.
        omega_m = self.omega_mh2_fixed / h**2
        Ode0 = self._omega_lambda_fixed
        logL, bool = self.prior_omega_mh2(h, omega_m)
        if bool is True:
            logL += self.LCDM_lensLikelihood(H0, omega_m, Ode0)
        return logL, None

    def X2_chain_H0_omgega_m(self, args):
        """
        routine to compute X^2
        :param args:
        :return:
        """
        #extract parameters
        [H0, omega_m] = args
        Ode0 = self._omega_lambda_fixed
        logL_H0, bool_H0 = self.prior_H0(H0)
        logL_omega_m, bool_omega_m = self.prior_omega_m(omega_m)
        logL = logL_H0 + logL_omega_m
        if bool_H0 is True and bool_omega_m is True:
            logL += self.LCDM_lensLikelihood(H0, omega_m, Ode0)
        return logL + logL_H0 + logL_omega_m, None

    def X2_chain_H0_omgega_m_omega_de(self, args):
        """
        routine to compute X^2
        :param args:
        :return:
        """
        #extract parameters
        [H0, omega_m, Ode0] = args
        logL_H0, bool_H0 = self.prior_H0(H0)
        logL_omega_m, bool_omega_m = self.prior_omega_m(omega_m)
        logL = logL_H0 + logL_omega_m
        if bool_H0 is True and bool_omega_m is True:
            logL += self.LCDM_lensLikelihood(H0, omega_m, Ode0)
        return logL + logL_H0 + logL_omega_m, None

    def LCDM_lensLikelihood(self, H0, omega_m, Ode0=None):
        Dd = self.cosmoProp.D_d(H0, omega_m, Ode0)
        Ddt = self.cosmoProp.D_dt(H0, omega_m, Ode0)
        return self.lensLikelihood(Dd, Ddt)

    def lensLikelihood(self, Dd, Ddt):
        """

        :param alpha:
        :param beta:
        :param sigma_D:
        :return:
        """
        logL = self._kde_likelihood.logLikelihood(Dd, Ddt)
        return logL

    @staticmethod
    def prior_H0(H0, H0_min=0, H0_max=200):
        """
        checks whether the parameter vector has left its bound, if so, adds a big number
        """
        if H0 < H0_min or H0 > H0_max:
            penalty = -10**15
            return penalty, False
        else:
            return 0, True

    @staticmethod
    def prior_omega_m(omega_m, omega_m_min=0, omega_m_max=1):
        """
        checks whether the parameter omega_m is within the given bounds
        :param omega_m:
        :param omega_m_min:
        :param omega_m_max:
        :return:
        """
        if omega_m < omega_m_min or omega_m > omega_m_max:
            penalty = -10**15
            return penalty, False
        else:
            return 0, True

    def prior_omega_mh2(self, h, omega_m, h_max=2):
        """

        """
        if omega_m > 1 or h > h_max:
            penalty = -10**15
            return penalty, False
        else:
            prior = np.log(np.sqrt(1 + 4 * self.omega_mh2_fixed**2 / h**6))
            return prior, True

    def likelihood(self, a):
        logL, _ = self._likelihood(a)
        return logL

    def _likelihood(self, a):
        if self.sampling_option == 'H0_only':
            return self.X2_chain_H0(a)
        elif self.sampling_option == 'H0_omega_m':
            return self.X2_chain_H0_omgega_m(a)
        elif self.sampling_option == "fix_omega_mh2":
            return self.X2_chain_omega_mh2(a)
        elif self.sampling_option == 'H0_omega_m_omega_de':
            return self.X2_chain_H0_omgega_m_omega_de(a)
        else:
            raise ValueError("sampling method %s not supported!" %
                             self.sampling_option)
Exemplo n.º 6
0
class DdtDdKDELikelihood(object):
    """
    class for evaluating the 2-d posterior of Ddt vs Dd coming from a lens with time delays and kinematics measurement
    """
    def __init__(self,
                 z_lens,
                 z_source,
                 dd_samples,
                 ddt_samples,
                 kde_type='scipy_gaussian',
                 bandwidth=1,
                 interpol=False,
                 num_interp_grid=100):
        """

        :param z_lens: lens redshift
        :param z_source: source redshift
        :param dd_samples: angular diameter to the lens posteriors (in physical Mpc)
        :param ddt_samples: time-delay distance posteriors (in physical Mpc)
        :param kde_type: kernel density estimator type (see KDELikelihood class)
        :param bandwidth: width of kernel (in same units as the angular diameter quantities)
        :param interpol: bool, if True pre-computes an interpolation likelihood in 2d on a grid
        :param num_interp_grid: int, number of interpolations per axis
        """
        self._kde_likelihood = KDELikelihood(dd_samples,
                                             ddt_samples,
                                             kde_type=kde_type,
                                             bandwidth=bandwidth)

        if interpol is True:
            dd_grid = np.linspace(start=max(np.min(dd_samples), 0),
                                  stop=min(np.max(dd_samples), 10000),
                                  num=num_interp_grid)
            ddt_grid = np.linspace(np.min(ddt_samples),
                                   np.max(ddt_samples),
                                   num=num_interp_grid)
            z = np.zeros((num_interp_grid, num_interp_grid))
            for i, dd in enumerate(dd_grid):
                for j, ddt in enumerate(ddt_grid):
                    z[j, i] = self._kde_likelihood.logLikelihood(dd, ddt)[0]
            self._interp_log_likelihood = interpolate.interp2d(dd_grid,
                                                               ddt_grid,
                                                               z,
                                                               kind='cubic')
        self._interpol = interpol
        self.num_data = 2

    def log_likelihood(self, ddt, dd, aniso_scaling=None):
        """

        :param ddt: time-delay distance
        :param dd: angular diameter distance to the deflector
        :param aniso_scaling: array of size of the velocity dispersion measurement or None, scaling of the predicted
         dimensionless quantity J (proportional to sigma_v^2) of the anisotropy model in the sampling relative to the
         anisotropy model used to derive the prediction and covariance matrix in the init of this class.
        :return: log likelihood given the single lens analysis
        """
        if aniso_scaling is not None:
            dd_ = dd * aniso_scaling[0]
        else:
            dd_ = dd
        if self._interpol is True:
            return self._interp_log_likelihood(dd_, ddt)[0]
        return self._kde_likelihood.logLikelihood(dd_, ddt)[0]