Skip to content

torchsky.sphere

Stability: core. Names on this page follow the deprecation policy in contributing.

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Guides: healpix, sht, moc


This reference is generated from the package source. Names are grouped by the module that defines them; import every name from the public namespace torchsky.sphere unless the group text says otherwise.

Core

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

fit_monopole_dipole

fit_monopole_dipole(
    map_values: Tensor,
    nside: int,
    *,
    nest: bool = False,
    valid_mask: Tensor | None = None,
) -> tuple[Tensor, Tensor]

Fit monopole+dipole model to a HEALPix map.

Model: m(pix) = a + d_xx + d_yy + d_z*z Returns (monopole, dipole_xyz).

great_circle_distance

great_circle_distance(
    lon1_deg: Tensor | float,
    lat1_deg: Tensor | float,
    lon2_deg: Tensor | float,
    lat2_deg: Tensor | float,
    *,
    degrees: bool = True,
) -> Tensor

Return great-circle angular distance using a numerically stable atan2 formulation.

lonlat_to_unit_xyz

lonlat_to_unit_xyz(
    lon_deg: Tensor | float, lat_deg: Tensor | float
) -> Tensor

Convert longitude/latitude in degrees to unit Cartesian vectors [..., 3].

pairwise_angular_distance

pairwise_angular_distance(
    lon_deg: Tensor,
    lat_deg: Tensor,
    *,
    degrees: bool = True,
) -> Tensor

Pairwise angular distance matrix for N sky positions.

Inputs are 1D tensors of shape [N]. Output has shape [N, N].

remove_monopole_dipole

remove_monopole_dipole(
    map_values: Tensor,
    nside: int,
    *,
    nest: bool = False,
    valid_mask: Tensor | None = None,
) -> Tensor

Subtract fitted monopole+dipole model from a HEALPix map.

sample_healpix_map

sample_healpix_map(
    values: Tensor,
    nside: int,
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    nest: bool = False,
    interpolation: Literal[
        "nearest", "bilinear"
    ] = "bilinear",
) -> Tensor

Sample HEALPix maps on arbitrary sky coordinates.

values shape is [..., npix], output shape is [..., *coord_shape].

sample_map

sample_map(
    values: Tensor,
    nside_or_lon: int | Tensor | float,
    lon_or_lat: Tensor | float,
    lat_deg: Tensor | float | None = None,
    *,
    nside: int | None = None,
    nest: bool = False,
    interpolation: Literal[
        "nearest", "bilinear"
    ] = "bilinear",
    source_wavelength: Tensor | list[float] | None = None,
    target_wavelength: Tensor | list[float] | None = None,
) -> Tensor

Unified HEALPix map / multiband / multiwavelength sampler.

Supports both sample_map(values, lon_deg, lat_deg, ...) (inferring nside from values.shape[-1]) and sample_map(values, nside, lon_deg, lat_deg, ...).

sample_multiband_healpix

sample_multiband_healpix(
    cube: Tensor,
    nside: int,
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    nest: bool = False,
    interpolation: Literal[
        "nearest", "bilinear"
    ] = "bilinear",
) -> Tensor

Sample multi-band HEALPix cube with shape [..., n_band, npix].

Output has shape [..., n_band, *coord_shape].

sample_multiwavelength_healpix

sample_multiwavelength_healpix(
    cube: Tensor,
    nside: int,
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    source_wavelength: Tensor | list[float] | None = None,
    target_wavelength: Tensor | list[float] | None = None,
    nest: bool = False,
    interpolation: Literal[
        "nearest", "bilinear"
    ] = "bilinear",
) -> Tensor

Sample a multiwavelength HEALPix cube and optionally resample wavelengths.

cube shape: [..., n_wave, npix] Output shape without resampling: [..., n_wave, *coord_shape]

slerp_lonlat

slerp_lonlat(
    lon1_deg: Tensor | float,
    lat1_deg: Tensor | float,
    lon2_deg: Tensor | float,
    lat2_deg: Tensor | float,
    t: Tensor | float,
) -> tuple[Tensor, Tensor]

Spherical linear interpolation between two positions.

t=0 returns the start point, t=1 returns the end point.

unit_xyz_to_lonlat

unit_xyz_to_lonlat(
    vectors: Tensor, *, wrap_center_deg: float = 180.0
) -> tuple[Tensor, Tensor]

Convert unit Cartesian vectors [..., 3] to longitude/latitude in degrees.

wrap_longitude

wrap_longitude(
    lon_deg: Tensor | float, *, center_deg: float = 180.0
) -> Tensor

Wrap longitudes into [center_deg - 180, center_deg + 180).

Examples: - center_deg=180 -> [0, 360) - center_deg=0 -> [-180, 180)

Geom

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

ExactSphericalRegion dataclass

ExactSphericalRegion(_sg_poly: Any)

Exact spherical region wrapper backed by optional spherical-geometry.

_sg_poly instance-attribute

_sg_poly: Any

is_empty property

is_empty: bool

area

area(*, degrees: bool = False) -> float

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
) -> Tensor

difference

difference(
    other: RegionOperand, *, cap_steps: int = 256
) -> "ExactSphericalRegion"

intersection

intersection(
    other: RegionOperand, *, cap_steps: int = 256
) -> "ExactSphericalRegion"

intersects

intersects(
    other: RegionOperand, *, cap_steps: int = 256
) -> bool

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

to_multipolygon

to_multipolygon() -> SphericalMultiPolygon

union

union(
    other: RegionOperand, *, cap_steps: int = 256
) -> "ExactSphericalRegion"

LonLat dataclass

LonLat(lon: float, lat: float)

Spherical coordinates in degrees.

lat instance-attribute

lat: float

lon instance-attribute

lon: float

to_unit_xyz

to_unit_xyz() -> 'UnitVector3d'

NativeApproximateSphericalRegion dataclass

NativeApproximateSphericalRegion(
    _region: RegionOperand,
    _nsides: tuple[int, ...] = (256, 512, 1024, 2048),
)

Torch-native region wrapper with explicit center-sampled approximations.

Analytic area and emptiness are used where available. Unsupported exact predicates fail closed; area_estimate is the explicit HEALPix-center approximation. spherical-geometry remains the opt-in exact backend.

_nsides class-attribute instance-attribute

_nsides: tuple[int, ...] = (256, 512, 1024, 2048)

_region instance-attribute

_region: RegionOperand

is_empty property

is_empty: bool

_analytic_area_sr

_analytic_area_sr() -> float

area

area(*, degrees: bool = False) -> float

area_estimate

area_estimate() -> RegionAreaEstimate

contains

contains(
    lon_deg: Tensor | float, lat_deg: Tensor | float
) -> Tensor

difference

difference(
    other: RegionOperand,
) -> "NativeApproximateSphericalRegion"

intersection

intersection(
    other: RegionOperand,
) -> "NativeApproximateSphericalRegion"

intersects

intersects(other: RegionOperand) -> bool

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

to_multipolygon

to_multipolygon() -> SphericalMultiPolygon

union

union(
    other: RegionOperand,
) -> "NativeApproximateSphericalRegion"

PixelizedRegion dataclass

PixelizedRegion(nside: int, nest: bool, pixels: Tensor)

Pixelized spherical region with set-like boolean operations.

nest instance-attribute

nest: bool

nside instance-attribute

nside: int

pixels instance-attribute

pixels: Tensor

__post_init__

__post_init__() -> None

_check_compatible

_check_compatible(other: 'PixelizedRegion') -> None

area

area(*, degrees: bool = False) -> float

difference

difference(other: 'PixelizedRegion') -> 'PixelizedRegion'

intersection

intersection(other: 'PixelizedRegion') -> 'PixelizedRegion'

union

union(other: 'PixelizedRegion') -> 'PixelizedRegion'

RegionAreaEstimate dataclass

RegionAreaEstimate(
    area_sr: float,
    area_deg2: float,
    nside: int,
    pixels: int,
    convergence_rel: float | None,
    area_by_nside_sr: dict[str, float],
    pixels_by_nside: dict[str, int],
)

Controlled-error area estimate summary over a multi-resolution nside ladder.

area_by_nside_sr instance-attribute

area_by_nside_sr: dict[str, float]

area_deg2 instance-attribute

area_deg2: float

area_sr instance-attribute

area_sr: float

convergence_rel instance-attribute

convergence_rel: float | None

nside instance-attribute

nside: int

pixels instance-attribute

pixels: int

pixels_by_nside instance-attribute

pixels_by_nside: dict[str, int]

SphericalBooleanRegion dataclass

SphericalBooleanRegion(
    op: Literal["union", "intersection", "difference"],
    left: RegionOperand,
    right: RegionOperand,
)

Boolean composition of spherical regions with controlled-error HEALPix evaluation.

left instance-attribute

left: RegionOperand

op instance-attribute

op: Literal['union', 'intersection', 'difference']

right instance-attribute

right: RegionOperand

__post_init__

__post_init__() -> None

area

area(*, degrees: bool = False) -> float

Exact area of the combination (steradians unless degrees=True).

Defined when every operand is a SphericalPolygon or SphericalMultiPolygon (great-circle edges): the result's boundary is clipped from the operands' edges and integrated exactly. Operands with small-circle boundaries (caps, boxes, ellipses) raise ValueError; use area_estimate() for those.

area_estimate

area_estimate(
    *,
    nsides: tuple[int, ...] | list[int] = (
        128,
        256,
        512,
        1024,
    ),
    nest: bool = False,
) -> RegionAreaEstimate

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
) -> Tensor

difference

difference(
    other: RegionOperand,
) -> "SphericalBooleanRegion"

exact_area

