示例#1
0
class TestLOS(object):
    def setup(self):
        zlens, zsource = 0.5, 2.
        zmin = 0.01
        zmax = 1.98
        log_mlow = 6.
        log_mhigh = 9.
        host_m200 = 10**13
        LOS_normalization = 1.
        draw_poisson = False
        log_mass_sheet_min = 7.
        log_mass_sheet_max = 10.
        kappa_scale = 1.
        delta_power_law_index = -0.1
        delta_power_law_index_coupling = 0.5
        cone_opening_angle = 6.
        m_pivot = 10**8
        sigma_sub = 0.1
        power_law_index = -1.9
        subhalo_spatial_distribution = 'HOST_NFW'

        kwargs_cdm = {
            'zmin': zmin,
            'zmax': zmax,
            'log_mc': None,
            'log_mlow': log_mlow,
            'sigma_sub': sigma_sub,
            'c_scale': None,
            'c_power': None,
            'a_wdm': None,
            'b_wdm': None,
            'c_wdm': None,
            'c_scatter_dex': 0.2,
            'log_mhigh': log_mhigh,
            'mdef_los': 'TNFW',
            'host_m200': host_m200,
            'LOS_normalization': LOS_normalization,
            'draw_poisson': draw_poisson,
            'subhalo_spatial_distribution': subhalo_spatial_distribution,
            'log_mass_sheet_min': log_mass_sheet_min,
            'log_mass_sheet_max': log_mass_sheet_max,
            'kappa_scale': kappa_scale,
            'power_law_index': power_law_index,
            'delta_power_law_index': delta_power_law_index,
            'delta_power_law_index_coupling': delta_power_law_index_coupling,
            'm_pivot': m_pivot,
            'cone_opening_angle': cone_opening_angle,
            'subhalo_mass_sheet_scale': 1.,
            'subhalo_convergence_correction_profile': 'NFW',
            'r_tidal': '0.5Rs'
        }

        pyhalo = pyHalo(zlens, zsource)
        self.realization_cdm = pyhalo.render(['TWO_HALO'], kwargs_cdm)[0]

        lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts(
            kwargs_cdm)

        cosmo = Cosmology()
        self.lens_plane_redshifts = lens_plane_redshifts
        self.delta_zs = delta_zs
        self.halo_mass_function = LensingMassFunction(
            cosmo,
            zlens,
            zsource,
            kwargs_cdm['log_mlow'],
            kwargs_cdm['log_mhigh'],
            kwargs_cdm['cone_opening_angle'],
            m_pivot=kwargs_cdm['m_pivot'],
            geometry_type='DOUBLE_CONE')
        self.geometry = Geometry(cosmo, zlens, zsource,
                                 kwargs_cdm['cone_opening_angle'],
                                 'DOUBLE_CONE')
        self.lens_cosmo = LensCosmo(zlens, zsource, cosmo)

        self.kwargs_cdm = kwargs_cdm

        self.rendering_class = TwoHaloContribution(
            kwargs_cdm, self.halo_mass_function, self.geometry,
            self.lens_cosmo, self.lens_plane_redshifts, self.delta_zs)

    def test_norm_slope(self):

        delta_z = self.delta_zs[1]
        norm, slope = self.rendering_class._norm_slope(self.lens_cosmo.z_lens,
                                                       delta_z)
        slope_theory = self.halo_mass_function.plaw_index_z(
            self.lens_cosmo.z_lens) + self.kwargs_cdm['delta_power_law_index']
        npt.assert_almost_equal(slope, slope_theory)
        norm_theory_background = self.halo_mass_function.norm_at_z_density(
            self.lens_cosmo.z_lens, slope, self.kwargs_cdm['m_pivot'])
        norm_theory_background *= self.geometry.volume_element_comoving(
            self.lens_cosmo.z_lens, delta_z)
        rmax = self.lens_cosmo.cosmo.D_C_transverse(self.lens_cosmo.z_lens + delta_z) - \
               self.lens_cosmo.cosmo.D_C_transverse(self.lens_cosmo.z_lens)
        boost = self.halo_mass_function.two_halo_boost(
            self.kwargs_cdm['host_m200'], self.lens_cosmo.z_lens, rmax=rmax)
        norm_theory = (boost - 1) * norm_theory_background
        npt.assert_almost_equal(norm_theory, norm)

    def test_rendering(self):

        m = self.rendering_class.render_masses_at_z(self.lens_cosmo.z_lens,
                                                    0.02)
        npt.assert_equal(True, len(m) > 0)

        npt.assert_raises(Exception, self.rendering_class.render_masses_at_z,
                          0.9, 0.02)

        x, y = self.rendering_class.render_positions_at_z(
            self.lens_cosmo.z_lens, 10000)
        rmax = np.max(np.hypot(x, y))
        rmax_theory = 0.5 * self.kwargs_cdm[
            'cone_opening_angle'] * self.geometry.rendering_scale(
                self.lens_cosmo.z_lens)
        npt.assert_array_less(rmax, rmax_theory)

        x, y = self.rendering_class.render_positions_at_z(
            self.lens_cosmo.z_lens, 0)
        npt.assert_equal(True, len(x) == 0)

        m, x, y, r3, redshifts, flag = self.rendering_class.render()
        npt.assert_equal(len(m), len(x))
        npt.assert_equal(len(y), len(r3))

        n = 0
        for z in np.unique(redshifts):
            n += np.sum(redshifts == z)
        npt.assert_equal(True, n == len(m))

        npt.assert_equal(True, len(self.realization_cdm.halos) == len(m))

    def test_convergence_correction(self):

        kwargs_out, profile_names_out, redshifts = self.rendering_class.convergence_sheet_correction(
        )

        npt.assert_equal(0, len(kwargs_out))
        npt.assert_equal(0, len(profile_names_out))
        npt.assert_equal(0, len(redshifts))

    def test_keys_convergence_sheets(self):

        keywords_out = self.rendering_class.keys_convergence_sheets()
        npt.assert_equal(len(keywords_out), 0)

    def test_keys_rendering(self):

        keywords_out = self.rendering_class.keyword_parse_render(
            self.kwargs_cdm)
        required_keys = [
            'log_mlow', 'log_mhigh', 'host_m200', 'LOS_normalization',
            'draw_poisson', 'delta_power_law_index', 'm_pivot', 'log_mc',
            'a_wdm', 'b_wdm', 'c_wdm'
        ]

        for x in required_keys:
            npt.assert_equal(x in keywords_out.keys(), True)

        kw_cdm = deepcopy(self.kwargs_cdm)
        kw_cdm['log_mc'] = None
        keywords_out = self.rendering_class.keyword_parse_render(kw_cdm)
        npt.assert_equal(keywords_out['a_wdm'] is None, True)
        npt.assert_equal(keywords_out['b_wdm'] is None, True)
        npt.assert_equal(keywords_out['c_wdm'] is None, True)
