1use crate::G19_safe::eraJd2cal_safe;
6use crate::G8_safe::eraCal2jd_safe;
7use crate::G9_safe::eraDat_safe;
8use crate::H1_safe::{ERFA_D2PI, ERFA_DAYSEC, ERFA_DD2R, ERFA_DJ00, ERFA_DJM};
9
10#[path = "data/G10_safe/FAIRHD.rs"]
11mod fairhd_mod;
12use fairhd_mod::FAIRHD;
13
14pub type ErfaResult<T> = Result<T, ()>;
15
16#[inline]
17fn fmod(a: f64, b: f64) -> f64 {
18 a - (a / b).trunc() * b
20}
21
22pub fn eraDtdb_safe(
24 date1: f64,
25 date2: f64,
26 ut: f64,
27 elong: f64,
28 u: f64,
29 v: f64,
30) -> ErfaResult<f64> {
31 let t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM;
33
34 let tsol = fmod(ut, 1.0) * ERFA_D2PI + elong;
36
37 let w = t / 3600.0;
39
40 let elsun = fmod(280.466_456_83 + 1_296_027_711.034_29 * w, 360.0) * ERFA_DD2R;
42 let emsun = fmod(357.529_109_18 + 1_295_965_810.481_00 * w, 360.0) * ERFA_DD2R;
43 let d = fmod(297.850_195_47 + 16_029_616_012.090_00 * w, 360.0) * ERFA_DD2R;
44 let elj = fmod(34.351_518_74 + 109_306_899.894_53 * w, 360.0) * ERFA_DD2R;
45 let els = fmod(50.077_444_30 + 44_046_398.470_38 * w, 360.0) * ERFA_DD2R;
46
47 let wt = 0.000_29e-10 * u * (tsol + elsun - els).sin()
49 + 0.001_00e-10 * u * (tsol - 2.0 * emsun).sin()
50 + 0.001_33e-10 * u * (tsol - d).sin()
51 + 0.001_33e-10 * u * (tsol + elsun - elj).sin()
52 - 0.002_29e-10 * u * (tsol + 2.0 * elsun + emsun).sin()
53 - 0.022_00e-10 * v * (elsun + emsun).cos()
54 + 0.053_12e-10 * u * (tsol - emsun).sin()
55 - 0.136_77e-10 * u * (tsol + 2.0 * elsun).sin()
56 - 1.318_40e-10 * v * elsun.cos()
57 + 3.176_79e-10 * u * tsol.sin();
58
59 let mut w0 = 0.0;
61 for j in (0..=473).rev() {
62 let row = FAIRHD[j];
63 w0 += row[0] * (row[1] * t + row[2]).sin();
64 }
65 let mut w1 = 0.0;
66 for j in (474..=678).rev() {
67 let row = FAIRHD[j];
68 w1 += row[0] * (row[1] * t + row[2]).sin();
69 }
70 let mut w2 = 0.0;
71 for j in (679..=763).rev() {
72 let row = FAIRHD[j];
73 w2 += row[0] * (row[1] * t + row[2]).sin();
74 }
75 let mut w3 = 0.0;
76 for j in (764..=783).rev() {
77 let row = FAIRHD[j];
78 w3 += row[0] * (row[1] * t + row[2]).sin();
79 }
80 let mut w4 = 0.0;
81 for j in (784..=786).rev() {
82 let row = FAIRHD[j];
83 w4 += row[0] * (row[1] * t + row[2]).sin();
84 }
85
86 let wf = t * (t * (t * (t * w4 + w3) + w2) + w1) + w0;
88
89 let wj = 0.000_65e-6 * (6_069.776_754 * t + 4.021_194).sin()
91 + 0.000_33e-6 * (213.299_095 * t + 5.543_132).sin()
92 - 0.001_96e-6 * (6_208.294_251 * t + 5.696_701).sin()
93 - 0.001_73e-6 * (74.781_599 * t + 2.435_900).sin()
94 + 0.036_38e-6 * t * t;
95
96 Ok(wt + wf + wj)
98}
99
100pub fn eraDtf2d_safe(
102 scale: &str,
103 iy: i32,
104 im: i32,
105 id: i32,
106 ihr: i32,
107 imn: i32,
108 sec: f64,
109) -> Result<((f64, f64), i32), i32> {
110 let ((djm0, djm), j_cal) = eraCal2jd_safe(iy, im, id).map_err(|_| -9999)?;
112 if j_cal != 0 {
113 return Err(j_cal);
114 }
115 let dj = djm0 + djm;
116
117 let mut day = ERFA_DAYSEC;
119 let mut seclim = 60.0_f64;
120
121 if scale == "UTC" {
123 let (dat0, j0) = eraDat_safe(iy, im, id, 0.0).map_err(|_| -9999)?;
125 if j0 < 0 {
126 return Err(j0);
127 }
128
129 let (dat12, j12) = eraDat_safe(iy, im, id, 0.5).map_err(|_| -9999)?;
131 if j12 < 0 {
132 return Err(j12);
133 }
134
135 let ((iy2, im2, id2), _w, j_next) = eraJd2cal_safe(dj + 1.5, 0.0).map_err(|_| -9999)?;
137 if j_next != 0 {
138 return Err(j_next);
139 }
140 let (dat24, j24) = eraDat_safe(iy2, im2, id2, 0.0).map_err(|_| -9999)?;
141 if j24 < 0 {
142 return Err(j24);
143 }
144
145 let dleap = dat24 - (2.0 * dat12 - dat0);
147
148 day += dleap;
150 if ihr == 23 && imn == 59 {
151 seclim += dleap;
152 }
153 }
154
155 let mut js_warn = 0;
157 if (0..=23).contains(&ihr) {
158 if (0..=59).contains(&imn) {
159 if sec >= 0.0 {
160 if sec >= seclim {
161 js_warn += 2;
162 }
163 } else {
164 return Err(-6);
165 }
166 } else {
167 return Err(-5);
168 }
169 } else {
170 return Err(-4);
171 }
172
173 let time = (60.0 * (60.0 * ihr as f64 + imn as f64) + sec) / day;
175
176 Ok(((dj, time), js_warn))
178}