exact_area(
    *,
    degrees: bool = False,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> float

Exact area; native is :meth:area, spherical-geometry is opt-in.

intersection

intersection(
    other: RegionOperand,
) -> "SphericalBooleanRegion"

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

to_exact

to_exact(
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | NativeApproximateSphericalRegion"

union

union(other: RegionOperand) -> 'SphericalBooleanRegion'

SphericalBox dataclass

SphericalBox(
    lon_min: float,
    lon_max: float,
    lat_min: float,
    lat_max: float,
)

Longitude/Latitude angle box.

lat_max instance-attribute

lat_max: float

lat_min instance-attribute

lat_min: float

lon_max instance-attribute

lon_max: float

lon_min instance-attribute

lon_min: float

__post_init__

__post_init__() -> None

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
) -> Tensor

difference

difference(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

intersection

intersection(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

union

union(other: 'RegionOperand') -> 'SphericalBooleanRegion'

SphericalCap dataclass

SphericalCap(
    lon_deg: float, lat_deg: float, radius_deg: float
)

Spherical cap centered at (lon, lat) with angular radius in degrees.

lat_deg instance-attribute

lat_deg: float

lon_deg instance-attribute

lon_deg: float

radius_deg instance-attribute

radius_deg: float

__post_init__

__post_init__() -> None

area

area(*, degrees: bool = False) -> float

Exact cap area 2 pi (1 - cos r).

area_estimate

area_estimate(
    *,
    nsides: tuple[int, ...] | list[int] = (
        128,
        256,
        512,
        1024,
    ),
    nest: bool = False,
) -> RegionAreaEstimate

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 0.0,
) -> Tensor

difference

difference(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

exact_difference

exact_difference(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact difference; native returns a region whose area() is exact.

exact_intersection

exact_intersection(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact intersection; native returns a region whose area() is exact.

exact_union

exact_union(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact union; native returns a region whose area() is exact.

intersection

intersection(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

to_exact

to_exact(
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | NativeApproximateSphericalRegion"

union

union(other: 'RegionOperand') -> 'SphericalBooleanRegion'

SphericalEllipse dataclass

SphericalEllipse(
    lon_deg: float,
    lat_deg: float,
    semi_major_deg: float,
    semi_minor_deg: float,
    pa_deg: float = 0.0,
)

Spherical ellipse.

lat_deg instance-attribute

lat_deg: float

lon_deg instance-attribute

lon_deg: float

pa_deg class-attribute instance-attribute

pa_deg: float = 0.0

semi_major_deg instance-attribute

semi_major_deg: float

semi_minor_deg instance-attribute

semi_minor_deg: float

__post_init__

__post_init__() -> None

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
) -> Tensor

difference

difference(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

intersection

intersection(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

union

union(other: 'RegionOperand') -> 'SphericalBooleanRegion'

SphericalMultiPolygon dataclass

SphericalMultiPolygon(
    polygons: tuple[SphericalPolygon, ...],
)

Collection of spherical polygons with boolean-style predicates.

polygons instance-attribute

polygons: tuple[SphericalPolygon, ...]

__post_init__

__post_init__() -> None

area

area(
    *, degrees: bool = False, oriented: bool = False
) -> Tensor

Area of the union of the members (overlaps count once).

oriented=True returns the sum of the members' signed areas instead.

area_estimate

area_estimate(
    *,
    nsides: tuple[int, ...] | list[int] = (
        128,
        256,
        512,
        1024,
    ),
    nest: bool = False,
) -> RegionAreaEstimate

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
) -> Tensor

difference

difference(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

exact_difference

exact_difference(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact difference; native returns a region whose area() is exact.

exact_intersection

exact_intersection(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact intersection; native returns a region whose area() is exact.

exact_union

exact_union(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact union; native returns a region whose area() is exact.

intersection

intersection(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

intersects

intersects(
    other: "SphericalPolygon | SphericalMultiPolygon",
    *,
    atol_deg: float = 1e-08,
) -> bool

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

to_exact

to_exact(
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | NativeApproximateSphericalRegion"

union

union(other: 'RegionOperand') -> 'SphericalBooleanRegion'

SphericalPolygon dataclass

SphericalPolygon(
    lon_deg: Tensor,
    lat_deg: Tensor,
    inside_lon_deg: float | None = None,
    inside_lat_deg: float | None = None,
)

Simple spherical polygon with signed-area and containment contracts.

inside_lat_deg class-attribute instance-attribute

inside_lat_deg: float | None = None

inside_lon_deg class-attribute instance-attribute

inside_lon_deg: float | None = None

lat_deg instance-attribute

lat_deg: Tensor

lon_deg instance-attribute

lon_deg: Tensor

__post_init__

__post_init__() -> None

area

area(
    *, degrees: bool = False, oriented: bool = False
) -> Tensor

area_estimate

area_estimate(
    *,
    nsides: tuple[int, ...] | list[int] = (
        128,
        256,
        512,
        1024,
    ),
    nest: bool = False,
) -> RegionAreaEstimate

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
) -> Tensor

difference

difference(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

exact_difference

exact_difference(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact difference; native returns a region whose area() is exact.

exact_intersection

exact_intersection(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact intersection; native returns a region whose area() is exact.

exact_union

exact_union(
    other: "RegionOperand",
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | SphericalBooleanRegion"

Exact union; native returns a region whose area() is exact.

intersection

intersection(
    other: "RegionOperand",
) -> "SphericalBooleanRegion"

intersects

intersects(
    other: "SphericalPolygon", *, atol_deg: float = 1e-08
) -> bool

pixelize

pixelize(
    nside: int, *, nest: bool = False
) -> PixelizedRegion

query_pixels

query_pixels(nside: int, *, nest: bool = False) -> Tensor

signed_area

signed_area(*, degrees: bool = False) -> Tensor

to_exact

to_exact(
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
) -> "ExactSphericalRegion | NativeApproximateSphericalRegion"

union

union(other: 'RegionOperand') -> 'SphericalBooleanRegion'

UnitVector3d dataclass

UnitVector3d(x: float, y: float, z: float)

Unit-length 3D Cartesian vector.

x instance-attribute

x: float

y instance-attribute

y: float

z instance-attribute

z: float

to_lonlat

to_lonlat(wrap_center_deg: float = 180.0) -> LonLat

Vector3d dataclass

Vector3d(x: float, y: float, z: float)

3D Cartesian vector.

x instance-attribute

x: float

y instance-attribute

y: float

z instance-attribute

z: float

norm

norm() -> float

to_unit

to_unit() -> 'UnitVector3d'

convex_polygon_contains

convex_polygon_contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    poly_lon_deg: Tensor | list[float],
    poly_lat_deg: Tensor | list[float],
    *,
    atol: float = 1e-12,
) -> Tensor

Fast half-space point-in-convex-spherical-polygon predicate.

query_ellipse

query_ellipse(
    nside: int,
    lon_deg: float | Tensor,
    lat_deg: float | Tensor,
    semi_major_deg: float,
    semi_minor_deg: float,
    *,
    pa_deg: float = 0.0,
    nest: bool = False,
    inclusive: bool = False,
) -> Tensor

Query pixels inside a sky ellipse.

The ellipse is defined in geodesic polar coordinates around the center. pa_deg is position angle East of North.

query_polygon_general

query_polygon_general(
    nside: int,
    lon_deg: Tensor | list[float],
    lat_deg: Tensor | list[float],
    *,
    nest: bool = False,
    inclusive: bool = False,
) -> Tensor

Query HEALPix pixels inside a simple spherical polygon (convex or non-convex).

Non-convex polygons are triangulated via gnomonic-plane ear clipping.

spherical_polygon_area

spherical_polygon_area(
    lon_deg: Tensor | list[float],
    lat_deg: Tensor | list[float],
    *,
    degrees: bool = False,
    oriented: bool = False,
) -> Tensor

Area of a simple spherical polygon.

By default returns the non-oriented enclosed area in [0, 2*pi] steradians. Set oriented=True to preserve signed winding orientation.

spherical_polygon_contains

spherical_polygon_contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    poly_lon_deg: Tensor | list[float],
    poly_lat_deg: Tensor | list[float],
    *,
    inclusive: bool = True,
    atol_deg: float = 1e-10,
    inside_lon_deg: Tensor | float | None = None,
    inside_lat_deg: Tensor | float | None = None,
) -> Tensor

Point-in-polygon for simple (possibly non-convex) spherical polygons.

Uses tangent-plane winding number around each query point.

spherical_polygon_signed_area

spherical_polygon_signed_area(
    lon_deg: Tensor | list[float],
    lat_deg: Tensor | list[float],
    *,
    degrees: bool = False,
) -> Tensor

Signed area of a simple spherical polygon on the unit sphere.

Contract: - vertices must define a simple, non-self-intersecting polygon - polygon is expected to lie in a region smaller than a full sphere - sign follows vertex winding orientation

spherical_polygons_intersect

spherical_polygons_intersect(
    lon1_deg: Tensor | list[float],
    lat1_deg: Tensor | list[float],
    lon2_deg: Tensor | list[float],
    lat2_deg: Tensor | list[float],
    *,
    inside1_lon_deg: Tensor | float | None = None,
    inside1_lat_deg: Tensor | float | None = None,
    inside2_lon_deg: Tensor | float | None = None,
    inside2_lat_deg: Tensor | float | None = None,
    atol_deg: float = 1e-08,
) -> bool

Polygon intersection predicate for simple spherical polygons.

Returns True if interiors intersect or boundaries cross/touch.

spherical_triangle_area

spherical_triangle_area(
    lon1_deg: Tensor | float,
    lat1_deg: Tensor | float,
    lon2_deg: Tensor | float,
    lat2_deg: Tensor | float,
    lon3_deg: Tensor | float,
    lat3_deg: Tensor | float,
    *,
    degrees: bool = False,
) -> Tensor

Spherical triangle area on the unit sphere.

Returns steradians by default, or square degrees when degrees=True.

to_exact_region

to_exact_region(
    region: RegionOperand,
    *,
    cap_steps: int = 256,
    backend: Literal[
        "spherical-geometry", "native"
    ] = "native",
    nsides: tuple[int, ...] | list[int] = (
        256,
        512,
        1024,
        2048,
    ),
) -> (
    ExactSphericalRegion | NativeApproximateSphericalRegion
)

Convert a torchsky spherical region into a selected region backend.

Default native is torchsky-owned and exposes analytic results only when available, with explicitly named center-sampled estimates otherwise. spherical-geometry is the opt-in exact backend.

HEALPix indexing

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

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 lonlat=True.

required
phi Tensor | float

Longitude in radians, or latitude in degrees with lonlat=True.

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])

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_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, ...).

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.

nest2ring

nest2ring(nside: int, pix_nest: Tensor) -> Tensor

Convert NESTED pixel indices to RING.

npix2nside

npix2nside(npix: int) -> int

Return NSIDE for a given number of pixels.

nside2npix

nside2npix(nside: int) -> int

Return number of pixels for a given NSIDE.

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

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)

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_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_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.

ring2nest

ring2nest(nside: int, pix_ring: Tensor) -> Tensor

Convert RING pixel indices to NESTED.

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.

vec2pix

vec2pix(
    nside: int,
    x: Tensor,
    y: Tensor,
    z: Tensor,
    nest: bool = False,
) -> Tensor

Convert Cartesian vectors to pixel indices.

Multi-order coverage

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

BMOC

BMOC(uniq: Tensor, flag: Tensor | None = None)

Boolean Multi-Order Coverage map storing UNIQ cells and interior/boundary flags.

flag == 1 indicates a cell completely inside the region; flag == 0 indicates a partial/boundary cell at max_order.

Overlapping duplicate or parent/child cells are represented once. If their flags disagree, boundary (0) deterministically dominates interior (1), so normalization never overstates strictly interior coverage.

area property

area: float

Total area (interior + boundary) in steradians.

area_sq_deg property

area_sq_deg: float

from_circle class-attribute instance-attribute

from_circle = from_cone

interior_area property

interior_area: float

Area of strictly interior cells (flag == 1) in steradians.

interior_area_sq_deg property

interior_area_sq_deg: float

is_empty property

is_empty: bool

max_order property

max_order: int

__and__

__and__(other: BMOC) -> BMOC

__bool__

__bool__() -> bool

__eq__

__eq__(other: object) -> bool

__or__

__or__(other: BMOC) -> BMOC

__sub__

__sub__(other: BMOC) -> BMOC

boundary_moc

boundary_moc() -> MOC

Return the MOC of boundary cells (flag == 0).

contains

contains(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    include_boundary: bool = True,
) -> Tensor

Test whether points fall inside the BMOC.

difference

difference(other: BMOC) -> BMOC

Subtract all covered cells in other, preserving remaining flags.

empty classmethod

empty() -> BMOC

from_cone classmethod

from_cone(
    lon_deg: float,
    lat_deg: float,
    radius_deg: float,
    max_order: int = 10,
    *,
    inclusive: bool = True,
) -> BMOC

Build a BMOC for a spherical cone/disc.

from_polygon classmethod

from_polygon(
    lon_deg: Tensor | list[float],
    lat_deg: Tensor | list[float],
    max_order: int = 10,
) -> BMOC

Build a BMOC for a spherical polygon.

from_wcs classmethod

from_wcs(
    wcs: Any,
    shape: tuple[int, int] | None = None,
    *,
    max_order: int = 10,
    mask: Tensor | None = None,
) -> BMOC

Build a BMOC from a 2D WCS footprint (and optional valid-pixel mask).

full classmethod

full() -> BMOC

interior_moc

interior_moc() -> MOC

Return the MOC of strictly interior cells (flag == 1).

intersection

intersection(other: BMOC) -> BMOC

Intersect coverage; boundary dominates interior where both overlap.

prepare_random_sampler

prepare_random_sampler(
    *,
    include_boundary: bool = True,
    device: device | str | None = None,
) -> PreparedRandomSampler

Snapshot immutable, device-bound state for repeated random draws.

Boundary filtering and cell state are captured during preparation. Later mutation of uniq or flag has no effect; prepare again to observe changes.

sample_randoms

sample_randoms(
    n: int,
    *,
    include_boundary: bool = True,
    generator: Generator | None = None,
    device: device | str | None = None,
) -> tuple[Tensor, Tensor]

Draw n points uniformly in solid angle inside this BMOC.

to_moc

to_moc(*, include_boundary: bool = True) -> MOC

Convert to a standard MOC (optionally keeping only interior cells).

union

union(other: BMOC) -> BMOC

Union coverage; interior dominates boundary where operands overlap.

MOC

MOC(uniq: Tensor)

Multi-order sky coverage encoded as normalized IVOA NUNIQ cells.

Parameters:

Name Type Description Default
uniq Tensor

Integer tensor of NUNIQ cell identifiers.

required

Examples:

>>> from torchsky.sphere import MOC
>>> MOC.empty().is_empty
True

area property

area: float

Total area covered by the MOC in steradians.

area_sq_deg property

area_sq_deg: float

Total area covered by the MOC in square degrees.

is_empty property

is_empty: bool

max_order property

max_order: int

uniq instance-attribute

uniq = _normalize_moc(_as_int64_exact(uniq, name='uniq'))

__and__

__and__(other: MOC) -> MOC

__bool__

__bool__() -> bool

__eq__

__eq__(other: object) -> bool

__or__

__or__(other: MOC) -> MOC

__sub__

__sub__(other: MOC) -> MOC

_binary_op

_binary_op(other: MOC, op: str) -> MOC

_cache

_cache() -> dict

Per-instance memo (max order, range tensors), reset if uniq changes.

_flat_pixels

_flat_pixels(nside: int) -> Tensor

_from_range_tensors classmethod

_from_range_tensors(
    starts: Tensor, ends: Tensor, max_order: int
) -> MOC

Convert merged ranges to UNIQ cells without a second normalize pass.

_from_ranges classmethod

_from_ranges(
    ranges: list[tuple[int, int]], max_order: int
) -> MOC

Convert merged ranges to UNIQ cells without a second normalize pass.

_range_tensors

_range_tensors(max_order: int) -> tuple[Tensor, Tensor]

_to_ranges

_to_ranges(max_order: int) -> list[tuple[int, int]]

boundary

boundary() -> list[Tensor]

Return the boundaries of the MOC as a list of vertex loops. Each loop is a Tensor of shape [N, 2] (lon, lat) in degrees.

contains

contains(
    lon_deg: Tensor | float, lat_deg: Tensor | float
) -> Tensor

Check if points are contained in the MOC.

contains_moc

contains_moc(other: MOC) -> bool

Return True if this MOC contains all of other MOC (subset check).

contains_pixels

contains_pixels(
    nside: int, pixels: Tensor | int, *, nest: bool = True
) -> Tensor

Check whether HEALPix pixels are covered by this MOC.

pixels are interpreted at nside. MOC cells are internally NUNIQ / NESTED, so RING inputs are converted exactly when nest=False.

contains_rows

contains_rows(catalog: Any) -> Tensor

Boolean mask for catalog rows. Prefer Catalog.inside(moc).

contains_uniq

contains_uniq(uniq: Tensor | int) -> Tensor

Return which canonical UNIQ cells are fully covered by this MOC.

degrade

degrade(max_order: int) -> MOC

Drop cells finer than max_order onto their nested parents.

difference

difference(other: MOC) -> MOC

Subtract other MOC from this MOC.

empty classmethod

empty() -> MOC

filter_catalog

filter_catalog(
    lon_deg: Tensor, lat_deg: Tensor
) -> tuple[Tensor, Tensor]

Filter a catalogue by point-in-MOC containment. Returns (lon, lat) of contained points.

flatten

flatten(nside: int) -> Tensor

Project MOC to a dense HEALPix mask at fixed resolution.

from_ascii classmethod

from_ascii(ascii_str: str) -> MOC

Create a MOC from an IVOA ASCII string.

from_circle classmethod

from_circle(
    lon_deg: float,
    lat_deg: float,
    radius_deg: float,
    max_order: int = 10,
    inclusive: bool = True,
) -> MOC

Create a MOC from a circular cap without listing every leaf pixel.

from_json classmethod

from_json(json_str: str) -> MOC

Create a MOC from an IVOA JSON string.

from_lonlat classmethod

from_lonlat(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    max_order: int,
) -> MOC

Coverage of catalog points, compacted to parent UNIQ cells.

from_mocpy classmethod

from_mocpy(moc: Any) -> MOC

Import a host-side mocpy.MOC through IVOA JSON.

from_observations classmethod

from_observations(
    observations: Any, *, max_order: int = 10
) -> MOC

Build the union MOC of a sequence of observations or WCS objects.

from_polygon classmethod

from_polygon(
    lon_deg: Tensor | list[float],
    lat_deg: Tensor | list[float],
    max_order: int = 10,
) -> MOC

Create a MOC from a simple spherical polygon.

Convex and non-convex simple polygons are supported. Interior cells are kept coarse; only the boundary is subdivided to max_order.

from_region classmethod

from_region(
    region: Any, max_order: int | None = None
) -> MOC

Create a MOC from a torchsky spherical region or PixelizedRegion.

Pixelized regions preserve their current resolution by default. Other regions are pixelized at 2**max_order in NESTED ordering before conversion to UNIQ, defaulting to order 10 when max_order is omitted. Pass a matching max_order with a PixelizedRegion to assert the expected resolution.

from_sparse_map classmethod

from_sparse_map(smap: SparseHealpixMap) -> MOC

Create MOC from the coverage of a sparse map.

from_threshold classmethod

from_threshold(
    smap: SparseHealpixMap,
    threshold: float,
    op: Literal[">", ">=", "<", "<="] = ">",
) -> MOC

Create a MOC from pixels in a sparse map that satisfy a threshold.

from_wcs classmethod

from_wcs(
    wcs: Any,
    shape: tuple[int, int] | None = None,
    *,
    max_order: int = 10,
    mask: Tensor | None = None,
) -> MOC

Build a MOC from a 2D WCS (and optional valid-pixel mask).

full classmethod

full() -> MOC

intersection

intersection(other: MOC) -> MOC

Cells covered by both MOCs (range sweep at the finer max_order).

intersects_uniq

intersects_uniq(uniq: Tensor | int) -> Tensor

Return which canonical UNIQ cells intersect this MOC.

overlap_fraction

overlap_fraction(uniq: Tensor | int) -> Tensor

Fraction of each canonical UNIQ cell covered by this MOC.

overlaps

overlaps(other: MOC) -> bool

Return whether two footprint MOCs have non-empty intersection.

prepare_random_sampler

prepare_random_sampler(
    *, device: device | str | None = None
) -> PreparedRandomSampler

Snapshot immutable, device-bound state for repeated random draws.

Mutating self.uniq afterward does not update the returned sampler; call this method again to prepare from the changed MOC.

read_fits classmethod

read_fits(filename: str) -> MOC

Read a MOC from an IVOA FITS file through :mod:torchfits.

sample_randoms

sample_randoms(
    n: int,
    *,
    generator: Generator | None = None,
    device: device | str | None = None,
) -> tuple[Tensor, Tensor]

Draw n points uniformly in solid angle inside this MOC.

to_ascii

to_ascii(*, compact: bool = False) -> str

Return IVOA ASCII representation of the MOC.

to_json

to_json() -> str

Return IVOA JSON representation of the MOC.

to_mocpy

to_mocpy() -> Any

Export to mocpy.MOC when mocpy is installed.

to_pixelized_region

to_pixelized_region(
    nside: int, *, nest: bool = True
) -> PixelizedRegion

Realize this MOC as a PixelizedRegion at nside.

MOC UNIQ cells are NESTED by definition. Set nest=False to receive a RING-ordered PixelizedRegion after exact ordering conversion.

to_sparse_map

to_sparse_map(
    nside: int,
    sentinel: float = 0.0,
    *,
    nside_coverage: int | None = None,
    dtype: dtype = float32,
) -> SparseHealpixMap

Realize MOC coverage as a sparse HEALPix map at fixed resolution.

union

union(other: MOC) -> MOC

write_fits

write_fits(filename: str, overwrite: bool = False) -> None

Write the MOC to a FITS file following the IVOA MOC standard.

Writes the table through :mod:torchfits.

nest2uniq

nest2uniq(nside: int | Tensor, pix: int | Tensor) -> Tensor

Convert NESTED pixel index to UNIQ pixel index.

uniq2nest

uniq2nest(uniq: int | Tensor) -> tuple[Tensor, Tensor]

Convert UNIQ pixel index to (nside, NESTED pixel index).

Multiorder

UniqValueMapProtocol

<class 'torchsky.sphere.multiorder.UniqValueMapProtocol'>

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

MultiOrderHealpixMap

MultiOrderHealpixMap(
    uniq: Tensor | Any,
    values: Tensor | Any,
    *,
    values_are_densities: bool = False,
    metadata: Mapping[str, Any] | None = None,
)

Tensor values attached to sorted, disjoint IVOA NUNIQ cells.

coverage_moc property

coverage_moc: MOC

max_order property

max_order: int

metadata instance-attribute

metadata = dict(metadata) if metadata is not None else None

uniq instance-attribute

uniq = uniq_t

values instance-attribute

values = values_t

values_are_densities instance-attribute

values_are_densities = bool(values_are_densities)

cell_area

cell_area() -> Tensor

from_cdshealpix classmethod

from_cdshealpix(map_obj: Any) -> MultiOrderHealpixMap

from_columns classmethod

from_columns(
    columns: Mapping[str, Any] | Any,
    *,
    value_column: str,
    uniq_column: str = "UNIQ",
    values_are_densities: bool = False,
    metadata: Mapping[str, Any] | None = None,
) -> MultiOrderHealpixMap

from_mhealpy classmethod

from_mhealpy(
    map_obj: UniqValueMapProtocol,
) -> MultiOrderHealpixMap

from_sparse_map classmethod

from_sparse_map(
    sparse_map: SparseHealpixMap,
) -> MultiOrderHealpixMap

get_values_pos

get_values_pos(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    fill_value: float | int = 0,
    return_valid: bool = False,
) -> Tensor | tuple[Tensor, Tensor]

integral

integral(footprint: MOC | None = None) -> Tensor

overlap_fraction

overlap_fraction(footprint: MOC) -> Tensor

select

select(footprint: MOC) -> MultiOrderHealpixMap

to

to(
    device: device | str, *, dtype: dtype | None = None
) -> MultiOrderHealpixMap

to_cdshealpix

to_cdshealpix() -> Any

to_columns

to_columns(
    *, value_column: str = "VALUE"
) -> dict[str, Tensor]

to_mhealpy

to_mhealpy() -> Any

to_moc

to_moc() -> MOC

to_sparse_map

to_sparse_map(
    *,
    nside_coverage: int | None = None,
    fill_value: float = float(UNSEEN),
) -> SparseHealpixMap

Pseudocl

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

ApodizedMask dataclass

ApodizedMask(
    values: Tensor,
    first_derivative: Tensor,
    second_derivative: Tensor,
    geometry: CARGeometry,
    lmax: int,
    _validation_token: object | None = None,
)

A scalar mask and its spin-1/spin-2 raising derivatives.

first_derivative and second_derivative are two-component spin maps representing eth W and eth eth W in the geometry's declared spin convention. Construction verifies harmonic derivative identities and the pure-estimator boundary conditions W = eth W = 0 at both polar rings.

_validation_token class-attribute instance-attribute

_validation_token: object | None = field(
    default=None, repr=False, compare=False
)

first_derivative instance-attribute

first_derivative: Tensor

geometry instance-attribute

geometry: CARGeometry

lmax instance-attribute

lmax: int

second_derivative instance-attribute

second_derivative: Tensor

values instance-attribute

values: Tensor

__post_init__

__post_init__() -> None

from_mask classmethod

from_mask(
    values: Tensor,
    geometry: CARGeometry,
    lmax: int,
    *,
    backend: str | SHTBackend | None = None,
    latitude_block_size: int = 64,
) -> ApodizedMask

BandpowerBinning dataclass

BandpowerBinning(
    binning_matrix: Tensor, unbinning_matrix: Tensor
)

Paired ell-to-bandpower and bandpower-to-ell linear operators.

binning_matrix instance-attribute

binning_matrix: Tensor

lmax property

lmax: int

nband property

nband: int

unbinning_matrix instance-attribute

unbinning_matrix: Tensor

__post_init__

__post_init__() -> None

bin

bin(spectra: Tensor) -> Tensor

from_edges classmethod

from_edges(
    edges: list[int] | tuple[int, ...],
    lmax: int,
    *,
    weighting: Literal["uniform", "2ell+1"] = "uniform",
    dtype: dtype = float64,
    device: device | str | None = None,
) -> BandpowerBinning

Construct non-overlapping half-open bands from integer edges.

unbin

unbin(bandpowers: Tensor) -> Tensor

ModeCouplingDiagnostics dataclass

ModeCouplingDiagnostics(
    rank: int,
    size: int,
    condition_number: float,
    maximum_condition_number: float,
    singular_values: Tensor,
)

condition_number instance-attribute

condition_number: float

maximum_condition_number instance-attribute

maximum_condition_number: float

rank instance-attribute

rank: int

singular_values instance-attribute

singular_values: Tensor

size instance-attribute

size: int

ModeCouplingError

Bases: RuntimeError

Raised when a mode-coupling system cannot be inverted safely.

ModeCouplingWorkspace dataclass

ModeCouplingWorkspace(
    lmax: int,
    spins: tuple[int, int],
    spectrum_block_size: int,
    mask_spectrum: Tensor,
    transfer: Tensor,
    binning: BandpowerBinning,
    quadrature_nodes: Tensor,
    quadrature_weights: Tensor,
    mask_correlation: Tensor,
    coupling_matrix: Tensor,
    diagnostics: ModeCouplingDiagnostics,
    node_block_size: int,
)

Exact correlation-space block coupling and binned inversion.

binning instance-attribute

coupling_matrix instance-attribute

coupling_matrix: Tensor

diagnostics instance-attribute

lmax instance-attribute

lmax: int

mask_correlation instance-attribute

mask_correlation: Tensor

mask_spectrum instance-attribute

mask_spectrum: Tensor

node_block_size instance-attribute

node_block_size: int

quadrature_nodes instance-attribute

quadrature_nodes: Tensor

quadrature_weights instance-attribute

quadrature_weights: Tensor

spectrum_block_size instance-attribute

spectrum_block_size: int

spins instance-attribute

spins: tuple[int, int]

transfer instance-attribute

transfer: Tensor

bandpower_windows

bandpower_windows() -> Tensor

Return the exact linear map from unbinned theory C_ell to estimates.

couple_bandpowers

couple_bandpowers(theory_bandpowers: Tensor) -> Tensor

Couple piecewise-unbinned theory bandpowers and return binned pseudo-spectra.

couple_noise

couple_noise(noise_spectrum: Tensor) -> Tensor

Propagate an unbinned sky-noise spectrum through all coupling blocks.

couple_theory

couple_theory(theory_spectrum: Tensor) -> Tensor

Apply mask, beam, and pixel-window coupling to an unbinned theory spectrum.

decouple

decouple(
    coupled_spectrum: Tensor,
    *,
    noise_bias: Tensor | None = None,
    deprojection_bias: Tensor | None = None,
) -> Tensor

Subtract an unbinned coupled noise bias and solve for bandpowers.

from_fields classmethod

from_fields(
    field_a: PseudoClField,
    field_b: PseudoClField | None = None,
    binning: BandpowerBinning | None = None,
    *,
    maximum_condition_number: float | None = None,
    node_block_size: int = 256,
) -> ModeCouplingWorkspace

Build a workspace without materializing an ell-by-ell kernel.

PseudoClField dataclass

PseudoClField(
    values: Tensor,
    mask: Tensor,
    geometry: CARGeometry,
    lmax: int,
    spin: Literal[0, 2] = 0,
    beam: Tensor | None = None,
    pixel_window: Tensor | None = None,
    templates: Tensor | None = None,
    maximum_template_condition_number: float | None = None,
    apodized_mask: ApodizedMask | None = None,
    purify_e: bool = False,
    purify_b: bool = False,
    backend: str | SHTBackend | None = None,
    latitude_block_size: int = 64,
)

A scalar or spin-2 CAR map, mask, and harmonic transfer contract.

apodized_mask class-attribute instance-attribute

apodized_mask: ApodizedMask | None = None

backend class-attribute instance-attribute

backend: str | SHTBackend | None = field(
    default=None, repr=False, compare=False
)

beam class-attribute instance-attribute

beam: Tensor | None = None

geometry instance-attribute

geometry: CARGeometry

latitude_block_size class-attribute instance-attribute

latitude_block_size: int = 64

lmax instance-attribute

lmax: int

mask instance-attribute

mask: Tensor

maximum_template_condition_number class-attribute instance-attribute

maximum_template_condition_number: float | None = None

pixel_window class-attribute instance-attribute

pixel_window: Tensor | None = None

purify_b class-attribute instance-attribute

purify_b: bool = False

purify_e class-attribute instance-attribute

purify_e: bool = False

spin class-attribute instance-attribute

spin: Literal[0, 2] = 0

templates class-attribute instance-attribute

templates: Tensor | None = None

transfer property

transfer: Tensor

values instance-attribute

values: Tensor

__post_init__

__post_init__() -> None

deprojected_values

deprojected_values() -> Tensor

masked_alms

masked_alms() -> Tensor

coupled_spectra

coupled_spectra(
    field_a: PseudoClField,
    field_b: PseudoClField | None = None,
) -> Tensor

Return scalar, (E, B), or (EE, EB, BE, BB) coupled spectra.

pure_alms

pure_alms(
    field: PseudoClField, *, values: Tensor | None = None
) -> Tensor

Return pure (E, B) alms for a validated apodized spin-2 field.

The Smith--Zaldarriaga scalar chi_E/chi_B form is used. It is exactly the integration-by-parts form containing eth W and eth eth W when the validated boundary conditions hold. Multipoles below two are zero.

template_deprojection_bias

template_deprojection_bias(
    field_a: PseudoClField,
    signal_realizations_a: Tensor,
    field_b: PseudoClField | None = None,
    signal_realizations_b: Tensor | None = None,
) -> Tensor

Estimate the additive template-deprojection bias from signal realizations.

Realizations are interpreted as already beam/pixel-convolved maps and must have a leading realization axis. The returned coupled-spectrum bias is the ensemble mean of deprojected minus undeprojected estimates in the standard block ordering.

Randoms

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

PreparedRandomSampler dataclass

PreparedRandomSampler(
    _pix_nested: Tensor,
    _nsides: Tensor | int,
    _cdf: Tensor | None = None,
)

Immutable, device-bound state for repeated random sky draws.

Preparation snapshots the footprint, ordering conversion, and normalized selection state onto device. Later mutation of tensors in the source MOC, BMOC, sparse map, or weights does not change this sampler; prepare a new sampler to observe such mutations. The private snapshot tensors are immutable implementation state and must not be mutated.

_cdf class-attribute instance-attribute

_cdf: Tensor | None = field(
    default=None, repr=False, compare=False
)

_nsides class-attribute instance-attribute

_nsides: Tensor | int = field(repr=False, compare=False)

_pix_nested class-attribute instance-attribute

_pix_nested: Tensor = field(repr=False, compare=False)

device property

device: device

Device on which sampling state and returned coordinates reside.

sample_randoms

sample_randoms(
    n: int, *, generator: Generator | None = None
) -> tuple[Tensor, Tensor]

Draw n points using this sampler's snapshotted selection state.

sample_randoms

sample_randoms(
    n: int,
    footprint: MOC | BMOC | SparseHealpixMap | None = None,
    *,
    weights: SparseHealpixMap | Tensor | str | None = None,
    generator: Generator | None = None,
    device: device | str | None = None,
) -> tuple[Tensor, Tensor]

Generate n random sky coordinates (ra_deg, dec_deg) uniformly in solid angle.

Supports rejection-free sampling inside a :class:MOC, :class:BMOC, or :class:SparseHealpixMap, with optional per-pixel depth/completeness weights.

Spherical harmonics

SHTBackend

<class 'torchsky.sphere.sht.SHTBackend'>

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

SHTAnalysisResult module-attribute

SHTAnalysisResult = SHTResult

CARGeometry dataclass

CARGeometry(
    array_shape: tuple[int, int],
    latitude_axis: int,
    longitude_axis: int,
    sampling: CARSampling,
    latitude_radians: tuple[float, ...],
    quadrature_weights: tuple[float, ...],
    longitude_origin_radians: float,
    latitude_reversed: bool,
    longitude_reversed: bool,
    *,
    spin_convention: SpinConvention,
)

Bases: SHTGeometry

array_shape instance-attribute

array_shape: tuple[int, int]

kind property

kind: str

latitude_axis instance-attribute

latitude_axis: int

latitude_radians instance-attribute

latitude_radians: tuple[float, ...]

latitude_reversed instance-attribute

latitude_reversed: bool

longitude_axis instance-attribute

longitude_axis: int

longitude_origin_radians instance-attribute

longitude_origin_radians: float

longitude_reversed instance-attribute

longitude_reversed: bool

nlat property

nlat: int

nlon property

nlon: int

pixel_count property

pixel_count: int

quadrature_weights instance-attribute

quadrature_weights: tuple[float, ...]

sampling instance-attribute

sampling: CARSampling

shape property

shape: tuple[int, ...]

__post_init__

__post_init__() -> None

from_header classmethod

from_header(
    header: Mapping[str, Any],
    shape: tuple[int, int] | None = None,
    *,
    spin_convention: SpinConvention | str,
) -> CARGeometry

latitudes

latitudes(*, dtype: dtype, device: device | str) -> Tensor

ring_weights

ring_weights(
    *, dtype: dtype, device: device | str
) -> Tensor

CARSampling

Bases: StrEnum

CLENSHAW_CURTIS class-attribute instance-attribute

CLENSHAW_CURTIS = 'clenshaw-curtis'

FEJER1 class-attribute instance-attribute

FEJER1 = 'fejer-1'

HEALPixGeometry dataclass

HEALPixGeometry(
    nside: int,
    nest: bool = False,
    *,
    spin_convention: SpinConvention,
)

Bases: SHTGeometry

kind property

kind: str

nest class-attribute instance-attribute

nest: bool = False

nside instance-attribute

nside: int

shape property

shape: tuple[int, ...]

__post_init__

__post_init__() -> None

NativeSHTBackend

Spherical-harmonic backend implemented by torchsky native kernels.

capabilities class-attribute instance-attribute

capabilities = SHTBackendCapabilities(
    backend=name,
    operations=frozenset(SHTOperation),
    geometry_kinds=frozenset({"healpix", "car"}),
    spins=frozenset({0, 1, 2, 3}),
    devices=frozenset({"cpu", "cuda", "mps"}),
    dtypes=frozenset(
        {float32, float64, complex64, complex128}
    ),
    batched=True,
    autograd=True,
    analysis_kinds=frozenset({QUADRATURE, LEAST_SQUARES}),
)

name class-attribute instance-attribute

name = 'native'

_healpix

_healpix(
    values: Tensor,
    request: SHTRequest,
    geometry: HEALPixGeometry,
    tolerance: float,
    max_iterations: int,
) -> Tensor | tuple[Tensor, float, int]

execute

execute(
    values: Tensor,
    request: SHTRequest,
    *,
    tolerance: float,
    max_iterations: int,
) -> SHTResult

SHTAnalysisKind

Bases: StrEnum

LEAST_SQUARES class-attribute instance-attribute

LEAST_SQUARES = 'least-squares'

QUADRATURE class-attribute instance-attribute

QUADRATURE = 'quadrature'

SHTBackendCapabilities dataclass

SHTBackendCapabilities(
    backend: str,
    operations: frozenset[SHTOperation],
    geometry_kinds: frozenset[str],
    spins: frozenset[int],
    devices: frozenset[str],
    dtypes: frozenset[dtype],
    batched: bool,
    autograd: bool,
    analysis_kinds: frozenset[
        SHTAnalysisKind
    ] = frozenset(),
)

analysis_kinds class-attribute instance-attribute

analysis_kinds: frozenset[SHTAnalysisKind] = frozenset()

autograd instance-attribute

autograd: bool

backend instance-attribute

backend: str

batched instance-attribute

batched: bool

devices instance-attribute

devices: frozenset[str]

dtypes instance-attribute

dtypes: frozenset[dtype]

geometry_kinds instance-attribute

geometry_kinds: frozenset[str]

operations instance-attribute

operations: frozenset[SHTOperation]

spins instance-attribute

spins: frozenset[int]

require

require(request: SHTRequest, value: Tensor) -> None

supports

supports(
    request: SHTRequest, value: Tensor | None = None
) -> bool

SHTCapabilityError

Bases: RuntimeError

SHTGeometry dataclass

SHTGeometry(*, spin_convention: SpinConvention)

kind property

kind: str

shape property

shape: tuple[int, ...]

spin_convention class-attribute instance-attribute

spin_convention: SpinConvention = field(kw_only=True)

SHTOperation

Bases: StrEnum

ADJOINT_SYNTHESIZE class-attribute instance-attribute

ADJOINT_SYNTHESIZE = 'adjoint_synthesize'

ANALYZE class-attribute instance-attribute

ANALYZE = 'analyze'

PSEUDO_ANALYZE class-attribute instance-attribute

PSEUDO_ANALYZE = 'pseudo_analyze'

SYNTHESIZE class-attribute instance-attribute

SYNTHESIZE = 'synthesize'

SHTRequest dataclass

SHTRequest(
    geometry: SHTGeometry,
    lmax: int,
    operation: SHTOperation,
    mmax: int | None = None,
    spin: int = 0,
    latitude_block_size: int = 64,
)

geometry instance-attribute

geometry: SHTGeometry

latitude_block_size class-attribute instance-attribute

latitude_block_size: int = 64

lmax instance-attribute

lmax: int

mmax class-attribute instance-attribute

mmax: int | None = None

operation instance-attribute

operation: SHTOperation

spin class-attribute instance-attribute

spin: int = 0

__post_init__

__post_init__() -> None

SHTResult dataclass

SHTResult(
    values: Tensor,
    request: SHTRequest,
    backend: str,
    analysis_kind: SHTAnalysisKind | None = None,
    converged: bool | None = None,
    iterations: int | None = None,
    relative_residual: float | None = None,
)

analysis_kind class-attribute instance-attribute

analysis_kind: SHTAnalysisKind | None = None

backend instance-attribute

backend: str

converged class-attribute instance-attribute

converged: bool | None = None

iterations class-attribute instance-attribute

iterations: int | None = None

relative_residual class-attribute instance-attribute

relative_residual: float | None = None

request instance-attribute

request: SHTRequest

values instance-attribute

values: Tensor

SpinConvention

Bases: StrEnum

COSMO class-attribute instance-attribute

COSMO = 'cosmo'

IAU class-attribute instance-attribute

IAU = 'iau'

TorchHarmonicsBackend

Spherical-harmonic backend using the optional torch-harmonics package.

capabilities class-attribute instance-attribute

capabilities = SHTBackendCapabilities(
    backend=name,
    operations=frozenset({SYNTHESIZE, ANALYZE}),
    geometry_kinds=frozenset({"car"}),
    spins=frozenset({0}),
    devices=frozenset({"cpu", "cuda"}),
    dtypes=frozenset(
        {float32, float64, complex64, complex128}
    ),
    batched=True,
    autograd=True,
    analysis_kinds=frozenset({QUADRATURE}),
)

name class-attribute instance-attribute

name = 'torch-harmonics'

_module

_module() -> Any

_transform

_transform(
    module: Any,
    name: str,
    geometry: CARGeometry,
    lmax: int,
    mmax: int,
) -> Any

execute

execute(
    values: Tensor,
    request: SHTRequest,
    *,
    tolerance: float,
    max_iterations: int,
) -> SHTResult

adjoint_synthesize

adjoint_synthesize(
    map_values: Tensor,
    geometry_or_request: SHTGeometry | SHTRequest,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    spin: int = 0,
    backend: str | SHTBackend | None = None,
    latitude_block_size: int = 64,
) -> SHTResult

Apply the adjoint of harmonic synthesis to map samples.

analyze

analyze(
    map_values: Tensor,
    geometry_or_request: SHTGeometry | SHTRequest,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    spin: int = 0,
    backend: str | SHTBackend | None = None,
    latitude_block_size: int = 64,
) -> SHTResult

Analyze a scalar or spin map into packed harmonic coefficients.

pseudo_analyze

pseudo_analyze(
    map_values: Tensor,
    geometry_or_request: SHTGeometry | SHTRequest,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    spin: int = 0,
    backend: str | SHTBackend | None = None,
    tolerance: float = 1e-10,
    max_iterations: int = 50,
    latitude_block_size: int = 64,
) -> SHTResult

Solve a least-squares harmonic analysis on incomplete geometries.

synthesize

synthesize(
    alm: Tensor,
    geometry_or_request: SHTGeometry | SHTRequest,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    spin: int = 0,
    backend: str | SHTBackend | None = None,
    latitude_block_size: int = 64,
) -> SHTResult

Synthesize a scalar or spin map from packed harmonic coefficients.

Sparse maps

HealSparseHostProtocol

<class 'torchsky.sphere.sparse.HealSparseHostProtocol'>

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

SkyMaskPipe

SkyMaskPipe(nside: int, nest: bool = True)

Composable HEALPix mask pipeline at a fixed resolution and ordering.

nest instance-attribute

nest = nest

nside instance-attribute

nside = nside

stages instance-attribute

stages: dict[str, SparseHealpixMap] = {}

add_stage

add_stage(name: str, mask: SparseHealpixMap)

combine

combine(
    operation: Literal["and", "or"] = "and",
) -> SparseHealpixMap

SparseHealpixMap dataclass

SparseHealpixMap(
    nside: int,
    nest: bool,
    pixels: Tensor,
    values: Tensor,
    fill_value: float = float(UNSEEN),
    metadata: dict[str, Any] | None = None,
    column_names: tuple[str, ...] | None = None,
    nside_coverage: int | None = None,
    coverage_map: Tensor | None = None,
    _block_index: Tensor | None = None,
    _block_values: Tensor | None = None,
    _fill_tensor: Tensor | None = None,
)

Sparse HEALPix map supporting both simple (pixel list) and hierarchical (coverage map + blocks) representations.

_block_index class-attribute instance-attribute

_block_index: Tensor | None = field(
    default=None, repr=False, compare=False
)

_block_values class-attribute instance-attribute

_block_values: Tensor | None = field(
    default=None, repr=False, compare=False
)

_fill_tensor class-attribute instance-attribute

_fill_tensor: Tensor | None = field(
    default=None, repr=False, compare=False
)

column_names class-attribute instance-attribute

column_names: tuple[str, ...] | None = None

columns property

columns: tuple[str, ...] | None

coverage_map class-attribute instance-attribute

coverage_map: Tensor | None = None

coverage_mask property

coverage_mask: Tensor

Returns a boolean mask of the coverage. If nside_coverage is set, returns mask at that resolution (matches healsparse).

dtype_names property

dtype_names: tuple[str, ...] | None

fill_value class-attribute instance-attribute

fill_value: float = float(UNSEEN)

metadata class-attribute instance-attribute

metadata: dict[str, Any] | None = None

nest instance-attribute

nest: bool

nside instance-attribute

nside: int

nside_coverage class-attribute instance-attribute

nside_coverage: int | None = None

nside_sparse property

nside_sparse: int

pixels instance-attribute

pixels: Tensor

pixels_per_cov property

pixels_per_cov: int

sentinel property

sentinel: float

valid_pixels property

valid_pixels: Tensor

Valid pixel indices. External HealSparse hosts may still expose a method.

values instance-attribute

values: Tensor

__getitem__

__getitem__(
    key: str | int | Tensor | list[str] | tuple[str, ...],
) -> SparseHealpixMap | Tensor

__post_init__

__post_init__() -> None

_build_coverage_map

_build_coverage_map()

_build_lookup_blocks

_build_lookup_blocks() -> None

Dense per-coverage-cell value blocks for O(1) get_values.

Block 0 is the fill/sentinel row so uncovered cells gather without a missing-index branch (healsparse stores the same layout as a flat offset table). Blocks are skipped (_block_values is None) when they would hold more than _LOOKUP_BLOCK_MAX_SLOTS_PER_PIXEL slots per stored pixel; get_values then binary-searches the sorted pixels.

_coverage_pixels

_coverage_pixels() -> Tensor

_get_values_blocks

_get_values_blocks(pix_flat: Tensor) -> Tensor

_global_to_local

_global_to_local(pix: Tensor) -> tuple[Tensor, Tensor]

_read_healsparse_fits classmethod

_read_healsparse_fits(filename: str) -> 'SparseHealpixMap'

_resampled_nside_coverage

_resampled_nside_coverage(nside_out: int) -> int | None

_ud_grade_from_coverage_blocks

_ud_grade_from_coverage_blocks(
    nside_out: int,
    *,
    ratio: int,
    pess: bool,
    power: float | None,
    fv: Any,
    out_nside_coverage: int | None,
) -> SparseHealpixMap | None

Degrade using fill-block layout. None means use the pixel-list path.

Floating maps only, and only when coverage nside is unchanged so each coverage cell stays a contiguous NEST range. Bool/int occupancy lives in the pixel list; a fill-block cell cannot tell valid False/0 from an uncovered child.

_write_healsparse_fits

_write_healsparse_fits(
    filename: str,
    overwrite: bool = False,
    nside_coverage: int | None = None,
) -> None

convert_healpix_map classmethod

convert_healpix_map(
    dense: Tensor,
    nside_coverage: int,
    nest: bool = True,
    sentinel: float | None = None,
    metadata: dict[str, Any] | None = None,
) -> "SparseHealpixMap"

from_columns classmethod

from_columns(
    pixels: Tensor,
    columns: dict[str, Tensor],
    nside_sparse: int,
    *,
    nest: bool = True,
    nside_coverage: int | None = None,
    sentinel: float | None = None,
    metadata: dict[str, Any] | None = None,
) -> "SparseHealpixMap"

Construct a multi-column SparseHealpixMap from a dict of {name: tensor}.

from_dense classmethod

from_dense(
    dense: Tensor,
    nside: int | None = None,
    nest: bool = True,
    valid_mask: Tensor | None = None,
    fill_value: float | Any = None,
    coverage_mode: str = "any",
    nside_coverage: int | None = None,
    metadata: dict[str, Any] | None = None,
    column_names: tuple[str, ...] | list[str] | None = None,
) -> "SparseHealpixMap"

from_healsparse classmethod

from_healsparse(
    map_obj: HealSparseHostProtocol,
) -> "SparseHealpixMap"

Import a host-side healsparse.HealSparseMap without dense expansion.

from_moc classmethod

from_moc(
    moc: "MOC",
    nside: int,
    nside_coverage: int | None = None,
    *,
    value: Any = True,
    sentinel: float | None = False,
    dtype: Any | None = None,
    metadata: dict[str, Any] | None = None,
    nest: bool = True,
) -> "SparseHealpixMap"

Create a sparse map from MOC coverage without materializing a dense mask.

from_observations classmethod

from_observations(
    observations: Any,
    nside: int | None = None,
    *,
    nside_sparse: int | None = None,
    nside_coverage: int | None = None,
    nest: bool = True,
    columns: tuple[str, ...] | list[str] | None = (
        "weight",
        "nexp",
        "fracdet",
    ),
) -> "SparseHealpixMap"

Build a survey property SparseHealpixMap (weight, nexp, fracdet) from observations.

from_pixels classmethod

from_pixels(
    pixels: Tensor,
    values: Tensor,
    nside_sparse: int,
    nest: bool = True,
    nside_coverage: int | None = None,
    sentinel: float | None = None,
    metadata: dict[str, Any] | None = None,
    column_names: tuple[str, ...] | list[str] | None = None,
) -> "SparseHealpixMap"

from_region classmethod

from_region(
    region: object,
    nside: int,
    *,
    nest: bool = True,
    nside_coverage: int | None = None,
    value: Any = True,
    sentinel: float | None = False,
    dtype: Any | None = None,
    metadata: dict[str, Any] | None = None,
) -> "SparseHealpixMap"

Create a sparse coverage map from a spherical region.

PixelizedRegion inputs preserve exact pixels at matching resolution and otherwise use MOC flattening at the requested resolution. Exact regions are pixelized through their pixelize or query_pixels method via :meth:torchsky.sphere.moc.MOC.from_region.

from_wcs classmethod

from_wcs(
    wcs: Any,
    nside: int,
    *,
    shape: tuple[int, int] | None = None,
    weight: Tensor | None = None,
    mask: Tensor | None = None,
    nside_coverage: int | None = None,
    nest: bool = True,
) -> "SparseHealpixMap"

Build a SparseHealpixMap coverage/weight map from a 2D WCS and optional weight/mask.

get_column

get_column(name: str | int) -> 'SparseHealpixMap'

Extract a single named or indexed column as a 1D SparseHealpixMap.

get_covered_pixels

get_covered_pixels() -> Tensor

get_values

get_values(pixels: Tensor) -> Tensor

get_values_pos

get_values_pos(
    lon_or_theta: Tensor | float,
    lat_or_phi: Tensor | float,
    *,
    lonlat: bool = True,
    valid_mask: bool = False,
) -> Tensor | tuple[Tensor, Tensor]

Look up sparse map values at sky coordinates.

interpolate

interpolate(
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
    *,
    method: Literal["nearest", "bilinear"] = "bilinear",
) -> Tensor

lookup_radec

lookup_radec(
    ra_deg: Tensor | float, dec_deg: Tensor | float
) -> tuple[Tensor, Tensor]

Return (values, valid_mask) at (ra_deg, dec_deg).

lookup_with_valid

lookup_with_valid(pixels: Tensor) -> tuple[Tensor, Tensor]

Return (values, valid_mask) for queried pixel indices.

make_empty classmethod

make_empty(
    nside_coverage: int,
    nside_map: int,
    dtype: Any = float64,
    sentinel: float | None = None,
    metadata: dict[str, Any] | None = None,
    column_names: tuple[str, ...] | list[str] | None = None,
) -> "SparseHealpixMap"

Create an empty SparseHealpixMap with specified configuration.

prepare_random_sampler

prepare_random_sampler(
    *,
    weights: SparseHealpixMap | Tensor | str | None = None,
    device: device | str | None = None,
) -> PreparedRandomSampler

Snapshot immutable, device-bound state for repeated random draws.

Pixels, ordering conversion, and resolved weights are captured during preparation. Later mutation of this map or weight tensors does not update the sampler; call this method again to observe changes.

read_fits classmethod

read_fits(filename: str) -> 'SparseHealpixMap'

Read HealSparse COV+SPARSE images or a PIXEL/VALUE table.

sample_randoms

sample_randoms(
    n: int,
    *,
    weights: Tensor | str | None = None,
    generator: Generator | None = None,
    device: device | str | None = None,
) -> tuple[Tensor, Tensor]

Draw n points uniformly in solid angle (or weighted) inside this sparse map.

to_dense

to_dense(fill_value: float | None = None) -> Tensor

to_healsparse

to_healsparse() -> Any

Export to healsparse.HealSparseMap when healsparse is installed.

to_moc

to_moc() -> 'MOC'

Create a MOC from this sparse map's coverage.

to_pixelized_region

to_pixelized_region(
    nside: int | None = None, *, nest: bool | None = None
) -> "PixelizedRegion"

Expose sparse-map coverage as a PixelizedRegion.

Same-resolution conversions only change HEALPix ordering. Different resolutions go through MOC coverage normalization, avoiding dense masks.

ud_grade

ud_grade(
    nside_out: int,
    *,
    pess: bool = False,
    power: float | None = None,
    fill_value: float | None = None,
    reduction: str | None = None,
) -> "SparseHealpixMap"

update_values_pix

update_values_pix(pixels: Tensor, values: Tensor) -> None

Update existing or add new pixels to the sparse map.

write_fits

write_fits(filename: str, overwrite: bool = False) -> None

Write a HealSparse FITS file via torchfits (COV + SPARSE images).

Maps with a 1-D value vector write PIXTYPE=HEALSPARSE COV+SPARSE images. Coverage nside is taken from nside_coverage when set, otherwise max(1, nside // 16) (pixel-list maps). Multidimensional values are rejected because HealSparse image layout is one-dimensional.

WideBitMask

WideBitMask(n_bits: int, device: device | None = None)

Multiword bit mask for flag sets wider than one integer dtype.

device instance-attribute

device = device

n_bits instance-attribute

n_bits = n_bits

n_words instance-attribute

n_words = (n_bits + 64 - 1) // 64

create_null

create_null(n_pixels: int) -> Tensor

sum_intersection

sum_intersection(
    maps: list[SparseHealpixMap]
    | tuple[SparseHealpixMap, ...],
) -> SparseHealpixMap

Sum sparse maps only where every input has a valid pixel.

sum_union

sum_union(
    maps: list[SparseHealpixMap]
    | tuple[SparseHealpixMap, ...],
) -> SparseHealpixMap

Sum sparse maps over the union of valid pixels.

Missing pixels contribute zero, matching the common healsparse sum_union workflow while preserving sparse coverage on the output.

Spectral axes

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

alm2cl

alm2cl(
    alms1: Tensor | list[complex] | list[list[complex]],
    alms2: Tensor
    | list[complex]
    | list[list[complex]]
    | None = None,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    lmax_out: int | None = None,
    nspec: int | None = None,
) -> Tensor

Compute auto/cross power spectra from alm coefficients.

For a single alm input vector, returns shape (lmax_out+1,). For multiple inputs, returns stacked spectra in healpy-compatible ordering.

alm2lonlat

alm2lonlat(
    alm_values: Tensor
    | list[complex]
    | list[list[complex]],
    lon_deg: Tensor | list[float] | float,
    lat_deg: Tensor | list[float] | float,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
) -> Tensor

Evaluate scalar alm coefficients at arbitrary sky coordinates.

alm2lonlat_spin

alm2lonlat_spin(
    alms: tuple[Tensor, Tensor],
    spin: int,
    lon_deg: Tensor | list[float] | float,
    lat_deg: Tensor | list[float] | float,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
) -> Tensor

Evaluate spin-weighted alm coefficients at arbitrary sky coordinates.

alm2map

alm2map(
    alm_values: Tensor
    | list[complex]
    | list[list[complex]],
    nside: int,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    pol: bool = False,
    pixwin: bool = False,
) -> Tensor

Synthesize HEALPix map(s) from alm coefficients.

For scalar maps, m>0 terms use the real-map relation 2*Re(a_lm Y_lm). With pol=True, alm_values must be shape (3, nalm) in (T,E,B) order. Alms on CPU use fused C++. CUDA/MPS keep alms on device (ATen ring FFT).

alm2map_batched

alm2map_batched(
    alms: Tensor,
    nside: int,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    pol: bool = False,
    pixwin: bool = False,
) -> Tensor

Batched map synthesis with explicit leading batch dimension.

Scalar alms must be shaped (B, nalm) and return (B, npix). With pol=True, alms must be (B, 3, nalm) in (T,E,B) order and the result is (B, 3, npix).

alm2map_der1

alm2map_der1(
    alm_values: Tensor | list[complex],
    nside: int,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
) -> tuple[Tensor, Tensor, Tensor]

Synthesize a map and its first angular derivatives from scalar alm.

Returns (map, d_theta, d_phi) with healpy semantics: d_phi is already divided by sin(theta). Derivatives use the spin-1 relation a_{E,lm} = sqrt(l(l+1)) a_{lm} (B=0) via :func:alm2map_spin, not finite differences on the map.

alm2map_spin

alm2map_spin(
    alms: tuple[Tensor, Tensor],
    nside: int,
    spin: int,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
) -> Tensor

Spin-weighted alm->map transform (Q/U-like pair).

Returns tensor of shape (2, npix).

alm_index

alm_index(
    ell: int, m: int, lmax: int, mmax: int | None = None
) -> int

Return flat alm index for mode (ell, m) in healpy ordering.

alm_size

alm_size(lmax: int, mmax: int | None = None) -> int

Return number of alm coefficients in healpy ordering.

almxfl

almxfl(
    alm_values: Tensor
    | list[complex]
    | list[list[complex]],
    fl: Tensor | list[float],
    *,
    mmax: int | None = None,
    inplace: bool = False,
) -> Tensor

Multiply alm coefficient(s) by an ell-dependent transfer function.

Behaves like healpy's almxfl: if fl is shorter than lmax+1, missing multipliers are treated as zero; extra entries are ignored.

map2alm

map2alm(
    map_values: Tensor | list[float] | list[list[float]],
    *,
    nside: int | None = None,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    iter: int = 0,
    pol: bool = False,
    use_weights: bool = False,
    use_pixel_weights: bool = False,
    gal_cut: float = 0.0,
    datapath: str | PathLike[str] | None = None,
) -> Tensor

Compute alm coefficients in healpy ordering (m>=0 only).

With pol=True, input map must be shape (3, npix) and return is shape (3, nalm) in (T,E,B) ordering.

use_weights applies computed RING quadrature (mean 1). use_pixel_weights loads HEALPix full-pixel weight FITS via torchfits from datapath or TORCHSKY_HEALPIX_DATAPATH (full_weights/healpix_full_weights_nside_NNNN.fits) and multiplies by 1 + w. Missing files raise; nothing is downloaded. gal_cut zeros pixels whose RING-scheme latitude is below gal_cut degrees (healpy convention). CPU uses fused Ishioka/Wigner C++. CUDA/MPS keep maps on device (ATen ring FFT); they are not host-copied.

map2alm_batched

map2alm_batched(
    maps: Tensor,
    *,
    nside: int | None = None,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    iter: int = 0,
    pol: bool = False,
    use_weights: bool = False,
    use_pixel_weights: bool = False,
    gal_cut: float = 0.0,
    datapath: str | PathLike[str] | None = None,
) -> Tensor

Batched harmonic analysis with explicit leading batch dimension.

Scalar maps must be shaped (B, npix) and return (B, nalm). With pol=True, maps must be (B, 3, npix) in (T,E,B) order per batch row and the result is (B, 3, nalm).

map2alm_lsq

map2alm_lsq(
    map_values: Tensor | list[float] | list[list[float]],
    lmax: int,
    mmax: int | None = None,
    *,
    nside: int | None = None,
    pol: bool = True,
    tol: float = 1e-10,
    maxiter: int = 20,
    nest: bool = False,
    use_pixel_weights: bool = False,
    gal_cut: float = 0.0,
    datapath: str | PathLike[str] | None = None,
) -> tuple[Tensor, float, int]

Iterative least-squares map analysis up to (lmax, mmax).

Returns (alm, rel_res, n_iter) where rel_res is the residual L2 norm divided by the input map L2 norm.

map2alm_spin

map2alm_spin(
    maps: Tensor,
    spin: int,
    *,
    nside: int | None = None,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    iter: int = 0,
    use_weights: bool = False,
    use_pixel_weights: bool = False,
    gal_cut: float = 0.0,
    datapath: str | PathLike[str] | None = None,
) -> tuple[Tensor, Tensor]

Spin-weighted map->alm transform (Q/U-like pair).

Input maps shape must be (2, npix).

rotate_alm

rotate_alm(
    alm_values: Tensor
    | list[complex]
    | list[list[complex]],
    psi: float,
    theta: float,
    phi: float,
    *,
    lmax: int | None = None,
    mmax: int | None = None,
) -> Tensor

Rotate scalar alm by zyz Euler angles in radians (healpy convention).

Returns a new tensor. Modes with m<0 use a_{l,-m}=(-1)^m conj(a_{l,m}). ponytail: O(lmax^3) Wigner-d loop; fine for lmax used in tests. Batch the recurrence if survey-scale lmax shows up.

Spectral ops

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

anafast

anafast(
    map1: Tensor | list[float],
    map2: Tensor | list[float] | None = None,
    *,
    nside: int | None = None,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    nspec: int | None = None,
    iter: int = 0,
    alm: bool = False,
    pol: bool = True,
    use_weights: bool = False,
    use_pixel_weights: bool = False,
    gal_cut: float = 0.0,
    datapath: str | PathLike[str] | None = None,
) -> (
    Tensor
    | tuple[Tensor, Tensor]
    | tuple[Tensor, Tensor, Tensor]
)

Compute auto- or cross-angular power spectra from full-sky maps.

Parameters:

Name Type Description Default
map1 Tensor | list[float]

Scalar map or polarized map stack.

required
map2 Tensor | list[float] | None

Optional second map for cross spectra.

None
nside int | None

Explicit HEALPix resolution, otherwise inferred from map length.

None
lmax int | None

Maximum output multipole.

None
mmax int | None

Maximum harmonic order.

None
nest bool

Inputs use nested ordering.

False
alm bool

Also return analyzed harmonic coefficients.

False
pol bool

Interpret leading triplets as polarized I/Q/U maps.

True

Returns:

Type Description
Tensor | tuple[Tensor, Tensor] | tuple[Tensor, Tensor, Tensor]

Power spectra, optionally together with harmonic coefficients.

Examples:

>>> from torchsky.sphere import anafast
>>> callable(anafast)
True

beam2bl

beam2bl(
    beam: Tensor | list[float],
    theta: Tensor | list[float],
    lmax: int,
) -> Tensor

Compute harmonic window b_l from circular beam profile b(theta).

bl2beam

bl2beam(
    bl: Tensor | list[float], theta: Tensor | list[float]
) -> Tensor

Compute circular beam profile b(theta) from harmonic window b_l.

gaussian_beam

gaussian_beam(
    fwhm_rad: float, lmax: int, *, pol: bool = False
) -> Tensor

Return Gaussian beam transfer function(s) B_l.

pixwin

pixwin(
    nside: int,
    *,
    pol: bool = False,
    lmax: int | None = None,
) -> Tensor | tuple[Tensor, Tensor]

HEALPix pixel window function(s) w_l, computed from the pixel shapes.

w_l^2 is the average over pixels of each pixel's harmonic power, (1/N) sum_p (1/Omega^2) iint_p P_l(n . n'), the definition behind the HEALPix tables. It is evaluated exactly up to quadrature (better than 1e-12): a terminating hypergeometric series in the pair separation separates l from pixel moments that are integrated with Gauss-Legendre rules on each pixel shape. The polarization window uses the spin-2 kernel d^l_22 with the frame parallel-transported across the pixel.

The moments cost O(nside^2) once per nside (about a minute at nside=2048 on a laptop CPU) and are cached in memory and, from nside=256, under $TORCHSKY_CACHE_DIR/pixwin (default ~/.cache/torchsky/pixwin).

Parameters:

Name Type Description Default
nside int

HEALPix resolution, a power of two up to 8192.

required
pol bool

Also return the polarization window (zero for l < 2).

False
lmax int | None

Largest multipole; default 3 nside - 1, at most 4 nside.

None

Returns:

Type Description
Tensor | tuple[Tensor, Tensor]

Float64 CPU tensor w_l of length lmax + 1, or (w_T, w_P).

Examples:

>>> from torchsky.sphere import pixwin
>>> w = pixwin(16)
>>> w.shape, round(float(w[0]), 12)
(torch.Size([48]), 1.0)

smoothalm

smoothalm(
    alm_values: Tensor
    | list[complex]
    | list[list[complex]],
    *,
    lmax: int | None = None,
    mmax: int | None = None,
    fwhm_rad: float | None = None,
    beam: Tensor | None = None,
    pol: bool = False,
) -> Tensor

Apply scalar/polarized beam smoothing to alm coefficients.

smoothmap

smoothmap(
    map_values: Tensor | list[float] | list[list[float]],
    *,
    nside: int | None = None,
    lmax: int | None = None,
    mmax: int | None = None,
    nest: bool = False,
    fwhm_rad: float | None = None,
    sigma: float | None = None,
    beam: Tensor | None = None,
    beam_window: Tensor | None = None,
    pol: bool = False,
    iter: int = 0,
    use_weights: bool = False,
    use_pixel_weights: bool = False,
    gal_cut: float = 0.0,
    datapath: str | PathLike[str] | None = None,
) -> Tensor

Smooth HEALPix map(s) with scalar or polarized beam.

synalm

synalm(
    cls: Tensor
    | list[Tensor | list[float] | None]
    | tuple[Tensor | list[float] | None, ...],
    lmax: int | None = None,
    mmax: int | None = None,
    *,
    new: bool = False,
) -> Tensor

Generate alm coefficient vector(s) from power spectra.

The covariance factorisation and the Gaussian draw run in float64 on the CPU (so a seed gives the same coefficients on every device); the result is returned on the device of the input spectra (CPU for lists/arrays).

synfast

synfast(
    cls: Tensor
    | list[Tensor | list[float] | None]
    | tuple[Tensor | list[float] | None, ...],
    nside: int,
    lmax: int | None = None,
    mmax: int | None = None,
    *,
    alm: bool = False,
    pol: bool = True,
    pixwin: bool = False,
    fwhm: float = 0.0,
    sigma: float | None = None,
    new: bool = False,
) -> Tensor | tuple[Tensor, Tensor]

Draw and synthesize scalar or polarized maps from power spectra.

Parameters:

Name Type Description Default
cls Tensor | list[Tensor | list[float] | None] | tuple[Tensor | list[float] | None, ...]

Scalar spectrum or polarized spectrum sequence.

required
nside int

Output HEALPix resolution parameter.

required
lmax int | None

Maximum synthesized multipole.

None
mmax int | None

Maximum harmonic order.

None
alm bool

Also return the sampled harmonic coefficients.

False
pol bool

Interpret spectra as polarized when possible.

True
pixwin bool

Apply the HEALPix pixel window.

False
fwhm float

Gaussian smoothing FWHM in radians.

0.0
sigma float | None

Gaussian smoothing sigma in radians, overriding fwhm.

None
new bool

Use the modern polarized-spectrum ordering.

False

Returns:

Type Description
Tensor | tuple[Tensor, Tensor]

Synthesized map tensor, optionally with harmonic coefficients.

Examples:

>>> from torchsky.sphere import synfast
>>> callable(synfast)
True

Stmoc

Torch-native spherical geometry plus healpy-shaped HEALPix compatibility APIs.

Broader astronomy-stack compatibility (Astropy, spherical_geometry, …) is documented in docs/introduction/coming-from.md; healpy-shaped entry points live in :mod:torchsky.sphere.compat.

STMOC dataclass

STMOC(
    time_start_us: Tensor,
    time_end_us: Tensor,
    space: tuple[MOC, ...],
    time_depth: int,
    spatial_depth: int,
)

Space-time coverage: half-open time ranges (µs since JD=0) × spatial MOC.

_time_end_sorted class-attribute instance-attribute

_time_end_sorted: Tensor = field(
    init=False, repr=False, compare=False
)

_time_non_overlapping class-attribute instance-attribute

_time_non_overlapping: bool = field(
    init=False, repr=False, compare=False
)

_time_order class-attribute instance-attribute

_time_order: Tensor = field(
    init=False, repr=False, compare=False
)

_time_start_sorted class-attribute instance-attribute

_time_start_sorted: Tensor = field(
    init=False, repr=False, compare=False
)

n_segments property

n_segments: int

space instance-attribute

space: tuple[MOC, ...]

spatial_depth instance-attribute

spatial_depth: int

time_depth instance-attribute

time_depth: int

time_end_us instance-attribute

time_end_us: Tensor

time_start_us instance-attribute

time_start_us: Tensor

__post_init__

__post_init__() -> None

contains

contains(
    time_mjd: Tensor | float,
    lon_deg: Tensor | float,
    lat_deg: Tensor | float,
) -> Tensor

True where (time, lon, lat) lies in the space-time coverage.

difference

difference(other: 'STMOC') -> 'STMOC'

empty classmethod

empty(
    *, time_depth: int = 0, spatial_depth: int = 0
) -> "STMOC"

filter_catalog

filter_catalog(
    time_mjd: Tensor, lon_deg: Tensor, lat_deg: Tensor
) -> tuple[Tensor, Tensor, Tensor]

from_ascii classmethod

from_ascii(
    text: str, *, spatial_depth: int | None = None
) -> "STMOC"

Parse :meth:to_ascii output. Spatial depth defaults to the MOC max order.

from_spatial_coverages classmethod

from_spatial_coverages(
    t_start_mjd: Tensor | float,
    t_end_mjd: Tensor | float,
    spatial: MOC | tuple[MOC, ...],
    *,
    time_depth: int,
) -> "STMOC"

One spatial MOC per time interval (broadcasts a single MOC).

from_times_positions classmethod

from_times_positions(
    time_mjd: Tensor,
    lon_deg: Tensor,
    lat_deg: Tensor,
    *,
    time_depth: int,
    spatial_depth: int,
) -> "STMOC"

Coverage of catalog samples quantized to time_depth × spatial_depth.

intersection

intersection(other: 'STMOC') -> 'STMOC'

query_by_time

query_by_time(t_start_mjd: float, t_end_mjd: float) -> MOC

Spatial MOC of segments overlapping [t_start_mjd, t_end_mjd).

read_fits classmethod

read_fits(filename: str) -> 'STMOC'

to_ascii

to_ascii() -> str

IVOA-like STMOC ASCII: t<depth>/<c0>-<c1> plus spatial MOC ASCII.

union

union(other: 'STMOC') -> 'STMOC'

write_fits

write_fits(filename: str, overwrite: bool = False) -> None

Write IVOA RANGE packaging: interleaved [min,max) int64 pairs.

Time indices have bit 63 set. Spatial ranges are NESTED pixels at spatial_depth.

mjd_to_time_us

mjd_to_time_us(mjd: Tensor | float) -> Tensor

Convert MJD to integer microseconds since JD=0 (TMOC order-61 index).

time_us_to_mjd

time_us_to_mjd(time_us: Tensor) -> Tensor

Inverse of :func:mjd_to_time_us (sub-microsecond MJD).

Submodules

Module Stability Reference
torchsky.sphere.compat compatibility reference
torchsky.sphere.healpix core reference