1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//! Unified access to JPL ephemerides (legacy DE binaries and NAIF SPK/DAF).
//!
//! This module abstracts two **binary** JPL ephemeris formats behind a single API:
//!
//! - **Legacy JPL DE binaries** (TTL/CNAM/IPT layout) handled by the [`horizon`](crate::jpl_ephem::horizon) backend:
//! parsed into Chebyshev segments per body and interpolated on demand.
//! - **NAIF SPK/DAF kernels** handled by the [`naif`](crate::jpl_ephem::naif) backend: parsed via a DAF
//! header + summary/directory records into Chebyshev segments (SPK types).
//!
//! The enum [`JPLEphem`](crate::jpl_ephem::JPLEphem) wraps either backend and exposes a common entry point to
//! get Earth state vectors via [`JPLEphem::earth_ephemeris`](crate::jpl_ephem::JPLEphem::earth_ephemeris).
//!
//! # Frames, centers, and units
//!
//! - **Legacy DE backend (`horizon`)**
//! - **Query:** `Earth` relative to `Sun`.
//! - **Internal units:** kilometers; velocity in kilometers **per day** (JD spacing).
//! - After calling `.to_au()`: position in **AU**, velocity in **AU/day**.
//! - Earth geocenter is derived from EMB and Moon using the Earth–Moon mass ratio.
//!
//! - **NAIF SPK/DAF backend (`naif`)**
//! - **Query:** `Earth–Moon Barycenter (EMB)` relative to `Solar System Barycenter (SSB)`.
//! - **Internal units:** kilometers; velocity in kilometers **per second**.
//! - After calling `.to_au()`: position in **AU**, velocity in **AU/s**.
//!
//! > ⚠️ **Caveat:** the velocity unit differs between backends. If your pipeline needs
//! > a single unit (e.g. AU/day), convert NAIF velocities by multiplying by `86400.0`.
//! > If you require **geocentric Earth** when using SPK/DAF, convert EMB → Earth geocenter
//! > (or query a segment providing geocenter directly, if available).
//!
//! # Time scales
//! - `horizon`: input time is converted to **MJD(TT)** for interpolation on JD intervals.
//! - `naif`: input time is converted to **ET seconds** (SPICE TDB‑like) for SPK evaluation.
//!
//! # Submodules overview
//!
//! - [`download_jpl_file`](crate::jpl_ephem::download_jpl_file) — Ephemeris file resolution and retrieval (local/cache/remote).
//! - [`horizon`](crate::jpl_ephem::horizon) — Legacy DE reader and interpolator:
//! * [`horizon::HorizonData`](crate::jpl_ephem::horizon::horizon_data::HorizonData) — top‑level loader and query interface,
//! * [`horizon::horizon_records::HorizonRecord`](crate::jpl_ephem::horizon::horizon_records::HorizonRecord) — per‑interval Chebyshev coefficients,
//! * [`horizon::horizon_ids::HorizonID`](crate::jpl_ephem::horizon::horizon_ids::HorizonID) — body/center identifiers,
//! * [`horizon::horizon_version::JPLHorizonVersion`](crate::jpl_ephem::horizon::horizon_version::JPLHorizonVersion) — DE version to filename mapping,
//! * [`horizon::interpolation_result::InterpResult`](crate::jpl_ephem::horizon::interpolation_result::InterpResult) — (pos, vel?, acc?) with `.to_au()`.
//! - [`naif`](crate::jpl_ephem::naif) — SPK/DAF reader and interpolator:
//! * [`naif::NaifData`](crate::jpl_ephem::naif::naif_data::NaifData) — top‑level loader and query interface,
//! * [`naif::naif_ids`](crate::jpl_ephem::naif::naif_ids) — NAIF ID enums (planetary barycenters, SSB, …),
//! * [`naif::naif_version::NaifVersion`](crate::jpl_ephem::naif::naif_version::NaifVersion) — SPK file names by official DE label.
//!
//! # Example
//! ```rust, no_run
//! use outfit::jpl_ephem::{download_jpl_file::EphemFileSource, JPLEphem, horizon::horizon_version::JPLHorizonVersion};
//! use hifitime::Epoch;
//!
//! let eph = JPLEphem::new(&EphemFileSource::JPLHorizon(JPLHorizonVersion::DE440))?;
//! let t = Epoch::from_tai_seconds(1_700_000_000.0);
//!
//! // Position always in AU. Velocity is AU/day (legacy DE) or AU/s (SPK/DAF).
//! let (r_au, v_opt) = eph.earth_ephemeris(&t, true);
//!
//! // Normalize NAIF velocities to AU/day if your pipeline expects it:
//! let v_au_per_day = v_opt.map(|v| v * 86400.0);
//! # Ok::<(), outfit::outfit_errors::OutfitError>(())
//! ```
//!
//! # See also
//! * [`horizon::HorizonData::ephemeris`](crate::jpl_ephem::horizon::horizon_data::HorizonData::ephemeris) — Earth (geocenter) w.r.t. Sun, Chebyshev on JD.
//! * [`naif::NaifData::ephemeris`](crate::jpl_ephem::naif::naif_data::NaifData::ephemeris) — EMB w.r.t. SSB, Chebyshev on ET seconds.
//! * [`hifitime::Epoch`] — conversions to MJD(TT) and ET seconds.
use ;
use Epoch;
use ;
use ;
use Vector3;
use crateOutfitError;
/// Runtime‑selected ephemeris backend (legacy DE vs NAIF SPK/DAF).
///
/// # See also
/// * [`download_jpl_file::EphemFileSource`] – Source resolution policy.
/// * [`horizon::HorizonData`](crate::jpl_ephem::horizon::horizon_data::HorizonData) – Legacy DE binary reader/interpolator.
/// * [`naif::NaifData`](crate::jpl_ephem::naif::naif_data::NaifData) – SPK/DAF high‑level accessor.