def get_cartesian(comm, pos, cosmo=None): """ Utility function to convert sky coordinates to Cartesian coordinates and return the implied box size from the position bounds. If ``cosmo`` is not provided, return coordinates on the unit sphere. """ from nbodykit.utils import get_data_bounds # get RA,DEC in degrees ra, dec = numpy.deg2rad(pos[:, 0]), numpy.deg2rad(pos[:, 1]) # cartesian position x = numpy.cos(dec) * numpy.cos(ra) y = numpy.cos(dec) * numpy.sin(ra) z = numpy.sin(dec) cpos = numpy.vstack([x, y, z]).T # multiply by comoving distance? if cosmo is not None: assert pos.shape[-1] == 3 rdist = cosmo.comoving_distance(pos[:, 2]) # in Mpc/h cpos = rdist[:, None] * cpos else: rdist = None # min/max of position cpos_min, cpos_max = get_data_bounds(cpos, comm) boxsize = numpy.ceil(abs(cpos_max - cpos_min)) return cpos, boxsize, rdist
def get_cartesian(comm, pos, cosmo=None): """ Utility function to convert sky coordinates to Cartesian coordinates and return the implied box size from the position bounds. If ``cosmo`` is not provided, return coordinates on the unit sphere. """ from nbodykit.utils import get_data_bounds # get RA,DEC in degrees ra, dec = numpy.deg2rad(pos[:,0]), numpy.deg2rad(pos[:,1]) # cartesian position x = numpy.cos( dec ) * numpy.cos( ra ) y = numpy.cos( dec ) * numpy.sin( ra ) z = numpy.sin( dec ) cpos = numpy.vstack([x,y,z]).T # multiply by comoving distance? if cosmo is not None: assert pos.shape[-1] == 3 rdist = cosmo.comoving_distance(pos[:,2]) # in Mpc/h cpos = rdist[:,None] * cpos else: rdist = None # min/max of position cpos_min, cpos_max = get_data_bounds(cpos, comm) boxsize = abs(cpos_max - cpos_min) # some padding to avoid weird effects with domain decomposition # like sitting on an edge and goes out of bound due to round off errors. return cpos, cpos_min - 1e-3 * boxsize, cpos_max + 1e-3 * boxsize, rdist
def get_cartesian(comm, pos, cosmo=None): """ Utility function to convert sky coordinates to Cartesian coordinates and return the implied box size from the position bounds. If ``cosmo`` is not provided, return coordinates on the unit sphere. """ from nbodykit.utils import get_data_bounds # get RA,DEC in degrees ra, dec = numpy.deg2rad(pos[:,0]), numpy.deg2rad(pos[:,1]) # cartesian position x = numpy.cos( dec ) * numpy.cos( ra ) y = numpy.cos( dec ) * numpy.sin( ra ) z = numpy.sin( dec ) cpos = numpy.vstack([x,y,z]).T # multiply by comoving distance? if cosmo is not None: assert pos.shape[-1] == 3 rdist = cosmo.comoving_distance(pos[:,2]) # in Mpc/h cpos = rdist[:,None] * cpos else: rdist = None # min/max of position cpos_min, cpos_max = get_data_bounds(cpos, comm) boxsize = abs(cpos_max - cpos_min) # some padding to avoid weird effects with domain decomposition # like sitting on an edge and goes out of bound due to round off errors. return cpos, cpos_min - 1e-3 * boxsize, cpos_max + 1e-3 * boxsize, rdist
def _define_bbox(self, position, selection, species): """ Internal function to put the :attr:`randoms` CatalogSource in a Cartesian bounding box, using the positions of the given species. This function computings the size and center of the bounding box. #. `BoxSize` : array_like, (3,) if not provided, the BoxSize in each direction is computed from the maximum extent of the Cartesian coordinates of the :attr:`randoms` Source, with an optional, additional padding #. `BoxCenter`: array_like, (3,) the mean coordinate value in each direction; this is used to re-center the Cartesian coordinates of the :attr:`data` and :attr:`randoms` to the range of ``[-BoxSize/2, BoxSize/2]`` """ from nbodykit.utils import get_data_bounds # compute the min/max of the position data pos, sel = self[species].read([position, selection]) pos_min, pos_max = get_data_bounds(pos, self.comm, selection=sel) if self.comm.rank == 0: self.logger.info("cartesian coordinate range: %s : %s" % (str(pos_min), str(pos_max))) if numpy.isinf(pos_min).any() or numpy.isinf(pos_max).any(): raise ValueError( "Range of positions from `%s` is infinite;" "try to use the other species with (bbox_from_species='data'." % species) # used to center the data in the first cartesian quadrant delta = abs(pos_max - pos_min) BoxCenter = 0.5 * (pos_min + pos_max) # BoxSize is padded diff of min/max coordinates if self.attrs['BoxSize'] is None: delta *= 1.0 + self.attrs['BoxPad'] BoxSize = numpy.ceil(delta) # round up to nearest integer else: BoxSize = self.attrs['BoxSize'] return BoxSize, BoxCenter
def shift_to_box_center(pos, BoxSize, comm): """ Find the bounds of the input position array, and if needed, shift the position to an observer at the box center. Position should be bounded by [0, BoxSize] or [-BoxSize/2, BoxSize/2]; if not, an exception will be raised. Parameters ---------- pos : dask array the dask array holding the Position BoxSize : array_like the size of the box comm : the MPI communicator Returns ------- pos : dask array the position array, shifted such that observer is in the box center """ from nbodykit.utils import get_data_bounds # make BoxSize is a 3-vector _BoxSize = numpy.empty(3) _BoxSize[:] = BoxSize # get min/max of position (3-vectors) pos_min, pos_max = get_data_bounds(pos, comm) # Position is [0, BoxSize] --> shift to center of box if (pos_min > 0.).all() and (pos_max < _BoxSize).all(): pos -= 0.5 * _BoxSize elif (pos_min > -0.5 * _BoxSize).all() and (pos_max < 0.5 * _BoxSize).all(): pass else: raise ValueError( "input Position should be bounded by [0,BoxSize] or [-BoxSize/2,BoxSize/2]" ) return pos
def _define_bbox(self, position, selection, species): """ Internal function to put the :attr:`randoms` CatalogSource in a Cartesian bounding box, using the positions of the given species. This function computings the size and center of the bounding box. #. `BoxSize` : array_like, (3,) if not provided, the BoxSize in each direction is computed from the maximum extent of the Cartesian coordinates of the :attr:`randoms` Source, with an optional, additional padding #. `BoxCenter`: array_like, (3,) the mean coordinate value in each direction; this is used to re-center the Cartesian coordinates of the :attr:`data` and :attr:`randoms` to the range of ``[-BoxSize/2, BoxSize/2]`` """ from nbodykit.utils import get_data_bounds # compute the min/max of the position data pos, sel = self[species].read([position, selection]) pos_min, pos_max = get_data_bounds(pos, self.comm, selection=sel) if self.comm.rank == 0: self.logger.info("cartesian coordinate range: %s : %s" %(str(pos_min), str(pos_max))) if numpy.isinf(pos_min).any() or numpy.isinf(pos_max).any(): raise ValueError("Range of positions from `%s` is infinite;" "try to use the other species with (bbox_from_species='data'." % species) # used to center the data in the first cartesian quadrant delta = abs(pos_max - pos_min) BoxCenter = 0.5 * (pos_min + pos_max) # BoxSize is padded diff of min/max coordinates if self.attrs['BoxSize'] is None: delta *= 1.0 + self.attrs['BoxPad'] BoxSize = numpy.ceil(delta) # round up to nearest integer else: BoxSize = self.attrs['BoxSize'] return BoxSize, BoxCenter
def define_cartesian_box(catalogue, position='Position', selection='Selection', BoxCenter=None, BoxSize=None, BoxPad=0.05, **kwargs): """ Internal function to put the CatalogSource in a Cartesian box. This function add two necessary attribues: #. :attr:`BoxSize` : array_like, (3,) if not provided, the BoxSize in each direction is computed from the maximum extent of the Cartesian coordinates of the :attr:`randoms` Source, with an optional, additional padding #. :attr:`BoxCenter`: array_like, (3,) the mean coordinate value in each direction; this is used to re-center the Cartesian coordinates of the :attr:`data` and :attr:`randoms` to the range of ``[-BoxSize/2, BoxSize/2]`` """ from nbodykit.utils import get_data_bounds # compute the min/max of the position data pos, sel = catalogue.read([position, selection]) pos_min, pos_max = get_data_bounds(pos, catalogue.comm, selection=sel) # used to center the data in the first cartesian quadrant delta = abs(pos_max - pos_min) catalogue.attrs['BoxCenter'] = BoxCenter if catalogue.attrs['BoxCenter'] is None: catalogue.attrs['BoxCenter'] = 0.5 * (pos_min + pos_max) # BoxSize is padded diff of min/max coordinates catalogue.attrs['BoxSize'] = BoxSize catalogue.attrs['BoxPad'] = BoxPad if catalogue.attrs['BoxSize'] is None: delta *= 1.0 + catalogue.attrs['BoxPad'] catalogue.attrs['BoxSize'] = numpy.ceil(delta) # round up to nearest integer if (catalogue.attrs['BoxSize']<delta).any(): raise ValueError('BoxSize too small to contain all data.') # log some info if catalogue.comm.rank == 0: catalogue.logger.info("BoxSize = %s" %str(catalogue.attrs['BoxSize'])) catalogue.logger.info("cartesian coordinate range: %s : %s" %(str(pos_min), str(pos_max))) catalogue.logger.info("BoxCenter = %s" %str(catalogue.attrs['BoxCenter']))
def shift_to_box_center(pos, BoxSize, comm): """ Find the bounds of the input position array, and if needed, shift the position to an observer at the box center. Position should be bounded by [0, BoxSize] or [-BoxSize/2, BoxSize/2]; if not, an exception will be raised. Parameters ---------- pos : dask array the dask array holding the Position BoxSize : array_like the size of the box comm : the MPI communicator Returns ------- pos : dask array the position array, shifted such that observer is in the box center """ from nbodykit.utils import get_data_bounds # make BoxSize is a 3-vector _BoxSize = numpy.empty(3) _BoxSize[:] = BoxSize # get min/max of position (3-vectors) pos_min, pos_max = get_data_bounds(pos, comm) # Position is [0, BoxSize] --> shift to center of box if (pos_min > 0.).all() and (pos_max < _BoxSize).all(): pos -= 0.5 * _BoxSize elif (pos_min > -0.5*_BoxSize).all() and (pos_max < 0.5*_BoxSize).all(): pass else: raise ValueError("input Position should be bounded by [0,BoxSize] or [-BoxSize/2,BoxSize/2]") return pos
def _define_cartesian_box(self, position, selection): """ Internal function to put the :attr:`randoms` CatalogSource in a Cartesian box. This function add two necessary attribues: #. :attr:`BoxSize` : array_like, (3,) if not provided, the BoxSize in each direction is computed from the maximum extent of the Cartesian coordinates of the :attr:`randoms` Source, with an optional, additional padding #. :attr:`BoxCenter`: array_like, (3,) the mean coordinate value in each direction; this is used to re-center the Cartesian coordinates of the :attr:`data` and :attr:`randoms` to the range of ``[-BoxSize/2, BoxSize/2]`` """ from nbodykit.utils import get_data_bounds # compute the min/max of the position data pos, sel = self['randoms'].read([position, selection]) pos_min, pos_max = get_data_bounds(pos, self.comm, selection=sel) # used to center the data in the first cartesian quadrant delta = abs(pos_max - pos_min) self.attrs['BoxCenter'] = 0.5 * (pos_min + pos_max) # BoxSize is padded diff of min/max coordinates if self.attrs['BoxSize'] is None: delta *= 1.0 + self.attrs['BoxPad'] self.attrs['BoxSize'] = numpy.ceil( delta) # round up to nearest integer # log some info if self.comm.rank == 0: self.logger.info("BoxSize = %s" % str(self.attrs['BoxSize'])) self.logger.info("cartesian coordinate range: %s : %s" % (str(pos_min), str(pos_max))) self.logger.info("BoxCenter = %s" % str(self.attrs['BoxCenter']))