1pub const EMPYREAN_BUILTSYSTEM_OK: u32 = 0;
4pub const EMPYREAN_BUILTSYSTEM_NULL_POINTER: i32 = -1;
5pub const EMPYREAN_BUILTSYSTEM_INVALID_ARGUMENT: i32 = -2;
6pub const EMPYREAN_BUILTSYSTEM_PROPAGATION: i32 = -3;
7pub const EMPYREAN_BUILTSYSTEM_ALLOC: i32 = -5;
8pub const EMPYREAN_BUILTSYSTEM_DATA_MISMATCH: i32 = -20;
9pub const EMPYREAN_BUILTSYSTEM_KEY_MISMATCH_FRAME: i32 = -21;
10pub const EMPYREAN_BUILTSYSTEM_KEY_MISMATCH_FORCE_MODEL: i32 = -22;
11pub const EMPYREAN_BUILTSYSTEM_KEY_MISMATCH_DIVISOR: i32 = -23;
12pub const EMPYREAN_BUILTSYSTEM_STALE: i32 = -24;
13pub const EMPYREAN_BUILTSYSTEM_PANIC: i32 = -99;
14pub const EMPYREAN_KERNEL_KIND_SPK: u32 = 0;
15pub const EMPYREAN_KERNEL_KIND_BPC: u32 = 1;
16pub const EMPYREAN_KERNEL_KIND_TPC: u32 = 2;
17pub const EMPYREAN_KERNEL_KIND_GRAVITY: u32 = 3;
18pub const EMPYREAN_KERNEL_KIND_OBSCODES: u32 = 4;
19pub const EMPYREAN_KERNEL_PROVENANCE_FILE: u32 = 0;
20pub const EMPYREAN_KERNEL_PROVENANCE_IN_MEMORY: u32 = 1;
21pub const EMPYREAN_KERNEL_PROVENANCE_BUILT_IN: u32 = 2;
22pub const EMPYREAN_RADAR_KIND_DELAY: u32 = 0;
23pub const EMPYREAN_RADAR_KIND_DOPPLER: u32 = 1;
24pub const EMPYREAN_COVARIANCE_TRUST_NOT_EVALUATED: i32 = 0;
25pub const EMPYREAN_COVARIANCE_TRUST_TRUSTED: i32 = 1;
26pub const EMPYREAN_COVARIANCE_TRUST_ENCOUNTER_INTERVENES: i32 = 2;
27pub const EMPYREAN_COVARIANCE_TRUST_WEAKLY_DETERMINED_HIGH_N: i32 = 3;
28pub const EMPYREAN_TRUST_EVENT_NONE: i32 = 0;
29pub const EMPYREAN_TRUST_EVENT_CLOSE_APPROACH: i32 = 1;
30pub const EMPYREAN_TRUST_EVENT_HIGH_NONLINEARITY: i32 = 2;
31pub const EMPYREAN_REJECTION_ACCEPTED: u32 = 0;
32pub const EMPYREAN_REJECTION_CHI_SQUARED: u32 = 1;
33pub const EMPYREAN_REJECTION_SIGMA_CLIP: u32 = 2;
34pub const EMPYREAN_REJECTION_COOKS_DISTANCE: u32 = 3;
35pub const EMPYREAN_REJECTION_ADAPTIVE: u32 = 4;
36pub const EMPYREAN_REJECTION_UNSUPPORTED_OBSERVATORY: u32 = 5;
37pub const EMPYREAN_REJECTION_CMC2003: u32 = 6;
38pub const EMPYREAN_REJECTION_RADAR_UNSUPPORTED: u32 = 7;
39pub const EMPYREAN_REJECTION_OCCULTATION_UNSUPPORTED: u32 = 8;
40pub const EMPYREAN_REJECTION_OUTSIDE_ARC: u32 = 9;
41pub const EMPYREAN_REJECTION_NOT_EVALUATED: i32 = -1;
42pub const EMPYREAN_REJECTION_KIND_ADAPTIVE: u32 = 0;
43pub const EMPYREAN_REJECTION_KIND_CMC2003: u32 = 1;
44pub const EMPYREAN_WEIGHTING_PRESET_NONE: u32 = 0;
45pub const EMPYREAN_WEIGHTING_PRESET_VFC17: u32 = 1;
46pub const EMPYREAN_WEIGHTING_PRESET_NEODYS: u32 = 2;
47pub const EMPYREAN_SIGMA_POLICY_DEFAULT_ONLY: u32 = 0;
48pub const EMPYREAN_SIGMA_POLICY_FLOOR: u32 = 1;
49pub const EMPYREAN_WEIGHTING_LAYER_OBSERVATORY_RULE: u32 = 0;
50pub const EMPYREAN_WEIGHTING_LAYER_NIGHTLY_DEWEIGHTING: u32 = 1;
51pub const EMPYREAN_DEBIASING_TABLE_EFCC2020: u32 = 0;
52pub const EMPYREAN_DEBIASING_RESOLUTION_STANDARD: u32 = 0;
53pub const EMPYREAN_DEBIASING_RESOLUTION_HIRES: u32 = 1;
54pub const EMPYREAN_SOLVE_FOR_STATE_ONLY: u32 = 0;
55pub const EMPYREAN_SOLVE_FOR_STATE_AND_NONGRAV: u32 = 1;
56pub const EMPYREAN_SOLVE_FOR_AUTO: u32 = 2;
57pub const EMPYREAN_SOLVE_FOR_EXPLICIT: u32 = 3;
58pub const EMPYREAN_SOLVE_WIDTH: u32 = 20;
59pub const EMPYREAN_SLOT_NONE: u32 = 4294967295;
60pub const EMPYREAN_PHOTOMETRY_MODEL_AUTO: u32 = 0;
61pub const EMPYREAN_PHOTOMETRY_MODEL_HONLY: u32 = 1;
62pub const EMPYREAN_PHOTOMETRY_MODEL_HG: u32 = 2;
63pub const EMPYREAN_PHOTOMETRY_MODEL_HG12: u32 = 3;
64pub const EMPYREAN_PHOTOMETRY_MODEL_HG1G2: u32 = 4;
65pub const EMPYREAN_ABI_VERSION: u32 = 2;
66pub const EMPYREAN_ORIGIN_POLICY_AUTO: u32 = 0;
67pub const EMPYREAN_ORIGIN_POLICY_EXPLICIT: u32 = 1;
68pub const EMPYREAN_OUTPUT_EPOCH_MID_ARC: u32 = 0;
69pub const EMPYREAN_OUTPUT_EPOCH_LAST_OBSERVATION: u32 = 1;
70pub const EMPYREAN_OUTPUT_EPOCH_EXPLICIT: u32 = 2;
71pub const EMPYREAN_OUTPUT_EPOCH_IOD_EPOCH: u32 = 3;
72pub const EMPYREAN_REPRESENTATION_CARTESIAN: u32 = 0;
73pub const EMPYREAN_REPRESENTATION_KEPLERIAN: u32 = 1;
74pub const EMPYREAN_REPRESENTATION_COMETARY: u32 = 2;
75pub const EMPYREAN_REPRESENTATION_SPHERICAL: u32 = 3;
76pub const EMPYREAN_PHASE_FUNCTION_NONE: i32 = -1;
77pub const EMPYREAN_PHASE_FUNCTION_HG: u32 = 0;
78pub const EMPYREAN_PHASE_FUNCTION_HG1G2: u32 = 1;
79pub const EMPYREAN_PHASE_FUNCTION_HG12: u32 = 2;
80pub const EMPYREAN_STEERING_LAW_CONSTANT_RTN: u32 = 0;
81pub const EMPYREAN_STEERING_LAW_VELOCITY_TANGENT: u32 = 1;
82pub const EMPYREAN_STEERING_LAW_INERTIAL_FIXED: u32 = 2;
83pub const EMPYREAN_INTEGRATOR_GR15: u32 = 0;
84pub const EMPYREAN_INTEGRATOR_DOP853: u32 = 1;
85pub const EMPYREAN_ORIGIN_SWITCHING_DEFAULT: u32 = 0;
86pub const EMPYREAN_ORIGIN_SWITCHING_ON: u32 = 1;
87pub const EMPYREAN_ORIGIN_SWITCHING_OFF: u32 = 2;
88pub const EMPYREAN_UNCERTAINTY_FIRST: u32 = 0;
89pub const EMPYREAN_UNCERTAINTY_SECOND: u32 = 1;
90pub const EMPYREAN_UNCERTAINTY_SIGMA_POINT: u32 = 2;
91pub const EMPYREAN_UNCERTAINTY_MONTE_CARLO: u32 = 3;
92pub const EMPYREAN_UNCERTAINTY_AUTO: u32 = 4;
93pub const EMPYREAN_COVARIANCE_KIND_LINEAR: u32 = 0;
94pub const EMPYREAN_COVARIANCE_KIND_SECOND_ORDER: u32 = 1;
95pub const EMPYREAN_COVARIANCE_KIND_THIRD_ORDER: u32 = 2;
96pub const EMPYREAN_COVARIANCE_KIND_MIXTURE: u32 = 3;
97pub const EMPYREAN_COVARIANCE_KIND_MONTE_CARLO: u32 = 4;
98pub const EMPYREAN_COVARIANCE_KIND_SIGMA_POINT: u32 = 5;
99pub const EMPYREAN_COVARIANCE_QUALITY_POSITIVE_DEFINITE: u32 = 0;
100pub const EMPYREAN_COVARIANCE_QUALITY_INDEFINITE: u32 = 1;
101pub const EMPYREAN_COVARIANCE_QUALITY_REPAIRED: u32 = 2;
102pub const EMPYREAN_TARGET_FUNCTIONAL_CARTESIAN_STATE: u32 = 0;
103pub const EMPYREAN_TARGET_FUNCTIONAL_CLOSE_APPROACH_MISS_DISTANCE: u32 = 1;
104pub const EMPYREAN_TAGGED_COV_OK: u32 = 0;
105pub const EMPYREAN_TAGGED_COV_NULL_POINTER: i32 = -1;
106pub const EMPYREAN_TAGGED_COV_ORBIT_INDEX_OUT_OF_RANGE: i32 = -2;
107pub const EMPYREAN_TAGGED_COV_NO_INITIAL_COVARIANCE: i32 = -3;
108pub const EMPYREAN_TAGGED_COV_NO_DENSE_TRAJECTORY: i32 = -4;
109pub const EMPYREAN_TAGGED_COV_STATE_MISSING: i32 = -5;
110pub const EMPYREAN_TAGGED_COV_TRANSFORM: i32 = -6;
111pub const EMPYREAN_TAGGED_COV_UNCERTAINTY: i32 = -7;
112pub const EMPYREAN_TAGGED_COV_EPOCH_INDEX_OUT_OF_RANGE: i32 = -8;
113pub const EMPYREAN_TAGGED_COV_SAMPLE_COVARIANCE_MISSING: i32 = -9;
114pub const EMPYREAN_TAGGED_COV_PANIC: i32 = -99;
115#[repr(C)]
116#[derive(Debug, Copy, Clone)]
117pub struct Context {
118 _unused: [u8; 0],
119}
120#[repr(C)]
121#[derive(Debug, Copy, Clone)]
122pub struct Session {
123 _unused: [u8; 0],
124}
125#[doc = " Opaque handle wrapping a pre-assembled force model plus the\n kernel-identity snapshot taken from the context at construction (so\n [`empyrean_builtsystem_describe`] is self-contained). Construct with\n [`empyrean_builtsystem_new`]; release with [`empyrean_builtsystem_free`].\n\n The handle is `Send + Sync`: hand `&EmpyreanBuiltSystem` (via a `const`\n pointer) to as many threads as you like. It borrows nothing from the\n context after construction."]
126#[repr(C)]
127#[derive(Debug, Copy, Clone)]
128pub struct EmpyreanBuiltSystem {
129 _unused: [u8; 0],
130}
131#[doc = " C FFI opaque handle. Internally an [`empyrean_core::Context`]; the\n C header forward-declares `struct EmpyreanContext` — callers only\n see the pointer."]
132pub type EmpyreanContext = Context;
133#[doc = " Per-crate version strings reported by the empyrean stack.\n\n Mirrors [`empyrean_core::Versions`]. Each pointer is a heap-allocated\n NUL-terminated UTF-8 string owned by [`EmpyreanVersions`]; release\n the whole struct with [`empyrean_versions_free`] (do not free the\n individual fields with [`empyrean_string_free`])."]
134#[repr(C)]
135#[derive(Debug, Copy, Clone)]
136pub struct EmpyreanVersions {
137 #[doc = " `empyrean-core` crate version (semver string from `Cargo.toml`)."]
138 pub empyrean_core: *mut ::std::os::raw::c_char,
139 #[doc = " `villeneuve` crate version (`<tag>+<sha>` git-populated)."]
140 pub villeneuve: *mut ::std::os::raw::c_char,
141 #[doc = " `scott` crate version (`<tag>+<sha>` git-populated)."]
142 pub scott: *mut ::std::os::raw::c_char,
143 #[doc = " `nolan` crate version (`<tag>+<sha>` git-populated)."]
144 pub nolan: *mut ::std::os::raw::c_char,
145}
146#[allow(clippy::unnecessary_operation, clippy::identity_op)]
147const _: () = {
148 ["Size of EmpyreanVersions"][::std::mem::size_of::<EmpyreanVersions>() - 32usize];
149 ["Alignment of EmpyreanVersions"][::std::mem::align_of::<EmpyreanVersions>() - 8usize];
150 ["Offset of field: EmpyreanVersions::empyrean_core"]
151 [::std::mem::offset_of!(EmpyreanVersions, empyrean_core) - 0usize];
152 ["Offset of field: EmpyreanVersions::villeneuve"]
153 [::std::mem::offset_of!(EmpyreanVersions, villeneuve) - 8usize];
154 ["Offset of field: EmpyreanVersions::scott"]
155 [::std::mem::offset_of!(EmpyreanVersions, scott) - 16usize];
156 ["Offset of field: EmpyreanVersions::nolan"]
157 [::std::mem::offset_of!(EmpyreanVersions, nolan) - 24usize];
158};
159impl Default for EmpyreanVersions {
160 fn default() -> Self {
161 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
162 unsafe {
163 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
164 s.assume_init()
165 }
166 }
167}
168#[doc = " Flat C-ABI compatible coordinate state.\n\n Field-identical to [`empyrean_core::convert::CoordinateState`]; the\n duplicate definition exists so cbindgen (which has `parse_deps =\n false`) can emit the matching C struct in `empyrean.h` without\n traversing into the empyrean-core crate."]
169#[repr(C)]
170#[derive(Debug, Default, Copy, Clone)]
171pub struct CoordinateState {
172 pub epoch_mjd_tdb: f64,
173 pub elements: [f64; 6usize],
174 pub covariance: [[f64; 6usize]; 6usize],
175 pub has_covariance: u8,
176 pub representation: i32,
177 pub frame: i32,
178 pub origin: i32,
179}
180#[allow(clippy::unnecessary_operation, clippy::identity_op)]
181const _: () = {
182 ["Size of CoordinateState"][::std::mem::size_of::<CoordinateState>() - 360usize];
183 ["Alignment of CoordinateState"][::std::mem::align_of::<CoordinateState>() - 8usize];
184 ["Offset of field: CoordinateState::epoch_mjd_tdb"]
185 [::std::mem::offset_of!(CoordinateState, epoch_mjd_tdb) - 0usize];
186 ["Offset of field: CoordinateState::elements"]
187 [::std::mem::offset_of!(CoordinateState, elements) - 8usize];
188 ["Offset of field: CoordinateState::covariance"]
189 [::std::mem::offset_of!(CoordinateState, covariance) - 56usize];
190 ["Offset of field: CoordinateState::has_covariance"]
191 [::std::mem::offset_of!(CoordinateState, has_covariance) - 344usize];
192 ["Offset of field: CoordinateState::representation"]
193 [::std::mem::offset_of!(CoordinateState, representation) - 348usize];
194 ["Offset of field: CoordinateState::frame"]
195 [::std::mem::offset_of!(CoordinateState, frame) - 352usize];
196 ["Offset of field: CoordinateState::origin"]
197 [::std::mem::offset_of!(CoordinateState, origin) - 356usize];
198};
199#[doc = " A single continuous-thrust arc, mirroring\n [`empyrean_core::nongrav::ThrustArc`] as a flat `#[repr(C)]` record.\n\n Arcs are supplied through [`EmpyreanOrbit::thrust_arcs`] as a\n caller-owned side array borrowed read-only for the duration of the call.\n\n The acceleration during the arc is\n \\\\[ \\mathbf{a}(t) = \\sigma(t)\\,\\frac{F}{m(t)}\\,\\hat{d} \\\\]\n with a smooth \\\\(\\tanh\\\\) switch \\\\(\\sigma(t)\\\\) of width set by\n `sharpness`, steering direction \\\\(\\hat{d}\\\\) from `steering_law`, and\n mass \\\\(m(t)\\\\) that depletes when `isp_s` is finite."]
200#[repr(C)]
201#[derive(Debug, Default, Copy, Clone)]
202pub struct EmpyreanThrustArc {
203 #[doc = " Arc start epoch (MJD TDB)."]
204 pub start_mjd_tdb: f64,
205 #[doc = " Arc end epoch (MJD TDB)."]
206 pub end_mjd_tdb: f64,
207 #[doc = " Engine thrust force in Newtons."]
208 pub thrust_n: f64,
209 #[doc = " Spacecraft mass at arc start in kilograms."]
210 pub mass_kg: f64,
211 #[doc = " Specific impulse in seconds. Any non-finite value (`NaN` or `±∞`)\n selects constant mass (no depletion); a finite value depletes mass at\n \\\\(\\dot m = F/(I_{sp} g_0)\\\\). This is the `Option<f64>` NaN-sentinel\n convention shared with [`EmpyreanOrbit::non_grav_dt`]."]
212 pub isp_s: f64,
213 #[doc = " Steering-law selector — see the `EMPYREAN_STEERING_LAW_*` tag\n constants. An unrecognized value errors loudly."]
214 pub steering_law: i32,
215 #[doc = " `CONSTANT_RTN` in-plane angle α from radial toward transverse\n (radians). Read only when `steering_law == CONSTANT_RTN`."]
216 pub steering_alpha_rad: f64,
217 #[doc = " `CONSTANT_RTN` out-of-plane angle β toward orbit normal (radians).\n Read only when `steering_law == CONSTANT_RTN`."]
218 pub steering_beta_rad: f64,
219 #[doc = " `INERTIAL_FIXED` direction vector (normalized internally). Read only\n when `steering_law == INERTIAL_FIXED`."]
220 pub steering_direction: [f64; 3usize],
221 #[doc = " \\\\(\\tanh\\\\) switching sharpness (1/days). Higher = sharper on/off."]
222 pub sharpness: f64,
223 #[doc = " Central-body NAIF id for the RTN / velocity-tangent frame reference\n (same encoding as [`EmpyreanOrbit`]'s `state.origin`, e.g. `399` for\n Earth, `10` for the Sun). An unknown NAIF id errors loudly."]
224 pub central_body_naif_id: i32,
225}
226#[allow(clippy::unnecessary_operation, clippy::identity_op)]
227const _: () = {
228 ["Size of EmpyreanThrustArc"][::std::mem::size_of::<EmpyreanThrustArc>() - 104usize];
229 ["Alignment of EmpyreanThrustArc"][::std::mem::align_of::<EmpyreanThrustArc>() - 8usize];
230 ["Offset of field: EmpyreanThrustArc::start_mjd_tdb"]
231 [::std::mem::offset_of!(EmpyreanThrustArc, start_mjd_tdb) - 0usize];
232 ["Offset of field: EmpyreanThrustArc::end_mjd_tdb"]
233 [::std::mem::offset_of!(EmpyreanThrustArc, end_mjd_tdb) - 8usize];
234 ["Offset of field: EmpyreanThrustArc::thrust_n"]
235 [::std::mem::offset_of!(EmpyreanThrustArc, thrust_n) - 16usize];
236 ["Offset of field: EmpyreanThrustArc::mass_kg"]
237 [::std::mem::offset_of!(EmpyreanThrustArc, mass_kg) - 24usize];
238 ["Offset of field: EmpyreanThrustArc::isp_s"]
239 [::std::mem::offset_of!(EmpyreanThrustArc, isp_s) - 32usize];
240 ["Offset of field: EmpyreanThrustArc::steering_law"]
241 [::std::mem::offset_of!(EmpyreanThrustArc, steering_law) - 40usize];
242 ["Offset of field: EmpyreanThrustArc::steering_alpha_rad"]
243 [::std::mem::offset_of!(EmpyreanThrustArc, steering_alpha_rad) - 48usize];
244 ["Offset of field: EmpyreanThrustArc::steering_beta_rad"]
245 [::std::mem::offset_of!(EmpyreanThrustArc, steering_beta_rad) - 56usize];
246 ["Offset of field: EmpyreanThrustArc::steering_direction"]
247 [::std::mem::offset_of!(EmpyreanThrustArc, steering_direction) - 64usize];
248 ["Offset of field: EmpyreanThrustArc::sharpness"]
249 [::std::mem::offset_of!(EmpyreanThrustArc, sharpness) - 88usize];
250 ["Offset of field: EmpyreanThrustArc::central_body_naif_id"]
251 [::std::mem::offset_of!(EmpyreanThrustArc, central_body_naif_id) - 96usize];
252};
253#[doc = " An orbit with optional non-gravitational parameters, continuous-thrust\n arcs, and photometry.\n\n Thrust: when `n_thrust_arcs > 0`, [`thrust_arcs`](Self::thrust_arcs)\n (plus the optional [`dv_corrections`](Self::dv_corrections) /\n [`correction_covariances`](Self::correction_covariances) side arrays)\n build a [`ThrustParams`] for this orbit. All-zero `a1/a2/a3` and\n `n_thrust_arcs == 0` is a pure-gravity orbit.\n\n `a1/a2/a3` are the Marsden–Sekanina RTN coefficients (radial,\n transverse, normal) in AU/day². `ng_alpha … ng_k` parameterize the\n g(r) distance-dependent scaling:\n \\\\[ g(r) = \\alpha \\\\, (r/r_0)^{-m} \\\\, (1 + (r/r_0)^n)^{-k} \\\\].\n All-zeros for the g-function fields selects the inverse-square\n default (Yarkovsky / SRP asteroid case): \\\\(\\alpha = r_0 = 1\\\\),\n \\\\(m = 2\\\\), \\\\(n = k = 0\\\\). Comets typically pass SBDB's\n Marsden water-ice values\n (\\\\(\\alpha = 0.1113, r_0 = 2.808, m = 2.15, n = 5.093, k = 4.6142\\\\)).\n\n Photometry: when `phot_system` is one of the `EMPYREAN_PHASE_FUNCTION_*`\n non-`NONE` constants, ephemeris generation produces apparent magnitude\n using the (`H`, `slope1`, `slope2`) triple per the chosen phase function:\n\n | Model | `H` | `slope1` | `slope2` |\n |-------|-----|----------|----------|\n | `HG` | absolute magnitude | G | unused (0) |\n | `HG1G2` | absolute magnitude | G₁ | G₂ |\n | `HG12` | absolute magnitude | G₁₂ | unused (0) |"]
254#[repr(C)]
255#[derive(Debug, Copy, Clone)]
256pub struct EmpyreanOrbit {
257 pub state: CoordinateState,
258 #[doc = " Caller-supplied orbit identifier — primary key for joining\n outputs (propagated states, events, ephemeris, B-planes, IP) to\n the input row. NUL-terminated UTF-8. A null pointer or empty\n string causes the C ABI to fabricate a positional `\"orbit_{i}\"`\n tag instead — set this whenever you want stable joins.\n\n **Ownership:** read-only borrow from the caller; the C ABI does\n not free it."]
259 pub orbit_id: *const ::std::os::raw::c_char,
260 #[doc = " Caller-supplied object identifier (e.g. SBDB designation).\n Distinct from `orbit_id` so multiple orbit hypotheses for the\n same object can share an `object_id`. NUL-terminated UTF-8.\n Empty string or null = no object identifier.\n\n **Ownership:** read-only borrow from the caller; the C ABI does\n not free it."]
261 pub object_id: *const ::std::os::raw::c_char,
262 #[doc = " Marsden-Sekanina A1 coefficient (radial). 0 ⇒ no non-grav."]
263 pub a1: f64,
264 #[doc = " Marsden-Sekanina A2 coefficient (transverse)."]
265 pub a2: f64,
266 #[doc = " Marsden-Sekanina A3 coefficient (normal)."]
267 pub a3: f64,
268 #[doc = " g(r) normalizing constant α. All-zero g-fields → inverse_square."]
269 pub ng_alpha: f64,
270 #[doc = " g(r) reference distance r₀ (AU)."]
271 pub ng_r0: f64,
272 #[doc = " g(r) inner power-law exponent m."]
273 pub ng_m: f64,
274 #[doc = " g(r) outer power-law exponent n."]
275 pub ng_n: f64,
276 #[doc = " g(r) outer damping exponent k."]
277 pub ng_k: f64,
278 #[doc = " SBDB non-grav time delay in days. Use NaN for no delay (the\n asteroid default and the Marsden water-ice default for comets\n SBDB doesn't fit a delay for). Set to a finite value (positive\n or negative) when SBDB's `model_pars[]` exposes a `DT` field —\n e.g. 67P (+45.7d), 46P/Wirtanen (−14.1d), 2I/Borisov (−65.1d)."]
279 pub non_grav_dt: f64,
280 #[doc = " Prior variance on the non-grav time delay DT (days²). NaN or ≤0 = no\n prior; a finite positive value opens + priors the DT column in a\n StateAndNonGravAndDT fit."]
281 pub non_grav_dt_variance: f64,
282 #[doc = " 1 when `non_grav_covariance` carries a non-grav prior covariance; 0\n otherwise. Set by the OD output path (a fitted orbit) so it re-feeds\n into a StateAndNonGrav refine without losing its non-grav prior;\n leave 0 for hand-built / SBDB / propagate inputs."]
283 pub has_non_grav_covariance: u8,
284 #[doc = " Non-grav 3×3 covariance for (A1, A2, A3), row-major. Only read when\n `has_non_grav_covariance = 1`."]
285 pub non_grav_covariance: [[f64; 3usize]; 3usize],
286 #[doc = " Phase-function model. `EMPYREAN_PHASE_FUNCTION_NONE` disables\n magnitude computation; the other values map to villeneuve's\n `PhaseFunction` enum."]
287 pub phot_system: i32,
288 #[doc = " Absolute magnitude H. Ignored when `phot_system == NONE`."]
289 pub h_mag: f64,
290 #[doc = " Slope parameter slot 1 — G (HG), G₁ (HG1G2), or G₁₂ (HG12)."]
291 pub slope1: f64,
292 #[doc = " Slope parameter slot 2 — G₂ (HG1G2 only); unused (0) for HG / HG12."]
293 pub slope2: f64,
294 #[doc = " Continuous-thrust arcs (variable length). Null / `n_thrust_arcs == 0`\n ⇒ no thrust (gravity + non-grav only).\n\n **Ownership:** caller-owned; borrowed read-only for the duration of\n the call. The C ABI never frees it. A null pointer with\n `n_thrust_arcs > 0` is a loud argument error, not a silent skip; a\n non-null pointer with `n_thrust_arcs == 0` is treated as absent (the\n pointer is not read)."]
295 pub thrust_arcs: *const EmpyreanThrustArc,
296 #[doc = " Number of arcs in [`thrust_arcs`](Self::thrust_arcs)."]
297 pub n_thrust_arcs: usize,
298 #[doc = " Optional per-arc Δv corrections (AU/day), positional with\n [`thrust_arcs`](Self::thrust_arcs). Null / `n_dv_corrections == 0` ⇒\n no targeting corrections. Supplying corrections without any arc is a\n loud argument error.\n\n **Ownership:** caller-owned; borrowed read-only for the call."]
299 pub dv_corrections: *const [f64; 3usize],
300 #[doc = " Number of corrections in [`dv_corrections`](Self::dv_corrections)."]
301 pub n_dv_corrections: usize,
302 #[doc = " Optional 3×3 covariance (AU/day)² per Δv correction, positional with\n [`dv_corrections`](Self::dv_corrections). When non-empty its length\n MUST equal `n_dv_corrections`; a non-empty covariance triggers the\n wide-Jet burn-sensitivity propagation. The engine's higher-order\n (third-order) propagation path does not implement thrust-correction\n covariance and rejects that combination loudly upstream\n (`Not implemented: … ThirdOrder with thrust-correction covariance …`,\n surfaced as a propagation error) rather than silently dropping the\n covariance.\n\n **Ownership:** caller-owned; borrowed read-only for the call."]
303 pub correction_covariances: *const [[f64; 3usize]; 3usize],
304 #[doc = " Number of entries in\n [`correction_covariances`](Self::correction_covariances)."]
305 pub n_correction_covariances: usize,
306 #[doc = " 1 when this orbit carries a solar-radiation-pressure force slot\n (`srp_amrat` + `srp_cr`); 0 otherwise. SRP is **never** value-inferred\n — this explicit switch is the only trigger."]
307 pub has_srp: u8,
308 #[doc = " Area-to-mass ratio AMRAT (m²/kg) — the SRP-effective, fittable\n parameter. Only read when `has_srp == 1`; must be finite and > 0."]
309 pub srp_amrat: f64,
310 #[doc = " Radiation-pressure coefficient Cr. Fixed, never fitted. Only read\n when `has_srp == 1`; must be finite and > 0."]
311 pub srp_cr: f64,
312 #[doc = " Prior variance on AMRAT ((m²/kg)²). NaN or ≤0 = no prior; a finite\n positive value opens + priors the AMRAT column in a StateAndAMRAT /\n StateAndNonGravAndAMRAT fit. Only read when `has_srp == 1`."]
313 pub srp_amrat_variance: f64,
314}
315#[allow(clippy::unnecessary_operation, clippy::identity_op)]
316const _: () = {
317 ["Size of EmpyreanOrbit"][::std::mem::size_of::<EmpyreanOrbit>() - 648usize];
318 ["Alignment of EmpyreanOrbit"][::std::mem::align_of::<EmpyreanOrbit>() - 8usize];
319 ["Offset of field: EmpyreanOrbit::state"]
320 [::std::mem::offset_of!(EmpyreanOrbit, state) - 0usize];
321 ["Offset of field: EmpyreanOrbit::orbit_id"]
322 [::std::mem::offset_of!(EmpyreanOrbit, orbit_id) - 360usize];
323 ["Offset of field: EmpyreanOrbit::object_id"]
324 [::std::mem::offset_of!(EmpyreanOrbit, object_id) - 368usize];
325 ["Offset of field: EmpyreanOrbit::a1"][::std::mem::offset_of!(EmpyreanOrbit, a1) - 376usize];
326 ["Offset of field: EmpyreanOrbit::a2"][::std::mem::offset_of!(EmpyreanOrbit, a2) - 384usize];
327 ["Offset of field: EmpyreanOrbit::a3"][::std::mem::offset_of!(EmpyreanOrbit, a3) - 392usize];
328 ["Offset of field: EmpyreanOrbit::ng_alpha"]
329 [::std::mem::offset_of!(EmpyreanOrbit, ng_alpha) - 400usize];
330 ["Offset of field: EmpyreanOrbit::ng_r0"]
331 [::std::mem::offset_of!(EmpyreanOrbit, ng_r0) - 408usize];
332 ["Offset of field: EmpyreanOrbit::ng_m"]
333 [::std::mem::offset_of!(EmpyreanOrbit, ng_m) - 416usize];
334 ["Offset of field: EmpyreanOrbit::ng_n"]
335 [::std::mem::offset_of!(EmpyreanOrbit, ng_n) - 424usize];
336 ["Offset of field: EmpyreanOrbit::ng_k"]
337 [::std::mem::offset_of!(EmpyreanOrbit, ng_k) - 432usize];
338 ["Offset of field: EmpyreanOrbit::non_grav_dt"]
339 [::std::mem::offset_of!(EmpyreanOrbit, non_grav_dt) - 440usize];
340 ["Offset of field: EmpyreanOrbit::non_grav_dt_variance"]
341 [::std::mem::offset_of!(EmpyreanOrbit, non_grav_dt_variance) - 448usize];
342 ["Offset of field: EmpyreanOrbit::has_non_grav_covariance"]
343 [::std::mem::offset_of!(EmpyreanOrbit, has_non_grav_covariance) - 456usize];
344 ["Offset of field: EmpyreanOrbit::non_grav_covariance"]
345 [::std::mem::offset_of!(EmpyreanOrbit, non_grav_covariance) - 464usize];
346 ["Offset of field: EmpyreanOrbit::phot_system"]
347 [::std::mem::offset_of!(EmpyreanOrbit, phot_system) - 536usize];
348 ["Offset of field: EmpyreanOrbit::h_mag"]
349 [::std::mem::offset_of!(EmpyreanOrbit, h_mag) - 544usize];
350 ["Offset of field: EmpyreanOrbit::slope1"]
351 [::std::mem::offset_of!(EmpyreanOrbit, slope1) - 552usize];
352 ["Offset of field: EmpyreanOrbit::slope2"]
353 [::std::mem::offset_of!(EmpyreanOrbit, slope2) - 560usize];
354 ["Offset of field: EmpyreanOrbit::thrust_arcs"]
355 [::std::mem::offset_of!(EmpyreanOrbit, thrust_arcs) - 568usize];
356 ["Offset of field: EmpyreanOrbit::n_thrust_arcs"]
357 [::std::mem::offset_of!(EmpyreanOrbit, n_thrust_arcs) - 576usize];
358 ["Offset of field: EmpyreanOrbit::dv_corrections"]
359 [::std::mem::offset_of!(EmpyreanOrbit, dv_corrections) - 584usize];
360 ["Offset of field: EmpyreanOrbit::n_dv_corrections"]
361 [::std::mem::offset_of!(EmpyreanOrbit, n_dv_corrections) - 592usize];
362 ["Offset of field: EmpyreanOrbit::correction_covariances"]
363 [::std::mem::offset_of!(EmpyreanOrbit, correction_covariances) - 600usize];
364 ["Offset of field: EmpyreanOrbit::n_correction_covariances"]
365 [::std::mem::offset_of!(EmpyreanOrbit, n_correction_covariances) - 608usize];
366 ["Offset of field: EmpyreanOrbit::has_srp"]
367 [::std::mem::offset_of!(EmpyreanOrbit, has_srp) - 616usize];
368 ["Offset of field: EmpyreanOrbit::srp_amrat"]
369 [::std::mem::offset_of!(EmpyreanOrbit, srp_amrat) - 624usize];
370 ["Offset of field: EmpyreanOrbit::srp_cr"]
371 [::std::mem::offset_of!(EmpyreanOrbit, srp_cr) - 632usize];
372 ["Offset of field: EmpyreanOrbit::srp_amrat_variance"]
373 [::std::mem::offset_of!(EmpyreanOrbit, srp_amrat_variance) - 640usize];
374};
375impl Default for EmpyreanOrbit {
376 fn default() -> Self {
377 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
378 unsafe {
379 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
380 s.assume_init()
381 }
382 }
383}
384#[doc = " Uncertainty-propagation method, mirroring\n [`empyrean_core::propagation::UncertaintyMethod`] as a flat C struct.\n Fields outside the active variant are ignored — set them to zero /\n NaN.\n\n | tag | Variant | Active fields |\n |-----|---------|---------------|\n | 0 | First | (none) |\n | 1 | Second | (none) |\n | 2 | SigmaPoint | `sp_n_sigma`, `sp_samples_per_plane` |\n | 3 | MonteCarlo | `mc_n_samples`, `mc_seed_some` (1 = use `mc_seed`) |\n | 4 | Auto | `auto_threshold_first`, `auto_threshold_mixture`, `auto_threshold_ip_skip`, `auto_gmm_max_depth`, `auto_gmm_components_per_split` |"]
385#[repr(C)]
386#[derive(Debug, Default, Copy, Clone)]
387pub struct EmpyreanUncertaintyMethod {
388 #[doc = " Variant tag — see `EMPYREAN_UNCERTAINTY_*` constants."]
389 pub tag: u8,
390 #[doc = " SigmaPoint: number of sigma deviations (default 1.0)."]
391 pub sp_n_sigma: f64,
392 #[doc = " SigmaPoint: points per coordinate-plane pair (default 8 → 120 total)."]
393 pub sp_samples_per_plane: u64,
394 #[doc = " MonteCarlo: number of random samples."]
395 pub mc_n_samples: u64,
396 #[doc = " MonteCarlo: 1 if `mc_seed` is set, 0 to draw from `thread_rng`."]
397 pub mc_seed_some: u8,
398 #[doc = " MonteCarlo: RNG seed when `mc_seed_some == 1`."]
399 pub mc_seed: u64,
400 #[doc = " Auto: first-order regime tuning parameter."]
401 pub auto_threshold_first: f64,
402 #[doc = " Auto: adaptive-mixture regime tuning parameter."]
403 pub auto_threshold_mixture: f64,
404 #[doc = " Auto: impact-probability tuning parameter for the higher-order pass."]
405 pub auto_threshold_ip_skip: f64,
406 #[doc = " Auto: adaptive-Gaussian-mixture maximum recursion depth."]
407 pub auto_gmm_max_depth: u64,
408 #[doc = " Auto: adaptive-Gaussian-mixture components per split (odd)."]
409 pub auto_gmm_components_per_split: u64,
410}
411#[allow(clippy::unnecessary_operation, clippy::identity_op)]
412const _: () = {
413 ["Size of EmpyreanUncertaintyMethod"]
414 [::std::mem::size_of::<EmpyreanUncertaintyMethod>() - 88usize];
415 ["Alignment of EmpyreanUncertaintyMethod"]
416 [::std::mem::align_of::<EmpyreanUncertaintyMethod>() - 8usize];
417 ["Offset of field: EmpyreanUncertaintyMethod::tag"]
418 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, tag) - 0usize];
419 ["Offset of field: EmpyreanUncertaintyMethod::sp_n_sigma"]
420 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, sp_n_sigma) - 8usize];
421 ["Offset of field: EmpyreanUncertaintyMethod::sp_samples_per_plane"]
422 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, sp_samples_per_plane) - 16usize];
423 ["Offset of field: EmpyreanUncertaintyMethod::mc_n_samples"]
424 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, mc_n_samples) - 24usize];
425 ["Offset of field: EmpyreanUncertaintyMethod::mc_seed_some"]
426 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, mc_seed_some) - 32usize];
427 ["Offset of field: EmpyreanUncertaintyMethod::mc_seed"]
428 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, mc_seed) - 40usize];
429 ["Offset of field: EmpyreanUncertaintyMethod::auto_threshold_first"]
430 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_threshold_first) - 48usize];
431 ["Offset of field: EmpyreanUncertaintyMethod::auto_threshold_mixture"]
432 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_threshold_mixture) - 56usize];
433 ["Offset of field: EmpyreanUncertaintyMethod::auto_threshold_ip_skip"]
434 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_threshold_ip_skip) - 64usize];
435 ["Offset of field: EmpyreanUncertaintyMethod::auto_gmm_max_depth"]
436 [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_gmm_max_depth) - 72usize];
437 ["Offset of field: EmpyreanUncertaintyMethod::auto_gmm_components_per_split"][::std::mem::offset_of!(
438 EmpyreanUncertaintyMethod,
439 auto_gmm_components_per_split
440 ) - 80usize];
441};
442#[doc = " Event-detection configuration. Mirrors\n [`villeneuve::events::EventConfig`] (less the `enrichment` sub-config,\n which carries internal nested data that doesn't translate cleanly\n through C — it always uses upstream defaults).\n\n `body_filter_naif` is non-owning: caller must keep the array alive\n for the duration of the propagation call. Pass `null` /\n `num_body_filter = 0` to monitor all bodies."]
443#[repr(C)]
444#[derive(Debug, Copy, Clone)]
445pub struct EmpyreanEventConfig {
446 pub close_approaches: u8,
447 pub impacts: u8,
448 pub atmospheric: u8,
449 pub possible_impacts: u8,
450 pub shadow_events: u8,
451 #[doc = " Number of NAIF IDs in [`body_filter_naif`]; 0 = monitor all bodies."]
452 pub num_body_filter: usize,
453 #[doc = " Pointer to `num_body_filter` NAIF IDs to restrict event monitoring."]
454 pub body_filter_naif: *const i32,
455 #[doc = " Insert dense output points around close approaches. 1 = on (auto-enables\n `cache_integrator_steps`), 0 = off (default)."]
456 pub dense_output: u8,
457 #[doc = " Cadence (days) of dense output. 0.0 → upstream default (5 minutes)."]
458 pub dense_output_cadence_days: f64,
459}
460#[allow(clippy::unnecessary_operation, clippy::identity_op)]
461const _: () = {
462 ["Size of EmpyreanEventConfig"][::std::mem::size_of::<EmpyreanEventConfig>() - 40usize];
463 ["Alignment of EmpyreanEventConfig"][::std::mem::align_of::<EmpyreanEventConfig>() - 8usize];
464 ["Offset of field: EmpyreanEventConfig::close_approaches"]
465 [::std::mem::offset_of!(EmpyreanEventConfig, close_approaches) - 0usize];
466 ["Offset of field: EmpyreanEventConfig::impacts"]
467 [::std::mem::offset_of!(EmpyreanEventConfig, impacts) - 1usize];
468 ["Offset of field: EmpyreanEventConfig::atmospheric"]
469 [::std::mem::offset_of!(EmpyreanEventConfig, atmospheric) - 2usize];
470 ["Offset of field: EmpyreanEventConfig::possible_impacts"]
471 [::std::mem::offset_of!(EmpyreanEventConfig, possible_impacts) - 3usize];
472 ["Offset of field: EmpyreanEventConfig::shadow_events"]
473 [::std::mem::offset_of!(EmpyreanEventConfig, shadow_events) - 4usize];
474 ["Offset of field: EmpyreanEventConfig::num_body_filter"]
475 [::std::mem::offset_of!(EmpyreanEventConfig, num_body_filter) - 8usize];
476 ["Offset of field: EmpyreanEventConfig::body_filter_naif"]
477 [::std::mem::offset_of!(EmpyreanEventConfig, body_filter_naif) - 16usize];
478 ["Offset of field: EmpyreanEventConfig::dense_output"]
479 [::std::mem::offset_of!(EmpyreanEventConfig, dense_output) - 24usize];
480 ["Offset of field: EmpyreanEventConfig::dense_output_cadence_days"]
481 [::std::mem::offset_of!(EmpyreanEventConfig, dense_output_cadence_days) - 32usize];
482};
483impl Default for EmpyreanEventConfig {
484 fn default() -> Self {
485 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
486 unsafe {
487 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
488 s.assume_init()
489 }
490 }
491}
492#[doc = " Per-trajectory diagnostic outputs (sensitivity, nonlinearity, …).\n Mirrors [`villeneuve::diagnostics::DiagnosticsConfig`].\n\n All metrics default to off. Sentinel: `0` for `sample_stride` →\n upstream default (1); a NaN threshold means \"no event emission for\n that metric\"."]
493#[repr(C)]
494#[derive(Debug, Default, Copy, Clone)]
495pub struct EmpyreanDiagnosticsConfig {
496 #[doc = " Frobenius norm of position-STM block. 1 = on, 0 = off."]
497 pub sensitivity: u8,
498 #[doc = " Hessian/gradient ratio (Jet2 only). 1 = on, 0 = off."]
499 pub nonlinearity: u8,
500 #[doc = " Finite-time Lyapunov exponent. 1 = on, 0 = off."]
501 pub lyapunov: u8,
502 #[doc = " Keyhole detection at close approaches (Jet1+). 1 = on, 0 = off."]
503 pub keyholes: u8,
504 #[doc = " Bifurcation detection at close approaches (Jet2 only). 1 = on, 0 = off."]
505 pub bifurcations: u8,
506 #[doc = " Timeseries sampling stride: every Nth integration step. 0 → upstream default (1)."]
507 pub sample_stride: usize,
508 #[doc = " Threshold for `HighSensitivity` events. NaN → no emission."]
509 pub sensitivity_threshold: f64,
510 #[doc = " Threshold for `ChaoticRegion` events. NaN → no emission."]
511 pub lyapunov_threshold: f64,
512 #[doc = " Threshold for `HighNonlinearity` events (Jet2 only). NaN → no emission."]
513 pub nonlinearity_threshold: f64,
514}
515#[allow(clippy::unnecessary_operation, clippy::identity_op)]
516const _: () = {
517 ["Size of EmpyreanDiagnosticsConfig"]
518 [::std::mem::size_of::<EmpyreanDiagnosticsConfig>() - 40usize];
519 ["Alignment of EmpyreanDiagnosticsConfig"]
520 [::std::mem::align_of::<EmpyreanDiagnosticsConfig>() - 8usize];
521 ["Offset of field: EmpyreanDiagnosticsConfig::sensitivity"]
522 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, sensitivity) - 0usize];
523 ["Offset of field: EmpyreanDiagnosticsConfig::nonlinearity"]
524 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, nonlinearity) - 1usize];
525 ["Offset of field: EmpyreanDiagnosticsConfig::lyapunov"]
526 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, lyapunov) - 2usize];
527 ["Offset of field: EmpyreanDiagnosticsConfig::keyholes"]
528 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, keyholes) - 3usize];
529 ["Offset of field: EmpyreanDiagnosticsConfig::bifurcations"]
530 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, bifurcations) - 4usize];
531 ["Offset of field: EmpyreanDiagnosticsConfig::sample_stride"]
532 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, sample_stride) - 8usize];
533 ["Offset of field: EmpyreanDiagnosticsConfig::sensitivity_threshold"]
534 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, sensitivity_threshold) - 16usize];
535 ["Offset of field: EmpyreanDiagnosticsConfig::lyapunov_threshold"]
536 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, lyapunov_threshold) - 24usize];
537 ["Offset of field: EmpyreanDiagnosticsConfig::nonlinearity_threshold"]
538 [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, nonlinearity_threshold) - 32usize];
539};
540#[doc = " Origin-switching configuration for trajectory splitting at body\n Laplace spheres of influence (Amato/Baù/Bombardelli 2017 §6).\n\n Default **enabled** (the `_DEFAULT` sentinel resolves to\n `enabled = 1`). When enabled, integration switches to a\n body-centric frame inside the SOI of each eligible body and back\n to SSB on exit. Set `enabled = 0` explicitly to opt out.\n\n At the C-ABI surface, the per-body opt-in list (`bodies` in\n villeneuve) is not yet exposed — `EMPYREAN_ORIGIN_SWITCHING_ON`\n selects all monitored bodies. File a request if per-body scoping\n is needed from the C-ABI surface."]
541#[repr(C)]
542#[derive(Debug, Default, Copy, Clone)]
543pub struct EmpyreanOriginSwitchingConfig {
544 #[doc = " Trajectory-splitting policy. Tri-state, see\n `EMPYREAN_ORIGIN_SWITCHING_*` constants:\n - `0 = DEFAULT` — use the upstream default (currently `ON`).\n This is what `memset(0)` gives, matching the same sentinel\n convention used for `dt_min` / `dt_initial` / `epsilon` /\n `hysteresis` etc. — external C consumers can zero-init the\n config struct and get the right behavior automatically.\n - `1 = ON` — force trajectory-splitting on (matches the prior\n semantic for `enabled = 1`, backward-compatible).\n - `2 = OFF` — force trajectory-splitting off. (The prior\n semantic for `enabled = 0` is now reachable only via this\n explicit value, since 0 now means DEFAULT.)\n\n Unknown values fall back to the upstream default."]
545 pub enabled: u8,
546 #[doc = " Fractional band around the acceleration-ratio crossover used\n to suppress chatter (default 0.2 = ±20 %). 0.0 → upstream\n default."]
547 pub hysteresis: f64,
548}
549#[allow(clippy::unnecessary_operation, clippy::identity_op)]
550const _: () = {
551 ["Size of EmpyreanOriginSwitchingConfig"]
552 [::std::mem::size_of::<EmpyreanOriginSwitchingConfig>() - 16usize];
553 ["Alignment of EmpyreanOriginSwitchingConfig"]
554 [::std::mem::align_of::<EmpyreanOriginSwitchingConfig>() - 8usize];
555 ["Offset of field: EmpyreanOriginSwitchingConfig::enabled"]
556 [::std::mem::offset_of!(EmpyreanOriginSwitchingConfig, enabled) - 0usize];
557 ["Offset of field: EmpyreanOriginSwitchingConfig::hysteresis"]
558 [::std::mem::offset_of!(EmpyreanOriginSwitchingConfig, hysteresis) - 8usize];
559};
560#[doc = " Integrator tuning. Mirrors\n [`villeneuve::propagation::AdvancedIntegratorConfig`]. The default\n integrator backend is Gauss-Radau 15 (GR15), derived solely from the\n published papers; `epsilon` is interpreted as the relative b₆\n truncation tolerance.\n\n Sentinel rule: `0.0` requests the upstream default for `epsilon` /\n `encounter_timescale_divisor`; `dt_initial` / `dt_min` use NaN to\n mean \"auto-compute\"; `0` requests the upstream defaults for\n `max_steps` and `max_dense_steps`."]
561#[repr(C)]
562#[derive(Debug, Default, Copy, Clone)]
563pub struct EmpyreanAdvancedIntegratorConfig {
564 #[doc = " Integrator backend (0 = GR15 default, 1 = DOP853). See\n `EMPYREAN_INTEGRATOR_*` constants."]
565 pub integrator: i32,
566 #[doc = " Truncation-error tolerance (relative b₆ for GR15, rtol for\n DOP853 paired with a fixed atol = 1e-14). 0.0 → upstream\n default (1e-9)."]
567 pub epsilon: f64,
568 #[doc = " Initial step size in days. NaN → auto from orbital timescale."]
569 pub dt_initial: f64,
570 #[doc = " Minimum allowed step size in days. NaN → auto."]
571 pub dt_min: f64,
572 #[doc = " Encounter dynamical-timescale step floor divisor. 0.0 → upstream default (1000.0)."]
573 pub encounter_timescale_divisor: f64,
574 #[doc = " Maximum integration steps before aborting. 0 → upstream default (10_000_000)."]
575 pub max_steps: usize,
576 #[doc = " Memory cap on the per-step b-coefficient cache. 0 → upstream default (100_000)."]
577 pub max_dense_steps: usize,
578 #[doc = " Cache the integrator's per-step b-coefficients for fast\n interpolation (light-time iteration, dense output around close\n approaches, arbitrary-epoch state queries). 1 = on, 0 = off\n (default)."]
579 pub cache_integrator_steps: u8,
580 #[doc = " Origin-switching trajectory-splitting configuration. Default\n enabled."]
581 pub origin_switching: EmpyreanOriginSwitchingConfig,
582}
583#[allow(clippy::unnecessary_operation, clippy::identity_op)]
584const _: () = {
585 ["Size of EmpyreanAdvancedIntegratorConfig"]
586 [::std::mem::size_of::<EmpyreanAdvancedIntegratorConfig>() - 80usize];
587 ["Alignment of EmpyreanAdvancedIntegratorConfig"]
588 [::std::mem::align_of::<EmpyreanAdvancedIntegratorConfig>() - 8usize];
589 ["Offset of field: EmpyreanAdvancedIntegratorConfig::integrator"]
590 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, integrator) - 0usize];
591 ["Offset of field: EmpyreanAdvancedIntegratorConfig::epsilon"]
592 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, epsilon) - 8usize];
593 ["Offset of field: EmpyreanAdvancedIntegratorConfig::dt_initial"]
594 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, dt_initial) - 16usize];
595 ["Offset of field: EmpyreanAdvancedIntegratorConfig::dt_min"]
596 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, dt_min) - 24usize];
597 ["Offset of field: EmpyreanAdvancedIntegratorConfig::encounter_timescale_divisor"][::std::mem::offset_of!(
598 EmpyreanAdvancedIntegratorConfig,
599 encounter_timescale_divisor
600 ) - 32usize];
601 ["Offset of field: EmpyreanAdvancedIntegratorConfig::max_steps"]
602 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, max_steps) - 40usize];
603 ["Offset of field: EmpyreanAdvancedIntegratorConfig::max_dense_steps"]
604 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, max_dense_steps) - 48usize];
605 ["Offset of field: EmpyreanAdvancedIntegratorConfig::cache_integrator_steps"][::std::mem::offset_of!(
606 EmpyreanAdvancedIntegratorConfig,
607 cache_integrator_steps
608 ) - 56usize];
609 ["Offset of field: EmpyreanAdvancedIntegratorConfig::origin_switching"]
610 [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, origin_switching) - 64usize];
611};
612#[doc = " Propagation configuration.\n\n Mirrors [`villeneuve::propagation::PropagationConfig`] structurally:\n shared scalar fields at the top, nested config bundles for events,\n diagnostics, and integrator tuning. Sentinel rule for primitive\n fields: `0` / `0.0` requests the upstream default; documented\n negative-value sentinels retain their special meanings.\n\n `stop_condition` and `events.enrichment` are not exposed at this\n surface — both carry internal nested data that doesn't translate\n cleanly. They use upstream defaults; reach for empyrean-core's\n Rust API when they need to be overridden."]
613#[repr(C)]
614#[derive(Debug, Copy, Clone)]
615pub struct EmpyreanPropagationConfig {
616 #[doc = " Force-model tier: 0=Approximate, 1=Basic, 2=Standard."]
617 pub force_model: i32,
618 #[doc = " Number of `excluded_perturbers` in [`excluded_perturbers_naif`]; 0 = none."]
619 pub num_excluded_perturbers: usize,
620 #[doc = " NAIF IDs to exclude (self-perturbation avoidance for SB441-N16\n bodies). Non-owning. Pass `null` / count 0 to use the full\n perturber set."]
621 pub excluded_perturbers_naif: *const i32,
622 #[doc = " Uncertainty-propagation method (tag + per-variant params)."]
623 pub uncertainty_method: EmpyreanUncertaintyMethod,
624 #[doc = " Force `Jet1<6>` integration even without input covariance.\n 1 = on, 0 = off (default)."]
625 pub compute_stm: u8,
626 #[doc = " Output reference frame: 0=ICRF, 1=EclipticJ2000."]
627 pub frame: i32,
628 pub events: EmpyreanEventConfig,
629 pub diagnostics: EmpyreanDiagnosticsConfig,
630 #[doc = " Threads for multi-orbit propagation. 0 = use all cores\n (Rayon default); positive N = exactly N cores."]
631 pub num_threads: usize,
632 pub advanced: EmpyreanAdvancedIntegratorConfig,
633}
634#[allow(clippy::unnecessary_operation, clippy::identity_op)]
635const _: () = {
636 ["Size of EmpyreanPropagationConfig"]
637 [::std::mem::size_of::<EmpyreanPropagationConfig>() - 288usize];
638 ["Alignment of EmpyreanPropagationConfig"]
639 [::std::mem::align_of::<EmpyreanPropagationConfig>() - 8usize];
640 ["Offset of field: EmpyreanPropagationConfig::force_model"]
641 [::std::mem::offset_of!(EmpyreanPropagationConfig, force_model) - 0usize];
642 ["Offset of field: EmpyreanPropagationConfig::num_excluded_perturbers"]
643 [::std::mem::offset_of!(EmpyreanPropagationConfig, num_excluded_perturbers) - 8usize];
644 ["Offset of field: EmpyreanPropagationConfig::excluded_perturbers_naif"]
645 [::std::mem::offset_of!(EmpyreanPropagationConfig, excluded_perturbers_naif) - 16usize];
646 ["Offset of field: EmpyreanPropagationConfig::uncertainty_method"]
647 [::std::mem::offset_of!(EmpyreanPropagationConfig, uncertainty_method) - 24usize];
648 ["Offset of field: EmpyreanPropagationConfig::compute_stm"]
649 [::std::mem::offset_of!(EmpyreanPropagationConfig, compute_stm) - 112usize];
650 ["Offset of field: EmpyreanPropagationConfig::frame"]
651 [::std::mem::offset_of!(EmpyreanPropagationConfig, frame) - 116usize];
652 ["Offset of field: EmpyreanPropagationConfig::events"]
653 [::std::mem::offset_of!(EmpyreanPropagationConfig, events) - 120usize];
654 ["Offset of field: EmpyreanPropagationConfig::diagnostics"]
655 [::std::mem::offset_of!(EmpyreanPropagationConfig, diagnostics) - 160usize];
656 ["Offset of field: EmpyreanPropagationConfig::num_threads"]
657 [::std::mem::offset_of!(EmpyreanPropagationConfig, num_threads) - 200usize];
658 ["Offset of field: EmpyreanPropagationConfig::advanced"]
659 [::std::mem::offset_of!(EmpyreanPropagationConfig, advanced) - 208usize];
660};
661impl Default for EmpyreanPropagationConfig {
662 fn default() -> Self {
663 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
664 unsafe {
665 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
666 s.assume_init()
667 }
668 }
669}
670#[doc = " A single propagated Cartesian state."]
671#[repr(C)]
672#[derive(Debug, Default, Copy, Clone)]
673pub struct EmpyreanPropagatedState {
674 pub epoch_mjd_tdb: f64,
675 pub x: f64,
676 pub y: f64,
677 pub z: f64,
678 pub vx: f64,
679 pub vy: f64,
680 pub vz: f64,
681 pub origin: i32,
682 pub frame: i32,
683 pub covariance: [[f64; 6usize]; 6usize],
684 pub has_covariance: u8,
685 #[doc = " State Transition Matrix Φ(t, t₀). Zero-filled when `has_stm` is 0."]
686 pub stm: [[f64; 6usize]; 6usize],
687 pub has_stm: u8,
688 #[doc = " State Transition Tensor Ψ(t, t₀). Zero-filled when `has_stt` is 0."]
689 pub stt: [[[f64; 6usize]; 6usize]; 6usize],
690 pub has_stt: u8,
691 #[doc = " Resolved [`CovarianceKind`](empyrean_core::propagation::CovarianceKind)\n at this output epoch — see `EMPYREAN_COVARIANCE_KIND_*`.\n Defaults to `LINEAR` for non-Auto methods and for Auto epochs\n outside CA windows."]
692 pub resolved_kind: u8,
693}
694#[allow(clippy::unnecessary_operation, clippy::identity_op)]
695const _: () = {
696 ["Size of EmpyreanPropagatedState"]
697 [::std::mem::size_of::<EmpyreanPropagatedState>() - 2392usize];
698 ["Alignment of EmpyreanPropagatedState"]
699 [::std::mem::align_of::<EmpyreanPropagatedState>() - 8usize];
700 ["Offset of field: EmpyreanPropagatedState::epoch_mjd_tdb"]
701 [::std::mem::offset_of!(EmpyreanPropagatedState, epoch_mjd_tdb) - 0usize];
702 ["Offset of field: EmpyreanPropagatedState::x"]
703 [::std::mem::offset_of!(EmpyreanPropagatedState, x) - 8usize];
704 ["Offset of field: EmpyreanPropagatedState::y"]
705 [::std::mem::offset_of!(EmpyreanPropagatedState, y) - 16usize];
706 ["Offset of field: EmpyreanPropagatedState::z"]
707 [::std::mem::offset_of!(EmpyreanPropagatedState, z) - 24usize];
708 ["Offset of field: EmpyreanPropagatedState::vx"]
709 [::std::mem::offset_of!(EmpyreanPropagatedState, vx) - 32usize];
710 ["Offset of field: EmpyreanPropagatedState::vy"]
711 [::std::mem::offset_of!(EmpyreanPropagatedState, vy) - 40usize];
712 ["Offset of field: EmpyreanPropagatedState::vz"]
713 [::std::mem::offset_of!(EmpyreanPropagatedState, vz) - 48usize];
714 ["Offset of field: EmpyreanPropagatedState::origin"]
715 [::std::mem::offset_of!(EmpyreanPropagatedState, origin) - 56usize];
716 ["Offset of field: EmpyreanPropagatedState::frame"]
717 [::std::mem::offset_of!(EmpyreanPropagatedState, frame) - 60usize];
718 ["Offset of field: EmpyreanPropagatedState::covariance"]
719 [::std::mem::offset_of!(EmpyreanPropagatedState, covariance) - 64usize];
720 ["Offset of field: EmpyreanPropagatedState::has_covariance"]
721 [::std::mem::offset_of!(EmpyreanPropagatedState, has_covariance) - 352usize];
722 ["Offset of field: EmpyreanPropagatedState::stm"]
723 [::std::mem::offset_of!(EmpyreanPropagatedState, stm) - 360usize];
724 ["Offset of field: EmpyreanPropagatedState::has_stm"]
725 [::std::mem::offset_of!(EmpyreanPropagatedState, has_stm) - 648usize];
726 ["Offset of field: EmpyreanPropagatedState::stt"]
727 [::std::mem::offset_of!(EmpyreanPropagatedState, stt) - 656usize];
728 ["Offset of field: EmpyreanPropagatedState::has_stt"]
729 [::std::mem::offset_of!(EmpyreanPropagatedState, has_stt) - 2384usize];
730 ["Offset of field: EmpyreanPropagatedState::resolved_kind"]
731 [::std::mem::offset_of!(EmpyreanPropagatedState, resolved_kind) - 2385usize];
732};
733#[doc = " A detected dynamical event from propagation.\n\n For `event_type = \"covariance_regime_change\"` the audit-trail\n fields (`previous_kind`, `resolved_kind`, `kappa`,\n `threshold_below`, `threshold_above`) carry the\n [`CovarianceRegimeChange`](empyrean_core::propagation::events::DynamicalEvent::CovarianceRegimeChange)\n payload and the body / distance / velocity fields are zeroed\n (regime changes don't carry a body or geometry — they're audit\n markers from\n [`UncertaintyMethod::Auto`](empyrean_core::propagation::UncertaintyMethod::Auto)).\n For all other events these fields are sentinel-filled\n (`0xFF` / NaN).\n\n Field names mirror empyrean-core's variant fields for the\n regime-change payload — no per-variant prefix."]
734#[repr(C)]
735#[derive(Debug, Copy, Clone)]
736pub struct EmpyreanEvent {
737 pub event_type: *mut ::std::os::raw::c_char,
738 pub orbit_id: *mut ::std::os::raw::c_char,
739 #[doc = " Object identifier looked up by `orbit_id` from the input batch.\n Empty string when the input had no `object_id`. Owning C string —\n caller frees via `*_result_free`."]
740 pub object_id: *mut ::std::os::raw::c_char,
741 pub body: *mut ::std::os::raw::c_char,
742 pub body_naif_id: i32,
743 pub epoch_mjd_tdb: f64,
744 pub distance_au: f64,
745 pub distance_km: f64,
746 pub relative_velocity_au_day: f64,
747 #[doc = " `CovarianceRegimeChange` payload: previous resolved kind.\n Sentinel `0xFF` for non-regime events."]
748 pub previous_kind: u8,
749 #[doc = " `CovarianceRegimeChange` payload: new resolved kind.\n Sentinel `0xFF` for non-regime events."]
750 pub resolved_kind: u8,
751 #[doc = " `CovarianceRegimeChange` payload: local nonlinearity κ\n recorded at the CA. NaN for non-regime events."]
752 pub kappa: f64,
753 #[doc = " `CovarianceRegimeChange` payload: lower κ value recorded in\n this audit payload. NaN for non-regime events."]
754 pub threshold_below: f64,
755 #[doc = " `CovarianceRegimeChange` payload: upper κ value recorded in\n this audit payload. NaN for non-regime events."]
756 pub threshold_above: f64,
757 #[doc = " `CaptureStart` / `CaptureEnd` payload: two-body energy w.r.t. the\n capturing body (AU²/day²). NaN for non-capture events."]
758 pub two_body_energy: f64,
759 #[doc = " `CaptureStart` / `CaptureEnd` payload: Jacobi constant in the\n CR3BP. NaN for non-capture events or when unavailable."]
760 pub jacobi_constant: f64,
761 #[doc = " `CaptureStart` / `CaptureEnd` payload: 1σ uncertainty on the\n Jacobi constant. NaN when unavailable."]
762 pub jacobi_constant_sigma: f64,
763 #[doc = " `CaptureStart` / `CaptureEnd` payload: Jacobi constant at the L1\n gateway. NaN when unavailable."]
764 pub jacobi_constant_l1: f64,
765 #[doc = " `CaptureStart` / `CaptureEnd` payload: Jacobi constant at the L2\n gateway. NaN when unavailable."]
766 pub jacobi_constant_l2: f64,
767 #[doc = " `CaptureEnd` payload: number of periapsis passages during the\n temporary capture. `-1` sentinel for non-`CaptureEnd` events."]
768 pub n_periapses: i32,
769 #[doc = " `Impact` payload: planetodetic latitude of the surface intercept\n (degrees). NaN for non-impact events or when unresolved."]
770 pub impact_latitude_deg: f64,
771 #[doc = " `Impact` payload: planetodetic longitude of the surface intercept\n (degrees). NaN for non-impact events or when unresolved."]
772 pub impact_longitude_deg: f64,
773 #[doc = " `Impact` payload: altitude of the surface intercept above the\n reference ellipsoid (km). NaN for non-impact events or when\n unresolved."]
774 pub impact_altitude_km: f64,
775 #[doc = " `ShadowEntry` / `ShadowExit` payload: fraction of the Sun's disk\n occulted by the body (0 = none, 1 = full umbra). NaN for\n non-shadow events."]
776 pub shadow_fraction: f64,
777 #[doc = " `ShadowEntry` / `ShadowExit` payload: fraction of incident\n sunlight reaching the particle (1 = full sun, 0 = total eclipse).\n NaN for non-shadow events."]
778 pub illumination: f64,
779 #[doc = " `Periapsis` payload: relative position w.r.t. the approached body\n (AU), components x/y/z. NaN for non-periapsis events."]
780 pub relative_x: f64,
781 pub relative_y: f64,
782 pub relative_z: f64,
783 #[doc = " `Periapsis` payload: relative velocity w.r.t. the approached body\n (AU/day), components vx/vy/vz. NaN for non-periapsis events."]
784 pub relative_vx: f64,
785 pub relative_vy: f64,
786 pub relative_vz: f64,
787 #[doc = " `PossibleImpact` payload: effective capture radius with\n gravitational focusing (AU / km). NaN for non-possible-impact events."]
788 pub effective_radius_au: f64,
789 pub effective_radius_km: f64,
790 #[doc = " `PossibleImpact` payload: 1σ uncertainty along the miss direction\n (AU). NaN for non-possible-impact events."]
791 pub sigma_distance_au: f64,
792 #[doc = " `PossibleImpact` payload: linear (STM-mapped) impact probability.\n NaN for non-possible-impact events."]
793 pub ip_linear: f64,
794 #[doc = " `PossibleImpact` payload: second-order (Edgeworth) impact\n probability. NaN for non-possible-impact / first-order runs."]
795 pub ip_second_order: f64,
796 #[doc = " `PossibleImpact` payload: local nonlinearity κ at the encounter.\n NaN when unavailable."]
797 pub nonlinearity: f64,
798 #[doc = " `PossibleImpact` payload: adaptive-Gaussian-mixture impact\n probability. NaN when not an AGM run."]
799 pub ip_agm: f64,
800 #[doc = " `PossibleImpact` payload: Monte-Carlo impact probability. NaN when\n not a Monte-Carlo run."]
801 pub ip_mc: f64,
802}
803#[allow(clippy::unnecessary_operation, clippy::identity_op)]
804const _: () = {
805 ["Size of EmpyreanEvent"][::std::mem::size_of::<EmpyreanEvent>() - 304usize];
806 ["Alignment of EmpyreanEvent"][::std::mem::align_of::<EmpyreanEvent>() - 8usize];
807 ["Offset of field: EmpyreanEvent::event_type"]
808 [::std::mem::offset_of!(EmpyreanEvent, event_type) - 0usize];
809 ["Offset of field: EmpyreanEvent::orbit_id"]
810 [::std::mem::offset_of!(EmpyreanEvent, orbit_id) - 8usize];
811 ["Offset of field: EmpyreanEvent::object_id"]
812 [::std::mem::offset_of!(EmpyreanEvent, object_id) - 16usize];
813 ["Offset of field: EmpyreanEvent::body"][::std::mem::offset_of!(EmpyreanEvent, body) - 24usize];
814 ["Offset of field: EmpyreanEvent::body_naif_id"]
815 [::std::mem::offset_of!(EmpyreanEvent, body_naif_id) - 32usize];
816 ["Offset of field: EmpyreanEvent::epoch_mjd_tdb"]
817 [::std::mem::offset_of!(EmpyreanEvent, epoch_mjd_tdb) - 40usize];
818 ["Offset of field: EmpyreanEvent::distance_au"]
819 [::std::mem::offset_of!(EmpyreanEvent, distance_au) - 48usize];
820 ["Offset of field: EmpyreanEvent::distance_km"]
821 [::std::mem::offset_of!(EmpyreanEvent, distance_km) - 56usize];
822 ["Offset of field: EmpyreanEvent::relative_velocity_au_day"]
823 [::std::mem::offset_of!(EmpyreanEvent, relative_velocity_au_day) - 64usize];
824 ["Offset of field: EmpyreanEvent::previous_kind"]
825 [::std::mem::offset_of!(EmpyreanEvent, previous_kind) - 72usize];
826 ["Offset of field: EmpyreanEvent::resolved_kind"]
827 [::std::mem::offset_of!(EmpyreanEvent, resolved_kind) - 73usize];
828 ["Offset of field: EmpyreanEvent::kappa"]
829 [::std::mem::offset_of!(EmpyreanEvent, kappa) - 80usize];
830 ["Offset of field: EmpyreanEvent::threshold_below"]
831 [::std::mem::offset_of!(EmpyreanEvent, threshold_below) - 88usize];
832 ["Offset of field: EmpyreanEvent::threshold_above"]
833 [::std::mem::offset_of!(EmpyreanEvent, threshold_above) - 96usize];
834 ["Offset of field: EmpyreanEvent::two_body_energy"]
835 [::std::mem::offset_of!(EmpyreanEvent, two_body_energy) - 104usize];
836 ["Offset of field: EmpyreanEvent::jacobi_constant"]
837 [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant) - 112usize];
838 ["Offset of field: EmpyreanEvent::jacobi_constant_sigma"]
839 [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant_sigma) - 120usize];
840 ["Offset of field: EmpyreanEvent::jacobi_constant_l1"]
841 [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant_l1) - 128usize];
842 ["Offset of field: EmpyreanEvent::jacobi_constant_l2"]
843 [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant_l2) - 136usize];
844 ["Offset of field: EmpyreanEvent::n_periapses"]
845 [::std::mem::offset_of!(EmpyreanEvent, n_periapses) - 144usize];
846 ["Offset of field: EmpyreanEvent::impact_latitude_deg"]
847 [::std::mem::offset_of!(EmpyreanEvent, impact_latitude_deg) - 152usize];
848 ["Offset of field: EmpyreanEvent::impact_longitude_deg"]
849 [::std::mem::offset_of!(EmpyreanEvent, impact_longitude_deg) - 160usize];
850 ["Offset of field: EmpyreanEvent::impact_altitude_km"]
851 [::std::mem::offset_of!(EmpyreanEvent, impact_altitude_km) - 168usize];
852 ["Offset of field: EmpyreanEvent::shadow_fraction"]
853 [::std::mem::offset_of!(EmpyreanEvent, shadow_fraction) - 176usize];
854 ["Offset of field: EmpyreanEvent::illumination"]
855 [::std::mem::offset_of!(EmpyreanEvent, illumination) - 184usize];
856 ["Offset of field: EmpyreanEvent::relative_x"]
857 [::std::mem::offset_of!(EmpyreanEvent, relative_x) - 192usize];
858 ["Offset of field: EmpyreanEvent::relative_y"]
859 [::std::mem::offset_of!(EmpyreanEvent, relative_y) - 200usize];
860 ["Offset of field: EmpyreanEvent::relative_z"]
861 [::std::mem::offset_of!(EmpyreanEvent, relative_z) - 208usize];
862 ["Offset of field: EmpyreanEvent::relative_vx"]
863 [::std::mem::offset_of!(EmpyreanEvent, relative_vx) - 216usize];
864 ["Offset of field: EmpyreanEvent::relative_vy"]
865 [::std::mem::offset_of!(EmpyreanEvent, relative_vy) - 224usize];
866 ["Offset of field: EmpyreanEvent::relative_vz"]
867 [::std::mem::offset_of!(EmpyreanEvent, relative_vz) - 232usize];
868 ["Offset of field: EmpyreanEvent::effective_radius_au"]
869 [::std::mem::offset_of!(EmpyreanEvent, effective_radius_au) - 240usize];
870 ["Offset of field: EmpyreanEvent::effective_radius_km"]
871 [::std::mem::offset_of!(EmpyreanEvent, effective_radius_km) - 248usize];
872 ["Offset of field: EmpyreanEvent::sigma_distance_au"]
873 [::std::mem::offset_of!(EmpyreanEvent, sigma_distance_au) - 256usize];
874 ["Offset of field: EmpyreanEvent::ip_linear"]
875 [::std::mem::offset_of!(EmpyreanEvent, ip_linear) - 264usize];
876 ["Offset of field: EmpyreanEvent::ip_second_order"]
877 [::std::mem::offset_of!(EmpyreanEvent, ip_second_order) - 272usize];
878 ["Offset of field: EmpyreanEvent::nonlinearity"]
879 [::std::mem::offset_of!(EmpyreanEvent, nonlinearity) - 280usize];
880 ["Offset of field: EmpyreanEvent::ip_agm"]
881 [::std::mem::offset_of!(EmpyreanEvent, ip_agm) - 288usize];
882 ["Offset of field: EmpyreanEvent::ip_mc"]
883 [::std::mem::offset_of!(EmpyreanEvent, ip_mc) - 296usize];
884};
885impl Default for EmpyreanEvent {
886 fn default() -> Self {
887 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
888 unsafe {
889 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
890 s.assume_init()
891 }
892 }
893}
894#[doc = " One Gaussian sub-component of an AGM mixture decomposition.\n\n Mirrors\n [`empyrean_core::propagation::MixtureComponent`]. The mean carries\n the *propagated* sub-Gaussian centroid at the CA epoch (f64 from\n the Jet2 integrator); the covariance is the linearly-mapped\n \\\\(\\Phi \\, \\Sigma_k \\, \\Phi^\\top\\\\) over the same propagation\n segment. A consumer can evaluate\n \\\\(\\sum_k w_k \\\\, \\mathcal{N}(x \\mid \\mu_k, \\Sigma_k)\\\\) directly\n at the CA epoch.\n\n Each component is basis-tagged: `frame` / `origin` give the\n reference frame and center body its `mean` and `covariance` are\n expressed in, so the mixture is self-describing rather than relying\n on positional alignment with the propagated states."]
895#[repr(C)]
896#[derive(Debug, Default, Copy, Clone)]
897pub struct EmpyreanMixtureComponent {
898 pub weight: f64,
899 pub mean: [f64; 6usize],
900 pub covariance: [[f64; 6usize]; 6usize],
901 #[doc = " Reference frame `mean` / `covariance` are expressed in — the\n integration frame of the run. Same integer encoding as\n `EmpyreanPropagatedState.frame` (0 = ICRF, 1 = ecliptic J2000,\n 2 = ITRF93)."]
902 pub frame: i32,
903 #[doc = " Origin (center body) `mean` is expressed relative to, as a NAIF\n id — same encoding as `EmpyreanPropagatedState.origin`\n (e.g. 10 = Sun, 399 = Earth). Matches the propagation origin at\n the split's close-approach epoch, so it can differ between CA\n epochs of the same chain when origin switching occurred."]
904 pub origin: i32,
905}
906#[allow(clippy::unnecessary_operation, clippy::identity_op)]
907const _: () = {
908 ["Size of EmpyreanMixtureComponent"]
909 [::std::mem::size_of::<EmpyreanMixtureComponent>() - 352usize];
910 ["Alignment of EmpyreanMixtureComponent"]
911 [::std::mem::align_of::<EmpyreanMixtureComponent>() - 8usize];
912 ["Offset of field: EmpyreanMixtureComponent::weight"]
913 [::std::mem::offset_of!(EmpyreanMixtureComponent, weight) - 0usize];
914 ["Offset of field: EmpyreanMixtureComponent::mean"]
915 [::std::mem::offset_of!(EmpyreanMixtureComponent, mean) - 8usize];
916 ["Offset of field: EmpyreanMixtureComponent::covariance"]
917 [::std::mem::offset_of!(EmpyreanMixtureComponent, covariance) - 56usize];
918 ["Offset of field: EmpyreanMixtureComponent::frame"]
919 [::std::mem::offset_of!(EmpyreanMixtureComponent, frame) - 344usize];
920 ["Offset of field: EmpyreanMixtureComponent::origin"]
921 [::std::mem::offset_of!(EmpyreanMixtureComponent, origin) - 348usize];
922};
923#[doc = " Per-orbit AGM mixture decomposition retained by Auto / Mixture.\n\n Mirrors [`empyrean_core::propagation::MixtureChain`] in flat form.\n `ca_epochs_mjd_tdb` and `components_per_epoch` are\n `num_ca_epochs`-length parallel arrays. Components are flattened\n into a single `components` array — for CA index `k`, the slice is\n `components[components_offset[k] .. components_offset[k] +\n components_per_epoch[k]]`. `components_offset[k]` is the\n prefix-sum of `components_per_epoch[0..k]` (so\n `components_offset[0] == 0`).\n\n Only orbits whose AGM splits actually fired carry a chain;\n non-mixture orbits get one entry whose `num_ca_epochs == 0` and\n whose pointers are null."]
924#[repr(C)]
925#[derive(Debug, Copy, Clone)]
926pub struct EmpyreanMixtureChain {
927 #[doc = " Owning C string — caller frees via `*_result_free`."]
928 pub orbit_id: *mut ::std::os::raw::c_char,
929 #[doc = " `num_ca_epochs`-length array of CA epochs (mjd_tdb)."]
930 pub ca_epochs_mjd_tdb: *mut f64,
931 pub num_ca_epochs: usize,
932 #[doc = " `num_ca_epochs`-length array of per-epoch component counts."]
933 pub components_per_epoch: *mut usize,
934 #[doc = " `num_ca_epochs`-length array of starting offsets into the\n flattened `components` array. `components_offset[k]` is the\n prefix-sum of `components_per_epoch[0..k]`."]
935 pub components_offset: *mut usize,
936 #[doc = " Flattened components — total length =\n sum(components_per_epoch)."]
937 pub components: *mut EmpyreanMixtureComponent,
938 pub num_components_total: usize,
939}
940#[allow(clippy::unnecessary_operation, clippy::identity_op)]
941const _: () = {
942 ["Size of EmpyreanMixtureChain"][::std::mem::size_of::<EmpyreanMixtureChain>() - 56usize];
943 ["Alignment of EmpyreanMixtureChain"][::std::mem::align_of::<EmpyreanMixtureChain>() - 8usize];
944 ["Offset of field: EmpyreanMixtureChain::orbit_id"]
945 [::std::mem::offset_of!(EmpyreanMixtureChain, orbit_id) - 0usize];
946 ["Offset of field: EmpyreanMixtureChain::ca_epochs_mjd_tdb"]
947 [::std::mem::offset_of!(EmpyreanMixtureChain, ca_epochs_mjd_tdb) - 8usize];
948 ["Offset of field: EmpyreanMixtureChain::num_ca_epochs"]
949 [::std::mem::offset_of!(EmpyreanMixtureChain, num_ca_epochs) - 16usize];
950 ["Offset of field: EmpyreanMixtureChain::components_per_epoch"]
951 [::std::mem::offset_of!(EmpyreanMixtureChain, components_per_epoch) - 24usize];
952 ["Offset of field: EmpyreanMixtureChain::components_offset"]
953 [::std::mem::offset_of!(EmpyreanMixtureChain, components_offset) - 32usize];
954 ["Offset of field: EmpyreanMixtureChain::components"]
955 [::std::mem::offset_of!(EmpyreanMixtureChain, components) - 40usize];
956 ["Offset of field: EmpyreanMixtureChain::num_components_total"]
957 [::std::mem::offset_of!(EmpyreanMixtureChain, num_components_total) - 48usize];
958};
959impl Default for EmpyreanMixtureChain {
960 fn default() -> Self {
961 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
962 unsafe {
963 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
964 s.assume_init()
965 }
966 }
967}
968#[doc = " Propagation result containing states, events, and object identifiers.\n\n `mixtures` parallels `object_ids` only when populated — it is\n per-orbit (not per-state), so its length is the distinct orbit\n count, not `num_states`."]
969#[repr(C)]
970#[derive(Debug, Copy, Clone)]
971pub struct EmpyreanPropagationResult {
972 pub states: *mut EmpyreanPropagatedState,
973 pub num_states: usize,
974 pub object_ids: *mut *mut ::std::os::raw::c_char,
975 pub events: *mut EmpyreanEvent,
976 pub num_events: usize,
977 #[doc = " One [`EmpyreanMixtureChain`] per input orbit (positional with\n the input orbit batch). Empty / null when no orbits produced\n mixtures (the typical case for FirstOrder / SecondOrder /\n SigmaPoint / MonteCarlo)."]
978 pub mixtures: *mut EmpyreanMixtureChain,
979 pub num_mixtures: usize,
980 #[doc = " Opaque retained handle to the rich propagation result, enabling\n the on-demand tagged-covariance accessors\n (`empyrean_propagation_covariance_series_cartesian` /\n `_covariance_at_cartesian`). **Do not dereference from C** — it is\n freed by `empyrean_propagation_result_free`. Null when the\n propagation produced no retainable result."]
981 pub lazy_handle: *mut ::std::os::raw::c_void,
982}
983#[allow(clippy::unnecessary_operation, clippy::identity_op)]
984const _: () = {
985 ["Size of EmpyreanPropagationResult"]
986 [::std::mem::size_of::<EmpyreanPropagationResult>() - 64usize];
987 ["Alignment of EmpyreanPropagationResult"]
988 [::std::mem::align_of::<EmpyreanPropagationResult>() - 8usize];
989 ["Offset of field: EmpyreanPropagationResult::states"]
990 [::std::mem::offset_of!(EmpyreanPropagationResult, states) - 0usize];
991 ["Offset of field: EmpyreanPropagationResult::num_states"]
992 [::std::mem::offset_of!(EmpyreanPropagationResult, num_states) - 8usize];
993 ["Offset of field: EmpyreanPropagationResult::object_ids"]
994 [::std::mem::offset_of!(EmpyreanPropagationResult, object_ids) - 16usize];
995 ["Offset of field: EmpyreanPropagationResult::events"]
996 [::std::mem::offset_of!(EmpyreanPropagationResult, events) - 24usize];
997 ["Offset of field: EmpyreanPropagationResult::num_events"]
998 [::std::mem::offset_of!(EmpyreanPropagationResult, num_events) - 32usize];
999 ["Offset of field: EmpyreanPropagationResult::mixtures"]
1000 [::std::mem::offset_of!(EmpyreanPropagationResult, mixtures) - 40usize];
1001 ["Offset of field: EmpyreanPropagationResult::num_mixtures"]
1002 [::std::mem::offset_of!(EmpyreanPropagationResult, num_mixtures) - 48usize];
1003 ["Offset of field: EmpyreanPropagationResult::lazy_handle"]
1004 [::std::mem::offset_of!(EmpyreanPropagationResult, lazy_handle) - 56usize];
1005};
1006impl Default for EmpyreanPropagationResult {
1007 fn default() -> Self {
1008 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1009 unsafe {
1010 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1011 s.assume_init()
1012 }
1013 }
1014}
1015#[doc = " A single observer state for the C API."]
1016#[repr(C)]
1017#[derive(Debug, Default, Copy, Clone)]
1018pub struct EmpyreanObserver {
1019 #[doc = " MPC 3-character code, null-terminated (4 bytes)."]
1020 pub obs_code: [u8; 4usize],
1021 #[doc = " Epoch as MJD TDB."]
1022 pub epoch_mjd_tdb: f64,
1023 #[doc = " Position in ICRF relative to SSB (AU)."]
1024 pub x: f64,
1025 pub y: f64,
1026 pub z: f64,
1027 #[doc = " Velocity in ICRF relative to SSB (AU/day)."]
1028 pub vx: f64,
1029 pub vy: f64,
1030 pub vz: f64,
1031 #[doc = " Observing night as YYYYMMDD integer, or -1 if unavailable."]
1032 pub observing_night: i32,
1033}
1034#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1035const _: () = {
1036 ["Size of EmpyreanObserver"][::std::mem::size_of::<EmpyreanObserver>() - 72usize];
1037 ["Alignment of EmpyreanObserver"][::std::mem::align_of::<EmpyreanObserver>() - 8usize];
1038 ["Offset of field: EmpyreanObserver::obs_code"]
1039 [::std::mem::offset_of!(EmpyreanObserver, obs_code) - 0usize];
1040 ["Offset of field: EmpyreanObserver::epoch_mjd_tdb"]
1041 [::std::mem::offset_of!(EmpyreanObserver, epoch_mjd_tdb) - 8usize];
1042 ["Offset of field: EmpyreanObserver::x"][::std::mem::offset_of!(EmpyreanObserver, x) - 16usize];
1043 ["Offset of field: EmpyreanObserver::y"][::std::mem::offset_of!(EmpyreanObserver, y) - 24usize];
1044 ["Offset of field: EmpyreanObserver::z"][::std::mem::offset_of!(EmpyreanObserver, z) - 32usize];
1045 ["Offset of field: EmpyreanObserver::vx"]
1046 [::std::mem::offset_of!(EmpyreanObserver, vx) - 40usize];
1047 ["Offset of field: EmpyreanObserver::vy"]
1048 [::std::mem::offset_of!(EmpyreanObserver, vy) - 48usize];
1049 ["Offset of field: EmpyreanObserver::vz"]
1050 [::std::mem::offset_of!(EmpyreanObserver, vz) - 56usize];
1051 ["Offset of field: EmpyreanObserver::observing_night"]
1052 [::std::mem::offset_of!(EmpyreanObserver, observing_night) - 64usize];
1053};
1054#[doc = " Ephemeris-generation configuration.\n\n Wraps the inner [`EmpyreanPropagationConfig`] (force model,\n uncertainty method, output frame) plus the light-time iteration\n controls and a diagnostics toggle. The propagation runs internally\n to bring each orbit to its observation epoch, so every\n propagation-level knob applies here too."]
1055#[repr(C)]
1056#[derive(Debug, Copy, Clone)]
1057pub struct EmpyreanEphemerisConfig {
1058 #[doc = " Inner propagation configuration applied to the trajectory that\n brings each orbit to its observation epoch."]
1059 pub propagation: EmpyreanPropagationConfig,
1060 #[doc = " Maximum iterations for light-time convergence. 0 → use the\n upstream default (3)."]
1061 pub max_light_time_iterations: usize,
1062 #[doc = " Tolerance (days) for light-time convergence. 0.0 → upstream\n default (1e-10)."]
1063 pub light_time_tolerance_days: f64,
1064 #[doc = " 1 = compute phase angle / elongation / heliocentric distance /\n apparent magnitude. 0 = skip (faster; appropriate for OD inner\n loops that only need RA/Dec)."]
1065 pub compute_diagnostics: u8,
1066}
1067#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1068const _: () = {
1069 ["Size of EmpyreanEphemerisConfig"]
1070 [::std::mem::size_of::<EmpyreanEphemerisConfig>() - 312usize];
1071 ["Alignment of EmpyreanEphemerisConfig"]
1072 [::std::mem::align_of::<EmpyreanEphemerisConfig>() - 8usize];
1073 ["Offset of field: EmpyreanEphemerisConfig::propagation"]
1074 [::std::mem::offset_of!(EmpyreanEphemerisConfig, propagation) - 0usize];
1075 ["Offset of field: EmpyreanEphemerisConfig::max_light_time_iterations"]
1076 [::std::mem::offset_of!(EmpyreanEphemerisConfig, max_light_time_iterations) - 288usize];
1077 ["Offset of field: EmpyreanEphemerisConfig::light_time_tolerance_days"]
1078 [::std::mem::offset_of!(EmpyreanEphemerisConfig, light_time_tolerance_days) - 296usize];
1079 ["Offset of field: EmpyreanEphemerisConfig::compute_diagnostics"]
1080 [::std::mem::offset_of!(EmpyreanEphemerisConfig, compute_diagnostics) - 304usize];
1081};
1082impl Default for EmpyreanEphemerisConfig {
1083 fn default() -> Self {
1084 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1085 unsafe {
1086 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1087 s.assume_init()
1088 }
1089 }
1090}
1091#[doc = " A single predicted ephemeris entry."]
1092#[repr(C)]
1093#[derive(Debug, Copy, Clone)]
1094pub struct EmpyreanEphemerisEntry {
1095 #[doc = " Orbit identifier (heap-allocated, freed by empyrean_ephemeris_result_free)."]
1096 pub orbit_id: *mut ::std::os::raw::c_char,
1097 #[doc = " Epoch as MJD TDB."]
1098 pub epoch_mjd_tdb: f64,
1099 #[doc = " Right ascension (degrees)."]
1100 pub ra_deg: f64,
1101 #[doc = " Declination (degrees)."]
1102 pub dec_deg: f64,
1103 #[doc = " Topocentric distance (AU)."]
1104 pub rho_au: f64,
1105 #[doc = " Radial velocity (AU/day)."]
1106 pub vrho_au_day: f64,
1107 #[doc = " RA rate (deg/day)."]
1108 pub vra_deg_day: f64,
1109 #[doc = " Dec rate (deg/day)."]
1110 pub vdec_deg_day: f64,
1111 #[doc = " One-way light time (days). NaN if unavailable."]
1112 pub light_time_days: f64,
1113 #[doc = " Phase angle (degrees). NaN if unavailable."]
1114 pub phase_angle_deg: f64,
1115 #[doc = " Solar elongation (degrees). NaN if unavailable."]
1116 pub elongation_deg: f64,
1117 #[doc = " Heliocentric distance (AU). NaN if unavailable."]
1118 pub heliocentric_distance_au: f64,
1119 #[doc = " Predicted apparent magnitude. NaN if unavailable."]
1120 pub mag: f64,
1121 #[doc = " Magnitude uncertainty (1σ). Finite iff photometry is enabled AND\n the input orbit carried a state covariance; NaN otherwise. Today\n this reflects the state contribution only — an H-magnitude\n uncertainty is not yet an input, so `mag_sigma` under-reports σ_V\n when the H uncertainty is significant."]
1122 pub mag_sigma: f64,
1123 #[doc = " Topocentric zenith angle (degrees). NaN if unavailable (e.g. no\n observer geodetic position)."]
1124 pub zenith_angle_deg: f64,
1125 #[doc = " Topocentric azimuth, East of North (degrees). NaN if unavailable."]
1126 pub azimuth_deg: f64,
1127 #[doc = " Local hour angle (degrees). NaN if unavailable."]
1128 pub hour_angle_deg: f64,
1129 #[doc = " Angular separation from the Moon (degrees). NaN if unavailable."]
1130 pub lunar_elongation_deg: f64,
1131 #[doc = " Position angle of motion, East of North (degrees). NaN if unavailable."]
1132 pub position_angle_deg: f64,
1133 #[doc = " Total apparent sky-plane rate of motion (degrees/day). NaN if\n unavailable."]
1134 pub sky_rate_deg_day: f64,
1135 #[doc = " Observer code, null-terminated (4 bytes)."]
1136 pub obs_code: [u8; 4usize],
1137 #[doc = " 1 when `covariance` / `aberrated_state` / `aberrated_covariance`\n below are populated — i.e. the input orbit carried a state\n covariance and the STM/uncertainty path ran; 0 otherwise."]
1138 pub has_covariance: u8,
1139 #[doc = " 6×6 sky-plane covariance over (rho, RA, Dec, vrho, vRA, vDec) in\n (AU, deg) units, row-major. All-NaN when `has_covariance == 0`."]
1140 pub covariance: [[f64; 6usize]; 6usize],
1141 #[doc = " Aberrated (light-time corrected) barycentric ICRF Cartesian state\n `[x, y, z, vx, vy, vz]` (AU, AU/day) at the photon-emission epoch\n (`epoch_mjd_tdb - light_time_days`). Populated independently of\n covariance; NaN-filled in the (never-observed-today) case where\n the engine produced no aberrated state for the row."]
1142 pub aberrated_state: [f64; 6usize],
1143 #[doc = " 1 when `aberrated_covariance` is populated; 0 otherwise."]
1144 pub has_aberrated_covariance: u8,
1145 #[doc = " 6×6 Cartesian covariance of the aberrated state, row-major.\n All-NaN when `has_aberrated_covariance == 0`."]
1146 pub aberrated_covariance: [[f64; 6usize]; 6usize],
1147}
1148#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1149const _: () = {
1150 ["Size of EmpyreanEphemerisEntry"][::std::mem::size_of::<EmpyreanEphemerisEntry>() - 800usize];
1151 ["Alignment of EmpyreanEphemerisEntry"]
1152 [::std::mem::align_of::<EmpyreanEphemerisEntry>() - 8usize];
1153 ["Offset of field: EmpyreanEphemerisEntry::orbit_id"]
1154 [::std::mem::offset_of!(EmpyreanEphemerisEntry, orbit_id) - 0usize];
1155 ["Offset of field: EmpyreanEphemerisEntry::epoch_mjd_tdb"]
1156 [::std::mem::offset_of!(EmpyreanEphemerisEntry, epoch_mjd_tdb) - 8usize];
1157 ["Offset of field: EmpyreanEphemerisEntry::ra_deg"]
1158 [::std::mem::offset_of!(EmpyreanEphemerisEntry, ra_deg) - 16usize];
1159 ["Offset of field: EmpyreanEphemerisEntry::dec_deg"]
1160 [::std::mem::offset_of!(EmpyreanEphemerisEntry, dec_deg) - 24usize];
1161 ["Offset of field: EmpyreanEphemerisEntry::rho_au"]
1162 [::std::mem::offset_of!(EmpyreanEphemerisEntry, rho_au) - 32usize];
1163 ["Offset of field: EmpyreanEphemerisEntry::vrho_au_day"]
1164 [::std::mem::offset_of!(EmpyreanEphemerisEntry, vrho_au_day) - 40usize];
1165 ["Offset of field: EmpyreanEphemerisEntry::vra_deg_day"]
1166 [::std::mem::offset_of!(EmpyreanEphemerisEntry, vra_deg_day) - 48usize];
1167 ["Offset of field: EmpyreanEphemerisEntry::vdec_deg_day"]
1168 [::std::mem::offset_of!(EmpyreanEphemerisEntry, vdec_deg_day) - 56usize];
1169 ["Offset of field: EmpyreanEphemerisEntry::light_time_days"]
1170 [::std::mem::offset_of!(EmpyreanEphemerisEntry, light_time_days) - 64usize];
1171 ["Offset of field: EmpyreanEphemerisEntry::phase_angle_deg"]
1172 [::std::mem::offset_of!(EmpyreanEphemerisEntry, phase_angle_deg) - 72usize];
1173 ["Offset of field: EmpyreanEphemerisEntry::elongation_deg"]
1174 [::std::mem::offset_of!(EmpyreanEphemerisEntry, elongation_deg) - 80usize];
1175 ["Offset of field: EmpyreanEphemerisEntry::heliocentric_distance_au"]
1176 [::std::mem::offset_of!(EmpyreanEphemerisEntry, heliocentric_distance_au) - 88usize];
1177 ["Offset of field: EmpyreanEphemerisEntry::mag"]
1178 [::std::mem::offset_of!(EmpyreanEphemerisEntry, mag) - 96usize];
1179 ["Offset of field: EmpyreanEphemerisEntry::mag_sigma"]
1180 [::std::mem::offset_of!(EmpyreanEphemerisEntry, mag_sigma) - 104usize];
1181 ["Offset of field: EmpyreanEphemerisEntry::zenith_angle_deg"]
1182 [::std::mem::offset_of!(EmpyreanEphemerisEntry, zenith_angle_deg) - 112usize];
1183 ["Offset of field: EmpyreanEphemerisEntry::azimuth_deg"]
1184 [::std::mem::offset_of!(EmpyreanEphemerisEntry, azimuth_deg) - 120usize];
1185 ["Offset of field: EmpyreanEphemerisEntry::hour_angle_deg"]
1186 [::std::mem::offset_of!(EmpyreanEphemerisEntry, hour_angle_deg) - 128usize];
1187 ["Offset of field: EmpyreanEphemerisEntry::lunar_elongation_deg"]
1188 [::std::mem::offset_of!(EmpyreanEphemerisEntry, lunar_elongation_deg) - 136usize];
1189 ["Offset of field: EmpyreanEphemerisEntry::position_angle_deg"]
1190 [::std::mem::offset_of!(EmpyreanEphemerisEntry, position_angle_deg) - 144usize];
1191 ["Offset of field: EmpyreanEphemerisEntry::sky_rate_deg_day"]
1192 [::std::mem::offset_of!(EmpyreanEphemerisEntry, sky_rate_deg_day) - 152usize];
1193 ["Offset of field: EmpyreanEphemerisEntry::obs_code"]
1194 [::std::mem::offset_of!(EmpyreanEphemerisEntry, obs_code) - 160usize];
1195 ["Offset of field: EmpyreanEphemerisEntry::has_covariance"]
1196 [::std::mem::offset_of!(EmpyreanEphemerisEntry, has_covariance) - 164usize];
1197 ["Offset of field: EmpyreanEphemerisEntry::covariance"]
1198 [::std::mem::offset_of!(EmpyreanEphemerisEntry, covariance) - 168usize];
1199 ["Offset of field: EmpyreanEphemerisEntry::aberrated_state"]
1200 [::std::mem::offset_of!(EmpyreanEphemerisEntry, aberrated_state) - 456usize];
1201 ["Offset of field: EmpyreanEphemerisEntry::has_aberrated_covariance"]
1202 [::std::mem::offset_of!(EmpyreanEphemerisEntry, has_aberrated_covariance) - 504usize];
1203 ["Offset of field: EmpyreanEphemerisEntry::aberrated_covariance"]
1204 [::std::mem::offset_of!(EmpyreanEphemerisEntry, aberrated_covariance) - 512usize];
1205};
1206impl Default for EmpyreanEphemerisEntry {
1207 fn default() -> Self {
1208 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1209 unsafe {
1210 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1211 s.assume_init()
1212 }
1213 }
1214}
1215#[doc = " One observation-sensitivity row — the partial derivatives of the\n sky-plane observable w.r.t. the input state, for a single\n `(orbit, observer, epoch)`. One row per observation epoch within each\n `(orbit_id, obs_code)` chain. Owning struct: free\n the whole result with [`empyrean_ephemeris_result_free`].\n\n The Jacobian composes d(obs)/d(state at t_obs) * Phi(t_obs, t0) and\n omits the light-time terms (the -v * dtau/dx partial; the STM is\n sampled at t_obs rather than emission t_obs - tau): both are O(tau),\n landing in the velocity columns of the angle rows with fractional\n error ~ tau/dt (tau ~ 0.006-0.017 d) — negligible for multi-night\n arcs, growing as the arc shrinks toward intra-night."]
1216#[repr(C)]
1217#[derive(Debug, Copy, Clone)]
1218pub struct EmpyreanObservationSensitivity {
1219 #[doc = " Orbit identifier. Owning C string."]
1220 pub orbit_id: *mut ::std::os::raw::c_char,
1221 #[doc = " Object identifier (owning C string) or null when absent."]
1222 pub object_id: *mut ::std::os::raw::c_char,
1223 #[doc = " MPC observatory code, null-terminated (4 bytes)."]
1224 pub obs_code: [u8; 4usize],
1225 #[doc = " Observation epoch (MJD TDB)."]
1226 pub epoch_mjd_tdb: f64,
1227 #[doc = " Solved-parameter dimension: 6 (state) or 9 (state + non-grav)."]
1228 pub n_params: u8,
1229 #[doc = " Jacobian ∂(observable)/∂(input), row-major `[6][n_params]` flattened\n (length `6 * n_params`). Null when this epoch carries no Jacobian."]
1230 pub jacobian: *mut f64,
1231 #[doc = " Length of `jacobian` (`6 * n_params`), 0 when null."]
1232 pub jacobian_len: usize,
1233 #[doc = " Hessian ∂²(observable)/∂(input)², row-major `[6][n_params][n_params]`\n flattened (length `6 * n_params * n_params`). Null unless a\n second-order method (Jet2) ran."]
1234 pub hessian: *mut f64,
1235 #[doc = " Length of `hessian` (`6 * n_params²`), 0 when null."]
1236 pub hessian_len: usize,
1237 #[doc = " Frame of the input axis (Frame enum as int)."]
1238 pub frame: i32,
1239 #[doc = " Origin of the input axis (NAIF id)."]
1240 pub origin: i32,
1241}
1242#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1243const _: () = {
1244 ["Size of EmpyreanObservationSensitivity"]
1245 [::std::mem::size_of::<EmpyreanObservationSensitivity>() - 80usize];
1246 ["Alignment of EmpyreanObservationSensitivity"]
1247 [::std::mem::align_of::<EmpyreanObservationSensitivity>() - 8usize];
1248 ["Offset of field: EmpyreanObservationSensitivity::orbit_id"]
1249 [::std::mem::offset_of!(EmpyreanObservationSensitivity, orbit_id) - 0usize];
1250 ["Offset of field: EmpyreanObservationSensitivity::object_id"]
1251 [::std::mem::offset_of!(EmpyreanObservationSensitivity, object_id) - 8usize];
1252 ["Offset of field: EmpyreanObservationSensitivity::obs_code"]
1253 [::std::mem::offset_of!(EmpyreanObservationSensitivity, obs_code) - 16usize];
1254 ["Offset of field: EmpyreanObservationSensitivity::epoch_mjd_tdb"]
1255 [::std::mem::offset_of!(EmpyreanObservationSensitivity, epoch_mjd_tdb) - 24usize];
1256 ["Offset of field: EmpyreanObservationSensitivity::n_params"]
1257 [::std::mem::offset_of!(EmpyreanObservationSensitivity, n_params) - 32usize];
1258 ["Offset of field: EmpyreanObservationSensitivity::jacobian"]
1259 [::std::mem::offset_of!(EmpyreanObservationSensitivity, jacobian) - 40usize];
1260 ["Offset of field: EmpyreanObservationSensitivity::jacobian_len"]
1261 [::std::mem::offset_of!(EmpyreanObservationSensitivity, jacobian_len) - 48usize];
1262 ["Offset of field: EmpyreanObservationSensitivity::hessian"]
1263 [::std::mem::offset_of!(EmpyreanObservationSensitivity, hessian) - 56usize];
1264 ["Offset of field: EmpyreanObservationSensitivity::hessian_len"]
1265 [::std::mem::offset_of!(EmpyreanObservationSensitivity, hessian_len) - 64usize];
1266 ["Offset of field: EmpyreanObservationSensitivity::frame"]
1267 [::std::mem::offset_of!(EmpyreanObservationSensitivity, frame) - 72usize];
1268 ["Offset of field: EmpyreanObservationSensitivity::origin"]
1269 [::std::mem::offset_of!(EmpyreanObservationSensitivity, origin) - 76usize];
1270};
1271impl Default for EmpyreanObservationSensitivity {
1272 fn default() -> Self {
1273 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1274 unsafe {
1275 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1276 s.assume_init()
1277 }
1278 }
1279}
1280#[doc = " Result containing an array of ephemeris entries and, when an\n uncertainty method traced the STM, the observation-sensitivity chains."]
1281#[repr(C)]
1282#[derive(Debug, Copy, Clone)]
1283pub struct EmpyreanEphemerisResult {
1284 pub entries: *mut EmpyreanEphemerisEntry,
1285 pub num_entries: usize,
1286 #[doc = " Per-`(orbit, observer, epoch)` sensitivity rows. Null / 0 when no\n STM was traced (e.g. an f64-only path)."]
1287 pub sensitivity: *mut EmpyreanObservationSensitivity,
1288 pub num_sensitivity: usize,
1289 #[doc = " Non-fatal generation warnings: heap array of `num_warnings`\n NUL-terminated UTF-8 strings. Null when `num_warnings == 0` (a\n clean run). One list per call, not per row; each message names the\n affected orbit id, observatory code, and epoch (MJD TDB) where\n applicable. Freed by `empyrean_ephemeris_result_free`."]
1290 pub warnings: *mut *mut ::std::os::raw::c_char,
1291 #[doc = " Number of warning strings. 0 when the run had nothing to report."]
1292 pub num_warnings: usize,
1293}
1294#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1295const _: () = {
1296 ["Size of EmpyreanEphemerisResult"][::std::mem::size_of::<EmpyreanEphemerisResult>() - 48usize];
1297 ["Alignment of EmpyreanEphemerisResult"]
1298 [::std::mem::align_of::<EmpyreanEphemerisResult>() - 8usize];
1299 ["Offset of field: EmpyreanEphemerisResult::entries"]
1300 [::std::mem::offset_of!(EmpyreanEphemerisResult, entries) - 0usize];
1301 ["Offset of field: EmpyreanEphemerisResult::num_entries"]
1302 [::std::mem::offset_of!(EmpyreanEphemerisResult, num_entries) - 8usize];
1303 ["Offset of field: EmpyreanEphemerisResult::sensitivity"]
1304 [::std::mem::offset_of!(EmpyreanEphemerisResult, sensitivity) - 16usize];
1305 ["Offset of field: EmpyreanEphemerisResult::num_sensitivity"]
1306 [::std::mem::offset_of!(EmpyreanEphemerisResult, num_sensitivity) - 24usize];
1307 ["Offset of field: EmpyreanEphemerisResult::warnings"]
1308 [::std::mem::offset_of!(EmpyreanEphemerisResult, warnings) - 32usize];
1309 ["Offset of field: EmpyreanEphemerisResult::num_warnings"]
1310 [::std::mem::offset_of!(EmpyreanEphemerisResult, num_warnings) - 40usize];
1311};
1312impl Default for EmpyreanEphemerisResult {
1313 fn default() -> Self {
1314 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1315 unsafe {
1316 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1317 s.assume_init()
1318 }
1319 }
1320}
1321#[doc = " One entry of the kernel-identity manifest captured by a handle.\n\n Names the provenance of each loaded data file — never any tuning\n rationale. Free the owning [`EmpyreanSystemDescription`] with\n [`empyrean_builtsystem_description_free`]; do not free these fields\n individually."]
1322#[repr(C)]
1323#[derive(Debug, Copy, Clone)]
1324pub struct EmpyreanKernelRecord {
1325 #[doc = " Category of the entry (`EMPYREAN_KERNEL_KIND_*`)."]
1326 pub kind: i32,
1327 #[doc = " Where the entry came from (`EMPYREAN_KERNEL_PROVENANCE_*`)."]
1328 pub provenance: i32,
1329 #[doc = " Absolute path the kernel was loaded from. Non-null only for a\n `FILE` provenance; null otherwise. NUL-terminated UTF-8."]
1330 pub path: *mut ::std::os::raw::c_char,
1331 #[doc = " Lowercase-hex SHA-256 of the file's bytes (64 chars). Non-null only\n for a `FILE` provenance; null otherwise. NUL-terminated UTF-8."]
1332 pub sha256: *mut ::std::os::raw::c_char,
1333 #[doc = " Hashed file size in bytes. 0 unless `FILE` provenance."]
1334 pub bytes: u64,
1335 #[doc = " Human-readable model name. Non-null only for a `BUILT_IN`\n provenance; null otherwise. NUL-terminated UTF-8."]
1336 pub name: *mut ::std::os::raw::c_char,
1337}
1338#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1339const _: () = {
1340 ["Size of EmpyreanKernelRecord"][::std::mem::size_of::<EmpyreanKernelRecord>() - 40usize];
1341 ["Alignment of EmpyreanKernelRecord"][::std::mem::align_of::<EmpyreanKernelRecord>() - 8usize];
1342 ["Offset of field: EmpyreanKernelRecord::kind"]
1343 [::std::mem::offset_of!(EmpyreanKernelRecord, kind) - 0usize];
1344 ["Offset of field: EmpyreanKernelRecord::provenance"]
1345 [::std::mem::offset_of!(EmpyreanKernelRecord, provenance) - 4usize];
1346 ["Offset of field: EmpyreanKernelRecord::path"]
1347 [::std::mem::offset_of!(EmpyreanKernelRecord, path) - 8usize];
1348 ["Offset of field: EmpyreanKernelRecord::sha256"]
1349 [::std::mem::offset_of!(EmpyreanKernelRecord, sha256) - 16usize];
1350 ["Offset of field: EmpyreanKernelRecord::bytes"]
1351 [::std::mem::offset_of!(EmpyreanKernelRecord, bytes) - 24usize];
1352 ["Offset of field: EmpyreanKernelRecord::name"]
1353 [::std::mem::offset_of!(EmpyreanKernelRecord, name) - 32usize];
1354};
1355impl Default for EmpyreanKernelRecord {
1356 fn default() -> Self {
1357 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1358 unsafe {
1359 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1360 s.assume_init()
1361 }
1362 }
1363}
1364#[doc = " A reproducibility summary of a handle's frozen force model plus its\n captured kernel-identity manifest.\n\n Populated in full by [`empyrean_builtsystem_describe`] — every field\n reflects the assembled system; nothing is defaulted. Names the citable\n menu (tier, frame, GR, perturbers, BPC, kernel hashes) — never selection\n logic or tuning rationale. Release the heap-owned arrays with\n [`empyrean_builtsystem_description_free`]."]
1365#[repr(C)]
1366#[derive(Debug, Copy, Clone)]
1367pub struct EmpyreanSystemDescription {
1368 #[doc = " Force-model tier: 0=Approximate, 1=Basic, 2=Standard."]
1369 pub force_model: i32,
1370 #[doc = " Integration/output frame: 0=ICRF, 1=EclipticJ2000, 2=ITRF93."]
1371 pub frame: i32,
1372 #[doc = " The frozen encounter-timescale divisor."]
1373 pub encounter_timescale_divisor: f64,
1374 #[doc = " 1 if the post-Newtonian (EIH) GR correction is enabled, else 0."]
1375 pub relativistic: u8,
1376 #[doc = " 1 if the N16 asteroid perturbers are included, else 0."]
1377 pub asteroids: u8,
1378 #[doc = " 1 if a BPC (body-fixed rotation) kernel is loaded, else 0."]
1379 pub has_bpc: u8,
1380 #[doc = " Heap array of perturbing-body NAIF ids (length `num_perturbers`).\n Null when `num_perturbers == 0`."]
1381 pub perturber_origins: *mut i32,
1382 #[doc = " Number of entries in [`perturber_origins`](Self::perturber_origins)."]
1383 pub num_perturbers: usize,
1384 #[doc = " Heap array of kernel-identity records (length `num_kernels`). Null\n when `num_kernels == 0`."]
1385 pub kernels: *mut EmpyreanKernelRecord,
1386 #[doc = " Number of entries in [`kernels`](Self::kernels)."]
1387 pub num_kernels: usize,
1388}
1389#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1390const _: () = {
1391 ["Size of EmpyreanSystemDescription"]
1392 [::std::mem::size_of::<EmpyreanSystemDescription>() - 56usize];
1393 ["Alignment of EmpyreanSystemDescription"]
1394 [::std::mem::align_of::<EmpyreanSystemDescription>() - 8usize];
1395 ["Offset of field: EmpyreanSystemDescription::force_model"]
1396 [::std::mem::offset_of!(EmpyreanSystemDescription, force_model) - 0usize];
1397 ["Offset of field: EmpyreanSystemDescription::frame"]
1398 [::std::mem::offset_of!(EmpyreanSystemDescription, frame) - 4usize];
1399 ["Offset of field: EmpyreanSystemDescription::encounter_timescale_divisor"]
1400 [::std::mem::offset_of!(EmpyreanSystemDescription, encounter_timescale_divisor) - 8usize];
1401 ["Offset of field: EmpyreanSystemDescription::relativistic"]
1402 [::std::mem::offset_of!(EmpyreanSystemDescription, relativistic) - 16usize];
1403 ["Offset of field: EmpyreanSystemDescription::asteroids"]
1404 [::std::mem::offset_of!(EmpyreanSystemDescription, asteroids) - 17usize];
1405 ["Offset of field: EmpyreanSystemDescription::has_bpc"]
1406 [::std::mem::offset_of!(EmpyreanSystemDescription, has_bpc) - 18usize];
1407 ["Offset of field: EmpyreanSystemDescription::perturber_origins"]
1408 [::std::mem::offset_of!(EmpyreanSystemDescription, perturber_origins) - 24usize];
1409 ["Offset of field: EmpyreanSystemDescription::num_perturbers"]
1410 [::std::mem::offset_of!(EmpyreanSystemDescription, num_perturbers) - 32usize];
1411 ["Offset of field: EmpyreanSystemDescription::kernels"]
1412 [::std::mem::offset_of!(EmpyreanSystemDescription, kernels) - 40usize];
1413 ["Offset of field: EmpyreanSystemDescription::num_kernels"]
1414 [::std::mem::offset_of!(EmpyreanSystemDescription, num_kernels) - 48usize];
1415};
1416impl Default for EmpyreanSystemDescription {
1417 fn default() -> Self {
1418 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1419 unsafe {
1420 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1421 s.assume_init()
1422 }
1423 }
1424}
1425#[doc = " One impact-probability record emitted by\n [`empyrean_compute_impact_probabilities`]. Mirrors\n [`empyrean_core::impact::ImpactProbability`] flattened to primitives;\n nullable fields use NaN sentinels (Option<f64>) or 0 / null\n (Option<usize>).\n\n `method_tag` matches the `EMPYREAN_UNCERTAINTY_*` constants in\n `propagate.rs` and identifies which propagation produced this row."]
1426#[repr(C)]
1427#[derive(Debug, Copy, Clone)]
1428pub struct EmpyreanImpactProbability {
1429 #[doc = " Variant tag of the [`UncertaintyMethod`] that produced this row."]
1430 pub method_tag: u8,
1431 #[doc = " Owning C string — caller frees via `*_result_free`."]
1432 pub orbit_id: *mut ::std::os::raw::c_char,
1433 pub object_id: *mut ::std::os::raw::c_char,
1434 pub body: *mut ::std::os::raw::c_char,
1435 pub body_naif_id: i32,
1436 pub epoch_mjd_tdb: f64,
1437 pub miss_distance_au: f64,
1438 pub miss_distance_km: f64,
1439 pub effective_radius_au: f64,
1440 pub effective_radius_km: f64,
1441 pub sigma_distance_au: f64,
1442 pub sigma_distance_km: f64,
1443 pub ip_linear: f64,
1444 pub relative_velocity_au_day: f64,
1445 #[doc = " `ip_second_order`, NaN when not available."]
1446 pub ip_second_order: f64,
1447 #[doc = " Jet2 nonlinearity κ, NaN when not available."]
1448 pub nonlinearity: f64,
1449 #[doc = " AGM-mixed IP, NaN when not available."]
1450 pub ip_agm: f64,
1451 #[doc = " MC-sampled IP, NaN when not available."]
1452 pub ip_mc: f64,
1453 #[doc = " Number of MC samples drawn (0 when MC was not used)."]
1454 pub mc_n_samples: u64,
1455 #[doc = " Number of MC samples that impacted (0 when MC was not used)."]
1456 pub mc_n_impacts: u64,
1457 #[doc = " Geodetic latitude of the closest-approach surface point on the\n body's reference ellipsoid (degrees, north positive). NaN when no\n surface projection is available for this encounter."]
1458 pub impact_latitude_deg: f64,
1459 #[doc = " Geodetic longitude of the closest-approach surface point\n (degrees, east positive, [-180, 180]). NaN when unavailable."]
1460 pub impact_longitude_deg: f64,
1461 #[doc = " Altitude of the closest-approach point above the reference\n ellipsoid (km). NaN when unavailable."]
1462 pub impact_altitude_km: f64,
1463 #[doc = " Half-width of the 95% binomial confidence interval on `ip_mc`.\n The interval is `ip_mc ± mc_confidence_interval`. NaN when the\n producing method was not Monte Carlo."]
1464 pub mc_confidence_interval: f64,
1465 #[doc = " Second-order corrected mean miss distance (AU). On Monte-Carlo\n rows carries the sample-mean miss distance instead. NaN when the\n producing method computed neither."]
1466 pub mean_distance_second_order_au: f64,
1467 #[doc = " Second-order corrected 1σ miss-distance uncertainty (AU). NaN\n when the producing method carried no second-order derivatives."]
1468 pub sigma_distance_second_order_au: f64,
1469 #[doc = " Skewness γ₁ of the miss-distance distribution under the\n second-order expansion (dimensionless). NaN when not computed."]
1470 pub skewness: f64,
1471 #[doc = " Gradient ∂d/∂x₀ of the closest-approach distance w.r.t. the\n initial Cartesian state. All-zero on Monte-Carlo rows and on\n degenerate zero-miss encounters."]
1472 pub gradient: [f64; 6usize],
1473 #[doc = " Second derivatives ∂²d/∂x₀ᵢ∂x₀ⱼ of the closest-approach distance\n (6×6 symmetric). Every entry NaN when the producing method carried\n no second-order derivatives."]
1474 pub distance_hessian: [[f64; 6usize]; 6usize],
1475 #[doc = " Number of mixture components used by the adaptive\n Gaussian-mixture IP refinement. 0 when the refinement did not run\n (matches `ip_agm` = NaN)."]
1476 pub agm_components: u64,
1477}
1478#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1479const _: () = {
1480 ["Size of EmpyreanImpactProbability"]
1481 [::std::mem::size_of::<EmpyreanImpactProbability>() - 560usize];
1482 ["Alignment of EmpyreanImpactProbability"]
1483 [::std::mem::align_of::<EmpyreanImpactProbability>() - 8usize];
1484 ["Offset of field: EmpyreanImpactProbability::method_tag"]
1485 [::std::mem::offset_of!(EmpyreanImpactProbability, method_tag) - 0usize];
1486 ["Offset of field: EmpyreanImpactProbability::orbit_id"]
1487 [::std::mem::offset_of!(EmpyreanImpactProbability, orbit_id) - 8usize];
1488 ["Offset of field: EmpyreanImpactProbability::object_id"]
1489 [::std::mem::offset_of!(EmpyreanImpactProbability, object_id) - 16usize];
1490 ["Offset of field: EmpyreanImpactProbability::body"]
1491 [::std::mem::offset_of!(EmpyreanImpactProbability, body) - 24usize];
1492 ["Offset of field: EmpyreanImpactProbability::body_naif_id"]
1493 [::std::mem::offset_of!(EmpyreanImpactProbability, body_naif_id) - 32usize];
1494 ["Offset of field: EmpyreanImpactProbability::epoch_mjd_tdb"]
1495 [::std::mem::offset_of!(EmpyreanImpactProbability, epoch_mjd_tdb) - 40usize];
1496 ["Offset of field: EmpyreanImpactProbability::miss_distance_au"]
1497 [::std::mem::offset_of!(EmpyreanImpactProbability, miss_distance_au) - 48usize];
1498 ["Offset of field: EmpyreanImpactProbability::miss_distance_km"]
1499 [::std::mem::offset_of!(EmpyreanImpactProbability, miss_distance_km) - 56usize];
1500 ["Offset of field: EmpyreanImpactProbability::effective_radius_au"]
1501 [::std::mem::offset_of!(EmpyreanImpactProbability, effective_radius_au) - 64usize];
1502 ["Offset of field: EmpyreanImpactProbability::effective_radius_km"]
1503 [::std::mem::offset_of!(EmpyreanImpactProbability, effective_radius_km) - 72usize];
1504 ["Offset of field: EmpyreanImpactProbability::sigma_distance_au"]
1505 [::std::mem::offset_of!(EmpyreanImpactProbability, sigma_distance_au) - 80usize];
1506 ["Offset of field: EmpyreanImpactProbability::sigma_distance_km"]
1507 [::std::mem::offset_of!(EmpyreanImpactProbability, sigma_distance_km) - 88usize];
1508 ["Offset of field: EmpyreanImpactProbability::ip_linear"]
1509 [::std::mem::offset_of!(EmpyreanImpactProbability, ip_linear) - 96usize];
1510 ["Offset of field: EmpyreanImpactProbability::relative_velocity_au_day"]
1511 [::std::mem::offset_of!(EmpyreanImpactProbability, relative_velocity_au_day) - 104usize];
1512 ["Offset of field: EmpyreanImpactProbability::ip_second_order"]
1513 [::std::mem::offset_of!(EmpyreanImpactProbability, ip_second_order) - 112usize];
1514 ["Offset of field: EmpyreanImpactProbability::nonlinearity"]
1515 [::std::mem::offset_of!(EmpyreanImpactProbability, nonlinearity) - 120usize];
1516 ["Offset of field: EmpyreanImpactProbability::ip_agm"]
1517 [::std::mem::offset_of!(EmpyreanImpactProbability, ip_agm) - 128usize];
1518 ["Offset of field: EmpyreanImpactProbability::ip_mc"]
1519 [::std::mem::offset_of!(EmpyreanImpactProbability, ip_mc) - 136usize];
1520 ["Offset of field: EmpyreanImpactProbability::mc_n_samples"]
1521 [::std::mem::offset_of!(EmpyreanImpactProbability, mc_n_samples) - 144usize];
1522 ["Offset of field: EmpyreanImpactProbability::mc_n_impacts"]
1523 [::std::mem::offset_of!(EmpyreanImpactProbability, mc_n_impacts) - 152usize];
1524 ["Offset of field: EmpyreanImpactProbability::impact_latitude_deg"]
1525 [::std::mem::offset_of!(EmpyreanImpactProbability, impact_latitude_deg) - 160usize];
1526 ["Offset of field: EmpyreanImpactProbability::impact_longitude_deg"]
1527 [::std::mem::offset_of!(EmpyreanImpactProbability, impact_longitude_deg) - 168usize];
1528 ["Offset of field: EmpyreanImpactProbability::impact_altitude_km"]
1529 [::std::mem::offset_of!(EmpyreanImpactProbability, impact_altitude_km) - 176usize];
1530 ["Offset of field: EmpyreanImpactProbability::mc_confidence_interval"]
1531 [::std::mem::offset_of!(EmpyreanImpactProbability, mc_confidence_interval) - 184usize];
1532 ["Offset of field: EmpyreanImpactProbability::mean_distance_second_order_au"]
1533 [::std::mem::offset_of!(EmpyreanImpactProbability, mean_distance_second_order_au)
1534 - 192usize];
1535 ["Offset of field: EmpyreanImpactProbability::sigma_distance_second_order_au"]
1536 [::std::mem::offset_of!(EmpyreanImpactProbability, sigma_distance_second_order_au)
1537 - 200usize];
1538 ["Offset of field: EmpyreanImpactProbability::skewness"]
1539 [::std::mem::offset_of!(EmpyreanImpactProbability, skewness) - 208usize];
1540 ["Offset of field: EmpyreanImpactProbability::gradient"]
1541 [::std::mem::offset_of!(EmpyreanImpactProbability, gradient) - 216usize];
1542 ["Offset of field: EmpyreanImpactProbability::distance_hessian"]
1543 [::std::mem::offset_of!(EmpyreanImpactProbability, distance_hessian) - 264usize];
1544 ["Offset of field: EmpyreanImpactProbability::agm_components"]
1545 [::std::mem::offset_of!(EmpyreanImpactProbability, agm_components) - 552usize];
1546};
1547impl Default for EmpyreanImpactProbability {
1548 fn default() -> Self {
1549 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1550 unsafe {
1551 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1552 s.assume_init()
1553 }
1554 }
1555}
1556#[repr(C)]
1557#[derive(Debug, Copy, Clone)]
1558pub struct EmpyreanImpactProbabilitiesResult {
1559 pub records: *mut EmpyreanImpactProbability,
1560 pub num_records: usize,
1561}
1562#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1563const _: () = {
1564 ["Size of EmpyreanImpactProbabilitiesResult"]
1565 [::std::mem::size_of::<EmpyreanImpactProbabilitiesResult>() - 16usize];
1566 ["Alignment of EmpyreanImpactProbabilitiesResult"]
1567 [::std::mem::align_of::<EmpyreanImpactProbabilitiesResult>() - 8usize];
1568 ["Offset of field: EmpyreanImpactProbabilitiesResult::records"]
1569 [::std::mem::offset_of!(EmpyreanImpactProbabilitiesResult, records) - 0usize];
1570 ["Offset of field: EmpyreanImpactProbabilitiesResult::num_records"]
1571 [::std::mem::offset_of!(EmpyreanImpactProbabilitiesResult, num_records) - 8usize];
1572};
1573impl Default for EmpyreanImpactProbabilitiesResult {
1574 fn default() -> Self {
1575 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1576 unsafe {
1577 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1578 s.assume_init()
1579 }
1580 }
1581}
1582#[doc = " One B-plane breakdown emitted by [`empyrean_compute_b_planes`].\n Mirrors [`empyrean_core::impact::BPlaneData`] flattened to primitives.\n Nullable f64 fields use NaN sentinels."]
1583#[repr(C)]
1584#[derive(Debug, Copy, Clone)]
1585pub struct EmpyreanBPlane {
1586 #[doc = " Variant tag of the [`UncertaintyMethod`] that produced this row."]
1587 pub method_tag: u8,
1588 #[doc = " Owning C string — caller frees via `*_result_free`."]
1589 pub body: *mut ::std::os::raw::c_char,
1590 pub epoch_mjd_tdb: f64,
1591 pub b_dot_t_km: f64,
1592 pub b_dot_r_km: f64,
1593 pub b_mag_km: f64,
1594 pub v_inf_km_s: f64,
1595 pub effective_radius_km: f64,
1596 pub body_radius_km: f64,
1597 #[doc = " `[σ_TT, σ_TR, σ_RR]` covariance elements (km²); NaN when no\n projected covariance is available."]
1598 pub cov_b_plane: [f64; 3usize],
1599 pub semi_major_3sig_km: f64,
1600 pub semi_minor_3sig_km: f64,
1601 pub ellipse_angle_rad: f64,
1602 pub ip_linear: f64,
1603}
1604#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1605const _: () = {
1606 ["Size of EmpyreanBPlane"][::std::mem::size_of::<EmpyreanBPlane>() - 128usize];
1607 ["Alignment of EmpyreanBPlane"][::std::mem::align_of::<EmpyreanBPlane>() - 8usize];
1608 ["Offset of field: EmpyreanBPlane::method_tag"]
1609 [::std::mem::offset_of!(EmpyreanBPlane, method_tag) - 0usize];
1610 ["Offset of field: EmpyreanBPlane::body"]
1611 [::std::mem::offset_of!(EmpyreanBPlane, body) - 8usize];
1612 ["Offset of field: EmpyreanBPlane::epoch_mjd_tdb"]
1613 [::std::mem::offset_of!(EmpyreanBPlane, epoch_mjd_tdb) - 16usize];
1614 ["Offset of field: EmpyreanBPlane::b_dot_t_km"]
1615 [::std::mem::offset_of!(EmpyreanBPlane, b_dot_t_km) - 24usize];
1616 ["Offset of field: EmpyreanBPlane::b_dot_r_km"]
1617 [::std::mem::offset_of!(EmpyreanBPlane, b_dot_r_km) - 32usize];
1618 ["Offset of field: EmpyreanBPlane::b_mag_km"]
1619 [::std::mem::offset_of!(EmpyreanBPlane, b_mag_km) - 40usize];
1620 ["Offset of field: EmpyreanBPlane::v_inf_km_s"]
1621 [::std::mem::offset_of!(EmpyreanBPlane, v_inf_km_s) - 48usize];
1622 ["Offset of field: EmpyreanBPlane::effective_radius_km"]
1623 [::std::mem::offset_of!(EmpyreanBPlane, effective_radius_km) - 56usize];
1624 ["Offset of field: EmpyreanBPlane::body_radius_km"]
1625 [::std::mem::offset_of!(EmpyreanBPlane, body_radius_km) - 64usize];
1626 ["Offset of field: EmpyreanBPlane::cov_b_plane"]
1627 [::std::mem::offset_of!(EmpyreanBPlane, cov_b_plane) - 72usize];
1628 ["Offset of field: EmpyreanBPlane::semi_major_3sig_km"]
1629 [::std::mem::offset_of!(EmpyreanBPlane, semi_major_3sig_km) - 96usize];
1630 ["Offset of field: EmpyreanBPlane::semi_minor_3sig_km"]
1631 [::std::mem::offset_of!(EmpyreanBPlane, semi_minor_3sig_km) - 104usize];
1632 ["Offset of field: EmpyreanBPlane::ellipse_angle_rad"]
1633 [::std::mem::offset_of!(EmpyreanBPlane, ellipse_angle_rad) - 112usize];
1634 ["Offset of field: EmpyreanBPlane::ip_linear"]
1635 [::std::mem::offset_of!(EmpyreanBPlane, ip_linear) - 120usize];
1636};
1637impl Default for EmpyreanBPlane {
1638 fn default() -> Self {
1639 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1640 unsafe {
1641 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1642 s.assume_init()
1643 }
1644 }
1645}
1646#[repr(C)]
1647#[derive(Debug, Copy, Clone)]
1648pub struct EmpyreanBPlanesResult {
1649 pub records: *mut EmpyreanBPlane,
1650 pub num_records: usize,
1651}
1652#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1653const _: () = {
1654 ["Size of EmpyreanBPlanesResult"][::std::mem::size_of::<EmpyreanBPlanesResult>() - 16usize];
1655 ["Alignment of EmpyreanBPlanesResult"]
1656 [::std::mem::align_of::<EmpyreanBPlanesResult>() - 8usize];
1657 ["Offset of field: EmpyreanBPlanesResult::records"]
1658 [::std::mem::offset_of!(EmpyreanBPlanesResult, records) - 0usize];
1659 ["Offset of field: EmpyreanBPlanesResult::num_records"]
1660 [::std::mem::offset_of!(EmpyreanBPlanesResult, num_records) - 8usize];
1661};
1662impl Default for EmpyreanBPlanesResult {
1663 fn default() -> Self {
1664 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1665 unsafe {
1666 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1667 s.assume_init()
1668 }
1669 }
1670}
1671#[doc = " A batch of orbits with their identifiers.\n\n Returned by every `empyrean_orbits_read_*` and consumed by every\n `empyrean_orbits_write_*`. `orbit_ids` and `object_ids` are parallel\n to `orbits` (same length); each `object_ids[i]` may be null when the\n underlying orbit had no object designation.\n\n Free with [`empyrean_orbits_batch_free`] when done."]
1672#[repr(C)]
1673#[derive(Debug, Copy, Clone)]
1674pub struct EmpyreanOrbitBatch {
1675 #[doc = " Heap-allocated array of `EmpyreanOrbit`. Null when `num_orbits == 0`."]
1676 pub orbits: *mut EmpyreanOrbit,
1677 #[doc = " Heap-allocated array of orbit identifiers (null-terminated UTF-8).\n Each `orbit_ids[i]` is non-null when `i < num_orbits`."]
1678 pub orbit_ids: *mut *mut ::std::os::raw::c_char,
1679 #[doc = " Heap-allocated array of optional object identifiers\n (null-terminated UTF-8 or null pointer when absent)."]
1680 pub object_ids: *mut *mut ::std::os::raw::c_char,
1681 #[doc = " Number of orbits in the batch."]
1682 pub num_orbits: usize,
1683}
1684#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1685const _: () = {
1686 ["Size of EmpyreanOrbitBatch"][::std::mem::size_of::<EmpyreanOrbitBatch>() - 32usize];
1687 ["Alignment of EmpyreanOrbitBatch"][::std::mem::align_of::<EmpyreanOrbitBatch>() - 8usize];
1688 ["Offset of field: EmpyreanOrbitBatch::orbits"]
1689 [::std::mem::offset_of!(EmpyreanOrbitBatch, orbits) - 0usize];
1690 ["Offset of field: EmpyreanOrbitBatch::orbit_ids"]
1691 [::std::mem::offset_of!(EmpyreanOrbitBatch, orbit_ids) - 8usize];
1692 ["Offset of field: EmpyreanOrbitBatch::object_ids"]
1693 [::std::mem::offset_of!(EmpyreanOrbitBatch, object_ids) - 16usize];
1694 ["Offset of field: EmpyreanOrbitBatch::num_orbits"]
1695 [::std::mem::offset_of!(EmpyreanOrbitBatch, num_orbits) - 24usize];
1696};
1697impl Default for EmpyreanOrbitBatch {
1698 fn default() -> Self {
1699 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1700 unsafe {
1701 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1702 s.assume_init()
1703 }
1704 }
1705}
1706#[doc = " Per-observation result from orbit determination or evaluation.\n\n Mirrors scott's [`ObservationResult`](scott::results::ObservationResult)\n — every field upstream produces is carried across the C ABI. NaN /\n `EMPYREAN_REJECTION_NOT_EVALUATED` mark fields that aren't populated\n for the call type (e.g. evaluate doesn't compute rejection or\n influence diagnostics).\n\n `obs_id` is a heap-allocated NUL-terminated UTF-8 string; the\n pointer is freed by [`empyrean_od_result_free`] /\n [`empyrean_evaluate_result_free`] when the parent array is freed.\n Do NOT free it manually."]
1707#[repr(C)]
1708#[derive(Debug, Copy, Clone)]
1709pub struct EmpyreanObservationResult {
1710 #[doc = " ADES `obsID` (or scott auto-assigned). Owned by the parent array\n — freed by the matching `*_result_free` call."]
1711 pub obs_id: *mut ::std::os::raw::c_char,
1712 #[doc = " MPC observatory code (3-byte + NUL)."]
1713 pub obs_code: [u8; 4usize],
1714 #[doc = " Star catalog used for astrometric reduction (ADES `astCat`).\n Heap-allocated; null when ADES did not carry one. Freed with the array."]
1715 pub ast_cat: *mut ::std::os::raw::c_char,
1716 #[doc = " Observation epoch (MJD TDB)."]
1717 pub epoch_mjd_tdb: f64,
1718 #[doc = " RA·cosδ residual (observed - predicted), arcsec."]
1719 pub ra_residual_arcsec: f64,
1720 #[doc = " Dec residual, arcsec."]
1721 pub dec_residual_arcsec: f64,
1722 #[doc = " Mahalanobis χ² of this observation. NaN if covariance unavailable."]
1723 pub chi2: f64,
1724 #[doc = " Degrees of freedom (number of non-NaN residual dimensions)."]
1725 pub dof: u32,
1726 #[doc = " χ² survival probability."]
1727 pub probability: f64,
1728 #[doc = " Whether this observation was used in the fit (1 = yes, 0 = no)."]
1729 pub selected: u8,
1730 #[doc = " Combined obs+predicted RA covariance (arcsec²). NaN if absent."]
1731 pub residual_cov_ra: f64,
1732 #[doc = " Combined obs+predicted Dec covariance (arcsec²). NaN if absent."]
1733 pub residual_cov_dec: f64,
1734 #[doc = " Off-diagonal correlation coefficient (dimensionless, [-1, 1]). NaN if absent."]
1735 pub residual_cov_corr: f64,
1736 #[doc = " Reason this observation was kept / rejected. One of the\n `EMPYREAN_REJECTION_*` codes; `EMPYREAN_REJECTION_NOT_EVALUATED`\n when the call did not run rejection (e.g. `empyrean_evaluate`)."]
1737 pub rejection_reason: i32,
1738 #[doc = " Criterion value (chi², Cook's D, …) tested against the threshold. NaN if not evaluated."]
1739 pub rejection_criterion: f64,
1740 #[doc = " Static threshold the criterion was compared against. NaN if not evaluated."]
1741 pub rejection_threshold: f64,
1742 #[doc = " Effective threshold for adaptive rejection (Layer 3). NaN otherwise."]
1743 pub rejection_effective_threshold: f64,
1744 #[doc = " D-optimality information loss from removing this observation. NaN if not computed."]
1745 pub rejection_information_loss: f64,
1746 #[doc = " Cook's distance. NaN if no influence pass was run."]
1747 pub cooks_distance: f64,
1748 #[doc = " Scalar leverage h_ii ∈ [0, 2]. NaN if no influence pass."]
1749 pub leverage: f64,
1750 #[doc = " D-optimality fractional information contribution\n `f_i = tr(N⁻¹ I_i)`. NaN if no influence pass."]
1751 pub fractional_information: f64,
1752 #[doc = " Along-track residual (arcsec). NaN if no sky-motion rates."]
1753 pub along_track_arcsec: f64,
1754 #[doc = " Cross-track residual (arcsec). NaN if no sky-motion rates."]
1755 pub cross_track_arcsec: f64,
1756 #[doc = " Along-track 1σ (arcsec). NaN if unavailable."]
1757 pub along_track_error_arcsec: f64,
1758 #[doc = " Cross-track 1σ (arcsec). NaN if unavailable."]
1759 pub cross_track_error_arcsec: f64,
1760 #[doc = " Position angle of sky motion (degrees, East of North). NaN if unavailable."]
1761 pub track_position_angle_deg: f64,
1762 #[doc = " D-optimality information loss on removal, from the influence
1763 pass: logdet(N) − logdet(N − I_i). NaN if no influence pass was
1764 run, or if removing this observation makes the normal matrix
1765 singular (the observation is indispensable)."]
1766 pub influence_information_loss: f64,
1767 #[doc = " Off-diagonal covariance of the (along-track, cross-track)
1768 residual pair (arcsec²). Symmetric 2×2: the diagonal is
1769 `along_track_error_arcsec`² / `cross_track_error_arcsec`².
1770 NaN when the AT/CT covariance is unavailable."]
1771 pub along_cross_covariance_arcsec2: f64,
1772 #[doc = " Radar (delay/Doppler) residual: observed − predicted. Seconds
1773 for delay, hertz for Doppler (see `radar_kind`). NaN when
1774 `has_radar == 0`."]
1775 pub radar_residual: f64,
1776 #[doc = " χ² of the radar residual. NaN when `has_radar == 0`."]
1777 pub radar_chi2: f64,
1778 #[doc = " χ² survival probability of the radar residual. NaN when
1779 `has_radar == 0`."]
1780 pub radar_probability: f64,
1781 #[doc = " Combined observed+predicted radar residual variance (s² for
1782 delay, Hz² for Doppler). NaN when unavailable or
1783 `has_radar == 0`."]
1784 pub radar_variance: f64,
1785 #[doc = " Degrees of freedom of the radar residual (1 for radar). 0 when
1786 `has_radar == 0`."]
1787 pub radar_dof: u32,
1788 #[doc = " 1 when this row is a radar observation and the `radar_*` fields
1789 are live. The optical RA/Dec residual fields are NaN on radar
1790 rows."]
1791 pub has_radar: u8,
1792 #[doc = " `EMPYREAN_RADAR_KIND_DELAY` (0) or `EMPYREAN_RADAR_KIND_DOPPLER`
1793 (1). Only meaningful when `has_radar == 1`."]
1794 pub radar_kind: u8,
1795}
1796#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1797const _: () = {
1798 ["Size of EmpyreanObservationResult"]
1799 [::std::mem::size_of::<EmpyreanObservationResult>() - 264usize];
1800 ["Alignment of EmpyreanObservationResult"]
1801 [::std::mem::align_of::<EmpyreanObservationResult>() - 8usize];
1802 ["Offset of field: EmpyreanObservationResult::obs_id"]
1803 [::std::mem::offset_of!(EmpyreanObservationResult, obs_id) - 0usize];
1804 ["Offset of field: EmpyreanObservationResult::obs_code"]
1805 [::std::mem::offset_of!(EmpyreanObservationResult, obs_code) - 8usize];
1806 ["Offset of field: EmpyreanObservationResult::ast_cat"]
1807 [::std::mem::offset_of!(EmpyreanObservationResult, ast_cat) - 16usize];
1808 ["Offset of field: EmpyreanObservationResult::epoch_mjd_tdb"]
1809 [::std::mem::offset_of!(EmpyreanObservationResult, epoch_mjd_tdb) - 24usize];
1810 ["Offset of field: EmpyreanObservationResult::ra_residual_arcsec"]
1811 [::std::mem::offset_of!(EmpyreanObservationResult, ra_residual_arcsec) - 32usize];
1812 ["Offset of field: EmpyreanObservationResult::dec_residual_arcsec"]
1813 [::std::mem::offset_of!(EmpyreanObservationResult, dec_residual_arcsec) - 40usize];
1814 ["Offset of field: EmpyreanObservationResult::chi2"]
1815 [::std::mem::offset_of!(EmpyreanObservationResult, chi2) - 48usize];
1816 ["Offset of field: EmpyreanObservationResult::dof"]
1817 [::std::mem::offset_of!(EmpyreanObservationResult, dof) - 56usize];
1818 ["Offset of field: EmpyreanObservationResult::probability"]
1819 [::std::mem::offset_of!(EmpyreanObservationResult, probability) - 64usize];
1820 ["Offset of field: EmpyreanObservationResult::selected"]
1821 [::std::mem::offset_of!(EmpyreanObservationResult, selected) - 72usize];
1822 ["Offset of field: EmpyreanObservationResult::residual_cov_ra"]
1823 [::std::mem::offset_of!(EmpyreanObservationResult, residual_cov_ra) - 80usize];
1824 ["Offset of field: EmpyreanObservationResult::residual_cov_dec"]
1825 [::std::mem::offset_of!(EmpyreanObservationResult, residual_cov_dec) - 88usize];
1826 ["Offset of field: EmpyreanObservationResult::residual_cov_corr"]
1827 [::std::mem::offset_of!(EmpyreanObservationResult, residual_cov_corr) - 96usize];
1828 ["Offset of field: EmpyreanObservationResult::rejection_reason"]
1829 [::std::mem::offset_of!(EmpyreanObservationResult, rejection_reason) - 104usize];
1830 ["Offset of field: EmpyreanObservationResult::rejection_criterion"]
1831 [::std::mem::offset_of!(EmpyreanObservationResult, rejection_criterion) - 112usize];
1832 ["Offset of field: EmpyreanObservationResult::rejection_threshold"]
1833 [::std::mem::offset_of!(EmpyreanObservationResult, rejection_threshold) - 120usize];
1834 ["Offset of field: EmpyreanObservationResult::rejection_effective_threshold"][::std::mem::offset_of!(
1835 EmpyreanObservationResult,
1836 rejection_effective_threshold
1837 ) - 128usize];
1838 ["Offset of field: EmpyreanObservationResult::rejection_information_loss"]
1839 [::std::mem::offset_of!(EmpyreanObservationResult, rejection_information_loss) - 136usize];
1840 ["Offset of field: EmpyreanObservationResult::cooks_distance"]
1841 [::std::mem::offset_of!(EmpyreanObservationResult, cooks_distance) - 144usize];
1842 ["Offset of field: EmpyreanObservationResult::leverage"]
1843 [::std::mem::offset_of!(EmpyreanObservationResult, leverage) - 152usize];
1844 ["Offset of field: EmpyreanObservationResult::fractional_information"]
1845 [::std::mem::offset_of!(EmpyreanObservationResult, fractional_information) - 160usize];
1846 ["Offset of field: EmpyreanObservationResult::along_track_arcsec"]
1847 [::std::mem::offset_of!(EmpyreanObservationResult, along_track_arcsec) - 168usize];
1848 ["Offset of field: EmpyreanObservationResult::cross_track_arcsec"]
1849 [::std::mem::offset_of!(EmpyreanObservationResult, cross_track_arcsec) - 176usize];
1850 ["Offset of field: EmpyreanObservationResult::along_track_error_arcsec"]
1851 [::std::mem::offset_of!(EmpyreanObservationResult, along_track_error_arcsec) - 184usize];
1852 ["Offset of field: EmpyreanObservationResult::cross_track_error_arcsec"]
1853 [::std::mem::offset_of!(EmpyreanObservationResult, cross_track_error_arcsec) - 192usize];
1854 ["Offset of field: EmpyreanObservationResult::track_position_angle_deg"]
1855 [::std::mem::offset_of!(EmpyreanObservationResult, track_position_angle_deg) - 200usize];
1856 ["Offset of field: EmpyreanObservationResult::influence_information_loss"]
1857 [::std::mem::offset_of!(EmpyreanObservationResult, influence_information_loss) - 208usize];
1858 ["Offset of field: EmpyreanObservationResult::along_cross_covariance_arcsec2"]
1859 [::std::mem::offset_of!(EmpyreanObservationResult, along_cross_covariance_arcsec2)
1860 - 216usize];
1861 ["Offset of field: EmpyreanObservationResult::radar_residual"]
1862 [::std::mem::offset_of!(EmpyreanObservationResult, radar_residual) - 224usize];
1863 ["Offset of field: EmpyreanObservationResult::radar_chi2"]
1864 [::std::mem::offset_of!(EmpyreanObservationResult, radar_chi2) - 232usize];
1865 ["Offset of field: EmpyreanObservationResult::radar_probability"]
1866 [::std::mem::offset_of!(EmpyreanObservationResult, radar_probability) - 240usize];
1867 ["Offset of field: EmpyreanObservationResult::radar_variance"]
1868 [::std::mem::offset_of!(EmpyreanObservationResult, radar_variance) - 248usize];
1869 ["Offset of field: EmpyreanObservationResult::radar_dof"]
1870 [::std::mem::offset_of!(EmpyreanObservationResult, radar_dof) - 256usize];
1871 ["Offset of field: EmpyreanObservationResult::has_radar"]
1872 [::std::mem::offset_of!(EmpyreanObservationResult, has_radar) - 260usize];
1873 ["Offset of field: EmpyreanObservationResult::radar_kind"]
1874 [::std::mem::offset_of!(EmpyreanObservationResult, radar_kind) - 261usize];
1875};
1876impl Default for EmpyreanObservationResult {
1877 fn default() -> Self {
1878 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1879 unsafe {
1880 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1881 s.assume_init()
1882 }
1883 }
1884}
1885#[doc = " Result containing an array of observer states."]
1886#[repr(C)]
1887#[derive(Debug, Copy, Clone)]
1888pub struct EmpyreanObserverResult {
1889 pub observers: *mut EmpyreanObserver,
1890 pub num_observers: usize,
1891}
1892#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1893const _: () = {
1894 ["Size of EmpyreanObserverResult"][::std::mem::size_of::<EmpyreanObserverResult>() - 16usize];
1895 ["Alignment of EmpyreanObserverResult"]
1896 [::std::mem::align_of::<EmpyreanObserverResult>() - 8usize];
1897 ["Offset of field: EmpyreanObserverResult::observers"]
1898 [::std::mem::offset_of!(EmpyreanObserverResult, observers) - 0usize];
1899 ["Offset of field: EmpyreanObserverResult::num_observers"]
1900 [::std::mem::offset_of!(EmpyreanObserverResult, num_observers) - 8usize];
1901};
1902impl Default for EmpyreanObserverResult {
1903 fn default() -> Self {
1904 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
1905 unsafe {
1906 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
1907 s.assume_init()
1908 }
1909 }
1910}
1911#[doc = " A single optical observation for orbit determination — full ADES schema.\n\n String fields are nullable (`null` pointer = absent). Float fields\n use NaN as the absent sentinel. The `n_stars` integer uses `-1` as\n the absent sentinel (since `u32::MAX` is a valid count). The\n `obs_code` is fixed-size 4-byte null-padded to keep the common case\n allocation-free.\n\n Mirrors scott's `OpticalObservation` field-for-field — every named\n PSV column round-trips losslessly except for ADES extension fields\n not yet in the upstream schema."]
1912#[repr(C)]
1913#[derive(Debug, Copy, Clone)]
1914pub struct EmpyreanObservation {
1915 #[doc = " IAU permanent designation (nullable)."]
1916 pub perm_id: *mut ::std::os::raw::c_char,
1917 #[doc = " MPC provisional designation (nullable)."]
1918 pub prov_id: *mut ::std::os::raw::c_char,
1919 #[doc = " Observer-assigned tracklet identifier (nullable)."]
1920 pub trk_sub: *mut ::std::os::raw::c_char,
1921 #[doc = " MPC-assigned observation identifier (`obsid`, nullable)."]
1922 pub obs_id: *mut ::std::os::raw::c_char,
1923 #[doc = " Observer-assigned sub-identifier (`obsSubID`, nullable)."]
1924 pub obs_sub_id: *mut ::std::os::raw::c_char,
1925 #[doc = " Track identifier (`trkID`, nullable)."]
1926 pub trk_id: *mut ::std::os::raw::c_char,
1927 #[doc = " MPC observatory code, null-padded to 4 bytes."]
1928 pub obs_code: [u8; 4usize],
1929 #[doc = " Observation mode (CCD, CMOS, etc.) (nullable)."]
1930 pub mode: *mut ::std::os::raw::c_char,
1931 #[doc = " MPC program code (nullable)."]
1932 pub prog: *mut ::std::os::raw::c_char,
1933 #[doc = " Coordinate system for observer position (nullable)."]
1934 pub sys: *mut ::std::os::raw::c_char,
1935 #[doc = " Center body NAIF ID. NaN if unset."]
1936 pub ctr: f64,
1937 #[doc = " Position component 1 (lon for WGS84, X for ICRF_KM). NaN if unset."]
1938 pub pos1: f64,
1939 #[doc = " Position component 2 (lat for WGS84, Y for ICRF_KM). NaN if unset."]
1940 pub pos2: f64,
1941 #[doc = " Position component 3 (alt for WGS84, Z for ICRF_KM). NaN if unset."]
1942 pub pos3: f64,
1943 #[doc = " Observation time as ISO 8601 UTC string."]
1944 pub obs_time: *mut ::std::os::raw::c_char,
1945 #[doc = " Right ascension (degrees)."]
1946 pub ra_deg: f64,
1947 #[doc = " Declination (degrees)."]
1948 pub dec_deg: f64,
1949 #[doc = " RA·cos(Dec) uncertainty (arcseconds). NaN if unavailable."]
1950 pub rms_ra_arcsec: f64,
1951 #[doc = " Dec uncertainty (arcseconds). NaN if unavailable."]
1952 pub rms_dec_arcsec: f64,
1953 #[doc = " RA-Dec correlation coefficient [-1, 1]. NaN if unavailable."]
1954 pub rms_corr: f64,
1955 #[doc = " Star catalog used for astrometric reduction (nullable)."]
1956 pub ast_cat: *mut ::std::os::raw::c_char,
1957 #[doc = " Apparent magnitude. NaN if unavailable."]
1958 pub mag: f64,
1959 #[doc = " Magnitude uncertainty. NaN if unavailable."]
1960 pub rms_mag: f64,
1961 #[doc = " Photometric passband (nullable)."]
1962 pub band: *mut ::std::os::raw::c_char,
1963 #[doc = " Photometric catalog (nullable)."]
1964 pub phot_cat: *mut ::std::os::raw::c_char,
1965 #[doc = " Photometric aperture (arcseconds). NaN if unavailable."]
1966 pub phot_ap: f64,
1967 #[doc = " log10(SNR) of the detection. NaN if unavailable."]
1968 pub log_snr: f64,
1969 #[doc = " Seeing FWHM (arcseconds). NaN if unavailable."]
1970 pub seeing: f64,
1971 #[doc = " Exposure time (seconds). NaN if unavailable."]
1972 pub exp: f64,
1973 #[doc = " RMS of astrometric fit (arcseconds). NaN if unavailable."]
1974 pub rms_fit: f64,
1975 #[doc = " Number of reference stars in astrometric fit. -1 if unavailable."]
1976 pub n_stars: i32,
1977 #[doc = " MPC note flags (nullable)."]
1978 pub notes: *mut ::std::os::raw::c_char,
1979 #[doc = " Free-text observer remarks (nullable)."]
1980 pub remarks: *mut ::std::os::raw::c_char,
1981}
1982#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1983const _: () = {
1984 ["Size of EmpyreanObservation"][::std::mem::size_of::<EmpyreanObservation>() - 264usize];
1985 ["Alignment of EmpyreanObservation"][::std::mem::align_of::<EmpyreanObservation>() - 8usize];
1986 ["Offset of field: EmpyreanObservation::perm_id"]
1987 [::std::mem::offset_of!(EmpyreanObservation, perm_id) - 0usize];
1988 ["Offset of field: EmpyreanObservation::prov_id"]
1989 [::std::mem::offset_of!(EmpyreanObservation, prov_id) - 8usize];
1990 ["Offset of field: EmpyreanObservation::trk_sub"]
1991 [::std::mem::offset_of!(EmpyreanObservation, trk_sub) - 16usize];
1992 ["Offset of field: EmpyreanObservation::obs_id"]
1993 [::std::mem::offset_of!(EmpyreanObservation, obs_id) - 24usize];
1994 ["Offset of field: EmpyreanObservation::obs_sub_id"]
1995 [::std::mem::offset_of!(EmpyreanObservation, obs_sub_id) - 32usize];
1996 ["Offset of field: EmpyreanObservation::trk_id"]
1997 [::std::mem::offset_of!(EmpyreanObservation, trk_id) - 40usize];
1998 ["Offset of field: EmpyreanObservation::obs_code"]
1999 [::std::mem::offset_of!(EmpyreanObservation, obs_code) - 48usize];
2000 ["Offset of field: EmpyreanObservation::mode"]
2001 [::std::mem::offset_of!(EmpyreanObservation, mode) - 56usize];
2002 ["Offset of field: EmpyreanObservation::prog"]
2003 [::std::mem::offset_of!(EmpyreanObservation, prog) - 64usize];
2004 ["Offset of field: EmpyreanObservation::sys"]
2005 [::std::mem::offset_of!(EmpyreanObservation, sys) - 72usize];
2006 ["Offset of field: EmpyreanObservation::ctr"]
2007 [::std::mem::offset_of!(EmpyreanObservation, ctr) - 80usize];
2008 ["Offset of field: EmpyreanObservation::pos1"]
2009 [::std::mem::offset_of!(EmpyreanObservation, pos1) - 88usize];
2010 ["Offset of field: EmpyreanObservation::pos2"]
2011 [::std::mem::offset_of!(EmpyreanObservation, pos2) - 96usize];
2012 ["Offset of field: EmpyreanObservation::pos3"]
2013 [::std::mem::offset_of!(EmpyreanObservation, pos3) - 104usize];
2014 ["Offset of field: EmpyreanObservation::obs_time"]
2015 [::std::mem::offset_of!(EmpyreanObservation, obs_time) - 112usize];
2016 ["Offset of field: EmpyreanObservation::ra_deg"]
2017 [::std::mem::offset_of!(EmpyreanObservation, ra_deg) - 120usize];
2018 ["Offset of field: EmpyreanObservation::dec_deg"]
2019 [::std::mem::offset_of!(EmpyreanObservation, dec_deg) - 128usize];
2020 ["Offset of field: EmpyreanObservation::rms_ra_arcsec"]
2021 [::std::mem::offset_of!(EmpyreanObservation, rms_ra_arcsec) - 136usize];
2022 ["Offset of field: EmpyreanObservation::rms_dec_arcsec"]
2023 [::std::mem::offset_of!(EmpyreanObservation, rms_dec_arcsec) - 144usize];
2024 ["Offset of field: EmpyreanObservation::rms_corr"]
2025 [::std::mem::offset_of!(EmpyreanObservation, rms_corr) - 152usize];
2026 ["Offset of field: EmpyreanObservation::ast_cat"]
2027 [::std::mem::offset_of!(EmpyreanObservation, ast_cat) - 160usize];
2028 ["Offset of field: EmpyreanObservation::mag"]
2029 [::std::mem::offset_of!(EmpyreanObservation, mag) - 168usize];
2030 ["Offset of field: EmpyreanObservation::rms_mag"]
2031 [::std::mem::offset_of!(EmpyreanObservation, rms_mag) - 176usize];
2032 ["Offset of field: EmpyreanObservation::band"]
2033 [::std::mem::offset_of!(EmpyreanObservation, band) - 184usize];
2034 ["Offset of field: EmpyreanObservation::phot_cat"]
2035 [::std::mem::offset_of!(EmpyreanObservation, phot_cat) - 192usize];
2036 ["Offset of field: EmpyreanObservation::phot_ap"]
2037 [::std::mem::offset_of!(EmpyreanObservation, phot_ap) - 200usize];
2038 ["Offset of field: EmpyreanObservation::log_snr"]
2039 [::std::mem::offset_of!(EmpyreanObservation, log_snr) - 208usize];
2040 ["Offset of field: EmpyreanObservation::seeing"]
2041 [::std::mem::offset_of!(EmpyreanObservation, seeing) - 216usize];
2042 ["Offset of field: EmpyreanObservation::exp"]
2043 [::std::mem::offset_of!(EmpyreanObservation, exp) - 224usize];
2044 ["Offset of field: EmpyreanObservation::rms_fit"]
2045 [::std::mem::offset_of!(EmpyreanObservation, rms_fit) - 232usize];
2046 ["Offset of field: EmpyreanObservation::n_stars"]
2047 [::std::mem::offset_of!(EmpyreanObservation, n_stars) - 240usize];
2048 ["Offset of field: EmpyreanObservation::notes"]
2049 [::std::mem::offset_of!(EmpyreanObservation, notes) - 248usize];
2050 ["Offset of field: EmpyreanObservation::remarks"]
2051 [::std::mem::offset_of!(EmpyreanObservation, remarks) - 256usize];
2052};
2053impl Default for EmpyreanObservation {
2054 fn default() -> Self {
2055 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2056 unsafe {
2057 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2058 s.assume_init()
2059 }
2060 }
2061}
2062#[doc = " A single radar (delay or Doppler) observation for orbit determination —\n the ADES `<radar>` schema.\n\n ADES models radar astrometry as its own top-level table, parallel to\n `<optical>` (not as an optical `mode`). A record carries a round-trip\n time **delay** *or* a **Doppler** shift (the ADES `RadarValue` is an\n XSD `<choice>`), referred to a transmitting (`trx`) and receiving\n (`rcv`) station — equal for a monostatic observation, distinct for a\n bistatic one.\n\n **Units are ADES-native through this FFI — the C ABI performs ZERO unit\n conversion.** The delay *value* is in **seconds** while its uncertainty\n `rms_delay_microseconds` is in **microseconds** (this asymmetry is\n intentional in the ADES schema, verified against the IAU-ADES\n `a4179_radar` reference data and the JPL SSD radar API); Doppler value\n and uncertainty are both in **Hz**; `frq_mhz` is in **MHz**. The single\n SI normalisation happens once downstream in scott's\n `Observation::from_radar`, never here.\n\n String fields are nullable (`null` pointer = absent). The `trx`/`rcv`\n station codes are fixed-size 4-byte null-padded (like `obs_code`).\n Absent f64 fields use `f64::NAN`. The `com` flag is a tri-state `i8`.\n No field is silently zeroed or defaulted.\n\n Mirrors scott's `RadarObservation` field-for-field."]
2063#[repr(C)]
2064#[derive(Debug, Copy, Clone)]
2065pub struct EmpyreanRadarObservation {
2066 #[doc = " IAU permanent designation (nullable)."]
2067 pub perm_id: *mut ::std::os::raw::c_char,
2068 #[doc = " MPC provisional designation (nullable)."]
2069 pub prov_id: *mut ::std::os::raw::c_char,
2070 #[doc = " Observer-assigned tracklet identifier (nullable)."]
2071 pub trk_sub: *mut ::std::os::raw::c_char,
2072 #[doc = " MPC station code of the **transmitting** antenna (ADES `trx`),\n null-padded to 4 bytes."]
2073 pub trx: [u8; 4usize],
2074 #[doc = " MPC station code of the **receiving** antenna (ADES `rcv`),\n null-padded to 4 bytes. Equal to `trx` for a monostatic\n observation; differs for a bistatic one."]
2075 pub rcv: [u8; 4usize],
2076 #[doc = " Observation epoch as an ISO 8601 UTC string. For radar this is the\n **receive** epoch (the time the returned signal is recorded).\n Required, non-null."]
2077 pub obs_time: *mut ::std::os::raw::c_char,
2078 #[doc = " Measurement kind: `EMPYREAN_RADAR_KIND_DELAY` (0) or\n `EMPYREAN_RADAR_KIND_DOPPLER` (1). Selects which value pair is live."]
2079 pub kind: u8,
2080 #[doc = " Round-trip time delay in **seconds** (ADES-native). Valid iff\n `kind == EMPYREAN_RADAR_KIND_DELAY`, else `f64::NAN`."]
2081 pub delay_seconds: f64,
2082 #[doc = " 1σ uncertainty of the delay in **microseconds** (ADES-native; the\n asymmetry vs `delay_seconds` is intentional). Valid iff\n `kind == EMPYREAN_RADAR_KIND_DELAY`, else `f64::NAN`."]
2083 pub rms_delay_microseconds: f64,
2084 #[doc = " Doppler shift in **Hz** (ADES-native, signed). Valid iff\n `kind == EMPYREAN_RADAR_KIND_DOPPLER`, else `f64::NAN`."]
2085 pub doppler_hz: f64,
2086 #[doc = " 1σ uncertainty of the Doppler shift in **Hz** (ADES-native). Valid\n iff `kind == EMPYREAN_RADAR_KIND_DOPPLER`, else `f64::NAN`."]
2087 pub rms_doppler_hz: f64,
2088 #[doc = " Transmit carrier reference frequency in **MHz** (ADES `frq`).\n Required; relates a Doppler shift to a range rate."]
2089 pub frq_mhz: f64,
2090 #[doc = " Center-of-mass flag (ADES `com`), tri-state: `-1` = absent,\n `0` = false (peak-power / leading-edge reduction), `1` = true\n (reduced to target center of mass). Mirrors `Option<bool>`; a\n missing flag MUST map to `-1` (never `0`) — the ADES center-of-mass\n default is applied explicitly downstream, not silently here."]
2091 pub com: i8,
2092 #[doc = " log10(SNR) of the echo, if reported. `f64::NAN` if absent."]
2093 pub log_snr: f64,
2094 #[doc = " Free-text observer remarks (nullable)."]
2095 pub remarks: *mut ::std::os::raw::c_char,
2096}
2097#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2098const _: () = {
2099 ["Size of EmpyreanRadarObservation"]
2100 [::std::mem::size_of::<EmpyreanRadarObservation>() - 112usize];
2101 ["Alignment of EmpyreanRadarObservation"]
2102 [::std::mem::align_of::<EmpyreanRadarObservation>() - 8usize];
2103 ["Offset of field: EmpyreanRadarObservation::perm_id"]
2104 [::std::mem::offset_of!(EmpyreanRadarObservation, perm_id) - 0usize];
2105 ["Offset of field: EmpyreanRadarObservation::prov_id"]
2106 [::std::mem::offset_of!(EmpyreanRadarObservation, prov_id) - 8usize];
2107 ["Offset of field: EmpyreanRadarObservation::trk_sub"]
2108 [::std::mem::offset_of!(EmpyreanRadarObservation, trk_sub) - 16usize];
2109 ["Offset of field: EmpyreanRadarObservation::trx"]
2110 [::std::mem::offset_of!(EmpyreanRadarObservation, trx) - 24usize];
2111 ["Offset of field: EmpyreanRadarObservation::rcv"]
2112 [::std::mem::offset_of!(EmpyreanRadarObservation, rcv) - 28usize];
2113 ["Offset of field: EmpyreanRadarObservation::obs_time"]
2114 [::std::mem::offset_of!(EmpyreanRadarObservation, obs_time) - 32usize];
2115 ["Offset of field: EmpyreanRadarObservation::kind"]
2116 [::std::mem::offset_of!(EmpyreanRadarObservation, kind) - 40usize];
2117 ["Offset of field: EmpyreanRadarObservation::delay_seconds"]
2118 [::std::mem::offset_of!(EmpyreanRadarObservation, delay_seconds) - 48usize];
2119 ["Offset of field: EmpyreanRadarObservation::rms_delay_microseconds"]
2120 [::std::mem::offset_of!(EmpyreanRadarObservation, rms_delay_microseconds) - 56usize];
2121 ["Offset of field: EmpyreanRadarObservation::doppler_hz"]
2122 [::std::mem::offset_of!(EmpyreanRadarObservation, doppler_hz) - 64usize];
2123 ["Offset of field: EmpyreanRadarObservation::rms_doppler_hz"]
2124 [::std::mem::offset_of!(EmpyreanRadarObservation, rms_doppler_hz) - 72usize];
2125 ["Offset of field: EmpyreanRadarObservation::frq_mhz"]
2126 [::std::mem::offset_of!(EmpyreanRadarObservation, frq_mhz) - 80usize];
2127 ["Offset of field: EmpyreanRadarObservation::com"]
2128 [::std::mem::offset_of!(EmpyreanRadarObservation, com) - 88usize];
2129 ["Offset of field: EmpyreanRadarObservation::log_snr"]
2130 [::std::mem::offset_of!(EmpyreanRadarObservation, log_snr) - 96usize];
2131 ["Offset of field: EmpyreanRadarObservation::remarks"]
2132 [::std::mem::offset_of!(EmpyreanRadarObservation, remarks) - 104usize];
2133};
2134impl Default for EmpyreanRadarObservation {
2135 fn default() -> Self {
2136 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2137 unsafe {
2138 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2139 s.assume_init()
2140 }
2141 }
2142}
2143#[doc = " One element of [`EmpyreanWeightingConfig::additional_layers`].\n Tagged-union shape: the active fields depend on `kind`."]
2144#[repr(C)]
2145#[derive(Debug, Default, Copy, Clone)]
2146pub struct EmpyreanWeightingLayer {
2147 #[doc = " Layer kind discriminator — one of\n `EMPYREAN_WEIGHTING_LAYER_*`."]
2148 pub kind: i32,
2149 #[doc = " MPC observatory code, null-padded to 4 bytes."]
2150 pub obs_code: [u8; 4usize],
2151 #[doc = " 1σ RA·cos(δ) in arcsec."]
2152 pub sigma_ra_arcsec: f64,
2153 #[doc = " 1σ Dec in arcsec."]
2154 pub sigma_dec_arcsec: f64,
2155 #[doc = " Start of applicable time range (MJD TDB). NaN = unbounded."]
2156 pub start_epoch_mjd_tdb: f64,
2157 #[doc = " End of applicable time range (MJD TDB). NaN = unbounded."]
2158 pub end_epoch_mjd_tdb: f64,
2159 #[doc = " Scale factor on the resulting weight. 0.0 → upstream default (1.0)."]
2160 pub scale: f64,
2161 #[doc = " Maximum gap between observations to count as the same night\n (days). 0.0 → upstream default (0.5)."]
2162 pub max_gap_days: f64,
2163}
2164#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2165const _: () = {
2166 ["Size of EmpyreanWeightingLayer"][::std::mem::size_of::<EmpyreanWeightingLayer>() - 56usize];
2167 ["Alignment of EmpyreanWeightingLayer"]
2168 [::std::mem::align_of::<EmpyreanWeightingLayer>() - 8usize];
2169 ["Offset of field: EmpyreanWeightingLayer::kind"]
2170 [::std::mem::offset_of!(EmpyreanWeightingLayer, kind) - 0usize];
2171 ["Offset of field: EmpyreanWeightingLayer::obs_code"]
2172 [::std::mem::offset_of!(EmpyreanWeightingLayer, obs_code) - 4usize];
2173 ["Offset of field: EmpyreanWeightingLayer::sigma_ra_arcsec"]
2174 [::std::mem::offset_of!(EmpyreanWeightingLayer, sigma_ra_arcsec) - 8usize];
2175 ["Offset of field: EmpyreanWeightingLayer::sigma_dec_arcsec"]
2176 [::std::mem::offset_of!(EmpyreanWeightingLayer, sigma_dec_arcsec) - 16usize];
2177 ["Offset of field: EmpyreanWeightingLayer::start_epoch_mjd_tdb"]
2178 [::std::mem::offset_of!(EmpyreanWeightingLayer, start_epoch_mjd_tdb) - 24usize];
2179 ["Offset of field: EmpyreanWeightingLayer::end_epoch_mjd_tdb"]
2180 [::std::mem::offset_of!(EmpyreanWeightingLayer, end_epoch_mjd_tdb) - 32usize];
2181 ["Offset of field: EmpyreanWeightingLayer::scale"]
2182 [::std::mem::offset_of!(EmpyreanWeightingLayer, scale) - 40usize];
2183 ["Offset of field: EmpyreanWeightingLayer::max_gap_days"]
2184 [::std::mem::offset_of!(EmpyreanWeightingLayer, max_gap_days) - 48usize];
2185};
2186#[doc = " Weighting configuration. Mirrors\n [`scott::weighting::WeightingConfig`] structurally; extends it\n with an `enabled` toggle and a preset selector for the common\n case of \"use the production preset\" without constructing layers\n by hand.\n\n `enabled = 0` runs OD with uniform 1″ weighting (the old\n `use_weighting = 0` behavior). `enabled = 1` activates the\n pipeline; the resulting layer chain is the preset's layers\n followed by `additional_layers` (allows e.g. VFC17 + per-survey\n override)."]
2187#[repr(C)]
2188#[derive(Debug, Copy, Clone)]
2189pub struct EmpyreanWeightingConfig {
2190 #[doc = " 1 = enabled (default), 0 = uniform 1″ weighting."]
2191 pub enabled: u8,
2192 #[doc = " Preset selector. One of `EMPYREAN_WEIGHTING_PRESET_*`.\n Default `0` (NONE) means \"use additional_layers only\";\n when `enabled = 1` and zero-init, the conversion code\n substitutes `VFC17` so default-zero structs keep the\n production behavior."]
2193 pub preset: u8,
2194 #[doc = " Default 1σ used when no rule applies (arcsec). 0.0 →\n upstream default (1.0). Ignored when preset != NONE."]
2195 pub default_sigma_arcsec: f64,
2196 #[doc = " Sigma combination policy. -1 = use the preset's policy;\n otherwise one of `EMPYREAN_SIGMA_POLICY_*`."]
2197 pub sigma_policy: i32,
2198 #[doc = " Pointer to additional layers appended to the preset's chain.\n Non-owning — caller keeps the array alive for the OD call."]
2199 pub additional_layers: *const EmpyreanWeightingLayer,
2200 pub num_additional_layers: usize,
2201}
2202#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2203const _: () = {
2204 ["Size of EmpyreanWeightingConfig"][::std::mem::size_of::<EmpyreanWeightingConfig>() - 40usize];
2205 ["Alignment of EmpyreanWeightingConfig"]
2206 [::std::mem::align_of::<EmpyreanWeightingConfig>() - 8usize];
2207 ["Offset of field: EmpyreanWeightingConfig::enabled"]
2208 [::std::mem::offset_of!(EmpyreanWeightingConfig, enabled) - 0usize];
2209 ["Offset of field: EmpyreanWeightingConfig::preset"]
2210 [::std::mem::offset_of!(EmpyreanWeightingConfig, preset) - 1usize];
2211 ["Offset of field: EmpyreanWeightingConfig::default_sigma_arcsec"]
2212 [::std::mem::offset_of!(EmpyreanWeightingConfig, default_sigma_arcsec) - 8usize];
2213 ["Offset of field: EmpyreanWeightingConfig::sigma_policy"]
2214 [::std::mem::offset_of!(EmpyreanWeightingConfig, sigma_policy) - 16usize];
2215 ["Offset of field: EmpyreanWeightingConfig::additional_layers"]
2216 [::std::mem::offset_of!(EmpyreanWeightingConfig, additional_layers) - 24usize];
2217 ["Offset of field: EmpyreanWeightingConfig::num_additional_layers"]
2218 [::std::mem::offset_of!(EmpyreanWeightingConfig, num_additional_layers) - 32usize];
2219};
2220impl Default for EmpyreanWeightingConfig {
2221 fn default() -> Self {
2222 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2223 unsafe {
2224 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2225 s.assume_init()
2226 }
2227 }
2228}
2229#[doc = " Catalog-bias-correction configuration. Mirrors scott's\n `Option<Arc<DebiasingTable>>` field on `ODConfig`.\n\n `enabled = 0` runs OD with no catalog debiasing (matches the old\n `use_debiasing = 0` behavior). `enabled = 1` activates the\n EFCC2020 pipeline; the table is loaded from `bias_dat_path` if\n non-NULL, otherwise from the DataManager-default location at the\n requested `resolution`."]
2230#[repr(C)]
2231#[derive(Debug, Copy, Clone)]
2232pub struct EmpyreanDebiasingConfig {
2233 #[doc = " 1 = on (default), 0 = no debiasing."]
2234 pub enabled: u8,
2235 #[doc = " Table identity. Currently `EFCC2020` only."]
2236 pub table_id: i32,
2237 #[doc = " `EMPYREAN_DEBIASING_RESOLUTION_*` — Standard (~35 MB) or Hires (~567 MB)."]
2238 pub resolution: i32,
2239 #[doc = " Optional path to the bias.dat file. NULL = DataManager default.\n Non-owning."]
2240 pub bias_dat_path: *const ::std::os::raw::c_char,
2241}
2242#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2243const _: () = {
2244 ["Size of EmpyreanDebiasingConfig"][::std::mem::size_of::<EmpyreanDebiasingConfig>() - 24usize];
2245 ["Alignment of EmpyreanDebiasingConfig"]
2246 [::std::mem::align_of::<EmpyreanDebiasingConfig>() - 8usize];
2247 ["Offset of field: EmpyreanDebiasingConfig::enabled"]
2248 [::std::mem::offset_of!(EmpyreanDebiasingConfig, enabled) - 0usize];
2249 ["Offset of field: EmpyreanDebiasingConfig::table_id"]
2250 [::std::mem::offset_of!(EmpyreanDebiasingConfig, table_id) - 4usize];
2251 ["Offset of field: EmpyreanDebiasingConfig::resolution"]
2252 [::std::mem::offset_of!(EmpyreanDebiasingConfig, resolution) - 8usize];
2253 ["Offset of field: EmpyreanDebiasingConfig::bias_dat_path"]
2254 [::std::mem::offset_of!(EmpyreanDebiasingConfig, bias_dat_path) - 16usize];
2255};
2256impl Default for EmpyreanDebiasingConfig {
2257 fn default() -> Self {
2258 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2259 unsafe {
2260 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2261 s.assume_init()
2262 }
2263 }
2264}
2265#[doc = " Origin-policy selector for the OD pipeline (mirrors\n [`OriginPolicy`]).\n\n `policy = EMPYREAN_ORIGIN_POLICY_AUTO` ignores `explicit_naif`;\n `_EXPLICIT` interprets the field as the NAIF body ID of the central\n body to pin to (e.g. 10 = Sun, 399 = Earth, 4 = Mars-barycenter)."]
2266#[repr(C)]
2267#[derive(Debug, Default, Copy, Clone)]
2268pub struct EmpyreanOriginPolicy {
2269 pub policy: i32,
2270 pub explicit_naif: i32,
2271}
2272#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2273const _: () = {
2274 ["Size of EmpyreanOriginPolicy"][::std::mem::size_of::<EmpyreanOriginPolicy>() - 8usize];
2275 ["Alignment of EmpyreanOriginPolicy"][::std::mem::align_of::<EmpyreanOriginPolicy>() - 4usize];
2276 ["Offset of field: EmpyreanOriginPolicy::policy"]
2277 [::std::mem::offset_of!(EmpyreanOriginPolicy, policy) - 0usize];
2278 ["Offset of field: EmpyreanOriginPolicy::explicit_naif"]
2279 [::std::mem::offset_of!(EmpyreanOriginPolicy, explicit_naif) - 4usize];
2280};
2281#[doc = " IOD ranging tuning (mirrors the IOD section of [`scott::od::ODConfig`]).\n\n Nested rather than flattened so callers can pass the bundle around\n as a single value and zero-init pulls the upstream defaults\n uniformly. Sentinel rule: `0` / `0.0` requests the upstream default;\n `opposition_gap_days < 0` disables opposition splitting."]
2282#[repr(C)]
2283#[derive(Debug, Default, Copy, Clone)]
2284pub struct EmpyreanIODConfig {
2285 pub max_triplet_attempts: u32,
2286 pub max_triplet_span_days: f64,
2287 #[doc = " `-1.0` disables opposition splitting; `0.0` uses upstream default (90)."]
2288 pub opposition_gap_days: f64,
2289 pub max_iod_arc_days: f64,
2290 pub curvature_snr_threshold: f64,
2291 pub max_iod_fractional_sigma_a: f64,
2292}
2293#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2294const _: () = {
2295 ["Size of EmpyreanIODConfig"][::std::mem::size_of::<EmpyreanIODConfig>() - 48usize];
2296 ["Alignment of EmpyreanIODConfig"][::std::mem::align_of::<EmpyreanIODConfig>() - 8usize];
2297 ["Offset of field: EmpyreanIODConfig::max_triplet_attempts"]
2298 [::std::mem::offset_of!(EmpyreanIODConfig, max_triplet_attempts) - 0usize];
2299 ["Offset of field: EmpyreanIODConfig::max_triplet_span_days"]
2300 [::std::mem::offset_of!(EmpyreanIODConfig, max_triplet_span_days) - 8usize];
2301 ["Offset of field: EmpyreanIODConfig::opposition_gap_days"]
2302 [::std::mem::offset_of!(EmpyreanIODConfig, opposition_gap_days) - 16usize];
2303 ["Offset of field: EmpyreanIODConfig::max_iod_arc_days"]
2304 [::std::mem::offset_of!(EmpyreanIODConfig, max_iod_arc_days) - 24usize];
2305 ["Offset of field: EmpyreanIODConfig::curvature_snr_threshold"]
2306 [::std::mem::offset_of!(EmpyreanIODConfig, curvature_snr_threshold) - 32usize];
2307 ["Offset of field: EmpyreanIODConfig::max_iod_fractional_sigma_a"]
2308 [::std::mem::offset_of!(EmpyreanIODConfig, max_iod_fractional_sigma_a) - 40usize];
2309};
2310#[doc = " Output epoch specification (mirrors [`OutputEpoch`]).\n\n The `mode` field determines which variant is active:\n `EMPYREAN_OUTPUT_EPOCH_MID_ARC` / `_LAST_OBSERVATION` / `_IOD_EPOCH`\n ignore `explicit_mjd_tdb`; `_EXPLICIT` reads the field as MJD TDB."]
2311#[repr(C)]
2312#[derive(Debug, Default, Copy, Clone)]
2313pub struct EmpyreanOutputEpoch {
2314 pub mode: i32,
2315 pub explicit_mjd_tdb: f64,
2316}
2317#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2318const _: () = {
2319 ["Size of EmpyreanOutputEpoch"][::std::mem::size_of::<EmpyreanOutputEpoch>() - 16usize];
2320 ["Alignment of EmpyreanOutputEpoch"][::std::mem::align_of::<EmpyreanOutputEpoch>() - 8usize];
2321 ["Offset of field: EmpyreanOutputEpoch::mode"]
2322 [::std::mem::offset_of!(EmpyreanOutputEpoch, mode) - 0usize];
2323 ["Offset of field: EmpyreanOutputEpoch::explicit_mjd_tdb"]
2324 [::std::mem::offset_of!(EmpyreanOutputEpoch, explicit_mjd_tdb) - 8usize];
2325};
2326#[doc = " Auto-escalation policy for [`SolveForParams::Auto`]\n (mirrors [`scott::od::AutoEscalationPolicy`]). Sentinel: `0` /\n `0.0` → upstream default."]
2327#[repr(C)]
2328#[derive(Debug, Default, Copy, Clone)]
2329pub struct EmpyreanAutoEscalationPolicy {
2330 pub reduced_chi2: f64,
2331 pub at_ct_ratio: f64,
2332 pub min_arc_days: f64,
2333 pub min_n_obs: u32,
2334}
2335#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2336const _: () = {
2337 ["Size of EmpyreanAutoEscalationPolicy"]
2338 [::std::mem::size_of::<EmpyreanAutoEscalationPolicy>() - 32usize];
2339 ["Alignment of EmpyreanAutoEscalationPolicy"]
2340 [::std::mem::align_of::<EmpyreanAutoEscalationPolicy>() - 8usize];
2341 ["Offset of field: EmpyreanAutoEscalationPolicy::reduced_chi2"]
2342 [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, reduced_chi2) - 0usize];
2343 ["Offset of field: EmpyreanAutoEscalationPolicy::at_ct_ratio"]
2344 [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, at_ct_ratio) - 8usize];
2345 ["Offset of field: EmpyreanAutoEscalationPolicy::min_arc_days"]
2346 [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, min_arc_days) - 16usize];
2347 ["Offset of field: EmpyreanAutoEscalationPolicy::min_n_obs"]
2348 [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, min_n_obs) - 24usize];
2349};
2350#[doc = " Acceptability thresholds for the post-DC fit-quality checks\n (mirrors [`scott::od::AcceptabilityThresholds`]). Sentinel: `0.0` →\n upstream default."]
2351#[repr(C)]
2352#[derive(Debug, Default, Copy, Clone)]
2353pub struct EmpyreanAcceptabilityThresholds {
2354 pub reduced_chi2: f64,
2355 pub rms_arcsec: f64,
2356 pub at_ct_ratio: f64,
2357 pub min_arc_days: f64,
2358 pub fractional_sigma_a: f64,
2359}
2360#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2361const _: () = {
2362 ["Size of EmpyreanAcceptabilityThresholds"]
2363 [::std::mem::size_of::<EmpyreanAcceptabilityThresholds>() - 40usize];
2364 ["Alignment of EmpyreanAcceptabilityThresholds"]
2365 [::std::mem::align_of::<EmpyreanAcceptabilityThresholds>() - 8usize];
2366 ["Offset of field: EmpyreanAcceptabilityThresholds::reduced_chi2"]
2367 [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, reduced_chi2) - 0usize];
2368 ["Offset of field: EmpyreanAcceptabilityThresholds::rms_arcsec"]
2369 [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, rms_arcsec) - 8usize];
2370 ["Offset of field: EmpyreanAcceptabilityThresholds::at_ct_ratio"]
2371 [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, at_ct_ratio) - 16usize];
2372 ["Offset of field: EmpyreanAcceptabilityThresholds::min_arc_days"]
2373 [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, min_arc_days) - 24usize];
2374 ["Offset of field: EmpyreanAcceptabilityThresholds::fractional_sigma_a"]
2375 [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, fractional_sigma_a) - 32usize];
2376};
2377#[doc = " Per-station RA/Dec bias-fit configuration (mirrors\n [`scott::nuisance::BiasKind::StationRaDec`]).\n\n Activated by [`EmpyreanODConfig::fit_station_biases`]. Per-station\n sigma overrides and `BiasScope` filtering aren't carried across the\n C ABI yet — every active station uses `sigma_prior_arcsec` and the\n scope is always [`BiasScope::AllStations`]. Reach for the\n empyrean-core Rust API when you need finer control."]
2378#[repr(C)]
2379#[derive(Debug, Default, Copy, Clone)]
2380pub struct EmpyreanStationRaDecConfig {
2381 #[doc = " Default 1-sigma prior on the RA / Dec offset (arcsec). Default = 0.3."]
2382 pub sigma_prior_arcsec: f64,
2383 #[doc = " Minimum observations per station for a bias parameter to be\n allocated. Stations below this threshold contribute observations\n at face value. 0 → upstream default (5)."]
2384 pub min_obs_per_station: usize,
2385}
2386#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2387const _: () = {
2388 ["Size of EmpyreanStationRaDecConfig"]
2389 [::std::mem::size_of::<EmpyreanStationRaDecConfig>() - 16usize];
2390 ["Alignment of EmpyreanStationRaDecConfig"]
2391 [::std::mem::align_of::<EmpyreanStationRaDecConfig>() - 8usize];
2392 ["Offset of field: EmpyreanStationRaDecConfig::sigma_prior_arcsec"]
2393 [::std::mem::offset_of!(EmpyreanStationRaDecConfig, sigma_prior_arcsec) - 0usize];
2394 ["Offset of field: EmpyreanStationRaDecConfig::min_obs_per_station"]
2395 [::std::mem::offset_of!(EmpyreanStationRaDecConfig, min_obs_per_station) - 8usize];
2396};
2397#[doc = " Outlier rejection configuration. Selects between two strategies via\n the [`kind`](Self::kind) discriminator:\n\n - `kind = EMPYREAN_REJECTION_KIND_ADAPTIVE` (default): mirrors\n [`scott::rejection::AdaptiveRejectionConfig`]. Reads\n `chi2_base` / `lambda` / `max_threshold`. Sentinels:\n `chi2_base = 0.0` → 9.21, `lambda < 0` → 1.0,\n `max_threshold = 0.0` → 100.0.\n - `kind = EMPYREAN_REJECTION_KIND_CMC2003`: mirrors\n [`scott::rejection::CMC2003Config`]. Reads `chi2_rej` / `chi2_rec`\n (the upper / lower hysteresis thresholds). Sentinels:\n `chi2_rej = 0.0` → 8.0, `chi2_rec = 0.0` → 7.0.\n\n `enabled = 0` runs OD without any rejection pass — the strategy\n fields are ignored. `enabled = 1` activates rejection."]
2398#[repr(C)]
2399#[derive(Debug, Default, Copy, Clone)]
2400pub struct EmpyreanRejectionConfig {
2401 #[doc = " 1 = run rejection (default), 0 = skip."]
2402 pub enabled: u8,
2403 #[doc = " Strategy selector — one of the `EMPYREAN_REJECTION_KIND_*`\n constants. Default `0` (Adaptive) keeps existing C callers\n working without code changes."]
2404 pub kind: u8,
2405 pub chi2_base: f64,
2406 #[doc = " `-1.0` selects the upstream default (1.0); negative values are\n otherwise valid and disable adaptation when 0.0."]
2407 pub lambda: f64,
2408 pub max_threshold: f64,
2409 #[doc = " CMC2003 upper threshold (reject when χ² > chi2_rej). 0.0 →\n upstream default (8.0). Ignored unless `kind ==\n EMPYREAN_REJECTION_KIND_CMC2003`."]
2410 pub chi2_rej: f64,
2411 #[doc = " CMC2003 lower threshold (recover when χ² < chi2_rec). 0.0 →\n upstream default (7.0). Must be strictly less than `chi2_rej`\n for hysteresis to break cycles. Ignored unless `kind ==\n EMPYREAN_REJECTION_KIND_CMC2003`."]
2412 pub chi2_rec: f64,
2413 #[doc = " Maximum rejection-refit passes. 0 → upstream default (3)."]
2414 pub max_passes: u32,
2415}
2416#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2417const _: () = {
2418 ["Size of EmpyreanRejectionConfig"][::std::mem::size_of::<EmpyreanRejectionConfig>() - 56usize];
2419 ["Alignment of EmpyreanRejectionConfig"]
2420 [::std::mem::align_of::<EmpyreanRejectionConfig>() - 8usize];
2421 ["Offset of field: EmpyreanRejectionConfig::enabled"]
2422 [::std::mem::offset_of!(EmpyreanRejectionConfig, enabled) - 0usize];
2423 ["Offset of field: EmpyreanRejectionConfig::kind"]
2424 [::std::mem::offset_of!(EmpyreanRejectionConfig, kind) - 1usize];
2425 ["Offset of field: EmpyreanRejectionConfig::chi2_base"]
2426 [::std::mem::offset_of!(EmpyreanRejectionConfig, chi2_base) - 8usize];
2427 ["Offset of field: EmpyreanRejectionConfig::lambda"]
2428 [::std::mem::offset_of!(EmpyreanRejectionConfig, lambda) - 16usize];
2429 ["Offset of field: EmpyreanRejectionConfig::max_threshold"]
2430 [::std::mem::offset_of!(EmpyreanRejectionConfig, max_threshold) - 24usize];
2431 ["Offset of field: EmpyreanRejectionConfig::chi2_rej"]
2432 [::std::mem::offset_of!(EmpyreanRejectionConfig, chi2_rej) - 32usize];
2433 ["Offset of field: EmpyreanRejectionConfig::chi2_rec"]
2434 [::std::mem::offset_of!(EmpyreanRejectionConfig, chi2_rec) - 40usize];
2435 ["Offset of field: EmpyreanRejectionConfig::max_passes"]
2436 [::std::mem::offset_of!(EmpyreanRejectionConfig, max_passes) - 48usize];
2437};
2438#[doc = " Result of orbit determination (determine or refine).\n\n Per-axis solve-for flags (mirrors scott's `SolveFor`). Read only when\n [`EmpyreanODConfig::solve_for`] is [`EMPYREAN_SOLVE_FOR_EXPLICIT`]; the\n three coarse `EMPYREAN_SOLVE_FOR_*` codes cover the common shapes\n without it. Each flag turns on a wide-STM axis, subject to its own\n precondition (a declared prior on the orbit) enforced by scott."]
2439#[repr(C)]
2440#[derive(Debug, Default, Copy, Clone)]
2441pub struct EmpyreanSolveFor {
2442 #[doc = " Solve the Marsden A1/A2/A3 block (requires a non-grav covariance)."]
2443 pub marsden: u8,
2444 #[doc = " Solve the non-grav time delay DT (requires `marsden` + a DT prior)."]
2445 pub dt: u8,
2446 #[doc = " Solve the SRP AMRAT (requires an SRP AMRAT prior)."]
2447 pub amrat: u8,
2448 #[doc = " Number of thrust Δv segments to solve (3 columns each; 0 = none)."]
2449 pub thrust_segments: u32,
2450}
2451#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2452const _: () = {
2453 ["Size of EmpyreanSolveFor"][::std::mem::size_of::<EmpyreanSolveFor>() - 8usize];
2454 ["Alignment of EmpyreanSolveFor"][::std::mem::align_of::<EmpyreanSolveFor>() - 4usize];
2455 ["Offset of field: EmpyreanSolveFor::marsden"]
2456 [::std::mem::offset_of!(EmpyreanSolveFor, marsden) - 0usize];
2457 ["Offset of field: EmpyreanSolveFor::dt"]
2458 [::std::mem::offset_of!(EmpyreanSolveFor, dt) - 1usize];
2459 ["Offset of field: EmpyreanSolveFor::amrat"]
2460 [::std::mem::offset_of!(EmpyreanSolveFor, amrat) - 2usize];
2461 ["Offset of field: EmpyreanSolveFor::thrust_segments"]
2462 [::std::mem::offset_of!(EmpyreanSolveFor, thrust_segments) - 4usize];
2463};
2464#[doc = " Post-OD photometric-fit request (mirrors scott's `PhotometryConfig`).\n Enabled by [`EmpyreanODConfig::has_photometry`]; the fit runs after the\n orbit is solved and never touches the state (photometry has no\n astrometric partials). Zero-init reproduces scott's defaults."]
2465#[repr(C)]
2466#[derive(Debug, Default, Copy, Clone)]
2467pub struct EmpyreanPhotometryConfig {
2468 #[doc = " Model to fit (`EMPYREAN_PHOTOMETRY_MODEL_*`). Default = Auto (0)."]
2469 pub model: i32,
2470 #[doc = " 1σ lightcurve scatter floor (mag). 0.0 → upstream default (0.2)."]
2471 pub sigma_lightcurve: f64,
2472 #[doc = " Include astrometrically-rejected observations' magnitudes. 0 = off."]
2473 pub include_rejected: u8,
2474 #[doc = " Max Huber-IRLS iterations. 0 → upstream default (30)."]
2475 pub max_irls_iterations: u32,
2476 #[doc = " Huber tuning constant. 0.0 → upstream default (1.5)."]
2477 pub huber_k: f64,
2478}
2479#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2480const _: () = {
2481 ["Size of EmpyreanPhotometryConfig"]
2482 [::std::mem::size_of::<EmpyreanPhotometryConfig>() - 32usize];
2483 ["Alignment of EmpyreanPhotometryConfig"]
2484 [::std::mem::align_of::<EmpyreanPhotometryConfig>() - 8usize];
2485 ["Offset of field: EmpyreanPhotometryConfig::model"]
2486 [::std::mem::offset_of!(EmpyreanPhotometryConfig, model) - 0usize];
2487 ["Offset of field: EmpyreanPhotometryConfig::sigma_lightcurve"]
2488 [::std::mem::offset_of!(EmpyreanPhotometryConfig, sigma_lightcurve) - 8usize];
2489 ["Offset of field: EmpyreanPhotometryConfig::include_rejected"]
2490 [::std::mem::offset_of!(EmpyreanPhotometryConfig, include_rejected) - 16usize];
2491 ["Offset of field: EmpyreanPhotometryConfig::max_irls_iterations"]
2492 [::std::mem::offset_of!(EmpyreanPhotometryConfig, max_irls_iterations) - 20usize];
2493 ["Offset of field: EmpyreanPhotometryConfig::huber_k"]
2494 [::std::mem::offset_of!(EmpyreanPhotometryConfig, huber_k) - 24usize];
2495};
2496#[doc = " Orbit-determination configuration.\n\n Drives `empyrean_determine`, `empyrean_evaluate`, and `empyrean_refine`.\n Mirrors [`scott::od::ODConfig`](scott::od::ODConfig) **structurally** —\n where scott has a nested config (e.g. `auto_escalation`,\n `acceptability`), this surface keeps the same nesting via\n [`EmpyreanAutoEscalationPolicy`], [`EmpyreanAcceptabilityThresholds`],\n etc., so the C-side caller's mental model matches the upstream Rust\n type. Sentinel rule for primitive fields: `0` / `0.0` requests the\n upstream default; only the few fields documented inline (e.g.\n `opposition_gap_days < 0`, `lambda < 0`) carry their own special\n values.\n\n IOD strategy configs (Gauss / Herget / SystematicRanging /\n Refinement) are not exposed here — those are tens of internal\n tuning fields that don't translate cleanly. They always run with\n their upstream defaults; reach for the empyrean-core Rust API when\n you need to override them."]
2497#[repr(C)]
2498#[derive(Debug, Copy, Clone)]
2499pub struct EmpyreanODConfig {
2500 #[doc = " Force-model tier: 0=Approximate, 1=Basic, 2=Standard."]
2501 pub force_model: i32,
2502 #[doc = " Integrator truncation-error tolerance (interpreted by the\n active integrator backend — for the default GR15 this is the\n relative b₆ truncation tolerance). 0.0 → upstream default\n (1e-9)."]
2503 pub epsilon: f64,
2504 #[doc = " Maximum light-time iterations. 0 → upstream default (3)."]
2505 pub max_light_time_iterations: usize,
2506 #[doc = " Threads for batch operations. 0 → all available cores."]
2507 pub num_threads: usize,
2508 #[doc = " Output reference frame: 0=ICRF, 1=EclipticJ2000."]
2509 pub frame: i32,
2510 #[doc = " Observation weighting pipeline configuration. Zero-init = the\n production default (VFC17 + nightly de-weighting at floor-σ\n policy). See [`EmpyreanWeightingConfig`]."]
2511 pub weighting: EmpyreanWeightingConfig,
2512 #[doc = " Catalog-bias-correction configuration. Zero-init = the\n production default (EFCC2020 standard resolution, loaded from\n the DataManager default path). See [`EmpyreanDebiasingConfig`]."]
2513 pub debiasing: EmpyreanDebiasingConfig,
2514 #[doc = " Number of `excluded_perturbers` in [`excluded_perturbers_naif`]; 0 = none."]
2515 pub num_excluded_perturbers: usize,
2516 #[doc = " Pointer to `num_excluded_perturbers` NAIF body IDs to exclude\n from the perturber set (for self-determination of SB441-N16\n bodies). Non-owning — caller must keep the array alive for the\n duration of the OD call."]
2517 pub excluded_perturbers_naif: *const i32,
2518 #[doc = " Origin-policy selector. Zero-init = `Auto` (heliocentric → geo-\n centric Earth cascade). See [`EmpyreanOriginPolicy`]."]
2519 pub origin: EmpyreanOriginPolicy,
2520 pub iod: EmpyreanIODConfig,
2521 pub output_epoch: EmpyreanOutputEpoch,
2522 #[doc = " Maximum DC iterations. 0 → upstream default (100)."]
2523 pub max_iterations: u32,
2524 #[doc = " DC convergence tolerance on Δx^T N Δx. 0.0 → upstream default (0.1)."]
2525 pub convergence_tol: f64,
2526 #[doc = " Use STM-cached ephemeris updates for iterations 2+. 1 = on (default)."]
2527 pub use_stm_cache: u8,
2528 #[doc = " Solve-for parameter set (`EMPYREAN_SOLVE_FOR_*`). Default = Auto."]
2529 pub solve_for: i32,
2530 pub auto_escalation: EmpyreanAutoEscalationPolicy,
2531 pub acceptability: EmpyreanAcceptabilityThresholds,
2532 #[doc = " Schur-eliminate per-station RA/Dec biases. 1 = enable, 0 = off (default)."]
2533 pub fit_station_biases: u8,
2534 #[doc = " Per-station RA/Dec bias config. Honored only when\n [`fit_station_biases`] is non-zero."]
2535 pub station_radec: EmpyreanStationRaDecConfig,
2536 #[doc = " Use span-grouped Jacobian reuse on cache iterations. 0 = off (default)."]
2537 pub use_span_grouping: u8,
2538 pub rejection: EmpyreanRejectionConfig,
2539 #[doc = " Auto-select force-model tier from IOD elements. 0 = off (default)."]
2540 pub auto_force_model: u8,
2541 #[doc = " Output coordinate representation for the fitted orbit + covariance\n (`EMPYREAN_REPRESENTATION_*`). Default = Cartesian."]
2542 pub output_representation: i32,
2543 #[doc = " Per-axis solve-for flags, read ONLY when\n [`solve_for`](EmpyreanODConfig::solve_for) is\n [`EMPYREAN_SOLVE_FOR_EXPLICIT`]. The three coarse `solve_for` codes\n ignore this field."]
2544 pub solve_for_flags: EmpyreanSolveFor,
2545 #[doc = " Permit solving a thrust Δv segment whose burn window is not\n bracketed by observations (degenerate with the state; the Gates\n prior then carries it). 0 = refuse loudly (default)."]
2546 pub allow_unbracketed_maneuvers: u8,
2547 #[doc = " 1 to run the post-OD photometric fit; 0 = off (default). When 0,\n [`photometry`](EmpyreanODConfig::photometry) is ignored."]
2548 pub has_photometry: u8,
2549 #[doc = " Post-OD photometric-fit configuration. Honored only when\n [`has_photometry`](EmpyreanODConfig::has_photometry) is non-zero."]
2550 pub photometry: EmpyreanPhotometryConfig,
2551}
2552#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2553const _: () = {
2554 ["Size of EmpyreanODConfig"][::std::mem::size_of::<EmpyreanODConfig>() - 432usize];
2555 ["Alignment of EmpyreanODConfig"][::std::mem::align_of::<EmpyreanODConfig>() - 8usize];
2556 ["Offset of field: EmpyreanODConfig::force_model"]
2557 [::std::mem::offset_of!(EmpyreanODConfig, force_model) - 0usize];
2558 ["Offset of field: EmpyreanODConfig::epsilon"]
2559 [::std::mem::offset_of!(EmpyreanODConfig, epsilon) - 8usize];
2560 ["Offset of field: EmpyreanODConfig::max_light_time_iterations"]
2561 [::std::mem::offset_of!(EmpyreanODConfig, max_light_time_iterations) - 16usize];
2562 ["Offset of field: EmpyreanODConfig::num_threads"]
2563 [::std::mem::offset_of!(EmpyreanODConfig, num_threads) - 24usize];
2564 ["Offset of field: EmpyreanODConfig::frame"]
2565 [::std::mem::offset_of!(EmpyreanODConfig, frame) - 32usize];
2566 ["Offset of field: EmpyreanODConfig::weighting"]
2567 [::std::mem::offset_of!(EmpyreanODConfig, weighting) - 40usize];
2568 ["Offset of field: EmpyreanODConfig::debiasing"]
2569 [::std::mem::offset_of!(EmpyreanODConfig, debiasing) - 80usize];
2570 ["Offset of field: EmpyreanODConfig::num_excluded_perturbers"]
2571 [::std::mem::offset_of!(EmpyreanODConfig, num_excluded_perturbers) - 104usize];
2572 ["Offset of field: EmpyreanODConfig::excluded_perturbers_naif"]
2573 [::std::mem::offset_of!(EmpyreanODConfig, excluded_perturbers_naif) - 112usize];
2574 ["Offset of field: EmpyreanODConfig::origin"]
2575 [::std::mem::offset_of!(EmpyreanODConfig, origin) - 120usize];
2576 ["Offset of field: EmpyreanODConfig::iod"]
2577 [::std::mem::offset_of!(EmpyreanODConfig, iod) - 128usize];
2578 ["Offset of field: EmpyreanODConfig::output_epoch"]
2579 [::std::mem::offset_of!(EmpyreanODConfig, output_epoch) - 176usize];
2580 ["Offset of field: EmpyreanODConfig::max_iterations"]
2581 [::std::mem::offset_of!(EmpyreanODConfig, max_iterations) - 192usize];
2582 ["Offset of field: EmpyreanODConfig::convergence_tol"]
2583 [::std::mem::offset_of!(EmpyreanODConfig, convergence_tol) - 200usize];
2584 ["Offset of field: EmpyreanODConfig::use_stm_cache"]
2585 [::std::mem::offset_of!(EmpyreanODConfig, use_stm_cache) - 208usize];
2586 ["Offset of field: EmpyreanODConfig::solve_for"]
2587 [::std::mem::offset_of!(EmpyreanODConfig, solve_for) - 212usize];
2588 ["Offset of field: EmpyreanODConfig::auto_escalation"]
2589 [::std::mem::offset_of!(EmpyreanODConfig, auto_escalation) - 216usize];
2590 ["Offset of field: EmpyreanODConfig::acceptability"]
2591 [::std::mem::offset_of!(EmpyreanODConfig, acceptability) - 248usize];
2592 ["Offset of field: EmpyreanODConfig::fit_station_biases"]
2593 [::std::mem::offset_of!(EmpyreanODConfig, fit_station_biases) - 288usize];
2594 ["Offset of field: EmpyreanODConfig::station_radec"]
2595 [::std::mem::offset_of!(EmpyreanODConfig, station_radec) - 296usize];
2596 ["Offset of field: EmpyreanODConfig::use_span_grouping"]
2597 [::std::mem::offset_of!(EmpyreanODConfig, use_span_grouping) - 312usize];
2598 ["Offset of field: EmpyreanODConfig::rejection"]
2599 [::std::mem::offset_of!(EmpyreanODConfig, rejection) - 320usize];
2600 ["Offset of field: EmpyreanODConfig::auto_force_model"]
2601 [::std::mem::offset_of!(EmpyreanODConfig, auto_force_model) - 376usize];
2602 ["Offset of field: EmpyreanODConfig::output_representation"]
2603 [::std::mem::offset_of!(EmpyreanODConfig, output_representation) - 380usize];
2604 ["Offset of field: EmpyreanODConfig::solve_for_flags"]
2605 [::std::mem::offset_of!(EmpyreanODConfig, solve_for_flags) - 384usize];
2606 ["Offset of field: EmpyreanODConfig::allow_unbracketed_maneuvers"]
2607 [::std::mem::offset_of!(EmpyreanODConfig, allow_unbracketed_maneuvers) - 392usize];
2608 ["Offset of field: EmpyreanODConfig::has_photometry"]
2609 [::std::mem::offset_of!(EmpyreanODConfig, has_photometry) - 393usize];
2610 ["Offset of field: EmpyreanODConfig::photometry"]
2611 [::std::mem::offset_of!(EmpyreanODConfig, photometry) - 400usize];
2612};
2613impl Default for EmpyreanODConfig {
2614 fn default() -> Self {
2615 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2616 unsafe {
2617 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2618 s.assume_init()
2619 }
2620 }
2621}
2622#[doc = " Aggregate residual statistics.\n\n All angular quantities in arcseconds. NaN entries indicate the stat\n could not be computed (e.g. AT/CT RMS when no sky-motion rates were\n available, or weighted RMS when no weighting layer was active)."]
2623#[repr(C)]
2624#[derive(Debug, Default, Copy, Clone)]
2625pub struct EmpyreanResidualSummary {
2626 pub num_obs: usize,
2627 pub num_selected: usize,
2628 pub num_rejected: usize,
2629 #[doc = " Total χ² over selected observations."]
2630 pub chi2: f64,
2631 #[doc = " Effective degrees of freedom (after subtracting solve-for params)."]
2632 pub dof: usize,
2633 #[doc = " Reduced χ² = chi2 / dof. NaN when dof ≤ 0."]
2634 pub reduced_chi2: f64,
2635 pub rms_ra_arcsec: f64,
2636 pub rms_dec_arcsec: f64,
2637 #[doc = " Combined RA·cosδ + Dec residual RMS (arcsec). Matches the\n find_orb / OrbFit `rms` reporting convention — a single\n number directly comparable across tools."]
2638 pub rms_combined_arcsec: f64,
2639 #[doc = " RMS weighted by the per-observation σ (matches scott's `weighted_rms`)."]
2640 pub weighted_rms_ra_arcsec: f64,
2641 pub weighted_rms_dec_arcsec: f64,
2642 #[doc = " Combined weighted RA·cosδ + Dec residual RMS (arcsec)."]
2643 pub weighted_rms_combined_arcsec: f64,
2644 pub mean_ra_arcsec: f64,
2645 pub mean_dec_arcsec: f64,
2646 pub std_ra_arcsec: f64,
2647 pub std_dec_arcsec: f64,
2648 #[doc = " RMS along-track residual (arcsec). NaN if no AT/CT data."]
2649 pub rms_along_track_arcsec: f64,
2650 #[doc = " RMS cross-track residual (arcsec). NaN if no AT/CT data."]
2651 pub rms_cross_track_arcsec: f64,
2652}
2653#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2654const _: () = {
2655 ["Size of EmpyreanResidualSummary"]
2656 [::std::mem::size_of::<EmpyreanResidualSummary>() - 144usize];
2657 ["Alignment of EmpyreanResidualSummary"]
2658 [::std::mem::align_of::<EmpyreanResidualSummary>() - 8usize];
2659 ["Offset of field: EmpyreanResidualSummary::num_obs"]
2660 [::std::mem::offset_of!(EmpyreanResidualSummary, num_obs) - 0usize];
2661 ["Offset of field: EmpyreanResidualSummary::num_selected"]
2662 [::std::mem::offset_of!(EmpyreanResidualSummary, num_selected) - 8usize];
2663 ["Offset of field: EmpyreanResidualSummary::num_rejected"]
2664 [::std::mem::offset_of!(EmpyreanResidualSummary, num_rejected) - 16usize];
2665 ["Offset of field: EmpyreanResidualSummary::chi2"]
2666 [::std::mem::offset_of!(EmpyreanResidualSummary, chi2) - 24usize];
2667 ["Offset of field: EmpyreanResidualSummary::dof"]
2668 [::std::mem::offset_of!(EmpyreanResidualSummary, dof) - 32usize];
2669 ["Offset of field: EmpyreanResidualSummary::reduced_chi2"]
2670 [::std::mem::offset_of!(EmpyreanResidualSummary, reduced_chi2) - 40usize];
2671 ["Offset of field: EmpyreanResidualSummary::rms_ra_arcsec"]
2672 [::std::mem::offset_of!(EmpyreanResidualSummary, rms_ra_arcsec) - 48usize];
2673 ["Offset of field: EmpyreanResidualSummary::rms_dec_arcsec"]
2674 [::std::mem::offset_of!(EmpyreanResidualSummary, rms_dec_arcsec) - 56usize];
2675 ["Offset of field: EmpyreanResidualSummary::rms_combined_arcsec"]
2676 [::std::mem::offset_of!(EmpyreanResidualSummary, rms_combined_arcsec) - 64usize];
2677 ["Offset of field: EmpyreanResidualSummary::weighted_rms_ra_arcsec"]
2678 [::std::mem::offset_of!(EmpyreanResidualSummary, weighted_rms_ra_arcsec) - 72usize];
2679 ["Offset of field: EmpyreanResidualSummary::weighted_rms_dec_arcsec"]
2680 [::std::mem::offset_of!(EmpyreanResidualSummary, weighted_rms_dec_arcsec) - 80usize];
2681 ["Offset of field: EmpyreanResidualSummary::weighted_rms_combined_arcsec"]
2682 [::std::mem::offset_of!(EmpyreanResidualSummary, weighted_rms_combined_arcsec) - 88usize];
2683 ["Offset of field: EmpyreanResidualSummary::mean_ra_arcsec"]
2684 [::std::mem::offset_of!(EmpyreanResidualSummary, mean_ra_arcsec) - 96usize];
2685 ["Offset of field: EmpyreanResidualSummary::mean_dec_arcsec"]
2686 [::std::mem::offset_of!(EmpyreanResidualSummary, mean_dec_arcsec) - 104usize];
2687 ["Offset of field: EmpyreanResidualSummary::std_ra_arcsec"]
2688 [::std::mem::offset_of!(EmpyreanResidualSummary, std_ra_arcsec) - 112usize];
2689 ["Offset of field: EmpyreanResidualSummary::std_dec_arcsec"]
2690 [::std::mem::offset_of!(EmpyreanResidualSummary, std_dec_arcsec) - 120usize];
2691 ["Offset of field: EmpyreanResidualSummary::rms_along_track_arcsec"]
2692 [::std::mem::offset_of!(EmpyreanResidualSummary, rms_along_track_arcsec) - 128usize];
2693 ["Offset of field: EmpyreanResidualSummary::rms_cross_track_arcsec"]
2694 [::std::mem::offset_of!(EmpyreanResidualSummary, rms_cross_track_arcsec) - 136usize];
2695};
2696#[doc = " The fitted orbit's absolute solar-radiation-pressure slot, flattened\n for the C ABI. Mirrors the SRP fields the input `EmpyreanOrbit` carries\n so a fitted orbit's SRP force re-feeds off [`EmpyreanODResult::srp`] with\n no loss."]
2697#[repr(C)]
2698#[derive(Debug, Default, Copy, Clone)]
2699pub struct EmpyreanSRPParams {
2700 #[doc = " Absolute area-to-mass ratio AMRAT (m²/kg) — the input prior plus any\n fitted correction."]
2701 pub amrat: f64,
2702 #[doc = " Radiation-pressure coefficient Cr, carried through unchanged."]
2703 pub cr: f64,
2704 #[doc = " 1 when `amrat_variance` carries a meaningful AMRAT variance; 0 otherwise."]
2705 pub has_amrat_variance: u8,
2706 #[doc = " AMRAT variance ((m²/kg)²). Only meaningful when `has_amrat_variance = 1`."]
2707 pub amrat_variance: f64,
2708}
2709#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2710const _: () = {
2711 ["Size of EmpyreanSRPParams"][::std::mem::size_of::<EmpyreanSRPParams>() - 32usize];
2712 ["Alignment of EmpyreanSRPParams"][::std::mem::align_of::<EmpyreanSRPParams>() - 8usize];
2713 ["Offset of field: EmpyreanSRPParams::amrat"]
2714 [::std::mem::offset_of!(EmpyreanSRPParams, amrat) - 0usize];
2715 ["Offset of field: EmpyreanSRPParams::cr"][::std::mem::offset_of!(EmpyreanSRPParams, cr) - 8usize];
2716 ["Offset of field: EmpyreanSRPParams::has_amrat_variance"]
2717 [::std::mem::offset_of!(EmpyreanSRPParams, has_amrat_variance) - 16usize];
2718 ["Offset of field: EmpyreanSRPParams::amrat_variance"]
2719 [::std::mem::offset_of!(EmpyreanSRPParams, amrat_variance) - 24usize];
2720};
2721#[doc = " A complete non-gravitational acceleration model, flattened for the C ABI.\n\n Mirrors the fields the input [`EmpyreanOrbit`] carries, so a fitted orbit's\n non-grav can be read back off [`EmpyreanODResult::non_grav`] and re-applied\n to an `EmpyreanOrbit` with no loss: the radial/transverse/normal\n coefficients (A1/A2/A3, AU/day²), the Marsden–Sekanina g(r) exponents\n (`ng_alpha`..`ng_k`; all-zero = inverse-square default), and the optional\n thermal-lag delay `non_grav_dt` (days, valid only when `has_dt = 1`)."]
2722#[repr(C)]
2723#[derive(Debug, Default, Copy, Clone)]
2724pub struct EmpyreanNonGravParams {
2725 pub a1: f64,
2726 pub a2: f64,
2727 pub a3: f64,
2728 pub ng_alpha: f64,
2729 pub ng_r0: f64,
2730 pub ng_m: f64,
2731 pub ng_n: f64,
2732 pub ng_k: f64,
2733 #[doc = " 1 when `non_grav_dt` carries a thermal-lag delay; 0 otherwise."]
2734 pub has_dt: u8,
2735 #[doc = " g(r) evaluation time delay (days); only meaningful when `has_dt = 1`."]
2736 pub non_grav_dt: f64,
2737 #[doc = " 1 when `covariance` carries the fitted non-grav covariance; 0 otherwise."]
2738 pub has_covariance: u8,
2739 #[doc = " Fitted non-grav 3×3 covariance for (A1, A2, A3), row-major. Only\n meaningful when `has_covariance = 1`. Re-feeding it onto an input\n orbit lets a fitted orbit flow into a StateAndNonGrav refine without\n losing its non-grav prior."]
2740 pub covariance: [[f64; 3usize]; 3usize],
2741}
2742#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2743const _: () = {
2744 ["Size of EmpyreanNonGravParams"][::std::mem::size_of::<EmpyreanNonGravParams>() - 160usize];
2745 ["Alignment of EmpyreanNonGravParams"]
2746 [::std::mem::align_of::<EmpyreanNonGravParams>() - 8usize];
2747 ["Offset of field: EmpyreanNonGravParams::a1"]
2748 [::std::mem::offset_of!(EmpyreanNonGravParams, a1) - 0usize];
2749 ["Offset of field: EmpyreanNonGravParams::a2"]
2750 [::std::mem::offset_of!(EmpyreanNonGravParams, a2) - 8usize];
2751 ["Offset of field: EmpyreanNonGravParams::a3"]
2752 [::std::mem::offset_of!(EmpyreanNonGravParams, a3) - 16usize];
2753 ["Offset of field: EmpyreanNonGravParams::ng_alpha"]
2754 [::std::mem::offset_of!(EmpyreanNonGravParams, ng_alpha) - 24usize];
2755 ["Offset of field: EmpyreanNonGravParams::ng_r0"]
2756 [::std::mem::offset_of!(EmpyreanNonGravParams, ng_r0) - 32usize];
2757 ["Offset of field: EmpyreanNonGravParams::ng_m"]
2758 [::std::mem::offset_of!(EmpyreanNonGravParams, ng_m) - 40usize];
2759 ["Offset of field: EmpyreanNonGravParams::ng_n"]
2760 [::std::mem::offset_of!(EmpyreanNonGravParams, ng_n) - 48usize];
2761 ["Offset of field: EmpyreanNonGravParams::ng_k"]
2762 [::std::mem::offset_of!(EmpyreanNonGravParams, ng_k) - 56usize];
2763 ["Offset of field: EmpyreanNonGravParams::has_dt"]
2764 [::std::mem::offset_of!(EmpyreanNonGravParams, has_dt) - 64usize];
2765 ["Offset of field: EmpyreanNonGravParams::non_grav_dt"]
2766 [::std::mem::offset_of!(EmpyreanNonGravParams, non_grav_dt) - 72usize];
2767 ["Offset of field: EmpyreanNonGravParams::has_covariance"]
2768 [::std::mem::offset_of!(EmpyreanNonGravParams, has_covariance) - 80usize];
2769 ["Offset of field: EmpyreanNonGravParams::covariance"]
2770 [::std::mem::offset_of!(EmpyreanNonGravParams, covariance) - 88usize];
2771};
2772#[doc = " Acceptability sub-checks computed post-DC.\n\n Mirrors scott's [`AcceptabilityReport`](scott::od::AcceptabilityReport).\n Boolean fields are encoded as `u8` (0/1). When a value is unavailable\n (e.g. AT/CT ratio with no sky-motion rates), the `_value` is NaN and\n the corresponding `_ok` flag is 0. Always populated on\n [`EmpyreanODResult`]; on [`EmpyreanEvaluateResult`] the report is\n filled with NaN/0 because evaluate does not produce a fitted orbit."]
2773#[repr(C)]
2774#[derive(Debug, Default, Copy, Clone)]
2775pub struct EmpyreanAcceptabilityReport {
2776 pub fit_acceptable: u8,
2777 pub extrapolation_acceptable: u8,
2778 pub converged_ok: u8,
2779 pub reduced_chi2_ok: u8,
2780 pub reduced_chi2_value: f64,
2781 pub reduced_chi2_threshold: f64,
2782 pub rms_ok: u8,
2783 pub rms_value_arcsec: f64,
2784 pub rms_threshold_arcsec: f64,
2785 pub residual_isotropy_ok: u8,
2786 pub at_ct_ratio_value: f64,
2787 pub at_ct_ratio_threshold: f64,
2788 pub covariance_ok: u8,
2789 pub arc_coverage_ok: u8,
2790 pub arc_days_value: f64,
2791 pub arc_days_threshold: f64,
2792 pub fractional_sigma_a_ok: u8,
2793 pub fractional_sigma_a_value: f64,
2794 pub fractional_sigma_a_threshold: f64,
2795}
2796#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2797const _: () = {
2798 ["Size of EmpyreanAcceptabilityReport"]
2799 [::std::mem::size_of::<EmpyreanAcceptabilityReport>() - 120usize];
2800 ["Alignment of EmpyreanAcceptabilityReport"]
2801 [::std::mem::align_of::<EmpyreanAcceptabilityReport>() - 8usize];
2802 ["Offset of field: EmpyreanAcceptabilityReport::fit_acceptable"]
2803 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, fit_acceptable) - 0usize];
2804 ["Offset of field: EmpyreanAcceptabilityReport::extrapolation_acceptable"]
2805 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, extrapolation_acceptable) - 1usize];
2806 ["Offset of field: EmpyreanAcceptabilityReport::converged_ok"]
2807 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, converged_ok) - 2usize];
2808 ["Offset of field: EmpyreanAcceptabilityReport::reduced_chi2_ok"]
2809 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, reduced_chi2_ok) - 3usize];
2810 ["Offset of field: EmpyreanAcceptabilityReport::reduced_chi2_value"]
2811 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, reduced_chi2_value) - 8usize];
2812 ["Offset of field: EmpyreanAcceptabilityReport::reduced_chi2_threshold"]
2813 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, reduced_chi2_threshold) - 16usize];
2814 ["Offset of field: EmpyreanAcceptabilityReport::rms_ok"]
2815 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, rms_ok) - 24usize];
2816 ["Offset of field: EmpyreanAcceptabilityReport::rms_value_arcsec"]
2817 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, rms_value_arcsec) - 32usize];
2818 ["Offset of field: EmpyreanAcceptabilityReport::rms_threshold_arcsec"]
2819 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, rms_threshold_arcsec) - 40usize];
2820 ["Offset of field: EmpyreanAcceptabilityReport::residual_isotropy_ok"]
2821 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, residual_isotropy_ok) - 48usize];
2822 ["Offset of field: EmpyreanAcceptabilityReport::at_ct_ratio_value"]
2823 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, at_ct_ratio_value) - 56usize];
2824 ["Offset of field: EmpyreanAcceptabilityReport::at_ct_ratio_threshold"]
2825 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, at_ct_ratio_threshold) - 64usize];
2826 ["Offset of field: EmpyreanAcceptabilityReport::covariance_ok"]
2827 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, covariance_ok) - 72usize];
2828 ["Offset of field: EmpyreanAcceptabilityReport::arc_coverage_ok"]
2829 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, arc_coverage_ok) - 73usize];
2830 ["Offset of field: EmpyreanAcceptabilityReport::arc_days_value"]
2831 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, arc_days_value) - 80usize];
2832 ["Offset of field: EmpyreanAcceptabilityReport::arc_days_threshold"]
2833 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, arc_days_threshold) - 88usize];
2834 ["Offset of field: EmpyreanAcceptabilityReport::fractional_sigma_a_ok"]
2835 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, fractional_sigma_a_ok) - 96usize];
2836 ["Offset of field: EmpyreanAcceptabilityReport::fractional_sigma_a_value"]
2837 [::std::mem::offset_of!(EmpyreanAcceptabilityReport, fractional_sigma_a_value) - 104usize];
2838 ["Offset of field: EmpyreanAcceptabilityReport::fractional_sigma_a_threshold"][::std::mem::offset_of!(
2839 EmpyreanAcceptabilityReport,
2840 fractional_sigma_a_threshold
2841 ) - 112usize];
2842};
2843#[doc = " One per-station bias estimate from a Schur-eliminated nuisance fit.\n\n Mirrors [`scott::results::StationBias`]. Populated rows in the\n returned array correspond to stations that met the\n `min_obs_per_station` threshold; under-observed stations are absent.\n Timing fields are populated only when a `BiasKind::StationTiming`\n nuisance was active (currently no surface to enable it from the C\n ABI; reserved for a planned follow-up).\n\n `obs_code` is heap-allocated and owned by the parent array — freed\n by [`empyrean_od_result_free`] when the result is freed. Don't free\n it manually."]
2844#[repr(C)]
2845#[derive(Debug, Copy, Clone)]
2846pub struct EmpyreanStationBias {
2847 pub obs_code: *mut ::std::os::raw::c_char,
2848 #[doc = " Pre-rejection observation count from this station."]
2849 pub n_obs: usize,
2850 pub bias_ra_arcsec: f64,
2851 pub sigma_ra_arcsec: f64,
2852 pub bias_dec_arcsec: f64,
2853 pub sigma_dec_arcsec: f64,
2854 #[doc = " 1 when the timing bias is populated; 0 otherwise. Reserved for\n the planned `BiasKind::StationTiming` follow-up."]
2855 pub has_timing: u8,
2856 pub bias_timing_sec: f64,
2857 pub sigma_timing_sec: f64,
2858 #[doc = " Scalar significance: max of |bᵢ|/σᵢ across populated components."]
2859 pub significance: f64,
2860}
2861#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2862const _: () = {
2863 ["Size of EmpyreanStationBias"][::std::mem::size_of::<EmpyreanStationBias>() - 80usize];
2864 ["Alignment of EmpyreanStationBias"][::std::mem::align_of::<EmpyreanStationBias>() - 8usize];
2865 ["Offset of field: EmpyreanStationBias::obs_code"]
2866 [::std::mem::offset_of!(EmpyreanStationBias, obs_code) - 0usize];
2867 ["Offset of field: EmpyreanStationBias::n_obs"]
2868 [::std::mem::offset_of!(EmpyreanStationBias, n_obs) - 8usize];
2869 ["Offset of field: EmpyreanStationBias::bias_ra_arcsec"]
2870 [::std::mem::offset_of!(EmpyreanStationBias, bias_ra_arcsec) - 16usize];
2871 ["Offset of field: EmpyreanStationBias::sigma_ra_arcsec"]
2872 [::std::mem::offset_of!(EmpyreanStationBias, sigma_ra_arcsec) - 24usize];
2873 ["Offset of field: EmpyreanStationBias::bias_dec_arcsec"]
2874 [::std::mem::offset_of!(EmpyreanStationBias, bias_dec_arcsec) - 32usize];
2875 ["Offset of field: EmpyreanStationBias::sigma_dec_arcsec"]
2876 [::std::mem::offset_of!(EmpyreanStationBias, sigma_dec_arcsec) - 40usize];
2877 ["Offset of field: EmpyreanStationBias::has_timing"]
2878 [::std::mem::offset_of!(EmpyreanStationBias, has_timing) - 48usize];
2879 ["Offset of field: EmpyreanStationBias::bias_timing_sec"]
2880 [::std::mem::offset_of!(EmpyreanStationBias, bias_timing_sec) - 56usize];
2881 ["Offset of field: EmpyreanStationBias::sigma_timing_sec"]
2882 [::std::mem::offset_of!(EmpyreanStationBias, sigma_timing_sec) - 64usize];
2883 ["Offset of field: EmpyreanStationBias::significance"]
2884 [::std::mem::offset_of!(EmpyreanStationBias, significance) - 72usize];
2885};
2886impl Default for EmpyreanStationBias {
2887 fn default() -> Self {
2888 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2889 unsafe {
2890 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2891 s.assume_init()
2892 }
2893 }
2894}
2895#[doc = " Full solved-parameter covariance at the ABI-frozen width\n [`EMPYREAN_SOLVE_WIDTH`] (mirrors scott's `SolvedCovariance`\n tag-for-tag). The leading `width × width` block is meaningful; rows and\n columns beyond `width` are zero (RESERVED, not defaulted covariance).\n Consumers MUST read the slot tags to locate a parameter — the width\n alone is ambiguous (width 9 is Marsden OR a one-segment thrust). An\n absent tag carries [`EMPYREAN_SLOT_NONE`]."]
2896#[repr(C)]
2897#[derive(Debug, Default, Copy, Clone)]
2898pub struct EmpyreanSolvedCovariance {
2899 #[doc = " Covariance at fixed storage width; leading `width×width` meaningful."]
2900 pub matrix: [[f64; 20usize]; 20usize],
2901 #[doc = " Real solved width — 6..=17 under scott v1.14.0 (`MAX_SOLVE_WIDTH`);\n the struct reserves storage to 20. The leading `width × width`\n block is meaningful."]
2902 pub width: u32,
2903 #[doc = " Slot of the first Marsden coefficient, or [`EMPYREAN_SLOT_NONE`]."]
2904 pub marsden_slot: u32,
2905 #[doc = " Slot of the DT scalar, or [`EMPYREAN_SLOT_NONE`]."]
2906 pub dt_slot: u32,
2907 #[doc = " Slot of the AMRAT scalar, or [`EMPYREAN_SLOT_NONE`]."]
2908 pub amrat_slot: u32,
2909 #[doc = " Slots of each fitted thrust Δv segment (3 wide each); entries\n `0..thrust_count` meaningful. Δv axes are INTEGRATION-frame\n components (see [`EmpyreanODResult::dv_frame`])."]
2910 pub thrust_slots: [[u32; 3usize]; 3usize],
2911 #[doc = " Number of fitted thrust segments (0..=3)."]
2912 pub thrust_count: u32,
2913}
2914#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2915const _: () = {
2916 ["Size of EmpyreanSolvedCovariance"]
2917 [::std::mem::size_of::<EmpyreanSolvedCovariance>() - 3256usize];
2918 ["Alignment of EmpyreanSolvedCovariance"]
2919 [::std::mem::align_of::<EmpyreanSolvedCovariance>() - 8usize];
2920 ["Offset of field: EmpyreanSolvedCovariance::matrix"]
2921 [::std::mem::offset_of!(EmpyreanSolvedCovariance, matrix) - 0usize];
2922 ["Offset of field: EmpyreanSolvedCovariance::width"]
2923 [::std::mem::offset_of!(EmpyreanSolvedCovariance, width) - 3200usize];
2924 ["Offset of field: EmpyreanSolvedCovariance::marsden_slot"]
2925 [::std::mem::offset_of!(EmpyreanSolvedCovariance, marsden_slot) - 3204usize];
2926 ["Offset of field: EmpyreanSolvedCovariance::dt_slot"]
2927 [::std::mem::offset_of!(EmpyreanSolvedCovariance, dt_slot) - 3208usize];
2928 ["Offset of field: EmpyreanSolvedCovariance::amrat_slot"]
2929 [::std::mem::offset_of!(EmpyreanSolvedCovariance, amrat_slot) - 3212usize];
2930 ["Offset of field: EmpyreanSolvedCovariance::thrust_slots"]
2931 [::std::mem::offset_of!(EmpyreanSolvedCovariance, thrust_slots) - 3216usize];
2932 ["Offset of field: EmpyreanSolvedCovariance::thrust_count"]
2933 [::std::mem::offset_of!(EmpyreanSolvedCovariance, thrust_count) - 3252usize];
2934};
2935#[doc = " Per-band photometric statistics (mirrors scott's `BandStat`). Owned\n heap entry, freed by [`empyrean_od_result_free`]."]
2936#[repr(C)]
2937#[derive(Debug, Copy, Clone)]
2938pub struct EmpyreanBandStat {
2939 #[doc = " Photometric band tag (owned C string)."]
2940 pub band: *mut ::std::os::raw::c_char,
2941 #[doc = " Number of observations in this band."]
2942 pub n: usize,
2943 #[doc = " Band→V offset applied (mag)."]
2944 pub offset_applied: f64,
2945 #[doc = " Mean residual in V (mag)."]
2946 pub mean_residual: f64,
2947 #[doc = " RMS residual in V (mag)."]
2948 pub rms: f64,
2949}
2950#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2951const _: () = {
2952 ["Size of EmpyreanBandStat"][::std::mem::size_of::<EmpyreanBandStat>() - 40usize];
2953 ["Alignment of EmpyreanBandStat"][::std::mem::align_of::<EmpyreanBandStat>() - 8usize];
2954 ["Offset of field: EmpyreanBandStat::band"]
2955 [::std::mem::offset_of!(EmpyreanBandStat, band) - 0usize];
2956 ["Offset of field: EmpyreanBandStat::n"][::std::mem::offset_of!(EmpyreanBandStat, n) - 8usize];
2957 ["Offset of field: EmpyreanBandStat::offset_applied"]
2958 [::std::mem::offset_of!(EmpyreanBandStat, offset_applied) - 16usize];
2959 ["Offset of field: EmpyreanBandStat::mean_residual"]
2960 [::std::mem::offset_of!(EmpyreanBandStat, mean_residual) - 24usize];
2961 ["Offset of field: EmpyreanBandStat::rms"]
2962 [::std::mem::offset_of!(EmpyreanBandStat, rms) - 32usize];
2963};
2964impl Default for EmpyreanBandStat {
2965 fn default() -> Self {
2966 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2967 unsafe {
2968 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
2969 s.assume_init()
2970 }
2971 }
2972}
2973#[doc = " One model-ladder gate decision (mirrors scott's `GateRecord`). Owned\n heap entry, freed by [`empyrean_od_result_free`]."]
2974#[repr(C)]
2975#[derive(Debug, Copy, Clone)]
2976pub struct EmpyreanGateRecord {
2977 #[doc = " Model the gate evaluated (`EMPYREAN_PHOTOMETRY_MODEL_*`, fitted)."]
2978 pub model: i32,
2979 #[doc = " 1 if the model was admitted."]
2980 pub passed: u8,
2981 #[doc = " Human-readable gate reason (owned C string)."]
2982 pub reason: *mut ::std::os::raw::c_char,
2983}
2984#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2985const _: () = {
2986 ["Size of EmpyreanGateRecord"][::std::mem::size_of::<EmpyreanGateRecord>() - 16usize];
2987 ["Alignment of EmpyreanGateRecord"][::std::mem::align_of::<EmpyreanGateRecord>() - 8usize];
2988 ["Offset of field: EmpyreanGateRecord::model"]
2989 [::std::mem::offset_of!(EmpyreanGateRecord, model) - 0usize];
2990 ["Offset of field: EmpyreanGateRecord::passed"]
2991 [::std::mem::offset_of!(EmpyreanGateRecord, passed) - 4usize];
2992 ["Offset of field: EmpyreanGateRecord::reason"]
2993 [::std::mem::offset_of!(EmpyreanGateRecord, reason) - 8usize];
2994};
2995impl Default for EmpyreanGateRecord {
2996 fn default() -> Self {
2997 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
2998 unsafe {
2999 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3000 s.assume_init()
3001 }
3002 }
3003}
3004#[doc = " Post-OD photometric solution (mirrors scott's `PhotometryResult`).\n Present only when photometry was requested and ran\n ([`EmpyreanODResult::has_photometry`]). H carries honest σ via the\n [`covariance`](EmpyreanODPhotometryResult::covariance) block."]
3005#[repr(C)]
3006#[derive(Debug, Copy, Clone)]
3007pub struct EmpyreanODPhotometryResult {
3008 #[doc = " Fitted absolute magnitude H (mag)."]
3009 pub h: f64,
3010 #[doc = " First slope parameter (G / G12 / G1 by model)."]
3011 pub slope1: f64,
3012 #[doc = " Second slope parameter (G2 for HG1G2; unused otherwise)."]
3013 pub slope2: f64,
3014 #[doc = " 1 when [`covariance`](EmpyreanODPhotometryResult::covariance) is populated."]
3015 pub has_covariance: u8,
3016 #[doc = " Parameter covariance (H, slope1, slope2 order)."]
3017 pub covariance: [[f64; 3usize]; 3usize],
3018 #[doc = " Model actually fitted (`EMPYREAN_PHOTOMETRY_MODEL_*`; never Auto)."]
3019 pub model_used: i32,
3020 #[doc = " Reduced χ² of the photometric fit over its used magnitudes."]
3021 pub reduced_chi2: f64,
3022 #[doc = " 1 when a simplex constraint was active on the fitted slopes."]
3023 pub constraint_active: u8,
3024 #[doc = " Magnitudes used in the fit."]
3025 pub n_mags_used: usize,
3026 #[doc = " Magnitudes rejected by the photometric outlier pass."]
3027 pub n_mags_rejected_photometric: usize,
3028 #[doc = " Observations carrying no magnitude."]
3029 pub n_obs_without_mags: usize,
3030 #[doc = " Magnitudes drawn from astrometrically-selected observations."]
3031 pub n_mags_from_astrometric_selected: usize,
3032 #[doc = " Magnitudes drawn from astrometrically-rejected observations."]
3033 pub n_mags_from_astrometric_rejected: usize,
3034 #[doc = " Phase-angle coverage of the fitted magnitudes (deg)."]
3035 pub alpha_min_deg: f64,
3036 pub alpha_max_deg: f64,
3037 pub alpha_span_deg: f64,
3038 #[doc = " Owned per-band statistics array; freed by [`empyrean_od_result_free`]."]
3039 pub per_band: *mut EmpyreanBandStat,
3040 pub num_per_band: usize,
3041 #[doc = " Owned model-ladder gate records; freed by [`empyrean_od_result_free`]."]
3042 pub gates: *mut EmpyreanGateRecord,
3043 pub num_gates: usize,
3044 #[doc = " Magnitudes excluded from the fit because their photometric band
3045 has no adopted V-band conversion (unknown/unspecified band
3046 codes, comet total/nuclear magnitudes). Never silent: each
3047 exclusion is counted here and the distinct offending band codes
3048 are listed in `dropped_bands`. The observations' astrometry is
3049 unaffected."]
3050 pub n_mags_dropped_unconvertible: usize,
3051 #[doc = " Distinct band codes that were dropped (owned array of owned C
3052 strings, sorted). Freed by `empyrean_od_result_free`. Null when
3053 `num_dropped_bands == 0`."]
3054 pub dropped_bands: *mut *mut ::std::os::raw::c_char,
3055 #[doc = " Number of entries in `dropped_bands` (0 when null)."]
3056 pub num_dropped_bands: usize,
3057}
3058#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3059const _: () = {
3060 ["Size of EmpyreanODPhotometryResult"]
3061 [::std::mem::size_of::<EmpyreanODPhotometryResult>() - 248usize];
3062 ["Alignment of EmpyreanODPhotometryResult"]
3063 [::std::mem::align_of::<EmpyreanODPhotometryResult>() - 8usize];
3064 ["Offset of field: EmpyreanODPhotometryResult::h"]
3065 [::std::mem::offset_of!(EmpyreanODPhotometryResult, h) - 0usize];
3066 ["Offset of field: EmpyreanODPhotometryResult::slope1"]
3067 [::std::mem::offset_of!(EmpyreanODPhotometryResult, slope1) - 8usize];
3068 ["Offset of field: EmpyreanODPhotometryResult::slope2"]
3069 [::std::mem::offset_of!(EmpyreanODPhotometryResult, slope2) - 16usize];
3070 ["Offset of field: EmpyreanODPhotometryResult::has_covariance"]
3071 [::std::mem::offset_of!(EmpyreanODPhotometryResult, has_covariance) - 24usize];
3072 ["Offset of field: EmpyreanODPhotometryResult::covariance"]
3073 [::std::mem::offset_of!(EmpyreanODPhotometryResult, covariance) - 32usize];
3074 ["Offset of field: EmpyreanODPhotometryResult::model_used"]
3075 [::std::mem::offset_of!(EmpyreanODPhotometryResult, model_used) - 104usize];
3076 ["Offset of field: EmpyreanODPhotometryResult::reduced_chi2"]
3077 [::std::mem::offset_of!(EmpyreanODPhotometryResult, reduced_chi2) - 112usize];
3078 ["Offset of field: EmpyreanODPhotometryResult::constraint_active"]
3079 [::std::mem::offset_of!(EmpyreanODPhotometryResult, constraint_active) - 120usize];
3080 ["Offset of field: EmpyreanODPhotometryResult::n_mags_used"]
3081 [::std::mem::offset_of!(EmpyreanODPhotometryResult, n_mags_used) - 128usize];
3082 ["Offset of field: EmpyreanODPhotometryResult::n_mags_rejected_photometric"][::std::mem::offset_of!(
3083 EmpyreanODPhotometryResult,
3084 n_mags_rejected_photometric
3085 ) - 136usize];
3086 ["Offset of field: EmpyreanODPhotometryResult::n_obs_without_mags"]
3087 [::std::mem::offset_of!(EmpyreanODPhotometryResult, n_obs_without_mags) - 144usize];
3088 ["Offset of field: EmpyreanODPhotometryResult::n_mags_from_astrometric_selected"][::std::mem::offset_of!(
3089 EmpyreanODPhotometryResult,
3090 n_mags_from_astrometric_selected
3091 ) - 152usize];
3092 ["Offset of field: EmpyreanODPhotometryResult::n_mags_from_astrometric_rejected"][::std::mem::offset_of!(
3093 EmpyreanODPhotometryResult,
3094 n_mags_from_astrometric_rejected
3095 ) - 160usize];
3096 ["Offset of field: EmpyreanODPhotometryResult::alpha_min_deg"]
3097 [::std::mem::offset_of!(EmpyreanODPhotometryResult, alpha_min_deg) - 168usize];
3098 ["Offset of field: EmpyreanODPhotometryResult::alpha_max_deg"]
3099 [::std::mem::offset_of!(EmpyreanODPhotometryResult, alpha_max_deg) - 176usize];
3100 ["Offset of field: EmpyreanODPhotometryResult::alpha_span_deg"]
3101 [::std::mem::offset_of!(EmpyreanODPhotometryResult, alpha_span_deg) - 184usize];
3102 ["Offset of field: EmpyreanODPhotometryResult::per_band"]
3103 [::std::mem::offset_of!(EmpyreanODPhotometryResult, per_band) - 192usize];
3104 ["Offset of field: EmpyreanODPhotometryResult::num_per_band"]
3105 [::std::mem::offset_of!(EmpyreanODPhotometryResult, num_per_band) - 200usize];
3106 ["Offset of field: EmpyreanODPhotometryResult::gates"]
3107 [::std::mem::offset_of!(EmpyreanODPhotometryResult, gates) - 208usize];
3108 ["Offset of field: EmpyreanODPhotometryResult::num_gates"]
3109 [::std::mem::offset_of!(EmpyreanODPhotometryResult, num_gates) - 216usize];
3110 ["Offset of field: EmpyreanODPhotometryResult::n_mags_dropped_unconvertible"]
3111 [::std::mem::offset_of!(EmpyreanODPhotometryResult, n_mags_dropped_unconvertible)
3112 - 224usize];
3113 ["Offset of field: EmpyreanODPhotometryResult::dropped_bands"]
3114 [::std::mem::offset_of!(EmpyreanODPhotometryResult, dropped_bands) - 232usize];
3115 ["Offset of field: EmpyreanODPhotometryResult::num_dropped_bands"]
3116 [::std::mem::offset_of!(EmpyreanODPhotometryResult, num_dropped_bands) - 240usize];
3117};
3118impl Default for EmpyreanODPhotometryResult {
3119 fn default() -> Self {
3120 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3121 unsafe {
3122 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3123 s.assume_init()
3124 }
3125 }
3126}
3127#[doc = " Mirrors scott's [`ODResult`](scott::od::ODResult). Carries the fitted\n orbit, the 6×6 (or 9×9 when non-grav was solved) formal covariance,\n the per-observation result array, the summary, the structured\n acceptability report, and the per-station nuisance-bias array\n when `fit_station_biases` was active.\n\n The fitted **absolute** non-gravitational model (when one was solved\n or carried) is exposed via [`has_non_grav`](EmpyreanODResult::has_non_grav)\n / [`non_grav`](EmpyreanODResult::non_grav) so the orbit can be re-fed into\n propagation / evaluate / refine without losing the force model. This is\n distinct from [`non_grav_delta`](EmpyreanODResult::non_grav_delta), which\n is the *cumulative correction* the fit applied and is kept for inspection."]
3128#[repr(C)]
3129#[derive(Debug, Copy, Clone)]
3130pub struct EmpyreanODResult {
3131 pub orbit: EmpyreanPropagatedState,
3132 pub observations: *mut EmpyreanObservationResult,
3133 pub num_observations: usize,
3134 pub summary: EmpyreanResidualSummary,
3135 pub iterations: u32,
3136 #[doc = " Convergence metric at the final DC iteration (Δx^T N Δx)."]
3137 pub update_norm: f64,
3138 #[doc = " Solver reached its stopping criterion (1 = yes).\n Equivalent to `acceptability.converged_ok`; kept for backwards\n compatibility with the v0.7.0 surface that pre-dated the\n structured acceptability report."]
3139 pub converged: u8,
3140 #[doc = " Fitted 6×6 state covariance in [`covariance_representation`]."]
3141 pub covariance: [[f64; 6usize]; 6usize],
3142 #[doc = " Coordinate basis the 6×6 / 9×9 covariance is reported in\n (`EMPYREAN_REPRESENTATION_*`)."]
3143 pub covariance_representation: i32,
3144 #[doc = " 1 when [`covariance_9x9`] is populated (non-grav was solved)."]
3145 pub has_covariance_9x9: u8,
3146 #[doc = " Full 9×9 covariance over (state, A1, A2, A3) when solving for non-grav."]
3147 pub covariance_9x9: [[f64; 9usize]; 9usize],
3148 #[doc = " 1 when [`non_grav_delta`] is populated."]
3149 pub has_non_grav_delta: u8,
3150 #[doc = " Cumulative non-grav parameter corrections (ΔA1, ΔA2, ΔA3) when solving for non-grav."]
3151 pub non_grav_delta: [f64; 3usize],
3152 #[doc = " 1 when [`non_grav`] carries a fitted/absolute non-gravitational model."]
3153 pub has_non_grav: u8,
3154 #[doc = " The fitted orbit's **absolute** non-gravitational model (A1/A2/A3 +\n g(r) exponents + optional thermal-lag `dt`). Re-feed this onto the\n orbit for propagation / evaluate / refine. Zeroed when the orbit is\n gravity-only (`has_non_grav = 0`)."]
3155 pub non_grav: EmpyreanNonGravParams,
3156 #[doc = " Number of rejection/refit passes performed."]
3157 pub rejection_passes: u32,
3158 #[doc = " Number of oppositions successfully fit."]
3159 pub num_oppositions_fit: u32,
3160 #[doc = " Force model tier actually used (0=Approximate, 1=Basic, 2=Standard)."]
3161 pub force_model_used: i32,
3162 #[doc = " Solve-for parameter set requested on the driving config\n (`EMPYREAN_SOLVE_FOR_*`). Together with `has_covariance_9x9`\n disambiguates Auto outcomes."]
3163 pub solve_for_used: i32,
3164 #[doc = " Structured fit-quality verdict. The `acceptable` flags can be\n checked directly; per-check values + thresholds are exposed for\n reporting and downstream sub-classification."]
3165 pub acceptability: EmpyreanAcceptabilityReport,
3166 #[doc = " Per-station fitted nuisance biases when [`EmpyreanODConfig::fit_station_biases`]\n was set. Owned heap allocation; freed by [`empyrean_od_result_free`].\n Null + `num_station_biases = 0` when no bias fit was configured."]
3167 pub station_biases: *mut EmpyreanStationBias,
3168 pub num_station_biases: usize,
3169 #[doc = " 1 when [`solved_covariance`](EmpyreanODResult::solved_covariance)\n is populated (any solved width > 6). 0 for a pure state-only fit."]
3170 pub has_solved_covariance: u8,
3171 #[doc = " Full tagged solved-parameter covariance at the frozen width. The\n go-forward field for ALL solved widths (including 9); the legacy\n `covariance_9x9` remains for one deprecation window."]
3172 pub solved_covariance: EmpyreanSolvedCovariance,
3173 #[doc = " 1 when [`dt_delta`](EmpyreanODResult::dt_delta) is populated (DT solved)."]
3174 pub has_dt_delta: u8,
3175 #[doc = " Cumulative non-grav time-delay correction ΔDT (days)."]
3176 pub dt_delta: f64,
3177 #[doc = " 1 when [`amrat_delta`](EmpyreanODResult::amrat_delta) is populated (AMRAT solved)."]
3178 pub has_amrat_delta: u8,
3179 #[doc = " Cumulative SRP AMRAT correction (m²/kg)."]
3180 pub amrat_delta: f64,
3181 #[doc = " Number of fitted thrust Δv segments (0..=3); 0 = no thrust solve."]
3182 pub thrust_delta_count: u32,
3183 #[doc = " Per-segment fitted Δv in m/s, expressed in\n [`dv_frame`](EmpyreanODResult::dv_frame). Entries\n `0..thrust_delta_count` meaningful."]
3184 pub thrust_delta_m_per_s: [[f64; 3usize]; 3usize],
3185 #[doc = " Integration frame the Δv components are expressed in (0=ICRF,\n 1=EclipticJ2000). Only meaningful when `thrust_delta_count > 0`."]
3186 pub dv_frame: i32,
3187 #[doc = " 1 when [`photometry`](EmpyreanODResult::photometry) carries a fitted H/G solution."]
3188 pub has_photometry: u8,
3189 #[doc = " Post-OD photometric solution when photometry was requested + ran.\n Owns its per-band / gate arrays (freed by `empyrean_od_result_free`)."]
3190 pub photometry: EmpyreanODPhotometryResult,
3191 #[doc = " 1 when [`srp`] carries a fitted/carried absolute SRP slot."]
3192 pub has_srp: u8,
3193 #[doc = " The fitted orbit's absolute SRP slot (AMRAT + Cr + optional AMRAT\n variance). Re-feed this onto the orbit (`has_srp = 1`) so a fitted orbit\n never silently drops its SRP force. Zeroed when `has_srp = 0`."]
3194 pub srp: EmpyreanSRPParams,
3195 #[doc = " Event-aware trust verdict on the delivered covariance
3196 (`EMPYREAN_COVARIANCE_TRUST_*`). `NOT_EVALUATED` (0) means the
3197 call path ran no gate — absence of a verdict is not trust."]
3198 pub covariance_trust: i32,
3199 #[doc = " Intervening-event kind (`EMPYREAN_TRUST_EVENT_*`); `NONE` unless
3200 `covariance_trust == ENCOUNTER_INTERVENES`."]
3201 pub trust_event_kind: i32,
3202 #[doc = " Event epoch (MJD TDB). NaN when no event."]
3203 pub trust_event_epoch_mjd_tdb: f64,
3204 #[doc = " Close-approach distance (AU). NaN unless
3205 `trust_event_kind == CLOSE_APPROACH`."]
3206 pub trust_event_distance_au: f64,
3207 #[doc = " Nonlinearity ratio at the crossing. NaN unless
3208 `trust_event_kind == HIGH_NONLINEARITY`."]
3209 pub trust_event_nonlinearity: f64,
3210 #[doc = " Threshold the nonlinearity exceeded. NaN unless
3211 `trust_event_kind == HIGH_NONLINEARITY`."]
3212 pub trust_event_threshold: f64,
3213 #[doc = " Name of the approached body (owned C string; freed by
3214 `empyrean_od_result_free`). Null unless
3215 `trust_event_kind == CLOSE_APPROACH`."]
3216 pub trust_event_body: *mut ::std::os::raw::c_char,
3217 #[doc = " Solved-for width N of the fit the verdict refers to. 0 when the
3218 verdict carries no width (`TRUSTED` / `NOT_EVALUATED`)."]
3219 pub trust_solved_width: u32,
3220 #[doc = " 1 when a second-order (state-only) correction can recover the
3221 encounter (solved width 6); 0 otherwise. Meaningful only for
3222 `ENCOUNTER_INTERVENES`."]
3223 pub trust_second_order_recoverable: u8,
3224}
3225#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3226const _: () = {
3227 ["Size of EmpyreanODResult"][::std::mem::size_of::<EmpyreanODResult>() - 7600usize];
3228 ["Alignment of EmpyreanODResult"][::std::mem::align_of::<EmpyreanODResult>() - 8usize];
3229 ["Offset of field: EmpyreanODResult::orbit"]
3230 [::std::mem::offset_of!(EmpyreanODResult, orbit) - 0usize];
3231 ["Offset of field: EmpyreanODResult::observations"]
3232 [::std::mem::offset_of!(EmpyreanODResult, observations) - 2392usize];
3233 ["Offset of field: EmpyreanODResult::num_observations"]
3234 [::std::mem::offset_of!(EmpyreanODResult, num_observations) - 2400usize];
3235 ["Offset of field: EmpyreanODResult::summary"]
3236 [::std::mem::offset_of!(EmpyreanODResult, summary) - 2408usize];
3237 ["Offset of field: EmpyreanODResult::iterations"]
3238 [::std::mem::offset_of!(EmpyreanODResult, iterations) - 2552usize];
3239 ["Offset of field: EmpyreanODResult::update_norm"]
3240 [::std::mem::offset_of!(EmpyreanODResult, update_norm) - 2560usize];
3241 ["Offset of field: EmpyreanODResult::converged"]
3242 [::std::mem::offset_of!(EmpyreanODResult, converged) - 2568usize];
3243 ["Offset of field: EmpyreanODResult::covariance"]
3244 [::std::mem::offset_of!(EmpyreanODResult, covariance) - 2576usize];
3245 ["Offset of field: EmpyreanODResult::covariance_representation"]
3246 [::std::mem::offset_of!(EmpyreanODResult, covariance_representation) - 2864usize];
3247 ["Offset of field: EmpyreanODResult::has_covariance_9x9"]
3248 [::std::mem::offset_of!(EmpyreanODResult, has_covariance_9x9) - 2868usize];
3249 ["Offset of field: EmpyreanODResult::covariance_9x9"]
3250 [::std::mem::offset_of!(EmpyreanODResult, covariance_9x9) - 2872usize];
3251 ["Offset of field: EmpyreanODResult::has_non_grav_delta"]
3252 [::std::mem::offset_of!(EmpyreanODResult, has_non_grav_delta) - 3520usize];
3253 ["Offset of field: EmpyreanODResult::non_grav_delta"]
3254 [::std::mem::offset_of!(EmpyreanODResult, non_grav_delta) - 3528usize];
3255 ["Offset of field: EmpyreanODResult::has_non_grav"]
3256 [::std::mem::offset_of!(EmpyreanODResult, has_non_grav) - 3552usize];
3257 ["Offset of field: EmpyreanODResult::non_grav"]
3258 [::std::mem::offset_of!(EmpyreanODResult, non_grav) - 3560usize];
3259 ["Offset of field: EmpyreanODResult::rejection_passes"]
3260 [::std::mem::offset_of!(EmpyreanODResult, rejection_passes) - 3720usize];
3261 ["Offset of field: EmpyreanODResult::num_oppositions_fit"]
3262 [::std::mem::offset_of!(EmpyreanODResult, num_oppositions_fit) - 3724usize];
3263 ["Offset of field: EmpyreanODResult::force_model_used"]
3264 [::std::mem::offset_of!(EmpyreanODResult, force_model_used) - 3728usize];
3265 ["Offset of field: EmpyreanODResult::solve_for_used"]
3266 [::std::mem::offset_of!(EmpyreanODResult, solve_for_used) - 3732usize];
3267 ["Offset of field: EmpyreanODResult::acceptability"]
3268 [::std::mem::offset_of!(EmpyreanODResult, acceptability) - 3736usize];
3269 ["Offset of field: EmpyreanODResult::station_biases"]
3270 [::std::mem::offset_of!(EmpyreanODResult, station_biases) - 3856usize];
3271 ["Offset of field: EmpyreanODResult::num_station_biases"]
3272 [::std::mem::offset_of!(EmpyreanODResult, num_station_biases) - 3864usize];
3273 ["Offset of field: EmpyreanODResult::has_solved_covariance"]
3274 [::std::mem::offset_of!(EmpyreanODResult, has_solved_covariance) - 3872usize];
3275 ["Offset of field: EmpyreanODResult::solved_covariance"]
3276 [::std::mem::offset_of!(EmpyreanODResult, solved_covariance) - 3880usize];
3277 ["Offset of field: EmpyreanODResult::has_dt_delta"]
3278 [::std::mem::offset_of!(EmpyreanODResult, has_dt_delta) - 7136usize];
3279 ["Offset of field: EmpyreanODResult::dt_delta"]
3280 [::std::mem::offset_of!(EmpyreanODResult, dt_delta) - 7144usize];
3281 ["Offset of field: EmpyreanODResult::has_amrat_delta"]
3282 [::std::mem::offset_of!(EmpyreanODResult, has_amrat_delta) - 7152usize];
3283 ["Offset of field: EmpyreanODResult::amrat_delta"]
3284 [::std::mem::offset_of!(EmpyreanODResult, amrat_delta) - 7160usize];
3285 ["Offset of field: EmpyreanODResult::thrust_delta_count"]
3286 [::std::mem::offset_of!(EmpyreanODResult, thrust_delta_count) - 7168usize];
3287 ["Offset of field: EmpyreanODResult::thrust_delta_m_per_s"]
3288 [::std::mem::offset_of!(EmpyreanODResult, thrust_delta_m_per_s) - 7176usize];
3289 ["Offset of field: EmpyreanODResult::dv_frame"]
3290 [::std::mem::offset_of!(EmpyreanODResult, dv_frame) - 7248usize];
3291 ["Offset of field: EmpyreanODResult::has_photometry"]
3292 [::std::mem::offset_of!(EmpyreanODResult, has_photometry) - 7252usize];
3293 ["Offset of field: EmpyreanODResult::photometry"]
3294 [::std::mem::offset_of!(EmpyreanODResult, photometry) - 7256usize];
3295 ["Offset of field: EmpyreanODResult::has_srp"]
3296 [::std::mem::offset_of!(EmpyreanODResult, has_srp) - 7504usize];
3297 ["Offset of field: EmpyreanODResult::srp"]
3298 [::std::mem::offset_of!(EmpyreanODResult, srp) - 7512usize];
3299 ["Offset of field: EmpyreanODResult::covariance_trust"]
3300 [::std::mem::offset_of!(EmpyreanODResult, covariance_trust) - 7544usize];
3301 ["Offset of field: EmpyreanODResult::trust_event_kind"]
3302 [::std::mem::offset_of!(EmpyreanODResult, trust_event_kind) - 7548usize];
3303 ["Offset of field: EmpyreanODResult::trust_event_epoch_mjd_tdb"]
3304 [::std::mem::offset_of!(EmpyreanODResult, trust_event_epoch_mjd_tdb) - 7552usize];
3305 ["Offset of field: EmpyreanODResult::trust_event_distance_au"]
3306 [::std::mem::offset_of!(EmpyreanODResult, trust_event_distance_au) - 7560usize];
3307 ["Offset of field: EmpyreanODResult::trust_event_nonlinearity"]
3308 [::std::mem::offset_of!(EmpyreanODResult, trust_event_nonlinearity) - 7568usize];
3309 ["Offset of field: EmpyreanODResult::trust_event_threshold"]
3310 [::std::mem::offset_of!(EmpyreanODResult, trust_event_threshold) - 7576usize];
3311 ["Offset of field: EmpyreanODResult::trust_event_body"]
3312 [::std::mem::offset_of!(EmpyreanODResult, trust_event_body) - 7584usize];
3313 ["Offset of field: EmpyreanODResult::trust_solved_width"]
3314 [::std::mem::offset_of!(EmpyreanODResult, trust_solved_width) - 7592usize];
3315 ["Offset of field: EmpyreanODResult::trust_second_order_recoverable"]
3316 [::std::mem::offset_of!(EmpyreanODResult, trust_second_order_recoverable) - 7596usize];
3317};
3318impl Default for EmpyreanODResult {
3319 fn default() -> Self {
3320 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3321 unsafe {
3322 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3323 s.assume_init()
3324 }
3325 }
3326}
3327#[doc = " Result of orbit evaluation (residuals without fitting).\n\n Same per-observation surface as [`EmpyreanODResult`] (rejection +\n influence fields are NaN / `NOT_EVALUATED` because evaluate does\n not run rejection or influence passes), but no fitted orbit or\n acceptability report."]
3328#[repr(C)]
3329#[derive(Debug, Copy, Clone)]
3330pub struct EmpyreanEvaluateResult {
3331 pub observations: *mut EmpyreanObservationResult,
3332 pub num_observations: usize,
3333 pub summary: EmpyreanResidualSummary,
3334}
3335#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3336const _: () = {
3337 ["Size of EmpyreanEvaluateResult"][::std::mem::size_of::<EmpyreanEvaluateResult>() - 160usize];
3338 ["Alignment of EmpyreanEvaluateResult"]
3339 [::std::mem::align_of::<EmpyreanEvaluateResult>() - 8usize];
3340 ["Offset of field: EmpyreanEvaluateResult::observations"]
3341 [::std::mem::offset_of!(EmpyreanEvaluateResult, observations) - 0usize];
3342 ["Offset of field: EmpyreanEvaluateResult::num_observations"]
3343 [::std::mem::offset_of!(EmpyreanEvaluateResult, num_observations) - 8usize];
3344 ["Offset of field: EmpyreanEvaluateResult::summary"]
3345 [::std::mem::offset_of!(EmpyreanEvaluateResult, summary) - 16usize];
3346};
3347impl Default for EmpyreanEvaluateResult {
3348 fn default() -> Self {
3349 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3350 unsafe {
3351 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3352 s.assume_init()
3353 }
3354 }
3355}
3356#[doc = " A single planned (candidate) observation: an epoch plus either an optical or\n a radar measurement spec. Optical fields are read when `kind == 0`, radar\n fields when `kind == 1`; absent optional radar target properties use NaN\n (the link budget refuses, rather than silently defaults, a missing value)."]
3357#[repr(C)]
3358#[derive(Debug, Copy, Clone)]
3359pub struct EmpyreanPlannedObservation {
3360 #[doc = " Planned (receive, for radar) epoch — MJD, TDB."]
3361 pub epoch_mjd_tdb: f64,
3362 #[doc = " 0 = optical, 1 = radar."]
3363 pub kind: u8,
3364 #[doc = " Optical: registered MPC station code (null-terminated UTF-8)."]
3365 pub optical_code: *const ::std::os::raw::c_char,
3366 #[doc = " Optical 1σ (RA·cosδ) uncertainty (arcsec)."]
3367 pub optical_sigma_ra_arcsec: f64,
3368 #[doc = " Optical 1σ Dec uncertainty (arcsec)."]
3369 pub optical_sigma_dec_arcsec: f64,
3370 #[doc = " Radar transmit dish preset: 0 = Goldstone DSS-14, 1 = Green Bank\n (receive-only), 2 = Arecibo (defunct — rejected loudly, never scheduled)."]
3371 pub radar_transmit_station: u8,
3372 #[doc = " Radar receive dish preset (same encoding; equal to transmit = monostatic)."]
3373 pub radar_receive_station: u8,
3374 #[doc = " Radar mode: 0 = Delay, 1 = Doppler, 2 = Both."]
3375 pub radar_mode: u8,
3376 #[doc = " Waveform bandwidth (Hz) — sets the delay (range) σ."]
3377 pub radar_bandwidth_hz: f64,
3378 #[doc = " Doppler frequency resolution (Hz) — sets the Doppler (range-rate) σ."]
3379 pub radar_freq_resolution_hz: f64,
3380 #[doc = " Supplied effective SNR (linear, not dB). NaN → compute from the link\n budget using the target properties + integration time below."]
3381 pub radar_snr: f64,
3382 #[doc = " Link-budget target absolute magnitude H (mag). NaN = absent."]
3383 pub radar_target_h_mag: f64,
3384 #[doc = " Link-budget target visual geometric albedo. NaN = absent."]
3385 pub radar_target_visual_albedo: f64,
3386 #[doc = " Link-budget target radar (OC) albedo. NaN = absent."]
3387 pub radar_target_radar_albedo: f64,
3388 #[doc = " Link-budget target effective diameter (km). NaN = absent."]
3389 pub radar_target_diameter_km: f64,
3390 #[doc = " Link-budget target rotation period (hours), caps coherent integration.\n NaN = absent."]
3391 pub radar_target_spin_period_hours: f64,
3392 #[doc = " Coherent integration time (s) for the link-budget SNR."]
3393 pub radar_integration_s: f64,
3394}
3395#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3396const _: () = {
3397 ["Size of EmpyreanPlannedObservation"]
3398 [::std::mem::size_of::<EmpyreanPlannedObservation>() - 120usize];
3399 ["Alignment of EmpyreanPlannedObservation"]
3400 [::std::mem::align_of::<EmpyreanPlannedObservation>() - 8usize];
3401 ["Offset of field: EmpyreanPlannedObservation::epoch_mjd_tdb"]
3402 [::std::mem::offset_of!(EmpyreanPlannedObservation, epoch_mjd_tdb) - 0usize];
3403 ["Offset of field: EmpyreanPlannedObservation::kind"]
3404 [::std::mem::offset_of!(EmpyreanPlannedObservation, kind) - 8usize];
3405 ["Offset of field: EmpyreanPlannedObservation::optical_code"]
3406 [::std::mem::offset_of!(EmpyreanPlannedObservation, optical_code) - 16usize];
3407 ["Offset of field: EmpyreanPlannedObservation::optical_sigma_ra_arcsec"]
3408 [::std::mem::offset_of!(EmpyreanPlannedObservation, optical_sigma_ra_arcsec) - 24usize];
3409 ["Offset of field: EmpyreanPlannedObservation::optical_sigma_dec_arcsec"]
3410 [::std::mem::offset_of!(EmpyreanPlannedObservation, optical_sigma_dec_arcsec) - 32usize];
3411 ["Offset of field: EmpyreanPlannedObservation::radar_transmit_station"]
3412 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_transmit_station) - 40usize];
3413 ["Offset of field: EmpyreanPlannedObservation::radar_receive_station"]
3414 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_receive_station) - 41usize];
3415 ["Offset of field: EmpyreanPlannedObservation::radar_mode"]
3416 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_mode) - 42usize];
3417 ["Offset of field: EmpyreanPlannedObservation::radar_bandwidth_hz"]
3418 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_bandwidth_hz) - 48usize];
3419 ["Offset of field: EmpyreanPlannedObservation::radar_freq_resolution_hz"]
3420 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_freq_resolution_hz) - 56usize];
3421 ["Offset of field: EmpyreanPlannedObservation::radar_snr"]
3422 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_snr) - 64usize];
3423 ["Offset of field: EmpyreanPlannedObservation::radar_target_h_mag"]
3424 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_h_mag) - 72usize];
3425 ["Offset of field: EmpyreanPlannedObservation::radar_target_visual_albedo"]
3426 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_visual_albedo) - 80usize];
3427 ["Offset of field: EmpyreanPlannedObservation::radar_target_radar_albedo"]
3428 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_radar_albedo) - 88usize];
3429 ["Offset of field: EmpyreanPlannedObservation::radar_target_diameter_km"]
3430 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_diameter_km) - 96usize];
3431 ["Offset of field: EmpyreanPlannedObservation::radar_target_spin_period_hours"][::std::mem::offset_of!(
3432 EmpyreanPlannedObservation,
3433 radar_target_spin_period_hours
3434 ) - 104usize];
3435 ["Offset of field: EmpyreanPlannedObservation::radar_integration_s"]
3436 [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_integration_s) - 112usize];
3437};
3438impl Default for EmpyreanPlannedObservation {
3439 fn default() -> Self {
3440 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3441 unsafe {
3442 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3443 s.assume_init()
3444 }
3445 }
3446}
3447#[doc = " Per-observatory assumptions: astrometric σ + observability filters."]
3448#[repr(C)]
3449#[derive(Debug, Copy, Clone)]
3450pub struct EmpyreanObservatoryConfig {
3451 #[doc = " MPC observatory code (null-terminated UTF-8)."]
3452 pub obs_code: *const ::std::os::raw::c_char,
3453 #[doc = " 1σ (RA·cosδ) astrometric uncertainty (arcsec)."]
3454 pub sigma_ra_arcsec: f64,
3455 #[doc = " 1σ Dec astrometric uncertainty (arcsec)."]
3456 pub sigma_dec_arcsec: f64,
3457 #[doc = " Limiting apparent magnitude."]
3458 pub max_apparent_mag: f64,
3459 #[doc = " Minimum solar elongation (degrees)."]
3460 pub min_elongation_deg: f64,
3461}
3462#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3463const _: () = {
3464 ["Size of EmpyreanObservatoryConfig"]
3465 [::std::mem::size_of::<EmpyreanObservatoryConfig>() - 40usize];
3466 ["Alignment of EmpyreanObservatoryConfig"]
3467 [::std::mem::align_of::<EmpyreanObservatoryConfig>() - 8usize];
3468 ["Offset of field: EmpyreanObservatoryConfig::obs_code"]
3469 [::std::mem::offset_of!(EmpyreanObservatoryConfig, obs_code) - 0usize];
3470 ["Offset of field: EmpyreanObservatoryConfig::sigma_ra_arcsec"]
3471 [::std::mem::offset_of!(EmpyreanObservatoryConfig, sigma_ra_arcsec) - 8usize];
3472 ["Offset of field: EmpyreanObservatoryConfig::sigma_dec_arcsec"]
3473 [::std::mem::offset_of!(EmpyreanObservatoryConfig, sigma_dec_arcsec) - 16usize];
3474 ["Offset of field: EmpyreanObservatoryConfig::max_apparent_mag"]
3475 [::std::mem::offset_of!(EmpyreanObservatoryConfig, max_apparent_mag) - 24usize];
3476 ["Offset of field: EmpyreanObservatoryConfig::min_elongation_deg"]
3477 [::std::mem::offset_of!(EmpyreanObservatoryConfig, min_elongation_deg) - 32usize];
3478};
3479impl Default for EmpyreanObservatoryConfig {
3480 fn default() -> Self {
3481 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3482 unsafe {
3483 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3484 s.assume_init()
3485 }
3486 }
3487}
3488#[doc = " Planning configuration: force model, integration tolerance, the\n per-observatory astrometric assumptions, and threading."]
3489#[repr(C)]
3490#[derive(Debug, Copy, Clone)]
3491pub struct EmpyreanPlanningConfig {
3492 #[doc = " Force-model tier: 0 = Approximate, 1 = Basic, 2 = Standard."]
3493 pub force_model: i32,
3494 #[doc = " GR15 / IAS15 integration tolerance."]
3495 pub epsilon: f64,
3496 #[doc = " Per-observatory config array."]
3497 pub observatories: *const EmpyreanObservatoryConfig,
3498 #[doc = " Number of entries in `observatories`."]
3499 pub num_observatories: usize,
3500 #[doc = " Threads for batch operations; -1 = all CPUs."]
3501 pub num_threads: i32,
3502}
3503#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3504const _: () = {
3505 ["Size of EmpyreanPlanningConfig"][::std::mem::size_of::<EmpyreanPlanningConfig>() - 40usize];
3506 ["Alignment of EmpyreanPlanningConfig"]
3507 [::std::mem::align_of::<EmpyreanPlanningConfig>() - 8usize];
3508 ["Offset of field: EmpyreanPlanningConfig::force_model"]
3509 [::std::mem::offset_of!(EmpyreanPlanningConfig, force_model) - 0usize];
3510 ["Offset of field: EmpyreanPlanningConfig::epsilon"]
3511 [::std::mem::offset_of!(EmpyreanPlanningConfig, epsilon) - 8usize];
3512 ["Offset of field: EmpyreanPlanningConfig::observatories"]
3513 [::std::mem::offset_of!(EmpyreanPlanningConfig, observatories) - 16usize];
3514 ["Offset of field: EmpyreanPlanningConfig::num_observatories"]
3515 [::std::mem::offset_of!(EmpyreanPlanningConfig, num_observatories) - 24usize];
3516 ["Offset of field: EmpyreanPlanningConfig::num_threads"]
3517 [::std::mem::offset_of!(EmpyreanPlanningConfig, num_threads) - 32usize];
3518};
3519impl Default for EmpyreanPlanningConfig {
3520 fn default() -> Self {
3521 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3522 unsafe {
3523 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3524 s.assume_init()
3525 }
3526 }
3527}
3528#[doc = " Covariance summary metrics (prior, posterior, or per-candidate cumulative)."]
3529#[repr(C)]
3530#[derive(Debug, Default, Copy, Clone)]
3531pub struct EmpyreanCovarianceMetrics {
3532 #[doc = " RSS position 1σ (km)."]
3533 pub position_sigma_km: f64,
3534 #[doc = " RSS velocity 1σ (m/s) — the rendezvous-Δv-knowledge term."]
3535 pub velocity_sigma_m_s: f64,
3536 #[doc = " Semi-major axis of the 1σ position ellipsoid (km)."]
3537 pub semi_major_km: f64,
3538 #[doc = " Semi-minor axis of the 1σ position ellipsoid (km)."]
3539 pub semi_minor_km: f64,
3540 #[doc = " ln(det(Σ)) — D-optimality criterion."]
3541 pub log_det: f64,
3542}
3543#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3544const _: () = {
3545 ["Size of EmpyreanCovarianceMetrics"]
3546 [::std::mem::size_of::<EmpyreanCovarianceMetrics>() - 40usize];
3547 ["Alignment of EmpyreanCovarianceMetrics"]
3548 [::std::mem::align_of::<EmpyreanCovarianceMetrics>() - 8usize];
3549 ["Offset of field: EmpyreanCovarianceMetrics::position_sigma_km"]
3550 [::std::mem::offset_of!(EmpyreanCovarianceMetrics, position_sigma_km) - 0usize];
3551 ["Offset of field: EmpyreanCovarianceMetrics::velocity_sigma_m_s"]
3552 [::std::mem::offset_of!(EmpyreanCovarianceMetrics, velocity_sigma_m_s) - 8usize];
3553 ["Offset of field: EmpyreanCovarianceMetrics::semi_major_km"]
3554 [::std::mem::offset_of!(EmpyreanCovarianceMetrics, semi_major_km) - 16usize];
3555 ["Offset of field: EmpyreanCovarianceMetrics::semi_minor_km"]
3556 [::std::mem::offset_of!(EmpyreanCovarianceMetrics, semi_minor_km) - 24usize];
3557 ["Offset of field: EmpyreanCovarianceMetrics::log_det"]
3558 [::std::mem::offset_of!(EmpyreanCovarianceMetrics, log_det) - 32usize];
3559};
3560#[doc = " One predicted sky-plane point of the plan's optical ephemeris: the\n target's predicted topocentric right ascension and declination\n (degrees, ICRF) at an optical candidate's epoch (MJD, TDB)."]
3561#[repr(C)]
3562#[derive(Debug, Default, Copy, Clone)]
3563pub struct EmpyreanPlanEphemerisPoint {
3564 #[doc = " Epoch — MJD, TDB."]
3565 pub epoch_mjd_tdb: f64,
3566 #[doc = " Predicted topocentric right ascension (degrees, ICRF)."]
3567 pub ra_deg: f64,
3568 #[doc = " Predicted topocentric declination (degrees, ICRF)."]
3569 pub dec_deg: f64,
3570}
3571#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3572const _: () = {
3573 ["Size of EmpyreanPlanEphemerisPoint"]
3574 [::std::mem::size_of::<EmpyreanPlanEphemerisPoint>() - 24usize];
3575 ["Alignment of EmpyreanPlanEphemerisPoint"]
3576 [::std::mem::align_of::<EmpyreanPlanEphemerisPoint>() - 8usize];
3577 ["Offset of field: EmpyreanPlanEphemerisPoint::epoch_mjd_tdb"]
3578 [::std::mem::offset_of!(EmpyreanPlanEphemerisPoint, epoch_mjd_tdb) - 0usize];
3579 ["Offset of field: EmpyreanPlanEphemerisPoint::ra_deg"]
3580 [::std::mem::offset_of!(EmpyreanPlanEphemerisPoint, ra_deg) - 8usize];
3581 ["Offset of field: EmpyreanPlanEphemerisPoint::dec_deg"]
3582 [::std::mem::offset_of!(EmpyreanPlanEphemerisPoint, dec_deg) - 16usize];
3583};
3584#[doc = " Per-candidate information-gain analysis."]
3585#[repr(C)]
3586#[derive(Debug, Copy, Clone)]
3587pub struct EmpyreanPlanCandidate {
3588 #[doc = " Index into the planned-observation list."]
3589 pub index: usize,
3590 #[doc = " Observatory / receive-station code (owned; freed by\n `empyrean_plan_result_free`)."]
3591 pub obs_code: *mut ::std::os::raw::c_char,
3592 #[doc = " 0 = optical, 1 = radar."]
3593 pub kind: u8,
3594 #[doc = " 1 if observable at this epoch (passes the filters / has positive SNR)."]
3595 pub observable: u8,
3596 #[doc = " Sky-plane along-track 1σ (arcsec) — optical geometry (NaN for radar)."]
3597 pub along_track_sigma_arcsec: f64,
3598 #[doc = " Sky-plane cross-track 1σ (arcsec)."]
3599 pub cross_track_sigma_arcsec: f64,
3600 #[doc = " Predicted RA·cosδ 1σ (arcsec)."]
3601 pub ra_sigma_arcsec: f64,
3602 #[doc = " Predicted Dec 1σ (arcsec)."]
3603 pub dec_sigma_arcsec: f64,
3604 #[doc = " Position angle of the sky-plane uncertainty ellipse (degrees)."]
3605 pub position_angle_deg: f64,
3606 #[doc = " Marginal covariance-volume reduction factor from this observation (≤ 1)."]
3607 pub marginal_volume_reduction: f64,
3608 #[doc = " Fractional position-σ improvement from this observation (∈ [0, 1])."]
3609 pub marginal_position_improvement: f64,
3610 #[doc = " Post-observation along-track 1σ (arcsec)."]
3611 pub post_along_track_sigma_arcsec: f64,
3612 #[doc = " Post-observation cross-track 1σ (arcsec)."]
3613 pub post_cross_track_sigma_arcsec: f64,
3614 #[doc = " Covariance metrics after folding this observation and all prior ones."]
3615 pub cumulative: EmpyreanCovarianceMetrics,
3616 #[doc = " Active solve-for width (6 = state-only)."]
3617 pub active_width: usize,
3618 #[doc = " Radar only: effective signal-to-noise ratio used for the\n delay/Doppler measurement uncertainty (linear power ratio, not\n dB). Always finite and positive for a radar candidate; NaN for\n an optical candidate."]
3619 pub radar_snr: f64,
3620 #[doc = " Radar only: one-way topocentric range to the target at the\n receive epoch (km), derived from the predicted round-trip delay.\n NaN for an optical candidate."]
3621 pub radar_range_km: f64,
3622 #[doc = " Radar only: human-readable notes recording assumptions made\n while deriving the SNR from the link budget. Owned,\n null-terminated UTF-8 strings, freed by\n `empyrean_plan_result_free`. Null/0 when there are no notes."]
3623 pub radar_provenance: *mut *mut ::std::os::raw::c_char,
3624 #[doc = " Number of entries in `radar_provenance` (0 when null)."]
3625 pub num_radar_provenance: usize,
3626 #[doc = " Radar only: measurement mode — 0 = delay, 1 = Doppler,\n 2 = both. -1 for an optical candidate."]
3627 pub radar_mode: i32,
3628}
3629#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3630const _: () = {
3631 ["Size of EmpyreanPlanCandidate"][::std::mem::size_of::<EmpyreanPlanCandidate>() - 184usize];
3632 ["Alignment of EmpyreanPlanCandidate"]
3633 [::std::mem::align_of::<EmpyreanPlanCandidate>() - 8usize];
3634 ["Offset of field: EmpyreanPlanCandidate::index"]
3635 [::std::mem::offset_of!(EmpyreanPlanCandidate, index) - 0usize];
3636 ["Offset of field: EmpyreanPlanCandidate::obs_code"]
3637 [::std::mem::offset_of!(EmpyreanPlanCandidate, obs_code) - 8usize];
3638 ["Offset of field: EmpyreanPlanCandidate::kind"]
3639 [::std::mem::offset_of!(EmpyreanPlanCandidate, kind) - 16usize];
3640 ["Offset of field: EmpyreanPlanCandidate::observable"]
3641 [::std::mem::offset_of!(EmpyreanPlanCandidate, observable) - 17usize];
3642 ["Offset of field: EmpyreanPlanCandidate::along_track_sigma_arcsec"]
3643 [::std::mem::offset_of!(EmpyreanPlanCandidate, along_track_sigma_arcsec) - 24usize];
3644 ["Offset of field: EmpyreanPlanCandidate::cross_track_sigma_arcsec"]
3645 [::std::mem::offset_of!(EmpyreanPlanCandidate, cross_track_sigma_arcsec) - 32usize];
3646 ["Offset of field: EmpyreanPlanCandidate::ra_sigma_arcsec"]
3647 [::std::mem::offset_of!(EmpyreanPlanCandidate, ra_sigma_arcsec) - 40usize];
3648 ["Offset of field: EmpyreanPlanCandidate::dec_sigma_arcsec"]
3649 [::std::mem::offset_of!(EmpyreanPlanCandidate, dec_sigma_arcsec) - 48usize];
3650 ["Offset of field: EmpyreanPlanCandidate::position_angle_deg"]
3651 [::std::mem::offset_of!(EmpyreanPlanCandidate, position_angle_deg) - 56usize];
3652 ["Offset of field: EmpyreanPlanCandidate::marginal_volume_reduction"]
3653 [::std::mem::offset_of!(EmpyreanPlanCandidate, marginal_volume_reduction) - 64usize];
3654 ["Offset of field: EmpyreanPlanCandidate::marginal_position_improvement"]
3655 [::std::mem::offset_of!(EmpyreanPlanCandidate, marginal_position_improvement) - 72usize];
3656 ["Offset of field: EmpyreanPlanCandidate::post_along_track_sigma_arcsec"]
3657 [::std::mem::offset_of!(EmpyreanPlanCandidate, post_along_track_sigma_arcsec) - 80usize];
3658 ["Offset of field: EmpyreanPlanCandidate::post_cross_track_sigma_arcsec"]
3659 [::std::mem::offset_of!(EmpyreanPlanCandidate, post_cross_track_sigma_arcsec) - 88usize];
3660 ["Offset of field: EmpyreanPlanCandidate::cumulative"]
3661 [::std::mem::offset_of!(EmpyreanPlanCandidate, cumulative) - 96usize];
3662 ["Offset of field: EmpyreanPlanCandidate::active_width"]
3663 [::std::mem::offset_of!(EmpyreanPlanCandidate, active_width) - 136usize];
3664 ["Offset of field: EmpyreanPlanCandidate::radar_snr"]
3665 [::std::mem::offset_of!(EmpyreanPlanCandidate, radar_snr) - 144usize];
3666 ["Offset of field: EmpyreanPlanCandidate::radar_range_km"]
3667 [::std::mem::offset_of!(EmpyreanPlanCandidate, radar_range_km) - 152usize];
3668 ["Offset of field: EmpyreanPlanCandidate::radar_provenance"]
3669 [::std::mem::offset_of!(EmpyreanPlanCandidate, radar_provenance) - 160usize];
3670 ["Offset of field: EmpyreanPlanCandidate::num_radar_provenance"]
3671 [::std::mem::offset_of!(EmpyreanPlanCandidate, num_radar_provenance) - 168usize];
3672 ["Offset of field: EmpyreanPlanCandidate::radar_mode"]
3673 [::std::mem::offset_of!(EmpyreanPlanCandidate, radar_mode) - 176usize];
3674};
3675impl Default for EmpyreanPlanCandidate {
3676 fn default() -> Self {
3677 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3678 unsafe {
3679 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3680 s.assume_init()
3681 }
3682 }
3683}
3684#[doc = " Result of a plan evaluation. The caller allocates the struct; the\n `orbit_id` string and the `candidates` array (with their `obs_code`\n strings) are heap-allocated here and must be released with\n [`empyrean_plan_result_free`]."]
3685#[repr(C)]
3686#[derive(Debug, Copy, Clone)]
3687pub struct EmpyreanPlanResult {
3688 #[doc = " Orbit identifier (owned)."]
3689 pub orbit_id: *mut ::std::os::raw::c_char,
3690 #[doc = " Prior (pre-observation) covariance metrics."]
3691 pub prior: EmpyreanCovarianceMetrics,
3692 #[doc = " Posterior (all candidates folded) covariance metrics."]
3693 pub posterior: EmpyreanCovarianceMetrics,
3694 #[doc = " Per-candidate analysis array (owned)."]
3695 pub candidates: *mut EmpyreanPlanCandidate,
3696 #[doc = " Number of entries in `candidates`."]
3697 pub num_candidates: usize,
3698 #[doc = " Active solve-for width (6 = state-only)."]
3699 pub active_width: usize,
3700 #[doc = " Predicted optical ephemeris, one point per optical candidate in\n chronological order; an optical candidate's `index` field gives\n its row in this array (radar candidates carry no sky-plane\n prediction). Owned; freed by `empyrean_plan_result_free`. Null\n with count 0 for a radar-only plan."]
3701 pub ephemeris: *mut EmpyreanPlanEphemerisPoint,
3702 #[doc = " Number of entries in `ephemeris` (0 when null)."]
3703 pub num_ephemeris: usize,
3704}
3705#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3706const _: () = {
3707 ["Size of EmpyreanPlanResult"][::std::mem::size_of::<EmpyreanPlanResult>() - 128usize];
3708 ["Alignment of EmpyreanPlanResult"][::std::mem::align_of::<EmpyreanPlanResult>() - 8usize];
3709 ["Offset of field: EmpyreanPlanResult::orbit_id"]
3710 [::std::mem::offset_of!(EmpyreanPlanResult, orbit_id) - 0usize];
3711 ["Offset of field: EmpyreanPlanResult::prior"]
3712 [::std::mem::offset_of!(EmpyreanPlanResult, prior) - 8usize];
3713 ["Offset of field: EmpyreanPlanResult::posterior"]
3714 [::std::mem::offset_of!(EmpyreanPlanResult, posterior) - 48usize];
3715 ["Offset of field: EmpyreanPlanResult::candidates"]
3716 [::std::mem::offset_of!(EmpyreanPlanResult, candidates) - 88usize];
3717 ["Offset of field: EmpyreanPlanResult::num_candidates"]
3718 [::std::mem::offset_of!(EmpyreanPlanResult, num_candidates) - 96usize];
3719 ["Offset of field: EmpyreanPlanResult::active_width"]
3720 [::std::mem::offset_of!(EmpyreanPlanResult, active_width) - 104usize];
3721 ["Offset of field: EmpyreanPlanResult::ephemeris"]
3722 [::std::mem::offset_of!(EmpyreanPlanResult, ephemeris) - 112usize];
3723 ["Offset of field: EmpyreanPlanResult::num_ephemeris"]
3724 [::std::mem::offset_of!(EmpyreanPlanResult, num_ephemeris) - 120usize];
3725};
3726impl Default for EmpyreanPlanResult {
3727 fn default() -> Self {
3728 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3729 unsafe {
3730 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3731 s.assume_init()
3732 }
3733 }
3734}
3735#[doc = " Flattened, owned form of `empyrean_core::propagation::TaggedCovariance`\n (villeneuve's provenance-tagged covariance). Self-describing: the 6×6\n matrix together with the co-located nominal state, how the covariance\n was derived, its definiteness, its basis, the solved-for parameters,\n and the functional it describes — so a consumer can never read a\n second-order CA ellipsoid as a linear one.\n\n NOTE on the `_cartesian` accessor's reachable range: that accessor\n classifies but never repairs (`quality` ∈ {POSITIVE_DEFINITE,\n INDEFINITE}), is always state-only (`solved_width == 6`,\n `target_functional == CARTESIAN_STATE`, `has_mean_shift_input == 0`),\n and resolves Monte-Carlo epochs to an error rather than a row. The\n constant fields are carried for the future element-space / off-grid /\n CA-window accessors that *do* vary them."]
3736#[repr(C)]
3737#[derive(Debug, Default, Copy, Clone)]
3738pub struct EmpyreanTaggedCovariance {
3739 #[doc = " Epoch of this covariance (TDB)."]
3740 pub epoch_mjd_tdb: f64,
3741 #[doc = " Propagated nominal state [x, y, z, vx, vy, vz] (AU, AU/day),\n co-located engine-side. The CORRECTED mean is\n `state + (has_mean_shift_prop ? mean_shift_prop : 0)\n + (has_mean_shift_input ? mean_shift_input : 0)`."]
3742 pub state: [f64; 6usize],
3743 #[doc = " The 6×6 covariance (AU², AU²/day, AU²/day² blocks)."]
3744 pub matrix: [[f64; 6usize]; 6usize],
3745 #[doc = " `EMPYREAN_COVARIANCE_KIND_*`."]
3746 pub kind: u8,
3747 #[doc = " RNG seed — valid iff `has_mc_seed == 1` (kind == MONTE_CARLO)."]
3748 pub mc_seed: u64,
3749 #[doc = " Disambiguates a real `mc_seed == 0` from \"no seed\". 0 on the\n `_cartesian` accessor (MC resolves to an error there)."]
3750 pub has_mc_seed: u8,
3751 #[doc = " Second-order propagation mean shift δμ_prop (zero at t₀).\n Zero-filled when `has_mean_shift_prop == 0`."]
3752 pub mean_shift_prop: [f64; 6usize],
3753 pub has_mean_shift_prop: u8,
3754 #[doc = " OD-estimator mean shift δμ₀ (nonzero at t₀). Zero-filled when\n `has_mean_shift_input == 0` (always 0 on the `_cartesian` accessor)."]
3755 pub mean_shift_input: [f64; 6usize],
3756 pub has_mean_shift_input: u8,
3757 #[doc = " `EMPYREAN_COVARIANCE_QUALITY_*`."]
3758 pub quality: u8,
3759 #[doc = " `min_eig` for INDEFINITE / REPAIRED; `f64::NAN` for\n POSITIVE_DEFINITE. **Read-only provenance** — `isnan`-guard before\n any arithmetic; never feed to a clamp."]
3760 pub quality_min_eig: f64,
3761 #[doc = " `EMPYREAN_REPRESENTATION_*` (always CARTESIAN=0 on this accessor)."]
3762 pub representation: i32,
3763 #[doc = " Frame, same encoding as `EmpyreanPropagatedState.frame`."]
3764 pub frame: i32,
3765 #[doc = " Origin NAIF id, same encoding as `EmpyreanPropagatedState.origin`."]
3766 pub origin: i32,
3767 #[doc = " [A1, A2, A3] non-grav solved flags (0/1). The returned 6×6 is the\n MARGINALIZED state block of a possibly-wider fit."]
3768 pub non_grav: [u8; 3usize],
3769 #[doc = " Thrust Δv segments solved for."]
3770 pub thrust_segments: u32,
3771 #[doc = " `TaggedCovariance::solved_width()` (6 / 9 / 12 / …) — the scalar\n IP consumers key on (6 on this accessor)."]
3772 pub solved_width: u32,
3773 #[doc = " `EMPYREAN_TARGET_FUNCTIONAL_*` (always CARTESIAN_STATE on this accessor)."]
3774 pub target_functional: u8,
3775}
3776#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3777const _: () = {
3778 ["Size of EmpyreanTaggedCovariance"]
3779 [::std::mem::size_of::<EmpyreanTaggedCovariance>() - 520usize];
3780 ["Alignment of EmpyreanTaggedCovariance"]
3781 [::std::mem::align_of::<EmpyreanTaggedCovariance>() - 8usize];
3782 ["Offset of field: EmpyreanTaggedCovariance::epoch_mjd_tdb"]
3783 [::std::mem::offset_of!(EmpyreanTaggedCovariance, epoch_mjd_tdb) - 0usize];
3784 ["Offset of field: EmpyreanTaggedCovariance::state"]
3785 [::std::mem::offset_of!(EmpyreanTaggedCovariance, state) - 8usize];
3786 ["Offset of field: EmpyreanTaggedCovariance::matrix"]
3787 [::std::mem::offset_of!(EmpyreanTaggedCovariance, matrix) - 56usize];
3788 ["Offset of field: EmpyreanTaggedCovariance::kind"]
3789 [::std::mem::offset_of!(EmpyreanTaggedCovariance, kind) - 344usize];
3790 ["Offset of field: EmpyreanTaggedCovariance::mc_seed"]
3791 [::std::mem::offset_of!(EmpyreanTaggedCovariance, mc_seed) - 352usize];
3792 ["Offset of field: EmpyreanTaggedCovariance::has_mc_seed"]
3793 [::std::mem::offset_of!(EmpyreanTaggedCovariance, has_mc_seed) - 360usize];
3794 ["Offset of field: EmpyreanTaggedCovariance::mean_shift_prop"]
3795 [::std::mem::offset_of!(EmpyreanTaggedCovariance, mean_shift_prop) - 368usize];
3796 ["Offset of field: EmpyreanTaggedCovariance::has_mean_shift_prop"]
3797 [::std::mem::offset_of!(EmpyreanTaggedCovariance, has_mean_shift_prop) - 416usize];
3798 ["Offset of field: EmpyreanTaggedCovariance::mean_shift_input"]
3799 [::std::mem::offset_of!(EmpyreanTaggedCovariance, mean_shift_input) - 424usize];
3800 ["Offset of field: EmpyreanTaggedCovariance::has_mean_shift_input"]
3801 [::std::mem::offset_of!(EmpyreanTaggedCovariance, has_mean_shift_input) - 472usize];
3802 ["Offset of field: EmpyreanTaggedCovariance::quality"]
3803 [::std::mem::offset_of!(EmpyreanTaggedCovariance, quality) - 473usize];
3804 ["Offset of field: EmpyreanTaggedCovariance::quality_min_eig"]
3805 [::std::mem::offset_of!(EmpyreanTaggedCovariance, quality_min_eig) - 480usize];
3806 ["Offset of field: EmpyreanTaggedCovariance::representation"]
3807 [::std::mem::offset_of!(EmpyreanTaggedCovariance, representation) - 488usize];
3808 ["Offset of field: EmpyreanTaggedCovariance::frame"]
3809 [::std::mem::offset_of!(EmpyreanTaggedCovariance, frame) - 492usize];
3810 ["Offset of field: EmpyreanTaggedCovariance::origin"]
3811 [::std::mem::offset_of!(EmpyreanTaggedCovariance, origin) - 496usize];
3812 ["Offset of field: EmpyreanTaggedCovariance::non_grav"]
3813 [::std::mem::offset_of!(EmpyreanTaggedCovariance, non_grav) - 500usize];
3814 ["Offset of field: EmpyreanTaggedCovariance::thrust_segments"]
3815 [::std::mem::offset_of!(EmpyreanTaggedCovariance, thrust_segments) - 504usize];
3816 ["Offset of field: EmpyreanTaggedCovariance::solved_width"]
3817 [::std::mem::offset_of!(EmpyreanTaggedCovariance, solved_width) - 508usize];
3818 ["Offset of field: EmpyreanTaggedCovariance::target_functional"]
3819 [::std::mem::offset_of!(EmpyreanTaggedCovariance, target_functional) - 512usize];
3820};
3821#[doc = " Owned series of [`EmpyreanTaggedCovariance`], one entry per output\n epoch. Free with [`empyrean_tagged_covariance_series_free`]."]
3822#[repr(C)]
3823#[derive(Debug, Copy, Clone)]
3824pub struct EmpyreanTaggedCovarianceSeries {
3825 pub entries: *mut EmpyreanTaggedCovariance,
3826 pub num_entries: usize,
3827}
3828#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3829const _: () = {
3830 ["Size of EmpyreanTaggedCovarianceSeries"]
3831 [::std::mem::size_of::<EmpyreanTaggedCovarianceSeries>() - 16usize];
3832 ["Alignment of EmpyreanTaggedCovarianceSeries"]
3833 [::std::mem::align_of::<EmpyreanTaggedCovarianceSeries>() - 8usize];
3834 ["Offset of field: EmpyreanTaggedCovarianceSeries::entries"]
3835 [::std::mem::offset_of!(EmpyreanTaggedCovarianceSeries, entries) - 0usize];
3836 ["Offset of field: EmpyreanTaggedCovarianceSeries::num_entries"]
3837 [::std::mem::offset_of!(EmpyreanTaggedCovarianceSeries, num_entries) - 8usize];
3838};
3839impl Default for EmpyreanTaggedCovarianceSeries {
3840 fn default() -> Self {
3841 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3842 unsafe {
3843 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3844 s.assume_init()
3845 }
3846 }
3847}
3848#[doc = " Opaque handle to an `empyrean_core::determination::Session`.\n\n Owns observations, the mask state, and the fit history. Construct\n with [`empyrean_session_new`]; release with\n [`empyrean_session_free`]. The handle is **not** thread-safe — do\n not share between threads without external synchronization."]
3849pub type EmpyreanSession = Session;
3850#[doc = " Pairwise diagnostic returned by [`empyrean_session_diff`]."]
3851#[repr(C)]
3852#[derive(Debug, Default, Copy, Clone)]
3853pub struct EmpyreanSessionDiff {
3854 #[doc = " Δ reduced χ² (positive ⇒ current fit is worse than prior)."]
3855 pub reduced_chi2_delta: f64,
3856 #[doc = " Δ iteration count."]
3857 pub iterations_delta: i64,
3858 #[doc = " Δ number of observations used (negative ⇒ observations were\n masked between prior and current)."]
3859 pub n_observations_delta: i64,
3860 #[doc = " Final update-norm convergence metric on the current fit."]
3861 pub update_norm_current: f64,
3862 #[doc = " Final update-norm convergence metric on the prior fit."]
3863 pub update_norm_prior: f64,
3864}
3865#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3866const _: () = {
3867 ["Size of EmpyreanSessionDiff"][::std::mem::size_of::<EmpyreanSessionDiff>() - 40usize];
3868 ["Alignment of EmpyreanSessionDiff"][::std::mem::align_of::<EmpyreanSessionDiff>() - 8usize];
3869 ["Offset of field: EmpyreanSessionDiff::reduced_chi2_delta"]
3870 [::std::mem::offset_of!(EmpyreanSessionDiff, reduced_chi2_delta) - 0usize];
3871 ["Offset of field: EmpyreanSessionDiff::iterations_delta"]
3872 [::std::mem::offset_of!(EmpyreanSessionDiff, iterations_delta) - 8usize];
3873 ["Offset of field: EmpyreanSessionDiff::n_observations_delta"]
3874 [::std::mem::offset_of!(EmpyreanSessionDiff, n_observations_delta) - 16usize];
3875 ["Offset of field: EmpyreanSessionDiff::update_norm_current"]
3876 [::std::mem::offset_of!(EmpyreanSessionDiff, update_norm_current) - 24usize];
3877 ["Offset of field: EmpyreanSessionDiff::update_norm_prior"]
3878 [::std::mem::offset_of!(EmpyreanSessionDiff, update_norm_prior) - 32usize];
3879};
3880#[doc = " A single body state for the C API."]
3881#[repr(C)]
3882#[derive(Debug, Default, Copy, Clone)]
3883pub struct EmpyreanState {
3884 #[doc = " Epoch as MJD TDB."]
3885 pub epoch_mjd_tdb: f64,
3886 #[doc = " Position (AU)."]
3887 pub x: f64,
3888 pub y: f64,
3889 pub z: f64,
3890 #[doc = " Velocity (AU/day)."]
3891 pub vx: f64,
3892 pub vy: f64,
3893 pub vz: f64,
3894 #[doc = " Reference frame (EMPYREAN_FRAME_*)."]
3895 pub frame: i32,
3896 #[doc = " Center body NAIF ID."]
3897 pub origin: i32,
3898}
3899#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3900const _: () = {
3901 ["Size of EmpyreanState"][::std::mem::size_of::<EmpyreanState>() - 64usize];
3902 ["Alignment of EmpyreanState"][::std::mem::align_of::<EmpyreanState>() - 8usize];
3903 ["Offset of field: EmpyreanState::epoch_mjd_tdb"]
3904 [::std::mem::offset_of!(EmpyreanState, epoch_mjd_tdb) - 0usize];
3905 ["Offset of field: EmpyreanState::x"][::std::mem::offset_of!(EmpyreanState, x) - 8usize];
3906 ["Offset of field: EmpyreanState::y"][::std::mem::offset_of!(EmpyreanState, y) - 16usize];
3907 ["Offset of field: EmpyreanState::z"][::std::mem::offset_of!(EmpyreanState, z) - 24usize];
3908 ["Offset of field: EmpyreanState::vx"][::std::mem::offset_of!(EmpyreanState, vx) - 32usize];
3909 ["Offset of field: EmpyreanState::vy"][::std::mem::offset_of!(EmpyreanState, vy) - 40usize];
3910 ["Offset of field: EmpyreanState::vz"][::std::mem::offset_of!(EmpyreanState, vz) - 48usize];
3911 ["Offset of field: EmpyreanState::frame"]
3912 [::std::mem::offset_of!(EmpyreanState, frame) - 56usize];
3913 ["Offset of field: EmpyreanState::origin"]
3914 [::std::mem::offset_of!(EmpyreanState, origin) - 60usize];
3915};
3916#[doc = " Result containing an array of body states."]
3917#[repr(C)]
3918#[derive(Debug, Copy, Clone)]
3919pub struct EmpyreanStateResult {
3920 pub states: *mut EmpyreanState,
3921 pub num_states: usize,
3922}
3923#[allow(clippy::unnecessary_operation, clippy::identity_op)]
3924const _: () = {
3925 ["Size of EmpyreanStateResult"][::std::mem::size_of::<EmpyreanStateResult>() - 16usize];
3926 ["Alignment of EmpyreanStateResult"][::std::mem::align_of::<EmpyreanStateResult>() - 8usize];
3927 ["Offset of field: EmpyreanStateResult::states"]
3928 [::std::mem::offset_of!(EmpyreanStateResult, states) - 0usize];
3929 ["Offset of field: EmpyreanStateResult::num_states"]
3930 [::std::mem::offset_of!(EmpyreanStateResult, num_states) - 8usize];
3931};
3932impl Default for EmpyreanStateResult {
3933 fn default() -> Self {
3934 let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
3935 unsafe {
3936 ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
3937 s.assume_init()
3938 }
3939 }
3940}
3941pub struct EmpyreanLib {
3942 __library: ::libloading::Library,
3943 pub empyrean_last_error: unsafe extern "C" fn() -> *const ::std::os::raw::c_char,
3944 pub empyrean_context_new_minimal: unsafe extern "C" fn(
3945 de440_path: *const ::std::os::raw::c_char,
3946 gm_path: *const ::std::os::raw::c_char,
3947 ) -> *mut EmpyreanContext,
3948 pub empyrean_context_with_spk: unsafe extern "C" fn(
3949 ctx: *mut EmpyreanContext,
3950 spk_path: *const ::std::os::raw::c_char,
3951 ) -> i32,
3952 pub empyrean_context_from_data_dir:
3953 unsafe extern "C" fn(data_dir: *const ::std::os::raw::c_char) -> *mut EmpyreanContext,
3954 pub empyrean_context_free: unsafe extern "C" fn(ctx: *mut EmpyreanContext),
3955 pub empyrean_default_data_dir: unsafe extern "C" fn() -> *mut ::std::os::raw::c_char,
3956 pub empyrean_string_free: unsafe extern "C" fn(s: *mut ::std::os::raw::c_char),
3957 pub empyrean_version_string: unsafe extern "C" fn() -> *mut ::std::os::raw::c_char,
3958 pub empyrean_versions: unsafe extern "C" fn(out: *mut EmpyreanVersions) -> i32,
3959 pub empyrean_versions_free: unsafe extern "C" fn(versions: *mut EmpyreanVersions),
3960 pub empyrean_builtsystem_new: unsafe extern "C" fn(
3961 ctx: *const EmpyreanContext,
3962 force_model: i32,
3963 frame: i32,
3964 encounter_timescale_divisor: f64,
3965 out: *mut *mut EmpyreanBuiltSystem,
3966 ) -> i32,
3967 pub empyrean_builtsystem_free: unsafe extern "C" fn(handle: *mut EmpyreanBuiltSystem),
3968 pub empyrean_builtsystem_propagate: unsafe extern "C" fn(
3969 handle: *const EmpyreanBuiltSystem,
3970 ctx: *const EmpyreanContext,
3971 orbits_ptr: *const EmpyreanOrbit,
3972 num_orbits: usize,
3973 times_ptr: *const f64,
3974 num_times: usize,
3975 config: *const EmpyreanPropagationConfig,
3976 result_out: *mut EmpyreanPropagationResult,
3977 ) -> i32,
3978 pub empyrean_builtsystem_generate_ephemeris: unsafe extern "C" fn(
3979 handle: *const EmpyreanBuiltSystem,
3980 ctx: *const EmpyreanContext,
3981 orbits_ptr: *const EmpyreanOrbit,
3982 num_orbits: usize,
3983 observers_ptr: *const EmpyreanObserver,
3984 num_observers: usize,
3985 config: *const EmpyreanEphemerisConfig,
3986 result_out: *mut EmpyreanEphemerisResult,
3987 ) -> i32,
3988 pub empyrean_builtsystem_describe: unsafe extern "C" fn(
3989 handle: *const EmpyreanBuiltSystem,
3990 out: *mut EmpyreanSystemDescription,
3991 ) -> i32,
3992 pub empyrean_builtsystem_description_free:
3993 unsafe extern "C" fn(desc: *mut EmpyreanSystemDescription),
3994 pub empyrean_generate_ephemeris: unsafe extern "C" fn(
3995 ctx: *const EmpyreanContext,
3996 orbits_ptr: *const EmpyreanOrbit,
3997 num_orbits: usize,
3998 observers_ptr: *const EmpyreanObserver,
3999 num_observers: usize,
4000 config: *const EmpyreanEphemerisConfig,
4001 result_out: *mut EmpyreanEphemerisResult,
4002 ) -> i32,
4003 pub empyrean_ephemeris_result_free: unsafe extern "C" fn(result: *mut EmpyreanEphemerisResult),
4004 pub empyrean_compute_impact_probabilities: unsafe extern "C" fn(
4005 ctx: *const EmpyreanContext,
4006 orbits_ptr: *const EmpyreanOrbit,
4007 num_orbits: usize,
4008 end_mjd_tdb: f64,
4009 methods_ptr: *const EmpyreanUncertaintyMethod,
4010 num_methods: usize,
4011 body_filter_naif: *const i32,
4012 num_body_filter: usize,
4013 result_out: *mut EmpyreanImpactProbabilitiesResult,
4014 ) -> i32,
4015 pub empyrean_compute_impact_probabilities_result_free:
4016 unsafe extern "C" fn(result: *mut EmpyreanImpactProbabilitiesResult),
4017 pub empyrean_compute_b_planes: unsafe extern "C" fn(
4018 ctx: *const EmpyreanContext,
4019 orbits_ptr: *const EmpyreanOrbit,
4020 num_orbits: usize,
4021 end_mjd_tdb: f64,
4022 methods_ptr: *const EmpyreanUncertaintyMethod,
4023 num_methods: usize,
4024 body_filter_naif: *const i32,
4025 num_body_filter: usize,
4026 result_out: *mut EmpyreanBPlanesResult,
4027 ) -> i32,
4028 pub empyrean_compute_b_planes_result_free:
4029 unsafe extern "C" fn(result: *mut EmpyreanBPlanesResult),
4030 pub empyrean_orbits_batch_free: unsafe extern "C" fn(batch: *mut EmpyreanOrbitBatch),
4031 pub empyrean_orbits_read_parquet: unsafe extern "C" fn(
4032 path: *const ::std::os::raw::c_char,
4033 out: *mut EmpyreanOrbitBatch,
4034 ) -> i32,
4035 pub empyrean_orbits_write_parquet: unsafe extern "C" fn(
4036 path: *const ::std::os::raw::c_char,
4037 batch: *const EmpyreanOrbitBatch,
4038 ) -> i32,
4039 pub empyrean_orbits_read_json: unsafe extern "C" fn(
4040 path: *const ::std::os::raw::c_char,
4041 out: *mut EmpyreanOrbitBatch,
4042 ) -> i32,
4043 pub empyrean_orbits_write_json: unsafe extern "C" fn(
4044 path: *const ::std::os::raw::c_char,
4045 batch: *const EmpyreanOrbitBatch,
4046 ) -> i32,
4047 pub empyrean_orbits_read_csv: unsafe extern "C" fn(
4048 path: *const ::std::os::raw::c_char,
4049 out: *mut EmpyreanOrbitBatch,
4050 ) -> i32,
4051 pub empyrean_orbits_write_csv: unsafe extern "C" fn(
4052 path: *const ::std::os::raw::c_char,
4053 batch: *const EmpyreanOrbitBatch,
4054 ) -> i32,
4055 pub empyrean_ephemeris_write_parquet: unsafe extern "C" fn(
4056 path: *const ::std::os::raw::c_char,
4057 entries_ptr: *const EmpyreanEphemerisEntry,
4058 num_entries: usize,
4059 ) -> i32,
4060 pub empyrean_ephemeris_write_json: unsafe extern "C" fn(
4061 path: *const ::std::os::raw::c_char,
4062 entries_ptr: *const EmpyreanEphemerisEntry,
4063 num_entries: usize,
4064 ) -> i32,
4065 pub empyrean_ephemeris_write_csv: unsafe extern "C" fn(
4066 path: *const ::std::os::raw::c_char,
4067 entries_ptr: *const EmpyreanEphemerisEntry,
4068 num_entries: usize,
4069 ) -> i32,
4070 pub empyrean_events_write_parquet: unsafe extern "C" fn(
4071 path: *const ::std::os::raw::c_char,
4072 events_ptr: *const EmpyreanEvent,
4073 num_events: usize,
4074 ) -> i32,
4075 pub empyrean_events_write_json: unsafe extern "C" fn(
4076 path: *const ::std::os::raw::c_char,
4077 events_ptr: *const EmpyreanEvent,
4078 num_events: usize,
4079 ) -> i32,
4080 pub empyrean_events_write_csv: unsafe extern "C" fn(
4081 path: *const ::std::os::raw::c_char,
4082 events_ptr: *const EmpyreanEvent,
4083 num_events: usize,
4084 ) -> i32,
4085 pub empyrean_residuals_write_parquet: unsafe extern "C" fn(
4086 path: *const ::std::os::raw::c_char,
4087 obs_ptr: *const EmpyreanObservationResult,
4088 num_obs: usize,
4089 ) -> i32,
4090 pub empyrean_residuals_write_json: unsafe extern "C" fn(
4091 path: *const ::std::os::raw::c_char,
4092 obs_ptr: *const EmpyreanObservationResult,
4093 num_obs: usize,
4094 ) -> i32,
4095 pub empyrean_residuals_write_csv: unsafe extern "C" fn(
4096 path: *const ::std::os::raw::c_char,
4097 obs_ptr: *const EmpyreanObservationResult,
4098 num_obs: usize,
4099 ) -> i32,
4100 pub empyrean_eigenvector_max_6x6: unsafe extern "C" fn(
4101 matrix: *const [[f64; 6usize]; 6usize],
4102 eigenvalue_out: *mut f64,
4103 eigenvector_out: *mut [f64; 6usize],
4104 ) -> i32,
4105 pub empyrean_split_gaussian: unsafe extern "C" fn(
4106 mean: *const [f64; 6usize],
4107 covariance: *const [[f64; 6usize]; 6usize],
4108 k: usize,
4109 weights_out: *mut f64,
4110 means_out: *mut [f64; 6usize],
4111 covariances_out: *mut [[f64; 6usize]; 6usize],
4112 ) -> i32,
4113 pub empyrean_get_observers: unsafe extern "C" fn(
4114 ctx: *const EmpyreanContext,
4115 obs_codes: *const *const ::std::os::raw::c_char,
4116 num_codes: usize,
4117 epochs_mjd_tdb: *const f64,
4118 num_epochs: usize,
4119 result_out: *mut EmpyreanObserverResult,
4120 ) -> i32,
4121 pub empyrean_observer_result_free: unsafe extern "C" fn(result: *mut EmpyreanObserverResult),
4122 pub empyrean_abi_version: unsafe extern "C" fn() -> u32,
4123 pub empyrean_read_ades: unsafe extern "C" fn(
4124 content: *const ::std::os::raw::c_char,
4125 observations_out: *mut *mut EmpyreanObservation,
4126 num_observations_out: *mut usize,
4127 radar_out: *mut *mut EmpyreanRadarObservation,
4128 num_radar_out: *mut usize,
4129 ) -> i32,
4130 pub empyrean_observations_from_array: unsafe extern "C" fn(
4131 input: *const EmpyreanObservation,
4132 num: usize,
4133 out_ptr: *mut *mut EmpyreanObservation,
4134 out_num: *mut usize,
4135 ) -> i32,
4136 pub empyrean_observations_free:
4137 unsafe extern "C" fn(observations: *mut EmpyreanObservation, num: usize),
4138 pub empyrean_radar_observations_from_array: unsafe extern "C" fn(
4139 input: *const EmpyreanRadarObservation,
4140 num: usize,
4141 out_ptr: *mut *mut EmpyreanRadarObservation,
4142 out_num: *mut usize,
4143 ) -> i32,
4144 pub empyrean_radar_observations_free:
4145 unsafe extern "C" fn(observations: *mut EmpyreanRadarObservation, num: usize),
4146 pub empyrean_determine: unsafe extern "C" fn(
4147 ctx: *const EmpyreanContext,
4148 observations: *const EmpyreanObservation,
4149 num_observations: usize,
4150 radar: *const EmpyreanRadarObservation,
4151 num_radar: usize,
4152 initial_orbits: *const EmpyreanOrbit,
4153 num_initial_orbits: usize,
4154 config: *const EmpyreanODConfig,
4155 result_out: *mut EmpyreanODResult,
4156 ) -> i32,
4157 pub empyrean_od_result_free: unsafe extern "C" fn(result: *mut EmpyreanODResult),
4158 pub empyrean_evaluate: unsafe extern "C" fn(
4159 ctx: *const EmpyreanContext,
4160 orbit: *const EmpyreanOrbit,
4161 observations: *const EmpyreanObservation,
4162 num_observations: usize,
4163 config: *const EmpyreanODConfig,
4164 result_out: *mut EmpyreanEvaluateResult,
4165 ) -> i32,
4166 pub empyrean_evaluate_result_free: unsafe extern "C" fn(result: *mut EmpyreanEvaluateResult),
4167 pub empyrean_refine: unsafe extern "C" fn(
4168 ctx: *const EmpyreanContext,
4169 orbit: *const EmpyreanOrbit,
4170 observations: *const EmpyreanObservation,
4171 num_observations: usize,
4172 config: *const EmpyreanODConfig,
4173 result_out: *mut EmpyreanODResult,
4174 ) -> i32,
4175 pub empyrean_evaluate_plan: unsafe extern "C" fn(
4176 ctx: *const EmpyreanContext,
4177 orbit: *const EmpyreanOrbit,
4178 orbit_id: *const ::std::os::raw::c_char,
4179 planned: *const EmpyreanPlannedObservation,
4180 num_planned: usize,
4181 config: *const EmpyreanPlanningConfig,
4182 result_out: *mut EmpyreanPlanResult,
4183 ) -> i32,
4184 pub empyrean_plan_result_free: unsafe extern "C" fn(result: *mut EmpyreanPlanResult),
4185 pub empyrean_propagate: unsafe extern "C" fn(
4186 ctx: *const EmpyreanContext,
4187 orbits_ptr: *const EmpyreanOrbit,
4188 num_orbits: usize,
4189 times_ptr: *const f64,
4190 num_times: usize,
4191 config: *const EmpyreanPropagationConfig,
4192 result_out: *mut EmpyreanPropagationResult,
4193 ) -> i32,
4194 pub empyrean_propagation_result_free:
4195 unsafe extern "C" fn(result: *mut EmpyreanPropagationResult),
4196 pub empyrean_propagation_covariance_series_cartesian: unsafe extern "C" fn(
4197 result: *const EmpyreanPropagationResult,
4198 orbit_index: usize,
4199 out_series: *mut *mut EmpyreanTaggedCovarianceSeries,
4200 ) -> i32,
4201 pub empyrean_propagation_covariance_at_cartesian: unsafe extern "C" fn(
4202 result: *const EmpyreanPropagationResult,
4203 orbit_index: usize,
4204 epoch_index: usize,
4205 out: *mut EmpyreanTaggedCovariance,
4206 ) -> i32,
4207 pub empyrean_tagged_covariance_series_free:
4208 unsafe extern "C" fn(series: *mut EmpyreanTaggedCovarianceSeries),
4209 pub empyrean_query_sbdb: unsafe extern "C" fn(
4210 object_ids: *const *const ::std::os::raw::c_char,
4211 num_object_ids: usize,
4212 cache_dir: *const ::std::os::raw::c_char,
4213 out: *mut EmpyreanOrbitBatch,
4214 ) -> i32,
4215 pub empyrean_query_horizons: unsafe extern "C" fn(
4216 object_ids: *const *const ::std::os::raw::c_char,
4217 num_object_ids: usize,
4218 obs_code: *const ::std::os::raw::c_char,
4219 times_mjd_tdb: *const f64,
4220 num_times: usize,
4221 cache_dir: *const ::std::os::raw::c_char,
4222 out: *mut EmpyreanEphemerisResult,
4223 ) -> i32,
4224 pub empyrean_query_horizons_vectors: unsafe extern "C" fn(
4225 command: *const ::std::os::raw::c_char,
4226 epoch_mjd_tdb: f64,
4227 cache_dir: *const ::std::os::raw::c_char,
4228 out_pos: *mut f64,
4229 out_vel: *mut f64,
4230 ) -> i32,
4231 pub empyrean_query_observations: unsafe extern "C" fn(
4232 designations: *const *const ::std::os::raw::c_char,
4233 num_designations: usize,
4234 cache_dir: *const ::std::os::raw::c_char,
4235 out_ptr: *mut *mut EmpyreanObservation,
4236 out_num: *mut usize,
4237 ) -> i32,
4238 pub empyrean_query_radar: unsafe extern "C" fn(
4239 designations: *const *const ::std::os::raw::c_char,
4240 num_designations: usize,
4241 cache_dir: *const ::std::os::raw::c_char,
4242 out_ptr: *mut *mut EmpyreanRadarObservation,
4243 out_num: *mut usize,
4244 ) -> i32,
4245 pub empyrean_session_new: unsafe extern "C" fn(
4246 observations: *const EmpyreanObservation,
4247 num_observations: usize,
4248 config: *const EmpyreanODConfig,
4249 ) -> *mut EmpyreanSession,
4250 pub empyrean_session_free: unsafe extern "C" fn(session: *mut EmpyreanSession),
4251 pub empyrean_session_n_observations:
4252 unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
4253 pub empyrean_session_n_masked: unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
4254 pub empyrean_session_n_active: unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
4255 pub empyrean_session_mask:
4256 unsafe extern "C" fn(session: *mut EmpyreanSession, idx: usize) -> i32,
4257 pub empyrean_session_unmask:
4258 unsafe extern "C" fn(session: *mut EmpyreanSession, idx: usize) -> i32,
4259 pub empyrean_session_unmask_all: unsafe extern "C" fn(session: *mut EmpyreanSession) -> i32,
4260 pub empyrean_session_is_masked:
4261 unsafe extern "C" fn(session: *const EmpyreanSession, idx: usize) -> u8,
4262 pub empyrean_session_refine: unsafe extern "C" fn(
4263 session: *mut EmpyreanSession,
4264 ctx: *const EmpyreanContext,
4265 result_out: *mut EmpyreanODResult,
4266 ) -> i32,
4267 pub empyrean_session_history_len:
4268 unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
4269 pub empyrean_session_get_history: unsafe extern "C" fn(
4270 session: *const EmpyreanSession,
4271 idx: usize,
4272 result_out: *mut EmpyreanODResult,
4273 ) -> i32,
4274 pub empyrean_session_diff: unsafe extern "C" fn(
4275 session: *const EmpyreanSession,
4276 prior_idx: usize,
4277 diff_out: *mut EmpyreanSessionDiff,
4278 ) -> i32,
4279 pub empyrean_get_states: unsafe extern "C" fn(
4280 ctx: *const EmpyreanContext,
4281 target_naif_id: i32,
4282 center_naif_id: i32,
4283 epochs_mjd_tdb: *const f64,
4284 num_epochs: usize,
4285 frame: i32,
4286 result_out: *mut EmpyreanStateResult,
4287 ) -> i32,
4288 pub empyrean_state_result_free: unsafe extern "C" fn(result: *mut EmpyreanStateResult),
4289 pub empyrean_iso_to_mjd: unsafe extern "C" fn(
4290 iso: *const ::std::os::raw::c_char,
4291 scale: i32,
4292 out_mjd: *mut f64,
4293 ) -> i32,
4294 pub empyrean_mjd_to_iso: unsafe extern "C" fn(
4295 mjd: f64,
4296 scale: i32,
4297 out_buf: *mut ::std::os::raw::c_char,
4298 buf_len: usize,
4299 ) -> i32,
4300 pub empyrean_transform_coordinates: unsafe extern "C" fn(
4301 ctx: *const EmpyreanContext,
4302 input: *const CoordinateState,
4303 target_representation: i32,
4304 target_frame: i32,
4305 target_origin: i32,
4306 output: *mut CoordinateState,
4307 ) -> i32,
4308}
4309impl EmpyreanLib {
4310 pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
4311 where
4312 P: AsRef<::std::ffi::OsStr>,
4313 {
4314 let library = ::libloading::Library::new(path)?;
4315 Self::from_library(library)
4316 }
4317 pub unsafe fn from_library<L>(library: L) -> Result<Self, ::libloading::Error>
4318 where
4319 L: Into<::libloading::Library>,
4320 {
4321 let __library = library.into();
4322 let empyrean_last_error = __library.get(b"empyrean_last_error\0").map(|sym| *sym)?;
4323 let empyrean_context_new_minimal = __library
4324 .get(b"empyrean_context_new_minimal\0")
4325 .map(|sym| *sym)?;
4326 let empyrean_context_with_spk = __library
4327 .get(b"empyrean_context_with_spk\0")
4328 .map(|sym| *sym)?;
4329 let empyrean_context_from_data_dir = __library
4330 .get(b"empyrean_context_from_data_dir\0")
4331 .map(|sym| *sym)?;
4332 let empyrean_context_free = __library.get(b"empyrean_context_free\0").map(|sym| *sym)?;
4333 let empyrean_default_data_dir = __library
4334 .get(b"empyrean_default_data_dir\0")
4335 .map(|sym| *sym)?;
4336 let empyrean_string_free = __library.get(b"empyrean_string_free\0").map(|sym| *sym)?;
4337 let empyrean_version_string = __library
4338 .get(b"empyrean_version_string\0")
4339 .map(|sym| *sym)?;
4340 let empyrean_versions = __library.get(b"empyrean_versions\0").map(|sym| *sym)?;
4341 let empyrean_versions_free = __library.get(b"empyrean_versions_free\0").map(|sym| *sym)?;
4342 let empyrean_builtsystem_new = __library
4343 .get(b"empyrean_builtsystem_new\0")
4344 .map(|sym| *sym)?;
4345 let empyrean_builtsystem_free = __library
4346 .get(b"empyrean_builtsystem_free\0")
4347 .map(|sym| *sym)?;
4348 let empyrean_builtsystem_propagate = __library
4349 .get(b"empyrean_builtsystem_propagate\0")
4350 .map(|sym| *sym)?;
4351 let empyrean_builtsystem_generate_ephemeris = __library
4352 .get(b"empyrean_builtsystem_generate_ephemeris\0")
4353 .map(|sym| *sym)?;
4354 let empyrean_builtsystem_describe = __library
4355 .get(b"empyrean_builtsystem_describe\0")
4356 .map(|sym| *sym)?;
4357 let empyrean_builtsystem_description_free = __library
4358 .get(b"empyrean_builtsystem_description_free\0")
4359 .map(|sym| *sym)?;
4360 let empyrean_generate_ephemeris = __library
4361 .get(b"empyrean_generate_ephemeris\0")
4362 .map(|sym| *sym)?;
4363 let empyrean_ephemeris_result_free = __library
4364 .get(b"empyrean_ephemeris_result_free\0")
4365 .map(|sym| *sym)?;
4366 let empyrean_compute_impact_probabilities = __library
4367 .get(b"empyrean_compute_impact_probabilities\0")
4368 .map(|sym| *sym)?;
4369 let empyrean_compute_impact_probabilities_result_free = __library
4370 .get(b"empyrean_compute_impact_probabilities_result_free\0")
4371 .map(|sym| *sym)?;
4372 let empyrean_compute_b_planes = __library
4373 .get(b"empyrean_compute_b_planes\0")
4374 .map(|sym| *sym)?;
4375 let empyrean_compute_b_planes_result_free = __library
4376 .get(b"empyrean_compute_b_planes_result_free\0")
4377 .map(|sym| *sym)?;
4378 let empyrean_orbits_batch_free = __library
4379 .get(b"empyrean_orbits_batch_free\0")
4380 .map(|sym| *sym)?;
4381 let empyrean_orbits_read_parquet = __library
4382 .get(b"empyrean_orbits_read_parquet\0")
4383 .map(|sym| *sym)?;
4384 let empyrean_orbits_write_parquet = __library
4385 .get(b"empyrean_orbits_write_parquet\0")
4386 .map(|sym| *sym)?;
4387 let empyrean_orbits_read_json = __library
4388 .get(b"empyrean_orbits_read_json\0")
4389 .map(|sym| *sym)?;
4390 let empyrean_orbits_write_json = __library
4391 .get(b"empyrean_orbits_write_json\0")
4392 .map(|sym| *sym)?;
4393 let empyrean_orbits_read_csv = __library
4394 .get(b"empyrean_orbits_read_csv\0")
4395 .map(|sym| *sym)?;
4396 let empyrean_orbits_write_csv = __library
4397 .get(b"empyrean_orbits_write_csv\0")
4398 .map(|sym| *sym)?;
4399 let empyrean_ephemeris_write_parquet = __library
4400 .get(b"empyrean_ephemeris_write_parquet\0")
4401 .map(|sym| *sym)?;
4402 let empyrean_ephemeris_write_json = __library
4403 .get(b"empyrean_ephemeris_write_json\0")
4404 .map(|sym| *sym)?;
4405 let empyrean_ephemeris_write_csv = __library
4406 .get(b"empyrean_ephemeris_write_csv\0")
4407 .map(|sym| *sym)?;
4408 let empyrean_events_write_parquet = __library
4409 .get(b"empyrean_events_write_parquet\0")
4410 .map(|sym| *sym)?;
4411 let empyrean_events_write_json = __library
4412 .get(b"empyrean_events_write_json\0")
4413 .map(|sym| *sym)?;
4414 let empyrean_events_write_csv = __library
4415 .get(b"empyrean_events_write_csv\0")
4416 .map(|sym| *sym)?;
4417 let empyrean_residuals_write_parquet = __library
4418 .get(b"empyrean_residuals_write_parquet\0")
4419 .map(|sym| *sym)?;
4420 let empyrean_residuals_write_json = __library
4421 .get(b"empyrean_residuals_write_json\0")
4422 .map(|sym| *sym)?;
4423 let empyrean_residuals_write_csv = __library
4424 .get(b"empyrean_residuals_write_csv\0")
4425 .map(|sym| *sym)?;
4426 let empyrean_eigenvector_max_6x6 = __library
4427 .get(b"empyrean_eigenvector_max_6x6\0")
4428 .map(|sym| *sym)?;
4429 let empyrean_split_gaussian = __library
4430 .get(b"empyrean_split_gaussian\0")
4431 .map(|sym| *sym)?;
4432 let empyrean_get_observers = __library.get(b"empyrean_get_observers\0").map(|sym| *sym)?;
4433 let empyrean_observer_result_free = __library
4434 .get(b"empyrean_observer_result_free\0")
4435 .map(|sym| *sym)?;
4436 let empyrean_abi_version = __library.get(b"empyrean_abi_version\0").map(|sym| *sym)?;
4437 let empyrean_read_ades = __library.get(b"empyrean_read_ades\0").map(|sym| *sym)?;
4438 let empyrean_observations_from_array = __library
4439 .get(b"empyrean_observations_from_array\0")
4440 .map(|sym| *sym)?;
4441 let empyrean_observations_free = __library
4442 .get(b"empyrean_observations_free\0")
4443 .map(|sym| *sym)?;
4444 let empyrean_radar_observations_from_array = __library
4445 .get(b"empyrean_radar_observations_from_array\0")
4446 .map(|sym| *sym)?;
4447 let empyrean_radar_observations_free = __library
4448 .get(b"empyrean_radar_observations_free\0")
4449 .map(|sym| *sym)?;
4450 let empyrean_determine = __library.get(b"empyrean_determine\0").map(|sym| *sym)?;
4451 let empyrean_od_result_free = __library
4452 .get(b"empyrean_od_result_free\0")
4453 .map(|sym| *sym)?;
4454 let empyrean_evaluate = __library.get(b"empyrean_evaluate\0").map(|sym| *sym)?;
4455 let empyrean_evaluate_result_free = __library
4456 .get(b"empyrean_evaluate_result_free\0")
4457 .map(|sym| *sym)?;
4458 let empyrean_refine = __library.get(b"empyrean_refine\0").map(|sym| *sym)?;
4459 let empyrean_evaluate_plan = __library.get(b"empyrean_evaluate_plan\0").map(|sym| *sym)?;
4460 let empyrean_plan_result_free = __library
4461 .get(b"empyrean_plan_result_free\0")
4462 .map(|sym| *sym)?;
4463 let empyrean_propagate = __library.get(b"empyrean_propagate\0").map(|sym| *sym)?;
4464 let empyrean_propagation_result_free = __library
4465 .get(b"empyrean_propagation_result_free\0")
4466 .map(|sym| *sym)?;
4467 let empyrean_propagation_covariance_series_cartesian = __library
4468 .get(b"empyrean_propagation_covariance_series_cartesian\0")
4469 .map(|sym| *sym)?;
4470 let empyrean_propagation_covariance_at_cartesian = __library
4471 .get(b"empyrean_propagation_covariance_at_cartesian\0")
4472 .map(|sym| *sym)?;
4473 let empyrean_tagged_covariance_series_free = __library
4474 .get(b"empyrean_tagged_covariance_series_free\0")
4475 .map(|sym| *sym)?;
4476 let empyrean_query_sbdb = __library.get(b"empyrean_query_sbdb\0").map(|sym| *sym)?;
4477 let empyrean_query_horizons = __library
4478 .get(b"empyrean_query_horizons\0")
4479 .map(|sym| *sym)?;
4480 let empyrean_query_horizons_vectors = __library
4481 .get(b"empyrean_query_horizons_vectors\0")
4482 .map(|sym| *sym)?;
4483 let empyrean_query_observations = __library
4484 .get(b"empyrean_query_observations\0")
4485 .map(|sym| *sym)?;
4486 let empyrean_query_radar = __library.get(b"empyrean_query_radar\0").map(|sym| *sym)?;
4487 let empyrean_session_new = __library.get(b"empyrean_session_new\0").map(|sym| *sym)?;
4488 let empyrean_session_free = __library.get(b"empyrean_session_free\0").map(|sym| *sym)?;
4489 let empyrean_session_n_observations = __library
4490 .get(b"empyrean_session_n_observations\0")
4491 .map(|sym| *sym)?;
4492 let empyrean_session_n_masked = __library
4493 .get(b"empyrean_session_n_masked\0")
4494 .map(|sym| *sym)?;
4495 let empyrean_session_n_active = __library
4496 .get(b"empyrean_session_n_active\0")
4497 .map(|sym| *sym)?;
4498 let empyrean_session_mask = __library.get(b"empyrean_session_mask\0").map(|sym| *sym)?;
4499 let empyrean_session_unmask = __library
4500 .get(b"empyrean_session_unmask\0")
4501 .map(|sym| *sym)?;
4502 let empyrean_session_unmask_all = __library
4503 .get(b"empyrean_session_unmask_all\0")
4504 .map(|sym| *sym)?;
4505 let empyrean_session_is_masked = __library
4506 .get(b"empyrean_session_is_masked\0")
4507 .map(|sym| *sym)?;
4508 let empyrean_session_refine = __library
4509 .get(b"empyrean_session_refine\0")
4510 .map(|sym| *sym)?;
4511 let empyrean_session_history_len = __library
4512 .get(b"empyrean_session_history_len\0")
4513 .map(|sym| *sym)?;
4514 let empyrean_session_get_history = __library
4515 .get(b"empyrean_session_get_history\0")
4516 .map(|sym| *sym)?;
4517 let empyrean_session_diff = __library.get(b"empyrean_session_diff\0").map(|sym| *sym)?;
4518 let empyrean_get_states = __library.get(b"empyrean_get_states\0").map(|sym| *sym)?;
4519 let empyrean_state_result_free = __library
4520 .get(b"empyrean_state_result_free\0")
4521 .map(|sym| *sym)?;
4522 let empyrean_iso_to_mjd = __library.get(b"empyrean_iso_to_mjd\0").map(|sym| *sym)?;
4523 let empyrean_mjd_to_iso = __library.get(b"empyrean_mjd_to_iso\0").map(|sym| *sym)?;
4524 let empyrean_transform_coordinates = __library
4525 .get(b"empyrean_transform_coordinates\0")
4526 .map(|sym| *sym)?;
4527 Ok(EmpyreanLib {
4528 __library,
4529 empyrean_last_error,
4530 empyrean_context_new_minimal,
4531 empyrean_context_with_spk,
4532 empyrean_context_from_data_dir,
4533 empyrean_context_free,
4534 empyrean_default_data_dir,
4535 empyrean_string_free,
4536 empyrean_version_string,
4537 empyrean_versions,
4538 empyrean_versions_free,
4539 empyrean_builtsystem_new,
4540 empyrean_builtsystem_free,
4541 empyrean_builtsystem_propagate,
4542 empyrean_builtsystem_generate_ephemeris,
4543 empyrean_builtsystem_describe,
4544 empyrean_builtsystem_description_free,
4545 empyrean_generate_ephemeris,
4546 empyrean_ephemeris_result_free,
4547 empyrean_compute_impact_probabilities,
4548 empyrean_compute_impact_probabilities_result_free,
4549 empyrean_compute_b_planes,
4550 empyrean_compute_b_planes_result_free,
4551 empyrean_orbits_batch_free,
4552 empyrean_orbits_read_parquet,
4553 empyrean_orbits_write_parquet,
4554 empyrean_orbits_read_json,
4555 empyrean_orbits_write_json,
4556 empyrean_orbits_read_csv,
4557 empyrean_orbits_write_csv,
4558 empyrean_ephemeris_write_parquet,
4559 empyrean_ephemeris_write_json,
4560 empyrean_ephemeris_write_csv,
4561 empyrean_events_write_parquet,
4562 empyrean_events_write_json,
4563 empyrean_events_write_csv,
4564 empyrean_residuals_write_parquet,
4565 empyrean_residuals_write_json,
4566 empyrean_residuals_write_csv,
4567 empyrean_eigenvector_max_6x6,
4568 empyrean_split_gaussian,
4569 empyrean_get_observers,
4570 empyrean_observer_result_free,
4571 empyrean_abi_version,
4572 empyrean_read_ades,
4573 empyrean_observations_from_array,
4574 empyrean_observations_free,
4575 empyrean_radar_observations_from_array,
4576 empyrean_radar_observations_free,
4577 empyrean_determine,
4578 empyrean_od_result_free,
4579 empyrean_evaluate,
4580 empyrean_evaluate_result_free,
4581 empyrean_refine,
4582 empyrean_evaluate_plan,
4583 empyrean_plan_result_free,
4584 empyrean_propagate,
4585 empyrean_propagation_result_free,
4586 empyrean_propagation_covariance_series_cartesian,
4587 empyrean_propagation_covariance_at_cartesian,
4588 empyrean_tagged_covariance_series_free,
4589 empyrean_query_sbdb,
4590 empyrean_query_horizons,
4591 empyrean_query_horizons_vectors,
4592 empyrean_query_observations,
4593 empyrean_query_radar,
4594 empyrean_session_new,
4595 empyrean_session_free,
4596 empyrean_session_n_observations,
4597 empyrean_session_n_masked,
4598 empyrean_session_n_active,
4599 empyrean_session_mask,
4600 empyrean_session_unmask,
4601 empyrean_session_unmask_all,
4602 empyrean_session_is_masked,
4603 empyrean_session_refine,
4604 empyrean_session_history_len,
4605 empyrean_session_get_history,
4606 empyrean_session_diff,
4607 empyrean_get_states,
4608 empyrean_state_result_free,
4609 empyrean_iso_to_mjd,
4610 empyrean_mjd_to_iso,
4611 empyrean_transform_coordinates,
4612 })
4613 }
4614 #[doc = " Return a pointer to the last error message (thread-local, null-terminated).\n\n The pointer is valid until the next call that sets an error on the same\n thread."]
4615 pub unsafe fn empyrean_last_error(&self) -> *const ::std::os::raw::c_char {
4616 (self.empyrean_last_error)()
4617 }
4618 #[doc = " Create a **minimal** `EmpyreanContext` from a DE440 SPK file and a\n GM TPC file.\n\n Loads ONLY the planetary ephemeris and gravitational parameters —\n no Earth/Moon BPC kernels, no SB441-N16 asteroid perturbers, no\n MPC observatory codes, no Earth gravity field. This is sufficient\n for coordinate transforms and basic propagation under the\n `Approximate` force model, but is **not** enough for production\n orbit propagation, orbit determination, or topocentric ephemeris\n generation. Most callers should use\n [`empyrean_context_from_data_dir`] instead, which loads the full\n Standard-tier kernel set (downloading any missing files).\n\n Use [`empyrean_context_with_spk`] to chain additional SPK kernels\n (e.g. SB441-N16) onto a context built by this function.\n\n Returns a heap-allocated pointer on success, or null on error.\n Call `empyrean_last_error()` to retrieve the error message when null is\n returned. The caller owns the returned pointer and must free it with\n `empyrean_context_free()`."]
4619 pub unsafe fn empyrean_context_new_minimal(
4620 &self,
4621 de440_path: *const ::std::os::raw::c_char,
4622 gm_path: *const ::std::os::raw::c_char,
4623 ) -> *mut EmpyreanContext {
4624 (self.empyrean_context_new_minimal)(de440_path, gm_path)
4625 }
4626 #[doc = " Load an additional SPK kernel into an existing context, in place.\n\n Useful for layering SB441-N16 asteroid perturbers or spacecraft\n SPK kernels (JWST, Gaia, custom probes) on top of a context built\n by [`empyrean_context_new_minimal`] or [`empyrean_context_from_data_dir`].\n The merged context picks up the new kernel's body coverage on top\n of what was already loaded.\n\n Returns 0 on success; negative error code on failure. The context\n pointer remains valid and unchanged when this function returns\n non-zero — failure does not invalidate `ctx`."]
4627 pub unsafe fn empyrean_context_with_spk(
4628 &self,
4629 ctx: *mut EmpyreanContext,
4630 spk_path: *const ::std::os::raw::c_char,
4631 ) -> i32 {
4632 (self.empyrean_context_with_spk)(ctx, spk_path)
4633 }
4634 #[doc = " Create a new `EmpyreanContext` from a data directory.\n\n Loads the full Standard-tier kernel set (DE440, SB441-N16, Earth/Moon\n BPCs, GM, MPC observatory codes) from `data_dir`, downloading any\n missing files. Pass null for `data_dir` to use the platform data\n directory (`~/.local/share/empyrean/data` on Linux,\n `~/Library/Application Support/empyrean/data` on macOS).\n\n Returns a heap-allocated pointer on success, or null on error.\n Call `empyrean_last_error()` to retrieve the error message when null is\n returned. The caller owns the returned pointer and must free it with\n `empyrean_context_free()`."]
4635 pub unsafe fn empyrean_context_from_data_dir(
4636 &self,
4637 data_dir: *const ::std::os::raw::c_char,
4638 ) -> *mut EmpyreanContext {
4639 (self.empyrean_context_from_data_dir)(data_dir)
4640 }
4641 #[doc = " Free an `EmpyreanContext` previously returned by `empyrean_context_new()`.\n\n Passing null is a no-op."]
4642 pub unsafe fn empyrean_context_free(&self, ctx: *mut EmpyreanContext) {
4643 (self.empyrean_context_free)(ctx)
4644 }
4645 #[doc = " Return the platform XDG-compliant default data directory as a\n heap-allocated, NUL-terminated UTF-8 string.\n\n Mirrors villeneuve's [`DataManager::new`] resolution: honors\n `EMPYREAN_DATA_DIR` first, then falls back to `dirs::data_dir()` —\n `~/.local/share/empyrean/data/` on Linux, `~/Library/Application\n Support/empyrean/data/` on macOS, `%APPDATA%\\empyrean\\data\\` on\n Windows. Cheap (no filesystem I/O).\n\n Returns null on failure (non-UTF-8 path, NUL byte in path, panic).\n Call `empyrean_last_error()` for details.\n\n **The caller owns the returned pointer and must release it with\n [`empyrean_string_free`].**"]
4646 pub unsafe fn empyrean_default_data_dir(&self) -> *mut ::std::os::raw::c_char {
4647 (self.empyrean_default_data_dir)()
4648 }
4649 #[doc = " Free a string returned by an empyrean C API function (e.g.,\n [`empyrean_default_data_dir`], [`empyrean_version_string`]).\n\n Passing null is a no-op. Passing any pointer not obtained from an\n empyrean string-returning function is undefined behavior."]
4650 pub unsafe fn empyrean_string_free(&self, s: *mut ::std::os::raw::c_char) {
4651 (self.empyrean_string_free)(s)
4652 }
4653 #[doc = " Multi-line version report — `empyrean-core <ver>\\nvilleneuve <ver>\\n…`.\n\n Mirrors [`empyrean_core::version_string`]. Useful for `--version`-style\n output and for verifying the build provenance of a deployed cdylib.\n Returns null on allocation failure (extremely unlikely — the strings\n are short and `&'static` underneath); call `empyrean_last_error()` if\n it does.\n\n **The caller owns the returned pointer and must release it with\n [`empyrean_string_free`].**"]
4654 pub unsafe fn empyrean_version_string(&self) -> *mut ::std::os::raw::c_char {
4655 (self.empyrean_version_string)()
4656 }
4657 #[doc = " Populate `out` with the per-crate versions of the empyrean stack.\n\n Returns 0 on success, non-zero on failure (`empyrean_last_error()`\n has the details). On failure `out` is left zero-initialized — no\n allocation needs freeing.\n\n **The caller owns the strings inside `out` and must release the\n whole struct with [`empyrean_versions_free`] when done.**"]
4658 pub unsafe fn empyrean_versions(&self, out: *mut EmpyreanVersions) -> i32 {
4659 (self.empyrean_versions)(out)
4660 }
4661 #[doc = " Free the version strings inside `versions` (each was heap-allocated\n by a previous successful [`empyrean_versions`] call). After this\n returns, `versions` itself is zero-initialized — safe to drop on\n the caller's stack.\n\n Passing null is a no-op. Calling this twice on the same struct, or\n passing a struct that wasn't populated by [`empyrean_versions`], is\n undefined behavior."]
4662 pub unsafe fn empyrean_versions_free(&self, versions: *mut EmpyreanVersions) {
4663 (self.empyrean_versions_free)(versions)
4664 }
4665 #[doc = " Assemble a reusable force-model handle for `(force_model, frame)` from\n `ctx`, freezing `encounter_timescale_divisor` into its key.\n\n - `force_model`: tier code (0=Approximate, 1=Basic, 2=Standard).\n - `frame`: output/integration frame code (0=ICRF, 1=EclipticJ2000, 2=ITRF93).\n - `encounter_timescale_divisor`: pass `0.0` to freeze the engine default;\n any positive value freezes that divisor into the key *before* it is\n used to validate calls.\n - `out`: receives the heap-allocated handle on success.\n\n The handle snapshots `ctx`'s kernel manifest at construction so\n [`empyrean_builtsystem_describe`] is self-contained. After you load any\n additional kernel into `ctx`, rebuild the handle — a stale handle is\n rejected loudly by every forward-model call, never silently reused.\n\n Returns [`EMPYREAN_BUILTSYSTEM_OK`] on success; on error, `out` is left\n untouched and `empyrean_last_error()` carries the message. The caller\n owns the returned handle and must free it with\n [`empyrean_builtsystem_free`]."]
4666 pub unsafe fn empyrean_builtsystem_new(
4667 &self,
4668 ctx: *const EmpyreanContext,
4669 force_model: i32,
4670 frame: i32,
4671 encounter_timescale_divisor: f64,
4672 out: *mut *mut EmpyreanBuiltSystem,
4673 ) -> i32 {
4674 (self.empyrean_builtsystem_new)(ctx, force_model, frame, encounter_timescale_divisor, out)
4675 }
4676 #[doc = " Free a handle previously returned by [`empyrean_builtsystem_new`].\n Passing null is a no-op."]
4677 pub unsafe fn empyrean_builtsystem_free(&self, handle: *mut EmpyreanBuiltSystem) {
4678 (self.empyrean_builtsystem_free)(handle)
4679 }
4680 #[doc = " Propagate `orbits` to `times` through the pre-built handle.\n\n Signature parallels the one-shot\n [`empyrean_propagate`](crate::propagate::empyrean_propagate) but takes\n `(handle, ctx, ...)`. Before dispatch the identity guard runs: the handle\n must have been built from `ctx`'s ephemeris data\n ([`EMPYREAN_BUILTSYSTEM_DATA_MISMATCH`]); the config must match the frozen\n key ([`EMPYREAN_BUILTSYSTEM_KEY_MISMATCH_FRAME`] /\n `_FORCE_MODEL` / `_DIVISOR`); and the data must be unmutated since build\n ([`EMPYREAN_BUILTSYSTEM_STALE`]). On pass, the result is bit-identical to\n the one-shot with the same config.\n\n On success populates `result_out`; free it with\n [`empyrean_propagation_result_free`](crate::propagate::empyrean_propagation_result_free)."]
4681 pub unsafe fn empyrean_builtsystem_propagate(
4682 &self,
4683 handle: *const EmpyreanBuiltSystem,
4684 ctx: *const EmpyreanContext,
4685 orbits_ptr: *const EmpyreanOrbit,
4686 num_orbits: usize,
4687 times_ptr: *const f64,
4688 num_times: usize,
4689 config: *const EmpyreanPropagationConfig,
4690 result_out: *mut EmpyreanPropagationResult,
4691 ) -> i32 {
4692 (self.empyrean_builtsystem_propagate)(
4693 handle, ctx, orbits_ptr, num_orbits, times_ptr, num_times, config, result_out,
4694 )
4695 }
4696 #[doc = " Generate predicted ephemeris for `orbits` and `observers` through the\n pre-built handle.\n\n Signature parallels the one-shot\n [`empyrean_generate_ephemeris`](crate::ephemeris::empyrean_generate_ephemeris)\n but takes `(handle, ctx, ...)`. Runs the same identity guard as\n [`empyrean_builtsystem_propagate`] before dispatch; on pass the result is\n bit-identical to the one-shot. Note the C-ABI ephemeris config carries no\n divisor knob, so a handle frozen at a non-default divisor is rejected here\n with [`EMPYREAN_BUILTSYSTEM_KEY_MISMATCH_DIVISOR`] rather than served under\n the wrong dynamics — build the handle with the default divisor for\n ephemeris reuse.\n\n On success populates `result_out`; free it with\n [`empyrean_ephemeris_result_free`](crate::ephemeris::empyrean_ephemeris_result_free)."]
4697 pub unsafe fn empyrean_builtsystem_generate_ephemeris(
4698 &self,
4699 handle: *const EmpyreanBuiltSystem,
4700 ctx: *const EmpyreanContext,
4701 orbits_ptr: *const EmpyreanOrbit,
4702 num_orbits: usize,
4703 observers_ptr: *const EmpyreanObserver,
4704 num_observers: usize,
4705 config: *const EmpyreanEphemerisConfig,
4706 result_out: *mut EmpyreanEphemerisResult,
4707 ) -> i32 {
4708 (self.empyrean_builtsystem_generate_ephemeris)(
4709 handle,
4710 ctx,
4711 orbits_ptr,
4712 num_orbits,
4713 observers_ptr,
4714 num_observers,
4715 config,
4716 result_out,
4717 )
4718 }
4719 #[doc = " Populate `out` with a full reproducibility summary of the handle's frozen\n force model and its captured kernel manifest.\n\n Every field is populated from the system description and the manifest\n snapshot — no field is left defaulted. Returns\n [`EMPYREAN_BUILTSYSTEM_OK`] on success. The caller owns the heap arrays\n inside `out` and must release them with\n [`empyrean_builtsystem_description_free`]."]
4720 pub unsafe fn empyrean_builtsystem_describe(
4721 &self,
4722 handle: *const EmpyreanBuiltSystem,
4723 out: *mut EmpyreanSystemDescription,
4724 ) -> i32 {
4725 (self.empyrean_builtsystem_describe)(handle, out)
4726 }
4727 #[doc = " Free the heap arrays inside a description populated by\n [`empyrean_builtsystem_describe`] (the perturber-id array and the kernel\n records with their C strings). After this returns `desc` is\n zero-initialized — safe to drop on the caller's stack. Passing null is a\n no-op."]
4728 pub unsafe fn empyrean_builtsystem_description_free(
4729 &self,
4730 desc: *mut EmpyreanSystemDescription,
4731 ) {
4732 (self.empyrean_builtsystem_description_free)(desc)
4733 }
4734 #[doc = " Generate predicted ephemeris for orbits and observers.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with ephemeris entries:\n `num_orbits * num_observers` rows, orbit-major, and within each orbit\n in **observer-input order** (sensitivity rows follow the same order).\n Each observer carries its own epoch, so positional pairing against\n the input observers is safe within an orbit block.\n The caller must free the result with `empyrean_ephemeris_result_free()`."]
4735 pub unsafe fn empyrean_generate_ephemeris(
4736 &self,
4737 ctx: *const EmpyreanContext,
4738 orbits_ptr: *const EmpyreanOrbit,
4739 num_orbits: usize,
4740 observers_ptr: *const EmpyreanObserver,
4741 num_observers: usize,
4742 config: *const EmpyreanEphemerisConfig,
4743 result_out: *mut EmpyreanEphemerisResult,
4744 ) -> i32 {
4745 (self.empyrean_generate_ephemeris)(
4746 ctx,
4747 orbits_ptr,
4748 num_orbits,
4749 observers_ptr,
4750 num_observers,
4751 config,
4752 result_out,
4753 )
4754 }
4755 #[doc = " Free an ephemeris result previously returned by `empyrean_generate_ephemeris()`."]
4756 pub unsafe fn empyrean_ephemeris_result_free(&self, result: *mut EmpyreanEphemerisResult) {
4757 (self.empyrean_ephemeris_result_free)(result)
4758 }
4759 #[doc = " Run [`empyrean_core::impact::compute_impact_probabilities`] over a\n caller-supplied set of [`UncertaintyMethod`] variants and return\n the flattened IP records tagged by method.\n\n Caller is responsible for freeing the result via\n [`empyrean_compute_impact_probabilities_result_free`].\n\n # Returns\n `0` on success, negative on failure (see [`crate::set_last_error`]).\n\n # Safety\n All non-null pointer arguments must point to valid arrays of the\n indicated length for the duration of the call. The output struct\n is allocated by the caller; pointer fields inside it are allocated\n here and owned by the result."]
4760 pub unsafe fn empyrean_compute_impact_probabilities(
4761 &self,
4762 ctx: *const EmpyreanContext,
4763 orbits_ptr: *const EmpyreanOrbit,
4764 num_orbits: usize,
4765 end_mjd_tdb: f64,
4766 methods_ptr: *const EmpyreanUncertaintyMethod,
4767 num_methods: usize,
4768 body_filter_naif: *const i32,
4769 num_body_filter: usize,
4770 result_out: *mut EmpyreanImpactProbabilitiesResult,
4771 ) -> i32 {
4772 (self.empyrean_compute_impact_probabilities)(
4773 ctx,
4774 orbits_ptr,
4775 num_orbits,
4776 end_mjd_tdb,
4777 methods_ptr,
4778 num_methods,
4779 body_filter_naif,
4780 num_body_filter,
4781 result_out,
4782 )
4783 }
4784 #[doc = " Free the records array allocated by\n [`empyrean_compute_impact_probabilities`]. After calling, the\n struct's `records` is reset to null and `num_records` to 0."]
4785 pub unsafe fn empyrean_compute_impact_probabilities_result_free(
4786 &self,
4787 result: *mut EmpyreanImpactProbabilitiesResult,
4788 ) {
4789 (self.empyrean_compute_impact_probabilities_result_free)(result)
4790 }
4791 #[doc = " Run [`empyrean_core::impact::compute_b_planes`] over a caller-\n supplied set of [`UncertaintyMethod`] variants and return the\n flattened B-plane records tagged by method.\n\n Caller is responsible for freeing the result via\n [`empyrean_compute_b_planes_result_free`].\n\n # Safety\n Same contract as\n [`empyrean_compute_impact_probabilities`]."]
4792 pub unsafe fn empyrean_compute_b_planes(
4793 &self,
4794 ctx: *const EmpyreanContext,
4795 orbits_ptr: *const EmpyreanOrbit,
4796 num_orbits: usize,
4797 end_mjd_tdb: f64,
4798 methods_ptr: *const EmpyreanUncertaintyMethod,
4799 num_methods: usize,
4800 body_filter_naif: *const i32,
4801 num_body_filter: usize,
4802 result_out: *mut EmpyreanBPlanesResult,
4803 ) -> i32 {
4804 (self.empyrean_compute_b_planes)(
4805 ctx,
4806 orbits_ptr,
4807 num_orbits,
4808 end_mjd_tdb,
4809 methods_ptr,
4810 num_methods,
4811 body_filter_naif,
4812 num_body_filter,
4813 result_out,
4814 )
4815 }
4816 #[doc = " Free the records array allocated by [`empyrean_compute_b_planes`]."]
4817 pub unsafe fn empyrean_compute_b_planes_result_free(&self, result: *mut EmpyreanBPlanesResult) {
4818 (self.empyrean_compute_b_planes_result_free)(result)
4819 }
4820 #[doc = " Free a batch previously returned by an `empyrean_orbits_read_*`\n function. Passing null is a no-op."]
4821 pub unsafe fn empyrean_orbits_batch_free(&self, batch: *mut EmpyreanOrbitBatch) {
4822 (self.empyrean_orbits_batch_free)(batch)
4823 }
4824 #[doc = " Read an orbits parquet file. Caller frees the result with\n [`empyrean_orbits_batch_free`]."]
4825 pub unsafe fn empyrean_orbits_read_parquet(
4826 &self,
4827 path: *const ::std::os::raw::c_char,
4828 out: *mut EmpyreanOrbitBatch,
4829 ) -> i32 {
4830 (self.empyrean_orbits_read_parquet)(path, out)
4831 }
4832 #[doc = " Write an orbit batch to a parquet file."]
4833 pub unsafe fn empyrean_orbits_write_parquet(
4834 &self,
4835 path: *const ::std::os::raw::c_char,
4836 batch: *const EmpyreanOrbitBatch,
4837 ) -> i32 {
4838 (self.empyrean_orbits_write_parquet)(path, batch)
4839 }
4840 #[doc = " Read an orbits JSON file (array of orbit-row objects). Caller frees\n with [`empyrean_orbits_batch_free`]."]
4841 pub unsafe fn empyrean_orbits_read_json(
4842 &self,
4843 path: *const ::std::os::raw::c_char,
4844 out: *mut EmpyreanOrbitBatch,
4845 ) -> i32 {
4846 (self.empyrean_orbits_read_json)(path, out)
4847 }
4848 #[doc = " Write an orbit batch to JSON."]
4849 pub unsafe fn empyrean_orbits_write_json(
4850 &self,
4851 path: *const ::std::os::raw::c_char,
4852 batch: *const EmpyreanOrbitBatch,
4853 ) -> i32 {
4854 (self.empyrean_orbits_write_json)(path, batch)
4855 }
4856 #[doc = " Read an orbits CSV file.\n\n CSV does not carry covariance (use parquet for covariance round-trip)."]
4857 pub unsafe fn empyrean_orbits_read_csv(
4858 &self,
4859 path: *const ::std::os::raw::c_char,
4860 out: *mut EmpyreanOrbitBatch,
4861 ) -> i32 {
4862 (self.empyrean_orbits_read_csv)(path, out)
4863 }
4864 #[doc = " Write an orbit batch to CSV."]
4865 pub unsafe fn empyrean_orbits_write_csv(
4866 &self,
4867 path: *const ::std::os::raw::c_char,
4868 batch: *const EmpyreanOrbitBatch,
4869 ) -> i32 {
4870 (self.empyrean_orbits_write_csv)(path, batch)
4871 }
4872 #[doc = " Write ephemeris entries to parquet using the villeneuve schema."]
4873 pub unsafe fn empyrean_ephemeris_write_parquet(
4874 &self,
4875 path: *const ::std::os::raw::c_char,
4876 entries_ptr: *const EmpyreanEphemerisEntry,
4877 num_entries: usize,
4878 ) -> i32 {
4879 (self.empyrean_ephemeris_write_parquet)(path, entries_ptr, num_entries)
4880 }
4881 #[doc = " Write ephemeris entries to JSON."]
4882 pub unsafe fn empyrean_ephemeris_write_json(
4883 &self,
4884 path: *const ::std::os::raw::c_char,
4885 entries_ptr: *const EmpyreanEphemerisEntry,
4886 num_entries: usize,
4887 ) -> i32 {
4888 (self.empyrean_ephemeris_write_json)(path, entries_ptr, num_entries)
4889 }
4890 #[doc = " Write ephemeris entries to CSV."]
4891 pub unsafe fn empyrean_ephemeris_write_csv(
4892 &self,
4893 path: *const ::std::os::raw::c_char,
4894 entries_ptr: *const EmpyreanEphemerisEntry,
4895 num_entries: usize,
4896 ) -> i32 {
4897 (self.empyrean_ephemeris_write_csv)(path, entries_ptr, num_entries)
4898 }
4899 #[doc = " Write events to parquet."]
4900 pub unsafe fn empyrean_events_write_parquet(
4901 &self,
4902 path: *const ::std::os::raw::c_char,
4903 events_ptr: *const EmpyreanEvent,
4904 num_events: usize,
4905 ) -> i32 {
4906 (self.empyrean_events_write_parquet)(path, events_ptr, num_events)
4907 }
4908 #[doc = " Write events to JSON."]
4909 pub unsafe fn empyrean_events_write_json(
4910 &self,
4911 path: *const ::std::os::raw::c_char,
4912 events_ptr: *const EmpyreanEvent,
4913 num_events: usize,
4914 ) -> i32 {
4915 (self.empyrean_events_write_json)(path, events_ptr, num_events)
4916 }
4917 #[doc = " Write events to CSV."]
4918 pub unsafe fn empyrean_events_write_csv(
4919 &self,
4920 path: *const ::std::os::raw::c_char,
4921 events_ptr: *const EmpyreanEvent,
4922 num_events: usize,
4923 ) -> i32 {
4924 (self.empyrean_events_write_csv)(path, events_ptr, num_events)
4925 }
4926 #[doc = " Write OD residuals to parquet."]
4927 pub unsafe fn empyrean_residuals_write_parquet(
4928 &self,
4929 path: *const ::std::os::raw::c_char,
4930 obs_ptr: *const EmpyreanObservationResult,
4931 num_obs: usize,
4932 ) -> i32 {
4933 (self.empyrean_residuals_write_parquet)(path, obs_ptr, num_obs)
4934 }
4935 #[doc = " Write OD residuals to JSON."]
4936 pub unsafe fn empyrean_residuals_write_json(
4937 &self,
4938 path: *const ::std::os::raw::c_char,
4939 obs_ptr: *const EmpyreanObservationResult,
4940 num_obs: usize,
4941 ) -> i32 {
4942 (self.empyrean_residuals_write_json)(path, obs_ptr, num_obs)
4943 }
4944 #[doc = " Write OD residuals to CSV."]
4945 pub unsafe fn empyrean_residuals_write_csv(
4946 &self,
4947 path: *const ::std::os::raw::c_char,
4948 obs_ptr: *const EmpyreanObservationResult,
4949 num_obs: usize,
4950 ) -> i32 {
4951 (self.empyrean_residuals_write_csv)(path, obs_ptr, num_obs)
4952 }
4953 #[doc = " Find the dominant eigenvalue and eigenvector of a 6x6 symmetric matrix.\n\n Returns 0 on success. `eigenvalue_out` receives the eigenvalue,\n `eigenvector_out` receives the 6-element eigenvector."]
4954 pub unsafe fn empyrean_eigenvector_max_6x6(
4955 &self,
4956 matrix: *const [[f64; 6usize]; 6usize],
4957 eigenvalue_out: *mut f64,
4958 eigenvector_out: *mut [f64; 6usize],
4959 ) -> i32 {
4960 (self.empyrean_eigenvector_max_6x6)(matrix, eigenvalue_out, eigenvector_out)
4961 }
4962 #[doc = " Split a 6D Gaussian into K weighted components along the dominant\n eigenvector of the covariance.\n\n `weights_out`, `means_out`, `covariances_out` must point to arrays\n of size K, K×6, and K×6×6 respectively. Returns 0 on success."]
4963 pub unsafe fn empyrean_split_gaussian(
4964 &self,
4965 mean: *const [f64; 6usize],
4966 covariance: *const [[f64; 6usize]; 6usize],
4967 k: usize,
4968 weights_out: *mut f64,
4969 means_out: *mut [f64; 6usize],
4970 covariances_out: *mut [[f64; 6usize]; 6usize],
4971 ) -> i32 {
4972 (self.empyrean_split_gaussian)(mean, covariance, k, weights_out, means_out, covariances_out)
4973 }
4974 #[doc = " Compute observer states for given observatory codes and epochs.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with observer states.\n The caller must free the result with `empyrean_observer_result_free()`."]
4975 pub unsafe fn empyrean_get_observers(
4976 &self,
4977 ctx: *const EmpyreanContext,
4978 obs_codes: *const *const ::std::os::raw::c_char,
4979 num_codes: usize,
4980 epochs_mjd_tdb: *const f64,
4981 num_epochs: usize,
4982 result_out: *mut EmpyreanObserverResult,
4983 ) -> i32 {
4984 (self.empyrean_get_observers)(
4985 ctx,
4986 obs_codes,
4987 num_codes,
4988 epochs_mjd_tdb,
4989 num_epochs,
4990 result_out,
4991 )
4992 }
4993 #[doc = " Free an observer result previously returned by `empyrean_get_observers()`.\n\n Passing a zeroed/null result is a no-op."]
4994 pub unsafe fn empyrean_observer_result_free(&self, result: *mut EmpyreanObserverResult) {
4995 (self.empyrean_observer_result_free)(result)
4996 }
4997 #[doc = " Runtime accessor for [`EMPYREAN_ABI_VERSION`] — lets a dynamically\n linked consumer confirm the loaded library's frozen-shape contract\n matches what it compiled against."]
4998 pub unsafe fn empyrean_abi_version(&self) -> u32 {
4999 (self.empyrean_abi_version)()
5000 }
5001 #[doc = " Read ADES PSV / MPC80 data from a string and pack into the C array.\n\n `path_or_content` is a null-terminated UTF-8 string with the ADES\n content directly (not a file path)."]
5002 pub unsafe fn empyrean_read_ades(
5003 &self,
5004 content: *const ::std::os::raw::c_char,
5005 observations_out: *mut *mut EmpyreanObservation,
5006 num_observations_out: *mut usize,
5007 radar_out: *mut *mut EmpyreanRadarObservation,
5008 num_radar_out: *mut usize,
5009 ) -> i32 {
5010 (self.empyrean_read_ades)(
5011 content,
5012 observations_out,
5013 num_observations_out,
5014 radar_out,
5015 num_radar_out,
5016 )
5017 }
5018 #[doc = " Free an observation array previously returned by `empyrean_read_ades()`.\n Copy a caller-owned array of [`EmpyreanObservation`] into a fresh\n allocation that matches the layout produced by\n [`empyrean_read_ades`].\n\n The strings on the input observations (`perm_id` / `prov_id` /\n `obs_time`) are duplicated into freshly-allocated `CString`s so the\n returned array owns its own memory independent of the input.\n\n On success populates `*out_ptr` with the new array and `*out_num`\n with its length, both freeable with [`empyrean_observations_free`].\n\n Returns 0 on success; negative error code on failure."]
5019 pub unsafe fn empyrean_observations_from_array(
5020 &self,
5021 input: *const EmpyreanObservation,
5022 num: usize,
5023 out_ptr: *mut *mut EmpyreanObservation,
5024 out_num: *mut usize,
5025 ) -> i32 {
5026 (self.empyrean_observations_from_array)(input, num, out_ptr, out_num)
5027 }
5028 pub unsafe fn empyrean_observations_free(
5029 &self,
5030 observations: *mut EmpyreanObservation,
5031 num: usize,
5032 ) {
5033 (self.empyrean_observations_free)(observations, num)
5034 }
5035 #[doc = " Copy a caller-owned array of [`EmpyreanRadarObservation`] into a fresh\n allocation matching the layout produced by [`empyrean_read_ades`].\n\n The nullable `*mut c_char` fields (`perm_id` / `prov_id` / `trk_sub` /\n `obs_time` / `remarks`) are duplicated into freshly-allocated\n `CString`s so the returned array owns its own memory independent of the\n input. All scalar fields (including the ADES-native delay/Doppler\n values) are copied verbatim — no unit conversion, nothing zeroed.\n\n On success populates `*out_ptr` with the new array and `*out_num` with\n its length, both freeable with [`empyrean_radar_observations_free`].\n\n Returns 0 on success; negative error code on failure."]
5036 pub unsafe fn empyrean_radar_observations_from_array(
5037 &self,
5038 input: *const EmpyreanRadarObservation,
5039 num: usize,
5040 out_ptr: *mut *mut EmpyreanRadarObservation,
5041 out_num: *mut usize,
5042 ) -> i32 {
5043 (self.empyrean_radar_observations_from_array)(input, num, out_ptr, out_num)
5044 }
5045 #[doc = " Free a radar observation array previously returned by\n [`empyrean_read_ades`] or [`empyrean_radar_observations_from_array`]."]
5046 pub unsafe fn empyrean_radar_observations_free(
5047 &self,
5048 observations: *mut EmpyreanRadarObservation,
5049 num: usize,
5050 ) {
5051 (self.empyrean_radar_observations_free)(observations, num)
5052 }
5053 #[doc = " Run the full orbit determination pipeline.\n\n When `num_initial_orbits > 0`, the supplied orbits are used as DC\n seeds (one per ADES object_id encountered in `observations`,\n matched by orbit index). Pass `null, 0` to let the IOD pipeline\n produce its own seeds."]
5054 pub unsafe fn empyrean_determine(
5055 &self,
5056 ctx: *const EmpyreanContext,
5057 observations: *const EmpyreanObservation,
5058 num_observations: usize,
5059 radar: *const EmpyreanRadarObservation,
5060 num_radar: usize,
5061 initial_orbits: *const EmpyreanOrbit,
5062 num_initial_orbits: usize,
5063 config: *const EmpyreanODConfig,
5064 result_out: *mut EmpyreanODResult,
5065 ) -> i32 {
5066 (self.empyrean_determine)(
5067 ctx,
5068 observations,
5069 num_observations,
5070 radar,
5071 num_radar,
5072 initial_orbits,
5073 num_initial_orbits,
5074 config,
5075 result_out,
5076 )
5077 }
5078 #[doc = " Free an OD result previously returned by `empyrean_determine()` or `empyrean_refine()`."]
5079 pub unsafe fn empyrean_od_result_free(&self, result: *mut EmpyreanODResult) {
5080 (self.empyrean_od_result_free)(result)
5081 }
5082 #[doc = " Evaluate residuals for a single orbit against observations."]
5083 pub unsafe fn empyrean_evaluate(
5084 &self,
5085 ctx: *const EmpyreanContext,
5086 orbit: *const EmpyreanOrbit,
5087 observations: *const EmpyreanObservation,
5088 num_observations: usize,
5089 config: *const EmpyreanODConfig,
5090 result_out: *mut EmpyreanEvaluateResult,
5091 ) -> i32 {
5092 (self.empyrean_evaluate)(
5093 ctx,
5094 orbit,
5095 observations,
5096 num_observations,
5097 config,
5098 result_out,
5099 )
5100 }
5101 #[doc = " Free an evaluate result previously returned by `empyrean_evaluate()`."]
5102 pub unsafe fn empyrean_evaluate_result_free(&self, result: *mut EmpyreanEvaluateResult) {
5103 (self.empyrean_evaluate_result_free)(result)
5104 }
5105 #[doc = " Refine a single orbit estimate with new observations using a\n Bayesian prior."]
5106 pub unsafe fn empyrean_refine(
5107 &self,
5108 ctx: *const EmpyreanContext,
5109 orbit: *const EmpyreanOrbit,
5110 observations: *const EmpyreanObservation,
5111 num_observations: usize,
5112 config: *const EmpyreanODConfig,
5113 result_out: *mut EmpyreanODResult,
5114 ) -> i32 {
5115 (self.empyrean_refine)(
5116 ctx,
5117 orbit,
5118 observations,
5119 num_observations,
5120 config,
5121 result_out,
5122 )
5123 }
5124 #[doc = " Evaluate an observation plan: how much each candidate observation would\n tighten the prior orbit covariance.\n\n `orbit` must carry a 6×6 Cartesian covariance (e.g. a `determine` result).\n `planned` is an array of `num_planned` candidate observations. `orbit_id`\n may be null (defaults to `\"orbit_0\"`). On success populates `*result_out`\n (caller-allocated); free with [`empyrean_plan_result_free`].\n\n Returns 0 on success, -1 for a null/invalid argument, -3 if planning fails\n (missing/singular prior covariance, an infeasible or invalid candidate, an\n ephemeris-generation error), -99 on an internal panic. The error message is\n retrievable via `empyrean_last_error()`."]
5125 pub unsafe fn empyrean_evaluate_plan(
5126 &self,
5127 ctx: *const EmpyreanContext,
5128 orbit: *const EmpyreanOrbit,
5129 orbit_id: *const ::std::os::raw::c_char,
5130 planned: *const EmpyreanPlannedObservation,
5131 num_planned: usize,
5132 config: *const EmpyreanPlanningConfig,
5133 result_out: *mut EmpyreanPlanResult,
5134 ) -> i32 {
5135 (self.empyrean_evaluate_plan)(
5136 ctx,
5137 orbit,
5138 orbit_id,
5139 planned,
5140 num_planned,
5141 config,
5142 result_out,
5143 )
5144 }
5145 #[doc = " Free the heap allocations inside a plan result populated by\n [`empyrean_evaluate_plan`]. Does not free the caller-allocated struct."]
5146 pub unsafe fn empyrean_plan_result_free(&self, result: *mut EmpyreanPlanResult) {
5147 (self.empyrean_plan_result_free)(result)
5148 }
5149 #[doc = " Propagate orbits to the requested target times.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with the propagated states.\n The caller must free the result with `empyrean_propagation_result_free()`.\n\n States are flat in orbit-major order; within each orbit, rows are in\n **ascending epoch order, always** (engine guarantee since villeneuve\n v1.18.0), regardless of request order. Positional pairing against an\n ascending, duplicate-free request grid is exact; for any other\n request shape, join on `epoch_mjd_tdb`."]
5150 pub unsafe fn empyrean_propagate(
5151 &self,
5152 ctx: *const EmpyreanContext,
5153 orbits_ptr: *const EmpyreanOrbit,
5154 num_orbits: usize,
5155 times_ptr: *const f64,
5156 num_times: usize,
5157 config: *const EmpyreanPropagationConfig,
5158 result_out: *mut EmpyreanPropagationResult,
5159 ) -> i32 {
5160 (self.empyrean_propagate)(
5161 ctx, orbits_ptr, num_orbits, times_ptr, num_times, config, result_out,
5162 )
5163 }
5164 #[doc = " Free a propagation result previously returned by `empyrean_propagate()`."]
5165 pub unsafe fn empyrean_propagation_result_free(&self, result: *mut EmpyreanPropagationResult) {
5166 (self.empyrean_propagation_result_free)(result)
5167 }
5168 #[doc = " Resolved-kind tagged covariance at every output epoch for one orbit,\n Cartesian basis. On success `out_series` owns the array; free with\n [`empyrean_tagged_covariance_series_free`]. On error `out_series` is\n left null and the detail is on `empyrean_last_error()`.\n\n # Safety\n `result` must be a valid pointer returned by `empyrean_propagate`;\n `out_series` must be a valid pointer to write the result into."]
5169 pub unsafe fn empyrean_propagation_covariance_series_cartesian(
5170 &self,
5171 result: *const EmpyreanPropagationResult,
5172 orbit_index: usize,
5173 out_series: *mut *mut EmpyreanTaggedCovarianceSeries,
5174 ) -> i32 {
5175 (self.empyrean_propagation_covariance_series_cartesian)(result, orbit_index, out_series)
5176 }
5177 #[doc = " Resolved-kind tagged covariance at a single `(orbit_index,\n epoch_index)`, Cartesian basis (the gm-free point query). `out` is\n written on success.\n\n # Safety\n `result` and `out` must be valid pointers; `result` from `empyrean_propagate`."]
5178 pub unsafe fn empyrean_propagation_covariance_at_cartesian(
5179 &self,
5180 result: *const EmpyreanPropagationResult,
5181 orbit_index: usize,
5182 epoch_index: usize,
5183 out: *mut EmpyreanTaggedCovariance,
5184 ) -> i32 {
5185 (self.empyrean_propagation_covariance_at_cartesian)(result, orbit_index, epoch_index, out)
5186 }
5187 #[doc = " Free a series returned by\n [`empyrean_propagation_covariance_series_cartesian`].\n\n # Safety\n `series` must be null or a pointer returned by that accessor, freed once."]
5188 pub unsafe fn empyrean_tagged_covariance_series_free(
5189 &self,
5190 series: *mut EmpyreanTaggedCovarianceSeries,
5191 ) {
5192 (self.empyrean_tagged_covariance_series_free)(series)
5193 }
5194 #[doc = " Query the JPL Small-Body Database for one or more orbits.\n\n `object_ids` is an array of `num_object_ids` null-terminated UTF-8\n designations / names / SPK IDs (e.g. `\"apophis\"`, `\"99942\"`,\n `\"2024 YR4\"`, `\"67P\"`). `cache_dir` may be null to skip caching, or\n a directory path where SBDB JSON responses are cached on disk.\n\n On success the populated [`EmpyreanOrbitBatch`] must be released with\n [`empyrean_orbits_batch_free`](crate::io::empyrean_orbits_batch_free)."]
5195 pub unsafe fn empyrean_query_sbdb(
5196 &self,
5197 object_ids: *const *const ::std::os::raw::c_char,
5198 num_object_ids: usize,
5199 cache_dir: *const ::std::os::raw::c_char,
5200 out: *mut EmpyreanOrbitBatch,
5201 ) -> i32 {
5202 (self.empyrean_query_sbdb)(object_ids, num_object_ids, cache_dir, out)
5203 }
5204 #[doc = " Query JPL Horizons for predicted ephemeris records.\n\n `object_ids` is an array of `num_object_ids` null-terminated UTF-8\n designations / names / SPK IDs. `obs_code` is the MPC observatory\n code as a null-terminated string. `times_mjd_tdb` carries\n `num_times` epochs in MJD TDB.\n\n On success populates an [`EmpyreanEphemerisResult`] with one entry\n per `(object_id × epoch)`. Free with\n [`empyrean_ephemeris_result_free`](crate::ephemeris::empyrean_ephemeris_result_free).\n\n All angular values are converted to **degrees** at the FFI boundary\n (Horizons natively returns radians)."]
5205 pub unsafe fn empyrean_query_horizons(
5206 &self,
5207 object_ids: *const *const ::std::os::raw::c_char,
5208 num_object_ids: usize,
5209 obs_code: *const ::std::os::raw::c_char,
5210 times_mjd_tdb: *const f64,
5211 num_times: usize,
5212 cache_dir: *const ::std::os::raw::c_char,
5213 out: *mut EmpyreanEphemerisResult,
5214 ) -> i32 {
5215 (self.empyrean_query_horizons)(
5216 object_ids,
5217 num_object_ids,
5218 obs_code,
5219 times_mjd_tdb,
5220 num_times,
5221 cache_dir,
5222 out,
5223 )
5224 }
5225 #[doc = " Query JPL Horizons for a Cartesian state vector at a single epoch.\n\n `command` is the Horizons COMMAND string as a null-terminated UTF-8\n string (e.g. `\"99942;\"`, `\"DES=C/2019 Q4;\"`). `epoch_mjd_tdb` is\n the epoch in MJD TDB. `cache_dir` may be null to skip caching, or\n a directory path where Horizons JSON responses are cached on disk.\n\n On success writes the position (AU) to `out_pos` (length 3) and the\n velocity (AU/day) to `out_vel` (length 3) — both solar-system\n barycenter (SSB) centered, ICRF."]
5226 pub unsafe fn empyrean_query_horizons_vectors(
5227 &self,
5228 command: *const ::std::os::raw::c_char,
5229 epoch_mjd_tdb: f64,
5230 cache_dir: *const ::std::os::raw::c_char,
5231 out_pos: *mut f64,
5232 out_vel: *mut f64,
5233 ) -> i32 {
5234 (self.empyrean_query_horizons_vectors)(command, epoch_mjd_tdb, cache_dir, out_pos, out_vel)
5235 }
5236 #[doc = " Query the MPC observations API for ADES records of one or more\n designations.\n\n `designations` is an array of `num_designations` null-terminated\n UTF-8 designations (e.g. `\"99942\"`, `\"2024 YR4\"`, `\"67P\"`). The\n MPC API returns ADES_DF JSON; this function parses each row into\n the C-ABI [`EmpyreanObservation`] struct, filling the full ADES\n schema (perm_id / prov_id / trk_sub / mode / sys / ctr / pos1-3 /\n rms_corr / mag / rms_mag / band / ast_cat / phot_cat / phot_ap /\n log_snr / seeing / exp / rms_fit / n_stars / notes / remarks) when\n present in the JSON.\n\n On success `*out_ptr` carries a heap-allocated array of length\n `*out_num`. Free with\n [`empyrean_observations_free`](crate::od::empyrean_observations_free)."]
5237 pub unsafe fn empyrean_query_observations(
5238 &self,
5239 designations: *const *const ::std::os::raw::c_char,
5240 num_designations: usize,
5241 cache_dir: *const ::std::os::raw::c_char,
5242 out_ptr: *mut *mut EmpyreanObservation,
5243 out_num: *mut usize,
5244 ) -> i32 {
5245 (self.empyrean_query_observations)(
5246 designations,
5247 num_designations,
5248 cache_dir,
5249 out_ptr,
5250 out_num,
5251 )
5252 }
5253 #[doc = " Query the JPL `sb_radar` API for delay/Doppler radar astrometry of one\n or more designations.\n\n `designations` is an array of `num_designations` null-terminated UTF-8\n designations (e.g. `\"99942\"`, `\"2024 YR4\"`). Asteroid radar astrometry\n is a JPL SSD product — it is **not** served by the MPC observations API\n (`empyrean_query_observations` returns only optical / occultation\n records), so radar ships as its own live-query entry point. JPL\n `sb_radar` JSON records are converted to ADES-native scott\n `RadarObservation`s and packed into the C-ABI\n [`EmpyreanRadarObservation`] struct (the same layout\n [`empyrean_read_ades`](crate::od::empyrean_read_ades) emits): the delay\n value is in seconds, its σ in microseconds, Doppler in Hz, frequency in\n MHz, and the `com` flag is a tri-state i8. `cache_dir` may be null to\n skip caching, or a directory path where `sb_radar` JSON responses are\n cached on disk.\n\n An object with no radar astrometry contributes no records (it is not an\n error). A JPL record that fails to parse (missing required field, or an\n unrecognised DSN station code) is rejected loudly rather than silently\n dropped — the whole call fails so no radar quietly goes missing.\n\n On success `*out_ptr` carries a heap-allocated array of length\n `*out_num`. Free with\n [`empyrean_radar_observations_free`](crate::od::empyrean_radar_observations_free)."]
5254 pub unsafe fn empyrean_query_radar(
5255 &self,
5256 designations: *const *const ::std::os::raw::c_char,
5257 num_designations: usize,
5258 cache_dir: *const ::std::os::raw::c_char,
5259 out_ptr: *mut *mut EmpyreanRadarObservation,
5260 out_num: *mut usize,
5261 ) -> i32 {
5262 (self.empyrean_query_radar)(designations, num_designations, cache_dir, out_ptr, out_num)
5263 }
5264 #[doc = " Construct a new orbit-determination session over a fixed\n observation set.\n\n Returns a heap-allocated handle on success, or null on error.\n The caller owns the returned pointer and must free it with\n [`empyrean_session_free`]."]
5265 pub unsafe fn empyrean_session_new(
5266 &self,
5267 observations: *const EmpyreanObservation,
5268 num_observations: usize,
5269 config: *const EmpyreanODConfig,
5270 ) -> *mut EmpyreanSession {
5271 (self.empyrean_session_new)(observations, num_observations, config)
5272 }
5273 #[doc = " Free a session previously returned by [`empyrean_session_new`].\n Passing null is a no-op."]
5274 pub unsafe fn empyrean_session_free(&self, session: *mut EmpyreanSession) {
5275 (self.empyrean_session_free)(session)
5276 }
5277 #[doc = " Total number of observations in the session (masked or not).\n Returns 0 if `session` is null."]
5278 pub unsafe fn empyrean_session_n_observations(&self, session: *const EmpyreanSession) -> usize {
5279 (self.empyrean_session_n_observations)(session)
5280 }
5281 #[doc = " Number of observations currently masked."]
5282 pub unsafe fn empyrean_session_n_masked(&self, session: *const EmpyreanSession) -> usize {
5283 (self.empyrean_session_n_masked)(session)
5284 }
5285 #[doc = " Number of observations active (not masked) in the next refine."]
5286 pub unsafe fn empyrean_session_n_active(&self, session: *const EmpyreanSession) -> usize {
5287 (self.empyrean_session_n_active)(session)
5288 }
5289 #[doc = " Mask the observation at `idx`. Returns 0 on success, -1 on null\n or out-of-bounds."]
5290 pub unsafe fn empyrean_session_mask(&self, session: *mut EmpyreanSession, idx: usize) -> i32 {
5291 (self.empyrean_session_mask)(session, idx)
5292 }
5293 #[doc = " Unmask the observation at `idx`. Returns 0 on success, -1 on null\n or out-of-bounds."]
5294 pub unsafe fn empyrean_session_unmask(&self, session: *mut EmpyreanSession, idx: usize) -> i32 {
5295 (self.empyrean_session_unmask)(session, idx)
5296 }
5297 #[doc = " Clear all masks. Returns 0 on success, -1 on null."]
5298 pub unsafe fn empyrean_session_unmask_all(&self, session: *mut EmpyreanSession) -> i32 {
5299 (self.empyrean_session_unmask_all)(session)
5300 }
5301 #[doc = " Whether the observation at `idx` is masked. Returns 1 = masked,\n 0 = active, 255 (-1 cast) on null/out-of-bounds."]
5302 pub unsafe fn empyrean_session_is_masked(
5303 &self,
5304 session: *const EmpyreanSession,
5305 idx: usize,
5306 ) -> u8 {
5307 (self.empyrean_session_is_masked)(session, idx)
5308 }
5309 #[doc = " Run an OD refine using the current mask state.\n\n On the first call, runs the full IOD → DC pipeline. On subsequent\n calls, uses the previously-fit orbit as the IOD seed (skipping the\n IOD step). Pushes the new fit onto the session's history.\n\n On success populates `result_out` with the latest fit. The caller\n must free `result_out` with [`empyrean_od_result_free`](crate::od::empyrean_od_result_free)."]
5310 pub unsafe fn empyrean_session_refine(
5311 &self,
5312 session: *mut EmpyreanSession,
5313 ctx: *const EmpyreanContext,
5314 result_out: *mut EmpyreanODResult,
5315 ) -> i32 {
5316 (self.empyrean_session_refine)(session, ctx, result_out)
5317 }
5318 #[doc = " Number of fits in the session history."]
5319 pub unsafe fn empyrean_session_history_len(&self, session: *const EmpyreanSession) -> usize {
5320 (self.empyrean_session_history_len)(session)
5321 }
5322 #[doc = " Copy the i-th history entry into `result_out`. Returns 0 on\n success, -1 on null/out-of-bounds. Caller frees `result_out` with\n [`empyrean_od_result_free`](crate::od::empyrean_od_result_free)."]
5323 pub unsafe fn empyrean_session_get_history(
5324 &self,
5325 session: *const EmpyreanSession,
5326 idx: usize,
5327 result_out: *mut EmpyreanODResult,
5328 ) -> i32 {
5329 (self.empyrean_session_get_history)(session, idx, result_out)
5330 }
5331 #[doc = " Diff the current fit against an earlier history entry. Returns 0\n on success, -1 if there is no current fit or `prior_idx` is out\n of bounds."]
5332 pub unsafe fn empyrean_session_diff(
5333 &self,
5334 session: *const EmpyreanSession,
5335 prior_idx: usize,
5336 diff_out: *mut EmpyreanSessionDiff,
5337 ) -> i32 {
5338 (self.empyrean_session_diff)(session, prior_idx, diff_out)
5339 }
5340 #[doc = " Query body states relative to a center body at given epochs.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with body states.\n The caller must free the result with `empyrean_state_result_free()`."]
5341 pub unsafe fn empyrean_get_states(
5342 &self,
5343 ctx: *const EmpyreanContext,
5344 target_naif_id: i32,
5345 center_naif_id: i32,
5346 epochs_mjd_tdb: *const f64,
5347 num_epochs: usize,
5348 frame: i32,
5349 result_out: *mut EmpyreanStateResult,
5350 ) -> i32 {
5351 (self.empyrean_get_states)(
5352 ctx,
5353 target_naif_id,
5354 center_naif_id,
5355 epochs_mjd_tdb,
5356 num_epochs,
5357 frame,
5358 result_out,
5359 )
5360 }
5361 #[doc = " Free a state result previously returned by `empyrean_get_states()`.\n\n Passing a zeroed/null result is a no-op."]
5362 pub unsafe fn empyrean_state_result_free(&self, result: *mut EmpyreanStateResult) {
5363 (self.empyrean_state_result_free)(result)
5364 }
5365 #[doc = " Parse an ISO 8601 UTC string (e.g. ``\"2024-08-01T00:00:00.000Z\"``)\n to MJD in the requested target scale.\n\n `scale` is `0` for UTC, `1` for TDB.\n\n On success writes the MJD value to `*out_mjd` and returns 0.\n On failure returns a negative code; consult\n [`empyrean_last_error`](crate::empyrean_last_error)."]
5366 pub unsafe fn empyrean_iso_to_mjd(
5367 &self,
5368 iso: *const ::std::os::raw::c_char,
5369 scale: i32,
5370 out_mjd: *mut f64,
5371 ) -> i32 {
5372 (self.empyrean_iso_to_mjd)(iso, scale, out_mjd)
5373 }
5374 #[doc = " Format an MJD value (in the given scale) as an ISO 8601 UTC string.\n\n `scale` is `0` for UTC, `1` for TDB. Writes a null-terminated\n string of length ≤ `buf_len-1` into `out_buf`. A 32-byte buffer is\n always sufficient (typical output is 24 bytes:\n ``\"2024-08-01T00:00:00.000Z\"``).\n\n Returns 0 on success; negative on failure."]
5375 pub unsafe fn empyrean_mjd_to_iso(
5376 &self,
5377 mjd: f64,
5378 scale: i32,
5379 out_buf: *mut ::std::os::raw::c_char,
5380 buf_len: usize,
5381 ) -> i32 {
5382 (self.empyrean_mjd_to_iso)(mjd, scale, out_buf, buf_len)
5383 }
5384 #[doc = " Transform a coordinate state to a new representation, frame, and/or origin.\n\n Returns 0 on success or a negative error code on failure.\n Call `empyrean_last_error()` to retrieve the error message on failure."]
5385 pub unsafe fn empyrean_transform_coordinates(
5386 &self,
5387 ctx: *const EmpyreanContext,
5388 input: *const CoordinateState,
5389 target_representation: i32,
5390 target_frame: i32,
5391 target_origin: i32,
5392 output: *mut CoordinateState,
5393 ) -> i32 {
5394 (self.empyrean_transform_coordinates)(
5395 ctx,
5396 input,
5397 target_representation,
5398 target_frame,
5399 target_origin,
5400 output,
5401 )
5402 }
5403}