1use crate::G15_safe::{
11 eraFad03_safe, eraFae03_safe, eraFaf03_safe, eraFal03_safe, eraFalp03_safe, eraFaom03_safe,
12 eraFapa03_safe, eraFave03_safe,
13};
14use crate::G26_safe::{eraPnm00a_safe, eraPnm00b_safe};
15use crate::G6_safe::eraBpn2xy_safe;
16use crate::H1_safe::{ERFA_DAS2R, ERFA_DJ00, ERFA_DJC};
17
18pub type ErfaResult<T> = Result<T, ()>;
19
20pub fn eraS00_safe(date1: f64, date2: f64, x: f64, y: f64) -> ErfaResult<f64> {
25 let t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
27
28 #[derive(Clone, Copy)]
30 struct Term {
31 nfa: [i32; 8], s: f64, c: f64, }
35
36 const SP: [f64; 6] = [
38 94.00e-6,
39 3808.35e-6,
40 -119.94e-6,
41 -72574.09e-6,
42 27.70e-6,
43 15.61e-6,
44 ];
45
46 const S0: [Term; 33] = [
48 Term {
49 nfa: [0, 0, 0, 0, 1, 0, 0, 0],
50 s: -2640.73e-6,
51 c: 0.39e-6,
52 },
53 Term {
54 nfa: [0, 0, 0, 0, 2, 0, 0, 0],
55 s: -63.53e-6,
56 c: 0.02e-6,
57 },
58 Term {
59 nfa: [0, 0, 2, -2, 3, 0, 0, 0],
60 s: -11.75e-6,
61 c: -0.01e-6,
62 },
63 Term {
64 nfa: [0, 0, 2, -2, 1, 0, 0, 0],
65 s: -11.21e-6,
66 c: -0.01e-6,
67 },
68 Term {
69 nfa: [0, 0, 2, -2, 2, 0, 0, 0],
70 s: 4.57e-6,
71 c: 0.00e-6,
72 },
73 Term {
74 nfa: [0, 0, 2, 0, 3, 0, 0, 0],
75 s: -2.02e-6,
76 c: 0.00e-6,
77 },
78 Term {
79 nfa: [0, 0, 2, 0, 1, 0, 0, 0],
80 s: -1.98e-6,
81 c: 0.00e-6,
82 },
83 Term {
84 nfa: [0, 0, 0, 0, 3, 0, 0, 0],
85 s: 1.72e-6,
86 c: 0.00e-6,
87 },
88 Term {
89 nfa: [0, 1, 0, 0, 1, 0, 0, 0],
90 s: 1.41e-6,
91 c: 0.01e-6,
92 },
93 Term {
94 nfa: [0, 1, 0, 0, -1, 0, 0, 0],
95 s: 1.26e-6,
96 c: 0.01e-6,
97 },
98 Term {
99 nfa: [1, 0, 0, 0, -1, 0, 0, 0],
100 s: 0.63e-6,
101 c: 0.00e-6,
102 },
103 Term {
104 nfa: [1, 0, 0, 0, 1, 0, 0, 0],
105 s: 0.63e-6,
106 c: 0.00e-6,
107 },
108 Term {
109 nfa: [0, 1, 2, -2, 3, 0, 0, 0],
110 s: -0.46e-6,
111 c: 0.00e-6,
112 },
113 Term {
114 nfa: [0, 1, 2, -2, 1, 0, 0, 0],
115 s: -0.45e-6,
116 c: 0.00e-6,
117 },
118 Term {
119 nfa: [0, 0, 4, -4, 4, 0, 0, 0],
120 s: -0.36e-6,
121 c: 0.00e-6,
122 },
123 Term {
124 nfa: [0, 0, 1, -1, 1, -8, 12, 0],
125 s: 0.24e-6,
126 c: 0.12e-6,
127 },
128 Term {
129 nfa: [0, 0, 2, 0, 0, 0, 0, 0],
130 s: -0.32e-6,
131 c: 0.00e-6,
132 },
133 Term {
134 nfa: [0, 0, 2, 0, 2, 0, 0, 0],
135 s: -0.28e-6,
136 c: 0.00e-6,
137 },
138 Term {
139 nfa: [1, 0, 2, 0, 3, 0, 0, 0],
140 s: -0.27e-6,
141 c: 0.00e-6,
142 },
143 Term {
144 nfa: [1, 0, 2, 0, 1, 0, 0, 0],
145 s: -0.26e-6,
146 c: 0.00e-6,
147 },
148 Term {
149 nfa: [0, 0, 2, -2, 0, 0, 0, 0],
150 s: 0.21e-6,
151 c: 0.00e-6,
152 },
153 Term {
154 nfa: [0, 1, -2, 2, -3, 0, 0, 0],
155 s: -0.19e-6,
156 c: 0.00e-6,
157 },
158 Term {
159 nfa: [0, 1, -2, 2, -1, 0, 0, 0],
160 s: -0.18e-6,
161 c: 0.00e-6,
162 },
163 Term {
164 nfa: [0, 0, 0, 0, 0, 8, -13, -1],
165 s: 0.10e-6,
166 c: -0.05e-6,
167 },
168 Term {
169 nfa: [0, 0, 0, 2, 0, 0, 0, 0],
170 s: -0.15e-6,
171 c: 0.00e-6,
172 },
173 Term {
174 nfa: [2, 0, -2, 0, -1, 0, 0, 0],
175 s: 0.14e-6,
176 c: 0.00e-6,
177 },
178 Term {
179 nfa: [0, 1, 2, -2, 2, 0, 0, 0],
180 s: 0.14e-6,
181 c: 0.00e-6,
182 },
183 Term {
184 nfa: [1, 0, 0, -2, 1, 0, 0, 0],
185 s: -0.14e-6,
186 c: 0.00e-6,
187 },
188 Term {
189 nfa: [1, 0, 0, -2, -1, 0, 0, 0],
190 s: -0.14e-6,
191 c: 0.00e-6,
192 },
193 Term {
194 nfa: [0, 0, 4, -2, 4, 0, 0, 0],
195 s: -0.13e-6,
196 c: 0.00e-6,
197 },
198 Term {
199 nfa: [0, 0, 2, -2, 4, 0, 0, 0],
200 s: 0.11e-6,
201 c: 0.00e-6,
202 },
203 Term {
204 nfa: [1, 0, -2, 0, -3, 0, 0, 0],
205 s: -0.11e-6,
206 c: 0.00e-6,
207 },
208 Term {
209 nfa: [1, 0, -2, 0, -1, 0, 0, 0],
210 s: -0.11e-6,
211 c: 0.00e-6,
212 },
213 ];
214
215 const S1: [Term; 3] = [
217 Term {
218 nfa: [0, 0, 0, 0, 2, 0, 0, 0],
219 s: -0.07e-6,
220 c: 3.57e-6,
221 },
222 Term {
223 nfa: [0, 0, 0, 0, 1, 0, 0, 0],
224 s: 1.71e-6,
225 c: -0.03e-6,
226 },
227 Term {
228 nfa: [0, 0, 2, -2, 3, 0, 0, 0],
229 s: 0.00e-6,
230 c: 0.48e-6,
231 },
232 ];
233
234 const S2: [Term; 25] = [
236 Term {
237 nfa: [0, 0, 0, 0, 1, 0, 0, 0],
238 s: 743.53e-6,
239 c: -0.17e-6,
240 },
241 Term {
242 nfa: [0, 0, 2, -2, 2, 0, 0, 0],
243 s: 56.91e-6,
244 c: 0.06e-6,
245 },
246 Term {
247 nfa: [0, 0, 2, 0, 2, 0, 0, 0],
248 s: 9.84e-6,
249 c: -0.01e-6,
250 },
251 Term {
252 nfa: [0, 0, 0, 0, 2, 0, 0, 0],
253 s: -8.85e-6,
254 c: 0.01e-6,
255 },
256 Term {
257 nfa: [0, 1, 0, 0, 0, 0, 0, 0],
258 s: -6.38e-6,
259 c: -0.05e-6,
260 },
261 Term {
262 nfa: [1, 0, 0, 0, 0, 0, 0, 0],
263 s: -3.07e-6,
264 c: 0.00e-6,
265 },
266 Term {
267 nfa: [0, 1, 2, -2, 2, 0, 0, 0],
268 s: 2.23e-6,
269 c: 0.00e-6,
270 },
271 Term {
272 nfa: [0, 0, 2, 0, 1, 0, 0, 0],
273 s: 1.67e-6,
274 c: 0.00e-6,
275 },
276 Term {
277 nfa: [1, 0, 2, 0, 2, 0, 0, 0],
278 s: 1.30e-6,
279 c: 0.00e-6,
280 },
281 Term {
282 nfa: [0, 1, -2, 2, -2, 0, 0, 0],
283 s: 0.93e-6,
284 c: 0.00e-6,
285 },
286 Term {
287 nfa: [1, 0, 0, -2, 0, 0, 0, 0],
288 s: 0.68e-6,
289 c: 0.00e-6,
290 },
291 Term {
292 nfa: [0, 0, 2, -2, 1, 0, 0, 0],
293 s: -0.55e-6,
294 c: 0.00e-6,
295 },
296 Term {
297 nfa: [1, 0, -2, 0, -2, 0, 0, 0],
298 s: 0.53e-6,
299 c: 0.00e-6,
300 },
301 Term {
302 nfa: [0, 0, 0, 2, 0, 0, 0, 0],
303 s: -0.27e-6,
304 c: 0.00e-6,
305 },
306 Term {
307 nfa: [1, 0, 0, 0, 1, 0, 0, 0],
308 s: -0.27e-6,
309 c: 0.00e-6,
310 },
311 Term {
312 nfa: [1, 0, -2, -2, -2, 0, 0, 0],
313 s: -0.26e-6,
314 c: 0.00e-6,
315 },
316 Term {
317 nfa: [1, 0, 0, 0, -1, 0, 0, 0],
318 s: -0.25e-6,
319 c: 0.00e-6,
320 },
321 Term {
322 nfa: [1, 0, 2, 0, 1, 0, 0, 0],
323 s: 0.22e-6,
324 c: 0.00e-6,
325 },
326 Term {
327 nfa: [2, 0, 0, -2, 0, 0, 0, 0],
328 s: -0.21e-6,
329 c: 0.00e-6,
330 },
331 Term {
332 nfa: [2, 0, -2, 0, -1, 0, 0, 0],
333 s: 0.20e-6,
334 c: 0.00e-6,
335 },
336 Term {
337 nfa: [0, 0, 2, 2, 2, 0, 0, 0],
338 s: 0.17e-6,
339 c: 0.00e-6,
340 },
341 Term {
342 nfa: [2, 0, 2, 0, 2, 0, 0, 0],
343 s: 0.13e-6,
344 c: 0.00e-6,
345 },
346 Term {
347 nfa: [2, 0, 0, 0, 0, 0, 0, 0],
348 s: -0.13e-6,
349 c: 0.00e-6,
350 },
351 Term {
352 nfa: [1, 0, 2, -2, 2, 0, 0, 0],
353 s: -0.12e-6,
354 c: 0.00e-6,
355 },
356 Term {
357 nfa: [0, 0, 2, 0, 0, 0, 0, 0],
358 s: -0.11e-6,
359 c: 0.00e-6,
360 },
361 ];
362
363 const S3: [Term; 4] = [
365 Term {
366 nfa: [0, 0, 0, 0, 1, 0, 0, 0],
367 s: 0.30e-6,
368 c: -23.51e-6,
369 },
370 Term {
371 nfa: [0, 0, 2, -2, 2, 0, 0, 0],
372 s: -0.03e-6,
373 c: -1.39e-6,
374 },
375 Term {
376 nfa: [0, 0, 2, 0, 2, 0, 0, 0],
377 s: -0.01e-6,
378 c: -0.24e-6,
379 },
380 Term {
381 nfa: [0, 0, 0, 0, 2, 0, 0, 0],
382 s: 0.00e-6,
383 c: 0.22e-6,
384 },
385 ];
386
387 const S4: [Term; 1] = [Term {
389 nfa: [0, 0, 0, 0, 1, 0, 0, 0],
390 s: -0.26e-6,
391 c: -0.01e-6,
392 }];
393
394 let mut fa = [0.0_f64; 8];
396 fa[0] = eraFal03_safe(t)?;
397 fa[1] = eraFalp03_safe(t)?;
398 fa[2] = eraFaf03_safe(t)?;
399 fa[3] = eraFad03_safe(t)?;
400 fa[4] = eraFaom03_safe(t)?;
401 fa[5] = eraFave03_safe(t)?;
402 fa[6] = eraFae03_safe(t)?;
403 fa[7] = eraFapa03_safe(t)?;
404
405 let mut w = [SP[0], SP[1], SP[2], SP[3], SP[4], SP[5]];
407
408 #[inline(always)]
409 fn accum(arr: &[Term], idx: usize, fa: &[f64; 8], w: &mut [f64; 6]) {
410 for term in arr {
411 let mut a = 0.0_f64;
412 for j in 0..8 {
413 a += (term.nfa[j] as f64) * fa[j];
414 }
415 w[idx] += term.s * a.sin() + term.c * a.cos();
416 }
417 }
418 accum(&S0, 0, &fa, &mut w);
419 accum(&S1, 1, &fa, &mut w);
420 accum(&S2, 2, &fa, &mut w);
421 accum(&S3, 3, &fa, &mut w);
422 accum(&S4, 4, &fa, &mut w);
423
424 let s = (w[0] + (w[1] + (w[2] + (w[3] + (w[4] + w[5] * t) * t) * t) * t) * t) * ERFA_DAS2R
426 - x * y / 2.0;
427
428 Ok(s)
429}
430
431pub fn eraS00a_safe(date1: f64, date2: f64) -> ErfaResult<f64> {
436 let rbpn = eraPnm00a_safe(date1, date2)?;
437 let (x, y) = eraBpn2xy_safe(&rbpn)?;
438 eraS00_safe(date1, date2, x, y)
439}
440
441pub fn eraS00b_safe(date1: f64, date2: f64) -> ErfaResult<f64> {
446 let rbpn = eraPnm00b_safe(date1, date2)?;
447 let (x, y) = eraBpn2xy_safe(&rbpn)?;
448 eraS00_safe(date1, date2, x, y)
449}
450
451pub fn eraS2c_safe(theta: f64, phi: f64) -> ErfaResult<[f64; 3]> {
456 let cp = phi.cos();
457 Ok([theta.cos() * cp, theta.sin() * cp, phi.sin()])
458}
459
460pub fn eraS2p_safe(theta: f64, phi: f64, r: f64) -> ErfaResult<[f64; 3]> {
465 let u = eraS2c_safe(theta, phi)?;
466 Ok([r * u[0], r * u[1], r * u[2]])
467}
468
469pub fn eraS2pv_safe(
474 theta: f64,
475 phi: f64,
476 r: f64,
477 td: f64,
478 pd: f64,
479 rd: f64,
480) -> ErfaResult<[[f64; 3]; 2]> {
481 let st = theta.sin();
482 let ct = theta.cos();
483 let sp = phi.sin();
484 let cp = phi.cos();
485
486 let rcp = r * cp;
487 let x = rcp * ct;
488 let y = rcp * st;
489 let rpd = r * pd;
490 let w = rpd * sp - cp * rd;
491
492 let p = [x, y, r * sp];
493 let v = [-y * td - w * ct, x * td - w * st, rpd * cp + sp * rd];
494
495 Ok([p, v])
496}
497
498pub fn eraS2xpv_safe(s1: f64, s2: f64, pv: &[[f64; 3]; 2]) -> ErfaResult<[[f64; 3]; 2]> {
503 let p = [s1 * pv[0][0], s1 * pv[0][1], s1 * pv[0][2]];
504 let v = [s2 * pv[1][0], s2 * pv[1][1], s2 * pv[1][2]];
505 Ok([p, v])
506}