class TestLensingMassFunction(object):
    def setup(self):

        cosmo = Cosmology()
        mlow = 10**6
        mhigh = 10**10
        zlens = 0.5
        zsource = 1.5
        cone_opening_angle = 6.
        m_pivot = 10**8
        mass_function_model = 'sheth99'
        use_lookup_table = True
        geometry_type = 'DOUBLE_CONE'
        self.lmf_lookup_ShethTormen = LensingMassFunction(
            cosmo, zlens, zsource, mlow, mhigh, cone_opening_angle, m_pivot,
            mass_function_model, use_lookup_table, geometry_type)

        use_lookup_table = False
        self.lmf_no_lookup_ShethTormen = LensingMassFunction(
            cosmo, zlens, zsource, mlow, mhigh, cone_opening_angle, m_pivot,
            mass_function_model, use_lookup_table, geometry_type)

        self._m = np.logspace(6., 10, 50)

        self.cosmo = cosmo
        self.cone_opening_angle = cone_opening_angle

    def test_lookup(self):

        dndm_1 = self.lmf_lookup_ShethTormen.dN_dMdV_comoving(self._m, 0.5)
        dndm_2 = self.lmf_no_lookup_ShethTormen.dN_dMdV_comoving(self._m, 0.5)
        npt.assert_almost_equal(dndm_1, dndm_2)

    def test_normalization(self):

        z = 0.5
        plaw_index = self.lmf_lookup_ShethTormen.plaw_index_z(z)
        rho_dv = self.lmf_lookup_ShethTormen.norm_at_z_density(
            z, plaw_index, 10**8)
        dz = 0.01
        rho = self.lmf_no_lookup_ShethTormen.norm_at_z(z, plaw_index, dz,
                                                       10**8)

        radius_arcsec = self.cone_opening_angle * 0.5
        A = self.lmf_lookup_ShethTormen.geometry.angle_to_comoving_area(
            radius_arcsec, z)
        dr = self.cosmo.D_C_transverse(z + dz) - self.cosmo.D_C_transverse(z)
        dv = A * dr
        rho_2 = dv * rho_dv
        npt.assert_almost_equal(rho_2 / rho, 1.0, 2)

    def test_power_law_index(self):

        plaw_index = self.lmf_lookup_ShethTormen.plaw_index_z(0.5)
        npt.assert_almost_equal(plaw_index, -1.91)
        plaw_index = self.lmf_no_lookup_ShethTormen.plaw_index_z(0.5)
        npt.assert_almost_equal(np.round(plaw_index, 2), -1.91)

    def test_two_halo_boost(self):

        z = 0.5
        m_halo = 10**13

        def _integrand(x):
            return self.lmf_no_lookup_ShethTormen.twohaloterm(x, m_halo, z)

        dz = 0.01
        dr = self.cosmo.D_C_transverse(z + dz) - self.cosmo.D_C_transverse(z)
        integral_over_two_halo_term = quad(_integrand, 0.5, dr)[0]
        length = dr - 0.5
        average_value = integral_over_two_halo_term / length

        # factor of two for symmetry in front/behind lens
        boost_factor = 1 + 2 * average_value
        boost_factor_no_lookup = self.lmf_no_lookup_ShethTormen.two_halo_boost(
            m_halo, z, 0.5, dr)
        boost_factor_lookup = self.lmf_lookup_ShethTormen.two_halo_boost(
            m_halo, z, 0.5, dr)
        npt.assert_almost_equal(boost_factor, boost_factor_no_lookup)
        npt.assert_almost_equal(boost_factor, boost_factor_lookup)

    def test_component_density(self):

        f = 1.
        rho = self.lmf_no_lookup_ShethTormen.component_density(f)
        rho_dm = self.cosmo.astropy.Odm(
            0.) * self.cosmo.astropy.critical_density(0.).value
        rho_dm *= self.cosmo.density_to_MsunperMpc
        npt.assert_almost_equal(rho, rho_dm, 4)

    def test_mass_function_fit(self):

        m = np.logspace(6, 10, 50)
        m_pivot = 10**8

        z = 0.2
        norm_mpivot_8, index = self.lmf_no_lookup_ShethTormen._mass_function_params(
            m, z)
        norm_theory = self.lmf_no_lookup_ShethTormen.norm_at_z_density(
            z, index, 10**8)
        norm = norm_mpivot_8 / (m_pivot**index)
        npt.assert_almost_equal(norm / norm_theory, 1., 3)

        z = 1.2
        norm_mpivot_8, index = self.lmf_no_lookup_ShethTormen._mass_function_params(
            m, z)
        norm_theory = self.lmf_no_lookup_ShethTormen.norm_at_z_density(
            z, index, 10**8)
        norm = norm_mpivot_8 / (m_pivot**index)
        npt.assert_almost_equal(norm / norm_theory, 1., 3)

    def test_mass_fraction_in_halos(self):

        z = 0.5
        mlow = 10**6
        mhigh = 10**9
        frac1 = self.lmf_no_lookup_ShethTormen.mass_fraction_in_halos(
            z, mlow, mhigh, mlow_global=10**-4)
        frac2 = self.lmf_no_lookup_ShethTormen.mass_fraction_in_halos(
            z, 10**-4, mhigh, mlow_global=10**-4)
        frac3 = self.lmf_no_lookup_ShethTormen.mass_fraction_in_halos(
            z, 0.99999 * mhigh, mhigh)
        npt.assert_almost_equal(frac2, 1)
        npt.assert_almost_equal(frac1, 0.43799, 3)
        npt.assert_almost_equal(frac3, 0., 3)

    def test_norm(self):

        h = self.cosmo.h

        z = 0.5
        mass_function = self.lmf_no_lookup_ShethTormen.dN_dMdV_comoving

        m = np.logspace(6, 10, 10)

        # units Mpc ^ -3 M ^ -1
        mfunc = mass_function(m, z)

        # to units (Mpc/h) ^ =3 M ^ -1
        mfunc *= h**-3

        # to units (Mpc/h) ^ -3 (M/h) ^ -1
        mfunc *= h**-1
        coefs = np.polyfit(np.log10(m), np.log10(mfunc), 1)
        # coefs = (-1.907, 8.732)

        m_h = m * h
        # units (Mpc/h) ^ -3 ln(M/h)^-1
        dndlogm = massFunction(m_h, z, q_out='dndlnM', model='sheth99')
        # units (Mpc/h) ^ -3 M ^ -1
        dndm = dndlogm / m
        # units (Mpc/h) ^ -3 (M/h) ^ -1
        dndm *= h**-1
        coefs_theory = np.polyfit(np.log10(m), np.log10(dndm), 1)
        # coefs_theory = (-1.907, 8.732)

        npt.assert_almost_equal(coefs_theory, coefs)

    def test_samples(self):

        h = self.cosmo.h
        z = 0.5

        volume_element = 100000.
        nbins = 15
        m = np.logspace(6, 8.7, nbins)
        m_h = m * h
        dndlnmdv = massFunction(m_h, z, q_out='dndlnM', model='sheth99')
        dndm_theory = dndlnmdv * h**3 / m
        coefs_theory = np.polyfit(np.log10(m), np.log10(dndm_theory), 1)

        norm_theory = coefs_theory[1]
        plaw_index_theory = coefs_theory[0]

        norm = volume_element * self.lmf_no_lookup_ShethTormen.norm_at_z_density(
            z, plaw_index_theory, 10**8)

        mfunc = GeneralPowerLaw(6, 8.7, plaw_index_theory, False, norm, None,
                                None, None, None)
        mdraw = mfunc.draw()
        dndm_model = []

        mstep = 0.08
        msteps = 10**np.arange(6, 8.7 + mstep, mstep)
        for i in range(0, len(msteps) - 1):
            cond1 = mdraw >= msteps[i]
            cond2 = mdraw < msteps[i + 1]
            n = np.sum(np.logical_and(cond1, cond2))
            delta_m = msteps[i + 1] - msteps[i]
            new = n / delta_m
            dndm_model.append(new)

        coefs_model = np.polyfit(np.log10(msteps[0:-1]), np.log10(dndm_model),
                                 1)
        norm_model = coefs_model[1]
        npt.assert_almost_equal(
            10**(norm_model - norm_theory) / volume_element, 1, 1)