Source code for nbodykit.source.mesh.linear

from nbodykit.base.mesh import MeshSource
from nbodykit import CurrentMPIComm, mockmaker
from nbodykit.utils import attrs_to_dict
import numpy

[docs]class LinearMesh(MeshSource): """ A MeshSource object that generates a :class:`~pmesh.pm.RealField` density mesh from a linear power spectrum function :math:`P(k)`. Parameters ---------- Plin: callable the callable linear power spectrum function, which takes the wavenumber as its single argument BoxSize : float, 3-vector of floats the size of the box to generate the grid on Nmesh : int, 3-vector of int the number of the mesh cells per side seed : int, optional the global random seed, used to set the seeds across all ranks remove_variance : bool, optional .. deprecated:: 0.2.9 use ``unitary_amplitude`` instead unitary_amplitude: bool, optional ``True`` to remove variance from the complex field by fixing the amplitude to :math:`P(k)` and only the phase is random. inverted_phase: bool, optional ``True`` to invert phase of the complex field by fixing the amplitude to :math:`P(k)` and only the phase is random. comm : MPI communicator the MPI communicator """ def __repr__(self): return "LinearMesh(seed=%(seed)d)" % self.attrs @CurrentMPIComm.enable def __init__(self, Plin, BoxSize, Nmesh, seed=None, unitary_amplitude=False, inverted_phase=False, remove_variance=None, comm=None): self.Plin = Plin # cosmology and communicator self.comm = comm self.attrs.update(attrs_to_dict(Plin, 'plin.')) # set the seed randomly if it is None if seed is None: if self.comm.rank == 0: seed = numpy.random.randint(0, 4294967295) seed = self.comm.bcast(seed) self.attrs['seed'] = seed if remove_variance is not None: unitary_amplitude = remove_variance self.attrs['unitary_amplitude'] = unitary_amplitude self.attrs['inverted_phase'] = inverted_phase MeshSource.__init__(self, BoxSize=BoxSize, Nmesh=Nmesh, dtype='f4', comm=comm)
[docs] def to_complex_field(self): """ Return a ComplexField, generating from the linear power spectrum. .. note:: The density field is normalized to :math:`1+\delta` such that the mean of the return field in real space is unity. Returns ------- :class:`pmesh.pm.ComplexField` an array-like object holding the generated linear density field in Fourier space """ # generate linear density field with desired seed complex, _ = mockmaker.gaussian_complex_fields(self.pm, self.Plin, self.attrs['seed'], unitary_amplitude=self.attrs['unitary_amplitude'], inverted_phase=self.attrs['inverted_phase'], compute_displacement=False) # set normalization to 1 + \delta. def filter(k, v): mask = numpy.bitwise_and.reduce([ki == 0 for ki in k]) v[mask] = 1.0 return v complex.apply(filter) complex.attrs = {} complex.attrs.update(self.attrs) return complex