use crate::{Ephemeris, EphemerisError};
pub fn de421() -> Result<Ephemeris, EphemerisError> {
let bytes = astrodyn_ephemeris::data::load(&astrodyn_ephemeris::data::DE421)?;
Ephemeris::from_bsp_bytes(&bytes)
}
pub fn de421_with_moon_pa() -> Result<Ephemeris, EphemerisError> {
let mut eph = de421()?;
let bpc = astrodyn_ephemeris::data::load(&astrodyn_ephemeris::data::MOON_PA)?;
eph.load_bpc_bytes(&bpc)?;
Ok(eph)
}
pub fn de421_with_moon_me() -> Result<Ephemeris, EphemerisError> {
let mut eph = de421_with_moon_pa()?;
let fk = astrodyn_ephemeris::data::load(&astrodyn_ephemeris::data::MOON_FK)?;
eph.load_euler_bytes(&fk)?;
Ok(eph)
}
pub fn de421_with_iau() -> Result<Ephemeris, EphemerisError> {
let mut eph = de421()?;
let pca = astrodyn_ephemeris::data::load(&astrodyn_ephemeris::data::PCK11)?;
eph.load_pca_bytes(&pca)?;
Ok(eph)
}
pub fn de440() -> Result<Ephemeris, EphemerisError> {
let bytes = astrodyn_ephemeris::data::load(&astrodyn_ephemeris::data::DE440)?;
Ephemeris::from_bsp_bytes(&bytes)
}
pub fn de440_with_moon_pa() -> Result<Ephemeris, EphemerisError> {
let mut eph = de440()?;
let bpc = astrodyn_ephemeris::data::load(&astrodyn_ephemeris::data::MOON_PA)?;
eph.load_bpc_bytes(&bpc)?;
Ok(eph)
}
#[cfg(test)]
mod tests {
use crate::{BodyFixedFrame, EphemerisBody, Moon};
#[test]
fn de421_with_moon_me_resolves_me_distinct_from_pa() {
let eph = super::de421_with_moon_me().expect("load DE421 + Moon PA + ME FK");
let pa = eph
.get_body_rotation_to_jd::<Moon>(
EphemerisBody::Moon,
BodyFixedFrame::MoonPaDe421,
2_451_545.0,
)
.expect("PA")
.matrix();
let me = eph
.get_body_rotation_to_jd::<Moon>(
EphemerisBody::Moon,
BodyFixedFrame::MoonMeDe421,
2_451_545.0,
)
.expect("ME")
.matrix();
let max_diff = (pa - me)
.to_cols_array()
.iter()
.fold(0.0_f64, |m, &x| m.max(x.abs()));
assert!(
max_diff > 1e-5,
"ME must differ from PA by the libration offset; max element diff = {max_diff:e}",
);
}
#[test]
fn de421_with_iau_resolves_jupiter_rotation() {
use crate::Jupiter;
let eph = super::de421_with_iau().expect("load DE421 + IAU PCA");
let m = eph
.get_body_rotation_to_jd::<Jupiter>(
EphemerisBody::Jupiter,
BodyFixedFrame::Iau,
2_451_545.0,
)
.expect("Jupiter IAU rotation")
.matrix();
let off_identity = (m - glam::DMat3::IDENTITY)
.to_cols_array()
.iter()
.fold(0.0_f64, |acc, &x| acc.max(x.abs()));
assert!(
off_identity > 0.1,
"Jupiter IAU orientation must be a real rotation, not identity (got {off_identity:e})",
);
}
}