torchsky.sphere.healpix¶
Stability: core. Names on this page follow the deprecation policy in contributing.
The torch-native HEALPix kernels: indexing, neighbors, interpolation, queries, reordering, and map sampling. These functions accept and return PyTorch tensors.
Guides: healpix
This page is generated from the module source. Import these names from
torchsky.sphere.healpix.
Module¶
torchsky.sphere.healpix ¶
__all__
module-attribute
¶
__all__ = [
"UNSEEN",
"ang2pix",
"ang2pix_nested",
"ang2pix_ring",
"ang2vec",
"angular_distance_deg",
"boundaries",
"compact_bits",
"degrade_pixels",
"degrade_pixel_ranges",
"get_all_neighbours",
"get_interp_val",
"get_interp_weights",
"get_map_size",
"get_nside",
"isnpixok",
"isnsideok",
"lonlat_to_xyz",
"mask_bad",
"max_pixel_radius",
"neighbors",
"nest2ring",
"nest_children",
"nest_parent",
"npix2nside",
"nside2npix",
"nside2order",
"nside2pixarea",
"nside2resol",
"order2nside",
"pixel_ranges_to_pixels",
"pixel_resolution_to_nside",
"pixels_to_pixel_ranges",
"pix2ang",
"pix2ang_nested",
"pix2ang_ring",
"pix2vec",
"query_box",
"query_circle",
"query_circle_vec",
"query_disc",
"query_polygon",
"query_polygon_vec",
"query_strip",
"reorder",
"ring2nest",
"spread_bits",
"ud_grade",
"upgrade_pixels",
"upgrade_pixel_ranges",
"vec2ang",
"vec2pix",
"xyz_to_lonlat",
]
_ud_grade_core_nested ¶
_ud_grade_core_nested(
m_nest: Tensor,
nside_out: int,
*,
pess: bool = False,
power: float | None = None,
badval: float = UNSEEN,
) -> Tensor
ang2pix ¶
ang2pix(
nside: int,
theta: Tensor | float,
phi: Tensor | float,
nest: bool = False,
lonlat: bool = False,
) -> Tensor
Convert angles to pixel indices.
If lonlat is False, inputs are (theta, phi) in radians with theta=colatitude. If lonlat is True, inputs are (lon, lat) in degrees.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nside
|
int
|
HEALPix resolution parameter. |
required |
theta
|
Tensor | float
|
Colatitude in radians, or longitude in degrees with |
required |
phi
|
Tensor | float
|
Longitude in radians, or latitude in degrees with |
required |
nest
|
bool
|
Use nested rather than ring ordering. |
False
|
lonlat
|
bool
|
Interpret inputs as longitude and latitude in degrees. |
False
|
Returns:
| Type | Description |
|---|---|
Tensor
|
Integer HEALPix indices with the broadcast input shape. |
Examples:
>>> import torch
>>> from torchsky.sphere import ang2pix
>>> ang2pix(1, torch.tensor([0.0]), torch.tensor([0.0]), lonlat=True).shape
torch.Size([1])
ang2pix_nested ¶
ang2pix_nested(
nside: int, ra: Tensor, dec: Tensor
) -> Tensor
Convert RA/Dec (degrees) to HEALPix NESTED indices.
ang2pix_ring ¶
ang2pix_ring(nside: int, ra: Tensor, dec: Tensor) -> Tensor
Convert RA/Dec (degrees) to HEALPix RING indices.
ang2vec ¶
ang2vec(
theta: Tensor | float,
phi: Tensor | float,
lonlat: bool = False,
) -> Tensor
Convert angles to unit vectors.
If lonlat=False, input is (theta, phi) in radians with theta=colatitude. If lonlat=True, input is (lon, lat) in degrees. Returns vectors with last dimension 3.
angular_distance_deg ¶
angular_distance_deg(
ra1: Tensor, dec1: Tensor, ra2: Tensor, dec2: Tensor
) -> Tensor
Great-circle angular distance between two lon/lat points in degrees.
boundaries ¶
boundaries(
nside: int,
pix: Tensor,
step: int = 1,
nest: bool = False,
) -> Tensor
Return pixel boundary points as Cartesian vectors.
Output shape:
- scalar pix: (3, 4step)
- 1D pix: (Npix, 3, 4step)
degrade_pixel_ranges ¶
degrade_pixel_ranges(
nside: int,
pixel_ranges: Tensor | Sequence[Sequence[int]],
nside_degrade: int,
) -> Tensor
Degrade NESTED pixel ranges from nside to nside_degrade.
Half-open child ranges [start, stop) map to every parent pixel touched by at least one child. Output ranges are sorted, disjoint, and half-open.
degrade_pixels ¶
degrade_pixels(
nside: int,
pixels: Tensor | Sequence[int],
nside_degrade: int,
*,
nest: bool = False,
) -> Tensor
Degrade explicit HEALPix pixel ids to a coarser resolution.
Every parent pixel touched by at least one input child is returned. Duplicates are removed and output is sorted in the requested output ordering.
get_all_neighbours ¶
get_all_neighbours(
nside: int,
theta: Tensor | float | int,
phi: Tensor | float | None = None,
nest: bool = False,
lonlat: bool = False,
) -> Tensor
Healpy-compatible neighbors API.
If phi is None, theta is interpreted as pixel index. Otherwise,
(theta, phi) are interpreted as angular coordinates.
get_interp_val ¶
get_interp_val(
m: Tensor | list[float],
theta: Tensor | float,
phi: Tensor | float,
nest: bool = False,
lonlat: bool = False,
) -> Tensor
Healpy-compatible bilinear interpolation of map values.
m can be shape (npix,) or (nmaps, npix).
get_interp_weights ¶
get_interp_weights(
nside: int,
theta: Tensor | float | int,
phi: Tensor | float | None = None,
nest: bool = False,
lonlat: bool = False,
) -> tuple[Tensor, Tensor]
Healpy-compatible bilinear interpolation neighbors and weights.
Returns (pixels, weights) with shape (4, ...).
get_map_size ¶
get_map_size(
m: Tensor | Sequence[float] | Sequence[Sequence[float]],
) -> int
Return map size (npix) for a map input.
get_nside ¶
get_nside(
m: Tensor | Sequence[float] | Sequence[Sequence[float]],
) -> int
Return NSIDE from a map (shape (npix,) or (nmaps, npix)).
isnpixok ¶
isnpixok(npix: Tensor | int | list[int]) -> bool | Tensor
Check whether NPIX values are valid HEALPix sizes.
Returns bool for scalar input and bool tensor for array-like input.
isnsideok ¶
isnsideok(
nside: Tensor | int | list[int], nest: bool = False
) -> bool | Tensor
Check whether NSIDE values are valid.
Returns bool for scalar input and bool tensor for array-like input.
lonlat_to_xyz ¶
lonlat_to_xyz(
ra: Tensor, dec: Tensor
) -> Tuple[Tensor, Tensor, Tensor]
Convert spherical lon/lat in degrees to unit Cartesian coordinates.
mask_bad ¶
mask_bad(
m: Tensor | float,
badval: float = UNSEEN,
rtol: float = 1e-05,
atol: float = 1e-08,
) -> Tensor
Boolean mask for bad (UNSEEN/non-finite) map values.
max_pixel_radius ¶
max_pixel_radius(
nside: int, degrees: bool = False
) -> float
Return a conservative maximum center-to-corner radius for pixels at nside.
Uses representative polar/equatorial/southern pixels and caches result.
neighbors ¶
neighbors(
nside: int, ipix: Tensor | int, nest: bool = False
) -> Tensor
Return 8 neighbors (SW, W, NW, N, NE, E, SE, S) for input pixels.
Output shape is ipix.shape + (8,) for array inputs and (8,) for scalars.
Missing neighbors are set to -1.
nest_children ¶
nest_children(pix_nest: Tensor, levels: int = 1) -> Tensor
Return all NESTED children after increasing resolution by levels.
nest_parent ¶
nest_parent(pix_nest: Tensor, levels: int = 1) -> Tensor
Return NESTED parent index after reducing resolution by levels.
nside2order ¶
nside2order(nside: int) -> int
Return HEALPix order for a given NSIDE (order = log2(nside)).
nside2pixarea ¶
nside2pixarea(nside: int, degrees: bool = False) -> float
Return pixel area for a given NSIDE.
nside2resol ¶
nside2resol(nside: int, arcmin: bool = False) -> float
Return approximate resolution (sqrt pixel area).
order2nside ¶
order2nside(order: int) -> int
Return NSIDE for a given HEALPix order (nside = 2**order).
pix2ang ¶
pix2ang(
nside: int,
ipix: Tensor,
nest: bool = False,
lonlat: bool = False,
) -> Tuple[Tensor, Tensor]
Convert pixel indices to angles.
If lonlat is False, returns (theta, phi) in radians with theta=colatitude. If lonlat is True, returns (lon, lat) in degrees.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nside
|
int
|
HEALPix resolution parameter. |
required |
ipix
|
Tensor
|
Integer pixel indices. |
required |
nest
|
bool
|
Use nested rather than ring ordering. |
False
|
lonlat
|
bool
|
Return longitude and latitude in degrees. |
False
|
Returns:
| Type | Description |
|---|---|
Tuple[Tensor, Tensor]
|
Two tensors containing angular coordinates. |
Examples:
>>> import torch
>>> from torchsky.sphere import pix2ang
>>> lon, lat = pix2ang(1, torch.tensor([0]), lonlat=True)
>>> lon.shape == lat.shape
True
pix2ang_nested ¶
pix2ang_nested(
nside: int, pix: Tensor
) -> Tuple[Tensor, Tensor]
Convert HEALPix NESTED indices to RA/Dec (degrees).
pix2ang_ring ¶
pix2ang_ring(
nside: int, pix: Tensor
) -> Tuple[Tensor, Tensor]
Convert HEALPix RING indices to RA/Dec (degrees).
pix2vec ¶
pix2vec(
nside: int, ipix: Tensor, nest: bool = False
) -> Tuple[Tensor, Tensor, Tensor]
Convert pixel indices to Cartesian vectors.
pixel_ranges_to_pixels ¶
pixel_ranges_to_pixels(
pixel_ranges: Tensor | Sequence[Sequence[int]],
*,
inclusive: bool = False,
) -> Tensor
Expand pixel ranges into explicit pixels.
Range semantics match hpgeom.pixel_ranges_to_pixels:
- inclusive=False: each row is [start, stop) (half-open)
- inclusive=True: each row is [start, stop] (closed)
pixel_resolution_to_nside ¶
pixel_resolution_to_nside(
resolution: float,
*,
degrees: bool = False,
arcmin: bool = False,
round_to_power_of_two: bool = True,
) -> int
Approximate NSIDE from angular resolution.
pixels_to_pixel_ranges ¶
pixels_to_pixel_ranges(
pixels: Tensor | Sequence[int],
) -> Tensor
Compress explicit pixels into sorted disjoint half-open ranges [start, stop).
Unlike hpgeom, this helper is torchsky-native and canonicalizes by
sorting + deduplicating input pixels before range construction.
query_box ¶
query_box(
nside: int,
lon_min: float,
lat_min: float,
lon_max: float,
lat_max: float,
*,
nest: bool = False,
inclusive: bool = False,
chunk_size: int = 1000000,
) -> Tensor
Return pixels whose centers lie in lon/lat box (degrees). Handles longitude wrap-around.
Uses a latitude (colatitude) ring preselect via query_strip, then applies
the longitude filter only on that band — typically far cheaper than scanning all
npix pixels when the declination range is narrow.
query_circle ¶
query_circle(
nside: int,
lon: Tensor | float,
lat: Tensor | float,
radius: float,
*,
degrees: bool = True,
inclusive: bool = False,
fact: int = 4,
nest: bool = False,
chunk_size: int = 1000000,
) -> Tensor
Lon/lat convenience wrapper around query_disc.
query_circle_vec ¶
query_circle_vec(
nside: int,
vec: Tensor | Sequence[float],
radius: float,
*,
inclusive: bool = False,
fact: int = 4,
nest: bool = False,
chunk_size: int = 1000000,
) -> Tensor
Cartesian-vector convenience wrapper around query_disc.
query_disc ¶
query_disc(
nside: int,
vec: Tensor | Sequence[float],
radius: float,
*,
inclusive: bool = False,
fact: int = 4,
nest: bool = False,
chunk_size: int = 1000000,
) -> Tensor
Return pixels whose centers fall in a spherical disc.
vec is a 3-vector (x, y, z); radius is in radians.
If inclusive=True and fact==4 (healpy default), pad the radius by the
maximum pixel radius. If inclusive=True and fact!=4, supersample at
nside * fact (pad at the fine nside), then degrade to parent pixels —
healpy-shaped inclusive overlap. fact is ignored when inclusive=False.
Performance: when the C++ extension is available on CPU (or CUDA via a host
copy of vec), queries use ring pruning (O(nside + output)).
Without the extension, and on MPS, a torch quadtree descent selects the same
pixel centres in O(boundary cells x depth + output), never O(npix).
CUDA copies a length-3 vec to host; that copy is O(1) and far below 10%
of nside≥512 wall, so the query stays on the CPU kernel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nside
|
int
|
HEALPix resolution parameter. |
required |
vec
|
Tensor | Sequence[float]
|
Cartesian unit vector at the disc center. |
required |
radius
|
float
|
Angular radius in radians. |
required |
inclusive
|
bool
|
Include pixels overlapping the disc boundary. |
False
|
fact
|
int
|
Oversampling factor for inclusive queries. |
4
|
nest
|
bool
|
Return nested rather than ring indices. |
False
|
chunk_size
|
int
|
Accepted for API compatibility; unused. |
1000000
|
Returns:
| Type | Description |
|---|---|
Tensor
|
One-dimensional integer tensor of matching pixels. |
Examples:
>>> from torchsky.sphere import query_disc
>>> query_disc(1, [1.0, 0.0, 0.0], 0.1).ndim
1
query_polygon ¶
query_polygon(
nside: int,
vertices: Tensor
| Sequence[Sequence[float]]
| Sequence[float],
lat_deg: Tensor | Sequence[float] | None = None,
*,
inclusive: bool = False,
nest: bool = False,
lonlat: bool = False,
chunk_size: int = 1000000,
) -> Tensor
Return pixels with centers inside a spherical polygon.
Convex polygons use the direct half-space query. Concave simple polygons are
triangulated by :func:torchsky.sphere.geom.query_polygon_general.
Accepts either:
- query_polygon(nside, lon_deg, lat_deg, ...) (1D degree sequences/tensors)
- query_polygon(nside, vertices, lonlat=True, ...) with shape (N, 2) or (2, N)
- query_polygon(nside, vertices, lonlat=False, ...) with Cartesian shape (N, 3) or (3, N)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nside
|
int
|
HEALPix resolution parameter. |
required |
vertices
|
Tensor | Sequence[Sequence[float]] | Sequence[float]
|
Longitude samples or two-/three-dimensional polygon vertices. |
required |
lat_deg
|
Tensor | Sequence[float] | None
|
Latitude samples for the separate longitude/latitude form. |
None
|
inclusive
|
bool
|
Include pixels overlapping the polygon boundary. |
False
|
nest
|
bool
|
Return nested rather than ring indices. |
False
|
lonlat
|
bool
|
Interpret paired vertices as degrees rather than Cartesian vectors. |
False
|
chunk_size
|
int
|
Pixel chunk size for the tensor fallback. |
1000000
|
Returns:
| Type | Description |
|---|---|
Tensor
|
One-dimensional integer tensor of matching pixels. |
Examples:
>>> from torchsky.sphere import query_polygon
>>> callable(query_polygon)
True
query_polygon_vec ¶
query_polygon_vec(
nside: int,
vertices: Tensor | Sequence[Sequence[float]],
*,
inclusive: bool = False,
nest: bool = False,
chunk_size: int = 1000000,
) -> Tensor
Cartesian-vector convenience wrapper around query_polygon.
query_strip ¶
query_strip(
nside: int,
theta1: float,
theta2: float,
*,
nest: bool = False,
inclusive: bool = False,
) -> Tensor
Return pixels with center colatitude in [theta1, theta2] (radians).
Uses ring pruning (O(nside + output)), not a full O(npix) map scan.
reorder ¶
reorder(
m: Tensor, *, r2n: bool = False, n2r: bool = False
) -> Tensor
Reorder HEALPix maps between RING and NESTED layouts along the last axis.
spherical_fourier_features ¶
spherical_fourier_features(
ra: Tensor,
dec: Tensor,
num_frequencies: int = 6,
min_frequency: float = 1.0,
base: float = 2.0,
include_xyz: bool = True,
include_lonlat: bool = True,
) -> Tensor
Build multi-scale periodic features for spherical positional encoders.
Output shape is ra.shape + (D,), where:
- xyz block contributes 3 channels if include_xyz=True
- each frequency contributes 12 channels for xyz sin/cos (if enabled)
- each frequency contributes 4 channels for lon/lat sin/cos (if enabled)
ud_grade ¶
ud_grade(
map_in: Tensor
| Sequence[float]
| Sequence[Sequence[float]],
nside_out: int,
pess: bool = False,
badval: float = UNSEEN,
order_in: str = "RING",
order_out: str | None = None,
power: float | None = None,
dtype: object | None = None,
) -> Tensor
Upgrade or degrade resolution of HEALPix map(s), healpy-compatible shape semantics.
Supports map input shapes (npix,) and (nmaps, npix).
upgrade_pixel_ranges ¶
upgrade_pixel_ranges(
nside: int,
pixel_ranges: Tensor | Sequence[Sequence[int]],
nside_upgrade: int,
) -> Tensor
Upgrade NESTED pixel ranges from nside to nside_upgrade.
Semantics match hpgeom.upgrade_pixel_ranges, where half-open ranges
[start, stop) scale by 4**levels.
upgrade_pixels ¶
upgrade_pixels(
nside: int,
pixels: Tensor | Sequence[int],
nside_upgrade: int,
*,
nest: bool = False,
) -> Tensor
Upgrade explicit HEALPix pixel ids to a finer resolution.
Each input pixel expands to all child pixels at nside_upgrade. Duplicates are
removed and output is sorted in the requested output ordering.
vec2ang ¶
vec2ang(
vectors: Tensor | Sequence[Sequence[float]],
lonlat: bool = False,
) -> Tuple[Tensor, Tensor]
Convert vectors to angles.
Accepts shape (..., 3) or (3, ...). If lonlat=False returns (theta, phi) in radians, otherwise returns (lon, lat) in degrees.
vec2pix ¶
vec2pix(
nside: int,
x: Tensor,
y: Tensor,
z: Tensor,
nest: bool = False,
) -> Tensor
Convert Cartesian vectors to pixel indices.
xyz_to_lonlat ¶
xyz_to_lonlat(
x: Tensor, y: Tensor, z: Tensor, eps: float = 1e-15
) -> Tuple[Tensor, Tensor]
Convert Cartesian coordinates to lon/lat in degrees.