Maps and spectra

kszx.multiply_rfunc(box, arr, f, dest=None, in_place=False, regulate=False, eps=1e-06)

Multiply real-space map ‘arr’ by a function f(r), where r is scalar radial coordinate.

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • arr: numpy array representing a real-space map. (The array shape should be given by box.real_space_shape and the dtype should be float.)

  • f (function): The function r -> f(r).

  • dest (array or None): real-space map where output will be written (if None, then new array will be allocated).

  • in_place (boolean): Setting this to True is equivalent to dest=arr.

  • regulate (boolean): This optional argument is intended to regulate cases where \(\lim_{r\rightarrow 0} f(r) = \infty\). If regulate=True, then we replace r by max(r, eps*pixsize) before calling f().

  • eps (float): only used if regulate=True. See description in previous bullet point.

Return value:

  • A real-space map. (Numpy array with same shape and dtype as arr.)

Note

  • The function f() must be vectorized: its argument ‘r’ will be a 3-dimensional arary, and the return value should be an array with the same shape.

  • r-values passed to f() will be in “observer” coordinates.

    (Reminder: in observer coordinates, the observer is at the origin, coordinates have units of distance, and the corners of the box are at box.{lpos,rpos}. See Box for more info.)

kszx.multiply_kfunc(box, arr, f, dest=None, in_place=False, dc=None)

Multiply Fourier-space map ‘arr’ by a real-valued function f(k), where k=|k| is scalar wavenumber.

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • arr: numpy array representing a Fourier-space map. (The array shape should be given by box.fourier_space_shape and the dtype should be complex, see note below.)

  • f (function): The function k -> f(k).

  • dest: Fourier-space map where output will be written (if None, then new array will be allocated)

  • in_place: Setting this to True is equivalent to dest=arr.

  • dc (float): This optional argument is intended to regulate cases where \(\lim_{k\rightarrow 0} f(k) = \infty\). If dc is specified, then f() is not evaluated at k=0, and the value of dc is used instead of f(0).

Return value:

  • A Fourier-space map. (Numpy array with same shape and dtype as arr.)

Notes

  • The function f() must be vectorized: its argument ‘k’ will be a 3-dimensional arary, and the return value should be a real-valued array with the same shape.

  • k-values passed to f() will be in “physical” units, i.e. the factor (2*pi / box.boxsize) is included.

  • The arr argument and the returned array are Fourier-space maps.

    Reminder: real-space and Fourier-space array shapes are given by box.real_space_shape and box.fourier_space_shape, and are related as follows:

    \[\begin{split}\begin{align} (\mbox{real-space shape}) &= (n_0, n_1, \cdots, n_{d-1}) \\ (\mbox{Fourier-space shape}) &= (n_0, n_1, \cdots, \lfloor n_{d-1}/2 \rfloor + 1) \end{align}\end{split}\]

kszx.multiply_r_component(box, arr, axis, dest=None, in_place=True)

Multiply real-space map ‘arr’ by \(r_j\) (the j-th Cartesian coordinate).

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • arr: numpy array representing a real-space map. (The array shape should be given by box.real_space_shape and the dtype should be float.)

  • axis (integer): axis j (satisfying 0 <= j < box.ndim) along which \(r_j\) is computed.

  • dest (array or None): real-space map where output will be written (if None, then new array will be allocated).

  • in_place (boolean): Setting this to True is equivalent to dest=arr.

Return value:

  • A real-space map. (Numpy array with same shape and dtype as arr.)

Note

  • Values of \(r_j\) will be signed, and in “observer” coordinates.

    (Reminder: in observer coordinates, the observer is at the origin, coordinates have units of distance, and the corners of the box are at box.{lpos,rpos}. See Box for more info.)

kszx.apply_partial_derivative(box, arr, axis, dest=None, in_place=True)

Multiply Fourier-space map ‘arr’ by \((i k_j)\). (This is the partial derivative \(\partial_j\) in Fourier space.)

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • arr: numpy array representing a Fourier-space map. (The array shape should be given by box.fourier_space_shape and the dtype should be complex, see note below.)

  • axis (integer): axis j (satisfying 0 <= j < box.ndim) along which \((i k_j)\) is computed.

  • dest (array or None): Fourier-space map where output will be written (if None, then new array will be allocated).

  • in_place (boolean): Setting this to True is equivalent to dest=arr.

