Skip to content

Commit cdc3277

Browse files
committed
WIP
1 parent 64d918a commit cdc3277

File tree

16 files changed

+491
-152
lines changed

16 files changed

+491
-152
lines changed

crates/lox-derive/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ pub fn derive_offset_provider(input: proc_macro::TokenStream) -> proc_macro::Tok
379379
output.extend(quote! {
380380
impl From<::core::convert::Infallible> for #err {
381381
fn from(_: ::core::convert::Infallible) -> Self {
382-
#err::default()
382+
unreachable!()
383383
}
384384
}
385385
});

crates/lox-earth/src/eop.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ use std::{
88
};
99

1010
use csv::{ByteRecord, ReaderBuilder};
11-
use lox_core::f64::consts::{SECONDS_BETWEEN_MJD_AND_J2000, SECONDS_PER_DAY};
11+
use lox_core::{
12+
f64::consts::{SECONDS_BETWEEN_MJD_AND_J2000, SECONDS_PER_DAY},
13+
units::Angle,
14+
};
15+
use lox_frames::transformations::RotationProvider;
1216
use lox_math::series::{Series, SeriesError};
1317
use lox_time::{
1418
OffsetProvider,
@@ -23,6 +27,8 @@ use lox_time::{
2327
use serde::Deserialize;
2428
use thiserror::Error;
2529

30+
use crate::{cip::CipCoords, nutation::Nutation, polar_motion::PoleCoords};
31+
2632
#[derive(Debug, Deserialize)]
2733
struct EopRecord {
2834
#[serde(rename = "MJD")]
@@ -257,22 +263,25 @@ pub struct EopProvider {
257263
}
258264

259265
impl EopProvider {
260-
pub fn polar_motion<T: TryToUtc>(&self, t: T) -> Result<(f64, f64), EopProviderError> {
266+
pub fn polar_motion<T: TryToUtc>(&self, t: T) -> Result<PoleCoords, EopProviderError> {
261267
let t = t.try_to_utc()?.seconds_since_j2000();
262-
let px = self.polar_motion.0.interpolate(t);
263-
let py = self.polar_motion.1.interpolate(t);
268+
let xp = self.polar_motion.0.interpolate(t);
269+
let yp = self.polar_motion.1.interpolate(t);
264270
let (min, _) = self.polar_motion.0.first();
265271
let (max, _) = self.polar_motion.0.last();
266272
if t < min || t > max {
267-
return Err(EopProviderError::ExtrapolatedValues(px, py));
273+
return Err(EopProviderError::ExtrapolatedValues(xp, yp));
268274
}
269-
Ok((px, py))
275+
Ok(PoleCoords {
276+
xp: Angle::arcseconds(xp),
277+
yp: Angle::arcseconds(yp),
278+
})
270279
}
271280

272281
pub fn nutation_precession_iau1980<T: TryToUtc>(
273282
&self,
274283
t: T,
275-
) -> Result<(f64, f64), EopProviderError> {
284+
) -> Result<Nutation, EopProviderError> {
276285
let Some(nut_prec) = &self.nut_prec.iau1980 else {
277286
return Err(EopProviderError::MissingIau1980);
278287
};
@@ -284,13 +293,16 @@ impl EopProvider {
284293
if t < min || t > max {
285294
return Err(EopProviderError::ExtrapolatedValues(dpsi, deps));
286295
}
287-
Ok((dpsi, deps))
296+
Ok(Nutation {
297+
longitude: Angle::arcseconds(dpsi * 1e-3),
298+
obliquity: Angle::arcseconds(deps * 1e-3),
299+
})
288300
}
289301

290302
pub fn nutation_precession_iau2000<T: TryToUtc>(
291303
&self,
292304
t: T,
293-
) -> Result<(f64, f64), EopProviderError> {
305+
) -> Result<CipCoords, EopProviderError> {
294306
let Some(nut_prec) = &self.nut_prec.iau2000 else {
295307
return Err(EopProviderError::MissingIau2000);
296308
};
@@ -302,7 +314,10 @@ impl EopProvider {
302314
if t < min || t > max {
303315
return Err(EopProviderError::ExtrapolatedValues(dx, dy));
304316
}
305-
Ok((dx, dy))
317+
Ok(CipCoords {
318+
x: Angle::arcseconds(dx * 1e-3),
319+
y: Angle::arcseconds(dy * 1e-3),
320+
})
306321
}
307322

308323
pub fn delta_ut1_tai(&self, tai: TimeDelta) -> Result<TimeDelta, EopProviderError> {
@@ -333,6 +348,8 @@ impl EopProvider {
333348
}
334349
}
335350

351+
impl RotationProvider for EopProvider {}
352+
336353
#[cfg(test)]
337354
mod tests {
338355
use lox_test_utils::data_file;

crates/lox-earth/src/frames.rs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,209 @@
22
//
33
// SPDX-License-Identifier: MPL-2.0
44

5+
use lox_frames::{
6+
Icrf,
7+
frames::{J2000, Mod},
8+
iers::{Iers1996, Iers2003},
9+
transformations::{Rotation, TryRotation},
10+
};
11+
use lox_time::{
12+
Time,
13+
offsets::TryOffset,
14+
time_scales::{Tdb, TimeScale, Tt},
15+
utc::transformations::TryToUtc,
16+
};
17+
18+
use crate::{
19+
cip::CipCoords,
20+
eop::EopProvider,
21+
frames::{
22+
iers1996::j2000_to_mod,
23+
j2000::{icrf_to_j2000, j2000_to_icrf},
24+
},
25+
nutation::Nutation,
26+
polar_motion::PoleCoords,
27+
};
28+
529
pub mod iers1996;
630
pub mod iers2003;
731
pub mod iers2010;
832
pub mod j2000;
33+
34+
pub trait CorrectionsProvider<T> {
35+
fn equinox_corrections(&self, _time: T) -> Option<Nutation> {
36+
None
37+
}
38+
39+
fn cip_corrections(&self, _time: T) -> Option<CipCoords> {
40+
None
41+
}
42+
43+
fn pole_coords(&self, _time: T) -> Option<PoleCoords> {
44+
None
45+
}
46+
}
47+
48+
impl<T> CorrectionsProvider<T> for EopProvider
49+
where
50+
T: TryToUtc,
51+
{
52+
fn equinox_corrections(&self, time: T) -> Option<Nutation> {
53+
let utc = time.try_to_utc().ok()?;
54+
self.nutation_precession_iau1980(utc).ok()
55+
}
56+
57+
fn cip_corrections(&self, time: T) -> Option<CipCoords> {
58+
let utc = time.try_to_utc().ok()?;
59+
self.nutation_precession_iau2000(utc).ok()
60+
}
61+
62+
fn pole_coords(&self, time: T) -> Option<PoleCoords> {
63+
let utc = time.try_to_utc().ok()?;
64+
self.polar_motion(utc).ok()
65+
}
66+
}
67+
68+
impl<T> TryRotation<Icrf, J2000, T> for EopProvider
69+
where
70+
T: TimeScale + Copy,
71+
EopProvider: TryOffset<T, Tt>,
72+
{
73+
type Error = <EopProvider as TryOffset<T, Tt>>::Error;
74+
75+
fn try_rotation(
76+
&self,
77+
_origin: Icrf,
78+
_target: J2000,
79+
time: Time<T>,
80+
) -> Result<Rotation, Self::Error> {
81+
let time = time.try_to_scale(Tt, self)?;
82+
Ok(icrf_to_j2000(time))
83+
}
84+
}
85+
86+
impl<T> TryRotation<J2000, Icrf, T> for EopProvider
87+
where
88+
T: TimeScale + Copy,
89+
EopProvider: TryOffset<T, Tt>,
90+
{
91+
type Error = <EopProvider as TryOffset<T, Tt>>::Error;
92+
93+
fn try_rotation(
94+
&self,
95+
_origin: J2000,
96+
_target: Icrf,
97+
time: Time<T>,
98+
) -> Result<Rotation, Self::Error> {
99+
let time = time.try_to_scale(Tt, self)?;
100+
Ok(j2000_to_icrf(time))
101+
}
102+
}
103+
104+
impl<T> TryRotation<J2000, Mod<Iers1996>, T> for EopProvider
105+
where
106+
T: TimeScale + Copy,
107+
EopProvider: TryOffset<T, Tdb>,
108+
{
109+
type Error = <EopProvider as TryOffset<T, Tdb>>::Error;
110+
111+
fn try_rotation(
112+
&self,
113+
_origin: J2000,
114+
_target: Mod<Iers1996>,
115+
time: Time<T>,
116+
) -> Result<Rotation, Self::Error> {
117+
let time = time.try_to_scale(Tdb, self)?;
118+
Ok(iers1996::j2000_to_mod(time))
119+
}
120+
}
121+
122+
impl<T> TryRotation<Mod<Iers1996>, J2000, T> for EopProvider
123+
where
124+
T: TimeScale + Copy,
125+
EopProvider: TryOffset<T, Tdb>,
126+
{
127+
type Error = <EopProvider as TryOffset<T, Tdb>>::Error;
128+
129+
fn try_rotation(
130+
&self,
131+
_origin: Mod<Iers1996>,
132+
_target: J2000,
133+
time: Time<T>,
134+
) -> Result<Rotation, Self::Error> {
135+
let time = time.try_to_scale(Tdb, self)?;
136+
Ok(iers1996::mod_to_j2000(time))
137+
}
138+
}
139+
140+
impl<T> TryRotation<Icrf, Mod<Iers1996>, T> for EopProvider
141+
where
142+
T: TimeScale + Copy,
143+
EopProvider: TryOffset<T, Tdb>,
144+
{
145+
type Error = <EopProvider as TryOffset<T, Tdb>>::Error;
146+
147+
fn try_rotation(
148+
&self,
149+
_origin: Icrf,
150+
_target: Mod<Iers1996>,
151+
time: Time<T>,
152+
) -> Result<Rotation, Self::Error> {
153+
let time = time.try_to_scale(Tdb, self)?;
154+
Ok(iers1996::j2000_to_mod(time))
155+
}
156+
}
157+
158+
impl<T> TryRotation<Mod<Iers1996>, Icrf, T> for EopProvider
159+
where
160+
T: TimeScale + Copy,
161+
EopProvider: TryOffset<T, Tdb>,
162+
{
163+
type Error = <EopProvider as TryOffset<T, Tdb>>::Error;
164+
165+
fn try_rotation(
166+
&self,
167+
_origin: Mod<Iers1996>,
168+
_target: Icrf,
169+
time: Time<T>,
170+
) -> Result<Rotation, Self::Error> {
171+
let time = time.try_to_scale(Tdb, self)?;
172+
Ok(iers1996::mod_to_j2000(time))
173+
}
174+
}
175+
176+
impl<T> TryRotation<Icrf, Mod<Iers2003>, T> for EopProvider
177+
where
178+
T: TimeScale + Copy,
179+
EopProvider: TryOffset<T, Tt>,
180+
{
181+
type Error = <EopProvider as TryOffset<T, Tt>>::Error;
182+
183+
fn try_rotation(
184+
&self,
185+
_origin: Icrf,
186+
_target: Mod<Iers2003>,
187+
time: Time<T>,
188+
) -> Result<Rotation, Self::Error> {
189+
let time = time.try_to_scale(Tt, self)?;
190+
Ok(iers2003::icrf_to_mod(time))
191+
}
192+
}
193+
194+
impl<T> TryRotation<Mod<Iers2003>, Icrf, T> for EopProvider
195+
where
196+
T: TimeScale + Copy,
197+
EopProvider: TryOffset<T, Tt>,
198+
{
199+
type Error = <EopProvider as TryOffset<T, Tt>>::Error;
200+
201+
fn try_rotation(
202+
&self,
203+
_origin: Mod<Iers2003>,
204+
_target: Icrf,
205+
time: Time<T>,
206+
) -> Result<Rotation, Self::Error> {
207+
let time = time.try_to_scale(Tt, self)?;
208+
Ok(iers2003::mod_to_icrf(time))
209+
}
210+
}

crates/lox-earth/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ pub mod eop;
1111
pub mod ephemeris;
1212
pub mod frames;
1313
pub mod fundamental;
14-
pub mod iers;
1514
pub mod nutation;
1615
pub mod polar_motion;
1716
pub mod precession;

crates/lox-frames/src/dynamic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ impl ReferenceFrame for DynFrame {
6666
}
6767
}
6868

69-
fn frame_id(&self, _: crate::traits::private::Internal) -> Option<i32> {
69+
fn frame_id(&self, _: crate::traits::private::Internal) -> Option<usize> {
7070
match self {
7171
DynFrame::Icrf => frame_id(&Icrf),
7272
DynFrame::Cirf => frame_id(&Cirf),
7373
DynFrame::Tirf => frame_id(&Tirf),
7474
DynFrame::Itrf => frame_id(&Itrf),
75-
DynFrame::Iau(dyn_origin) => Some(1000 + dyn_origin.id().0),
75+
DynFrame::Iau(dyn_origin) => Some(1000 + dyn_origin.id().0 as usize),
7676
}
7777
}
7878
}

0 commit comments

Comments
 (0)