Esempio n. 1
0
def tabulate_3D_variances(ell, DA, growth, power):
    """
    Tabulate 3D matter-power contributions to shear power variances.

    This function is defined as:

    .. math::

        V(\ell, D_A) = \\frac{\pi}{\ell} G(D)^2
        \Delta^2_\delta(k=\ell/D_A(D), z=0)

    where :math:`D` is the comoving distance corresponding to the comoving
    transverse distance :math:`D_A` and :math:`\ell` is a 2D wavenumber.

    Use :func:`calculate_shear_power` to calculate the lensing shear power
    associated with the returned 3D matter-power contributions.

    Parameters
    ----------
    ell : numpy.ndarray
        1D array of 2D wavenumbers where shear power variances should be
        tabulated.  Values must be positive and increasing, but do not need
        to be equally spaced.
    DA : numpy.ndarray
        1D array of :meth:`comoving transverse distances
        <astropy.cosmology.FLRW.comoving_transverse_distance>` :math:`D_A(z)`
        where shear power variances should be tabulated. Values must be
        positive and increasing, but do not need to be equally spaced. Values
        can be in either Mpc/h or Mpc, but must be consistent with the power
        spectrum normalization.
    growth : numpy.ndarray
        1D array of growth function values :math:`G(z)` corresponding to each
        input :math:`DA(z)` value.  Must have the same number of elements as
        DA.  Can be calculated using
        :func:`randomfield.cosmotools.get_growth_function`.
    power : structured numpy.ndarray
        Power spectrum to use, which meets the criteria tested by
        :func:`randomfield.powertools.validate_power`.  Can be calculated using
        :func:`randomfield.cosmotools.calculate_power` if the optional
        ``classy`` package is installed.  Values of k and P(k) can either be
        in Mpc/h or Mpc units, but must be consistent with the values of DA.

    Returns
    -------
    numpy.ndarray
        Two dimensional array with shape (nell, nDA) where nell = len(ell) and
        nDA = len(DA).  The value ``out[i,j]`` gives the contribution to the
        shear variance :math:`\Delta^2_{EE}` at 2D wavenumber ``ell[i]`` from
        lensing by mass inhomogeneities at comoving transverse distance
        ``DA[j]``.  The output is dimensionless.
    """
    try:
        assert len(ell.shape) == 1
    except (AssertionError, AttributeError):
        raise ValueError('Wavenumbers ell must be a 1D array.')
    if not np.array_equal(np.unique(ell), ell) or ell[0] <= 0:
        raise ValueError('Wavenumbers ell must be increasing values > 0.')

    try:
        assert len(DA.shape) == 1
    except (AssertionError, AttributeError):
        raise ValueError('Distances DA must be a 1D array.')
    if not np.array_equal(np.unique(DA), DA) or DA[0] <= 0:
        raise ValueError('Distances DA must be increasing values > 0.')

    try:
        assert DA.shape == growth.shape
    except (AssertionError, AttributeError):
        raise ValueError('Growth array must match DA array dimensions.')

    # Build an interpolator for the dimensionless function
    # Delta**2(k) = k**3/(2*pi**2) * P(k) that is linear in log10(k).
    power = powertools.validate_power(power)
    k_grid = power['k']
    Delta2_grid = k_grid**3 / (2 * np.pi**2) * power['Pk']
    Delta2 = scipy.interpolate.interp1d(np.log10(k_grid), Delta2_grid,
                                        kind='linear', copy=False)
    # Tabulate a 2D array of k values for each (ell, DA).
    log10k_of_DA = np.log10(ell[:, np.newaxis] / DA)
    # Tabulate pi/ell * Delta**2(k) * G(DA)**2 values on this grid.
    return (np.pi / ell[:, np.newaxis]) * Delta2(log10k_of_DA) * growth**2
