use super::ierstable::IERSTable;
use crate::{TimeLike, TimeScale};
use crate::mathtypes::*;
type Delaunay = numeris::Vector<f64, 14>;
use std::f64::consts::PI;
use std::sync::OnceLock;
fn table5a_singleton() -> &'static IERSTable {
static INSTANCE: OnceLock<IERSTable> = OnceLock::new();
INSTANCE.get_or_init(|| IERSTable::from_file("tab5.2a.txt").unwrap())
}
fn table5b_singleton() -> &'static IERSTable {
static INSTANCE: OnceLock<IERSTable> = OnceLock::new();
INSTANCE.get_or_init(|| IERSTable::from_file("tab5.2b.txt").unwrap())
}
fn table5d_singleton() -> &'static IERSTable {
static INSTANCE: OnceLock<IERSTable> = OnceLock::new();
INSTANCE.get_or_init(|| IERSTable::from_file("tab5.2d.txt").unwrap())
}
pub fn qcirs2gcrs_dxdy<T: TimeLike>(tm: &T, dxdy: Option<(f64, f64)>) -> Quaternion {
let t_tt = (tm.as_mjd_with_scale(TimeScale::TT) - 51544.5) / 36525.0;
const ASEC2RAD: f64 = PI / 180.0 / 3600.0;
let mut delaunay = Delaunay::zeros();
delaunay[0] = ASEC2RAD
* 3600.0f64.mul_add(
134.96340251,
t_tt * t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(-0.00024470, 0.051635), 31.8792),
1717915923.2178,
),
);
delaunay[1] = ASEC2RAD
* 3600.0f64.mul_add(
357.52910918,
t_tt * t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(-0.00001149, 0.000136), -0.5532),
129596581.0481,
),
);
delaunay[2] = ASEC2RAD
* 3600.0f64.mul_add(
93.27209062,
t_tt * t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(0.00000417, -0.001037), -12.7512),
1739527262.8478,
),
);
delaunay[3] = ASEC2RAD
* 3600.0f64.mul_add(
297.85019547,
t_tt * t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(-0.00003169, 0.006593), -6.37006),
1602961601.2090,
),
);
delaunay[4] = ASEC2RAD
* 3600.0f64.mul_add(
125.04455501,
t_tt * t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(-0.00005939, 0.007702), 7.4722),
-6962890.5431,
),
);
delaunay[5] = 2608.7903141574f64.mul_add(t_tt, 4.402608842);
delaunay[6] = 1021.3285546211f64.mul_add(t_tt, 3.176146697);
delaunay[7] = 628.3075849991f64.mul_add(t_tt, 1.753470314);
delaunay[8] = 334.0612426700f64.mul_add(t_tt, 6.203480913);
delaunay[9] = 52.9690962641f64.mul_add(t_tt, 0.599546497);
delaunay[10] = 21.3299104960f64.mul_add(t_tt, 0.874016757);
delaunay[11] = 7.4781598567f64.mul_add(t_tt, 5.481293872);
delaunay[12] = 3.8133035638f64.mul_add(t_tt, 5.311886287);
delaunay[13] = t_tt * t_tt.mul_add(0.00000538691, 0.02438175);
let x0 = t_tt.mul_add(
t_tt.mul_add(
t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(0.0000059285, 0.000007578), -0.19861834),
-0.4297829,
),
2004.191898,
),
-0.016617,
);
let y0 = t_tt.mul_add(
t_tt.mul_add(
t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(0.0000001358, 0.001112526), 0.00190059),
-22.4072747,
),
-0.025896,
),
-0.006951,
);
let s0 = t_tt.mul_add(
t_tt.mul_add(
t_tt.mul_add(t_tt.mul_add(t_tt.mul_add(15.62, 27.98), -72574.11), -122.68),
3808.65,
),
94.0,
);
let xsums = table5a_singleton().compute(t_tt, &delaunay);
let ysums = table5b_singleton().compute(t_tt, &delaunay);
let ssums = table5d_singleton().compute(t_tt, &delaunay);
let mut x = xsums.mul_add(1.0e-6, x0) * ASEC2RAD;
let mut y = ysums.mul_add(1.0e-6, y0) * ASEC2RAD;
if let Some((dx, dy)) = dxdy {
x += dx * 1e-3 * ASEC2RAD;
y += dy * 1e-3 * ASEC2RAD;
}
let s = ((s0 + ssums) * 1.0e-6).mul_add(ASEC2RAD, -(x * y / 2.0));
let e = f64::atan2(y, x);
let d = f64::asin(f64::sqrt(x.mul_add(x, y * y)));
Quaternion::rotz(e) * Quaternion::roty(d) * Quaternion::rotz(-(e + s))
}
pub fn qcirs2gcrs<T: TimeLike>(tm: &T) -> Quaternion {
let dxdy: Option<(f64, f64)> = crate::earth_orientation_params::get(tm).map(|v| (v[4], v[5]));
qcirs2gcrs_dxdy(tm, dxdy)
}