1use crate::H1_safe::{
16 ERFA_D2PI, ERFA_DAS2R, ERFA_DAU, ERFA_DAYSEC, ERFA_DC, ERFA_DJ00, ERFA_DJC, ERFA_DJY,
17 ERFA_DR2AS,
18};
19
20use crate::G17_safe::eraGd2gc_safe;
21use crate::G1_safe::eraAnp_safe;
22use crate::G24_safe::{eraPdp_safe, eraPm_safe};
23use crate::G25_safe::{eraPmp_safe, eraPn_safe};
24use crate::G26_safe::{eraPom00_safe, eraPpp_safe, eraPpsp_safe};
25use crate::G30_safe::eraSxp_safe;
26use crate::G33_safe::eraTrxp_safe;
27use crate::G8_safe::{eraCp_safe, eraCpv_safe};
28
29pub type ErfaResult<T> = Result<T, ()>;
30
31pub fn eraPrec76_safe(
33 date01: f64,
34 date02: f64,
35 date11: f64,
36 date12: f64,
37) -> ErfaResult<(f64, f64, f64)> {
38 let t0 = ((date01 - ERFA_DJ00) + date02) / ERFA_DJC;
39 let t = ((date11 - date01) + (date12 - date02)) / ERFA_DJC;
40 let tas2r = t * ERFA_DAS2R;
41 let w = 2306.2181 + (1.39656 - 0.000139 * t0) * t0;
42 let zeta = (w + ((0.30188 - 0.000344 * t0) + 0.017998 * t) * t) * tas2r;
43 let z = (w + ((1.09468 + 0.000066 * t0) + 0.018203 * t) * t) * tas2r;
44 let theta = ((2004.3109 + (-0.85330 - 0.000217 * t0) * t0)
45 + ((-0.42665 - 0.000217 * t0) - 0.041833 * t) * t)
46 * tas2r;
47 Ok((zeta, z, theta))
48}
49
50pub fn eraPv2p_safe(pv: &[[f64; 3]; 2]) -> ErfaResult<[f64; 3]> {
52 Ok(pv[0])
53}
54
55pub fn eraPv2s_safe(pv: &[[f64; 3]; 2]) -> ErfaResult<(f64, f64, f64, f64, f64, f64)> {
57 let mut x = pv[0][0];
58 let mut y = pv[0][1];
59 let mut z = pv[0][2];
60 let xd = pv[1][0];
61 let yd = pv[1][1];
62 let zd = pv[1][2];
63
64 let mut rxy2 = x * x + y * y;
65 let mut r2 = rxy2 + z * z;
66 let rtrue = r2.sqrt();
67
68 let rw = if rtrue == 0.0 {
69 x = xd;
70 y = yd;
71 z = zd;
72 rxy2 = x * x + y * y;
73 r2 = rxy2 + z * z;
74 r2.sqrt()
75 } else {
76 rtrue
77 };
78
79 let rxy = rxy2.sqrt();
80 let xyp = x * xd + y * yd;
81 let (theta, phi, td, pd) = if rxy2 != 0.0 {
82 let theta = y.atan2(x);
83 let phi = z.atan2(rxy);
84 let td = (x * yd - y * xd) / rxy2;
85 let pd = (zd * rxy2 - z * xyp) / (r2 * rxy);
86 (theta, phi, td, pd)
87 } else {
88 let theta = 0.0;
89 let phi = if z != 0.0 { z.atan2(rxy) } else { 0.0 };
90 let td = 0.0;
91 let pd = 0.0;
92 (theta, phi, td, pd)
93 };
94 let r = rtrue;
95 let rd = if rw != 0.0 { (xyp + z * zd) / rw } else { 0.0 };
96
97 Ok((theta, phi, r, td, pd, rd))
98}
99
100pub fn eraPvdpv_safe(a: &[[f64; 3]; 2], b: &[[f64; 3]; 2]) -> ErfaResult<(f64, f64)> {
102 let p_dot = eraPdp_safe(&a[0], &b[0])?;
103 let adbd = eraPdp_safe(&a[0], &b[1])?;
104 let addb = eraPdp_safe(&a[1], &b[0])?;
105 let d_dot = adbd + addb;
106 Ok((p_dot, d_dot))
107}
108
109pub fn eraPvm_safe(pv: &[[f64; 3]; 2]) -> ErfaResult<(f64, f64)> {
111 let r = eraPm_safe(&pv[0])?;
112 let s = eraPm_safe(&pv[1])?;
113 Ok((r, s))
114}
115
116pub fn eraPvmpv_safe(a: &[[f64; 3]; 2], b: &[[f64; 3]; 2]) -> ErfaResult<[[f64; 3]; 2]> {
118 let p = eraPmp_safe(&a[0], &b[0])?;
119 let v = eraPmp_safe(&a[1], &b[1])?;
120 Ok([p, v])
121}
122
123pub fn eraPvppv_safe(a: &[[f64; 3]; 2], b: &[[f64; 3]; 2]) -> ErfaResult<[[f64; 3]; 2]> {
125 let p = eraPpp_safe(&a[0], &b[0])?;
126 let v = eraPpp_safe(&a[1], &b[1])?;
127 Ok([p, v])
128}
129
130pub fn eraPvstar_safe(pv: &[[f64; 3]; 2]) -> ErfaResult<((f64, f64, f64, f64, f64, f64), i32)> {
132 let (_r, pu) = eraPn_safe(&pv[0])?;
133 let vr = eraPdp_safe(&pu, &pv[1])?;
134 let ur = eraSxp_safe(vr, &pu)?;
135 let ut = eraPmp_safe(&pv[1], &ur)?;
136 let vt = eraPm_safe(&ut)?;
137
138 let bett = vt / ERFA_DC;
139 let betr = vr / ERFA_DC;
140 let d = 1.0 + betr;
141 let w = betr * betr + bett * bett;
142 if d == 0.0 || w > 1.0 {
143 return Ok(((0.0, 0.0, 0.0, 0.0, 0.0, 0.0), -1));
144 }
145 let del = -w / ((1.0 - w).sqrt() + 1.0);
146
147 let ust = eraSxp_safe(1.0 / d, &ut)?;
148 let usr = eraSxp_safe(ERFA_DC * (betr - del) / d, &pu)?;
149 let vnew = eraPpp_safe(&usr, &ust)?;
150 let pv_mod = [pv[0], vnew];
151
152 let (a, dec, r_out, rad, decd, rd) = eraPv2s_safe(&pv_mod)?;
153 if r_out == 0.0 {
154 return Ok(((0.0, 0.0, 0.0, 0.0, 0.0, 0.0), -2));
155 }
156
157 let ra = eraAnp_safe(a)?;
158 let pmr = rad * ERFA_DJY;
159 let pmd = decd * ERFA_DJY;
160 let px = ERFA_DR2AS / r_out;
161 let rv = 1e-3 * rd * ERFA_DAU / ERFA_DAYSEC;
162
163 Ok(((ra, dec, pmr, pmd, px, rv), 0))
164}
165
166pub fn eraPvtob_safe(
168 elong: f64,
169 phi: f64,
170 hm: f64,
171 xp: f64,
172 yp: f64,
173 sp: f64,
174 theta: f64,
175) -> ErfaResult<[[f64; 3]; 2]> {
176 const OM: f64 = 1.002_737_811_911_354_48 * ERFA_D2PI / ERFA_DAYSEC;
177
178 let (xyzm, _j) = eraGd2gc_safe(1, elong, phi, hm)?;
179 let rpm = eraPom00_safe(xp, yp, sp)?;
180 let xyz = eraTrxp_safe(&rpm, &xyzm)?;
181
182 let x = xyz[0];
183 let y = xyz[1];
184 let z = xyz[2];
185 let (s, c) = theta.sin_cos();
186
187 let px = c * x - s * y;
188 let py = s * x + c * y;
189 let pz = z;
190
191 let vx = OM * (-s * x - c * y);
192 let vy = OM * (c * x - s * y);
193 let vz = 0.0;
194
195 Ok([[px, py, pz], [vx, vy, vz]])
196}
197
198pub fn eraPvu_safe(dt: f64, pv: &[[f64; 3]; 2]) -> ErfaResult<[[f64; 3]; 2]> {
200 let p = eraPpsp_safe(&pv[0], dt, &pv[1])?;
201 let mut v = [0.0_f64; 3];
202 eraCp_safe(&pv[1], &mut v)?;
203 Ok([p, v])
204}
205
206pub fn eraPvup_safe(dt: f64, pv: &[[f64; 3]; 2]) -> ErfaResult<[f64; 3]> {
208 Ok([
209 pv[0][0] + dt * pv[1][0],
210 pv[0][1] + dt * pv[1][1],
211 pv[0][2] + dt * pv[1][2],
212 ])
213}
214
215pub fn eraPvxpv_safe(a: &[[f64; 3]; 2], b: &[[f64; 3]; 2]) -> ErfaResult<[[f64; 3]; 2]> {
217 let mut wa = [[0.0_f64; 3]; 2];
218 let mut wb = [[0.0_f64; 3]; 2];
219 eraCpv_safe(a, &mut wa)?;
220 eraCpv_safe(b, &mut wb)?;
221
222 let p = eraPxp_safe(&wa[0], &wb[0])?;
223 let axbd = eraPxp_safe(&wa[0], &wb[1])?;
224 let adxb = eraPxp_safe(&wa[1], &wb[0])?;
225 let v = eraPpp_safe(&axbd, &adxb)?;
226 Ok([p, v])
227}
228
229pub fn eraPxp_safe(a: &[f64; 3], b: &[f64; 3]) -> ErfaResult<[f64; 3]> {
231 let xa = a[0];
232 let ya = a[1];
233 let za = a[2];
234 let xb = b[0];
235 let yb = b[1];
236 let zb = b[2];
237
238 Ok([ya * zb - za * yb, za * xb - xa * zb, xa * yb - ya * xb])
239}