Right ascension (\(\alpha\)) and declination (\(\delta\)) are the standard spherical coordinates for describing directions in an inertial frame: \(\alpha\) is measured eastward in the fundamental plane from a reference direction, and \(\delta\) is measured perpendicular to that plane. Brahe's RA/Dec functions are frame-agnostic - they convert between the spherical \((\alpha, \delta, r)\) representation and whatever Cartesian inertial frame the caller supplies. For star catalog positions (FK5, Hipparcos, Tycho-2) that frame is ICRS/GCRF; for other applications it can be any inertial frame consistent with the input Cartesian state.
Right ascension is normalized to \([0, 360)\) degrees (or \([0, 2\pi)\) radians). At the polar singularity (\(x = y = 0\)), \(\alpha\) is indeterminate from position alone and position_inertial_to_radec returns 0; use the state-based conversion below to resolve it from velocity instead.
Including velocity extends the position relations to their rates. Converting \((\alpha, \delta, r, \dot\alpha, \dot\delta, \dot r)\) to Cartesian state:
\[ \dot{z} = \dot r \sin\delta + r\cos\delta\,\dot\delta \]
with \(x, y, z\) given by the Eq. 4-1 position relation above. The inverse (Cartesian state to \(\alpha, \delta, r\) and rates) resolves the polar singularity using velocity rather than returning \(\alpha = 0\):
Inertial state: pos=[4286607.050, 4286607.050, 3500000.000] m
vel=[-501.561970, 994.746166, -504.024815] m/s
RA/Dec round-trip: ra=45.000000 deg, dec=30.000000 deg, range=7000000.000 m
ra_dot=0.010000 deg/s, dec_dot=-0.005000 deg/s, range_dot=50.000 m/s
Topocentric line of sight: ra=31.654779 deg, dec=14.702943 deg, range=1969995.939 m
Inertial state: pos=[4286607.050, 4286607.050, 3500000.000] m
vel=[-501.561970, 994.746166, -504.024815] m/s
RA/Dec round-trip: ra=45.000000 deg, dec=30.000000 deg, range=7000000.000 m
ra_dot=0.010000 deg/s, dec_dot=-0.005000 deg/s, range_dot=50.000 m/s
Topocentric line of sight: ra=31.654779 deg, dec=14.702943 deg, range=1969995.939 m
The RA/Dec conversions above assume the input position/state is already relative to the frame's origin. For a ground-based observation, the object's position must first be made relative to the observing site: subtract the site's inertial position (or state) from the object's before converting.
This subtract-then-convert pattern is the vector form of Vallado Algorithm 26 (Topocentric): applying state_inertial_to_radec to the slant-range vector \(\vec{r}_{\text{sat}} - \vec{r}_{\text{site}}\) is equivalent to running Algorithm 25 directly on that vector, because the topocentric frame's axes are parallel to the geocentric inertial frame - only the origin is translated to the site.
# A satellite and an observing site, both as Cartesian inertial states (m, m/s)x_sat=np.array([8000e3,1000e3,500e3,-1000.0,7000.0,2000.0])x_site=np.array([6378e3,0.0,0.0,0.0,0.0,0.0])x_topocentric=x_sat-x_sitex_radec_topo=bh.state_inertial_to_radec(x_topocentric,bh.AngleFormat.DEGREES)print(f"\nTopocentric line of sight: ra={x_radec_topo[0]:.6f} deg, "f"dec={x_radec_topo[1]:.6f} deg, range={x_radec_topo[2]:.3f} m")
// A satellite and an observing site, both as Cartesian inertial states (m, m/s)letx_sat=na::SVector::<f64,6>::new(8000e3,1000e3,500e3,-1000.0,7000.0,2000.0);letx_site=na::SVector::<f64,6>::new(6378e3,0.0,0.0,0.0,0.0,0.0);letx_topocentric=x_sat-x_site;letx_radec_topo=bh::state_inertial_to_radec(x_topocentric,bh::AngleFormat::Degrees);println!("\nTopocentric line of sight: ra={:.6} deg, dec={:.6} deg, range={:.3} m",x_radec_topo[0],x_radec_topo[1],x_radec_topo[2]);
This continues the same radec_state_transforms example above - see its output for the resulting topocentric line of sight.
For stars, which are effectively at infinite range, this correction is unnecessary: the geocentric catalog \((\alpha, \delta)\) and the topocentric \((\alpha, \delta)\) are the same to any achievable precision, so position_radec_to_azel can be called directly on the catalog values.
position_radec_to_azel and position_azel_to_radec rotate a topocentric line-of-sight direction between the equatorial \((\alpha, \delta)\) representation and the local horizon azimuth-elevation representation. Both conversions are direction-only: no parallax translation between the geocenter and the site is applied (the site's altitude does not affect the result), range passes through unchanged, and a global EOP provider must be initialized for the inertial ↔ Earth-fixed rotation.
Azimuth is measured clockwise from North. This is the same convention used by the Topocentric Coordinates ENZ/SEZ-to-azimuth-elevation functions, so position_radec_to_azel results are directly comparable to position_enz_to_azel/position_sez_to_azel results.
Catalog positions are only valid at their reference epoch. apply_proper_motion propagates \((\alpha, \delta)\) from a catalog epoch to a target epoch using IAU SOFA's iauPmsafe space-motion routine, given the star's proper motion and, when available, its parallax and radial velocity.
iauPmsafe reconstructs the star's full barycentric position/velocity (pv-)state from the catalog \((\alpha, \delta)\), proper motion, parallax, and radial velocity; advances it assuming straight-line motion at constant velocity - including a light-time correction and the special-relativistic (Doppler) treatment of Stumpff (1985) - and reduces the result back to catalog \((\alpha, \delta)\) at the target epoch. The pm_ra argument follows the standard catalog convention \(\mu_{\alpha*} = \mu_\alpha \cos\delta\) (matching the pmRA/pmDE columns of Hipparcos, Tycho-2, Gaia, and most other catalogs), not the raw coordinate rate \(\dot\alpha\). When parallax or radial_velocity is unavailable it is treated as zero; iauPmsafe additionally applies a proper-motion-scaled minimum-parallax guard so a star with a missing or tiny parallax still propagates correctly rather than being clamped to a no-op.
To first order the direction change iauPmsafe produces is the rigorous epoch transformation of ESA SP-1200 §1.5.5. The star's unit direction \(\hat{u}_0\) moves in the tangent plane spanned by
driven by the tangential proper-motion vector \(\vec{\mu} = \hat{p}\,\mu_{\alpha*} + \hat{q}\,\mu_\delta\) (with \(\mu_{\alpha*}\), \(\mu_\delta\) converted from mas/yr to rad/yr) and a radial "perspective-acceleration" term \(\mu_r\) that captures the change in angular rate as the star's line-of-sight distance changes:
where \(v_r\) is the radial velocity (km/s), \(\varpi_{\text{rad}}\) is the parallax in radians, and \(4.740470446\ \text{km/s}\) is the speed of one astronomical unit per year. The perspective term is significant only for high radial-velocity, high-parallax stars such as Barnard's Star; when parallax or radial velocity is unknown it vanishes and the propagation reduces to purely linear proper motion. iauPmsafe goes beyond this first-order model by carrying the full pv-state and adding the light-time and Doppler corrections noted above.
The worked example above (Position Conversions) continues past the round-trip check to call apply_proper_motion on Barnard's Star, propagating it 10 years forward using its Hipparcos catalog proper motion, parallax, and radial velocity - see its output for the resulting \((\alpha, \delta)\) shift.
Reference
Proper motion propagation is performed by IAU SOFA's iauPmsafe (SOFA Tools for Earth Attitude, 2023); the underlying epoch-transformation theory is ESA, The Hipparcos and Tycho Catalogues, ESA SP-1200, Vol. 1, §1.5.5, 1997. The RA/Dec position, state, and topocentric conversions follow D. Vallado, Fundamentals of Astrodynamics and Applications, 4th Ed., §4.4 (Eq. 4-1, Eq. 4-2, Algorithm 25, Algorithm 26), 2013.
Star catalog records expose this transformation directly via radec_at_epoch - see Star Catalogs.