def nu_masses(OmNuh2, mass_split, ccl_TCMB=2.725): """nu_masses Returns the neutrinos mass(es) for a given OmNuh2, according to the splitting convention specified by the user. Args: OmNuh2 (float): Neutrino energy density at z=0 times h^2 mass_split: indicates how the masses should be split up TCMB (float, optional): Temperature of the CMB (K). Default: 2.725. Returns: Neutrino mass(es) corresponding to this Omeganuh2 """ status = 0 if mass_split not in neutrino_mass_splits.keys() : raise ValueError( "'%s' is not a valid species type. " "Available options are: %s" \ % (mass_split,neutrino_mass_splits.keys()) ) # Call function if ((mass_split=='normal') or (mass_split=='inverted') or (mass_split=='equal')): mnu, status = lib.nu_masses_vec(OmNuh2, neutrino_mass_splits[mass_split], ccl_TCMB, 3, status) elif mass_split=='sum': mnu, status = lib.nu_masses_vec(OmNuh2, neutrino_mass_splits[mass_split], ccl_TCMB, 1, status) mnu = mnu[0] # Check status and return check(status) return mnu
def correlation_3d(cosmo, a, r): """ Compute the 3D correlation function. Args: cosmo (:obj:`Cosmology`): A Cosmology object. a (float): scale factor. r (float or array_like): distance(s) at which to calculate the 3D correlation function (in Mpc). Returns: Value(s) of the correlation function at the input distance(s). """ cosmo_in = cosmo cosmo = _cosmology_obj(cosmo) status = 0 # Convert scalar input into an array scalar = False if isinstance(r, float) or isinstance(r, int): scalar = True r = np.array([ r, ]) # Call 3D correlation function xi, status = lib.correlation_3d_vec(cosmo, a, r, len(r), status) check(status, cosmo_in) if scalar: return xi[0] return xi
def Omeganuh2(a, mnu, TCMB=2.725): """Omeganuh2 .. note:: for all practical purposes, Neff is simply N_nu_mass. Args: a (float): Scale factor, normalized to 1 today. mnu (float or array_like): Neutrino mass (in eV) TCMB (float, optional): Temperature of the CMB (K). Default: 2.725. Returns: float or array_like: corresponding to a given neutrino mass. """ status = 0 scalar = True if isinstance(a, float) else False # Convert to array if it's not already an array if not isinstance(a, np.ndarray): a = np.array([a,]).flatten() if not isinstance(mnu, np.ndarray): mnu = np.array([mnu,]).flatten() N_nu_mass = len(mnu) # Call function OmNuh2, status = lib.Omeganuh2_vec(N_nu_mass, TCMB, a, mnu, a.size, status) # Check status and return check(status) if scalar: return OmNuh2[0] return OmNuh2
def dNdz_tomog(z, dNdz_type, zmin, zmax, pz_func): """Calculates dNdz in a particular tomographic bin, convolved with a photo-z model (defined by the user), and normalized. Args: z (float or array_like): Spectroscopic redshifts to evaluate dNdz at. dNdz_type (:obj:`str`): Type of redshift distribution. zmin (float): Minimum photo-z of the bin. zmax (float): Maximum photo-z of the bin. pz_func (callable): User-defined photo-z function. Return: dNdz (float or array_like): dNdz values evalued at each z. """ # Ensure that an array will be passed to specs_dNdz_tomog_vec z = np.atleast_1d(z) # Do type-check for pz_func argument if not isinstance(pz_func, PhotoZFunction): raise TypeError("pz_func must be a PhotoZFunction instance.") # Get dNdz type if dNdz_type not in dNdz_types.keys(): raise ValueError("'%s' not a valid dNdz_type." % dNdz_type) # Call dNdz tomography function status = 0 dNdz, status = lib.specs_dNdz_tomog_vec(dNdz_types[dNdz_type], zmin, zmax, pz_func.pz_func, z, z.size, status) check(status) return dNdz
def compute_growth(self): """Interfaces with src/ccl_background.c: ccl_cosmology_compute_growth(). Sets up the splines for the growth function. """ status = 0 status = lib.cosmology_compute_growth(self.cosmo, status) check(status, self.cosmo)
def compute_power(self): """Interfaces with src/ccl_power.c: ccl_cosmology_compute_power(). Sets up the splines for the power spectrum. """ status = 0 status = lib.cosmology_compute_power(self.cosmo, status) check(status, self.cosmo)
def compute_distances(self): """Interfaces with src/compute_background.c: ccl_cosmology_compute_distances(). Sets up the splines for the distances. """ status = 0 status = lib.cosmology_compute_distances(self.cosmo, status) check(status, self.cosmo)
def get_internal_function(self, cosmo, function, a): """ Method to evaluate any internal function of redshift for this tracer. Args: cosmo (:obj:`Cosmology`): Cosmology object. function (:obj:`str`): Specifies which function to evaluate. Must be one of the types specified in the `pyccl.cls.function_types` dictionary. a (:obj: float or array-like): list of scale factors at which to evaluate the function. Returns: Array of function values at the input scale factors. """ # Access ccl_cosmology object cosmo_in = cosmo cosmo = _cosmology_obj(cosmo) # Access CCL_ClTracer objects clt = self.cltracer # Check that specified function type exists if function not in function_types.keys(): raise KeyError("Internal function type '%s' not recognized." % function) # Check input types status = 0 is_scalar = False if isinstance(a, float): is_scalar = True aarr = np.array([a]) na = 1 elif isinstance(a, np.ndarray): aarr = a na = a.size else: aarr = a na = len(a) # Evaluate function farr, status = lib.clt_fa_vec(cosmo, self.cltracer, function_types[function], aarr, na, status) check(status, cosmo_in) if is_scalar: return farr[0] else: return farr
def correlation(cosmo, ell, C_ell, theta, corr_type='gg', method='fftlog'): """Compute the angular correlation function. Args: cosmo (:obj:`Cosmology`): A Cosmology object. ell (array_like): Multipoles corresponding to the input angular power spectrum. C_ell (array_like): Input angular power spectrum. theta (float or array_like): Angular separation(s) at which to calculate the angular correlation function (in degrees). corr_type (string): Type of correlation function. Choices: 'GG' (galaxy-galaxy), 'GL' (galaxy-shear), 'L+' (shear-shear, xi+), 'L-' (shear-shear, xi-). method (string, optional): Method to compute the correlation function. Choices: 'Bessel' (direct integration over Bessel function), 'FFTLog' (fast integration with FFTLog), 'Legendre' (brute-force sum over Legendre polynomials). Returns: float or array_like: Value(s) of the correlation function at the input angular separations. """ cosmo_in = cosmo cosmo = _cosmology_obj(cosmo) status = 0 # Convert to lower case corr_type = corr_type.lower() method = method.lower() if corr_type not in correlation_types.keys(): raise KeyError("'%s' is not a valid correlation type." % corr_type) if method.lower() not in correlation_methods.keys(): raise KeyError("'%s' is not a valid correlation method." % method) # Convert scalar input into an array scalar = False if isinstance(theta, float) or isinstance(theta, int): scalar = True theta = np.array([ theta, ]) # Call correlation function wth, status = lib.correlation_vec(cosmo, ell, C_ell, theta, correlation_types[corr_type], correlation_methods[method], len(theta), status) check(status, cosmo_in) if scalar: return wth[0] return wth
def angular_cl(cosmo, cltracer1, cltracer2, ell): """ Calculate the angular (cross-)power spectrum for a pair of tracers. Args: cosmo (:obj:`Cosmology`): A Cosmology object. cltracer1, cltracer2 (:obj:): ClTracer objects, of any kind. ell (float or array_like): Angular wavenumber(s) to evaluate the angular power spectrum at. Returns: cl (float or array_like): Angular (cross-)power spectrum values, C_ell, for the pair of tracers, as a function of `ell`. """ # Access ccl_cosmology object cosmo_in = cosmo cosmo = _cosmology_obj(cosmo) # Access CCL_ClTracer objects clt1 = _cltracer_obj(cltracer1) clt2 = _cltracer_obj(cltracer2) status = 0 # Return Cl values, according to whether ell is an array or not if isinstance(ell, float) or isinstance(ell, int) : # Use single-value function cl, status = lib.angular_cl(cosmo, ell, clt1, clt2, status) elif isinstance(ell, np.ndarray): # Use vectorised function cl, status = lib.angular_cl_vec(cosmo, clt1, clt2, ell, ell.size, status) else: # Use vectorised function cl, status = lib.angular_cl_vec(cosmo, clt1, clt2, ell, len(ell), status) check(status, cosmo_in) return cl
def __init__(self, Omega_c=None, Omega_b=None, h=None, A_s=None, n_s=None, Omega_k=0., Neff=3.046, m_nu=0., mnu_type=None, w0=-1., wa=0., bcm_log10Mc=np.log10(1.2e14), bcm_etab=0.5, bcm_ks=55., sigma8=None, z_mg=None, df_mg=None): """ Creates a set of cosmological parameters. .. note:: Although some arguments default to `None`, they will raise a ValueError inside this function if not specified, so they are not optional. Args: Omega_c (float): Cold dark matter density fraction. Omega_b (float): Baryonic matter density fraction. h (float): Hubble constant divided by 100 km/s/Mpc; unitless. A_s (float): Power spectrum normalization. Optional if sigma8 is specified. n_s (float): Primordial scalar perturbation spectral index. Omega_k (float, optional): Curvature density fraction. Defaults to 0. Neff (float, optional): Effective number of neutrino species. Defaults to 3.046 m_nu (float or array-like, optional): If float: total mass in eV of the massive neutrinos present. If array-like, masses of 3 neutrino species (must have length 3). mnu_type (string): treatment for neutrinos. Available: 'sum', 'sum_inverted', 'sum_equal', 'list'. Default if m_nu is a float is 'sum', default if m_nu is array-like with length 3 is 'list'. w0 (float, optional): First order term of dark energy equation of state. Defaults to -1. wa (float, optional): Second order term of dark energy equation of state. Defaults to 0. bcm_log10Mc (float, optional): One of the parameters of the BCM model. bcm_etab (float, optional): One of the parameters of the BCM model. bcm_ks (float, optional): One of the parameters of the BCM model. sigma8 (float): Variance of matter density perturbations at 8 Mpc/h scale. Optional if A_s is specified. df_mg (:obj: array_like): Perturbations to the GR growth rate as a function of redshift, Delta f. Used to implement simple modified growth scenarios. z_mg (:obj: array_like): Array of redshifts corresponding to df_mg. """ # Set current ccl_parameters object to None self.parameters = None # Set nz_mg (no. of redshift bins for modified growth fns.) if z_mg is not None and df_mg is not None: # Get growth array size and do sanity check z_mg = np.atleast_1d(z_mg) df_mg = np.atleast_1d(df_mg) assert z_mg.size == df_mg.size nz_mg = z_mg.size else: # If one or both of the MG growth arrays are set to zero, disable # all of them if z_mg is not None or df_mg is not None: raise ValueError("Must specify both z_mg and df_mg.") z_mg = None df_mg = None nz_mg = -1 # Check to make sure specified amplitude parameter is consistent if (A_s is None and sigma8 is None) \ or (A_s is not None and sigma8 is not None): raise ValueError("Must set either A_s or sigma8.") # Set norm_pk to either A_s or sigma8 norm_pk = A_s if A_s is not None else sigma8 # The C library decides whether A_s or sigma8 was the input parameter # based on value, so we need to make sure this is consistent too if norm_pk >= 1e-5 and A_s is not None: raise ValueError("A_s must be less than 1e-5.") if norm_pk < 1e-5 and sigma8 is not None: raise ValueError("sigma8 must be greater than 1e-5.") if isinstance(m_nu, float): if mnu_type == None: mnu_type = 'sum' m_nu = [m_nu] elif hasattr(m_nu, "__len__"): if (len(m_nu) != 3): raise ValueError("m_nu must be a float or array-like object " "with length 3.") elif ((mnu_type=='sum') \ or (mnu_type=='sum_inverted') \ or (mnu_type=='sum_equal')): raise ValueError("mnu type '%s' cannot be passed with a list " "of neutrino masses, only with a sum." \ % mnu_type) elif (mnu_type == None): mnu_type = 'list' # False else: raise ValueError("m_nu must be a float or array-like object with " "length 3.") # Check if any compulsory parameters are not set compul = [Omega_c, Omega_b, Omega_k, w0, wa, h, norm_pk, n_s] names = [ 'Omega_c', 'Omega_b', 'Omega_k', 'w0', 'wa', 'h', 'norm_pk', 'n_s' ] for nm, item in zip(names, compul): if item is None: raise ValueError("Necessary parameter '%s' was not set " "(or set to None)." % nm) # Create new instance of ccl_parameters object status = 0 # Create an internal status variable; needed to check massive neutrino integral. if (nz_mg == -1): # Create ccl_parameters without modified growth self.parameters, status \ = lib.parameters_create_nu( Omega_c, Omega_b, Omega_k, Neff, w0, wa, h, norm_pk, n_s, bcm_log10Mc, bcm_etab, bcm_ks, mnu_types[mnu_type], m_nu, status ) else: # Create ccl_parameters with modified growth arrays self.parameters, status \ = lib.parameters_create_nu_vec( Omega_c, Omega_b, Omega_k, Neff, w0, wa, h, norm_pk, n_s, bcm_log10Mc, bcm_etab, bcm_ks, z_mg, df_mg, mnu_types[mnu_type], m_nu, status ) check(status)
def __init__(self, cosmo, tracer_type=None, has_rsd=False, has_magnification=False, has_intrinsic_alignment=False, z=None, n=None, bias=None, mag_bias=None, bias_ia=None, f_red=None, z_source=1100.): """ ClTracer is a class for handling tracers that have an angular power spectrum. Note: unless otherwise stated, defaults are None. Args: cosmo (:obj:`Cosmology`): Cosmology object. tracer_type (:obj:`str`): Specifies which type of tracer is being specified. Must be one of the types specified in the `tracer_types` dict in `cls.py`. has_rsd (bool, optional): Flag for whether the tracer has a redshift-space distortion term. Defaults to False. has_magnification (bool, optional): Flag for whether the tracer has a magnification term. Defaults to False. has_intrinsic_alignment (bool, optional): Flag for whether the tracer has an intrinsic alignment term. Defaults to False. z (array_like, optional): Array of redshifts that the following functions are sampled at. This is overriden if tuples of the form (z, fn(z)) are specified for those kwargs instead (this allows the functions to be sampled differently in z). n (array_like or tuple, optional): Array of N(z) sampled at the redshifts given in the z array, or a tuple of arrays (z, N(z)). The units are arbitrary; N(z) will be normalized to unity. bias (array_like or tuple, optional): Array of galaxy bias b(z) sampled at the redshifts given in the z array, or a tuple of arrays (z, b(z)). mag_bias (array_like or tuple, optional): Array of magnification bias s(z) sampled at the redshifts given in the z array, or a tuple of arrays (z, s(z)). bias_ia (array_like or tuple, optional): Array of intrinsic alignment amplitudes b_IA(z), or a tuple of arrays (z, b_IA(z)). f_red (array_like or tuple, optional): Array of red galaxy fractions f_red(z), or a tuple of arrays (z, f_red(z)). z_source (float, optional): Redshift of source plane for CMB lensing. """ # Verify cosmo object cosmo = _cosmology_obj(cosmo) # Check tracer type if tracer_type not in tracer_types.keys(): raise KeyError("'%s' is not a valid tracer_type." % tracer_type) # Convert array arguments that are 'None' into 'NoneArr' type, and # check whether arrays were specified as tuples or with a common z array self.z_n, self.n = _check_array_params(z, n, 'n') self.z_b, self.b = _check_array_params(z, bias, 'bias') self.z_s, self.s = _check_array_params(z, mag_bias, 'mag_bias') self.z_ba, self.ba = _check_array_params(z, bias_ia, 'bias_ia') self.z_rf, self.rf = _check_array_params(z, f_red, 'f_red') self.z_source = z_source # Construct new ccl_cl_tracer status = 0 return_val = lib.cl_tracer_new_wrapper(cosmo, tracer_types[tracer_type], int(has_rsd), int(has_magnification), int(has_intrinsic_alignment), self.z_n, self.n, self.z_b, self.b, self.z_s, self.s, self.z_ba, self.ba, self.z_rf, self.rf, self.z_source, status) if (isinstance(return_val, int)): self.has_cltracer = False check(return_val) else: self.has_cltracer = True self.cltracer, status = return_val
def angular_cl(cosmo, cltracer1, cltracer2, ell, l_limber=-1., l_logstep=1.05, l_linstep=20., dchi=3., dlk=0.003, zmin=0.05, non_limber_method="native"): """ Calculate the angular (cross-)power spectrum for a pair of tracers. Args: cosmo (:obj:`Cosmology`): A Cosmology object. cltracer1, cltracer2 (:obj:): ClTracer objects, of any kind. ell (float or array_like): Angular wavenumber(s) to evaluate the angular power spectrum at. l_limber (float) : Angular wavenumber beyond which Limber's approximation will be used l_logstep (float) : logarithmic step in ell at low multipoles l_linstep (float) : linear step in ell at high multipoles dchi (float) : comoving distance step size in non-limber native integrals dlk (float) : logarithmic step for the k non-limber native integral zmin (float) : minimal redshift for the integrals non_limber_method (str) : non-Limber integration method. Supported: "native" and "angpow" Returns: cl (float or array_like): Angular (cross-)power spectrum values, C_ell, for the pair of tracers, as a function of `ell`. """ # Access ccl_cosmology object cosmo_in = cosmo cosmo = _cosmology_obj(cosmo) if non_limber_method not in nonlimber_methods.keys(): raise KeyError("'%s' is not a valid non-Limber integration method." % non_limber_method) # Access CCL_ClTracer objects clt1 = _cltracer_obj(cltracer1) clt2 = _cltracer_obj(cltracer2) status = 0 # Return Cl values, according to whether ell is an array or not if isinstance(ell, float) or isinstance(ell, int): # Use single-value function cl_one, status = lib.angular_cl_vec( cosmo, clt1, clt2, l_limber, l_logstep, l_linstep, dchi, dlk, zmin, nonlimber_methods[non_limber_method], [ell], 1, status) cl = cl_one[0] elif isinstance(ell, np.ndarray): # Use vectorised function cl, status = lib.angular_cl_vec(cosmo, clt1, clt2, l_limber, l_logstep, l_linstep, dchi, dlk, zmin, nonlimber_methods[non_limber_method], ell, ell.size, status) else: # Use vectorised function cl, status = lib.angular_cl_vec(cosmo, clt1, clt2, l_limber, l_logstep, l_linstep, dchi, dlk, zmin, nonlimber_methods[non_limber_method], ell, len(ell), status) check(status) return cl
def __init__(self, Omega_c=None, Omega_b=None, h=None, A_s=None, n_s=None, Omega_k=0., N_nu_rel=3.046, N_nu_mass=0., m_nu=0.,w0=-1., wa=0., bcm_log10Mc=math.log10(1.2e14), bcm_etab=0.5, bcm_ks=55., sigma8=None, z_mg=None, df_mg=None): """ Creates a set of cosmological parameters. Note: Although some arguments default to `None`, they will raise a ValueError inside this function if not specified, so they are not optional. Args: Omega_c (float): Cold dark matter density fraction. Omega_b (float): Baryonic matter density fraction. h (float): Hubble constant divided by 100 km/s/Mpc; unitless. A_s (float): Power spectrum normalization. Optional if sigma8 is specified. n_s (float): Primordial scalar perturbation spectral index. Omega_k (float, optional): Curvature density fraction. Defaults to 0. N_nu_rel (float, optional): Number of massless neutrinos present. Defaults to 3.046 N_nu_mass (float, optional): Number of massive neutrinos present. Defaults to 0. m_nu (float, optional): total mass in eV of the massive neutrinos present (current must be equal mass). Defaults to 0. w0 (float, optional): First order term of dark energy equation of state. Defaults to -1. wa (float, optional): Second order term of dark energy equation of state. Defaults to 0. log10Mc (float, optional): One of the parameters of the BCM model. etab (float, optional): One of the parameters of the BCM model. ks (float, optional): One of the parameters of the BCM model. sigma8 (float): Variance of matter density perturbations at 8 Mpc/h scale. Optional if A_s is specified. df_mg (:obj: array_like): Perturbations to the GR growth rate as a function of redshift, Delta f. Used to implement simple modified growth scenarios. z_mg (:obj: array_like): Array of redshifts corresponding to df_mg. """ # Set current ccl_parameters object to None self.parameters = None # Set nz_mg (no. of redshift bins for modified growth fns.) if z_mg is not None and df_mg is not None: # Get growth array size and do sanity check z_mg = np.atleast_1d(z_mg) df_mg = np.atleast_1d(df_mg) assert z_mg.size == df_mg.size nz_mg = z_mg.size else: # If one or both of the MG growth arrays are set to zero, disable # all of them if z_mg is not None or df_mg is not None: raise ValueError("Must specify both z_mg and df_mg.") z_mg = None df_mg = None nz_mg = -1 # Check to make sure specified amplitude parameter is consistent if (A_s is None and sigma8 is None) \ or (A_s is not None and sigma8 is not None): raise ValueError("Must set either A_s or sigma8.") # Set norm_pk to either A_s or sigma8 norm_pk = A_s if A_s is not None else sigma8 # The C library decides whether A_s or sigma8 was the input parameter # based on value, so we need to make sure this is consistent too if norm_pk >= 1e-5 and A_s is not None: raise ValueError("A_s must be less than 1e-5.") if norm_pk < 1e-5 and sigma8 is not None: raise ValueError("sigma8 must be greater than 1e-5.") # Check if any compulsory parameters are not set compul = [Omega_c, Omega_b, Omega_k, N_nu_rel, N_nu_mass, m_nu, w0, wa, h, norm_pk, n_s] names = ['Omega_c', 'Omega_b', 'Omega_k', 'N_nu_rel', 'N_nu_mass', 'mnu', 'w0', 'wa', 'h', 'norm_pk', 'n_s'] for nm, item in zip(names, compul): if item is None: raise ValueError("Necessary parameter '%s' was not set " "(or set to None)." % nm) # Create new instance of ccl_parameters object status = 0 # Create an internal status variable; needed to check massive neutrino integral. if nz_mg == -1: # Create ccl_parameters without modified growth self.parameters, status \ = lib.parameters_create( Omega_c, Omega_b, Omega_k, N_nu_rel, N_nu_mass, m_nu, w0, wa, h, norm_pk, n_s, bcm_log10Mc, bcm_etab, bcm_ks, -1, None, None, status ) else: # Create ccl_parameters with modified growth arrays self.parameters, status \ = lib.parameters_create_vec( Omega_c, Omega_b, Omega_k, N_nu_rel, N_nu_mass, m_nu, w0, wa, h, norm_pk, n_s, bcm_log10Mc, bcm_etab, bcm_ks, z_mg, df_mg, status ) check(status)