Passed
Pull Request — master (#17)
by
unknown
15:46
created

SparseHealpix.__add__()   A

Complexity

Conditions 1

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 17
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
import numpy as np
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
import healpy as hp
3
import pandas as pd
4
from ..special_values import UNSEEN
5
6
7
def _not_implemented():  # pragma: no cover
8
9
    raise RuntimeError("You cannot use the base class. Use the derived classes.")
10
11
12
class HealpixWrapperBase(object):
13
    """
14
    A class which wrap a numpy array containing an healpix map, in order to expose always the same interface
15
    independently of whether the underlying map is sparse or dense
16
    """
17
18
    def __init__(self, sparse, nside):
19
20
        self._nside = int(nside)
21
        self._npix = hp.nside2npix(self._nside)
22
        self._pixel_area = hp.nside2pixarea(self._nside, degrees=True)
23
24
        self._sparse = bool(sparse)
25
26
    @property
27
    def is_sparse(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
28
        return self._sparse
29
30
    @property
31
    def nside(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
32
        return self._nside
33
34
    @property
35
    def npix(self):
36
        """
37
        :return: total number of pixels for this nside. Note that mymap.npix is equivalent to
38
        healpy.nside2npix(mymap.nside)
39
        """
40
        return self._npix
41
42
    @property
43
    def pixel_area(self):
44
        """
45
        :return: area (solid angle) of the healpix pixel in sq. degrees
46
        """
47
        return self._pixel_area
48
49
    def as_dense(self):  # pragma: no cover
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
50
51
        return _not_implemented()
52
53
    def as_partial(self):  # pragma: no cover
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
54
55
        return _not_implemented()
56
57
    def to_pandas(self):
58
        """
59
        Returns a pandas Series with the dense representation of the data
60
61
        :return: pd.Series, type
62
        """
63
64
        return pd.Series(self.as_partial())
65
66
67
class SparseHealpix(HealpixWrapperBase):
0 ignored issues
show
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
68
69
    def __init__(self, partial_map, pixels_ids, nside, fill_value=UNSEEN):
70
71
        self._partial_map = partial_map
72
        self._pixels_ids = pixels_ids
73
        self._fill_value = fill_value
74
75
        super(SparseHealpix, self).__init__(sparse=True, nside=nside)
76
77
    def __add__(self, other_map):
78
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
79
        # Make sure they have the same pixels
80
        assert np.array_equal(self._pixels_ids, other_map._pixels_ids)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _pixels_ids was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
81
82
        # inflate them
83
        big_self_map = self.as_dense()
84
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
85
        big_other_map = other_map.as_dense()
86
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
87
        # add them
88
        dense_added = big_self_map + big_other_map
89
90
        # deflate
91
        sparse_added = SparseHealpix(dense_added[self._pixels_ids], self._pixels_ids, self.nside)
92
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
93
        return sparse_added
94
95
    def __sub__(self, other_map):
96
97
        # Make sure they have the same pixels
98
        assert np.array_equal(self._pixels_ids, other_map._pixels_ids)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _pixels_ids was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
99
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
100
        big_other_map = other_map.as_dense()
101
        big_self_map = self.as_dense()
102
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
103
        subtraction = big_self_map - big_other_map
104
105
        sparse_subtracted = SparseHealpix(subtraction[self._pixels_ids], self._pixels_ids, self.nside)
106
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
107
        return sparse_subtracted
108
109
    def as_dense(self):
110
        """
111
        Returns the dense (i.e., full sky) representation of the map. Note that this means unwrapping the map,
112
        and the memory usage increases a lot.
113
114
        :return: the dense map, suitable for use with healpy routine (among other uses)
115
        """
116
117
        # Make the full Healpix map
118
        new_map = np.full(self.npix, self._fill_value)
119
120
        # Assign the active pixels their values
121
        new_map[self._pixels_ids] = self._partial_map
122
123
        return new_map
124
125
    def as_partial(self):
126
127
        return self._partial_map
128
129
    def set_new_values(self, new_values):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
130
131
        assert new_values.shape == self._partial_map.shape
132
133
        self._partial_map[:] = new_values
134
135
136
137
class DenseHealpix(HealpixWrapperBase):
138
    """
139
    A dense (fullsky) healpix map. In this case partial and complete are the same map.
140
141
    """
142
143
    def __init__(self, healpix_array):
144
145
        self._dense_map = healpix_array
146
147
        super(DenseHealpix, self).__init__(nside=hp.npix2nside(healpix_array.shape[0]), sparse=False)
148
149
    def as_dense(self):
150
        """
151
        Returns the complete (i.e., full sky) representation of the map. Since this is a dense map, this is identical
152
        to the input map
153
154
        :return: the complete map, suitable for use with healpy routine (among other uses)
155
        """
156
157
        return self._dense_map
158
159
    def as_partial(self):
160
161
        return self._dense_map
162
163
    def set_new_values(self, new_values):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
164
165
        assert new_values.shape == self._dense_map.shape
166
167
        self._dense_map[:] = new_values
168
0 ignored issues
show
coding-style introduced by
Trailing newlines
Loading history...
169