Skip to content

torchsky.coords

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

Sky geometry facade. Kernels live in torchsky.wcs.

Guides: frames, coordinates


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.coords unless the group text says otherwise.

Catalog state

Sky geometry facade. Kernels live in torchsky.wcs.

Projects import torchsky.coords for catalog frames, observed place, and propagation. FITS WCS stays torchsky.wcs. This is not a SkyCoord graph and not torchsky.transforms (image ops).

CatalogState dataclass

CatalogState(
    lon: Tensor,
    lat: Tensor,
    frame: str = "ICRS",
    epoch: Tensor | float | Epoch = 2000.0,
    epoch_scale: TimeScale | None = None,
    epoch_format: TimeFormat | None = None,
    pm_lon_coslat_mas_yr: Tensor | None = None,
    pm_lat_mas_yr: Tensor | None = None,
    parallax_mas: Tensor | None = None,
    radial_velocity_km_s: Tensor | None = None,
    valid: Tensor | None = None,
)

Batched sky state with explicit missing components.

Missing proper motion, parallax, or radial velocity stay None. They are never filled from a default distance or a pmsafe override. valid is an optional boolean mask; it is never used to impute values.

epoch class-attribute instance-attribute

epoch: Tensor | float | Epoch = 2000.0

epoch_format class-attribute instance-attribute

epoch_format: TimeFormat | None = None

epoch_scale class-attribute instance-attribute

epoch_scale: TimeScale | None = None

frame class-attribute instance-attribute

frame: str = 'ICRS'

lat instance-attribute

lat: Tensor

lon instance-attribute

lon: Tensor

parallax_mas class-attribute instance-attribute

parallax_mas: Tensor | None = None

pm_lat_mas_yr class-attribute instance-attribute

pm_lat_mas_yr: Tensor | None = None

pm_lon_coslat_mas_yr class-attribute instance-attribute

pm_lon_coslat_mas_yr: Tensor | None = None

radial_velocity_km_s class-attribute instance-attribute

radial_velocity_km_s: Tensor | None = None

valid class-attribute instance-attribute

valid: Tensor | None = None

__post_init__

__post_init__() -> None

_target_epoch_value

_target_epoch_value(
    epoch: Tensor | float | Epoch,
) -> Tensor

propagate_angular

propagate_angular(
    epoch: Tensor | float | Epoch,
) -> CatalogState

propagate_physical

propagate_physical(
    epoch: Tensor | float | Epoch,
) -> CatalogState

to_frame

to_frame(
    frame: str, *, tt_mjd: Tensor | float | None = None
) -> CatalogState

to_representation

to_representation(
    kind: Representation = "lonlat_deg",
) -> Tensor

Coords

Sky geometry facade. Kernels live in torchsky.wcs.

Projects import torchsky.coords for catalog frames, observed place, and propagation. FITS WCS stays torchsky.wcs. This is not a SkyCoord graph and not torchsky.transforms (image ops).

transform

transform(
    lon: Any,
    lat: Any,
    *,
    from_frame: str,
    to_frame: str,
    obstime_mjd_utc: Any | None = None,
    site: Site | None = None,
    eop: EarthOrientation | None = None,
    pn: PNModel | None = None,
    aberration: bool = False,
    refraction: bool = False,
    refraction_model: RefractionModel = "refco",
) -> tuple[Tensor, Tensor]

Rotate or observe (lon, lat) tensors. Returns (lon_out, lat_out).

Geometric frames use CatalogState.to_frame. ALTAZ, ITRS, GCRS, CIRS, and TETE require obstime_mjd_utc and eop. ECLIPTIC_OF_DATE uses TT MJD (obstime_mjd_utc is treated as TT unless you pass a TT value through CatalogState.to_frame).

Parameters:

Name Type Description Default
lon Any

Longitude values in degrees.

required
lat Any

Latitude values in degrees.

required
from_frame str

Input coordinate-frame name.

required
to_frame str

Output coordinate-frame name.

required
obstime_mjd_utc Any | None

Observation time in UTC MJD, or TT MJD for ecliptic-of-date.

None
site Site | None

Observing site required for altitude-azimuth output.

None
eop EarthOrientation | None

Earth-orientation parameters required for observed frames.

None
pn PNModel | None

Precession-nutation model.

None
aberration bool

Apply annual aberration for supported observed frames.

False
refraction bool

Apply atmospheric refraction to altitude-azimuth output.

False
refraction_model RefractionModel

"refco" (ERFA, default; uses Site humidity and wavelength) or "saemundsson".

'refco'

Returns:

