healpix-geo 0.0.8__cp312-cp312-musllinux_1_2_i686.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.
@@ -0,0 +1,3 @@
1
+ from healpix_geo import geometry, nested, ring, slices
2
+
3
+ __all__ = ["nested", "ring", "slices", "geometry"]
@@ -0,0 +1,3 @@
1
+ from healpix_geo.healpix_geo import geometry
2
+
3
+ Bbox = geometry.Bbox # noqa: F401
healpix_geo/nested.py ADDED
@@ -0,0 +1,571 @@
1
+ import numpy as np
2
+
3
+ from healpix_geo import healpix_geo
4
+ from healpix_geo.utils import _check_depth, _check_ipixels, _check_ring
5
+
6
+ RangeMOCIndex = healpix_geo.nested.RangeMOCIndex
7
+
8
+
9
+ def create_empty(depth):
10
+ return RangeMOCIndex.create_empty(depth)
11
+
12
+
13
+ def healpix_to_lonlat(ipix, depth, ellipsoid, num_threads=0):
14
+ r"""Get the longitudes and latitudes of the center of some HEALPix cells.
15
+
16
+ Parameters
17
+ ----------
18
+ ipix : `numpy.ndarray`
19
+ The HEALPix cell indexes given as a `np.uint64` numpy array.
20
+ depth : `numpy.ndarray`
21
+ The HEALPix cell depth given as a `np.uint8` numpy array.
22
+ ellipsoid : ellipsoid-like, default: "sphere"
23
+ Reference ellipsoid to evaluate healpix on. If the reference ellipsoid
24
+ is spherical, this will return the same result as
25
+ :py:func:`cdshealpix.nested.healpix_to_lonlat`.
26
+ num_threads : int, optional
27
+ Specifies the number of threads to use for the computation. Default to 0 means
28
+ it will choose the number of threads based on the RAYON_NUM_THREADS environment variable (if set),
29
+ or the number of logical CPUs (otherwise)
30
+
31
+ Returns
32
+ -------
33
+ lon, lat : array-like
34
+ The coordinates of the center of the HEALPix cells given as a longitude, latitude tuple.
35
+
36
+ Raises
37
+ ------
38
+ ValueError
39
+ When the HEALPix cell indexes given have values out of :math:`[0, 4^{29 - depth}[`.
40
+ ValueError
41
+ When the name of the ellipsoid is unknown.
42
+
43
+ Examples
44
+ --------
45
+ >>> from healpix_geo.nested import healpix_to_lonlat
46
+ >>> import numpy as np
47
+ >>> cell_ids = np.array([42, 6, 10])
48
+ >>> depth = 3
49
+ >>> lon, lat = healpix_to_lonlat(ipix, depth, ellipsoid="WGS84")
50
+ """
51
+ _check_depth(depth)
52
+ ipix = np.atleast_1d(ipix)
53
+ _check_ipixels(data=ipix, depth=depth)
54
+ ipix = ipix.astype(np.uint64)
55
+
56
+ num_threads = np.uint16(num_threads)
57
+
58
+ latitude = np.empty_like(ipix, dtype="float64")
59
+ longitude = np.empty_like(ipix, dtype="float64")
60
+
61
+ healpix_geo.nested.healpix_to_lonlat(
62
+ depth, ipix, ellipsoid, longitude, latitude, num_threads
63
+ )
64
+
65
+ return longitude, latitude
66
+
67
+
68
+ def lonlat_to_healpix(longitude, latitude, depth, ellipsoid="sphere", num_threads=0):
69
+ r"""Get the HEALPix indexes that contains specific points.
70
+
71
+ Parameters
72
+ ----------
73
+ lon : array-like
74
+ The longitudes of the input points, in degrees.
75
+ lat : array-like
76
+ The latitudes of the input points, in degrees.
77
+ depth : int or array-like of int
78
+ The HEALPix cell depth given as a `np.uint8` numpy array.
79
+ ellipsoid : ellipsoid-like, default: "sphere"
80
+ Reference ellipsoid to evaluate healpix on. If the reference ellipsoid
81
+ is spherical, this will return the same result as
82
+ :py:func:`cdshealpix.nested.lonlat_to_healpix`.
83
+ num_threads : int, optional
84
+ Specifies the number of threads to use for the computation. Default to 0 means
85
+ it will choose the number of threads based on the RAYON_NUM_THREADS environment variable (if set),
86
+ or the number of logical CPUs (otherwise)
87
+
88
+ Returns
89
+ -------
90
+ ipix : `numpy.ndarray`
91
+ A numpy array containing all the HEALPix cell indexes stored as `np.uint64`.
92
+
93
+ Raises
94
+ ------
95
+ ValueError
96
+ When the number of longitudes and latitudes given do not match.
97
+ ValueError
98
+ When the name of the ellipsoid is unknown.
99
+
100
+ Examples
101
+ --------
102
+ >>> from cdshealpix.ring import lonlat_to_healpix
103
+ >>> import numpy as np
104
+ >>> lon = np.array([0, 50, 25], dtype="float64")
105
+ >>> lat = np.array([6, -12, 45], dtype="float64")
106
+ >>> depth = 3
107
+ >>> ipix = lonlat_to_healpix(lon, lat, depth, ellipsoid="WGS84")
108
+ """
109
+ _check_depth(depth)
110
+ longitude = np.atleast_1d(longitude).astype("float64")
111
+ latitude = np.atleast_1d(latitude).astype("float64")
112
+
113
+ num_threads = np.uint16(num_threads)
114
+
115
+ ipix = np.empty_like(longitude, dtype="uint64")
116
+
117
+ healpix_geo.nested.lonlat_to_healpix(
118
+ depth, longitude, latitude, ellipsoid, ipix, num_threads
119
+ )
120
+
121
+ return ipix
122
+
123
+
124
+ def vertices(ipix, depth, ellipsoid, num_threads=0):
125
+ """Get the longitudes and latitudes of the vertices of some HEALPix cells at a given depth.
126
+
127
+ This method returns the 4 vertices of each cell in `ipix`.
128
+
129
+ Parameters
130
+ ----------
131
+ ipix : `numpy.ndarray`
132
+ The HEALPix cell indexes given as a `np.uint64` numpy array.
133
+ depth : int, or `numpy.ndarray`
134
+ The depth of the HEALPix cells. If given as an array, should have the same shape than ipix
135
+ ellipsoid : ellipsoid-like, default: "sphere"
136
+ Reference ellipsoid to evaluate healpix on. If the reference ellipsoid
137
+ is spherical, this will return the same result as
138
+ :py:func:`cdshealpix.nested.vertices`.
139
+ num_threads : int, optional
140
+ Specifies the number of threads to use for the computation. Default to 0 means
141
+ it will choose the number of threads based on the RAYON_NUM_THREADS environment variable (if set),
142
+ or the number of logical CPUs (otherwise)
143
+
144
+ Returns
145
+ -------
146
+ longitude, latitude : array-like
147
+ The sky coordinates of the 4 vertices of the HEALPix cells.
148
+ `lon` and `lat` are of shape :math:`N` x :math:`4` numpy arrays where N is the number of HEALPix cell given in `ipix`.
149
+
150
+ Raises
151
+ ------
152
+ ValueError
153
+ When the HEALPix cell indexes given have values out of :math:`[0, 4^{29 - depth}[`.
154
+
155
+ Examples
156
+ --------
157
+ >>> from healpix_geo.nested import vertices
158
+ >>> import numpy as np
159
+ >>> ipix = np.array([42, 6, 10])
160
+ >>> depth = 12
161
+ >>> lon, lat = vertices(ipix, depth, ellipsoid="sphere")
162
+ """
163
+ _check_depth(depth)
164
+ ipix = np.atleast_1d(ipix)
165
+ _check_ipixels(data=ipix, depth=depth)
166
+ ipix = ipix.astype(np.uint64)
167
+
168
+ num_threads = np.uint16(num_threads)
169
+
170
+ shape = ipix.shape + (4,)
171
+ longitude = np.empty(shape=shape, dtype="float64")
172
+ latitude = np.empty(shape=shape, dtype="float64")
173
+
174
+ healpix_geo.nested.vertices(
175
+ depth, ipix, ellipsoid, longitude, latitude, num_threads
176
+ )
177
+
178
+ return longitude, latitude
179
+
180
+
181
+ def kth_neighbourhood(ipix, depth, ring, num_threads=0):
182
+ """Get the kth ring neighbouring cells of some HEALPix cells at a given depth.
183
+
184
+ This method returns a :math:`N` x :math:`(2 k + 1)^2` `np.uint64` numpy array containing the neighbours of each cell of the :math:`N` sized `ipix` array.
185
+ This method is wrapped around the `kth_neighbourhood <https://docs.rs/cdshealpix/0.1.5/cdshealpix/nested/struct.Layer.html#method.kth_neighbourhood>`__
186
+ method from the `cdshealpix Rust crate <https://crates.io/crates/cdshealpix>`__.
187
+
188
+ Parameters
189
+ ----------
190
+ ipix : `numpy.ndarray`
191
+ The HEALPix cell indexes given as a `np.uint64` numpy array.
192
+ depth : int
193
+ The depth of the HEALPix cells.
194
+ ring : int
195
+ The number of rings. `ring=0` returns just the input cell ids, `ring=1` returns the 8 (or 7) immediate
196
+ neighbours, `ring=2` returns the 8 (or 7) immediate neighbours plus their immediate neighbours (a total of 24 cells), and so on.
197
+ num_threads : int, optional
198
+ Specifies the number of threads to use for the computation. Default to 0 means
199
+ it will choose the number of threads based on the RAYON_NUM_THREADS environment variable (if set),
200
+ or the number of logical CPUs (otherwise)
201
+
202
+ Returns
203
+ -------
204
+ neighbours : `numpy.ndarray`
205
+ A :math:`N` x :math:`(2 k + 1)^2` `np.int64` numpy array containing the kth ring neighbours of each cell.
206
+ The :math:`5^{th}` element corresponds to the index of HEALPix cell from which the neighbours are evaluated.
207
+ All its 8 neighbours occup the remaining elements of the line.
208
+
209
+ Raises
210
+ ------
211
+ ValueError
212
+ When the HEALPix cell indexes given have values out of :math:`[0, 4^{29 - depth}[`.
213
+
214
+ Examples
215
+ --------
216
+ >>> from cdshealpix import neighbours_in_kth_ring
217
+ >>> import numpy as np
218
+ >>> ipix = np.array([42, 6, 10])
219
+ >>> depth = 12
220
+ >>> ring = 3
221
+ >>> neighbours = neighbours_in_kth_ring(ipix, depth, ring)
222
+ """
223
+ _check_depth(depth)
224
+ ipix = np.atleast_1d(ipix)
225
+ _check_ipixels(data=ipix, depth=depth)
226
+ ipix = ipix.astype(np.uint64)
227
+ _check_ring(depth, ring)
228
+
229
+ # Allocation of the array containing the neighbours
230
+ neighbours = np.full(
231
+ (*ipix.shape, (2 * ring + 1) ** 2), dtype=np.int64, fill_value=-1
232
+ )
233
+ num_threads = np.uint16(num_threads)
234
+ healpix_geo.nested.kth_neighbourhood(depth, ipix, ring, neighbours, num_threads)
235
+
236
+ return neighbours
237
+
238
+
239
+ def zoom_to(ipix, depth, new_depth, num_threads=0):
240
+ r"""Change the resolutions the given cell ids
241
+
242
+ Parameters
243
+ ----------
244
+ ipix : numpy.ndarray
245
+ The HEALPix cell indexes given as a `np.uint64` numpy array.
246
+ depth : int
247
+ The depth of the HEALPix cells.
248
+ new_depth : int
249
+ The new depth of the HEALPix cells.
250
+
251
+ Returns
252
+ -------
253
+ cells : numpy.ndarray
254
+ A :math:`N` (`depth >= new_depth`) or :math:`N` x :math:`4^{\delta d}` `np.int64` numpy array containing the parents or children of the given cells.
255
+ If `depth == new_depth`, returns the input pixels
256
+ """
257
+ _check_depth(depth)
258
+ _check_depth(new_depth)
259
+
260
+ if depth == new_depth:
261
+ return ipix
262
+
263
+ ipix = np.atleast_1d(ipix)
264
+ _check_ipixels(data=ipix, depth=depth)
265
+ ipix = ipix.astype(np.uint64)
266
+
267
+ num_threads = np.uint16(num_threads)
268
+ if depth > new_depth:
269
+ result = np.full_like(ipix, fill_value=0)
270
+ else:
271
+ relative_depth = new_depth - depth
272
+ shape = (*ipix.shape, 4**relative_depth)
273
+ result = np.full(shape, fill_value=0, dtype="uint64")
274
+
275
+ healpix_geo.nested.zoom_to(depth, ipix, new_depth, result, num_threads)
276
+
277
+ return result
278
+
279
+
280
+ def siblings(ipix, depth, num_threads=0):
281
+ r"""Find the siblings for every cell
282
+
283
+ Parameters
284
+ ----------
285
+ ipix : numpy.ndarray
286
+ The HEALPix cell indexes given as a `np.uint64` numpy array.
287
+ depth : int
288
+ The depth of the HEALPix cells.
289
+
290
+ Returns
291
+ -------
292
+ cells : numpy.ndarray
293
+ A :math:`N` x :math:`4` or :math:`N` x :math:`12` `np.uint64` numpy array containing the siblings of the given cells.
294
+ If `depth == 0`, the siblings are the base cells.
295
+ """
296
+ _check_depth(depth)
297
+ ipix = np.atleast_1d(ipix)
298
+ _check_ipixels(data=ipix, depth=depth)
299
+ ipix = ipix.astype(np.uint64)
300
+
301
+ num_threads = np.uint16(num_threads)
302
+
303
+ if depth != 0:
304
+ shape = (*ipix.shape, 4)
305
+ else:
306
+ shape = (*ipix.shape, 12)
307
+
308
+ result = np.full(shape, fill_value=0, dtype="uint64")
309
+
310
+ healpix_geo.nested.siblings(depth, ipix, result, num_threads)
311
+
312
+ return result
313
+
314
+
315
+ def angular_distances(from_, to_, depth, num_threads=0):
316
+ """Compute the angular distances between cell centers
317
+
318
+ Parameters
319
+ ----------
320
+ from_ : numpy.ndarray
321
+ The source Healpix cell indexes given as a ``np.uint64`` numpy array. Should be 1D.
322
+ to_ : numpy.ndarray
323
+ The destination Healpix cell indexes given as a ``np.uint64`` numpy array.
324
+ Should be 2D.
325
+ depth : int
326
+ The depth of the Healpix cells.
327
+ num_threads : int, default: 0
328
+ Specifies the number of threads to use for the computation. Default to 0 means
329
+ it will choose the number of threads based on the RAYON_NUM_THREADS environment variable (if set),
330
+ or the number of logical CPUs (otherwise)
331
+
332
+ Returns
333
+ -------
334
+ distances : numpy.ndarray
335
+ The angular distances in radians.
336
+
337
+ Raises
338
+ ------
339
+ ValueError
340
+ When the Healpix cell indexes given have values out of :math:`[0, 4^{depth}[`.
341
+ """
342
+ _check_depth(depth)
343
+
344
+ from_ = np.atleast_1d(from_)
345
+ _check_ipixels(data=from_, depth=depth)
346
+ from_ = from_.astype("uint64")
347
+
348
+ mask = to_ != -1
349
+ masked_to = np.where(mask, to_, 0)
350
+
351
+ to_ = np.atleast_1d(masked_to)
352
+ _check_ipixels(data=to_, depth=depth)
353
+ to_ = to_.astype("uint64")
354
+
355
+ if from_.shape != to_.shape and from_.shape != to_.shape[:-1]:
356
+ raise ValueError(
357
+ "The shape of `from_` must be compatible with the shape of `to_`:\n"
358
+ f"{to_.shape} or {to_.shape[:-1]} must be equal to {from_.shape}."
359
+ )
360
+
361
+ if from_.shape == to_.shape:
362
+ intermediate_shape = to_.shape + (1,)
363
+ else:
364
+ intermediate_shape = to_.shape
365
+
366
+ distances = np.full(intermediate_shape, dtype="float64", fill_value=np.nan)
367
+ num_threads = np.uint16(num_threads)
368
+
369
+ healpix_geo.nested.angular_distances(
370
+ depth, from_, np.reshape(to_, intermediate_shape), distances, num_threads
371
+ )
372
+
373
+ return np.where(mask, np.reshape(distances, to_.shape), np.nan)
374
+
375
+
376
+ def zone_coverage(bbox, depth, *, ellipsoid="sphere", flat=True):
377
+ """Search the cells covering the given bounding box
378
+
379
+ Parameters
380
+ ----------
381
+ bbox : tuple of float
382
+ The 2D bounding box to rasterize.
383
+ depth : int
384
+ The maximum depth of the cells to be returned.
385
+ ellipsoid : ellipsoid-like, default: "sphere"
386
+ Reference ellipsoid to evaluate healpix on.
387
+ flat : bool, default: True
388
+ If ``True``, the cells returned will all be at the passed depth.
389
+
390
+ Returns
391
+ -------
392
+ cell_ids : numpy.ndarray
393
+ The rasterized cell ids.
394
+ depths : numpy.ndarray
395
+ The depths of the cell ids. If ``flat is True``, these will all have the same value.
396
+ fully_covered : numpy.ndarray
397
+ Boolean array marking whether the cells are fully covered by the bounding box.
398
+ """
399
+ _check_depth(depth)
400
+
401
+ return healpix_geo.nested.zone_coverage(depth, bbox, ellipsoid=ellipsoid, flat=flat)
402
+
403
+
404
+ def box_coverage(center, size, angle, depth, *, ellipsoid="sphere", flat=True):
405
+ """Search the cells covering the given box.
406
+
407
+ Parameters
408
+ ----------
409
+ center : numpy.ndarray or tuple of float
410
+ The center of the box, either as a 2-sized array or as a 2-tuple of float.
411
+ size : numpy.ndarray or tuple of float
412
+ The size of the box, in degree.
413
+ angle : float
414
+ The angle by which the box is rotated, in degree.
415
+ depth : int
416
+ The maximum depth of the cells to be returned.
417
+ ellipsoid : ellipsoid-like, default: "sphere"
418
+ Reference ellipsoid to evaluate healpix on.
419
+ flat : bool, default: True
420
+ If ``True``, the cells returned will all be at the passed depth.
421
+
422
+ Returns
423
+ -------
424
+ cell_ids : numpy.ndarray
425
+ The rasterized cell ids.
426
+ depths : numpy.ndarray
427
+ The depths of the cell ids. If ``flat is True``, these will all have the same value.
428
+ fully_covered : numpy.ndarray
429
+ Boolean array marking whether the cells are fully covered by the box.
430
+ """
431
+ _check_depth(depth)
432
+
433
+ if not isinstance(center, tuple):
434
+ center = tuple(center)
435
+ if not isinstance(size, tuple):
436
+ size = tuple(size)
437
+
438
+ return healpix_geo.nested.box_coverage(
439
+ depth, center, size, angle, ellipsoid=ellipsoid, flat=flat
440
+ )
441
+
442
+
443
+ def polygon_coverage(vertices, depth, *, ellipsoid="sphere", flat=True):
444
+ """Search the cells covering the given polygon.
445
+
446
+ Parameters
447
+ ----------
448
+ vertices : numpy.ndarray
449
+ The vertices of the polygon without holes. Must be an array of shape ``(n, 2)``.
450
+ depth : int
451
+ The maximum depth of the cells to be returned.
452
+ ellipsoid : ellipsoid-like, default: "sphere"
453
+ Reference ellipsoid to evaluate healpix on. If the reference ellipsoid
454
+ is spherical, this will return the same result as
455
+ :py:func:`cdshealpix.nested.polygon_search`.
456
+ flat : bool, default: True
457
+ If ``True``, the cells returned will all be at the passed depth.
458
+
459
+ Returns
460
+ -------
461
+ cell_ids : numpy.ndarray
462
+ The rasterized cell ids.
463
+ depths : numpy.ndarray
464
+ The depths of the cell ids. If ``flat is True``, these will all have the same value.
465
+ fully_covered : numpy.ndarray
466
+ Boolean array marking whether the cells are fully covered by the polygon.
467
+ """
468
+ _check_depth(depth)
469
+
470
+ return healpix_geo.nested.polygon_coverage(
471
+ depth, vertices, ellipsoid=ellipsoid, flat=flat
472
+ )
473
+
474
+
475
+ def cone_coverage(
476
+ center, radius, depth, *, delta_depth=0, ellipsoid="sphere", flat=True
477
+ ):
478
+ """Search the cells covering the given cone
479
+
480
+ Cone in this case means a circle on the surface of the reference ellipsoid.
481
+
482
+ Parameters
483
+ ----------
484
+ center : numpy.ndarray or tuple of float
485
+ The center of the box, either as a 2-sized array or as a 2-tuple of float.
486
+ radius : float
487
+ The radius of the cone, in degree.
488
+ depth : int
489
+ The maximum depth of the cells to be returned.
490
+ ellipsoid : ellipsoid-like, default: "sphere"
491
+ Reference ellipsoid to evaluate healpix on. If the reference ellipsoid
492
+ is spherical, this will return the same result as
493
+ :py:func:`cdshealpix.nested.cone_search`.
494
+ flat : bool, default: True
495
+ If ``True``, the cells returned will all be at the passed depth.
496
+
497
+ Returns
498
+ -------
499
+ cell_ids : numpy.ndarray
500
+ The rasterized cell ids.
501
+ depths : numpy.ndarray
502
+ The depths of the cell ids. If ``flat is True``, these will all have the same value.
503
+ fully_covered : numpy.ndarray
504
+ Boolean array marking whether the cells are fully covered by the circle.
505
+ """
506
+ _check_depth(depth)
507
+
508
+ if not isinstance(center, tuple):
509
+ center = tuple(center)
510
+
511
+ return healpix_geo.nested.cone_coverage(
512
+ depth, center, radius, delta_depth=delta_depth, ellipsoid=ellipsoid, flat=flat
513
+ )
514
+
515
+
516
+ def elliptical_cone_coverage(
517
+ center,
518
+ ellipse_geometry,
519
+ position_angle,
520
+ depth,
521
+ *,
522
+ delta_depth=0,
523
+ ellipsoid="sphere",
524
+ flat=True,
525
+ ):
526
+ """Search the cells covering the given elliptical cone.
527
+
528
+ Elliptical cone in this case refers to an ellipse on the surface of the reference ellipsoid.
529
+
530
+ Parameters
531
+ ----------
532
+ center : numpy.ndarray or tuple of float
533
+ The center of the box, either as a 2-sized array or as a 2-tuple of float.
534
+ ellipse_geometry : numpy.ndarray or tuple of float
535
+ The semimajor and semimajor axis, as a 2-sized array or as a 2-tuple of float.
536
+ position_angle : float
537
+ The orientation of the ellipse.
538
+ depth : int
539
+ The maximum depth of the cells to be returned.
540
+ ellipsoid : ellipsoid-like, default: "sphere"
541
+ Reference ellipsoid to evaluate healpix on. If the reference ellipsoid
542
+ is spherical, this will return the same result as
543
+ :py:func:`cdshealpix.nested.elliptical_cone_search`.
544
+ flat : bool, default: True
545
+ If ``True``, the cells returned will all be at the passed depth.
546
+
547
+ Returns
548
+ -------
549
+ cell_ids : numpy.ndarray
550
+ The rasterized cell ids.
551
+ depths : numpy.ndarray
552
+ The depths of the cell ids. If ``flat is True``, these will all have the same value.
553
+ fully_covered : numpy.ndarray
554
+ Boolean array marking whether the cells are fully covered by the ellipse.
555
+ """
556
+ _check_depth(depth)
557
+
558
+ if not isinstance(center, tuple):
559
+ center = tuple(center)
560
+ if not isinstance(ellipse_geometry, tuple):
561
+ ellipse_geometry = tuple(ellipse_geometry)
562
+
563
+ return healpix_geo.nested.elliptical_cone_coverage(
564
+ depth,
565
+ center,
566
+ ellipse_geometry,
567
+ position_angle,
568
+ delta_depth=delta_depth,
569
+ ellipsoid=ellipsoid,
570
+ flat=flat,
571
+ )