Frames, units, and time scales¶
A single-page reference for what shape inputs and outputs take across
the empyrean public API. Defaults are chosen to match the integration
frame and the convention most NEO-work pipelines expect — override on
:class:~empyrean.PropagationConfig /
:class:~empyrean.transform_coordinates when you need something else.
Time scales¶
The :class:~empyrean.TimeScale enum carries the two scales empyrean
exposes at the API boundary:
Scale |
Use |
|---|---|
|
Barycentric Dynamical Time — the integration time scale, and what everything converts to internally. |
|
Coordinated Universal Time — leap-second-aware. Use for human-readable epochs (ISO strings) and observation timestamps. |
Every time you hand to empyrean is an :class:~empyrean.Epochs table,
and every Epochs states its scale. (The scale-pinned carve-outs
below are the exception, and they are named by their own definition
rather than by the caller.) There is no bare-MJD entry point
and no default scale to fall back on: a plain 61000.5 does not say
which clock it was read from, and read as UTC rather than TDB it names an
instant about 69 seconds earlier — a difference that grows with every
leap second, and one that is easily large enough to move a close-approach
geometry. Passing a bare list, array or float where a time is expected
raises TypeError naming the fix.
epochs = empyrean.Epochs.from_mjd([61000.5, 61010.5], scale="tdb")
epochs = empyrean.Epochs.from_mjd([61000.5, 61010.5], scale="utc") # not the same instants
epochs = empyrean.Epochs.from_iso(["2026-01-01T12:00:00.000Z"]) # ISO is UTC by format
Epochs carries the scale as a StringAttribute and exposes
.to_tdb() / .to_utc() / .to_scale(...) for conversion, plus
.mjd_tdb() / .mjd_utc() to read the values back out in a named
scale. UTC↔TDB conversion (leap seconds plus the TDB−TT periodic terms)
is built into the engine — no separate leap-second kernel is installed.
Plain floats remain in exactly three places, and each pins its scale by
definition rather than leaving it to the caller: columns named
mjd_tdb, arguments named epoch_mjd_tdb, and the epoch column on the
four coordinate tables (CartesianCoordinates, KeplerianCoordinates,
CometaryCoordinates, SphericalCoordinates), which is MJD TDB by
definition. Any raw MJD float at the API boundary is MJD TDB unless
documented otherwise.
That last one is a column you read, not a time you hand in. To use a
coordinate epoch as a time input, convert it —
Epochs.from_mjd(orbits.coordinates.epoch.to_numpy(), scale="tdb") — or
let Epochs.from_orbits(orbits, offsets_in_days) do both steps.
Earth-rotation kernels are stored on the TT scale internally; the TT ↔ TDB difference is small — a quasi-periodic term with peak amplitude ~1.7 ms (dominated by an annual component) — and is applied automatically.
Reference frames¶
The Frame enum (use the all-caps Python member
name; the string slug shown in the second column also works):
Member |
String slug |
Notes |
|---|---|---|
|
|
Mean ecliptic and equinox of J2000.0. Integration frame; default propagation output. Convert to ICRF via |
|
|
International Celestial Reference Frame (≈ J2000 equatorial). |
|
|
Earth-fixed (rotating) — for ground-station vectors. |
Conversion is via transform_coordinates(), which
accepts a target frame as a kwarg and propagates covariance through
the rotation.
Origins¶
The Origin enum is keyed by NAIF body code; only
the bodies whose ephemeris is actually loaded by ForceModelTier
≥ Approximate are exposed:
Member |
String slug |
Use |
|---|---|---|
|
|
Solar System Barycenter (NAIF 0) — the propagation origin. |
|
|
NAIF 10. Heliocentric — what SBDB returns for small-body orbits. |
|
|
NAIF 399. Geocentric — for Earth-observer ephemeris. |
|
|
NAIF 301. Selenocentric. |
|
|
NAIF 199. |
|
|
NAIF 299. |
|
|
NAIF 4. Mars body-center not exposed (DE440 ships the barycentre only). |
|
|
NAIF 5. |
|
|
NAIF 6. |
|
|
NAIF 7. |
|
|
NAIF 8. |
|
|
NAIF 9. Pluto body-center is not exposed; same DE440 reason as Mars. |
|
|
A frame, not a body, but accepted in the same parameter slot for API consistency. |
|
|
Numbered-asteroid origin — e.g. |
Observer states¶
from_code() /
from_codes() and
get_observer_states() return ICRF / SSB by default —
the construction basis, and the one
generate_ephemeris() and orbit determination require.
Requesting it takes no transform at all: the states come back exactly as
constructed, bit for bit.
Pass frame= / origin= when you want the geometry in some other
basis — plotting heliocentric ecliptic site positions, say:
sites = empyrean.Observers.from_codes(
["500", "568"], epochs, frame="eclipticj2000", origin="Sun"
)
Every returned row carries the basis it is expressed in, read off the state rather than echoed from the request, so a table is never ambiguous about which basis produced it.
For unfamiliar bodies, see NAIF’s body-ID page; to add a new body, the underlying ephemeris kernel set has to carry its segment.
Units¶
Quantity |
Unit |
Notes |
|---|---|---|
Position |
astronomical units (AU) |
At the public API boundary. |
Velocity |
AU / day |
Same. |
Time |
days |
Propagation step sizes, durations, etc. |
Epoch |
|
Inputs are |
Angle |
degrees |
At the boundary; converted to radians internally. |
Astrometric residuals |
arcseconds |
RA·cos(δ), Dec, AT/CT decompositions. |
Track position angle |
degrees (East of North) |
On |
Astrometric magnitudes |
V-band |
H, V, mag are V-equivalent unless documented otherwise. |
Impact-probability |
dimensionless probability |
|
B-plane coordinates |
km |
|
B-plane covariance |
km² |
|
Hyperbolic excess velocity |
km / s |
|
Earth-rotation kernels |
TT internally |
Conversion is automatic; users see TDB. |
When a function takes a Frame / Origin parameter, you can pass
either the enum value (Frame.ICRF) or the string slug
("icrf" / "eclipticj2000" — case-insensitive). Same for Origin
which also accepts a raw NAIF integer.
Coordinate representations¶
The CartesianCoordinates /
KeplerianCoordinates /
CometaryCoordinates /
SphericalCoordinates family supports four
representations on input and output:
Representation |
Elements |
Notes |
|---|---|---|
Cartesian |
|
The integration representation. |
Keplerian |
|
Mean anomaly. Angles in degrees. |
Cometary |
|
Time-of-perihelion. What SBDB returns for small bodies. |
Spherical |
|
Topocentric or geocentric astrometry. |
The propagator accepts any of the four; covariance gets transformed along with the elements via the analytic Jacobians.