Source code for nbodykit.source.mesh.bigfile

from __future__ import absolute_import
# the future import is important. or in python 2.7 we try to
# import this module itself. Due to the unfortnate name conflict!

from nbodykit.base.mesh import MeshSource
from nbodykit import CurrentMPIComm
from nbodykit.utils import JSONDecoder
from bigfile import FileMPI
from pmesh.pm import ParticleMesh, ComplexField, RealField

import numpy
import json
from six import string_types

[docs]class BigFileMesh(MeshSource): """ A MeshSource object that reads a mesh from disk using :mod:`bigfile`. This can read meshes that have been stored with the :func:`~nbodykit.base.mesh.MeshSource.save` function of MeshSource objects. Parameters ---------- path : str the name of the file to load dataset : str the name of the dataset in the Bigfile holding the grid comm : MPI.Communicator the MPI communicator **kwargs : extra meta-data to be stored in the :attr:`attrs` dict """ def __repr__(self): import os return "BigFileMesh(file=%s)" % os.path.basename(self.path) @CurrentMPIComm.enable def __init__(self, path, dataset, comm=None, **kwargs): self.path = path self.dataset = dataset self.comm = comm # update the meta-data self.attrs.update(kwargs) with FileMPI(comm=self.comm, filename=path)[dataset] as ff: for key in ff.attrs: v = ff.attrs[key] if isinstance(v, string_types) and v.startswith('json://'): self.attrs[key] = json.loads(v[7:], cls=JSONDecoder) else: self.attrs[key] = numpy.squeeze(v) # fourier space or config space if ff.dtype.kind == 'c': self.isfourier = True if ff.dtype.itemsize == 16: dtype = 'f8' else: dtype = 'f4' else: self.isfourier = False if ff.dtype.itemsize == 8: dtype = 'f8' else: dtype = 'f4' # determine Nmesh if 'ndarray.shape' not in self.attrs: raise ValueError("`ndarray.shape` should be stored in the Bigfile `attrs` to determine `Nmesh`") if 'Nmesh' not in self.attrs: raise ValueError("`ndarray.shape` should be stored in the Bigfile `attrs` to determine `Nmesh`") Nmesh = self.attrs['Nmesh'] BoxSize = self.attrs['BoxSize'] MeshSource.__init__(self, BoxSize=BoxSize, Nmesh=Nmesh, dtype=dtype, comm=comm)
[docs] def to_real_field(self): """ Return the RealField stored on disk. .. note:: The mesh stored on disk must be stored with ``mode=real`` Returns ------- real : pmesh.pm.RealField an array-like object holding the mesh loaded from disk in configuration space """ if self.isfourier: return NotImplemented # the real field to paint to pmread = self.pm with FileMPI(comm=self.comm, filename=self.path)[self.dataset] as ds: if self.comm.rank == 0: self.logger.info("reading real field from %s" % self.path) real2 = RealField(pmread) start = numpy.sum(self.comm.allgather(real2.size)[:self.comm.rank], dtype='intp') end = start + real2.size real2.unravel(ds[start:end]) return real2
[docs] def to_complex_field(self): """ Return the ComplexField stored on disk. .. note:: The mesh stored on disk must be stored with ``mode=complex`` Returns ------- real : pmesh.pm.ComplexField an array-like object holding the mesh loaded from disk in Fourier space """ if not self.isfourier: return NotImplemented pmread = self.pm if self.comm.rank == 0: self.logger.info("reading complex field from %s" % self.path) with FileMPI(comm=self.comm, filename=self.path)[self.dataset] as ds: complex2 = ComplexField(pmread) assert self.comm.allreduce(complex2.size) == ds.size start = numpy.sum(self.comm.allgather(complex2.size)[:self.comm.rank], dtype='intp') end = start + complex2.size complex2.unravel(ds[start:end]) return complex2