Astro
Library to help working with SPICE and ERFA libraries
Real osculating orbits at a real epoch, drawn from JPL DE440 ephemerides by
examples/orbits.livemd.
The nearby-star map is generated by
examples/stars.livemd
from published catalog astrometry propagated through Astro.Star.
Installation
It is a bit more complicated then normal lib so pay attention:
- instal ERFA library
- use
x86_64-linux; CSPICE N0067 is bundled, so compilation does not download the toolkit. The included Nix flake supplies GCC, ERFA, and GMP on NixOS. - add
ex_astrotomix.exs
def deps do
[
...
{:ex_astro, "~> 0.3"},
...
]
end
- download SPICE kernels; applications load configured paths when they start
mix astro.kernels
Kernels
Configure kernels that should load when the application starts:
config :ex_astro,
spice_kernels: [
"priv/kernels/lsk/naif0012.tls",
"priv/kernels/pck/pck00011.tpc",
"priv/kernels/spk/planets/de440.bsp"
]
Kernels downloaded after startup can be managed at runtime:
:ok = Astro.Kernel.load("/path/to/kernel.bsp")
Astro.Kernel.loaded()
:ok = Astro.Kernel.unload("/path/to/kernel.bsp")
Missing configured files log a warning instead of preventing application startup, so they can be downloaded and loaded later. Kernel mutations are atomic against the library's single CSPICE pool and safe while other Astro calls are running.
Time API
Astro.Time represents Julian Dates as two-part tuples {jd1, jd2} rather
than a single float. This follows ERFA/SOFA conventions and preserves much more
precision for time-scale conversions.
iex> jd = Astro.Time.to_julian_date(~N[2000-01-01 12:00:00])
iex> jd
{2451544.5, 0.5}
iex> Astro.Time.day2sec(jd)
0.0
Ephemeris and Orbit APIs
Astro.Ephemeris provides the low-level SPICE state and conic operations.
Astro.Orbit adds named osculating elements, propagation, derived quantities,
anomaly calculations, and perifocal geometry:
# UTC timestamp -> SPICE ephemeris time
et = Astro.Time.to_et(~U[2026-08-14 00:00:00Z])
# osculating orbit of Earth around the Sun in the ecliptic frame
{:ok, orbit} =
Astro.Orbit.osculating("3", "10", et, frame: "ECLIPJ2000")
semi_major_axis_km = Astro.Orbit.semi_major_axis(orbit)
period_seconds = Astro.Orbit.period(orbit)
Astro.Support handles the metadata around these calls: body name/ID
translation (bodn2c/1, bodc2n/1), scalar gravitational parameters
(gm/1), general kernel-pool constants (bodvcd/2, bodvrd/2), and SPK file
inspection (spkobj/1).
Star Catalog API
Astro.Star propagates caller-supplied Gaia, Hipparcos, and other star-catalog
entries between two-part TDB Julian Date epochs. It also converts catalog
coordinates to and from six-element BCRS position/velocity vectors. Catalog
data is not bundled with the library.
iex> Astro.Star.starpv(ra, dec, pm_ra, pm_dec, parallax, radial_velocity)
{:ok, [x, y, z, vx, vy, vz]}
Examples
The examples/
directory contains Livebooks that explain and run the library together:
orbits.livemd— draws the SVG orbit diagrams above from JPL ephemeridesstars.livemd— draws the rotating 3D map of the 100 nearest stellar systems
Open them in Livebook. The notebooks download their data on first run and write the SVG snapshots next to themselves.