Ejemplo n.º 1
0
def test_class_setup():
    cosmology = astropy.cosmology.Planck13
    assert cosmology.Om0 == cosmology.Odm0 + cosmology.Ob0
    assert 1 == (cosmology.Om0 + cosmology.Ode0 + cosmology.Ok0 +
                 cosmology.Ogamma0 + cosmology.Onu0)
    class_parameters = get_class_parameters(cosmology)
    try:
        from classy import Class
        cosmo = Class()
        cosmo.set(class_parameters)
        cosmo.compute()
        assert cosmo.h() == cosmology.h
        assert cosmo.T_cmb() == cosmology.Tcmb0.value
        assert cosmo.Omega_b() == cosmology.Ob0
        # Calculate Omega(CDM)_0 two ways:
        assert abs((cosmo.Omega_m() - cosmo.Omega_b()) -
                   (cosmology.Odm0 - cosmology.Onu0)) < 1e-8
        assert abs(cosmo.Omega_m() - (cosmology.Om0 - cosmology.Onu0)) < 1e-8
        # CLASS calculates Omega_Lambda itself so this is a non-trivial test.
        calculated_Ode0 = cosmo.get_current_derived_parameters(
            ['Omega_Lambda'])['Omega_Lambda']
        assert abs(calculated_Ode0 - (cosmology.Ode0 + cosmology.Onu0)) < 1e-5
        cosmo.struct_cleanup()
        cosmo.empty()
    except ImportError:
        pass
Ejemplo n.º 2
0
def test_class_setup():
    cosmology = astropy.cosmology.Planck13
    assert cosmology.Om0 == cosmology.Odm0 + cosmology.Ob0
    assert 1 == (cosmology.Om0 + cosmology.Ode0 + cosmology.Ok0 +
                 cosmology.Ogamma0 + cosmology.Onu0)
    class_parameters = get_class_parameters(cosmology)
    try:
        from classy import Class
        cosmo = Class()
        cosmo.set(class_parameters)
        cosmo.compute()
        assert cosmo.h() == cosmology.h
        assert cosmo.T_cmb() == cosmology.Tcmb0.value
        assert cosmo.Omega_b() == cosmology.Ob0
        # Calculate Omega(CDM)_0 two ways:
        assert abs((cosmo.Omega_m() - cosmo.Omega_b()) -
                   (cosmology.Odm0 - cosmology.Onu0)) < 1e-8
        assert abs(cosmo.Omega_m() - (cosmology.Om0 - cosmology.Onu0)) < 1e-8
        # CLASS calculates Omega_Lambda itself so this is a non-trivial test.
        calculated_Ode0 = cosmo.get_current_derived_parameters(
            ['Omega_Lambda'])['Omega_Lambda']
        assert abs(calculated_Ode0 - (cosmology.Ode0 + cosmology.Onu0)) < 1e-5
        cosmo.struct_cleanup()
        cosmo.empty()
    except ImportError:
        pass
Ejemplo n.º 3
0
    def calculate_spectra(self, cosmo_params, force_recalc=False):
        settings = cosmo_params.copy()
        settings.update({
            "output": "tCl,mPk",
            "evolver": "1",
            "gauge": "newtonian",
            "P_k_max_1/Mpc": 10,
            })

        database = Database(config.DATABASE_DIR, "spectra.dat")

        if settings in database and not force_recalc:
            data = database[settings]
            ell = data["ell"]
            tt = data["tt"]
            kh = data["kh"]
            Pkh = data["Pkh"]
            self.z_rec = data["z_rec"]
        else:
            cosmo = Class()
            cosmo.set(settings)
            cosmo.compute()
            # Cl's
            data = cosmo.raw_cl()
            ell = data["ell"]
            tt = data["tt"]
            # Matter spectrum
            k = np.logspace(-3, 1, config.MATTER_SPECTRUM_CLIENT_SAMPLES_PER_DECADE * 4)
            Pk = np.vectorize(cosmo.pk)(k, 0)
            kh = k * cosmo.h()
            Pkh = Pk / cosmo.h()**3
            # Get redshift of decoupling
            z_rec = cosmo.get_current_derived_parameters(['z_rec'])['z_rec']
            self.z_rec = z_rec
            # Store to database
            database[settings] = {
            "ell": data["ell"],
            "tt": data["tt"],

            "kh": k,
            "Pkh": Pk,

            "z_rec": z_rec,
            }

        return ClSpectrum(ell[2:], tt[2:]), PkSpectrum(kh, Pkh)
Ejemplo n.º 4
0
def calculate_power(cosmology,
                    k_min,
                    k_max,
                    z=0,
                    num_k=500,
                    scaled_by_h=True,
                    n_s=0.9619,
                    logA=3.0980):
    """
    Calculate the power spectrum P(k,z) over the range k_min <= k <= k_max.
    """
    try:
        from classy import Class
        cosmo = Class()
    except ImportError:
        raise RuntimeError('power.calculate_power requires classy.')

    class_parameters = get_class_parameters(cosmology)
    class_parameters['output'] = 'mPk'
    if scaled_by_h:
        class_parameters['P_k_max_h/Mpc'] = k_max
    else:
        class_parameters['P_k_max_1/Mpc'] = k_max
    class_parameters['n_s'] = n_s
    class_parameters['ln10^{10}A_s'] = logA
    cosmo.set(class_parameters)
    cosmo.compute()

    if scaled_by_h:
        k_scale = cosmo.h()
        Pk_scale = cosmo.h()**3
    else:
        k_scale = 1.
        Pk_scale = 1.

    result = np.empty((num_k, ), dtype=[('k', float), ('Pk', float)])
    result['k'][:] = np.logspace(np.log10(k_min), np.log10(k_max), num_k)
    for i, k in enumerate(result['k']):
        result['Pk'][i] = cosmo.pk(k * k_scale, z) * Pk_scale

    cosmo.struct_cleanup()
    cosmo.empty()

    return result
Ejemplo n.º 5
0
def calculate_power(cosmology, k_min, k_max, z=0, num_k=500, scaled_by_h=True,
                    n_s=0.9619, logA=3.0980):
    """
    Calculate the power spectrum P(k,z) over the range k_min <= k <= k_max.
    """
    try:
        from classy import Class
        cosmo = Class()
    except ImportError:
        raise RuntimeError('power.calculate_power requires classy.')

    class_parameters = get_class_parameters(cosmology)
    class_parameters['output'] = 'mPk'
    if scaled_by_h:
        class_parameters['P_k_max_h/Mpc'] = k_max
    else:
        class_parameters['P_k_max_1/Mpc'] = k_max
    class_parameters['n_s'] = n_s
    class_parameters['ln10^{10}A_s'] = logA
    cosmo.set(class_parameters)
    cosmo.compute()

    if scaled_by_h:
        k_scale = cosmo.h()
        Pk_scale = cosmo.h()**3
    else:
        k_scale = 1.
        Pk_scale = 1.

    result = np.empty((num_k,), dtype=[('k', float), ('Pk', float)])
    result['k'][:] = np.logspace(np.log10(k_min), np.log10(k_max), num_k)
    for i, k in enumerate(result['k']):
        result['Pk'][i] = cosmo.pk(k * k_scale, z) * Pk_scale

    cosmo.struct_cleanup()
    cosmo.empty()

    return result