Esempio n. 2
0
    def __init__(self,
                 nx,
                 ny,
                 nz,
                 grid_spacing_Mpc_h,
                 num_plot_sections=4,
                 cosmology=None,
                 power=None,
                 verbose=False):
        self.plan_c2r = transform.Plan(shape=(nx, ny, nz),
                                       dtype_in=np.complex64,
                                       packed=True,
                                       overwrite=True,
                                       inverse=True,
                                       use_pyfftw=True)
        self.plan_r2c = self.plan_c2r.create_reverse_plan(reuse_output=True,
                                                          overwrite=True)
        self.grid_spacing_Mpc_h = grid_spacing_Mpc_h
        self.k_min, self.k_max = powertools.get_k_bounds(self.plan_c2r.data_in,
                                                         grid_spacing_Mpc_h,
                                                         packed=True)
        self.potential = None

        if nz % num_plot_sections != 0:
            raise ValueError(
                'Z-axis does not evenly divided into {0} plot sections.'.
                format(num_plot_sections))
        self.num_plot_sections = num_plot_sections

        if cosmology is None:
            self.cosmology = cosmotools.create_cosmology()
            if power is None:
                power = powertools.load_default_power()
        else:
            self.cosmology = cosmology
            if power is None:
                power = cosmotools.calculate_power(self.cosmology,
                                                   k_min=self.k_min,
                                                   k_max=self.k_max,
                                                   scaled_by_h=True)
        self.power = powertools.validate_power(power)

        self.redshifts = cosmotools.get_redshifts(
            self.cosmology,
            self.plan_c2r.data_out,
            spacing=self.grid_spacing_Mpc_h,
            scaled_by_h=True,
            z_axis=2).reshape(nz)
        self.redshift_to_index = scipy.interpolate.interp1d(self.redshifts,
                                                            np.arange(nz),
                                                            kind='linear',
                                                            bounds_error=False)

        # Tabulate the comoving distance DC and transverse separation DA along
        # the line of sight in units of Mpc/h.
        self.DC = np.arange(nz) * self.grid_spacing_Mpc_h
        self.DA = (self.cosmology.comoving_transverse_distance(
            self.redshifts).to(u.Mpc).value) * self.cosmology.h

        # Calculate angular spacing in transverse (x,y) grid units per degree,
        # indexed by position along the z-axis.
        self.angular_spacing = (self.DA * (np.pi / 180.) /
                                self.grid_spacing_Mpc_h)
        self.z_max = self.redshifts.flat[-1]
        # Use the plane-parallel approximation here.
        self.x_fov = nx / self.angular_spacing.flat[-1]
        self.y_fov = ny / self.angular_spacing.flat[-1]

        self.growth_function = cosmotools.get_growth_function(
            self.cosmology, self.redshifts)
        self.mean_matter_density = cosmotools.get_mean_matter_densities(
            self.cosmology, self.redshifts)

        self.verbose = verbose
        if self.verbose:
            Mb = (self.plan_c2r.nbytes_allocated +
                  self.plan_r2c.nbytes_allocated) / 2.0**20
            print('Allocated {0:.1f} Mb for {1} x {2} x {3} grid.'.format(
                Mb, nx, ny, nz))
            print('{0} Mpc/h spacing covered by k = {1:.5f} - {2:.5f} h/Mpc.'.
                  format(self.grid_spacing_Mpc_h, self.k_min, self.k_max))
            print(
                'Grid has z < {0:.3f} with {1:.4f} deg x {2:.4f} deg'.format(
                    self.z_max, self.x_fov, self.y_fov),
                ' = {0:.4f} deg**2 field of view.'.format(self.x_fov *
                                                          self.y_fov))
Esempio n. 3
0
def tabulate_3D_variances(ell, DA, growth, power):
    """
    Tabulate 3D matter-power contributions to shear power variances.

    This function is defined as:

    .. math::

        V(\ell, D_A) = \\frac{\pi}{\ell} G(D)^2
        \Delta^2_\delta(k=\ell/D_A(D), z=0)

    where :math:`D` is the comoving distance corresponding to the comoving
    transverse distance :math:`D_A` and :math:`\ell` is a 2D wavenumber.

    Use :func:`calculate_shear_power` to calculate the lensing shear power
    associated with the returned 3D matter-power contributions.

    Parameters
    ----------
    ell : numpy.ndarray
        1D array of 2D wavenumbers where shear power variances should be
        tabulated.  Values must be positive and increasing, but do not need
        to be equally spaced.
    DA : numpy.ndarray
        1D array of :meth:`comoving transverse distances
        <astropy.cosmology.FLRW.comoving_transverse_distance>` :math:`D_A(z)`
        where shear power variances should be tabulated. Values must be
        positive and increasing, but do not need to be equally spaced. Values
        can be in either Mpc/h or Mpc, but must be consistent with the power
        spectrum normalization.
    growth : numpy.ndarray
        1D array of growth function values :math:`G(z)` corresponding to each
        input :math:`DA(z)` value.  Must have the same number of elements as
        DA.  Can be calculated using
        :func:`randomfield.cosmotools.get_growth_function`.
    power : structured numpy.ndarray
        Power spectrum to use, which meets the criteria tested by
        :func:`randomfield.powertools.validate_power`.  Can be calculated using
        :func:`randomfield.cosmotools.calculate_power` if the optional
        ``classy`` package is installed.  Values of k and P(k) can either be
        in Mpc/h or Mpc units, but must be consistent with the values of DA.

    Returns
    -------
    numpy.ndarray
        Two dimensional array with shape (nell, nDA) where nell = len(ell) and
        nDA = len(DA).  The value ``out[i,j]`` gives the contribution to the
        shear variance :math:`\Delta^2_{EE}` at 2D wavenumber ``ell[i]`` from
        lensing by mass inhomogeneities at comoving transverse distance
        ``DA[j]``.  The output is dimensionless.
    """
    try:
        assert len(ell.shape) == 1
    except (AssertionError, AttributeError):
        raise ValueError('Wavenumbers ell must be a 1D array.')
    if not np.array_equal(np.unique(ell), ell) or ell[0] <= 0:
        raise ValueError('Wavenumbers ell must be increasing values > 0.')

    try:
        assert len(DA.shape) == 1
    except (AssertionError, AttributeError):
        raise ValueError('Distances DA must be a 1D array.')
    if not np.array_equal(np.unique(DA), DA) or DA[0] <= 0:
        raise ValueError('Distances DA must be increasing values > 0.')

    try:
        assert DA.shape == growth.shape
    except (AssertionError, AttributeError):
        raise ValueError('Growth array must match DA array dimensions.')

    # Build an interpolator for the dimensionless function
    # Delta**2(k) = k**3/(2*pi**2) * P(k) that is linear in log10(k).
    power = powertools.validate_power(power)
    k_grid = power['k']
    Delta2_grid = k_grid**3 / (2 * np.pi**2) * power['Pk']
    Delta2 = scipy.interpolate.interp1d(np.log10(k_grid),
                                        Delta2_grid,
                                        kind='linear',
                                        copy=False)
    # Tabulate a 2D array of k values for each (ell, DA).
    log10k_of_DA = np.log10(ell[:, np.newaxis] / DA)
    # Tabulate pi/ell * Delta**2(k) * G(DA)**2 values on this grid.
    return (np.pi / ell[:, np.newaxis]) * Delta2(log10k_of_DA) * growth**2
