Parses JPL DE-series binary SPK ephemeris files (DAF/SPK format).
Supports Type 2 segments (Chebyshev position polynomials), which is the type used for planetary and lunar positions in DE440s and related files.
Usage
# This step is performed automatically at application start
{:ok, kernel} = Astro.Ephemeris.Kernel.load("priv/de440s.bsp")
# Moon wrt EMB
{:ok, seg} = Astro.Ephemeris.Kernel.find_segment(301, 3)
{x, y, z} = Astro.Ephemeris.Kernel.position(seg, dynamical_time)dynamical_time is TDB seconds past J2000.0 (2000-01-01T12:00:00 TT).
Returned {x, y, z} are in km relative to the segment's centre body.
Design notes
The full file binary is stored inside the kernel struct so that
position/3 does not re-read the file on every call. For a 32 MB
DE440s file this avoids ~thousands of disk reads per rise/set computation.
DAF/SPK Type 2 format
A DAF (Double Precision Array File) consists of 1024-byte records. Record 1 is the file header. Subsequent records form a comment area followed by a doubly-linked list of summary/name record pairs.
Each segment descriptor (summary) contains:
- ND=2 doubles: start_dt, end_dt (dynamical time — TDB seconds past J2000.0)
- NI=6 integers packed as raw int32 bytes: target, centre, frame, data_type, start_addr, end_addr
Addresses are 1-based word (8-byte double) indices into the whole file.
A Type 2 segment's data area contains N Chebyshev records followed by
4 metadata words [init_dt (dynamical time), intlen, rsize, n] at the very end.
Each Chebyshev record has rsize doubles:
[t_mid, t_half, cx_0..cx_d, cy_0..cy_d, cz_0..cz_d]where d = degree = (rsize - 2) / 3 - 1.
Summary
Functions
Returns the loaded ephemeris kernel from :persistent_term storage.
Finds the first segment matching target and centre NAIF IDs.
Loads and parses a JPL DE-series SPK binary ephemeris file.
Evaluates a Type 2 Chebyshev segment at the given dynamical time.
Types
Functions
Returns the loaded ephemeris kernel from :persistent_term storage.
The kernel is loaded at application start by Astro.Application
and stored under ephemeris_key/0.
Returns
- An
Astro.Ephemeris.Kernelstruct.
Finds the first segment matching target and centre NAIF IDs.
If dynamical_time is provided, only segments whose time span
covers the given instant are considered. If nil (the default),
the first matching segment regardless of time span is returned.
Arguments
targetis the NAIF body ID of the target body (e.g.301for the Moon).centreis the NAIF body ID of the centre body (e.g.3for the Earth–Moon Barycenter).dynamical_timeis TDB seconds past J2000.0, ornilto match any time span. Defaults tonil.
Returns
{:ok, segment}wheresegmentis a map describing the matching Type 2 segment.{:error, :not_found}if no matching segment exists.
Loads and parses a JPL DE-series SPK binary ephemeris file.
The entire file is read into memory and all Type 2 segment
descriptors are extracted so that subsequent position/2 calls
do not require disk I/O.
Arguments
pathis the filesystem path to a DAF/SPK file (e.g."priv/de440s.bsp").
Returns
{:ok, kernel}wherekernelis anAstro.Ephemeris.Kernelstruct containing the parsed segments and the raw binary data.{:error, reason}if the file cannot be read or is not a valid DAF/SPK file.
Evaluates a Type 2 Chebyshev segment at the given dynamical time.
Reads the appropriate Chebyshev record from the in-memory kernel data, normalizes the time argument to [-1, +1], and evaluates the polynomial for each Cartesian axis.
Arguments
segmentis a segment map as returned byfind_segment/3.dynamical_timeis TDB seconds past J2000.0.
Returns
{x, y, z}position in kilometers relative to the segment's centre body.