1use crate::G1_safe::{eraAb_safe, eraAnp_safe, eraApci13_safe};
14use crate::G20_safe::{eraLdn_safe, eraLdsun_safe};
15use crate::G25_safe::eraPmpx_safe;
16use crate::G28_safe::eraRxp_safe;
17use crate::G29_safe::eraS2c_safe;
18use crate::G2_safe::eraApco13_safe;
19use crate::G33_safe::eraTrxp_safe;
20use crate::G35_safe::eraZp_safe;
21use crate::G3_safe::eraApio13_safe;
22use crate::G7_safe::eraC2s_safe;
23use crate::H1_safe::{eraASTROM, eraLDBODY};
24
25pub type ErfaResult<T> = Result<T, ()>;
26
27pub fn eraAtci13_safe(
33 rc: f64,
34 dc: f64,
35 pr: f64,
36 pd: f64,
37 px: f64,
38 rv: f64,
39 date1: f64,
40 date2: f64,
41) -> ErfaResult<(f64, f64, f64)> {
42 let mut astrom = eraASTROM::default();
43 let eo = eraApci13_safe(date1, date2, &mut astrom)?;
44 let (ri, di) = eraAtciq_safe(rc, dc, pr, pd, px, rv, &astrom)?;
45 Ok((ri, di, eo))
46}
47
48pub fn eraAtciq_safe(
54 rc: f64,
55 dc: f64,
56 pr: f64,
57 pd: f64,
58 px: f64,
59 rv: f64,
60 astrom: &eraASTROM,
61) -> ErfaResult<(f64, f64)> {
62 let a = astrom;
63
64 let pco = eraPmpx_safe(rc, dc, pr, pd, px, rv, a.pmt, &a.eb)?;
66
67 let pnat = eraLdsun_safe(&pco, &a.eh, a.em)?;
69
70 let ppr = eraAb_safe(&pnat, &a.v, a.em, a.bm1)?;
72
73 let pi = eraRxp_safe(&a.bpn, &ppr)?;
75
76 let (w, di) = eraC2s_safe(&pi)?;
78 let ri = eraAnp_safe(w)?;
79 Ok((ri, di))
80}
81
82pub fn eraAtciqn_safe(
88 rc: f64,
89 dc: f64,
90 pr: f64,
91 pd: f64,
92 px: f64,
93 rv: f64,
94 astrom: &eraASTROM,
95 bodies: &[eraLDBODY],
96) -> ErfaResult<(f64, f64)> {
97 let a = astrom;
98
99 let pco = eraPmpx_safe(rc, dc, pr, pd, px, rv, a.pmt, &a.eb)?;
101
102 let pnat = eraLdn_safe(bodies, &a.eb, &pco)?;
104
105 let ppr = eraAb_safe(&pnat, &a.v, a.em, a.bm1)?;
107
108 let pi = eraRxp_safe(&a.bpn, &ppr)?;
110
111 let (w, di) = eraC2s_safe(&pi)?;
113 let ri = eraAnp_safe(w)?;
114 Ok((ri, di))
115}
116
117pub fn eraAtciqz_safe(rc: f64, dc: f64, astrom: &eraASTROM) -> ErfaResult<(f64, f64)> {
123 let a = astrom;
124
125 let pco = eraS2c_safe(rc, dc)?;
127
128 let pnat = eraLdsun_safe(&pco, &a.eh, a.em)?;
130 let ppr = eraAb_safe(&pnat, &a.v, a.em, a.bm1)?;
131
132 let pi = eraRxp_safe(&a.bpn, &ppr)?;
134
135 let (w, di) = eraC2s_safe(&pi)?;
137 let ri = eraAnp_safe(w)?;
138 Ok((ri, di))
139}
140
141pub fn eraAtco13_safe(
147 rc: f64,
148 dc: f64,
149 pr: f64,
150 pd: f64,
151 px: f64,
152 rv: f64,
153 utc1: f64,
154 utc2: f64,
155 dut1: f64,
156 elong: f64,
157 phi: f64,
158 hm: f64,
159 xp: f64,
160 yp: f64,
161 phpa: f64,
162 tc: f64,
163 rh: f64,
164 wl: f64,
165) -> ErfaResult<(f64, f64, f64, f64, f64, f64, i32)> {
166 let mut astrom = eraASTROM::default();
167
168 let (eo, j) = eraApco13_safe(
170 utc1,
171 utc2,
172 dut1,
173 elong,
174 phi,
175 hm,
176 xp,
177 yp,
178 phpa,
179 tc,
180 rh,
181 wl,
182 &mut astrom,
183 )?;
184
185 let (ri, di) = eraAtciq_safe(rc, dc, pr, pd, px, rv, &astrom)?;
187
188 let (aob, zob, hob, dob, rob) = eraAtioq_safe(ri, di, &astrom)?;
190 Ok((aob, zob, hob, dob, rob, eo, j))
191}
192
193pub fn eraAtic13_safe(ri: f64, di: f64, date1: f64, date2: f64) -> ErfaResult<(f64, f64, f64)> {
199 let mut astrom = eraASTROM::default();
200 let eo = eraApci13_safe(date1, date2, &mut astrom)?;
201 let (rc, dc) = eraAticq_safe(ri, di, &astrom)?;
202 Ok((rc, dc, eo))
203}
204
205pub fn eraAticq_safe(ri: f64, di: f64, astrom: &eraASTROM) -> ErfaResult<(f64, f64)> {
211 let a = astrom;
212
213 let pi = eraS2c_safe(ri, di)?;
215
216 let ppr = eraTrxp_safe(&a.bpn, &pi)?;
218
219 let mut d = eraZp_safe();
221 let mut pnat = [0.0_f64; 3];
222 let mut before = [0.0_f64; 3];
223 let mut after = [0.0_f64; 3];
224 for _ in 0..2 {
225 let mut r2 = 0.0;
227 for i in 0..3 {
228 let w = ppr[i] - d[i];
229 before[i] = w;
230 r2 += w * w;
231 }
232 let r = r2.sqrt();
233 for v in before.iter_mut() {
234 *v /= r;
235 }
236
237 let tmp = eraAb_safe(&before, &a.v, a.em, a.bm1)?;
239 after.copy_from_slice(&tmp);
240
241 let mut r2b = 0.0;
243 for i in 0..3 {
244 d[i] = after[i] - before[i];
245 let w = ppr[i] - d[i];
246 pnat[i] = w;
247 r2b += w * w;
248 }
249 let rb = r2b.sqrt();
250 for v in pnat.iter_mut() {
251 *v /= rb;
252 }
253 }
254
255 let mut pco = [0.0_f64; 3];
257 d = eraZp_safe();
258 for _ in 0..5 {
259 let mut r2 = 0.0;
261 for i in 0..3 {
262 let w = pnat[i] - d[i];
263 before[i] = w;
264 r2 += w * w;
265 }
266 let r = r2.sqrt();
267 for v in before.iter_mut() {
268 *v /= r;
269 }
270
271 let tmp = eraLdsun_safe(&before, &a.eh, a.em)?;
273 after.copy_from_slice(&tmp);
274
275 let mut r2b = 0.0;
277 for i in 0..3 {
278 d[i] = after[i] - before[i];
279 let w = pnat[i] - d[i];
280 pco[i] = w;
281 r2b += w * w;
282 }
283 let rb = r2b.sqrt();
284 for v in pco.iter_mut() {
285 *v /= rb;
286 }
287 }
288
289 let (w, dc) = eraC2s_safe(&pco)?;
291 let rc = eraAnp_safe(w)?;
292 Ok((rc, dc))
293}
294
295pub fn eraAticqn_safe(
301 ri: f64,
302 di: f64,
303 astrom: &eraASTROM,
304 bodies: &[eraLDBODY],
305) -> ErfaResult<(f64, f64)> {
306 let a = astrom;
307
308 let pi = eraS2c_safe(ri, di)?;
310 let ppr = eraTrxp_safe(&a.bpn, &pi)?;
311
312 let mut d = eraZp_safe();
314 let mut pnat = [0.0_f64; 3];
315 let mut before = [0.0_f64; 3];
316 let mut after = [0.0_f64; 3];
317 for _ in 0..2 {
318 let mut r2 = 0.0;
319 for i in 0..3 {
320 let w = ppr[i] - d[i];
321 before[i] = w;
322 r2 += w * w;
323 }
324 let r = r2.sqrt();
325 for v in before.iter_mut() {
326 *v /= r;
327 }
328 let tmp = eraAb_safe(&before, &a.v, a.em, a.bm1)?;
329 after.copy_from_slice(&tmp);
330 let mut r2b = 0.0;
331 for i in 0..3 {
332 d[i] = after[i] - before[i];
333 let w = ppr[i] - d[i];
334 pnat[i] = w;
335 r2b += w * w;
336 }
337 let rb = r2b.sqrt();
338 for v in pnat.iter_mut() {
339 *v /= rb;
340 }
341 }
342
343 let mut pco = [0.0_f64; 3];
345 d = eraZp_safe();
346 for _ in 0..5 {
347 let mut r2 = 0.0;
348 for i in 0..3 {
349 let w = pnat[i] - d[i];
350 before[i] = w;
351 r2 += w * w;
352 }
353 let r = r2.sqrt();
354 for v in before.iter_mut() {
355 *v /= r;
356 }
357 let tmp = eraLdn_safe(bodies, &a.eb, &before)?;
358 after.copy_from_slice(&tmp);
359 let mut r2b = 0.0;
360 for i in 0..3 {
361 d[i] = after[i] - before[i];
362 let w = pnat[i] - d[i];
363 pco[i] = w;
364 r2b += w * w;
365 }
366 let rb = r2b.sqrt();
367 for v in pco.iter_mut() {
368 *v /= rb;
369 }
370 }
371
372 let (w, dc) = eraC2s_safe(&pco)?;
374 let rc = eraAnp_safe(w)?;
375 Ok((rc, dc))
376}
377
378pub fn eraAtio13_safe(
384 ri: f64,
385 di: f64,
386 utc1: f64,
387 utc2: f64,
388 dut1: f64,
389 elong: f64,
390 phi: f64,
391 hm: f64,
392 xp: f64,
393 yp: f64,
394 phpa: f64,
395 tc: f64,
396 rh: f64,
397 wl: f64,
398) -> ErfaResult<(f64, f64, f64, f64, f64, i32)> {
399 let mut astrom = eraASTROM::default();
400 let j = eraApio13_safe(
401 utc1,
402 utc2,
403 dut1,
404 elong,
405 phi,
406 hm,
407 xp,
408 yp,
409 phpa,
410 tc,
411 rh,
412 wl,
413 &mut astrom,
414 )?;
415 let (aob, zob, hob, dob, rob) = eraAtioq_safe(ri, di, &astrom)?;
416 Ok((aob, zob, hob, dob, rob, j))
417}
418
419pub fn eraAtioq_safe(
425 ri: f64,
426 di: f64,
427 astrom: &eraASTROM,
428) -> ErfaResult<(f64, f64, f64, f64, f64)> {
429 const CELMIN: f64 = 1e-6;
430 const SELMIN: f64 = 0.05;
431
432 let a = astrom;
433
434 let v = eraS2c_safe(ri - a.eral, di)?;
436 let x = v[0];
437 let y = v[1];
438 let mut z = v[2];
439
440 let (sx, cx) = a.xpl.sin_cos();
442 let (sy, cy) = a.ypl.sin_cos();
443 let xhd = cx * x + sx * z;
444 let yhd = sx * sy * x + cy * y - cx * sy * z;
445 let zhd = -sx * cy * x + sy * y + cx * cy * z;
446
447 let f = 1.0 - a.diurab * yhd;
449 let xhdt = f * xhd;
450 let yhdt = f * (yhd + a.diurab);
451 let zhdt = f * zhd;
452
453 let xaet = a.sphi * xhdt - a.cphi * zhdt;
455 let yaet = yhdt;
456 let zaet = a.cphi * xhdt + a.sphi * zhdt;
457
458 let azobs = if xaet != 0.0 || yaet != 0.0 {
460 yaet.atan2(-xaet)
461 } else {
462 0.0
463 };
464
465 let mut r = (xaet * xaet + yaet * yaet).sqrt();
467 r = if r > CELMIN { r } else { CELMIN };
468 z = if zaet > SELMIN { zaet } else { SELMIN };
469
470 let tz = r / z;
472 let w = a.refb * tz * tz;
473 let del = (a.refa + w) * tz / (1.0 + (a.refa + 3.0 * w) / (z * z));
474
475 let cosdel = 1.0 - del * del / 2.0;
477 let f2 = cosdel - del * z / r;
478 let xaeo = xaet * f2;
479 let yaeo = yaet * f2;
480 let zaeo = cosdel * zaet + del * r;
481
482 let zdobs = ((xaeo * xaeo + yaeo * yaeo).sqrt()).atan2(zaeo);
484
485 let vx = a.sphi * xaeo + a.cphi * zaeo;
487 let vy = yaeo;
488 let vz = -a.cphi * xaeo + a.sphi * zaeo;
489 let v_obs = [vx, vy, vz];
490
491 let (hmobs, dcobs) = eraC2s_safe(&v_obs)?;
493
494 let raobs = a.eral + hmobs;
496
497 let aob = eraAnp_safe(azobs)?;
499 let zob = zdobs;
500 let hob = -hmobs;
501 let dob = dcobs;
502 let rob = eraAnp_safe(raobs)?;
503 Ok((aob, zob, hob, dob, rob))
504}