Ejemplo n.º 6
0
class Cosmology(object):
    """
    Class to hold the basic cosmology and CLASS attributes. This can be initialized by a set of cosmological parameters or a pre-defined cosmology.

    Loaded cosmological models:

    - **Planck18**: Bestfit cosmology from Planck 2018, using the baseline TT,TE,EE+lowE+lensing likelihood.
    - **Quijote**: Fiducial cosmology from the Quijote simulations of Francisco Villaescusa-Navarro et al.
    - **Abacus**: Fiducial cosmology from the Abacus simulations of Lehman Garrison et al.

    Args:
        redshift (float): Desired redshift :math:`z`
        name (str): Load cosmology from a list of predetermined cosmologies (see above).
        params (kwargs): Any other CLASS parameters. (Note that sigma8 does not seem to be supported by CLASS in Python 3).

    Keyword Args:
        verb (bool): If true output useful messages througout run-time, default: False.
        npoints (int): Number of points to use in the interpolators for sigma^2, default: 100000

    """

    loaded_models = {'Quijote':{"h":0.6711,"omega_cdm":(0.3175 - 0.049)*0.6711**2,
                                "Omega_b":0.049, "n_s":0.9624,
                                "N_eff":3.046, "A_s":2.134724e-09}, #"sigma8":0.834,
                     'Abacus':{"h":0.6726,"omega_cdm":0.1199,
                                "omega_b":0.02222,"n_s":0.9652,"A_s":2.135472e-09,#"sigma8":0.830,
                                "N_eff":3.046},
                     'Planck18':{"h":0.6732,"omega_cdm":0.12011,"omega_b":0.022383,
                                "n_s":0.96605,"A_s":2.042644e-09}}#,"sigma8":0.8120}}

    def __init__(self,redshift,name="",verb=False,npoints=int(1e5),**params):

        """
        Initialize the cosmology class with cosmological parameters or a defined model.

        """
        ## Load parameters into a dictionary to pass to CLASS
        class_params = dict(**params)
        if len(name)>0:
            if len(params.items())>0:
                raise Exception('Must either choose a preset cosmology or specify parameters!')
            if name in self.loaded_models.keys():
                if verb: print('Loading the %s cosmology at z = %.2f'%(name,redshift))
                loaded_model = self.loaded_models[name]
                for key in loaded_model.keys():
                    class_params[key] = loaded_model[key]
            else:
                raise Exception("This cosmology isn't yet implemented")
        else:
            if len(params.items())==0:
                if verb: print('Using default CLASS cosmology')
            for name, param in params.items():
                class_params[name] = param

        ## # Check we have the correct parameters
        if 'sigma8' in class_params.keys() and 'A_s' in class_params.keys():
            raise NameError('Cannot specify both A_s and sigma8!')

        ## Define other parameters
        self.z = redshift
        self.a = 1./(1.+redshift)
        if 'output' not in class_params.keys():
            class_params['output']='mPk'
        if 'P_k_max_h/Mpc' not in class_params.keys() and 'P_k_max_1/Mpc' not in class_params.keys():
            class_params['P_k_max_h/Mpc']=300.
        if 'z_pk' in class_params.keys():
            assert class_params['z_pk']==redshift, "Can't pass multiple redshifts!"
        else:
            class_params['z_pk']=redshift

        ## Load CLASS and set parameters
        if verb: print('Loading CLASS')
        self.cosmo = Class()
        self.cosmo.set(class_params)
        self.cosmo.compute()
        self.h = self.cosmo.h()
        self.name = name
        self.npoints = npoints
        self.verb = verb

        ## Check if we're using neutrinos here
        if self.cosmo.Omega_nu>0.:
            if self.verb: print("Using a neutrino fraction of Omega_nu = %.3e"%self.cosmo.Omega_nu)
            self.use_neutrinos = True
            # Define neutrino mass fraction
            self.f_nu = self.cosmo.Omega_nu/self.cosmo.Omega_m()
            if self.cosmo.Neff()>3.5:
                print("N_eff > 3.5, which seems large (standard value: 3.046). This may indicate that N_ur has not been set.")
        else:
            if self.verb: print("Assuming massless neturinos.")
            self.use_neutrinos = False

        ## Create a vectorized sigma(R) function from CLASS
        if self.use_neutrinos:
            self.vector_sigma_R = np.vectorize(lambda r: self.cosmo.sigma_cb(r/self.h,self.z))
        else:
            self.vector_sigma_R = np.vectorize(lambda r: self.cosmo.sigma(r/self.h,self.z))

        # get density in physical units at z = 0
        # rho_critical is in Msun/h / (Mpc/h)^3 units
        # rhoM is in **physical** units of Msun/Mpc^3
        self.rho_critical = ((3.*100.*100.)/(8.*np.pi*6.67408e-11)) * (1000.*1000.*3.085677581491367399198952281E+22/1.9884754153381438E+30)
        self.rhoM = self.rho_critical*self.cosmo.Omega0_m()

    def compute_linear_power(self,kh,kh_min=0.,with_neutrinos=False):
        """Compute the linear power spectrum from CLASS for a vector of input k.

        If set, we remove any modes below some minimum k.

        Args:
            kh (float, np.ndarray): Wavenumber or vector of wavenumbers (in h/Mpc units) to compute linear power with.

        Keyword Args:
            kh_min (float): Value of k (in h/Mpc units) below which to set :math:`P(k) = 0`, default: 0.
            with_neutrinos (bool): If True, return the full matter power spectrum, else return the CDM+baryon power spectrum (which is generally used in the halo model). Default: False.

        Returns:
            np.ndarray: Linear power spectrum in :math:`(h^{-1}\mathrm{Mpc})^3` units
        """

        if type(kh)==np.ndarray:

            # Define output vector and filter modes with too-small k
            output = np.zeros_like(kh)
            filt = np.where(kh>kh_min)
            N_k = len(filt[0])

            # Compute Pk using CLASS (vectorized)
            if not hasattr(self,'vector_linear_power'):
                ## NB: This works in physical 1/Mpc units so we convert here
                if self.use_neutrinos:
                    # Here we need both the CDM+baryon (cb) power spectra and the full matter power spectra
                    # The CDM+baryon spectrum is used for the halo model parts, and the residual (matter-cb) added at the end
                    self.vector_linear_power = np.vectorize(lambda k: self.cosmo.pk_cb_lin(k*self.h,self.z)*self.h**3.)
                    self.vector_linear_power_total = np.vectorize(lambda k: self.cosmo.pk_lin(k*self.h,self.z)*self.h**3.)
                else:
                    self.vector_linear_power = np.vectorize(lambda k: self.cosmo.pk_lin(k*self.h,self.z)*self.h**3.)

            if self.use_neutrinos and with_neutrinos:
                output[filt] = self.vector_linear_power_total(kh[filt])
            else:
                output[filt] = self.vector_linear_power(kh[filt])
            return output

        else:
            if kh<kh_min:
                return 0.
            else:
                if self.use_neutrinos and with_neutrinos:
                    return self.vector_linear_power_total(kh)
                else:
                    return self.vector_linear_power(kh)

    def sigma_logM_int(self,logM_h):
        """Return the value of :math:`\sigma(M,z)` using the prebuilt interpolators, which are constructed if not present.

        Args:
            logM (np.ndarray): Input :math:`\log_{10}(M/h^{-1}M_\mathrm{sun})`

        Returns:
            np.ndarray: :math:`\sigma(M,z)`
        """
        if not hasattr(self,'sigma_logM_int_func'):
            self._interpolate_sigma_and_deriv(npoints=self.npoints)
        return self._sigma_logM_int_func(logM_h)

    def dlns_dlogM_int(self,logM_h):
        """Return the value of :math:`d\ln\sigma/d\log M` using the prebuilt interpolators, which are constructed if not present.

        Args:
            logM (np.ndarray): Input :math:`\log_{10}(M/h^{-1}M_\mathrm{sun})`

        Returns:
            np.ndarray: :math:`d\ln\sigma/d\log M`
        """
        if not hasattr(self,'dlns_dlogM_int_func'):
            self._interpolate_sigma_and_deriv(npoints=self.npoints)
        return self._dlns_dlogM_int_func(logM_h)

    def _sigmaM(self,M_h):
        """Compute :math:`\sigma(M,z)` from CLASS as a vector function.

        Args:
            M_h (np.ndarray): Mass in :math:`h^{-1}M_\mathrm{sun}` units.
            z (float): Redshift.

        Returns:
            np.ndarray: :math:`\sigma(M,z)`
        """
        # convert to Lagrangian radius
        r_h = np.power((3.*M_h)/(4.*np.pi*self.rhoM),1./3.)
        sigma_func = self.vector_sigma_R(r_h)
        return sigma_func

    def _interpolate_sigma_and_deriv(self,logM_h_min=6,logM_h_max=17,npoints=int(1e5)):
        """Create an interpolator function for :math:`d\ln\sigma/d\log M` and :math:`sigma(M)`.

        NB: This has no effect if the interpolator has already been computed.

        Keyword Args:
            logM_min (float): Minimum mass in :math:`\log_{10}(M/h^{-1}M_\mathrm{sun})`, default: 6
            logM_max (float): Maximum mass in :math:`\log_{10}(M/h^{-1}M_\mathrm{sun})`, default 17
            npoints (int): Number of sampling points, default 100000

        """

        if not hasattr(self,'_sigma_logM_int_func'):
            if self.verb: print("Creating an interpolator for sigma(M) and its derivative.")
            ## Compute log derivative by interpolation and numerical differentiation
            # First compute the grid of M and sigma
            M_h_grid = np.logspace(logM_h_min,logM_h_max,10000)
            all_sigM = self._sigmaM(M_h_grid)
            logM_h_grid = np.log10(M_h_grid)

            # Define ln(sigma) and numerical derivatives
            all_lns = np.log(all_sigM)
            all_diff = -np.diff(all_lns)/np.diff(logM_h_grid)
            mid_logM_h = 0.5*(logM_h_grid[:-1]+logM_h_grid[1:])

            self._sigma_logM_int_func = interp1d(logM_h_grid,all_sigM)
            self._dlns_dlogM_int_func = interp1d(mid_logM_h,all_diff)

    def _h_over_h0(self):
        """Return the value of :math:`H(z)/H(0)` at the class redshift

        Returns:
            float: :math:`H(z)/H(0)`
        """
        Omega0_k = 1.-self.cosmo.Omega0_m()-self.cosmo.Omega_Lambda()
        Ea = np.sqrt((self.cosmo.Omega0_m()+self.cosmo.Omega_Lambda()*pow(self.a,-3)+Omega0_k*self.a)/pow(self.a,3))
        return Ea

    def _Omega_m(self):
        """Return the value of :math:`\Omega_m(z)` at the class redshift
Ejemplo n.º 7
0
class classy(BoltzmannBase):
    # Name of the Class repo/folder and version to download
    _classy_repo_name = "lesgourg/class_public"
    _min_classy_version = "v2.9.3"
    _classy_repo_version = os.environ.get('CLASSY_REPO_VERSION', _min_classy_version)

    def initialize(self):
        """Importing CLASS from the correct path, if given, and if not, globally."""
        # Allow global import if no direct path specification
        allow_global = not self.path
        if not self.path and self.packages_path:
            self.path = self.get_path(self.packages_path)
        self.classy_module = self.is_installed(path=self.path, allow_global=allow_global)
        if not self.classy_module:
            raise NotInstalledError(
                self.log, "Could not find CLASS. Check error message above.")
        from classy import Class, CosmoSevereError, CosmoComputationError
        global CosmoComputationError, CosmoSevereError
        self.classy = Class()
        super().initialize()
        # Add general CLASS stuff
        self.extra_args["output"] = self.extra_args.get("output", "")
        if "sBBN file" in self.extra_args:
            self.extra_args["sBBN file"] = (
                self.extra_args["sBBN file"].format(classy=self.path))
        # Derived parameters that may not have been requested, but will be necessary later
        self.derived_extra = []
        self.log.info("Initialized!")

    def must_provide(self, **requirements):
        # Computed quantities required by the likelihood
        super().must_provide(**requirements)
        for k, v in self._must_provide.items():
            # Products and other computations
            if k == "Cl":
                if any(("t" in cl.lower()) for cl in v):
                    self.extra_args["output"] += " tCl"
                if any((("e" in cl.lower()) or ("b" in cl.lower())) for cl in v):
                    self.extra_args["output"] += " pCl"
                # For modern experiments, always lensed Cl's!
                self.extra_args["output"] += " lCl"
                self.extra_args["lensing"] = "yes"
                # For l_max_scalars, remember previous entries.
                self.extra_args["l_max_scalars"] = max(v.values())
                self.collectors[k] = Collector(
                    method="lensed_cl", kwargs={"lmax": self.extra_args["l_max_scalars"]})
                if 'T_cmb' not in self.derived_extra:
                    self.derived_extra += ['T_cmb']
            elif k == "Hubble":
                self.collectors[k] = Collector(
                    method="Hubble",
                    args=[np.atleast_1d(v["z"])],
                    args_names=["z"],
                    arg_array=0)
            elif k == "angular_diameter_distance":
                self.collectors[k] = Collector(
                    method="angular_distance",
                    args=[np.atleast_1d(v["z"])],
                    args_names=["z"],
                    arg_array=0)
            elif k == "comoving_radial_distance":
                self.collectors[k] = Collector(
                    method="z_of_r",
                    args_names=["z"],
                    args=[np.atleast_1d(v["z"])])
            elif isinstance(k, tuple) and k[0] == "Pk_grid":
                self.extra_args["output"] += " mPk"
                v = deepcopy(v)
                self.add_P_k_max(v.pop("k_max"), units="1/Mpc")
                # NB: Actually, only the max z is used, and the actual sampling in z
                # for computing P(k,z) is controlled by `perturb_sampling_stepsize`
                # (default: 0.1). But let's leave it like this in case this changes
                # in the future.
                self.add_z_for_matter_power(v.pop("z"))

                if v["nonlinear"] and "non linear" not in self.extra_args:
                    self.extra_args["non linear"] = non_linear_default_code
                pair = k[2:]
                if pair == ("delta_tot", "delta_tot"):
                    v["only_clustering_species"] = False
                elif pair == ("delta_nonu", "delta_nonu"):
                    v["only_clustering_species"] = True
                else:
                    raise LoggedError(self.log, "NotImplemented in CLASS: %r", pair)
                self.collectors[k] = Collector(
                    method="get_pk_and_k_and_z",
                    kwargs=v,
                    post=(lambda P, kk, z: (kk, z, np.array(P).T)))
            elif isinstance(k, tuple) and k[0] == "sigma_R":
                raise LoggedError(
                    self.log, "Classy sigma_R not implemented as yet - use CAMB only")
            elif v is None:
                k_translated = self.translate_param(k)
                if k_translated not in self.derived_extra:
                    self.derived_extra += [k_translated]
            else:
                raise LoggedError(self.log, "Requested product not known: %r", {k: v})
        # Derived parameters (if some need some additional computations)
        if any(("sigma8" in s) for s in self.output_params or requirements):
            self.extra_args["output"] += " mPk"
            self.add_P_k_max(1, units="1/Mpc")
        # Adding tensor modes if requested
        if self.extra_args.get("r") or "r" in self.input_params:
            self.extra_args["modes"] = "s,t"
        # If B spectrum with l>50, or lensing, recommend using Halofit
        cls = self._must_provide.get("Cl", {})
        has_BB_l_gt_50 = (any(("b" in cl.lower()) for cl in cls) and
                          max(cls[cl] for cl in cls if "b" in cl.lower()) > 50)
        has_lensing = any(("p" in cl.lower()) for cl in cls)
        if (has_BB_l_gt_50 or has_lensing) and not self.extra_args.get("non linear"):
            self.log.warning("Requesting BB for ell>50 or lensing Cl's: "
                             "using a non-linear code is recommended (and you are not "
                             "using any). To activate it, set "
                             "'non_linear: halofit|hmcode|...' in classy's 'extra_args'.")
        # Cleanup of products string
        self.extra_args["output"] = " ".join(set(self.extra_args["output"].split()))
        self.check_no_repeated_input_extra()

    def add_z_for_matter_power(self, z):
        if getattr(self, "z_for_matter_power", None) is None:
            self.z_for_matter_power = np.empty(0)
        self.z_for_matter_power = np.flip(np.sort(np.unique(np.concatenate(
            [self.z_for_matter_power, np.atleast_1d(z)]))), axis=0)
        self.extra_args["z_pk"] = " ".join(["%g" % zi for zi in self.z_for_matter_power])

    def add_P_k_max(self, k_max, units):
        r"""
        Unifies treatment of :math:`k_\mathrm{max}` for matter power spectrum:
        ``P_k_max_[1|h]/Mpc]``.

        Make ``units="1/Mpc"|"h/Mpc"``.
        """
        # Fiducial h conversion (high, though it may slow the computations)
        h_fid = 1
        if units == "h/Mpc":
            k_max *= h_fid
        # Take into account possible manual set of P_k_max_***h/Mpc*** through extra_args
        k_max_old = self.extra_args.pop(
            "P_k_max_1/Mpc", h_fid * self.extra_args.pop("P_k_max_h/Mpc", 0))
        self.extra_args["P_k_max_1/Mpc"] = max(k_max, k_max_old)

    def set(self, params_values_dict):
        # If no output requested, remove arguments that produce an error
        # (e.g. complaints if halofit requested but no Cl's computed.)
        # Needed for facilitating post-processing
        if not self.extra_args["output"]:
            for k in ["non linear"]:
                self.extra_args.pop(k, None)
        # Prepare parameters to be passed: this-iteration + extra
        args = {self.translate_param(p): v for p, v in params_values_dict.items()}
        args.update(self.extra_args)
        # Generate and save
        self.log.debug("Setting parameters: %r", args)
        self.classy.set(**args)

    def calculate(self, state, want_derived=True, **params_values_dict):
        # Set parameters
        self.set(params_values_dict)
        # Compute!
        try:
            self.classy.compute()
        # "Valid" failure of CLASS: parameters too extreme -> log and report
        except CosmoComputationError as e:
            if self.stop_at_error:
                self.log.error(
                    "Computation error (see traceback below)! "
                    "Parameters sent to CLASS: %r and %r.\n"
                    "To ignore this kind of error, make 'stop_at_error: False'.",
                    state["params"], dict(self.extra_args))
                raise
            else:
                self.log.debug("Computation of cosmological products failed. "
                               "Assigning 0 likelihood and going on. "
                               "The output of the CLASS error was %s" % e)
            return False
        # CLASS not correctly initialized, or input parameters not correct
        except CosmoSevereError:
            self.log.error("Serious error setting parameters or computing results. "
                           "The parameters passed were %r and %r. To see the original "
                           "CLASS' error traceback, make 'debug: True'.",
                           state["params"], self.extra_args)
            raise  # No LoggedError, so that CLASS traceback gets printed
        # Gather products
        for product, collector in self.collectors.items():
            # Special case: sigma8 needs H0, which cannot be known beforehand:
            if "sigma8" in self.collectors:
                self.collectors["sigma8"].args[0] = 8 / self.classy.h()
            method = getattr(self.classy, collector.method)
            arg_array = self.collectors[product].arg_array
            if arg_array is None:
                state[product] = method(
                    *self.collectors[product].args, **self.collectors[product].kwargs)
            elif isinstance(arg_array, int):
                state[product] = np.zeros(
                    len(self.collectors[product].args[arg_array]))
                for i, v in enumerate(self.collectors[product].args[arg_array]):
                    args = (list(self.collectors[product].args[:arg_array]) + [v] +
                            list(self.collectors[product].args[arg_array + 1:]))
                    state[product][i] = method(
                        *args, **self.collectors[product].kwargs)
            elif arg_array in self.collectors[product].kwargs:
                value = np.atleast_1d(self.collectors[product].kwargs[arg_array])
                state[product] = np.zeros(value.shape)
                for i, v in enumerate(value):
                    kwargs = deepcopy(self.collectors[product].kwargs)
                    kwargs[arg_array] = v
                    state[product][i] = method(
                        *self.collectors[product].args, **kwargs)
            if collector.post:
                state[product] = collector.post(*state[product])
        # Prepare derived parameters
        d, d_extra = self._get_derived_all(derived_requested=want_derived)
        if want_derived:
            state["derived"] = {p: d.get(p) for p in self.output_params}
            # Prepare necessary extra derived parameters
        state["derived_extra"] = deepcopy(d_extra)

    def _get_derived_all(self, derived_requested=True):
        """
        Returns a dictionary of derived parameters with their values,
        using the *current* state (i.e. it should only be called from
        the ``compute`` method).

        Parameter names are returned in CLASS nomenclature.

        To get a parameter *from a likelihood* use `get_param` instead.
        """
        # TODO: fails with derived_requested=False
        # Put all parameters in CLASS nomenclature (self.derived_extra already is)
        requested = [self.translate_param(p) for p in (
            self.output_params if derived_requested else [])]
        requested_and_extra = dict.fromkeys(set(requested).union(set(self.derived_extra)))
        # Parameters with their own getters
        if "rs_drag" in requested_and_extra:
            requested_and_extra["rs_drag"] = self.classy.rs_drag()
        if "Omega_nu" in requested_and_extra:
            requested_and_extra["Omega_nu"] = self.classy.Omega_nu
        if "T_cmb" in requested_and_extra:
            requested_and_extra["T_cmb"] = self.classy.T_cmb()
        # Get the rest using the general derived param getter
        # No need for error control: classy.get_current_derived_parameters is passed
        # every derived parameter not excluded before, and cause an error, indicating
        # which parameters are not recognized
        requested_and_extra.update(
            self.classy.get_current_derived_parameters(
                [p for p, v in requested_and_extra.items() if v is None]))
        # Separate the parameters before returning
        # Remember: self.output_params is in sampler nomenclature,
        # but self.derived_extra is in CLASS
        derived = {
            p: requested_and_extra[self.translate_param(p)] for p in self.output_params}
        derived_extra = {p: requested_and_extra[p] for p in self.derived_extra}
        return derived, derived_extra

    def get_Cl(self, ell_factor=False, units="FIRASmuK2"):
        try:
            cls = deepcopy(self._current_state["Cl"])
        except:
            raise LoggedError(
                self.log,
                "No Cl's were computed. Are you sure that you have requested them?")
        # unit conversion and ell_factor
        ells_factor = ((cls["ell"] + 1) * cls["ell"] / (2 * np.pi))[
                      2:] if ell_factor else 1
        units_factor = self._cmb_unit_factor(
            units, self._current_state['derived_extra']['T_cmb'])

        for cl in cls:
            if cl not in ['pp', 'ell']:
                cls[cl][2:] *= units_factor ** 2 * ells_factor
        if "pp" in cls and ell_factor:
            cls['pp'][2:] *= ells_factor ** 2 * (2 * np.pi)
        return cls

    def _get_z_dependent(self, quantity, z):
        try:
            z_name = next(k for k in ["redshifts", "z"]
                          if k in self.collectors[quantity].kwargs)
            computed_redshifts = self.collectors[quantity].kwargs[z_name]
        except StopIteration:
            computed_redshifts = self.collectors[quantity].args[
                self.collectors[quantity].args_names.index("z")]
        i_kwarg_z = np.concatenate(
            [np.where(computed_redshifts == zi)[0] for zi in np.atleast_1d(z)])
        values = np.array(deepcopy(self._current_state[quantity]))
        if quantity == "comoving_radial_distance":
            values = values[0]
        return values[i_kwarg_z]

    def close(self):
        self.classy.empty()

    def get_can_provide_params(self):
        names = ['Omega_Lambda', 'Omega_cdm', 'Omega_b', 'Omega_m', 'rs_drag', 'z_reio',
                 'YHe', 'Omega_k', 'age', 'sigma8']
        for name, mapped in self.renames.items():
            if mapped in names:
                names.append(name)
        return names

    def get_version(self):
        return getattr(self.classy_module, '__version__', None)

    # Installation routines

    @classmethod
    def get_path(cls, path):
        return os.path.realpath(os.path.join(path, "code", cls.__name__))

    @classmethod
    def get_import_path(cls, path):
        log = logging.getLogger(cls.__name__)
        classy_build_path = os.path.join(path, "python", "build")
        if not os.path.isdir(classy_build_path):
            log.error("Either CLASS is not in the given folder, "
                      "'%s', or you have not compiled it.", path)
            return None
        py_version = "%d.%d" % (sys.version_info.major, sys.version_info.minor)
        try:
            post = next(d for d in os.listdir(classy_build_path)
                        if (d.startswith("lib.") and py_version in d))
        except StopIteration:
            log.error("The CLASS installation at '%s' has not been compiled for the "
                      "current Python version.", path)
            return None
        return os.path.join(classy_build_path, post)

    @classmethod
    def is_compatible(cls):
        import platform
        if platform.system() == "Windows":
            return False
        return True

    @classmethod
    def is_installed(cls, **kwargs):
        log = logging.getLogger(cls.__name__)
        if not kwargs.get("code", True):
            return True
        path = kwargs["path"]
        if path is not None and path.lower() == "global":
            path = None
        if path and not kwargs.get("allow_global"):
            log.info("Importing *local* CLASS from '%s'.", path)
            if not os.path.exists(path):
                log.error("The given folder does not exist: '%s'", path)
                return False
            classy_build_path = cls.get_import_path(path)
            if not classy_build_path:
                return False
        elif not path:
            log.info("Importing *global* CLASS.")
            classy_build_path = None
        else:
            log.info("Importing *auto-installed* CLASS (but defaulting to *global*).")
            classy_build_path = cls.get_import_path(path)
        try:
            return load_module(
                'classy', path=classy_build_path, min_version=cls._classy_repo_version)
        except ImportError:
            if path is not None and path.lower() != "global":
                log.error("Couldn't find the CLASS python interface at '%s'. "
                          "Are you sure it has been installed there?", path)
            else:
                log.error("Could not import global CLASS installation. "
                          "Specify a Cobaya or CLASS installation path, "
                          "or install the CLASS Python interface globally with "
                          "'cd /path/to/class/python/ ; python setup.py install'")
            return False
        except VersionCheckError as e:
            log.error(str(e))
            return False

    @classmethod
    def install(cls, path=None, force=False, code=True, no_progress_bars=False, **kwargs):
        log = logging.getLogger(cls.__name__)
        if not code:
            log.info("Code not requested. Nothing to do.")
            return True
        log.info("Installing pre-requisites...")
        exit_status = pip_install("cython")
        if exit_status:
            log.error("Could not install pre-requisite: cython")
            return False
        log.info("Downloading classy...")
        success = download_github_release(
            os.path.join(path, "code"), cls._classy_repo_name, cls._classy_repo_version,
            repo_rename=cls.__name__, no_progress_bars=no_progress_bars, logger=log)
        if not success:
            log.error("Could not download classy.")
            return False
        classy_path = cls.get_path(path)
        log.info("Compiling classy...")
        from subprocess import Popen, PIPE
        env = deepcopy(os.environ)
        env.update({"PYTHON": sys.executable})
        process_make = Popen(["make"], cwd=classy_path, stdout=PIPE, stderr=PIPE, env=env)
        out, err = process_make.communicate()
        if process_make.returncode:
            log.info(out)
            log.info(err)
            log.error("Compilation failed!")
            return False
        return True
Ejemplo n.º 8
0
plt.ylabel(r'$[\ell(\ell+1)/2\pi]  C_\ell^\mathrm{TT}$')
plt.plot(ll,clTT*ll*(ll+1)/2./pi,'r-')


# In[ ]:

plt.savefig('warmup_cltt.pdf')


# In[ ]:

# get P(k) at redhsift z=0
import numpy as np
kk = np.logspace(-4,np.log10(3),1000) # k in h/Mpc
Pk = [] # P(k) in (Mpc/h)**3
h = LambdaCDM.h() # get reduced Hubble for conversions to 1/Mpc
for k in kk:
    Pk.append(LambdaCDM.pk(k*h,0.)*h**3) # function .pk(k,z)


# In[ ]:

# plot P(k)
plt.figure(2)
plt.xscale('log');plt.yscale('log');plt.xlim(kk[0],kk[-1])
plt.xlabel(r'$k \,\,\,\, [h/\mathrm{Mpc}]$')
plt.ylabel(r'$P(k) \,\,\,\, [\mathrm{Mpc}/h]^3$')
plt.plot(kk,Pk,'b-')


# In[ ]:
Ejemplo n.º 9
0
class tsz_cl:
    def __init__(self):
        self.fort_lib_cl = cdll.LoadLibrary(LIBDIR + "/source/calc_cl")
        self.fort_lib_cl.calc_cl_.argtypes = [
            POINTER(c_double),  #h0
            POINTER(c_double),  #obh2
            POINTER(c_double),  #och2
            POINTER(c_double),  #mnu
            POINTER(c_double),  #bias
            POINTER(c_int64),  #pk_nk
            POINTER(c_int64),  #pk_nz
            np.ctypeslib.ndpointer(dtype=np.double),  #karr
            np.ctypeslib.ndpointer(dtype=np.double),  #pkarr
            np.ctypeslib.ndpointer(dtype=np.double),  #pk_z_arr
            POINTER(c_int64),  #n_ell_ptilde
            np.ctypeslib.ndpointer(dtype=np.double),  #ell_ptilde
            np.ctypeslib.ndpointer(dtype=np.double),  #ptilde_arr
            POINTER(c_int64),  #nl
            np.ctypeslib.ndpointer(dtype=np.double),  #ell
            np.ctypeslib.ndpointer(dtype=np.double),  #yy
            np.ctypeslib.ndpointer(dtype=np.double),  #tll
            POINTER(c_int64),  #flag_nu
            POINTER(c_int64),  #flag_tll
            POINTER(c_double),  #zmin
            POINTER(c_double),  #zmax
            POINTER(c_double),  #Mmin 
            POINTER(c_double)  #Mmax
        ]
        self.fort_lib_cl.calc_cl_.restype = c_void_p

        self.fort_lib_by = cdll.LoadLibrary(LIBDIR + "/source/calc_by")
        self.fort_lib_by.calc_by_.argtypes = [
            POINTER(c_double),  #h0
            POINTER(c_double),  #obh2
            POINTER(c_double),  #och2
            POINTER(c_double),  #mnu
            POINTER(c_double),  #bias
            POINTER(c_int64),  #pk_nk
            np.ctypeslib.ndpointer(dtype=np.double),  #karr
            np.ctypeslib.ndpointer(dtype=np.double),  #pkarr
            POINTER(c_int64),  #n_ell_ptilde
            np.ctypeslib.ndpointer(dtype=np.double),  #ell_ptilde
            np.ctypeslib.ndpointer(dtype=np.double),  #ptilde_arr
            POINTER(c_int64),  #nz
            np.ctypeslib.ndpointer(dtype=np.double),  #z_arr
            np.ctypeslib.ndpointer(dtype=np.double),  #by_arr
            np.ctypeslib.ndpointer(dtype=np.double),  #dydz_arr
            POINTER(c_int64),  #flag_nu
            POINTER(c_double),  #Mmin 
            POINTER(c_double)  #Mmax
        ]
        self.fort_lib_by.calc_by_.restype = c_void_p

        self.fort_lib_dydzdMh = cdll.LoadLibrary(LIBDIR +
                                                 "/source/calc_dydzdMh")
        self.fort_lib_dydzdMh.calc_dydzdmh_.argtypes = [
            POINTER(c_double),  #h0
            POINTER(c_double),  #obh2
            POINTER(c_double),  #och2
            POINTER(c_double),  #mnu
            POINTER(c_double),  #bias
            POINTER(c_int64),  #pk_nk
            POINTER(c_int64),  #pk_nz
            np.ctypeslib.ndpointer(dtype=np.double),  #karr
            np.ctypeslib.ndpointer(dtype=np.double),  #pkarr
            POINTER(c_int64),  #n_ell_ptilde
            np.ctypeslib.ndpointer(dtype=np.double),  #ell_ptilde
            np.ctypeslib.ndpointer(dtype=np.double),  #ptilde_arr
            POINTER(c_double),  # z
            POINTER(c_double),  # Mh
            POINTER(c_double),  # dydzdMh
            POINTER(c_int64),  #flag_nu
        ]
        self.fort_lib_dydzdMh.calc_dydzdmh_.restype = c_void_p

        # Calcualtion setup
        self.kmin = 1e-3
        self.kmax = 5.
        self.zmin = 1e-5
        self.zmax = 4.
        self.dz = 0.04
        self.nk_pk = 200
        self.nz_pk = int((self.zmax - self.zmin) / self.dz) + 1
        self.Mmin = 1e11
        self.Mmax = 5e15
        self.ptilde_in = np.loadtxt(LIBDIR + '/data/ptilde.txt')
        self.ell_ptilde = np.array(self.ptilde_in[:, 0])
        self.ptilde_arr = np.array(self.ptilde_in[:, 1])
        self.n_ptilde = len(self.ell_ptilde)

        # Class
        self.cosmo = Class()

    def get_tsz_cl(self,
                   ell_arr,
                   params,
                   zmin=None,
                   zmax=None,
                   Mmin=None,
                   Mmax=None):
        # integration range, optional
        if zmin == None: zmin = self.zmin
        if zmax == None: zmax = self.zmax
        nz_pk = int((zmax - zmin) / self.dz) + 1
        if Mmin == None: Mmin = self.Mmin
        if Mmax == None: Mmax = self.Mmax

        obh2 = params['obh2']
        och2 = params['och2']
        As = params['As']
        ns = params['ns']
        mnu = params['mnu']
        mass_bias = params['mass_bias']
        flag_nu_logic = params['flag_nu']
        flag_tll_logic = params['flag_tll']
        if type(flag_nu_logic) != bool:
            print('flag_nu must be boolean.')
            sys.exit()
        if type(flag_tll_logic) != bool:
            print('flag_tll must be boolean.')
            sys.exit()

        if flag_nu_logic:
            flag_nu = 1
        else:
            flag_nu = 0
        if flag_tll_logic:
            flag_tll = 1
        else:
            flag_tll = 0

        if 'theta' in params.keys():
            theta = params['theta']
            pars = {'output':'mPk','100*theta_s':theta,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':self.zmax,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()
            h0 = self.cosmo.h()
        elif 'h0' in params.keys():
            h0 = params['h0']
            pars = {'output':'mPk','h':h0,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':self.zmax,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()

        kh_arr = np.logspace(np.log10(self.kmin), np.log10(self.kmax),
                             self.nk_pk)
        kh = np.zeros((nz_pk, self.nk_pk))
        pk = np.zeros((nz_pk, self.nk_pk))
        pk_zarr = np.linspace(zmin, zmax, nz_pk + 1)
        for i in range(self.nz_pk):
            kh[i, :] = kh_arr
            if flag_nu == 0:
                pk[i, :] = np.array([
                    self.cosmo.pk(k * h0, pk_zarr[i]) * h0**3 for k in kh_arr
                ])
            elif flag_nu == 1:
                pk[i, :] = np.array([
                    self.cosmo.pk_cb(k * h0, pk_zarr[i]) * h0**3
                    for k in kh_arr
                ])

        ####  set variables for fortran codes ###
        nk = byref(c_int64(self.nk_pk))  # indx_z, indx_k
        nz = byref(c_int64(self.nz_pk))

        # params
        h0_in = byref(c_double(h0))
        obh2_in = byref(c_double(obh2))
        och2_in = byref(c_double(och2))
        mnu_in = byref(c_double(mnu))
        mass_bias_in = byref(c_double(mass_bias))
        flag_nu_in = byref(c_int64(flag_nu))
        flag_tll_in = byref(c_int64(flag_tll))
        zmin_in = byref(c_double(zmin))
        zmax_in = byref(c_double(zmax))
        Mmin_in = byref(c_double(Mmin))
        Mmax_in = byref(c_double(Mmax))

        # outputs
        nl = len(ell_arr)
        cl_yy = np.zeros((2, nl))
        tll = np.zeros((nl, nl))
        nl = c_int64(nl)

        self.fort_lib_cl.calc_cl_(
                h0_in, obh2_in, och2_in, mnu_in,\
                mass_bias_in, nk, nz,\
                np.array(kh),np.array(pk),np.array(pk_zarr),\
                byref(c_int64(self.n_ptilde)), self.ell_ptilde, self.ptilde_arr,\
                nl,np.array(ell_arr),\
                cl_yy,tll,\
                flag_nu_in,flag_tll_in,\
                zmin_in,zmax_in,\
                Mmin_in,Mmax_in
                )

        self.cosmo.struct_cleanup()
        return cl_yy, tll

    def get_by_dydz(self, z_arr, params, Mmin=None, Mmax=None):
        if Mmin == None: Mmin = self.Mmin
        if Mmax == None: Mmax = self.Mmax
        nz = len(z_arr)
        zmax = np.max(z_arr)

        obh2 = params['obh2']
        och2 = params['och2']
        As = params['As']
        ns = params['ns']
        mnu = params['mnu']
        mass_bias = params['mass_bias']
        flag_nu_logic = params['flag_nu']
        if type(flag_nu_logic) != bool:
            print('flag_nu must be boolean.')
            sys.exit()

        if flag_nu_logic:
            flag_nu = 1
        else:
            flag_nu = 0

        if 'theta' in params.keys():
            theta = params['theta']
            pars = {'output':'mPk','100*theta_s':theta,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':zmax,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()
            h0 = self.cosmo.h()
        elif 'h0' in params.keys():
            h0 = params['h0']
            pars = {'output':'mPk','h':h0,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':zmax,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()

        kh_arr = np.logspace(np.log10(self.kmin), np.log10(self.kmax),
                             self.nk_pk)
        kh = np.zeros((nz, self.nk_pk))
        pk = np.zeros((nz, self.nk_pk))
        for i in range(nz):
            kh[i, :] = kh_arr
            if flag_nu == 0:
                pk[i, :] = np.array(
                    [self.cosmo.pk(k * h0, z_arr[i]) * h0**3 for k in kh_arr])
            elif flag_nu == 1:
                pk[i, :] = np.array([
                    self.cosmo.pk_cb(k * h0, z_arr[i]) * h0**3 for k in kh_arr
                ])

        ####  set variables for fortran codes ###
        nk = byref(c_int64(self.nk_pk))  # indx_z, indx_k

        # params
        h0_in = byref(c_double(h0))
        obh2_in = byref(c_double(obh2))
        och2_in = byref(c_double(och2))
        mnu_in = byref(c_double(mnu))
        mass_bias_in = byref(c_double(mass_bias))
        flag_nu_in = byref(c_int64(flag_nu))

        # outputs
        by_arr = np.zeros(nz)
        dydz_arr = np.zeros(nz)
        nz = c_int64(nz)
        Mmin_in = byref(c_double(Mmin))
        Mmax_in = byref(c_double(Mmax))

        self.fort_lib_by.calc_by_(
                h0_in, obh2_in, och2_in, mnu_in, \
                mass_bias_in, nk, \
                np.array(kh),np.array(pk), \
                byref(c_int64(self.n_ptilde)), self.ell_ptilde, self.ptilde_arr,\
                nz,np.array(z_arr), \
                by_arr,dydz_arr, \
                flag_nu_in, \
                Mmin_in, Mmax_in
                )

        self.cosmo.struct_cleanup()
        return by_arr, dydz_arr

    def get_dydzdlogMh(self, z, Mh, params):
        obh2 = params['obh2']
        och2 = params['och2']
        As = params['As']
        ns = params['ns']
        mnu = params['mnu']
        mass_bias = params['mass_bias']
        flag_nu_logic = params['flag_nu']
        if type(flag_nu_logic) != bool:
            print('flag_nu must be boolean.')
            sys.exit()

        if flag_nu_logic:
            flag_nu = 1
        else:
            flag_nu = 0

        if 'theta' in params.keys():
            theta = params['theta']
            pars = {'output':'mPk','100*theta_s':theta,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':z,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()
            h0 = self.cosmo.h()
        elif 'h0' in params.keys():
            h0 = params['h0']
            pars = {'output':'mPk','h':h0,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':z,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()

        kh_arr = np.logspace(np.log10(self.kmin), np.log10(self.kmax),
                             self.nk_pk)
        kh = np.zeros((1, self.nk_pk))
        pk = np.zeros((1, self.nk_pk))
        kh[0, :] = kh_arr
        if flag_nu == 0:
            pk[0, :] = np.array(
                [self.cosmo.pk(k * h0, z) * h0**3 for k in kh_arr])
        elif flag_nu == 1:
            pk[0, :] = np.array(
                [self.cosmo.pk_cb(k * h0, z) * h0**3 for k in kh_arr])

        ####  set variables for fortran codes ###
        nk = byref(c_int64(self.nk_pk))  # indx_z, indx_k
        nz = byref(c_int64(1))

        # params
        h0_in = byref(c_double(h0))
        obh2_in = byref(c_double(obh2))
        och2_in = byref(c_double(och2))
        mnu_in = byref(c_double(mnu))
        mass_bias_in = byref(c_double(mass_bias))
        flag_nu_in = byref(c_int64(flag_nu))

        # outputs
        z_in = byref(c_double(z))
        Mh_in = byref(c_double(Mh))
        dydzdMh = c_double(0.0)

        self.fort_lib_dydzdMh.calc_dydzdmh_(
                h0_in, obh2_in, och2_in, mnu_in, \
                mass_bias_in, nk, nz, \
                np.array(kh),np.array(pk), \
                byref(c_int64(self.n_ptilde)), self.ell_ptilde, self.ptilde_arr,\
                z_in,Mh_in, \
                dydzdMh, \
                flag_nu_in \
                )

        self.cosmo.struct_cleanup()
        return dydzdMh.value
Ejemplo n.º 10
0
tau2[-1] *= 0.999 # this tiny shift avoids interpolation errors
tau = np.concatenate((tau1,tau2))
tau_num = len(tau)
#
# use table of background and thermodynamics quantitites to define some functions
# returning some characteristic scales
# (of Hubble crossing, sound horizon crossing, etc.) at different time
#
background = M.get_background() # load background table
#print background.viewkeys()
thermodynamics = M.get_thermodynamics() # load thermodynamics table
#print thermodynamics.viewkeys()
#
background_tau = background['conf. time [Mpc]'] # read conformal times in background table
background_z = background['z'] # read redshift
background_aH = 2.*math.pi*background['H [1/Mpc]']/(1.+background['z'])/M.h() # read 2pi * aH in [h/Mpc]
background_ks = 2.*math.pi/background['comov.snd.hrz.']/M.h() # read 2pi/(comoving sound horizon) in [h/Mpc]
background_rho_m_over_r =    (background['(.)rho_b']+background['(.)rho_cdm'])    /(background['(.)rho_g']+background['(.)rho_ur']) # read rho_r / rho_m (to find time of equality)
background_rho_l_over_m =    background['(.)rho_lambda']    /(background['(.)rho_b']+background['(.)rho_cdm']) # read rho_m / rho_lambda (to find time of equality)
thermodynamics_tau = thermodynamics['conf. time [Mpc]'] # read confromal times in thermodynamics table
thermodynamics_kd = 2.*math.pi/thermodynamics['r_d']/M.h() # read 2pi(comoving diffusion scale) in [h/Mpc]
#
# define a bunch of interpolation functions based on previous quantities
#
background_z_at_tau = interp1d(background_tau,background_z)
background_aH_at_tau = interp1d(background_tau,background_aH)
background_ks_at_tau = interp1d(background_tau,background_ks)
background_tau_at_mr = interp1d(background_rho_m_over_r,background_tau)
background_tau_at_lm = interp1d(background_rho_l_over_m,background_tau)
thermodynamics_kd_at_tau = interp1d(thermodynamics_tau, thermodynamics_kd)
#
Ejemplo n.º 11
0
class classy(Theory):
    def initialise(self):
        """Importing CLASS from the correct path, if given, and if not, globally."""
        # If path not given, try using general path to modules
        path_to_installation = get_path_to_installation()
        if not self.path and path_to_installation:
            self.path = os.path.join(path_to_installation, "code",
                                     classy_repo_rename)
        if self.path:
            self.log.info("Importing *local* classy from " + self.path)
            classy_build_path = os.path.join(self.path, "python", "build")
            post = next(d for d in os.listdir(classy_build_path)
                        if d.startswith("lib."))
            classy_build_path = os.path.join(classy_build_path, post)
            if not os.path.exists(classy_build_path):
                self.log.error(
                    "Either CLASS is not in the given folder, "
                    "'%s', or you have not compiled it.", self.path)
                raise HandledException
            # Inserting the previously found path into the list of import folders
            sys.path.insert(0, classy_build_path)
        else:
            self.log.info("Importing *global* CLASS.")
        try:
            from classy import Class, CosmoSevereError, CosmoComputationError
        except ImportError:
            self.log.error(
                "Couldn't find the CLASS python interface. "
                "Make sure that you have compiled it, and that you either\n"
                " (a) specify a path (you didn't) or\n"
                " (b) install the Python interface globally with\n"
                "     '/path/to/class/python/python setup.py install --user'")
            raise HandledException
        self.classy = Class()
        # Propagate errors up
        global CosmoComputationError, CosmoSevereError
        # Generate states, to avoid recomputing
        self.n_states = 3
        self.states = [{
            "params": None,
            "derived": None,
            "derived_extra": None,
            "last": 0
        } for i in range(self.n_states)]
        # Dict of named tuples to collect requirements and computation methods
        self.collectors = {}
        # Additional input parameters to pass to CLASS
        self.extra_args = self.extra_args or {}
        self.extra_args["output"] = self.extra_args.get("output", "")
        if "sBBN file" in self.extra_args:
            self.extra_args["sBBN file"] = (os.path.join(
                self.path, self.extra_args["sBBN file"]))
        # Derived parameters that may not have been requested, but will be necessary later
        self.derived_extra = []

    def current_state(self):
        lasts = [self.states[i]["last"] for i in range(self.n_states)]
        return self.states[lasts.index(max(lasts))]

    def needs(self, arguments):
        # Computed quantities requiered by the likelihood
        arguments = arguments or {}
        for k, v in arguments.items():
            # Precision parameters and boundaries (in general, take max of all requested)
            if k == "l_max":
                self.extra_args["l_max_scalars"] = (max(
                    v, self.extra_args.get("l_max_scalars", 0)))
            elif k == "k_max":
                self.extra_args["P_k_max_h/Mpc"] = (max(
                    v, self.extra_args.get("P_k_max_h/Mpc", 0)))
            # Products and other computations
            elif k == "Cl":
                if any([("t" in cl.lower()) for cl in v]):
                    self.extra_args["output"] += " tCl"
                if any([(("e" in cl.lower()) or ("b" in cl.lower()))
                        for cl in v]):
                    self.extra_args["output"] += " pCl"
                # For modern experiments, always lensed Cl's!
                self.extra_args["output"] += " lCl"
                self.extra_args["lensing"] = "yes"
                self.extra_args["non linear"] = "halofit"
                self.collectors[k] = collector(method="lensed_cl", kwargs={})
                self.collectors["TCMB"] = collector(method="T_cmb", kwargs={})
            elif k == "fsigma8":
                self.collectors["growth_factor_f"] = collector(
                    method="scale_independent_growth_factor_f",
                    args=[np.atleast_1d(v["redshifts"])],
                    arg_array=0)
                self.collectors["sigma8"] = collector(
                    method="sigma",
                    # Notice: Needs H0 for 1st arg (R), so added later
                    args=[None, np.atleast_1d(v["redshifts"])],
                    arg_array=1)
                if "H0" not in self.input_params:
                    self.derived_extra += ["H0"]
                self.extra_args["output"] += " mPk"
                self.extra_args["P_k_max_h/Mpc"] = (max(
                    1, self.extra_args.get("P_k_max_h/Mpc", 0)))
                self.add_z_for_matter_power(v["redshifts"])
            elif k == "h_of_z":
                self.collectors[k] = collector(
                    method="Hubble",
                    args=[np.atleast_1d(v["redshifts"])],
                    arg_array=0)
                self.H_units_conv_factor = {
                    "/Mpc": 1,
                    "km/s/Mpc": _c
                }[v["units"]]
            elif k == "angular_diameter_distance":
                self.collectors[k] = collector(
                    method="angular_distance",
                    args=[np.atleast_1d(v["redshifts"])],
                    arg_array=0)
            else:
                # Extra derived parameters
                if v is None:
                    self.derived_extra += [self.translate_param(k)]
                else:
                    self.log.error("Unknown required product: '%s:%s'.", k, v)
                    raise HandledException
        # Derived parameters (if some need some additional computations)
        if "sigma8" in self.output_params or arguments:
            self.extra_args["output"] += " mPk"
            self.extra_args["P_k_max_h/Mpc"] = (max(
                1, self.extra_args.get("P_k_max_h/Mpc", 0)))
        # Since the Cl collector needs lmax, update it now, in case it has increased
        # *after* declaring the Cl collector
        if "Cl" in self.collectors:
            self.collectors["Cl"].kwargs["lmax"] = self.extra_args[
                "l_max_scalars"]
        # Cleanup of products string
        self.extra_args["output"] = " ".join(
            set(self.extra_args["output"].split()))

    def add_z_for_matter_power(self, z):
        if not hasattr(self, "z_for_matter_power"):
            self.z_for_matter_power = np.empty((0))
        self.z_for_matter_power = np.flip(np.sort(
            np.unique(
                np.concatenate([self.z_for_matter_power,
                                np.atleast_1d(z)]))),
                                          axis=0)
        self.extra_args["z_pk"] = " ".join(
            ["%g" % zi for zi in self.z_for_matter_power])

    def translate_param(self, p):
        if self.use_planck_names:
            return self.planck_to_classy.get(p, p)
        return p

    def set(self, params_values_dict, i_state):
        # Store them, to use them later to identify the state
        self.states[i_state]["params"] = deepcopy(params_values_dict)
        # Prepare parameters to be passed: this-iteration + extra
        args = {
            self.translate_param(p): v
            for p, v in params_values_dict.items()
        }
        args.update(self.extra_args)
        # Generate and save
        self.log.debug("Setting parameters: %r", args)
        self.classy.struct_cleanup()
        self.classy.set(**args)

    def compute(self, derived=None, **params_values_dict):
        lasts = [self.states[i]["last"] for i in range(self.n_states)]
        try:
            # are the parameter values there already?
            i_state = next(i for i in range(self.n_states)
                           if self.states[i]["params"] == params_values_dict)
            # Get (pre-computed) derived parameters
            if derived == {}:
                derived.update(self.states[i_state]["derived"])
            self.log.debug("Re-using computed results (state %d)", i_state)
        except StopIteration:
            # update the (first) oldest one and compute
            i_state = lasts.index(min(lasts))
            self.log.debug("Computing (state %d)", i_state)
            # Set parameters
            self.set(params_values_dict, i_state)
            # Compute!
            try:
                self.classy.compute()
            # "Valid" failure of CLASS: parameters too extreme -> log and report
            except CosmoComputationError:
                self.log.debug("Computation of cosmological products failed. "
                               "Assigning 0 likelihood and going on.")
                return False
            # CLASS not correctly initialised, or input parameters not correct
            except CosmoSevereError:
                self.log.error(
                    "Serious error setting parameters or computing results. "
                    "The parameters passed were %r and %r. "
                    "See original CLASS's error traceback below.\n",
                    self.states[i_state]["params"], self.extra_args)
                raise  # No HandledException, so that CLASS traceback gets printed
            # Gather products
            for product, collector in self.collectors.items():
                # Special case: sigma8 needs H0, which cannot be known beforehand:
                if "sigma8" in self.collectors:
                    self.collectors["sigma8"].args[0] = 8 / self.classy.h()
                method = getattr(self.classy, collector.method)
                if self.collectors[product].arg_array is None:
                    self.states[i_state][product] = method(
                        *self.collectors[product].args,
                        **self.collectors[product].kwargs)
                else:
                    i_array = self.collectors[product].arg_array
                    self.states[i_state][product] = np.zeros(
                        len(self.collectors[product].args[i_array]))
                    for i, v in enumerate(
                            self.collectors[product].args[i_array]):
                        args = (
                            list(self.collectors[product].args[:i_array]) +
                            [v] +
                            list(self.collectors[product].args[i_array + 1:]))
                        self.states[i_state][product][i] = method(
                            *args, **self.collectors[product].kwargs)
            # Prepare derived parameters
            d, d_extra = self.get_derived_all(
                derived_requested=(derived == {}))
            derived.update(d)
            self.states[i_state]["derived"] = odict(
                [[p, derived.get(p)] for p in self.output_params])
            # Prepare necessary extra derived parameters
            self.states[i_state]["derived_extra"] = deepcopy(d_extra)
        # make this one the current one by decreasing the antiquity of the rest
        for i in range(self.n_states):
            self.states[i]["last"] -= max(lasts)
        self.states[i_state]["last"] = 1
        return True

    def get_derived_all(self, derived_requested=True):
        """
        Returns a dictionary of derived parameters with their values,
        using the *current* state (i.e. it should only be called from
        the ``compute`` method).

        To get a parameter *from a likelihood* use `get_param` instead.
        """
        list_requested_derived = self.output_params if derived_requested else []
        de_translated = {
            self.translate_param(p): p
            for p in list_requested_derived
        }
        requested_derived_with_extra = list(de_translated.keys()) + list(
            self.derived_extra)
        derived_aux = {}
        # Exceptions
        if "rs_drag" in requested_derived_with_extra:
            requested_derived_with_extra.remove("rs_drag")
            derived_aux["rs_drag"] = self.classy.rs_drag()
        derived_aux.update(
            self.classy.get_current_derived_parameters(
                requested_derived_with_extra))
        # Fill return dictionaries
        derived = {
            de_translated[p]: derived_aux[self.translate_param(p)]
            for p in de_translated
        }
        derived_extra = {p: derived_aux[p] for p in self.derived_extra}
        # No need for error control: classy.get_current_derived_parameters is passed
        # every derived parameter not excluded before, and cause an error if if founds a
        # parameter that it does not recognise
        return derived, derived_extra

    def get_param(self, p):
        """
        Interface function for likelihoods to get sampled and derived parameters.
        """
        current_state = self.current_state()
        for pool in ["params", "derived", "derived_extra"]:
            value = current_state[pool].get(self.translate_param(p), None)
            if value is not None:
                return value
        self.log.error("Parameter not known: '%s'", p)
        raise HandledException

    def get_cl(self, ell_factor=False):
        """
        Returns the power spectra in microK^2
        (unitless for lensing potential),
        using the *current* state.
        """
        current_state = self.current_state()
        # get C_l^XX from the cosmological code
        try:
            cl = deepcopy(current_state["Cl"])
        except:
            self.log.error(
                "No Cl's were computed. Are you sure that you have requested them?"
            )
            raise HandledException
        ell_factor = ((cl["ell"] + 1) * cl["ell"] /
                      (2 * np.pi))[2:] if ell_factor else 1
        # convert dimensionless C_l's to C_l in muK**2
        T = current_state["TCMB"]
        for key in cl:
            # All quantities need to be multiplied by this factor, except the
            # phi-phi term, that is already dimensionless
            if key not in ['pp', 'ell']:
                cl[key][2:] *= (T * 1.e6)**2 * ell_factor
        if "pp" in cl and ell_factor is not 1:
            cl['pp'][2:] *= ell_factor**2 * (2 * np.pi)
        return cl

    def get_fsigma8(self, z):
        indices = np.where(self.z_for_matter_power == z)
        return (self.current_state()["growth_factor_f"][indices] *
                self.current_state()["sigma8"][indices])

    def get_h_of_z(self, z):
        return self.current_state()["h_of_z"][np.where(
            self.collectors["h_of_z"].args[self.collectors["h_of_z"].arg_array]
            == z)] * self.H_units_conv_factor

    def get_angular_diameter_distance(self, z):
        return self.current_state()["angular_diameter_distance"][np.where(
            self.collectors["angular_diameter_distance"].args[
                self.collectors["angular_diameter_distance"].arg_array] == z)]
Ejemplo n.º 12
0
import myfuncs as my
from numpy import linalg as LA
import pickle

#Run ClASS-code and get transfer function for delta_cdm
cosmo = Class()
cosmo.set({
    'output': 'tCl mPk dTk vTk',
    'P_k_max_1/Mpc': 35,
    'gauge': 'Synchronous',
    'z_pk': '100., 0.'
})
cosmo.compute()
tr = cosmo.get_transfer(49)
delta_cdm = tr['d_cdm']
k = tr['k (h/Mpc)'] * cosmo.h()

# Create interpolating function for transfer function
dfunc = interp1d(k, delta_cdm, kind='cubic', bounds_error=False, fill_value=0)


# define class for saving data
class data:
    def __init__(self, Dat):
        self.Dat = Dat
        self.K = []
        self.Kused = []
        self.Kl = []
        self.Klu = []
        self.d1 = []
        self.d2 = []
Ejemplo n.º 13
0
def turboSij(zstakes=default_zstakes,
             cosmo_params=default_cosmo_params,
             cosmo_Class=None):

    # If the cosmology is not provided (in the same form as CLASS), run CLASS
    if cosmo_Class is None:
        cosmo = Class()
        dico_for_CLASS = cosmo_params
        dico_for_CLASS['output'] = 'mPk'
        cosmo.set(dico_for_CLASS)
        cosmo.compute()
    else:
        cosmo = cosmo_Class

    h = cosmo.h()  #for  conversions Mpc/h <-> Mpc

    # Define arrays of z, r(z), k, P(k)...
    nzbins = len(zstakes) - 1
    nz_perbin = 10
    z_arr = np.zeros((nz_perbin, nzbins))
    comov_dist = np.zeros((nz_perbin, nzbins))
    for j in range(nzbins):
        z_arr[:, j] = np.linspace(zstakes[j], zstakes[j + 1], nz_perbin)
        comov_dist[:, j] = (cosmo.z_of_r(z_arr[:, j]))[0]  #In Mpc
    keq = 0.02 / h  #Equality matter radiation in 1/Mpc (more or less)
    klogwidth = 10  #Factor of width of the integration range. 10 seems ok ; going higher needs to increase nk_fft to reach convergence (fine cancellation issue noted in Lacasa & Grain)
    kmin = min(keq, 1. / comov_dist.max()) / klogwidth
    kmax = max(keq, 1. / comov_dist.min()) * klogwidth
    nk_fft = 2**11  #seems to be enough. Increase to test precision, reduce to speed up.
    k_4fft = np.linspace(kmin, kmax,
                         nk_fft)  #linear grid on k, as we need to use an FFT
    Deltak = kmax - kmin
    Dk = Deltak / nk_fft
    Pk_4fft = np.zeros(nk_fft)
    for ik in range(nk_fft):
        Pk_4fft[ik] = cosmo.pk(k_4fft[ik], 0.)  #In Mpc^3
    dr_fft = np.linspace(0, nk_fft // 2, nk_fft // 2 + 1) * 2 * pi / Deltak

    # Compute necessary FFTs and make interpolation functions
    fft2 = np.fft.rfft(Pk_4fft / k_4fft**2) * Dk
    dct2 = fft2.real
    dst2 = -fft2.imag
    km2Pk_dct = interp1d(dr_fft, dct2, kind='cubic')
    fft3 = np.fft.rfft(Pk_4fft / k_4fft**3) * Dk
    dct3 = fft3.real
    dst3 = -fft3.imag
    km3Pk_dst = interp1d(dr_fft, dst3, kind='cubic')
    fft4 = np.fft.rfft(Pk_4fft / k_4fft**4) * Dk
    dct4 = fft4.real
    dst4 = -fft4.imag
    km4Pk_dct = interp1d(dr_fft, dct4, kind='cubic')

    # Compute Sij finally
    Sij = np.zeros((nzbins, nzbins))
    for j1 in range(nzbins):
        rmin1 = (comov_dist[:, j1]).min()
        rmax1 = (comov_dist[:, j1]).max()
        zmean1 = ((z_arr[:, j1]).min() + (z_arr[:, j1]).max()) / 2
        growth1 = cosmo.scale_independent_growth_factor(zmean1)
        pref1 = 3. * growth1 / (rmax1**3 - rmin1**3)
        for j2 in range(nzbins):
            rmin2 = (comov_dist[:, j2]).min()
            rmax2 = (comov_dist[:, j2]).max()
            zmean2 = ((z_arr[:, j2]).min() + (z_arr[:, j2]).max()) / 2
            growth2 = cosmo.scale_independent_growth_factor(zmean2)
            pref2 = 3. * growth2 / (rmax2**3 - rmin2**3)
            #p1p2: rmax1 & rmax2
            rsum = rmax1 + rmax2
            rdiff = abs(rmax1 - rmax2)
            rprod = rmax1 * rmax2
            Icp2 = km2Pk_dct(rsum)
            Icm2 = km2Pk_dct(rdiff)
            Isp3 = km3Pk_dst(rsum)
            Ism3 = km3Pk_dst(rdiff)
            Icp4 = km4Pk_dct(rsum)
            Icm4 = km4Pk_dct(rdiff)
            Fp1p2 = -Icp4 + Icm4 - rsum * Isp3 + rdiff * Ism3 + rprod * (Icp2 +
                                                                         Icm2)
            #p1m2: rmax1 & rmin2
            rsum = rmax1 + rmin2
            rdiff = abs(rmax1 - rmin2)
            rprod = rmax1 * rmin2
            Icp2 = km2Pk_dct(rsum)
            Icm2 = km2Pk_dct(rdiff)
            Isp3 = km3Pk_dst(rsum)
            Ism3 = km3Pk_dst(rdiff)
            Icp4 = km4Pk_dct(rsum)
            Icm4 = km4Pk_dct(rdiff)
            Fp1m2 = -Icp4 + Icm4 - rsum * Isp3 + rdiff * Ism3 + rprod * (Icp2 +
                                                                         Icm2)
            #m1p2: rmin1 & rmax2
            rsum = rmin1 + rmax2
            rdiff = abs(rmin1 - rmax2)
            rprod = rmin1 * rmax2
            Icp2 = km2Pk_dct(rsum)
            Icm2 = km2Pk_dct(rdiff)
            Isp3 = km3Pk_dst(rsum)
            Ism3 = km3Pk_dst(rdiff)
            Icp4 = km4Pk_dct(rsum)
            Icm4 = km4Pk_dct(rdiff)
            Fm1p2 = -Icp4 + Icm4 - rsum * Isp3 + rdiff * Ism3 + rprod * (Icp2 +
                                                                         Icm2)
            #m1m2: rmin1 & rmin2
            rsum = rmin1 + rmin2
            rdiff = abs(rmin1 - rmin2)
            rprod = rmin1 * rmin2
            Icp2 = km2Pk_dct(rsum)
            Icm2 = km2Pk_dct(rdiff)
            Isp3 = km3Pk_dst(rsum)
            Ism3 = km3Pk_dst(rdiff)
            Icp4 = km4Pk_dct(rsum)
            Icm4 = km4Pk_dct(rdiff)
            Fm1m2 = -Icp4 + Icm4 - rsum * Isp3 + rdiff * Ism3 + rprod * (Icp2 +
                                                                         Icm2)
            #now group everything
            Fsum = Fp1p2 - Fp1m2 - Fm1p2 + Fm1m2
            Sij[j1, j2] = pref1 * pref2 * Fsum / (4 * pi**2)

    return Sij
Ejemplo n.º 14
0
def Sij_alt(z_arr,
            windows,
            cosmo_params=default_cosmo_params,
            cosmo_Class=None):

    # Assert everything as the good type and shape, and find number of redshifts, bins etc
    zz = np.asarray(z_arr)
    win = np.asarray(windows)

    assert zz.ndim == 1, 'z_arr must be a 1-dimensional array'
    assert win.ndim == 2, 'windows must be a 2-dimensional array'

    nz = len(zz)
    nbins = win.shape[0]
    assert win.shape[1] == nz, 'windows must have shape (nbins,nz)'

    assert zz.min() > 0, 'z_arr must have values > 0'

    # If the cosmology is not provided (in the same form as CLASS), run CLASS
    if cosmo_Class is None:
        cosmo = Class()
        dico_for_CLASS = cosmo_params
        dico_for_CLASS['output'] = 'mPk'
        cosmo.set(dico_for_CLASS)
        cosmo.compute()
    else:
        cosmo = cosmo_Class

    h = cosmo.h()  #for  conversions Mpc/h <-> Mpc

    # Define arrays of r(z), k, P(k)...
    zofr = cosmo.z_of_r(zz)
    comov_dist = zofr[0]  #Comoving distance r(z) in Mpc
    dcomov_dist = 1 / zofr[1]  #Derivative dr/dz in Mpc
    dV = comov_dist**2 * dcomov_dist  #Comoving volume per solid angle in Mpc^3/sr
    growth = np.zeros(nz)  #Growth factor
    for iz in range(nz):
        growth[iz] = cosmo.scale_independent_growth_factor(zz[iz])

    keq = 0.02 / h  #Equality matter radiation in 1/Mpc (more or less)
    klogwidth = 10  #Factor of width of the integration range.
    #10 seems ok ; going higher needs to increase nk_fft to reach convergence (fine cancellation issue noted in Lacasa & Grain)
    kmin = min(keq, 1. / comov_dist.max()) / klogwidth
    kmax = max(keq, 1. / comov_dist.min()) * klogwidth
    nk_fft = 2**11  #seems to be enough. Increase to test precision, reduce to speed up.
    k_4fft = np.linspace(kmin, kmax,
                         nk_fft)  #linear grid on k, as we need to use an FFT
    Deltak = kmax - kmin
    Dk = Deltak / nk_fft
    Pk_4fft = np.zeros(nk_fft)
    for ik in range(nk_fft):
        Pk_4fft[ik] = cosmo.pk(k_4fft[ik], 0.)  #In Mpc^3
    dr_fft = np.linspace(0, nk_fft // 2, nk_fft // 2 + 1) * 2 * pi / Deltak

    # Compute necessary FFTs and make interpolation functions
    fft0 = np.fft.rfft(Pk_4fft) * Dk
    dct0 = fft0.real
    dst0 = -fft0.imag
    Pk_dct = interp1d(dr_fft, dct0, kind='cubic')

    # Compute sigma^2(z1,z2)
    sigma2_nog = np.zeros((nz, nz))
    #First with P(k,z=0) and z1<=z2
    for iz in range(nz):
        r1 = comov_dist[iz]
        for jz in range(iz, nz):
            r2 = comov_dist[jz]
            rsum = r1 + r2
            rdiff = abs(r1 - r2)
            Icp0 = Pk_dct(rsum)
            Icm0 = Pk_dct(rdiff)
            sigma2_nog[iz, jz] = (Icm0 - Icp0) / (4 * pi**2 * r1 * r2)
    #Now fill by symmetry and put back growth functions
    sigma2 = np.zeros((nz, nz))
    for iz in range(nz):
        growth1 = growth[iz]
        for jz in range(nz):
            growth2 = growth[jz]
            sigma2[iz, jz] = sigma2_nog[min(iz, jz),
                                        max(iz, jz)] * growth1 * growth2

    # Compute normalisations
    Inorm = np.zeros(nbins)
    for i1 in range(nbins):
        integrand = dV * windows[i1, :]**2
        Inorm[i1] = integrate.simps(integrand, zz)

    # Compute Sij finally
    prefactor = sigma2 * (dV * dV[:, None])
    Sij = np.zeros((nbins, nbins))
    #For i<=j
    for i1 in range(nbins):
        for i2 in range(i1, nbins):
            integrand = prefactor * (windows[i1, :]**2 *
                                     windows[i2, :, None]**2)
            Sij[i1, i2] = integrate.simps(integrate.simps(integrand, zz),
                                          zz) / (Inorm[i1] * Inorm[i2])
    #Fill by symmetry
    for i1 in range(nbins):
        for i2 in range(nbins):
            Sij[i1, i2] = Sij[min(i1, i2), max(i1, i2)]

    return Sij
Ejemplo n.º 15
0
def Sij(z_arr,
        windows,
        cosmo_params=default_cosmo_params,
        precision=10,
        cosmo_Class=None):

    # Assert everything as the good type and shape, and find number of redshifts, bins etc
    zz = np.asarray(z_arr)
    win = np.asarray(windows)

    assert zz.ndim == 1, 'z_arr must be a 1-dimensional array'
    assert win.ndim == 2, 'windows must be a 2-dimensional array'

    nz = len(zz)
    nbins = win.shape[0]
    assert win.shape[1] == nz, 'windows must have shape (nbins,nz)'

    assert zz.min() > 0, 'z_arr must have values > 0'

    # If the cosmology is not provided (in the same form as CLASS), run CLASS
    if cosmo_Class is None:
        cosmo = Class()
        dico_for_CLASS = cosmo_params
        dico_for_CLASS['output'] = 'mPk'
        cosmo.set(dico_for_CLASS)
        cosmo.compute()
    else:
        cosmo = cosmo_Class

    h = cosmo.h()  #for  conversions Mpc/h <-> Mpc

    # Define arrays of r(z), k, P(k)...
    zofr = cosmo.z_of_r(zz)
    comov_dist = zofr[0]  #Comoving distance r(z) in Mpc
    dcomov_dist = 1 / zofr[1]  #Derivative dr/dz in Mpc
    dV = comov_dist**2 * dcomov_dist  #Comoving volume per solid angle in Mpc^3/sr
    growth = np.zeros(nz)  #Growth factor
    for iz in range(nz):
        growth[iz] = cosmo.scale_independent_growth_factor(zz[iz])

    # Compute normalisations
    Inorm = np.zeros(nbins)
    for i1 in range(nbins):
        integrand = dV * windows[i1, :]**2
        Inorm[i1] = integrate.simps(integrand, zz)

    # Compute U(i,k)
    keq = 0.02 / h  #Equality matter radiation in 1/Mpc (more or less)
    klogwidth = 10  #Factor of width of the integration range. 10 seems ok
    kmin = min(keq, 1. / comov_dist.max()) / klogwidth
    kmax = max(keq, 1. / comov_dist.min()) * klogwidth
    nk = 2**precision  #10 seems to be enough. Increase to test precision, reduce to speed up.
    #kk          = np.linspace(kmin,kmax,num=nk)                   #linear grid on k
    logkmin = np.log(kmin)
    logkmax = np.log(kmax)
    logk = np.linspace(logkmin, logkmax, num=nk)
    kk = np.exp(logk)  #logarithmic grid on k
    Pk = np.zeros(nk)
    for ik in range(nk):
        Pk[ik] = cosmo.pk(kk[ik], 0.)  #In Mpc^3
    Uarr = np.zeros((nbins, nk))
    for ibin in range(nbins):
        for ik in range(nk):
            kr = kk[ik] * comov_dist
            integrand = dV * windows[ibin, :]**2 * growth * np.sin(kr) / kr
            Uarr[ibin, ik] = integrate.simps(integrand, zz)

    # Compute Sij finally
    Cl_zero = np.zeros((nbins, nbins))
    #For i<=j
    for ibin in range(nbins):
        U1 = Uarr[ibin, :] / Inorm[ibin]
        for jbin in range(ibin, nbins):
            U2 = Uarr[jbin, :] / Inorm[jbin]
            integrand = kk**2 * Pk * U1 * U2
            #Cl_zero[ibin,jbin] = 2/pi * integrate.simps(integrand,kk)     #linear integration
            Cl_zero[ibin, jbin] = 2 / pi * integrate.simps(
                integrand * kk, logk)  #log integration
    #Fill by symmetry
    for ibin in range(nbins):
        for jbin in range(nbins):
            Cl_zero[ibin, jbin] = Cl_zero[min(ibin, jbin), max(ibin, jbin)]
    Sij = Cl_zero / (4 * pi)

    return Sij
Ejemplo n.º 16
0
    def fitEE(self):

        # function to cimpute the band powers

        cosmo = Class()
        cosmo.set(self.cosmoParams)

        if self.settings.include_neutrino:
            cosmo.set(self.other_settings)
            cosmo.set(self.neutrino_settings)

        cosmo.set(self.class_argumets)

        try:
            cosmo.compute()

        except CosmoComputationError as failure_message:

            print(failure_message)

            self.sigma_8 = np.nan

            cosmo.struct_cleanup()
            cosmo.empty()

            return np.array([np.nan] * self.nzcorrs * self.bo_EE), np.array(
                [np.nan] * self.nzcorrs * self.bo_EE), np.array(
                    [np.nan] * self.nzcorrs * self.bo_EE)

        except CosmoSevereError as critical_message:

            print(critical_message)

            self.sigma_8 = np.nan

            cosmo.struct_cleanup()
            cosmo.empty()

            return np.array([np.nan] * self.nzcorrs * self.bo_EE), np.array(
                [np.nan] * self.nzcorrs * self.bo_EE), np.array(
                    [np.nan] * self.nzcorrs * self.bo_EE)

        # retrieve Omega_m and h from cosmo (CLASS)
        self.Omega_m = cosmo.Omega_m()
        self.small_h = cosmo.h()

        self.rho_crit = self.get_critical_density()

        # derive the linear growth factor D(z)
        linear_growth_rate = np.zeros_like(self.redshifts)
        # print self.redshifts
        for index_z, z in enumerate(self.redshifts):
            try:
                # for CLASS ver >= 2.6:
                linear_growth_rate[
                    index_z] = cosmo.scale_independent_growth_factor(z)
            except BaseException:
                # my own function from private CLASS modification:
                linear_growth_rate[index_z] = cosmo.growth_factor_at_z(z)
        # normalize to unity at z=0:
        try:
            # for CLASS ver >= 2.6:
            linear_growth_rate /= cosmo.scale_independent_growth_factor(0.)
        except BaseException:
            # my own function from private CLASS modification:
            linear_growth_rate /= cosmo.growth_factor_at_z(0.)

        # get distances from cosmo-module:
        r, dzdr = cosmo.z_of_r(self.redshifts)

        self.sigma_8 = cosmo.sigma8()

        # Get power spectrum P(k=l/r,z(r)) from cosmological module
        # this doesn't really have to go into the loop over fields!
        pk = np.zeros((self.settings.nellsmax, self.settings.nzmax), 'float64')
        k_max_in_inv_Mpc = self.settings.k_max_h_by_Mpc * self.small_h

        # note that this is being computed at only nellsmax
        # followed by an interplation
        record = np.zeros((self.settings.nellsmax, self.settings.nzmax))
        record_k = np.zeros((self.settings.nellsmax, self.settings.nzmax))
        for index_ells in range(self.settings.nellsmax):
            for index_z in range(1, self.settings.nzmax):
                k_in_inv_Mpc = (self.ells[index_ells] + 0.5) / r[index_z]
                z = self.redshifts[index_z]

                record[index_ells, index_z] = self.baryon_feedback_bias_sqr(
                    k_in_inv_Mpc / self.small_h,
                    self.redshifts[index_z],
                    A_bary=self.systematics['A_bary'])
                record_k[index_ells, index_z] = k_in_inv_Mpc

        self.record_bf = record[:, 1:].flatten()
        self.record_k = record_k[:, 1:].flatten()
        self.k_max_in_inv_Mpc = k_max_in_inv_Mpc

        for index_ells in range(self.settings.nellsmax):
            for index_z in range(1, self.settings.nzmax):
                # standard Limber approximation:
                # k = ells[index_ells] / r[index_z]
                # extended Limber approximation (cf. LoVerde & Afshordi 2008):
                k_in_inv_Mpc = (self.ells[index_ells] + 0.5) / r[index_z]
                if k_in_inv_Mpc > k_max_in_inv_Mpc:
                    pk_dm = 0.
                else:
                    pk_dm = cosmo.pk(k_in_inv_Mpc, self.redshifts[index_z])
                # pk[index_ells,index_z] = cosmo.pk(ells[index_ells]/r[index_z], self.redshifts[index_z])
                if self.settings.baryon_feedback:
                    pk[index_ells,
                       index_z] = pk_dm * self.baryon_feedback_bias_sqr(
                           k_in_inv_Mpc / self.small_h,
                           self.redshifts[index_z],
                           A_bary=self.systematics['A_bary'])
                else:
                    pk[index_ells, index_z] = pk_dm

    # for KiDS-450 constant biases in photo-z are not sufficient:
        if self.settings.bootstrap_photoz_errors:
            # draw a random bootstrap n(z); borders are inclusive!
            random_index_bootstrap = np.random.randint(
                int(self.settings.index_bootstrap_low),
                int(self.settings.index_bootstrap_high) + 1)
            # print 'Bootstrap index:', random_index_bootstrap
            pz = np.zeros((self.settings.nzmax, self.nzbins), 'float64')
            pz_norm = np.zeros(self.nzbins, 'float64')

            for zbin in range(self.nzbins):

                redshift_bin = self.redshift_bins[zbin]
                # ATTENTION: hard-coded subfolder!
                # index can be recycled since bootstraps for tomographic bins
                # are independent!
                fname = os.path.join(
                    self.settings.data_directory,
                    '{:}/bootstraps/{:}/n_z_avg_bootstrap{:}.hist'.format(
                        self.settings.photoz_method, redshift_bin,
                        random_index_bootstrap))
                z_hist, n_z_hist = np.loadtxt(fname, unpack=True)

                shift_to_midpoint = np.diff(z_hist)[0] / 2.
                spline_pz = itp.splrep(z_hist + shift_to_midpoint, n_z_hist)
                mask_min = self.redshifts >= z_hist.min() + shift_to_midpoint
                mask_max = self.redshifts <= z_hist.max() + shift_to_midpoint
                mask = mask_min & mask_max
                # points outside the z-range of the histograms are set to 0!
                pz[mask, zbin] = itp.splev(self.redshifts[mask], spline_pz)

                dz = self.redshifts[1:] - self.redshifts[:-1]
                pz_norm[zbin] = np.sum(0.5 * (pz[1:, zbin] + pz[:-1, zbin]) *
                                       dz)

            pr = pz * (dzdr[:, np.newaxis] / pz_norm)

        else:
            pr = self.pz * (dzdr[:, np.newaxis] / self.pz_norm)
            # pr[pr < 0] = 0

        g = np.zeros((self.settings.nzmax, self.nzbins), 'float64')

        for zbin in range(self.nzbins):
            # assumes that z[0] = 0
            for nr in range(1, self.settings.nzmax - 1):
                # for nr in range(self.nzmax - 1):
                fun = pr[nr:, zbin] * (r[nr:] - r[nr]) / r[nr:]
                g[nr, zbin] = np.sum(0.5 * (fun[1:] + fun[:-1]) *
                                     (r[nr + 1:] - r[nr:-1]))
                g[nr, zbin] *= 2. * r[nr] * (1. + self.redshifts[nr])

        # Start loop over l for computation of C_l^shear
        Cl_GG_integrand = np.zeros(
            (self.settings.nzmax, self.nzbins, self.nzbins), 'float64')
        Cl_GG = np.zeros((self.settings.nellsmax, self.nzbins, self.nzbins),
                         'float64')

        Cl_II_integrand = np.zeros_like(Cl_GG_integrand)
        Cl_II = np.zeros_like(Cl_GG)

        Cl_GI_integrand = np.zeros_like(Cl_GG_integrand)
        Cl_GI = np.zeros_like(Cl_GG)

        dr = r[1:] - r[:-1]
        for index_ell in range(self.settings.nellsmax):

            # find Cl_integrand = (g(r) / r)**2 * P(l/r,z(r))
            for zbin1 in range(self.nzbins):
                for zbin2 in range(zbin1 + 1):  # self.nzbins):
                    Cl_GG_integrand[1:, zbin1, zbin2] = g[1:, zbin1] * \
                        g[1:, zbin2] / r[1:]**2 * pk[index_ell, 1:]

                    factor_IA = self.get_factor_IA(
                        self.redshifts[1:], linear_growth_rate[1:],
                        self.systematics['A_IA'])  # / self.dzdr[1:]
                    # print F_of_x
                    # print self.eta_r[1:, zbin1].shape
                    Cl_II_integrand[1:, zbin1, zbin2] = pr[1:, zbin1] * \
                        pr[1:, zbin2] * factor_IA**2 / r[1:]**2 * pk[index_ell, 1:]
                    pref = g[1:, zbin1] * pr[1:, zbin2] + g[1:, zbin2] * pr[
                        1:, zbin1]
                    Cl_GI_integrand[1:, zbin1,
                                    zbin2] = pref * factor_IA / r[1:]**2 * pk[
                                        index_ell, 1:]

            # Integrate over r to get C_l^shear_ij = P_ij(l)
            # C_l^shear_ii = 9/4 Omega0_m^2 H_0^4 \sum_0^rmax dr (g_i(r) g_j(r)
            # /r**2) P(k=l/r,z(r))
            for zbin1 in range(self.nzbins):
                for zbin2 in range(zbin1 + 1):  # self.nzbins):
                    Cl_GG[index_ell, zbin1, zbin2] = np.sum(
                        0.5 * (Cl_GG_integrand[1:, zbin1, zbin2] +
                               Cl_GG_integrand[:-1, zbin1, zbin2]) * dr)
                    # here we divide by 16, because we get a 2^2 from g(z)!
                    Cl_GG[index_ell, zbin1, zbin2] *= 9. / 16. * \
                        self.Omega_m**2  # in units of Mpc**4
                    # dimensionless
                    Cl_GG[index_ell, zbin1,
                          zbin2] *= (self.small_h / 2997.9)**4

                    Cl_II[index_ell, zbin1, zbin2] = np.sum(
                        0.5 * (Cl_II_integrand[1:, zbin1, zbin2] +
                               Cl_II_integrand[:-1, zbin1, zbin2]) * dr)

                    Cl_GI[index_ell, zbin1, zbin2] = np.sum(
                        0.5 * (Cl_GI_integrand[1:, zbin1, zbin2] +
                               Cl_GI_integrand[:-1, zbin1, zbin2]) * dr)
                    # here we divide by 4, because we get a 2 from g(r)!
                    Cl_GI[index_ell, zbin1, zbin2] *= 3. / 4. * self.Omega_m
                    Cl_GI[index_ell, zbin1,
                          zbin2] *= (self.small_h / 2997.9)**2

        # ordering of redshift bins is correct in definition of theory below!
        theory_EE_GG = np.zeros((self.nzcorrs, self.bo_EE), 'float64')
        theory_EE_II = np.zeros((self.nzcorrs, self.bo_EE), 'float64')
        theory_EE_GI = np.zeros((self.nzcorrs, self.bo_EE), 'float64')

        index_corr = 0
        # A_noise_corr = np.zeros(self.nzcorrs)
        for zbin1 in range(self.nzbins):
            for zbin2 in range(zbin1 + 1):  # self.nzbins):
                # correlation = 'z{:}z{:}'.format(zbin1 + 1, zbin2 + 1)
                # print(zbin1, zbin2)

                Cl_sample_GG = Cl_GG[:, zbin1, zbin2]
                spline_Cl_GG = itp.splrep(self.ells, Cl_sample_GG)
                D_l_EE_GG = self.ell_norm * \
                    itp.splev(self.ells_sum, spline_Cl_GG)

                theory_EE_GG[index_corr, :] = self.get_theory(
                    self.ells_sum,
                    D_l_EE_GG,
                    self.band_window_matrix,
                    index_corr,
                    band_type_is_EE=True)

                Cl_sample_GI = Cl_GI[:, zbin1, zbin2]
                spline_Cl_GI = itp.splrep(self.ells, Cl_sample_GI)
                D_l_EE_GI = self.ell_norm * \
                    itp.splev(self.ells_sum, spline_Cl_GI)
                theory_EE_GI[index_corr, :] = self.get_theory(
                    self.ells_sum,
                    D_l_EE_GI,
                    self.band_window_matrix,
                    index_corr,
                    band_type_is_EE=True)

                Cl_sample_II = Cl_II[:, zbin1, zbin2]
                spline_Cl_II = itp.splrep(self.ells, Cl_sample_II)
                D_l_EE_II = self.ell_norm * \
                    itp.splev(self.ells_sum, spline_Cl_II)
                theory_EE_II[index_corr, :] = self.get_theory(
                    self.ells_sum,
                    D_l_EE_II,
                    self.band_window_matrix,
                    index_corr,
                    band_type_is_EE=True)

                index_corr += 1

        cosmo.struct_cleanup()
        cosmo.empty()

        return theory_EE_GG.flatten(), theory_EE_GI.flatten(
        ), theory_EE_II.flatten()
Ejemplo n.º 17
0
plt.xlim(2, 2500)
plt.xlabel(r'$\ell$')
plt.ylabel(r'$[\ell(\ell+1)/2\pi]  C_\ell^\mathrm{TT}$')
plt.plot(ll, clTT * ll * (ll + 1) / 2. / pi, 'r-')

# In[ ]:

plt.savefig('warmup_cltt.pdf')

# In[ ]:

# get P(k) at redhsift z=0
import numpy as np
kk = np.logspace(-4, np.log10(3), 1000)  # k in h/Mpc
Pk = []  # P(k) in (Mpc/h)**3
h = LambdaCDM.h()  # get reduced Hubble for conversions to 1/Mpc
for k in kk:
    Pk.append(LambdaCDM.pk(k * h, 0.) * h**3)  # function .pk(k,z)

# In[ ]:

# plot P(k)
plt.figure(2)
plt.xscale('log')
plt.yscale('log')
plt.xlim(kk[0], kk[-1])
plt.xlabel(r'$k \,\,\,\, [h/\mathrm{Mpc}]$')
plt.ylabel(r'$P(k) \,\,\,\, [\mathrm{Mpc}/h]^3$')
plt.plot(kk, Pk, 'b-')

# In[ ]:
Ejemplo n.º 18
0
params_def = {
    'output': 'mPk',
    'non linear': 'halofit',
    'Omega_cdm': ocdm_0,
    'N_ncdm': 3,
    'N_ur': 0.00441,
    'm_ncdm': str(m_0) + ',' + str(m_0) + ',' + str(m_0)
}

# Create an instance of the CLASS wrapper
cosmo = Class()
# Set the parameters to the cosmological code
cosmo.set(params_def)
cosmo.compute()
#### Define the linear growth factor and growth rate (growth factor f in class)
h = cosmo.h()
# ~mcu = cosmo.N_ur()
# ~print(mcu)

Plin = np.zeros(len(karray))
Pnonlin = np.zeros(len(karray))
for i, k in enumerate(karray):
    Plin[i] = (cosmo.pk_lin(k, z))  # function .pk(k,z)
    Pnonlin[i] = (cosmo.pk(k, z))  # function .pk(k,z)

Plin *= h**3
Pnonlin *= h**3

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
m_1 = 0.02
Ejemplo n.º 19
0
def Sijkl(z_arr,
          windows,
          cosmo_params=default_cosmo_params,
          precision=10,
          tol=1e-3,
          cosmo_Class=None):

    # Assert everything as the good type and shape, and find number of redshifts, bins etc
    zz = np.asarray(z_arr)
    win = np.asarray(windows)

    assert zz.ndim == 1, 'z_arr must be a 1-dimensional array'
    assert win.ndim == 2, 'windows must be a 2-dimensional array'

    nz = len(zz)
    nbins = win.shape[0]
    assert win.shape[1] == nz, 'windows must have shape (nbins,nz)'

    assert zz.min() > 0, 'z_arr must have values > 0'

    # If the cosmology is not provided (in the same form as CLASS), run CLASS
    if cosmo_Class is None:
        cosmo = Class()
        dico_for_CLASS = cosmo_params
        dico_for_CLASS['output'] = 'mPk'
        cosmo.set(dico_for_CLASS)
        cosmo.compute()
    else:
        cosmo = cosmo_Class

    h = cosmo.h()  #for  conversions Mpc/h <-> Mpc

    # Define arrays of r(z), k, P(k)...
    zofr = cosmo.z_of_r(zz)
    comov_dist = zofr[0]  #Comoving distance r(z) in Mpc
    dcomov_dist = 1 / zofr[1]  #Derivative dr/dz in Mpc
    dV = comov_dist**2 * dcomov_dist  #Comoving volume per solid angle in Mpc^3/sr
    growth = np.zeros(nz)  #Growth factor
    for iz in range(nz):
        growth[iz] = cosmo.scale_independent_growth_factor(zz[iz])

    #Index pairs of bins
    npairs = (nbins * (nbins + 1)) // 2
    pairs = np.zeros((2, npairs), dtype=int)
    count = 0
    for ibin in range(nbins):
        for jbin in range(ibin, nbins):
            pairs[0, count] = ibin
            pairs[1, count] = jbin
            count += 1

    # Compute normalisations
    Inorm = np.zeros(npairs)
    Inorm2D = np.zeros((nbins, nbins))
    for ipair in range(npairs):
        ibin = pairs[0, ipair]
        jbin = pairs[1, ipair]
        integrand = dV * windows[ibin, :] * windows[jbin, :]
        integral = integrate.simps(integrand, zz)
        Inorm[ipair] = integral
        Inorm2D[ibin, jbin] = integral
        Inorm2D[jbin, ibin] = integral
    #Flag pairs with too small overlap as unreliable
    #Note: this will also speed up later computations
    #Default tolerance : tol=1e-3
    flag = np.zeros(npairs, dtype=int)
    for ipair in range(npairs):
        ibin = pairs[0, ipair]
        jbin = pairs[1, ipair]
        ratio = abs(Inorm2D[ibin, jbin]) / np.sqrt(
            abs(Inorm2D[ibin, ibin] * Inorm2D[jbin, jbin]))
        if ratio < tol:
            flag[ipair] = 1

    # Compute U(i,j;kk)
    keq = 0.02 / h  #Equality matter radiation in 1/Mpc (more or less)
    klogwidth = 10  #Factor of width of the integration range. 10 seems ok
    kmin = min(keq, 1. / comov_dist.max()) / klogwidth
    kmax = max(keq, 1. / comov_dist.min()) * klogwidth
    nk = 2**precision  #10 seems to be enough. Increase to test precision, reduce to speed up.
    #kk          = np.linspace(kmin,kmax,num=nk)                   #linear grid on k
    logkmin = np.log(kmin)
    logkmax = np.log(kmax)
    logk = np.linspace(logkmin, logkmax, num=nk)
    kk = np.exp(logk)  #logarithmic grid on k
    Pk = np.zeros(nk)
    for ik in range(nk):
        Pk[ik] = cosmo.pk(kk[ik], 0.)  #In Mpc^3
    Uarr = np.zeros((npairs, nk))
    for ipair in range(npairs):
        if flag[ipair] == 0:
            ibin = pairs[0, ipair]
            jbin = pairs[1, ipair]
            for ik in range(nk):
                kr = kk[ik] * comov_dist
                integrand = dV * windows[ibin, :] * windows[
                    jbin, :] * growth * np.sin(kr) / kr
                Uarr[ipair, ik] = integrate.simps(integrand, zz)

    # Compute Sijkl finally
    Cl_zero = np.zeros((nbins, nbins, nbins, nbins))
    #For ipair<=jpair
    for ipair in range(npairs):
        if flag[ipair] == 0:
            U1 = Uarr[ipair, :] / Inorm[ipair]
            ibin = pairs[0, ipair]
            jbin = pairs[1, ipair]
            for jpair in range(ipair, npairs):
                if flag[jpair] == 0:
                    U2 = Uarr[jpair, :] / Inorm[jpair]
                    kbin = pairs[0, jpair]
                    lbin = pairs[1, jpair]
                    integrand = kk**2 * Pk * U1 * U2
                    #integral = 2/(i * integrate.simps(integrand,kk)     #linear integration
                    integral = 2 / pi * integrate.simps(integrand * kk,
                                                        logk)  #log integration
                    #Run through all valid symmetries to fill the 4D array
                    #Symmetries: i<->j, k<->l, (i,j)<->(k,l)
                    Cl_zero[ibin, jbin, kbin, lbin] = integral
                    Cl_zero[ibin, jbin, lbin, kbin] = integral
                    Cl_zero[jbin, ibin, kbin, lbin] = integral
                    Cl_zero[jbin, ibin, lbin, kbin] = integral
                    Cl_zero[kbin, lbin, ibin, jbin] = integral
                    Cl_zero[kbin, lbin, jbin, ibin] = integral
                    Cl_zero[lbin, kbin, ibin, jbin] = integral
                    Cl_zero[lbin, kbin, jbin, ibin] = integral
    Sijkl = Cl_zero / (4 * pi)

    return Sijkl


# End of PySSC.py
                    'Omega_cdm': 0.2607,
                    'YHe': 0.245,
                    'z_reio': 7.82,
                    'n_s': 0.9665,
                    'A_s': 2.105e-9,
                    'P_k_max_1/Mpc': 500.0,
                    'perturbed recombination': 'y',
                    'non linear': 'halofit'
                    }

M = Class()
M.set(class_parameters)
M.set({'z_pk': z_compute})
M.compute()

h = M.h()  # get reduced Hubble for conversions to 1/Mpc

one_time = M.get_transfer(z_compute)

# Transfer functions

# Convert to units of Mpc^{-1}
k_ary = one_time['k (h/Mpc)'] * h

delta_b_ary = one_time['d_b']
delta_chi_ary = one_time['d_chi']

n_s = M.n_s()

# Primordial PS
k_pivot = 0.05
Ejemplo n.º 21
0
class tsz_gal_cl:
    def __init__(self):
        # print 'Class for tSZ Cl'
        # self.ptilde = np.loadtxt(LIBDIR+'/aux_files/ptilde.txt')
        self.fort_lib_cl = cdll.LoadLibrary(LIBDIR + "/source/calc_cl")

        self.fort_lib_cl.calc_cl_.argtypes = [
            POINTER(c_double),  #h0
            POINTER(c_double),  #obh2
            POINTER(c_double),  #och2
            POINTER(c_double),  #mnu
            POINTER(c_double),  #bias
            POINTER(c_double),  #Mcut
            POINTER(c_double),  #M1
            POINTER(c_double),  #kappa
            POINTER(c_double),  #sigma_Ncen
            POINTER(c_double),  #alp_Nsat
            POINTER(c_double),  #rmax
            POINTER(c_double),  #rgs
            POINTER(c_int64),  #pk_nk
            POINTER(c_int64),  #pk_nz
            np.ctypeslib.ndpointer(dtype=np.double),  #karr
            np.ctypeslib.ndpointer(dtype=np.double),  #pkarr
            np.ctypeslib.ndpointer(dtype=np.double),  #dndz
            POINTER(c_int64),  #nz_dndz
            POINTER(c_double),  #z1
            POINTER(c_double),  #z2
            POINTER(c_double),  #z1_ng
            POINTER(c_double),  #z2_ng
            POINTER(c_int64),  #nl
            np.ctypeslib.ndpointer(dtype=np.double),  #ell
            np.ctypeslib.ndpointer(dtype=np.double),  #gg
            np.ctypeslib.ndpointer(dtype=np.double),  #gy
            np.ctypeslib.ndpointer(dtype=np.double),  #tll
            POINTER(c_double),  #ng(z1<z<z2)
            POINTER(c_int64),  #flag_nu
            POINTER(c_int64),  #flag_tll
            POINTER(c_int64),  #nm
            POINTER(c_int64)  #nz
        ]
        self.fort_lib_cl.calc_cl_.restype = c_void_p

        # Calcualtion setup
        self.kmin = 1e-3
        self.kmax = 5.
        self.zmax = 4.  # should be consistent with fortran code
        self.nk_pk = 200
        self.nz_pk = 51

        # Class
        self.cosmo = Class()

    def get_tsz_cl(self, ell_arr, params, dndz, z1, z2, z1_ng, z2_ng, nm, nz):
        self.zmin = z1
        self.zmax = z2
        obh2 = params['obh2']
        och2 = params['och2']
        As = params['As']
        ns = params['ns']
        mnu = params['mnu']
        mass_bias = params['mass_bias']
        Mcut = params['Mcut']
        M1 = params['M1']
        kappa = params['kappa']
        sigma_Ncen = params['sigma_Ncen']
        alp_Nsat = params['alp_Nsat']
        rmax = params['rmax']
        rgs = params['rgs']
        flag_nu_logic = params['flag_nu']
        flag_tll_logic = params['flag_tll']
        if type(flag_nu_logic) != bool:
            print 'flag_nu must be boolean.'
            sys.exit()
        if flag_nu_logic:
            flag_nu = 1
        else:
            flag_nu = 0
        if type(flag_tll_logic) != bool:
            print 'flag_tll must be boolean.'
            sys.exit()
        if flag_tll_logic:
            flag_tll = 1
        else:
            flag_tll = 0

        if 'theta' in params.keys():
            theta = params['theta']
            pars = {'output':'mPk','100*theta_s':theta,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':self.zmax,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()
            h0 = self.cosmo.h()
        elif 'h0' in params.keys():
            h0 = params['h0']
            pars = {'output':'mPk','h':h0,
                    'omega_b':obh2,'omega_cdm':och2,
                    'A_s':As,'n_s':ns,\
                    'N_ur':0.00641,'N_ncdm':1,'m_ncdm':mnu/3.,\
                    'T_ncdm':0.71611,\
                    'P_k_max_h/Mpc': self.kmax,'z_max_pk':self.zmax,\
                    'deg_ncdm':3.}
            self.cosmo.set(pars)
            self.cosmo.compute()

        # get matter power spectra
        kh_arr = np.logspace(np.log10(self.kmin), np.log10(self.kmax),
                             self.nk_pk)
        kh = np.zeros((self.nz_pk, self.nk_pk))
        pk = np.zeros((self.nz_pk, self.nk_pk))
        pk_zarr = np.linspace(self.zmin, self.zmax, self.nz_pk)
        for i in range(self.nz_pk):
            kh[i, :] = kh_arr
            if flag_nu == 0:
                pk[i, :] = np.array([
                    self.cosmo.pk(k * h0, pk_zarr[i]) * h0**3 for k in kh_arr
                ])
            elif flag_nu == 1:
                pk[i, :] = np.array([
                    self.cosmo.pk_cb(k * h0, pk_zarr[i]) * h0**3
                    for k in kh_arr
                ])

        # params
        h0_in = byref(c_double(h0))
        obh2_in = byref(c_double(obh2))
        och2_in = byref(c_double(och2))
        mnu_in = byref(c_double(mnu))
        mass_bias_in = byref(c_double(mass_bias))
        Mcut_in = byref(c_double(Mcut))
        M1_in = byref(c_double(M1))
        kappa_in = byref(c_double(kappa))
        sigma_Ncen_in = byref(c_double(sigma_Ncen))
        alp_Nsat_in = byref(c_double(alp_Nsat))
        rmax_in = byref(c_double(rmax))
        rgs_in = byref(c_double(rgs))
        flag_nu_in = byref(c_int64(flag_nu))
        flag_tll_in = byref(c_int64(flag_tll))

        # dNdz
        nz_dndz = byref(c_int64(len(dndz)))

        # integration setting
        z1_in = byref(c_double(self.zmin))
        z2_in = byref(c_double(self.zmax))

        # outputs
        nl = len(ell_arr)
        cl_gg = np.zeros((2, nl))
        cl_gy = np.zeros((2, nl))
        tll = np.zeros((nl * 2, nl * 2))
        ng = c_double(0.0)
        nl = c_int64(nl)

        self.fort_lib_cl.calc_cl_(
                h0_in, obh2_in, och2_in, mnu_in,\
                mass_bias_in, \
                Mcut_in, M1_in, kappa_in, sigma_Ncen_in, alp_Nsat_in,\
                rmax_in, rgs_in,\
                byref(c_int64(self.nk_pk)), byref(c_int64(self.nz_pk)),\
                np.array(kh),np.array(pk),\
                np.array(dndz),nz_dndz,\
                z1_in, z2_in,\
                byref(c_double(z1_ng)),byref(c_double(z2_ng)),\
                nl,np.array(ell_arr),\
                cl_gg,cl_gy,tll,ng,\
                flag_nu_in,flag_tll_in,\
                c_int64(nm), c_int64(nz)
                )

        self.cosmo.struct_cleanup()
        return cl_gg, cl_gy, tll, ng.value
Ejemplo n.º 22
0
 tau = np.concatenate((tau1,tau2))
 tau_num = len(tau)
 #
 # use table of background and thermodynamics quantitites to define some functions
 # returning some characteristic scales
 # (of Hubble crossing, sound horizon crossing, etc.) at different time
 #
 background = M.get_background() # load background table
 #print background.viewkeys()
 thermodynamics = M.get_thermodynamics() # load thermodynamics table
 #print thermodynamics.viewkeys()
 #
 background_tau = background['conf. time [Mpc]'] # read conformal times in background table
 background_z = background['z'] # read redshift
 # background_aH = 2.*math.pi*background['H [1/Mpc]']/(1.+background['z'])/M.h() # read 2pi * aH in [h/Mpc]
 background_aH = background['H [1/Mpc]']/(1.+background['z'])/M.h() # read 2pi * aH in [h/Mpc]
 background_ks = 2.*math.pi/background['comov.snd.hrz.']/M.h() # read 2pi/(comoving sound horizon) in [h/Mpc]
 background_rho_m_over_r =    (background['(.)rho_b']+background['(.)rho_cdm'])    /(background['(.)rho_g']+background['(.)rho_ur']) # read rho_r / rho_m (to find time of equality)
 background_rho_l_over_m =    background['(.)rho_lambda']    /(background['(.)rho_b']+background['(.)rho_cdm']) # read rho_m / rho_lambda (to find time of equality)
 thermodynamics_tau = thermodynamics['conf. time [Mpc]'] # read confromal times in thermodynamics table
 # thermodynamics_kd = 2.*math.pi/thermodynamics['r_d']/M.h() # read 2pi(comoving diffusion scale) in [h/Mpc]
 #
 # define a bunch of interpolation functions based on previous quantities
 #
 background_z_at_tau = interp1d(background_tau,background_z)
 background_tau_at_z = interp1d(background_z,background_tau)
 background_aH_at_tau = interp1d(background_tau,background_aH)
 background_ks_at_tau = interp1d(background_tau,background_ks)
 background_tau_at_mr = interp1d(background_rho_m_over_r,background_tau)
 background_tau_at_lm = interp1d(background_rho_l_over_m,background_tau)
 #
Ejemplo n.º 23
0
    NH.set(commonsettings)
    NH.set({'m_ncdm': str(m1) + ',' + str(m2) + ',' + str(m3)})
    NH.compute()
    # inverted hierarchy
    [m1, m2, m3] = get_masses(2.45e-3, 7.50e-5, sum_masses, 'IH')
    IH = Class()
    IH.set(commonsettings)
    IH.set({'m_ncdm': str(m1) + ',' + str(m2) + ',' + str(m3)})
    IH.compute()
    pkNH = []
    pkIH = []
    for k in kvec:
        pkNH.append(NH.pk(k, 0.))
        pkIH.append(IH.pk(k, 0.))
    NH.struct_cleanup()
    IH.struct_cleanup()
    # extract h value to convert k from 1/Mpc to h/Mpc
    h = NH.h()
    plt.semilogx(kvec / h, 1 - np.array(pkNH) / np.array(pkIH))
    legarray.append(r'$\Sigma m_i = ' + str(sum_masses) + '$eV')

plt.axhline(0, color='k')
plt.xlim(kvec[0] / h, kvec[-1] / h)
plt.xlabel(r'$k [h \mathrm{Mpc}^{-1}]$')
plt.ylabel(r'$1-P(k)^\mathrm{NH}/P(k)^\mathrm{IH}$')
plt.legend(legarray)

# In[6]:

plt.savefig('neutrinohierarchy.pdf')
Ejemplo n.º 24
0
tau_num = len(tau)
#
# use table of background and thermodynamics quantitites to define some functions
# returning some characteristic scales
# (of Hubble crossing, sound horizon crossing, etc.) at different time
#
background = M.get_background()  # load background table
#print background.viewkeys()
thermodynamics = M.get_thermodynamics()  # load thermodynamics table
#print thermodynamics.viewkeys()
#
background_tau = background[
    'conf. time [Mpc]']  # read conformal times in background table
background_z = background['z']  # read redshift
background_aH = 2. * math.pi * background['H [1/Mpc]'] / (
    1. + background['z']) / M.h()  # read 2pi * aH in [h/Mpc]
background_ks = 2. * math.pi / background['comov.snd.hrz.'] / M.h(
)  # read 2pi/(comoving sound horizon) in [h/Mpc]
background_rho_m_over_r = (background['(.)rho_b'] +
                           background['(.)rho_cdm']) / (
                               background['(.)rho_g'] + background['(.)rho_ur']
                           )  # read rho_r / rho_m (to find time of equality)
background_rho_l_over_m = background['(.)rho_lambda'] / (
    background['(.)rho_b'] + background['(.)rho_cdm']
)  # read rho_m / rho_lambda (to find time of equality)
thermodynamics_tau = thermodynamics[
    'conf. time [Mpc]']  # read confromal times in thermodynamics table
thermodynamics_kd = 2. * math.pi / thermodynamics['r_d'] / M.h(
)  # read 2pi(comoving diffusion scale) in [h/Mpc]
#
# define a bunch of interpolation functions based on previous quantities
Ejemplo n.º 25
0
    NH.set({'m_ncdm':str(m1)+','+str(m2)+','+str(m3)})
    NH.compute()
    # inverted hierarchy
    [m1, m2, m3] = get_masses(2.45e-3,7.50e-5, sum_masses, 'IH')
    IH = Class()
    IH.set(commonsettings)
    IH.set({'m_ncdm':str(m1)+','+str(m2)+','+str(m3)})
    IH.compute()
    pkNH = []
    pkIH = []
    for k in kvec:
        pkNH.append(NH.pk(k,0.))
        pkIH.append(IH.pk(k,0.))
    NH.struct_cleanup()
    IH.struct_cleanup()
    # extract h value to convert k from 1/Mpc to h/Mpc
    h = NH.h()
    plt.semilogx(kvec/h,1-np.array(pkNH)/np.array(pkIH))
    legarray.append(r'$\Sigma m_i = '+str(sum_masses)+'$eV')

plt.axhline(0,color='k')
plt.xlim(kvec[0]/h,kvec[-1]/h)
plt.xlabel(r'$k [h \mathrm{Mpc}^{-1}]$')
plt.ylabel(r'$1-P(k)^\mathrm{NH}/P(k)^\mathrm{IH}$')
plt.legend(legarray)


# In[6]:

plt.savefig('neutrinohierarchy.pdf')
Ejemplo n.º 26
0
class classy(_cosmo):

    def initialize(self):
        """Importing CLASS from the correct path, if given, and if not, globally."""
        # If path not given, try using general path to modules
        if not self.path and self.path_install:
            self.path = os.path.join(
                self.path_install, "code", classy_repo_rename)
        if self.path:
            self.log.info("Importing *local* classy from " + self.path)
            classy_build_path = os.path.join(self.path, "python", "build")
            post = next(d for d in os.listdir(classy_build_path) if d.startswith("lib."))
            classy_build_path = os.path.join(classy_build_path, post)
            if not os.path.exists(classy_build_path):
                self.log.error("Either CLASS is not in the given folder, "
                               "'%s', or you have not compiled it.", self.path)
                raise HandledException
            # Inserting the previously found path into the list of import folders
            sys.path.insert(0, classy_build_path)
        else:
            self.log.info("Importing *global* CLASS.")
        try:
            from classy import Class, CosmoSevereError, CosmoComputationError
        except ImportError:
            self.log.error(
                "Couldn't find the CLASS python interface. "
                "Make sure that you have compiled it, and that you either\n"
                " (a) specify a path (you didn't) or\n"
                " (b) install the Python interface globally with\n"
                "     '/path/to/class/python/python setup.py install --user'")
            raise HandledException
        self.classy = Class()
        # Propagate errors up
        global CosmoComputationError, CosmoSevereError
        # Generate states, to avoid recomputing
        self.n_states = 3
        self.states = [{"params": None, "derived": None, "derived_extra": None,
                        "last": 0} for i in range(self.n_states)]
        # Dict of named tuples to collect requirements and computation methods
        self.collectors = {}
        # Additional input parameters to pass to CLASS
        self.extra_args = self.extra_args or {}
        # Add general CLASS stuff
        self.extra_args["output"] = self.extra_args.get("output", "")
        if "sBBN file" in self.extra_args:
            self.extra_args["sBBN file"] = (
                self.extra_args["sBBN file"].format(classy=self.path))
        # Set aliases
        self.planck_to_classy = self.renames
        # Derived parameters that may not have been requested, but will be necessary later
        self.derived_extra = []

    def current_state(self):
        lasts = [self.states[i]["last"] for i in range(self.n_states)]
        return self.states[lasts.index(max(lasts))]

    def needs(self, **requirements):
        # Computed quantities required by the likelihood
        super(classy, self).needs(**requirements)
        for k, v in self._needs.items():
            # Products and other computations
            if k.lower() == "cl":
                if any([("t" in cl.lower()) for cl in v]):
                    self.extra_args["output"] += " tCl"
                if any([(("e" in cl.lower()) or ("b" in cl.lower())) for cl in v]):
                    self.extra_args["output"] += " pCl"
                # For modern experiments, always lensed Cl's!
                self.extra_args["output"] += " lCl"
                self.extra_args["lensing"] = "yes"
                # For l_max_scalars, remember previous entries.
                self.extra_args["l_max_scalars"] = max(v.values())
                self.collectors[k.lower()] = collector(
                    method="lensed_cl", kwargs={"lmax": self.extra_args["l_max_scalars"]})
            elif k.lower() == "h":
                self.collectors[k.lower()] = collector(
                    method="Hubble",
                    args=[np.atleast_1d(v["z"])],
                    args_names=["z"],
                    arg_array=0)
                self.H_units_conv_factor = {"1/Mpc": 1, "km/s/Mpc": _c_km_s}
            elif k.lower() == "angular_diameter_distance":
                self.collectors[k.lower()] = collector(
                    method="angular_distance",
                    args=[np.atleast_1d(v["z"])],
                    args_names=["z"],
                    arg_array=0)
            elif k.lower() == "comoving_radial_distance":
                self.collectors[k.lower()] = collector(
                    method="z_of_r",
                    args_names=["z"],
                    args=[np.atleast_1d(v["z"])])
            elif k.lower() == "pk_interpolator":
                self.extra_args["output"] += " mPk"
                self.extra_args["P_k_max_h/Mpc"] = max(
                    v.pop("k_max"), self.extra_args.get("P_k_max_h/Mpc", 0))
                self.add_z_for_matter_power(v.pop("z"))
                # Use halofit by default if non-linear requested but no code specified
                if v.get("nonlinear", False) and "non linear" not in self.extra_args:
                    self.extra_args["non linear"] = non_linear_default_code
                for pair in v.pop("vars_pairs", [["delta_tot", "delta_tot"]]):
                    if any([x.lower() != "delta_tot" for x in pair]):
                        self.log.error("NotImplemented in CLASS: %r", pair)
                        raise HandledException
                    self._Pk_interpolator_kwargs = {
                        "logk": True, "extrap_kmax": v.pop("extrap_kmax", None)}
                    name = "Pk_interpolator_%s_%s" % (pair[0], pair[1])
                    self.collectors[name] = collector(
                        method="get_pk_and_k_and_z",
                        kwargs=v,
                        post=(lambda P, k, z:PowerSpectrumInterpolator(
                            z, k, P.T, **self._Pk_interpolator_kwargs)))
            elif v is None:
                k_translated = self.translate_param(k, force=True)
                if k_translated not in self.derived_extra:
                    self.derived_extra += [k_translated]
            else:
                self.log.error("Requested product not known: %r", {k: v})
                raise HandledException
        # Derived parameters (if some need some additional computations)
        if any([("sigma8" in s) for s in self.output_params or requirements]):
            self.extra_args["output"] += " mPk"
            self.extra_args["P_k_max_h/Mpc"] = (
                max(1, self.extra_args.get("P_k_max_h/Mpc", 0)))
        # Adding tensor modes if requested
        if self.extra_args.get("r") or "r" in self.input_params:
            self.extra_args["modes"] = "s,t"
        # If B spectrum with l>50, or lensing, recommend using Halofit
        try:
            cls = self.needs[next(k for k in ["cl", "Cl", "CL"] if k in self._needs)]
        except:
            cls = {}
        if (((any([("b" in cl.lower()) for cl in cls]) and
              max([cls[cl] for cl in cls if "b" in cl.lower()]) > 50) or
             any([("p" in cl.lower()) for cl in cls]) and
             not self.extra_args.get("non linear"))):
            self.log.warning("Requesting BB for ell>50 or lensing Cl's: "
                             "using a non-linear code is recommended (and you are not "
                             "using any). To activate it, set "
                             "'non_linear: halofit|hmcode|...' in classy's 'extra_args'.")
        # Cleanup of products string
        self.extra_args["output"] = " ".join(set(self.extra_args["output"].split()))
        # Finally, check that there are no repeated parameters between input and extra
        if set(self.input_params).intersection(set(self.extra_args)):
            self.log.error(
                "The following parameters appear both as input parameters and as CLASS "
                "extra arguments: %s. Please, remove one of the definitions of each.",
                list(set(self.input_params).intersection(set(self.extra_args))))
            raise HandledException

    def add_z_for_matter_power(self, z):
        if not hasattr(self, "z_for_matter_power"):
            self.z_for_matter_power = np.empty((0))
        self.z_for_matter_power = np.flip(np.sort(np.unique(np.concatenate(
            [self.z_for_matter_power, np.atleast_1d(z)]))), axis=0)
        self.extra_args["z_pk"] = " ".join(["%g" % zi for zi in self.z_for_matter_power])

    def translate_param(self, p, force=False):
        # "force=True" is used when communicating with likelihoods, which speak "planck"
        if self.use_planck_names or force:
            return self.planck_to_classy.get(p, p)
        return p

    def set(self, params_values_dict, i_state):
        # Store them, to use them later to identify the state
        self.states[i_state]["params"] = deepcopy(params_values_dict)
        # Prepare parameters to be passed: this-iteration + extra
        args = {self.translate_param(p): v for p, v in params_values_dict.items()}
        args.update(self.extra_args)
        # Generate and save
        self.log.debug("Setting parameters: %r", args)
        self.classy.struct_cleanup()
        self.classy.set(**args)

    def compute(self, _derived=None, cached=True, **params_values_dict):
        lasts = [self.states[i]["last"] for i in range(self.n_states)]
        try:
            if not cached:
                raise StopIteration
            # are the parameter values there already?
            i_state = next(i for i in range(self.n_states)
                           if self.states[i]["params"] == params_values_dict)
            # has any new product been requested?
            for product in self.collectors:
                next(k for k in self.states[i_state] if k == product)
            reused_state = True
            # Get (pre-computed) derived parameters
            if _derived == {}:
                _derived.update(self.states[i_state]["derived"])
            self.log.debug("Re-using computed results (state %d)", i_state)
        except StopIteration:
            reused_state = False
            # update the (first) oldest one and compute
            i_state = lasts.index(min(lasts))
            self.log.debug("Computing (state %d)", i_state)
            if self.timing:
                a = time()
            # Set parameters
            self.set(params_values_dict, i_state)
            # Compute!
            try:
                self.classy.compute()
            # "Valid" failure of CLASS: parameters too extreme -> log and report
            except CosmoComputationError:
                self.log.debug("Computation of cosmological products failed. "
                               "Assigning 0 likelihood and going on.")
                return 0
            # CLASS not correctly initialized, or input parameters not correct
            except CosmoSevereError:
                self.log.error("Serious error setting parameters or computing results. "
                               "The parameters passed were %r and %r. "
                               "See original CLASS's error traceback below.\n",
                               self.states[i_state]["params"], self.extra_args)
                raise  # No HandledException, so that CLASS traceback gets printed
            # Gather products
            for product, collector in self.collectors.items():
                # Special case: sigma8 needs H0, which cannot be known beforehand:
                if "sigma8" in self.collectors:
                    self.collectors["sigma8"].args[0] = 8 / self.classy.h()
                method = getattr(self.classy, collector.method)
                arg_array = self.collectors[product].arg_array
                if arg_array is None:
                    self.states[i_state][product] = method(
                        *self.collectors[product].args, **self.collectors[product].kwargs)
                elif isinstance(arg_array, Number):
                    self.states[i_state][product] = np.zeros(
                        len(self.collectors[product].args[arg_array]))
                    for i, v in enumerate(self.collectors[product].args[arg_array]):
                        args = (list(self.collectors[product].args[:arg_array]) + [v] +
                                list(self.collectors[product].args[arg_array + 1:]))
                        self.states[i_state][product][i] = method(
                            *args, **self.collectors[product].kwargs)
                elif arg_array in self.collectors[product].kwargs:
                    value = np.atleast_1d(self.collectors[product].kwargs[arg_array])
                    self.states[i_state][product] = np.zeros(value.shape)
                    for i, v in enumerate(value):
                        kwargs = deepcopy(self.collectors[product].kwargs)
                        kwargs[arg_array] = v
                        self.states[i_state][product][i] = method(
                            *self.collectors[product].args, **kwargs)
                self.states[i_state][product] = collector.post(
                    self.states[i_state][product])
            # Prepare derived parameters
            d, d_extra = self.get_derived_all(derived_requested=(_derived == {}))
            if _derived == {}:
                _derived.update(d)
            self.states[i_state]["derived"] = odict(
                [[p, _derived.get(p)] for p in self.output_params])
            # Prepare necessary extra derived parameters
            self.states[i_state]["derived_extra"] = deepcopy(d_extra)
            if self.timing:
                self.n += 1
                self.time_avg = (time() - a + self.time_avg * (self.n - 1)) / self.n
                self.log.debug("Average running time: %g seconds", self.time_avg)
        # make this one the current one by decreasing the antiquity of the rest
        for i in range(self.n_states):
            self.states[i]["last"] -= max(lasts)
        self.states[i_state]["last"] = 1
        return 1 if reused_state else 2

    def get_derived_all(self, derived_requested=True):
        """
        Returns a dictionary of derived parameters with their values,
        using the *current* state (i.e. it should only be called from
        the ``compute`` method).

        Parameter names are returned in CLASS nomenclature.

        To get a parameter *from a likelihood* use `get_param` instead.
        """
        # Put all pamaremters in CLASS nomenclature (self.derived_extra already is)
        requested = [self.translate_param(p) for p in (
            self.output_params if derived_requested else [])]
        requested_and_extra = {
            p: None for p in set(requested).union(set(self.derived_extra))}
        # Parameters with their own getters
        if "rs_drag" in requested_and_extra:
            requested_and_extra["rs_drag"] = self.classy.rs_drag()
        elif "Omega_nu" in requested_and_extra:
            requested_and_extra["Omega_nu"] = self.classy.Omega_nu
        # Get the rest using the general derived param getter
        # No need for error control: classy.get_current_derived_parameters is passed
        # every derived parameter not excluded before, and cause an error, indicating
        # which parameters are not recognized
        requested_and_extra.update(
            self.classy.get_current_derived_parameters(
                [p for p, v in requested_and_extra.items() if v is None]))
        # Separate the parameters before returning
        # Remember: self.output_params is in sampler nomenclature,
        # but self.derived_extra is in CLASS
        derived = {
            p: requested_and_extra[self.translate_param(p)] for p in self.output_params}
        derived_extra = {p: requested_and_extra[p] for p in self.derived_extra}
        return derived, derived_extra

    def get_param(self, p):
        current_state = self.current_state()
        for pool in ["params", "derived", "derived_extra"]:
            value = deepcopy(
                current_state[pool].get(self.translate_param(p, force=True), None))
            if value is not None:
                return value
        self.log.error("Parameter not known: '%s'", p)
        raise HandledException

    def get_cl(self, ell_factor=False, units="muK2"):
        current_state = self.current_state()
        try:
            cls = deepcopy(current_state["cl"])
        except:
            self.log.error(
                "No Cl's were computed. Are you sure that you have requested them?")
            raise HandledException
        # unit conversion and ell_factor
        ell_factor = ((cls["ell"] + 1) * cls["ell"] / (2 * np.pi))[2:] if ell_factor else 1
        units_factors = {"1": 1,
                         "muK2": _T_CMB_K * 1.e6,
                         "K2": _T_CMB_K}
        try:
            units_factor = units_factors[units]
        except KeyError:
            self.log.error("Units '%s' not recognized. Use one of %s.",
                           units, list(units_factors))
            raise HandledException
        for cl in cls:
            if cl not in ['pp', 'ell']:
                cls[cl][2:] *= units_factor ** 2 * ell_factor
        if "pp" in cls and ell_factor is not 1:
            cls['pp'][2:] *= ell_factor ** 2 * (2 * np.pi)
        return cls

    def _get_z_dependent(self, quantity, z):
        try:
            z_name = next(k for k in ["redshifts", "z"]
                          if k in self.collectors[quantity].kwargs)
            computed_redshifts = self.collectors[quantity].kwargs[z_name]
        except StopIteration:
            computed_redshifts = self.collectors[quantity].args[
                self.collectors[quantity].args_names.index("z")]
        i_kwarg_z = np.concatenate(
            [np.where(computed_redshifts == zi)[0] for zi in np.atleast_1d(z)])
        values = np.array(deepcopy(self.current_state()[quantity]))
        if quantity == "comoving_radial_distance":
            values = values[0]
        return values[i_kwarg_z]

    def get_H(self, z, units="km/s/Mpc"):
        try:
            return self._get_z_dependent("h", z) * self.H_units_conv_factor[units]
        except KeyError:
            self.log.error("Units not known for H: '%s'. Try instead one of %r.",
                           units, list(self.H_units_conv_factor))
            raise HandledException

    def get_angular_diameter_distance(self, z):
        return self._get_z_dependent("angular_diameter_distance", z)

    def get_comoving_radial_distance(self, z):
        return self._get_z_dependent("comoving_radial_distance", z)

    def get_Pk_interpolator(self):
        current_state = self.current_state()
        prefix = "Pk_interpolator_"
        return {k[len(prefix):]: deepcopy(v)
                for k, v in current_state.items() if k.startswith(prefix)}

    def close(self):
        self.classy.struct_cleanup()
Ejemplo n.º 27
0
#
# call CLASS a first time just to compute z_rec (will compute transfer functions at default: z=0)
#
###############
M = Class()
M.set(common_settings)
M.compute()
derived = M.get_current_derived_parameters(['z_rec','tau_rec','conformal_age'])
print (derived.keys())
z_rec = derived['z_rec']
z_rec = int(1000.*z_rec)/1000. # round down at 4 digits after coma
print ('z_rec=',z_rec)
#
# In the last figure the x-axis will show l/(tau_0-tau_rec), so we need (tau_0-tau_rec) in units of [Mpc/h]
#
tau_0_minus_tau_rec_hMpc = (derived['conformal_age']-derived['tau_rec'])*M.h()


# In[ ]:


################
#
# call CLASS again for the perturbations (will compute transfer functions at input value z_rec)
#
################
M.empty() # reset input parameters to default, before passing a new parameter set
M.set(common_settings)
M.set({'z_pk':z_rec})
M.compute()
#
Ejemplo n.º 28
0
# get Theta0 oscillation amplitude (for vertical scale of plot)
#
Theta0_amp = max(Theta0.max(), -Theta0.min())
#
# use table of background quantitites to find the wavenumbers corresponding to
# Hubble crossing (k = 2 pi a H), sound horizon crossing (k = 2pi / rs)
#
background = M.get_background()  # load background table
#print background.viewkeys()
#
background_tau = background[
    'conf. time [Mpc]']  # read confromal times in background table
background_z = background['z']  # read redshift
background_kh = 2. * math.pi * background['H [1/Mpc]'] / (
    1. + background['z']
) / M.h()  # read kh = 2pi aH = 2pi H/(1+z) converted to [h/Mpc]
background_ks = 2. * math.pi / background['comov.snd.hrz.'] / M.h(
)  # read ks = 2pi/rs converted to [h/Mpc]
#
# define interpolation functions; we want the value of tau when the argument is equal to 2pi
#
kh_at_tau = interp1d(background_tau, background_kh)
ks_at_tau = interp1d(background_tau, background_ks)
#
# finally get these scales
#
tau_rec = derived['tau_rec']
kh = kh_at_tau(tau_rec)
ks = ks_at_tau(tau_rec)
#
#################
Ejemplo n.º 29
0
plt.plot((ttCLASS[:ell_max + 1] - ttCAMB[:ell_max + 1]) / ttCAMB[:ell_max + 1],
         '-')
plt.xlabel(r'$\ell$')
plt.ylabel(r'$\Delta C_{\ell}^{TT} / C_{\ell}^{TT}$')
plt.title('TT Comparison of CAMB and CLASS')

########## P(k) #########################

pars.set_matter_power(redshifts=[0.], kmax=2.0)
pars.NonLinear = model.NonLinear_none
results = camb.get_results(pars)
kh, z, pk = results.get_matter_power_spectrum(minkh=1e-4, maxkh=1, npoints=200)
s8 = np.array(results.get_sigma8())

PCLASS = np.array([cosmo.pk_lin(ki * cosmo.h(), 0) for ki in kh])

# plt.loglog(kh, Pmm, '-')
plt.loglog(kh, PCLASS / (cosmo.h())**(-3), '-')
plt.loglog(kh, pk[0, :], '-')
plt.title('LINEAR')

# P(k) Comparison

plt.loglog(kh, np.abs((PCLASS / (cosmo.h())**(-3) - pk[0, :]) / pk[0, :]))
plt.xlabel(r'$k/h$')
plt.ylabel(r'$|\Delta P(k)| / P(k)$')

# Nonlinear P(k) Difference

pars.NonLinear = model.NonLinear_both
Ejemplo n.º 30
0
    'omega_cdm': omega_cdm,
    'n_s': n_s
}

# update the CLASS object with the current parameters
class_cosmo = Class()

# update the cosmology
new_cosmo = {**fid_cosmo, **updated_dict}
new_cosmo['output'] = 'mPk'
new_cosmo['z_max_pk'] = 1.1
class_cosmo.set(new_cosmo)
class_cosmo.compute()

# search for the corresponding value of H0 that keeps theta_s constant and update Omega_b and c
h = class_cosmo.h()
#h = H0_search(class_cosmo, fid_cosmo['100*theta_s'], prec=1.e4, tol_t=1.e-4)
print(h)
param_dict['h'] = h
param_dict['Omega_c'] = omega_cdm / h**2
param_dict['Omega_b'] = omega_b / h**2
param_dict['A_s'] = A_s

# remove parameters not recognized by ccl
param_not_ccl = ['100*theta_s', 'omega_cdm', 'omega_b', 'output', 'sigma8']
for p in param_not_ccl:
    if p in param_dict.keys(): param_dict.pop(p)

#param_dict['T_cmb'] = header['T_cmb']
# cosmology of the current step
cosmo_ccl = ccl.Cosmology(**param_dict)
Ejemplo n.º 31
0
R = 3./4.*M.Omega_b()/M.Omega_g()/(1+z_rec)  # R = 3/4 * (rho_b/rho_gamma) at z_rec
zero_point = -(1.+R)*psi                     # zero point of oscillations: -(1.+R)*psi
#
# get Theta0 oscillation amplitude (for vertical scale of plot)
#
Theta0_amp = max(Theta0.max(),-Theta0.min())
#
# use table of background quantitites to find the wavenumbers corresponding to
# Hubble crossing (k = 2 pi a H), sound horizon crossing (k = 2pi / rs)
#
background = M.get_background() # load background table
#print background.viewkeys()
#
background_tau = background['conf. time [Mpc]'] # read confromal times in background table
background_z = background['z'] # read redshift
background_kh = 2.*math.pi*background['H [1/Mpc]']/(1.+background['z'])/M.h() # read kh = 2pi aH = 2pi H/(1+z) converted to [h/Mpc]
background_ks = 2.*math.pi/background['comov.snd.hrz.']/M.h() # read ks = 2pi/rs converted to [h/Mpc]
#
# define interpolation functions; we want the value of tau when the argument is equal to 2pi
#
kh_at_tau = interp1d(background_tau,background_kh)
ks_at_tau = interp1d(background_tau,background_ks)
#
# finally get these scales
#
tau_rec = derived['tau_rec']
kh = kh_at_tau(tau_rec)
ks = ks_at_tau(tau_rec)
#
#################
#