Return value:

  • A Fourier-space map. (Numpy array with same shape and dtype as arr.)

Notes

  • k-values passed to f() will be in “physical” units, i.e. the factor (2*pi / box.boxsize) is included.

  • Values of \(k_j\) will be signed, and include the factor (2pi / boxsize).

  • The value of k_j will be taken to be zero at the Nyquist frequency. (I think this is the only sensible choice, since the sign is ambiguous.)

  • The arr argument and the returned array are Fourier-space maps.

    Reminder: real-space and Fourier-space array shapes are given by box.real_space_shape and box.fourier_space_shape, and are related as follows:

    \[\begin{split}\begin{align} (\mbox{real-space shape}) &= (n_0, n_1, \cdots, n_{d-1}) \\ (\mbox{Fourier-space shape}) &= (n_0, n_1, \cdots, \lfloor n_{d-1}/2 \rfloor + 1) \end{align}\end{split}\]

kszx.zero_nyquist_modes(box, arr, zero_dc=False)

Given Fourier-space map ‘arr’, zero Nyquist frequencies (if npix is even) along all axes.

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • arr: numpy array representing a Fourier-space map. (The array shape should be given by box.fourier_space_shape and the dtype should be complex, see note below.)

  • zero_dc: if True, then the DC mode (k=0) is also zeroed.

kszx.simulate_white_noise(box, *, fourier)

Simulate white noise, in either real space or Fourier space, normalized to \(P(k)=1\).

Intended as a helper for simulate_gaussian_field(), but may be useful on its own.

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • fourier (boolean): determines whether output is real-space or Fourier-space.

Return value:

  • A numpy array representing a real-space (fourier=False) or Fourier-space (fourier=True) map.

    The real-space and Fourier-space array shapes are given by box.real_space_shape and box.fourier_space_shape, and are related as follows:

    \[\begin{split}\begin{align} (\mbox{real-space shape}) &= (n_0, n_1, \cdots, n_{d-1}) \\ (\mbox{Fourier-space shape}) &= (n_0, n_1, \cdots, \lfloor n_{d-1}/2 \rfloor + 1) \end{align}\end{split}\]

Note: our normalization conventions for the simulated field are (in Fourier and real space):

\[\langle f(k) f(k')^* \rangle = V_{\rm box} \delta_{kk'}\]
\[\langle f(x) f(x') \rangle = V_{\rm pix}^{-1} \delta_{xx'}\]

kszx.simulate_gaussian_field(box, pk, pk0=None)

Simulates a Gaussian field (in Fourier space) with specified power spectrum P(k).

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • pk (function or scalar): The power spectrum, represented as a function \(k \rightarrow P(k)\). If the power spectrum is constant in \(k\), then a scalar can be used instead of a function.

  • pk0 (scalar or None): This optional argument is intended to regulate cases where \(\lim_{k\rightarrow 0} P(k) = \infty\). If pk0 is specified, then pk() is not evaluated at k=0, and the value of pk0 is used instead of Pk(0).

Return value:

  • A numpy array representing a Fourier-space map. (Array shape is given by box.fourier_space_shape, and dtype is complex, see note below.)

Notes

  • The normalization of the simulated field is:

    \[\langle f(k) f(k')^* \rangle = V_{\rm box} P(k) \delta_{kk'}\]

  • The function pk() must be vectorized: its argument ‘k’ will be a 3-dimensional arary, and the return value should be a real-valued array with the same shape.

  • k-values passed to pk() will be in “physical” units, i.e. the factor (2*pi / box.boxsize) is included.

  • The returned array is a Fourier-space map.

    Reminder: real-space and Fourier-space array shapes are given by box.real_space_shape and box.fourier_space_shape, and are related as follows:

    \[\begin{split}\begin{align} (\mbox{real-space shape}) &= (n_0, n_1, \cdots, n_{d-1}) \\ (\mbox{Fourier-space shape}) &= (n_0, n_1, \cdots, \lfloor n_{d-1}/2 \rfloor + 1) \end{align}\end{split}\]

kszx.estimate_power_spectrum(box, map_or_maps, kbin_edges, *, use_dc=False, allow_empty_bins=False, return_counts=False)