Type Description
tuple[Tensor, Tensor]

Output longitude and latitude tensors in degrees.

Examples:

>>> import torch
>>> from torchsky.coords import transform
>>> lon, lat = transform(torch.tensor([0.0]), torch.tensor([0.0]), from_frame="ICRS", to_frame="GALACTIC")
>>> lon.shape == lat.shape
True

Celestial frames

Sky geometry facade. Kernels live in torchsky.wcs.

Projects import torchsky.coords for catalog frames, observed place, and propagation. FITS WCS stays torchsky.wcs. This is not a SkyCoord graph and not torchsky.transforms (image ops).

convert_celestial

convert_celestial(
    lon_deg: Any,
    lat_deg: Any,
    *,
    from_frame: str = "ICRS",
    to_frame: str = "ICRS",
    from_equinox: float | None = None,
    to_equinox: float | None = None,
    tt_mjd: Any | None = None,
) -> tuple[Tensor, Tensor]

Convert between the currently supported celestial frames.

heliocentric_rv_to_lsr

heliocentric_rv_to_lsr(
    ra_deg: Any,
    dec_deg: Any,
    rv_kms: Any,
    *,
    solar_u_kms: float = _SOLAR_U_KMS,
    solar_v_kms: float = _SOLAR_V_KMS,
    solar_w_kms: float = _SOLAR_W_KMS,
) -> Tensor

Heliocentric radial velocity → LSR (km/s) with explicit solar UVW.

icrs_to_ecliptic_of_date

icrs_to_ecliptic_of_date(
    ra_deg: Any, dec_deg: Any, tt_mjd: Any
) -> tuple[Tensor, Tensor]

Rotate ICRS to the mean ecliptic of date via IAU 2006 NPB.

tt_mjd is TT MJD. This is a geometric frame, not observed place: no aberration, refraction, or site.

icrs_to_galactocentric

icrs_to_galactocentric(
    ra_deg: Any,
    dec_deg: Any,
    distance_kpc: Any,
    *,
    galcen_distance_kpc: float = _GALCEN_DISTANCE_KPC,
    galcen_ra_deg: float = _GALCEN_RA_DEG,
    galcen_dec_deg: float = _GALCEN_DEC_DEG,
    z_sun_pc: float = _Z_SUN_PC,
) -> Tensor

Heliocentric ICRS spherical → Galactocentric Cartesian (kpc).

Origin at the Galactic Centre (galcen_ra_deg / galcen_dec_deg). +x toward the anticenter (Sun at x ≈ -R0), +y in rotation, +z toward the NGP. z_sun_pc tilts the midplane so the Sun sits at z = z_sun. Solar peculiar velocity is not applied.

propagate_proper_motion

propagate_proper_motion(
    lon_deg: Any,
    lat_deg: Any,
    pm_lon_coslat_mas_yr: Any,
    pm_lat_mas_yr: Any,
    *,
    source_epoch_jyear: Any,
    target_epoch_jyear: Any,
) -> tuple[Tensor, Tensor]

Propagate angular coordinates with proper motion.

pm_lon_coslat_mas_yr is the conventional longitude proper motion with the cosine-of-latitude factor already applied (for ICRS, pm_ra_cosdec). Epochs are Julian years. Inputs broadcast and outputs are longitude and latitude in degrees, with longitude wrapped to [0, 360).

This follows the same unit-distance Cartesian propagation used by SkyCoord.apply_space_motion when distance and radial velocity are not supplied. It stays well behaved at the poles, unlike dividing a longitude increment by cos(latitude).

Parameters:

Name Type Description Default
lon_deg Any

Initial longitude in degrees.

required
lat_deg Any

Initial latitude in degrees.

required
pm_lon_coslat_mas_yr Any

Cosine-weighted longitude proper motion in mas/yr.

required
pm_lat_mas_yr Any

Latitude proper motion in mas/yr.

required
source_epoch_jyear Any

Initial Julian epoch.

required
target_epoch_jyear Any

Destination Julian epoch.

required

Returns:

Type Description
tuple[Tensor, Tensor]

Propagated longitude and latitude tensors in degrees.

Examples:

>>> from torchsky.wcs import propagate_proper_motion
>>> lon, lat = propagate_proper_motion(10.0, 20.0, 0.0, 0.0, source_epoch_jyear=2000.0, target_epoch_jyear=2010.0)
>>> round(float(lon), 6), round(float(lat), 6)
(10.0, 20.0)

propagate_space_motion

