1use crate::H1_safe::{ERFA_DJ00, ERFA_DJY, ERFA_DR2AS};
12
13use crate::G12_safe::{eraEpb2jd_safe, eraEpj_safe};
14use crate::G15_safe::eraFk5hip_safe;
15use crate::G1_safe::eraAnp_safe;
16use crate::G6_safe::eraBpn2xy_safe;
17use crate::G7_safe::eraC2s_safe;
18
19use crate::G19_safe::eraIr_safe;
20
21use crate::G24_safe::{eraPdp_safe, eraPm_safe};
22use crate::G25_safe::eraPmp_safe;
23use crate::G26_safe::eraPpp_safe;
24use crate::G27_safe::{
25 eraPv2s_safe, eraPvmpv_safe, eraPvppv_safe, eraPvstar_safe, eraPvu_safe, eraPxp_safe,
26};
27use crate::G28_safe::{eraRv2m_safe, eraRx_safe, eraRxp_safe, eraRz_safe};
28use crate::G29_safe::{eraS2c_safe, eraS2pv_safe};
29use crate::G30_safe::eraStarpv_safe;
30use crate::G33_safe::eraTrxp_safe;
31
32pub type ErfaResult<T> = Result<T, ()>;
33
34pub fn eraFk425_safe(
38 r1950: f64,
39 d1950: f64,
40 dr1950: f64,
41 dd1950: f64,
42 p1950: f64,
43 v1950: f64,
44) -> ErfaResult<(f64, f64, f64, f64, f64, f64)> {
45 const PMF: f64 = 100.0 * ERFA_DR2AS; const TINY: f64 = 1.0e-30;
47 const VF: f64 = 21.095; const A: [[f64; 3]; 2] = [
51 [-1.62557e-6, -0.31919e-6, -0.13843e-6],
52 [1.245e-3, -1.580e-3, -0.659e-3],
53 ];
54
55 const EM: [[[[f64; 3]; 2]; 3]; 2] = [
57 [
58 [
59 [0.999_925_678_2, -0.011_182_061_1, -0.004_857_947_7],
60 [
61 0.000_002_423_950_18,
62 -0.000_000_027_106_63,
63 -0.000_000_011_776_56,
64 ],
65 ],
66 [
67 [0.011_182_061_0, 0.999_937_478_4, -0.000_027_176_5],
68 [
69 0.000_000_027_106_63,
70 0.000_002_423_978_78,
71 -0.000_000_000_065_87,
72 ],
73 ],
74 [
75 [0.004_857_947_9, -0.000_027_147_4, 0.999_988_199_7],
76 [
77 0.000_000_011_776_56,
78 -0.000_000_000_065_82,
79 0.000_002_424_101_73,
80 ],
81 ],
82 ],
83 [
84 [
85 [-0.000_551, -0.238_565, 0.435_739],
86 [0.999_947_04, -0.011_182_51, -0.004_857_67],
87 ],
88 [
89 [0.238_514, -0.002_667, -0.008_541],
90 [0.011_182_51, 0.999_958_83, -0.000_027_18],
91 ],
92 [
93 [-0.435_623, 0.012_254, 0.002_117],
94 [0.004_857_67, -0.000_027_14, 1.000_009_56],
95 ],
96 ],
97 ];
98
99 let ur = dr1950 * PMF;
101 let ud = dd1950 * PMF;
102 let mut px = p1950;
103 let mut rv = v1950;
104 let pxvf = px * VF;
105 let w_rv = rv * pxvf;
106
107 let r0 = eraS2pv_safe(r1950, d1950, 1.0, ur, ud, w_rv)?;
108
109 let mut pv1 = eraPvmpv_safe(&r0, &A)?;
111
112 let s_pos = eraPdp_safe(&r0[0], &A[0])?;
114 let v_pos = eraPdp_safe(&r0[0], &A[1])?;
115 let cpos = eraSxp_safe(s_pos, &r0[0])?;
116 let cvel = eraSxp_safe(v_pos, &r0[0])?;
117 let pv2 = [cpos, cvel];
118 pv1 = eraPvppv_safe(&pv1, &pv2)?;
119
120 let mut pv2_out = [[0.0_f64; 3]; 2];
122 for i in 0..2 {
123 for j in 0..3 {
124 let mut sum = 0.0_f64;
125 for k in 0..2 {
126 for l in 0..3 {
127 sum += EM[i][j][k][l] * pv1[k][l];
128 }
129 }
130 pv2_out[i][j] = sum;
131 }
132 }
133
134 let (r, d, w_scale, ur_out, ud_out, rd) = eraPv2s_safe(&pv2_out)?;
136 if px > TINY {
137 rv = rd / pxvf;
138 px = px / w_scale;
139 }
140
141 let r2000 = eraAnp_safe(r)?;
142 let d2000 = d;
143 let dr2000 = ur_out / PMF;
144 let dd2000 = ud_out / PMF;
145 let p2000 = px;
146 let v2000 = rv;
147
148 Ok((r2000, d2000, dr2000, dd2000, p2000, v2000))
149}
150
151pub fn eraFk45z_safe(r1950: f64, d1950: f64, bepoch: f64) -> ErfaResult<(f64, f64)> {
155 const PMF: f64 = 100.0 * ERFA_DR2AS;
156
157 const A: [f64; 3] = [-1.62557e-6, -0.31919e-6, -0.13843e-6];
158 const AD: [f64; 3] = [1.245e-3, -1.580e-3, -0.659e-3];
159
160 const EM: [[[f64; 3]; 3]; 2] = [
161 [
162 [0.999_925_678_2, -0.011_182_061_1, -0.004_857_947_7],
163 [0.011_182_061_0, 0.999_937_478_4, -0.000_027_176_5],
164 [0.004_857_947_9, -0.000_027_147_4, 0.999_988_199_7],
165 ],
166 [
167 [-0.000_551, -0.238_565, 0.435_739],
168 [0.238_514, -0.002_667, -0.008_541],
169 [-0.435_623, 0.012_254, 0.002_117],
170 ],
171 ];
172
173 let r0 = eraS2c_safe(r1950, d1950)?;
175
176 let w_epoch = (bepoch - 1950.0) / PMF;
178 let mut p = eraPpsp_safe(&A, w_epoch, &AD)?;
179
180 let dot = eraPdp_safe(&r0, &p)?;
182 p = eraPpsp_safe(&p, -dot, &r0)?;
183
184 p = eraPmp_safe(&r0, &p)?;
186
187 let mut pv = [[0.0_f64; 3]; 2];
189 for i in 0..2 {
190 for j in 0..3 {
191 let mut sum = 0.0_f64;
192 for k in 0..3 {
193 sum += EM[i][j][k] * p[k];
194 }
195 pv[i][j] = sum;
196 }
197 }
198
199 let (djm0, djm) = eraEpb2jd_safe(bepoch)?;
201 let w_years = (eraEpj_safe(djm0, djm)? - 2000.0) / PMF;
202 let pv = eraPvu_safe(w_years, &pv)?;
203
204 let (ra, d2000) = eraC2s_safe(&pv[0])?;
206 let r2000 = eraAnp_safe(ra)?;
207 Ok((r2000, d2000))
208}
209
210pub fn eraFk524_safe(
214 r2000: f64,
215 d2000: f64,
216 dr2000: f64,
217 dd2000: f64,
218 p2000: f64,
219 v2000: f64,
220) -> ErfaResult<(f64, f64, f64, f64, f64, f64)> {
221 const PMF: f64 = 100.0 * ERFA_DR2AS;
222 const TINY: f64 = 1.0e-30;
223 const VF: f64 = 21.095;
224
225 const A: [[f64; 3]; 2] = [
226 [-1.62557e-6, -0.31919e-6, -0.13843e-6],
227 [1.245e-3, -1.580e-3, -0.659e-3],
228 ];
229
230 const EM: [[[[f64; 3]; 2]; 3]; 2] = [
231 [
232 [
233 [0.999_925_679_5, 0.011_181_482_8, 0.004_859_003_9],
234 [
235 -0.000_002_423_898_40,
236 -0.000_000_027_105_44,
237 -0.000_000_011_777_42,
238 ],
239 ],
240 [
241 [-0.011_181_482_8, 0.999_937_484_9, -0.000_027_177_1],
242 [
243 0.000_000_027_105_44,
244 -0.000_002_423_927_02,
245 0.000_000_000_065_85,
246 ],
247 ],
248 [
249 [-0.004_859_004_0, -0.000_027_155_7, 0.999_988_194_6],
250 [
251 0.000_000_011_777_42,
252 0.000_000_000_065_85,
253 -0.000_002_424_049_95,
254 ],
255 ],
256 ],
257 [
258 [
259 [-0.000_551, 0.238_509, -0.435_614],
260 [0.999_904_32, 0.011_181_45, 0.004_858_52],
261 ],
262 [
263 [-0.238_560, -0.002_667, 0.012_254],
264 [-0.011_181_45, 0.999_916_13, -0.000_027_17],
265 ],
266 [
267 [0.435_730, -0.008_541, 0.002_117],
268 [-0.004_858_52, -0.000_027_16, 0.999_966_84],
269 ],
270 ],
271 ];
272
273 let pxvf = p2000 * VF;
275 let w_rv = v2000 * pxvf;
276 let r0 = eraS2pv_safe(r2000, d2000, 1.0, dr2000 * PMF, dd2000 * PMF, w_rv)?;
277
278 let mut r1 = [[0.0_f64; 3]; 2];
280 for i in 0..2 {
281 for j in 0..3 {
282 let mut sum = 0.0_f64;
283 for k in 0..2 {
284 for l in 0..3 {
285 sum += EM[i][j][k][l] * r0[k][l];
286 }
287 }
288 r1[i][j] = sum;
289 }
290 }
291
292 let len_r1 = eraPm_safe(&r1[0])?;
295 let mut p1 = eraSxp_safe(eraPdp_safe(&r1[0], &A[0])?, &r1[0])?;
296 let mut p2 = eraSxp_safe(len_r1, &A[0])?;
297 p1 = eraPmp_safe(&p2, &p1)?;
298 p1 = eraPpp_safe(&r1[0], &p1)?;
299
300 let len_p1 = eraPm_safe(&p1)?;
302 p1 = eraSxp_safe(eraPdp_safe(&r1[0], &A[0])?, &r1[0])?;
303 p2 = eraSxp_safe(len_p1, &A[0])?;
304 p1 = eraPmp_safe(&p2, &p1)?;
305 let mut pv = [[0.0_f64; 3]; 2];
306 pv[0] = eraPpp_safe(&r1[0], &p1)?;
307
308 let q1 = eraSxp_safe(eraPdp_safe(&r1[0], &A[1])?, &pv[0])?;
310 let q2 = eraSxp_safe(len_p1, &A[1])?;
311 let q = eraPmp_safe(&q2, &q1)?;
312 pv[1] = eraPpp_safe(&r1[1], &q)?;
313
314 let (ra, dec, w_scale, ur, ud, rd) = eraPv2s_safe(&pv)?;
316
317 let mut px = p2000;
318 let mut rv = v2000;
319 if px > TINY {
320 rv = rd / pxvf;
321 px = px / w_scale;
322 }
323
324 let r1950 = eraAnp_safe(ra)?;
325 let d1950 = dec;
326 let dr1950 = ur / PMF;
327 let dd1950 = ud / PMF;
328 let p1950 = px;
329 let v1950 = rv;
330
331 Ok((r1950, d1950, dr1950, dd1950, p1950, v1950))
332}
333
334pub fn eraFk52h_safe(
338 r5: f64,
339 d5: f64,
340 dr5: f64,
341 dd5: f64,
342 px5: f64,
343 rv5: f64,
344) -> ErfaResult<(f64, f64, f64, f64, f64, f64)> {
345 let (pv5, _warn) = eraStarpv_safe(r5, d5, dr5, dd5, px5, rv5)?;
346
347 let (r5h_m, mut s5h) = eraFk5hip_safe()?;
348
349 for v in &mut s5h {
351 *v /= 365.25;
352 }
353
354 let pvh_pos = eraRxp_safe(&r5h_m, &pv5[0])?;
356
357 let wxp = eraPxp_safe(&pv5[0], &s5h)?;
359 let vv = eraPpp_safe(&wxp, &pv5[1])?;
360 let pvh_vel = eraRxp_safe(&r5h_m, &vv)?;
361
362 let pvh = [pvh_pos, pvh_vel];
363 let ((rh, dh, drh, ddh, pxh, rvh), _j) = eraPvstar_safe(&pvh)?;
364 Ok((rh, dh, drh, ddh, pxh, rvh))
365}
366
367pub fn eraFk54z_safe(r2000: f64, d2000: f64, bepoch: f64) -> ErfaResult<(f64, f64, f64, f64)> {
371 let (r, d, pr, pd, _px, _rv) = eraFk524_safe(r2000, d2000, 0.0, 0.0, 0.0, 0.0)?;
372
373 let mut p = eraS2c_safe(r, d)?;
375
376 let v = [
378 -pr * p[1] - pd * r.cos() * d.sin(),
379 pr * p[0] - pd * r.sin() * d.sin(),
380 pd * d.cos(),
381 ];
382
383 let dt = bepoch - 1950.0;
385 for i in 0..3 {
386 p[i] += dt * v[i];
387 }
388
389 let (ra, d1950) = eraC2s_safe(&p)?;
391 let r1950 = eraAnp_safe(ra)?;
392 let dr1950 = pr;
393 let dd1950 = pd;
394
395 Ok((r1950, d1950, dr1950, dd1950))
396}
397
398pub fn eraFk5hz_safe(r5: f64, d5: f64, date1: f64, date2: f64) -> ErfaResult<(f64, f64)> {
402 let t = -((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
404
405 let p5e = eraS2c_safe(r5, d5)?;
406
407 let (r5h, s5h) = eraFk5hip_safe()?;
408
409 let vst = eraSxp_safe(t, &s5h)?;
411 let rst = eraRv2m_safe(&vst)?;
412
413 let p5 = eraTrxp_safe(&rst, &p5e)?;
415 let ph = eraRxp_safe(&r5h, &p5)?;
416
417 let (ra, dh) = eraC2s_safe(&ph)?;
418 let rh = eraAnp_safe(ra)?;
419 Ok((rh, dh))
420}
421
422pub fn eraFw2m_safe(gamb: f64, phib: f64, psi: f64, eps: f64) -> ErfaResult<[[f64; 3]; 3]> {
426 let mut r = [[0.0_f64; 3]; 3];
427 eraIr_safe(&mut r)?;
428 eraRz_safe(gamb, &mut r)?;
429 eraRx_safe(phib, &mut r)?;
430 eraRz_safe(-psi, &mut r)?;
431 eraRx_safe(-eps, &mut r)?;
432 Ok(r)
433}
434
435pub fn eraFw2xy_safe(gamb: f64, phib: f64, psi: f64, eps: f64) -> ErfaResult<(f64, f64)> {
439 let rmat = eraFw2m_safe(gamb, phib, psi, eps)?;
440 let (x, y) = eraBpn2xy_safe(&rmat)?;
441 Ok((x, y))
442}
443
444#[inline]
446fn eraSxp_safe(s: f64, p: &[f64; 3]) -> ErfaResult<[f64; 3]> {
447 Ok([s * p[0], s * p[1], s * p[2]])
448}
449
450#[inline]
452fn eraPpsp_safe(a: &[f64; 3], s: f64, b: &[f64; 3]) -> ErfaResult<[f64; 3]> {
453 Ok([a[0] + s * b[0], a[1] + s * b[1], a[2] + s * b[2]])
454}