Pyerfa
PyERFA provides Python bindings for the ERFA library (Essential Routines for Fundamental Astronomy), a C library based on the IAU SOFA library. It wraps ERFA's C routines as NumPy universal functions, allowing them to be called with scalar or array inputs. The library is actively maintained, with frequent patch releases addressing compatibility, especially with NumPy versions. The current version is 2.0.1.5.
Warnings
- breaking PyERFA 2.0.0 introduced a significant breaking change: it cannot run with previous versions of the `liberfa` C library due to an update to `liberfa v2.0.0`. Ensure that the `pyerfa` and `liberfa` versions are compatible, especially if attempting to use a system-installed `liberfa`.
- breaking NumPy 2.0 introduces Application Binary Interface (ABI) breaking changes. This means `pyerfa` binaries built against NumPy 1.x will not work with NumPy 2.0, potentially causing `ImportError` due to binary incompatibility. PyERFA has released specific versions (`2.0.1.3`, `2.0.1.4`) to provide wheels compatible with both NumPy 1.x and 2.0.
- gotcha Older NumPy versions might not be compatible with recent `pyerfa` releases. For instance, `pyerfa 2.0.0.3` explicitly ensured compatibility with `numpy >= 1.17`. Using `pyerfa` with very old NumPy versions can lead to build or runtime errors.
- gotcha Since `v2.0.1`, PyERFA transitioned to using only the Python limited API. While this generally improves forward compatibility, it might affect very specialized integrations that rely on specific Python-C API details not exposed by the limited API.
- gotcha A dangling pointer issue was fixed in `pyerfa v2.0.1` that could lead to unexpected behavior, especially when compiling projects that use `pyerfa` with the `-O3` optimization flag.
Install
-
pip install pyerfa
Imports
- erfa
import erfa
Quickstart
import erfa
# Convert Julian Date to Calendar Date
julian_date = 2460000.0
calendar_result = erfa.jd2cal(julian_date, [0]) # The second argument is for fractional days, here 0 for simplicity
print(f"Julian Date {julian_date} corresponds to year={calendar_result.iy[0]}, month={calendar_result.im[0]}, day={calendar_result.id[0]}, fraction={calendar_result.fd[0]}")
# Example of a planet's heliocentric position and velocity
# erfa.plan94(jd1, jd2, planet_id) where jd1+jd2 is Julian Date, planet_id (1=Mercury, ..., 9=Pluto)
position_velocity = erfa.plan94(julian_date, 0.0, 1) # Mercury
print(f"Mercury's position (x, y, z): {position_velocity['p'][0]}")
print(f"Mercury's velocity (vx, vy, vz): {position_velocity['v'][0]}")