propagate_space_motion(
    lon_deg: Any,
    lat_deg: Any,
    pm_lon_coslat_mas_yr: Any,
    pm_lat_mas_yr: Any,
    parallax_mas: Any,
    radial_velocity_km_s: Any,
    *,
    source_epoch_jyear: Any,
    target_epoch_jyear: Any,
) -> tuple[Tensor, Tensor, Tensor, Tensor, Tensor, Tensor]

Propagate a complete barycentric astrometric state in ICRS.

Inputs and outputs are longitude/latitude in degrees, cosine-weighted longitude and latitude proper motions in mas/yr, parallax in mas, and radial velocity in km/s. Epochs are TCB Julian years. Inputs broadcast.

The implementation follows the ERFA/SOFA starpv to rectilinear motion with changing light time to pvstar model, including the special- relativistic conversion between catalogue observables and inertial velocity. A complete state is required: use :func:propagate_proper_motion when distance or radial velocity is unavailable.

Returns:

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

(lon, lat, pm_lon_coslat, pm_lat, parallax, radial_velocity).

Parameters:

Name Type Description Default
lon_deg Any

Initial ICRS longitude in degrees.

required
lat_deg Any

Initial ICRS latitude in degrees.

required
pm_lon_coslat_mas_yr Any

Cosine-weighted longitude proper motion in mas/yr.

required
pm_lat_mas_yr Any

Latitude proper motion in mas/yr.

required
parallax_mas Any

Parallax in milliarcseconds.

required
radial_velocity_km_s Any

Radial velocity in km/s.

required
source_epoch_jyear Any

Initial TCB Julian epoch.

required
target_epoch_jyear Any

Destination TCB Julian epoch.

required

Examples:

>>> from torchsky.wcs import propagate_space_motion
>>> result = propagate_space_motion(10.0, 20.0, 0.0, 0.0, 10.0, 0.0, source_epoch_jyear=2000.0, target_epoch_jyear=2000.0)
>>> len(result)
6

Iau2006

Sky geometry facade. Kernels live in torchsky.wcs.

Projects import torchsky.coords for catalog frames, observed place, and propagation. FITS WCS stays torchsky.wcs. This is not a SkyCoord graph and not torchsky.transforms (image ops).

apply_dcr

apply_dcr(
    ra_deg: Tensor,
    dec_deg: Tensor,
    wavelength_angstrom: Tensor | float,
    zenith_deg: Tensor | float,
    parallactic_deg: Tensor | float = 0.0,
    *,
    ref_wavelength_angstrom: float = 5000.0,
    pressure_mbar: float = 780.0,
    temperature_c: float = 10.0,
    inverse: bool = False,
) -> tuple[Tensor, Tensor]

Apply or remove Differential Chromatic Refraction on (ra_deg, dec_deg).

apply_ephemeris_offset

apply_ephemeris_offset(
    ra_deg: Tensor,
    dec_deg: Tensor,
    *,
    mjd_obs: float,
    reference_mjd: float,
    tracking_rate: tuple[float, float] | None = None,
    dra_cosdec_arcsec_per_hr: float = 0.0,
    ddec_arcsec_per_hr: float = 0.0,
    inverse: bool = False,
) -> tuple[Tensor, Tensor]

Shift sky coordinates into (or out of) a moving target's comoving frame.

Parameters

tracking_rate (dra_cosdec_arcsec_per_hr, ddec_arcsec_per_hr) non-sidereal rate. inverse If False (default), maps sidereal sky coordinates at mjd_obs into the comoving target frame at reference_mjd (subtracting target motion). If True, maps comoving coordinates back to sidereal coordinates at mjd_obs.

apply_refraction

apply_refraction(
    alt_deg: Tensor,
    *,
    pressure_mbar: Tensor | float,
    temperature_c: Tensor | float,
) -> Tensor

Apply atmospheric refraction to altitude in degrees.

apply_stellar_aberration

apply_stellar_aberration(
    unit_xyz: Tensor, velocity_m_s: Tensor
) -> Tensor

Classical stellar aberration: normalize(p + v/c).

dcr_offset

dcr_offset(
    wavelength_angstrom: Tensor | float,
    zenith_deg: Tensor | float,
    parallactic_deg: Tensor | float = 0.0,
    *,
    ref_wavelength_angstrom: float = 5000.0,
    pressure_mbar: float = 780.0,
    temperature_c: float = 10.0,
) -> tuple[Tensor, Tensor]

Compute Differential Chromatic Refraction (DCR) tangent-plane offset (d_east_deg, d_north_deg).

Returns the apparent chromatic shift toward zenith at wavelength_angstrom relative to ref_wavelength_angstrom in degrees along local East and North.

