gl_space.py 5.62 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# NIFTy
# Copyright (C) 2017  Theo Steininger
#
# Author: Theo Steininger
#
# 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 <http://www.gnu.org/licenses/>.

csongor's avatar
csongor committed
19
20
from __future__ import division

Jait Dixit's avatar
Jait Dixit committed
21
import itertools
csongor's avatar
csongor committed
22
23
import numpy as np

24
from nifty.spaces.space import Space
25
from nifty.config import dependency_injector as gdi
26

Theo Steininger's avatar
Theo Steininger committed
27
28
29
pyHealpix = gdi.get('pyHealpix')


Theo Steininger's avatar
Theo Steininger committed
30
class GLSpace(Space):
csongor's avatar
csongor committed
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    """
        ..                 __
        ..               /  /
        ..     ____ __  /  /
        ..   /   _   / /  /
        ..  /  /_/  / /  /_
        ..  \___   /  \___/  space class
        .. /______/

        NIFTY subclass for Gauss-Legendre pixelizations [#]_ of the two-sphere.

        Parameters
        ----------
        nlat : int
            Number of latitudinal bins, or rings.
        nlon : int, *optional*
            Number of longitudinal bins (default: ``2*nlat - 1``).
        dtype : numpy.dtype, *optional*
            Data type of the field values (default: numpy.float64).

        See Also
        --------
        hp_space : A class for the HEALPix discretization of the sphere [#]_.
        lm_space : A class for spherical harmonic components.

        References
        ----------
        .. [#] M. Reinecke and D. Sverre Seljebotn, 2013, "Libsharp - spherical
               harmonic transforms revisited";
               `arXiv:1303.4945 <http://www.arxiv.org/abs/1303.4945>`_
        .. [#] 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.

        Attributes
        ----------
        dtype : numpy.dtype
            Data type of the field values.
    """

71
72
    # ---Overwritten properties and methods---

73
    def __init__(self, nlat, nlon=None, dtype=None):
csongor's avatar
csongor committed
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
        """
            Sets the attributes for a gl_space class instance.

            Parameters
            ----------
            nlat : int
                Number of latitudinal bins, or rings.
            nlon : int, *optional*
                Number of longitudinal bins (default: ``2*nlat - 1``).
            dtype : numpy.dtype, *optional*
                Data type of the field values (default: numpy.float64).

            Returns
            -------
            None

            Raises
            ------
            ValueError
93
                If input `nlat` is invalid.
csongor's avatar
csongor committed
94
95

        """
Theo Steininger's avatar
Theo Steininger committed
96
97
98
        if 'pyHealpix' not in gdi:
            raise ImportError(
                "The module pyHealpix is needed but not available.")
99
100

        super(GLSpace, self).__init__(dtype)
csongor's avatar
csongor committed
101

102
103
        self._nlat = self._parse_nlat(nlat)
        self._nlon = self._parse_nlon(nlon)
csongor's avatar
csongor committed
104

105
    # ---Mandatory properties and methods---
csongor's avatar
csongor committed
106

107
108
109
    @property
    def harmonic(self):
        return False
csongor's avatar
csongor committed
110
111
112

    @property
    def shape(self):
113
        return (np.int((self.nlat * self.nlon)),)
csongor's avatar
csongor committed
114

115
    @property
116
    def dim(self):
117
        return np.int((self.nlat * self.nlon))
118
119
120
121

    @property
    def total_volume(self):
        return 4 * np.pi
122

123
124
125
126
127
    def copy(self):
        return self.__class__(nlat=self.nlat,
                              nlon=self.nlon,
                              dtype=self.dtype)

Jait Dixit's avatar
Jait Dixit committed
128
    def weight(self, x, power=1, axes=None, inplace=False):
129
130
        nlon = self.nlon
        nlat = self.nlat
Theo Steininger's avatar
Theo Steininger committed
131
        vol = pyHealpix.GL_weights(nlat, nlon) ** power
132
        weight = np.array(list(itertools.chain.from_iterable(
Theo Steininger's avatar
Theo Steininger committed
133
                          itertools.repeat(x, nlon) for x in vol)))
Jait Dixit's avatar
Jait Dixit committed
134
135
136

        if axes is not None:
            # reshape the weight array to match the input shape
137
            new_shape = np.ones(len(x.shape), dtype=np.int)
138
139
            # we know len(axes) is always 1
            new_shape[axes[0]] = len(weight)
Jait Dixit's avatar
Jait Dixit committed
140
141
142
143
144
            weight = weight.reshape(new_shape)

        if inplace:
            x *= weight
            result_x = x
csongor's avatar
csongor committed
145
        else:
Jait Dixit's avatar
Jait Dixit committed
146
            result_x = x * weight
csongor's avatar
csongor committed
147

Jait Dixit's avatar
Jait Dixit committed
148
        return result_x
149

150
    def get_distance_array(self, distribution_strategy):
Theo Steininger's avatar
Theo Steininger committed
151
        raise NotImplementedError
152

153
    def get_fft_smoothing_kernel_function(self, sigma):
Theo Steininger's avatar
Theo Steininger committed
154
        raise NotImplementedError
155

156
157
158
159
160
161
162
163
164
165
166
167
    # ---Added properties and methods---

    @property
    def nlat(self):
        return self._nlat

    @property
    def nlon(self):
        return self._nlon

    def _parse_nlat(self, nlat):
        nlat = int(nlat)
168
169
170
        if nlat < 1:
            raise ValueError(
                "nlat must be a positive number.")
171
172
173
174
175
176
177
        return nlat

    def _parse_nlon(self, nlon):
        if nlon is None:
            nlon = 2 * self.nlat - 1
        else:
            nlon = int(nlon)
178
179
            if nlon < 1:
                raise ValueError("nlon must be a positive number.")
180
        return nlon
181
182
183
184

    # ---Serialization---

    def _to_hdf5(self, hdf5_group):
Jait Dixit's avatar
Jait Dixit committed
185
186
        hdf5_group['nlat'] = self.nlat
        hdf5_group['nlon'] = self.nlon
187
        hdf5_group.attrs['dtype'] = self.dtype.name
Jait Dixit's avatar
Jait Dixit committed
188

189
190
191
        return None

    @classmethod
Theo Steininger's avatar
Theo Steininger committed
192
    def _from_hdf5(cls, hdf5_group, repository):
193
        result = cls(
Jait Dixit's avatar
Jait Dixit committed
194
195
            nlat=hdf5_group['nlat'][()],
            nlon=hdf5_group['nlon'][()],
196
            dtype=np.dtype(hdf5_group.attrs['dtype'])
Jait Dixit's avatar
Jait Dixit committed
197
198
            )

199
        return result
200
201
202

    def plot(self):
        pass