1use crate::G11_safe::{eraEe00a_safe, eraEe00b_safe, eraEform_safe, eraEors_safe};
17use crate::G14_safe::{eraEqeq94_safe, eraEra00_safe};
18use crate::G1_safe::{eraAnp_safe, eraAnpm_safe};
19use crate::G26_safe::eraPnm06a_safe;
20use crate::G29_safe::eraS2c_safe;
21use crate::G30_safe::eraS06_safe;
22use crate::G33_safe::eraTrxp_safe;
23use crate::G6_safe::eraBpn2xy_safe;
24use crate::G7_safe::eraC2s_safe;
25use crate::H1_safe::{ERFA_DAS2R, ERFA_DAYSEC, ERFA_DJ00, ERFA_DJC, ERFA_DPI, ERFA_DS2R};
26
27pub type ErfaResult<T> = Result<T, ()>;
28
29pub fn eraG2icrs_safe(dl: f64, db: f64) -> ErfaResult<(f64, f64)> {
34 const R: [[f64; 3]; 3] = [
36 [
37 -0.054_875_560_416_215_37,
38 -0.873_437_090_234_885_0,
39 -0.483_835_015_548_713_2,
40 ],
41 [
42 0.494_109_427_875_583_66,
43 -0.444_829_629_960_011_16,
44 0.746_982_244_497_218_9,
45 ],
46 [
47 -0.867_666_149_019_004_7,
48 -0.198_076_373_431_201_53,
49 0.455_983_776_175_066_9,
50 ],
51 ];
52
53 let v1 = eraS2c_safe(dl, db)?;
54 let v2 = eraTrxp_safe(&R, &v1)?;
55 let (mut dr, mut dd) = eraC2s_safe(&v2)?;
56 dr = eraAnp_safe(dr)?;
57 dd = eraAnpm_safe(dd)?;
58 Ok((dr, dd))
59}
60
61pub fn eraGc2gd_safe(n: i32, xyz: &[f64; 3]) -> ErfaResult<(f64, f64, f64, i32)> {
66 let ((a, f), j_eform) = eraEform_safe(n)?;
67 let mut elong = 0.0_f64;
68 let mut phi = 0.0_f64;
69 let mut height = 0.0_f64;
70
71 let mut j = j_eform;
72 if j == 0 {
73 let (el, ph, h, j2) = eraGc2gde_safe(a, f, xyz)?;
74 elong = el;
75 phi = ph;
76 height = h;
77 if j2 < 0 {
78 j = -2;
79 }
80 }
81
82 if j < 0 {
83 elong = -1e9;
84 phi = -1e9;
85 height = -1e9;
86 }
87
88 Ok((elong, phi, height, j))
89}
90
91pub fn eraGc2gde_safe(a: f64, f: f64, xyz: &[f64; 3]) -> ErfaResult<(f64, f64, f64, i32)> {
96 if f < 0.0 || f >= 1.0 {
97 return Ok((0.0, 0.0, 0.0, -1));
98 }
99 if a <= 0.0 {
100 return Ok((0.0, 0.0, 0.0, -2));
101 }
102
103 let aeps2 = a * a * 1e-32;
104 let e2 = (2.0 - f) * f;
105 let e4t = e2 * e2 * 1.5;
106 let ec2 = 1.0 - e2;
107 if ec2 <= 0.0 {
108 return Ok((0.0, 0.0, 0.0, -1));
109 }
110 let ec = ec2.sqrt();
111 let b = a * ec;
112
113 let x = xyz[0];
114 let y = xyz[1];
115 let z = xyz[2];
116
117 let p2 = x * x + y * y;
118
119 let elong = if p2 > 0.0 { y.atan2(x) } else { 0.0 };
120
121 let absz = z.abs();
122
123 let (phi, height) = if p2 > aeps2 {
124 let p = p2.sqrt();
125 let s0 = absz / a;
126 let pn = p / a;
127 let zc = ec * s0;
128
129 let c0 = ec * pn;
130 let c02 = c0 * c0;
131 let c03 = c02 * c0;
132 let s02 = s0 * s0;
133 let s03 = s02 * s0;
134 let a02 = c02 + s02;
135 let a0 = a02.sqrt();
136 let a03 = a02 * a0;
137 let d0 = zc * a03 + e2 * s03;
138 let f0 = pn * a03 - e2 * c03;
139
140 let b0 = e4t * s02 * c02 * pn * (a0 - ec);
141 let s1 = d0 * f0 - b0 * s0;
142 let cc = ec * (f0 * f0 - b0 * c0);
143
144 let mut phi = (s1 / cc).atan();
145
146 let s12 = s1 * s1;
147 let cc2 = cc * cc;
148 let height = (p * cc + absz * s1 - a * (ec2 * s12 + cc2).sqrt()) / (s12 + cc2).sqrt();
149
150 if z < 0.0 {
151 phi = -phi;
152 }
153 (phi, height)
154 } else {
155 (ERFA_DPI / 2.0 * if z < 0.0 { -1.0 } else { 1.0 }, absz - b)
156 };
157
158 Ok((elong, phi, height, 0))
159}
160
161pub fn eraGd2gc_safe(n: i32, elong: f64, phi: f64, height: f64) -> ErfaResult<([f64; 3], i32)> {
166 let ((a, f), j_eform) = eraEform_safe(n)?;
167 let mut j = j_eform;
168 let mut xyz = [0.0_f64; 3];
169
170 if j == 0 {
171 let (out, j2) = eraGd2gce_safe(a, f, elong, phi, height)?;
172 xyz = out;
173 if j2 != 0 {
174 j = -2;
175 }
176 }
177
178 if j != 0 {
179 xyz = [0.0, 0.0, 0.0];
180 }
181 Ok((xyz, j))
182}
183
184pub fn eraGd2gce_safe(
189 a: f64,
190 f: f64,
191 elong: f64,
192 phi: f64,
193 height: f64,
194) -> ErfaResult<([f64; 3], i32)> {
195 let sp = phi.sin();
196 let cp = phi.cos();
197 let mut w = 1.0 - f;
198 w *= w;
199 let d = cp * cp + w * sp * sp;
200 if d <= 0.0 {
201 return Ok(([0.0, 0.0, 0.0], -1));
202 }
203
204 let ac = a / d.sqrt();
205 let as_ = w * ac;
206
207 let r = (ac + height) * cp;
208 let x = r * elong.cos();
209 let y = r * elong.sin();
210 let z = (as_ + height) * sp;
211
212 Ok(([x, y, z], 0))
213}
214
215pub fn eraGmst00_safe(uta: f64, utb: f64, tta: f64, ttb: f64) -> ErfaResult<f64> {
220 let t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC;
221 let gmst = eraAnp_safe(
222 eraEra00_safe(uta, utb)?
223 + (0.014_506
224 + (4612.157_399_66 + (1.396_677_21 + (-0.000_093_44 + 0.000_018_82 * t) * t) * t)
225 * t)
226 * ERFA_DAS2R,
227 )?;
228 Ok(gmst)
229}
230
231pub fn eraGmst06_safe(uta: f64, utb: f64, tta: f64, ttb: f64) -> ErfaResult<f64> {
236 let t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC;
237 let gmst = eraAnp_safe(
238 eraEra00_safe(uta, utb)?
239 + (0.014_506
240 + (4612.156_534
241 + (1.391_581_7
242 + (-0.000_000_44 + (-0.000_029_956 + (-0.000_000_036_8) * t) * t) * t)
243 * t)
244 * t)
245 * ERFA_DAS2R,
246 )?;
247 Ok(gmst)
248}
249
250pub fn eraGmst82_safe(dj1: f64, dj2: f64) -> ErfaResult<f64> {
255 const A: f64 = 24_110.548_41 - ERFA_DAYSEC / 2.0;
256 const B: f64 = 8_640_184.812_866;
257 const C: f64 = 0.093_104;
258 const D: f64 = -6.2e-6;
259
260 let (d1, d2) = if dj1 < dj2 { (dj1, dj2) } else { (dj2, dj1) };
261 let t = (d1 + (d2 - ERFA_DJ00)) / ERFA_DJC;
262
263 let f = ERFA_DAYSEC * (d1.fract() + d2.fract());
264
265 let gmst = eraAnp_safe(ERFA_DS2R * (A + (B + (C + D * t) * t) * t + f))?;
266 Ok(gmst)
267}
268
269pub fn eraGst00a_safe(uta: f64, utb: f64, tta: f64, ttb: f64) -> ErfaResult<f64> {
274 let gmst00 = eraGmst00_safe(uta, utb, tta, ttb)?;
275 let ee00a = eraEe00a_safe(tta, ttb)?;
276 eraAnp_safe(gmst00 + ee00a)
277}
278
279pub fn eraGst00b_safe(uta: f64, utb: f64) -> ErfaResult<f64> {
284 let gmst00 = eraGmst00_safe(uta, utb, uta, utb)?; let ee00b = eraEe00b_safe(uta, utb)?;
286 eraAnp_safe(gmst00 + ee00b)
287}
288
289pub fn eraGst06_safe(
294 uta: f64,
295 utb: f64,
296 tta: f64,
297 ttb: f64,
298 rnpb: &[[f64; 3]; 3],
299) -> ErfaResult<f64> {
300 let (x, y) = eraBpn2xy_safe(rnpb)?;
301 let s = eraS06_safe(tta, ttb, x, y)?;
302 let era = eraEra00_safe(uta, utb)?;
303 let eors = eraEors_safe(rnpb, s)?;
304 eraAnp_safe(era - eors)
305}
306
307pub fn eraGst06a_safe(uta: f64, utb: f64, tta: f64, ttb: f64) -> ErfaResult<f64> {
312 let rnpb = eraPnm06a_safe(tta, ttb)?;
313 eraGst06_safe(uta, utb, tta, ttb, &rnpb)
314}
315
316pub fn eraGst94_safe(uta: f64, utb: f64) -> ErfaResult<f64> {
321 let gmst82 = eraGmst82_safe(uta, utb)?;
322 let eqeq94 = eraEqeq94_safe(uta, utb)?;
323 eraAnp_safe(gmst82 + eqeq94)
324}