Observed

Sky geometry facade. Kernels live in torchsky.wcs.

Projects import torchsky.coords for catalog frames, observed place, and propagation. FITS WCS stays torchsky.wcs. This is not a SkyCoord graph and not torchsky.transforms (image ops).

EarthOrientation dataclass

EarthOrientation(
    dut1_s: Tensor,
    xp_arcsec: Tensor | None = None,
    yp_arcsec: Tensor | None = None,
    tt_minus_utc_s: Tensor | None = None,
)

IERS Earth orientation. dut1_s is required.

Polar motion xp_arcsec / yp_arcsec is optional. If either is set, both are applied (missing member treated as 0) via SOFA pom00 with TIO locator s' = 0. tt_minus_utc_s overrides TT−UTC; when it is None, TT−UTC is 32.184 s + TAI−UTC from torchsky's leap-second table, and epochs outside that table (before 1972 or after its expiry) raise ValueError.

dut1_s instance-attribute

dut1_s: Tensor

tt_minus_utc_s class-attribute instance-attribute

tt_minus_utc_s: Tensor | None = None

xp_arcsec class-attribute instance-attribute

xp_arcsec: Tensor | None = None

yp_arcsec class-attribute instance-attribute

yp_arcsec: Tensor | None = None

__post_init__

__post_init__() -> None

Site dataclass

Site(
    lon_deg: Tensor,
    lat_deg: Tensor,
    height_m: Tensor | float = 0.0,
    pressure_mbar: Tensor | float | None = None,
    temperature_c: Tensor | float | None = None,
    relative_humidity: Tensor | float = 0.0,
    wavelength_um: Tensor | float = 0.55,
)

Geodetic site. Height is WGS84 ellipsoidal height (metres) on the ITRS path.

relative_humidity (0..1) and wavelength_um (> 100 selects the radio formula) only enter the ERFA refco refraction model.

height_m class-attribute instance-attribute

height_m: Tensor | float = 0.0

lat_deg instance-attribute

lat_deg: Tensor

lon_deg instance-attribute

lon_deg: Tensor

pressure_mbar class-attribute instance-attribute

pressure_mbar: Tensor | float | None = None

relative_humidity class-attribute instance-attribute

relative_humidity: Tensor | float = 0.0

temperature_c class-attribute instance-attribute

temperature_c: Tensor | float | None = None

wavelength_um class-attribute instance-attribute

wavelength_um: Tensor | float = 0.55

__post_init__

__post_init__() -> None

observed_altaz

observed_altaz(
    state: CatalogState,
    *,
    obstime_mjd_utc: Any,
    site: Site,
    eop: EarthOrientation,
    pn: PNModel | None = None,
    aberration: bool = False,
    refraction: bool = False,
    refraction_model: RefractionModel = "refco",
) -> tuple[Tensor, Tensor]

Return (az_deg, alt_deg) from north toward east.

obstime_mjd_utc is UTC MJD. UT1 = UTC + DUT1. Polar motion is applied when xp/yp are set.

pn=None (default) and pn='iau2006' apply Fukushima-Williams bias-precession and IAU 2000A nutation via the CIRS matrix; with aberration=True this matches astropy AltAz to about 1 arcsec. TT−UTC is eop.tt_minus_utc_s when set, otherwise 32.184 s + TAI−UTC from torchsky's leap-second table; an epoch outside that table (before 1972, or after its expiry) raises ValueError rather than guessing. pn='none' is an explicit opt-in that omits precession-nutation and uses GMST; it is approximate (~0.3 deg off) and is continuous in xp/yp (zero polar motion equals no polar motion). aberration=True converts the astrometric ICRS direction to the apparent place as ERFA atciq does: solar light deflection plus annual and diurnal aberration (the observer's Earth-rotation velocity), with the epv00 Earth ephemeris. Without refraction the result agrees with erfa.atco13 to < 1 mas (residual: TIO locator s' = 0, observer offset in the solar deflection, TT used for TDB). refraction=True applies the ERFA refco model (A tan z + B tan^3 z, honouring site.relative_humidity and site.wavelength_um) to the topocentric direction as atioq does; refraction_model="saemundsson" selects the Saemundsson/Meeus altitude formula instead. Both are off unless requested and need site.pressure_mbar and site.temperature_c.

Time-only quantities are evaluated in float64 on CPU on every device; only the final rotation matrices move to the coordinate device (CUDA float64, MPS float32). Gradients flow through the coordinates. The kernels are ATen, not fused C++.