Esempio n. 4
0
    def __init__(self, nx, ny, nz, grid_spacing_Mpc_h, num_plot_sections=4,
                 cosmology=None, power=None, verbose=False):
        self.plan_c2r = transform.Plan(
            shape=(nx, ny, nz), dtype_in=np.complex64,
            packed=True, overwrite=True, inverse=True, use_pyfftw=True)
        self.plan_r2c = self.plan_c2r.create_reverse_plan(
            reuse_output=True, overwrite=True)
        self.grid_spacing_Mpc_h = grid_spacing_Mpc_h
        self.k_min, self.k_max = powertools.get_k_bounds(
            self.plan_c2r.data_in, grid_spacing_Mpc_h, packed=True)
        self.potential = None

        if nz % num_plot_sections != 0:
            raise ValueError(
                'Z-axis does not evenly divided into {0} plot sections.'
                .format(num_plot_sections))
        self.num_plot_sections = num_plot_sections

        if cosmology is None:
            self.cosmology = cosmotools.create_cosmology()
            if power is None:
                power = powertools.load_default_power()
        else:
            self.cosmology = cosmology
            if power is None:
                power = cosmotools.calculate_power(
                    self.cosmology, k_min=self.k_min, k_max=self.k_max,
                    scaled_by_h=True)
        self.power = powertools.validate_power(power)

        self.redshifts = cosmotools.get_redshifts(
            self.cosmology, self.plan_c2r.data_out,
            spacing=self.grid_spacing_Mpc_h, scaled_by_h=True,
            z_axis=2).reshape(nz)
        self.redshift_to_index = scipy.interpolate.interp1d(
            self.redshifts, np.arange(nz), kind='linear', bounds_error=False)

        # Tabulate the comoving distance DC and transverse separation DA along
        # the line of sight in units of Mpc/h.
        self.DC = np.arange(nz) * self.grid_spacing_Mpc_h
        self.DA = (self.cosmology.comoving_transverse_distance(self.redshifts)
            .to(u.Mpc).value) * self.cosmology.h

        # Calculate angular spacing in transverse (x,y) grid units per degree,
        # indexed by position along the z-axis.
        self.angular_spacing = (
            self.DA * (np.pi / 180.) / self.grid_spacing_Mpc_h)
        self.z_max = self.redshifts.flat[-1]
        # Use the plane-parallel approximation here.
        self.x_fov = nx / self.angular_spacing.flat[-1]
        self.y_fov = ny / self.angular_spacing.flat[-1]

        self.growth_function = cosmotools.get_growth_function(
            self.cosmology, self.redshifts)
        self.mean_matter_density = cosmotools.get_mean_matter_densities(
            self.cosmology, self.redshifts)

        self.verbose = verbose
        if self.verbose:
            Mb = (self.plan_c2r.nbytes_allocated +
                  self.plan_r2c.nbytes_allocated) / 2.0**20
            print('Allocated {0:.1f} Mb for {1} x {2} x {3} grid.'
                  .format(Mb, nx, ny, nz))
            print('{0} Mpc/h spacing covered by k = {1:.5f} - {2:.5f} h/Mpc.'
                  .format(self.grid_spacing_Mpc_h, self.k_min, self.k_max))
            print('Grid has z < {0:.3f} with {1:.4f} deg x {2:.4f} deg'
                  .format(self.z_max, self.x_fov, self.y_fov),
                  ' = {0:.4f} deg**2 field of view.'
                  .format(self.x_fov * self.y_fov))