healpix-geo 0.0.9__cp310-cp310-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of healpix-geo might be problematic. Click here for more details.

@@ -0,0 +1,81 @@
1
+ import numpy as np
2
+ import pytest
3
+
4
+ import healpix_geo
5
+
6
+
7
+ @pytest.mark.parametrize(
8
+ ["depth", "indexing_scheme", "from_", "to_", "expected"],
9
+ (
10
+ (
11
+ 1,
12
+ "nested",
13
+ np.array([0, 16, 25, 32, 46]),
14
+ np.array([2, 15, 27, 40, 41], dtype="int64"),
15
+ np.array(
16
+ [0.51262797, 1.60992678, 0.51347673, 0.82227572, 0.57850402],
17
+ dtype="float64",
18
+ ),
19
+ ),
20
+ (
21
+ 1,
22
+ "ring",
23
+ np.array([0, 16, 25, 32, 46]),
24
+ np.array([2, 15, 27, 40, 41], dtype="int64"),
25
+ np.array(
26
+ [0.82227572, 0.73824548, 1.57079633, 0.51262797, 0.48146047],
27
+ dtype="float64",
28
+ ),
29
+ ),
30
+ (
31
+ 1,
32
+ "nested",
33
+ np.array([0, 16, 25, 32, 46]),
34
+ np.array([[2], [15], [27], [40], [41]], dtype="int64"),
35
+ np.array(
36
+ [[0.51262797], [1.60992678], [0.51347673], [0.82227572], [0.57850402]],
37
+ dtype="float64",
38
+ ),
39
+ ),
40
+ (
41
+ 2,
42
+ "ring",
43
+ np.array([0, 16, 25, 32, 46]),
44
+ np.array([[2, 4], [15, 7], [27, 26], [40, -1], [-1, 41]], dtype="int64"),
45
+ np.array(
46
+ [
47
+ [0.4089604, 0.23486912],
48
+ [0.30291976, 0.283655],
49
+ [0.57850402, 0.29185825],
50
+ [1.87523829, np.nan],
51
+ [np.nan, 1.60781736],
52
+ ],
53
+ dtype="float64",
54
+ ),
55
+ ),
56
+ ),
57
+ )
58
+ def test_distance(depth, indexing_scheme, from_, to_, expected):
59
+ if indexing_scheme == "nested":
60
+ angular_distances = healpix_geo.nested.angular_distances
61
+ elif indexing_scheme == "ring":
62
+ angular_distances = healpix_geo.ring.angular_distances
63
+
64
+ actual = angular_distances(from_, to_, depth)
65
+
66
+ np.testing.assert_allclose(actual, expected)
67
+
68
+
69
+ @pytest.mark.parametrize("indexing_scheme", ["ring", "nested"])
70
+ def test_distance_error(indexing_scheme):
71
+ if indexing_scheme == "nested":
72
+ angular_distances = healpix_geo.nested.angular_distances
73
+ elif indexing_scheme == "ring":
74
+ angular_distances = healpix_geo.ring.angular_distances
75
+
76
+ from_ = np.array([4, 7])
77
+ to_ = np.array([[2, 3], [4, 6], [5, 4]])
78
+ depth = 1
79
+
80
+ with pytest.raises(ValueError, match="The shape of `from_` must be compatible"):
81
+ angular_distances(from_, to_, depth)
@@ -0,0 +1,290 @@
1
+ import pickle
2
+
3
+ import numpy as np
4
+ import pytest
5
+ import shapely
6
+
7
+ import healpix_geo
8
+
9
+
10
+ class TestRangeMOCIndex:
11
+ @pytest.mark.parametrize("level", [0, 3, 6])
12
+ def test_full_domain(self, level):
13
+ index = healpix_geo.nested.RangeMOCIndex.full_domain(level)
14
+
15
+ expected = np.arange(12 * 4**level, dtype="uint64")
16
+
17
+ assert index.nbytes == 16
18
+ assert index.size == expected.size
19
+ assert index.depth == level
20
+
21
+ @pytest.mark.parametrize(
22
+ ["level", "cell_ids"],
23
+ (
24
+ (0, np.array([1, 2, 5], dtype="uint64")),
25
+ (3, np.array([12, 16, 17, 19, 22, 23, 71, 72, 73, 79], dtype="uint64")),
26
+ (6, np.arange(3 * 4**6, 5 * 4**6, dtype="uint64")),
27
+ ),
28
+ )
29
+ def test_from_cell_ids(self, level, cell_ids):
30
+ index = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids)
31
+
32
+ assert index.size == cell_ids.size
33
+ assert index.depth == level
34
+
35
+ @pytest.mark.parametrize(
36
+ ["level", "cell_ids1", "cell_ids2", "expected"],
37
+ (
38
+ (
39
+ 4,
40
+ np.arange(0, 6 * 4**4, dtype="uint64"),
41
+ np.arange(6 * 4**4, 12 * 4**4, dtype="uint64"),
42
+ np.arange(12 * 4**4, dtype="uint64"),
43
+ ),
44
+ (
45
+ 1,
46
+ np.array([1, 2, 3, 4, 21, 22], dtype="uint64"),
47
+ np.array([23, 25, 26, 32, 33, 34, 35], dtype="uint64"),
48
+ np.array(
49
+ [1, 2, 3, 4, 21, 22, 23, 25, 26, 32, 33, 34, 35], dtype="uint64"
50
+ ),
51
+ ),
52
+ ),
53
+ )
54
+ def test_union(self, level, cell_ids1, cell_ids2, expected):
55
+ index1 = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids1)
56
+ index2 = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids2)
57
+
58
+ actual = index1.union(index2)
59
+
60
+ assert isinstance(actual, healpix_geo.nested.RangeMOCIndex)
61
+ np.testing.assert_equal(actual.cell_ids(), expected)
62
+
63
+ @pytest.mark.parametrize(
64
+ ["level", "cell_ids1", "cell_ids2", "expected"],
65
+ (
66
+ (
67
+ 4,
68
+ np.arange(2 * 4**4, 4 * 4**4, dtype="uint64"),
69
+ np.arange(3 * 4**4, 5 * 4**4, dtype="uint64"),
70
+ np.arange(3 * 4**4, 4 * 4**4, dtype="uint64"),
71
+ ),
72
+ (
73
+ 1,
74
+ np.array([1, 2, 3, 4, 21, 22, 23, 24, 25], dtype="uint64"),
75
+ np.array([21, 22, 23, 25, 26, 32, 33, 34, 35], dtype="uint64"),
76
+ np.array([21, 22, 23, 25], dtype="uint64"),
77
+ ),
78
+ ),
79
+ )
80
+ def test_intersection(self, level, cell_ids1, cell_ids2, expected):
81
+ index1 = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids1)
82
+ index2 = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids2)
83
+
84
+ actual = index1.intersection(index2)
85
+
86
+ assert isinstance(actual, healpix_geo.nested.RangeMOCIndex)
87
+ np.testing.assert_equal(actual.cell_ids(), expected)
88
+
89
+ @pytest.mark.parametrize(
90
+ ["level", "cell_ids"],
91
+ (
92
+ pytest.param(0, np.arange(12, dtype="uint64"), id="base cells"),
93
+ pytest.param(
94
+ 1,
95
+ np.array([0, 1, 2, 4, 5, 11, 12, 13, 25, 26, 27], dtype="uint64"),
96
+ id="list of level 1 cells",
97
+ ),
98
+ pytest.param(
99
+ 4,
100
+ np.arange(1 * 4**4, 2 * 4**4, dtype="uint64"),
101
+ id="single level 4 base cell",
102
+ ),
103
+ ),
104
+ )
105
+ @pytest.mark.parametrize(
106
+ "indexer",
107
+ [
108
+ slice(None),
109
+ slice(None, 4),
110
+ slice(2, None),
111
+ slice(3, 7),
112
+ np.arange(5, dtype="uint64"),
113
+ np.array([1, 2, 4, 6, 8], dtype="uint64"),
114
+ ],
115
+ )
116
+ def test_isel(self, level, cell_ids, indexer):
117
+ expected = cell_ids[indexer]
118
+
119
+ index = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids)
120
+
121
+ actual = index.isel(indexer)
122
+
123
+ np.testing.assert_equal(actual.cell_ids(), expected)
124
+
125
+ @pytest.mark.parametrize(
126
+ ["level", "cell_ids", "indexer"],
127
+ (
128
+ pytest.param(
129
+ 0,
130
+ np.arange(12, dtype="uint64"),
131
+ slice(None),
132
+ id="base cells-slice-full",
133
+ ),
134
+ pytest.param(
135
+ 0,
136
+ np.arange(12, dtype="uint64"),
137
+ slice(None, 6),
138
+ id="base cells-slice-left_open",
139
+ ),
140
+ pytest.param(
141
+ 0,
142
+ np.arange(12, dtype="uint64"),
143
+ slice(2, None),
144
+ id="base cells-slice-right_open",
145
+ ),
146
+ pytest.param(
147
+ 0,
148
+ np.arange(12, dtype="uint64"),
149
+ slice(2, 7),
150
+ id="base cells-slice-domain",
151
+ ),
152
+ pytest.param(
153
+ 0,
154
+ np.arange(12, dtype="uint64"),
155
+ np.arange(12, dtype="uint64"),
156
+ id="base cells-array-full",
157
+ ),
158
+ pytest.param(
159
+ 0,
160
+ np.arange(12, dtype="uint64"),
161
+ np.arange(2, 7, dtype="uint64"),
162
+ id="base cells-array-domain",
163
+ ),
164
+ pytest.param(
165
+ 0,
166
+ np.arange(12, dtype="uint64"),
167
+ np.array([1, 2, 3, 7, 8, 9, 10], dtype="uint64"),
168
+ id="base cells-array-disconnected",
169
+ ),
170
+ pytest.param(
171
+ 3,
172
+ np.arange(12 * 4**3, dtype="uint64"),
173
+ slice(None, 15),
174
+ id="level 3 cells-slice-left_open",
175
+ ),
176
+ pytest.param(
177
+ 1,
178
+ np.array([0, 1, 2, 4, 5, 11, 12, 13, 25, 26, 27], dtype="uint64"),
179
+ np.array([2, 5, 11, 12, 25, 27], dtype="uint64"),
180
+ id="list of level 1 cells-array-disconnected",
181
+ ),
182
+ pytest.param(
183
+ 4,
184
+ np.arange(1 * 4**4, 2 * 4**4, dtype="uint64"),
185
+ slice(260, 280),
186
+ id="single level 4 base cell-slice-domain",
187
+ ),
188
+ ),
189
+ )
190
+ def test_sel(self, level, cell_ids, indexer):
191
+ if isinstance(indexer, slice):
192
+ n = slice(
193
+ indexer.start if indexer.start is not None else 0,
194
+ (
195
+ indexer.stop + 1
196
+ if indexer.stop is not None
197
+ else int(np.max(cell_ids)) + 1
198
+ ),
199
+ indexer.step if indexer.step is not None else 1,
200
+ )
201
+ range_ = np.arange(n.start, n.stop, n.step, dtype="uint64")
202
+ condition = np.isin(cell_ids, range_)
203
+ else:
204
+ condition = np.isin(cell_ids, indexer)
205
+ expected_cell_ids = cell_ids[condition]
206
+
207
+ index = healpix_geo.nested.RangeMOCIndex.from_cell_ids(level, cell_ids)
208
+
209
+ actual_indexer, actual_moc = index.sel(indexer)
210
+
211
+ np.testing.assert_equal(cell_ids[actual_indexer], expected_cell_ids)
212
+ np.testing.assert_equal(actual_moc.cell_ids(), expected_cell_ids)
213
+
214
+ @pytest.mark.parametrize(
215
+ ["depth", "cell_ids"],
216
+ (
217
+ (2, np.arange(1 * 4**2, 3 * 4**2, dtype="uint64")),
218
+ (5, np.arange(12 * 4**5, dtype="uint64")),
219
+ ),
220
+ )
221
+ def test_pickle_roundtrip(self, depth, cell_ids):
222
+ index = healpix_geo.nested.RangeMOCIndex.from_cell_ids(depth, cell_ids)
223
+
224
+ pickled = pickle.dumps(index)
225
+ assert isinstance(pickled, bytes)
226
+ unpickled = pickle.loads(pickled)
227
+
228
+ assert isinstance(unpickled, healpix_geo.nested.RangeMOCIndex)
229
+ assert index.depth == unpickled.depth
230
+ np.testing.assert_equal(unpickled.cell_ids(), index.cell_ids())
231
+
232
+ @pytest.mark.parametrize("depth", (0, 2, 10))
233
+ @pytest.mark.parametrize(
234
+ "geom",
235
+ (
236
+ pytest.param(shapely.Point(30, 30), id="point"),
237
+ pytest.param(shapely.box(-25, 15, 25, 35), id="polygon"),
238
+ pytest.param(
239
+ shapely.LineString([(30, 30), (31, 31), (32, 33)]), id="linestring"
240
+ ),
241
+ pytest.param(healpix_geo.geometry.Bbox(-25, 15, 25, 35), id="bbox"),
242
+ ),
243
+ )
244
+ @pytest.mark.parametrize("domain", ["full", "partial"])
245
+ def test_query(self, depth, domain, geom):
246
+ import cdshealpix.nested
247
+ from astropy.coordinates import Latitude, Longitude
248
+
249
+ if domain == "full":
250
+ index = healpix_geo.nested.RangeMOCIndex.full_domain(depth)
251
+ cell_ids = index.cell_ids()
252
+ else:
253
+ cell_ids = np.arange(4**depth, dtype="uint64")
254
+ index = healpix_geo.nested.RangeMOCIndex.from_cell_ids(depth, cell_ids)
255
+
256
+ if isinstance(geom, shapely.Point):
257
+ coords = geom.coords[0]
258
+ lon = Longitude([coords[0]], unit="deg")
259
+ lat = Latitude([coords[0]], unit="deg")
260
+ expected = cdshealpix.nested.lonlat_to_healpix(lon, lat, depth=depth)
261
+ elif isinstance(geom, shapely.LineString):
262
+ coords = np.asarray(geom.coords[:])
263
+ lon = Longitude(coords[:, 0], unit="deg")
264
+ lat = Latitude(coords[:, 1], unit="deg")
265
+
266
+ expected_ = np.unique(
267
+ cdshealpix.nested.lonlat_to_healpix(lon, lat, depth=depth)
268
+ )
269
+ expected = expected_[np.isin(expected_, cell_ids)]
270
+ elif isinstance(geom, shapely.Polygon):
271
+ coords = np.asarray(geom.exterior.coords[:])
272
+ lon = Longitude(coords[:, 0], unit="deg")
273
+ lat = Latitude(coords[:, 1], unit="deg")
274
+ expected_, _, _ = cdshealpix.nested.polygon_search(
275
+ lon, lat, depth=depth, flat=True
276
+ )
277
+ expected = expected_[np.isin(expected_, cell_ids)]
278
+ else:
279
+ expected = None
280
+
281
+ multi_slice, moc = index.query(geom)
282
+
283
+ reconstructed = np.concatenate(
284
+ [cell_ids[s.as_pyslice()] for s in multi_slice], axis=0
285
+ )
286
+ actual = moc.cell_ids()
287
+
288
+ if expected is not None:
289
+ np.testing.assert_equal(reconstructed, expected)
290
+ np.testing.assert_equal(actual, reconstructed)