Astro.Ephemeris.Subset (Astro v2.5.0)

Copy Markdown View Source

Extracts a smaller DAF/SPK ephemeris kernel from a larger one.

JPL's de440s.bsp is ~31 MB because it carries all planetary barycenters over 1849–2150. Astro uses only four segments — Moon and Earth relative to the Earth–Moon Barycenter, and Sun and EMB relative to the Solar System Barycenter — so the remainder can be discarded.

Extraction is lossless within the retained window: the original Chebyshev coefficients are copied verbatim, so positions computed from a subset file are bit-for-bit identical to those computed from the source file. No refitting is performed.

What drives the file size

Body selection alone saves less than expected. The Moon and Earth segments are the two largest in the file (degree-12 polynomials on 4-day intervals), together ~17 MB, while the eight discarded planetary barycenters use 32-day intervals and cost little. The dominant lever is the time window — after body selection the cost is roughly 42 KB per year of coverage.

A second saving comes from omitting the Earth→EMB segment. By the definition of the barycenter it is an exact scalar multiple of the Moon→EMB segment:

EarthEMB = -(1 / EMRAT) x MoonEMB

where EMRAT is the Earth/Moon mass ratio (81.3005682214972154 for DE440). Astro.Ephemeris.Kernel reconstructs the segment on demand when it is absent, so omitting it halves the payload at a cost of one multiplication per evaluation.

Compatibility

The output is a valid DAF/SPK file. The source file record is copied intact — preserving the format identifier, the FTP validation string and the binary format marker — so the result is readable by other SPICE implementations (CSPICE, jplephem, Astropy) and not only by this library.

Summary

Functions

Returns the default set of {target_id, centre_id} pairs retained by extract/3.

Extracts selected segments and a time window from a DAF/SPK file.

Functions

default_bodies()

@spec default_bodies() :: [{integer(), integer()}]

Returns the default set of {target_id, centre_id} pairs retained by extract/3.

Earth→EMB (399→3) is deliberately absent; it is reconstructed from Moon→EMB at runtime. See the module documentation.

Returns

  • A list of {target_id, centre_id} tuples.

Examples

iex> Astro.Ephemeris.Subset.default_bodies()
[{301, 3}, {10, 0}, {3, 0}]

extract(source_path, dest_path, options \\ [])

@spec extract(Path.t(), Path.t(), keyword()) :: {:ok, map()} | {:error, term()}

Extracts selected segments and a time window from a DAF/SPK file.

Arguments

  • source_path is the path of the DAF/SPK file to read, typically a JPL de440s.bsp.

  • dest_path is the path of the subset file to write.

Options

  • :bodies is a list of {target_id, centre_id} NAIF body ID pairs to retain. Defaults to the four segments Astro requires, excluding Earth→EMB, which is reconstructed at runtime.

  • :from is the first instant the subset must cover, as a Date, DateTime or integer year. Defaults to the source file's start.

  • :to is the last instant the subset must cover, in the same forms as :from. Defaults to the source file's end.

Returns

  • {:ok, report} where report is a map containing :path, :bytes, :segments (a list of retained {target, centre} pairs) and :coverage (a {first_year, last_year} tuple).

  • {:error, reason} if the source cannot be read or parsed, or if a requested body pair or time window is not present in the source.

Examples

# Retain Astro's segments over 1900-2100
Astro.Ephemeris.Subset.extract(
  "de440s.bsp",
  "priv/de440s-astro.bsp",
  from: 1900,
  to: 2100
)