#![allow(clippy::all, clippy::pedantic, clippy::restriction, warnings)]
#[cfg(all(feature = "eop-tests", feature = "sidereal-earth"))]
mod sidereal_tests {
use deep_time::Dt;
use deep_time::eop::{EopData, EopFormat, Separator};
use deep_time::sidereal::Sidereal;
fn load_finals2000a() -> EopData {
let path = "tests/assets/finals.all.iau2000.txt";
EopData::from_text_file(path, EopFormat::Finals2000A, Separator::Whitespace)
.expect("failed to load EopData")
}
#[test]
fn test_sidereal_vs_astropy() {
fn check(eos: EoAndSiderealTimes, provider: &EopData) {
let mjd = eos.mjd;
let lon_deg = eos.longitude_deg;
let astropy_mjd_ut1 = eos.ut1_mjd;
let astropy_rot = eos.earth_rotation_angle_rad;
let _eo_app = eos.eo_apparent_rad;
let _eo_mean = eos.eo_mean_rad;
let _ee = eos.equation_of_equinoxes_rad;
let astropy_gmst = eos.gmst_rad;
let astropy_time = eos.mean_sidereal_time_sec;
let astropy_apparent_angle = eos.gast_rad;
let astropy_apparent_time = eos.apparent_sidereal_time_sec;
let sid = if lon_deg == 0.0 {
Sidereal::EARTH
} else {
Sidereal {
longitude_rad: lon_deg * (core::f64::consts::PI / 180.0),
..Sidereal::EARTH
}
};
let dut1 = Dt::mjd_to_eop_offset_f(mjd, &provider).expect("to_ut1 failed");
let rust_ut1_mjd = mjd + (dut1 / 86400.0);
let rust_rot = sid.local_rotation_angle(rust_ut1_mjd);
let rust_eo = sid.earth_eo_apparent(rust_ut1_mjd + 32.184 / 86400.0);
let rust_ee = sid.earth_ee(rust_ut1_mjd + 32.184 / 86400.0);
let rust_eo_mean = rust_eo + rust_ee;
let rust_local = sid.local_sidereal_angle_mean(rust_ut1_mjd, rust_eo_mean);
let rust_time = sid.local_sidereal_time_mean(rust_ut1_mjd, rust_eo_mean);
let rust_app_angle = sid.local_sidereal_angle_apparent(rust_ut1_mjd, rust_eo);
let rust_app_time = sid.local_sidereal_time_apparent(rust_ut1_mjd, rust_eo);
let ut1_diff = (rust_ut1_mjd - astropy_mjd_ut1).abs();
let rot_diff = (rust_rot - astropy_rot).abs();
let angle_diff = (rust_local - astropy_gmst).abs();
let time_diff = (rust_time - astropy_time).abs();
let app_angle_diff = (rust_app_angle - astropy_apparent_angle).abs();
let app_time_diff = (rust_app_time - astropy_apparent_time).abs();
assert!(
ut1_diff < 1e-9,
"UT1 MJD too far from Astropy: diff = {ut1_diff:.2e}"
);
assert!(
rot_diff < 5e-9,
"rotation_angle too far from Astropy: diff = {rot_diff:.2e}"
);
assert!(
angle_diff < 5e-9,
"sidereal_angle too far from Astropy: diff = {angle_diff:.2e}"
);
assert!(
time_diff < 6.10e-5,
"sidereal_time too far from Astropy: diff = {time_diff:.2e}"
);
assert!(
app_angle_diff < 5e-9,
"apparent sidereal_angle too far from Astropy: diff = {app_angle_diff:.2e}"
);
assert!(
app_time_diff < 7e-5,
"apparent sidereal_time too far from Astropy: diff = {app_time_diff:.2e}"
);
}
let provider = load_finals2000a();
#[derive(Debug, Clone, Copy)]
pub struct EoAndSiderealTimes {
pub mjd: f64,
pub longitude_deg: f64,
pub ut1_mjd: f64,
pub earth_rotation_angle_rad: f64, pub eo_apparent_rad: f64, pub eo_mean_rad: f64, pub gmst_rad: f64, pub mean_sidereal_time_sec: f64,
pub equation_of_equinoxes_rad: f64, pub gast_rad: f64, pub apparent_sidereal_time_sec: f64,
}
pub const TEST_CASES: [EoAndSiderealTimes; 5] = [
EoAndSiderealTimes {
mjd: 53371.0,
longitude_deg: 0.0,
ut1_mjd: 53370.999994170932041,
earth_rotation_angle_rad: 1.757186292111117,
eo_apparent_rad: -0.001085302402798,
eo_mean_rad: -0.001118258994844,
gmst_rad: 1.758304551105961,
mean_sidereal_time_sec: 24178.423170483926,
equation_of_equinoxes_rad: -0.000032956592046,
gast_rad: 1.758271594513915,
apparent_sidereal_time_sec: 24177.969984812393,
},
EoAndSiderealTimes {
mjd: 55197.0,
longitude_deg: 0.0,
ut1_mjd: 55197.000001321015588,
earth_rotation_angle_rad: 1.752484708914275,
eo_apparent_rad: -0.002309329056754,
eo_mean_rad: -0.002236174848923,
gmst_rad: 1.754720883763197,
mean_sidereal_time_sec: 24129.144207143308,
equation_of_equinoxes_rad: 0.000073154207832,
gast_rad: 1.754794037971029,
apparent_sidereal_time_sec: 24130.150149710280,
},
EoAndSiderealTimes {
mjd: 57753.999999,
longitude_deg: 0.0,
ut1_mjd: 57754.000005843590770,
earth_rotation_angle_rad: 1.756189226484602,
eo_apparent_rad: -0.003772953343248,
eo_mean_rad: -0.003801681054842,
gmst_rad: 1.759990907539444,
mean_sidereal_time_sec: 24201.612236018307,
equation_of_equinoxes_rad: -0.000028727711594,
gast_rad: 1.759962179827850,
apparent_sidereal_time_sec: 24201.217201627253,
},
EoAndSiderealTimes {
mjd: 57754.0,
longitude_deg: 0.0,
ut1_mjd: 57754.000006843598385,
earth_rotation_angle_rad: 1.756195526947061,
eo_apparent_rad: -0.003772953344064,
eo_mean_rad: -0.003801681055454,
gmst_rad: 1.759997208002515,
mean_sidereal_time_sec: 24201.698873604622,
equation_of_equinoxes_rad: -0.000028727711391,
gast_rad: 1.759968480291124,
apparent_sidereal_time_sec: 24201.303839216362,
},
EoAndSiderealTimes {
mjd: 56879.0,
longitude_deg: 350.0,
ut1_mjd: 56878.999996330509020,
earth_rotation_angle_rad: 5.379245158425889,
eo_apparent_rad: -0.003302266569225,
eo_mean_rad: -0.003265960688001,
gmst_rad: 5.382511119113890,
mean_sidereal_time_sec: 74014.840873791225,
equation_of_equinoxes_rad: 0.000036305881223,
gast_rad: 5.382547424995114,
apparent_sidereal_time_sec: 74015.340115494982,
},
];
for s in TEST_CASES {
check(s, &provider);
}
}
}