# NIFTY (Numerical Information Field Theory) has been developed at the # Max-Planck-Institute for Astrophysics. # # Copyright (C) 2015 Max-Planck-Society # # Author: Marco Selig # Project homepage: # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ .. __ ____ __ .. /__/ / _/ / /_ .. __ ___ __ / /_ / _/ __ __ .. / _ | / / / _/ / / / / / / .. / / / / / / / / / /_ / /_/ / .. /__/ /__/ /__/ /__/ \___/ \___ / lm .. /______/ NIFTY submodule for grids on the two-sphere. """ from __future__ import division import numpy as np import d2o from nifty.spaces.space import Space from nifty.config import nifty_configuration as gc, \ dependency_injector as gdi hp = gdi.get('healpy') class HPSpace(Space): """ .. __ .. / / .. / /___ ______ .. / _ | / _ | .. / / / / / /_/ / .. /__/ /__/ / ____/ space class .. /__/ NIFTY subclass for HEALPix discretizations of the two-sphere [#]_. Parameters ---------- nside : int Resolution parameter for the HEALPix discretization, resulting in ``12*nside**2`` pixels. See Also -------- gl_space : A class for the Gauss-Legendre discretization of the sphere [#]_. lm_space : A class for spherical harmonic components. Notes ----- Only powers of two are allowed for `nside`. References ---------- .. [#] K.M. Gorski et al., 2005, "HEALPix: A Framework for High-Resolution Discretization and Fast Analysis of Data Distributed on the Sphere", *ApJ* 622..759G. .. [#] M. Reinecke and D. Sverre Seljebotn, 2013, "Libsharp - spherical harmonic transforms revisited"; `arXiv:1303.4945 `_ Attributes ---------- para : numpy.ndarray Array containing the number `nside`. dtype : numpy.dtype Data type of the field values, which is always numpy.float64. discrete : bool Whether or not the underlying space is discrete, always ``False`` for spherical spaces. vol : numpy.ndarray An array with one element containing the pixel size. """ # ---Overwritten properties and methods--- def __init__(self, nside=2, dtype=None): """ Sets the attributes for a hp_space class instance. Parameters ---------- nside : int Resolution parameter for the HEALPix discretization, resulting in ``12*nside**2`` pixels. Returns ------- None Raises ------ ImportError If the healpy module is not available. ValueError If input `nside` is invaild. """ # check imports if not gc['use_healpy']: raise ImportError("healpy not available or not loaded.") super(HPSpace, self).__init__(dtype) self._nside = self._parse_nside(nside) # ---Mandatory properties and methods--- @property def harmonic(self): return False @property def shape(self): return (np.int(12 * self.nside ** 2),) @property def dim(self): return np.int(12 * self.nside ** 2) @property def total_volume(self): return 4 * np.pi def copy(self): return self.__class__(nside=self.nside, dtype=self.dtype) def weight(self, x, power=1, axes=None, inplace=False): weight = ((4 * np.pi) / (12 * self.nside**2))**power if inplace: x *= weight result_x = x else: result_x = x * weight return result_x def get_distance_array(self, distribution_strategy): """ Calculates distance from center to all the points on the sphere Parameters ---------- distribution_strategy: Result d2o's distribution strategy Returns ------- dists: distributed_data_object """ dists = d2o.arange( start=0, stop=self.shape[0], distribution_strategy=distribution_strategy ) # translate distances to 3D unit vectors on a sphere, # extract the first entry (simulates the scalar product with (1,0,0)) # and apply arccos dists = dists.apply_scalar_function( lambda z: np.arccos(hp.pix2vec(self.nside, z)[0]), dtype=np.float) return dists def get_fft_smoothing_kernel_function(self, sigma): if sigma is None: sigma = np.sqrt(2) * np.pi return lambda x: np.exp((-0.5 * x**2) / sigma**2) # ---Added properties and methods--- @property def nside(self): return self._nside def _parse_nside(self, nside): nside = int(nside) if nside < 2: raise ValueError("nside must be greater than 2.") elif nside % 2 != 0: raise ValueError("nside must be a multiple of 2.") return nside # ---Serialization--- def _to_hdf5(self, hdf5_group): hdf5_group['nside'] = self.nside hdf5_group['dtype'] = self.dtype.name return None @classmethod def _from_hdf5(cls, hdf5_group, repository): result = cls( nside=hdf5_group['nside'][()], dtype=np.dtype(hdf5_group['dtype'][()]) ) return result