Computes power spectrum \(P(k)\) for one or more maps (including cross-spectra). The window function is not deconvolved.

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • map_or_maps (array or list of arrays): single or multiple Fourier-space maps.

    • If map_or_maps is an array, then it represents a single Fourier-space map. (The array shape should be given by box.fourier_space_shape and the dtype should be complex, see note below.)

    • If map_or_maps is a list of arrays, then it represents multiple Fourier-space maps. (Each map in the list should have shape box.fourier_space_shape and dtype complex, see note below.)

  • kbin_edges (1-d array): 1-d array of length (nkbins+1) defining bin endpoints. The i-th bin covers k-range kbin_edges[i] <= i < kbin_edges[i+1].

  • use_dc (boolean): if False (the default), then the k=0 mode will not be used, even if the lowest bin includes k=0.

  • allow_empty_bins (boolean): if False (the default), then an execption is thrown if a k-bin is empty.

  • return_counts (boolean): See below.

Return value:

  • An array pk is returned, with two cases as follows:

    • If the map_or_maps argument is a single Fourier-space map (see above), then pk is a 1-d array with length nkbins, containing binned power spectrum estimates.

    • If the map_or_maps argument is a list of Fourier-space maps (see above), then pk is a 3-d array with shape (nmaps, nmaps, nkbins), containing all auto- and cross-power spectrum estimates.

  • If return_counts=False (the default), then the return value is simply the pk array.

    If return_counts=True, then the return value is a pair (pk, bin_counts), where bin_counts is a 1-d array with length nkbins, containing the number of Fourier modes in each k-bin.

Notes

  • Normalization: to estimate the power spectrum, we square each Fourier mode and divide by the box volume. This is consistent with our normalization for Fourier-space maps (see e.g. the simulate_gaussian_field() docstring), which is:

    \[\langle f(k) f(k')^* \rangle = V_{\rm box} P(k) \delta_{kk'}\]

  • The normalization of the estimated power spectrum P(k) assumes that the maps fill the entire box volume. If this is not the case (i.e. there is a survey window) then you’ll need to renormalize P(k) or deconvolve the window function.

  • The input arrays are Fourier-space maps.

    Reminder: real-space and Fourier-space array shapes are given by box.real_space_shape and box.fourier_space_shape, and are related as follows:

    \[\begin{split}\begin{align} (\mbox{real-space shape}) &= (n_0, n_1, \cdots, n_{d-1}) \\ (\mbox{Fourier-space shape}) &= (n_0, n_1, \cdots, \lfloor n_{d-1}/2 \rfloor + 1) \end{align}\end{split}\]

  • Before calling estimate_power_spectrum(), you may want to call apply_kernel_compensation() to mitigate high-\(k\) biases. See apply_kernel_compensation() docstring for more info.

kszx.kbin_average(box, f, kbin_edges, *, use_dc=False, allow_empty_bins=False, return_counts=False)

Averages a real-valued array/function f(k) in k-bins.

Function args:

  • box (kszx.Box): defines pixel size, bounding box size, and location of observer. See Box for more info.

  • f (function or array): the quantity f(k) to be averaged, represented either as a real-valued array of shape box.fourier_space_shape, or a function k -> f(k).

  • kbin_edges: 1-d array of length (nkbins+1) defining bin endpoints. The i-th bin covers k-range kbin_edges[i] <= k < kbin_edges[i+1].

  • use_dc (boolean): if False (the default), then the k=0 mode will not be used, even if the lowest bin includes k=0.

  • allow_empty_bins (boolean): if False (the default), then an execption is thrown if a k-bin is empty.

  • return_counts (boolean): See below.

Return value:

  • If return_counts=False (the default), then return value is a 1-d array fk_mean with length nkbins, containing bin-averaged values of f(k).

    If return_counts=True, then the return value is a pair (fk_mean, bin_counts), where bin_counts is a 1-d array with length nkbins, containing the number of Fourier modes in each k-bin.

Notes

  • This function is intended to be used in situations where we want to compare the output of estimate_power_spectrum() to a “theory” power spectrum, such as Cosmology.plin_z0(). To remove binning artifacts, you may want to bin-average the theory power spectrum over the same k-bins used in estimate_power_spectrum().

  • The function f() must be vectorized: its argument ‘k’ will be a 3-dimensional arary, and the return value should be a real-valued array with the same shape.

  • k-values passed to f() will include the factor (2pi / boxsize).

  • The output of kbin_average() does not include any normalization factors (such as the box or pixel size). It is just a straightforward average of f() values over each k-bin.