1pub type ErfaResult<T> = Result<T, ()>;
13
14pub fn eraRefco_safe(phpa: f64, tc: f64, rh: f64, wl: f64) -> ErfaResult<(f64, f64)> {
16 let optic = wl <= 100.0;
18
19 let mut t = if tc > -150.0 { tc } else { -150.0 };
21 t = if t < 200.0 { t } else { 200.0 };
22 let mut p = if phpa > 0.0 { phpa } else { 0.0 };
23 p = if p < 10_000.0 { p } else { 10_000.0 };
24 let mut r = if rh > 0.0 { rh } else { 0.0 };
25 r = if r < 1.0 { r } else { 1.0 };
26 let mut w = if wl > 0.1 { wl } else { 0.1 };
27 w = if w < 1.0e6 { w } else { 1.0e6 };
28
29 let pw = if p > 0.0 {
31 let ps = 10f64.powf((0.7859 + 0.03477 * t) / (1.0 + 0.00412 * t))
32 * (1.0 + p * (4.5e-6 + 6e-10 * t * t));
33 r * ps / (1.0 - (1.0 - r) * ps / p)
34 } else {
35 0.0
36 };
37
38 let tk = t + 273.15;
40 let gamma = if optic {
41 let wlsq = w * w;
42 (((77.534_84e-6) + (4.391_08e-7 + 3.666e-9 / wlsq) / wlsq) * p - 11.2684e-6 * pw) / tk
43 } else {
44 (77.6890e-6 * p - (6.3938e-6 - 0.375_463 / tk) * pw) / tk
45 };
46
47 let mut beta = 4.4474e-6 * tk;
49 if !optic {
50 beta -= 0.0074 * pw * beta;
51 }
52
53 let refa = gamma * (1.0 - beta);
55 let refb = -gamma * (beta - gamma / 2.0);
56
57 Ok((refa, refb))
58}
59
60pub fn eraRm2v_safe(r: &[[f64; 3]; 3]) -> ErfaResult<[f64; 3]> {
62 let x = r[1][2] - r[2][1];
63 let y = r[2][0] - r[0][2];
64 let z = r[0][1] - r[1][0];
65 let s2 = (x * x + y * y + z * z).sqrt();
66
67 let w = if s2 > 0.0 {
68 let c2 = r[0][0] + r[1][1] + r[2][2] - 1.0;
69 let phi = s2.atan2(c2);
70 let f = phi / s2;
71 [x * f, y * f, z * f]
72 } else {
73 [0.0, 0.0, 0.0]
74 };
75
76 Ok(w)
77}
78
79pub fn eraRv2m_safe(w: &[f64; 3]) -> ErfaResult<[[f64; 3]; 3]> {
81 let x0 = w[0];
82 let y0 = w[1];
83 let z0 = w[2];
84 let phi = (x0 * x0 + y0 * y0 + z0 * z0).sqrt();
85 let s = phi.sin();
86 let c = phi.cos();
87 let f = 1.0 - c;
88
89 let (mut x, mut y, mut z) = (x0, y0, z0);
90 if phi > 0.0 {
91 x /= phi;
92 y /= phi;
93 z /= phi;
94 }
95
96 let r = [
97 [x * x * f + c, x * y * f + z * s, x * z * f - y * s],
98 [y * x * f - z * s, y * y * f + c, y * z * f + x * s],
99 [z * x * f + y * s, z * y * f - x * s, z * z * f + c],
100 ];
101 Ok(r)
102}
103
104pub fn eraRx_safe(phi: f64, r: &mut [[f64; 3]; 3]) -> ErfaResult<()> {
106 let s = phi.sin();
107 let c = phi.cos();
108
109 let (r10, r11, r12) = (r[1][0], r[1][1], r[1][2]);
110 let (r20, r21, r22) = (r[2][0], r[2][1], r[2][2]);
111
112 let a10 = c * r10 + s * r20;
113 let a11 = c * r11 + s * r21;
114 let a12 = c * r12 + s * r22;
115 let a20 = -s * r10 + c * r20;
116 let a21 = -s * r11 + c * r21;
117 let a22 = -s * r12 + c * r22;
118
119 r[1][0] = a10;
120 r[1][1] = a11;
121 r[1][2] = a12;
122 r[2][0] = a20;
123 r[2][1] = a21;
124 r[2][2] = a22;
125 Ok(())
126}
127
128pub fn eraRy_safe(theta: f64, r: &mut [[f64; 3]; 3]) -> ErfaResult<()> {
130 let s = theta.sin();
131 let c = theta.cos();
132
133 let (r00, r01, r02) = (r[0][0], r[0][1], r[0][2]);
134 let (r20, r21, r22) = (r[2][0], r[2][1], r[2][2]);
135
136 let a00 = c * r00 - s * r20;
137 let a01 = c * r01 - s * r21;
138 let a02 = c * r02 - s * r22;
139 let a20 = s * r00 + c * r20;
140 let a21 = s * r01 + c * r21;
141 let a22 = s * r02 + c * r22;
142
143 r[0][0] = a00;
144 r[0][1] = a01;
145 r[0][2] = a02;
146 r[2][0] = a20;
147 r[2][1] = a21;
148 r[2][2] = a22;
149 Ok(())
150}
151
152pub fn eraRz_safe(psi: f64, r: &mut [[f64; 3]; 3]) -> ErfaResult<()> {
154 let s = psi.sin();
155 let c = psi.cos();
156
157 let (r00, r01, r02) = (r[0][0], r[0][1], r[0][2]);
158 let (r10, r11, r12) = (r[1][0], r[1][1], r[1][2]);
159
160 let a00 = c * r00 + s * r10;
161 let a01 = c * r01 + s * r11;
162 let a02 = c * r02 + s * r12;
163 let a10 = -s * r00 + c * r10;
164 let a11 = -s * r01 + c * r11;
165 let a12 = -s * r02 + c * r12;
166
167 r[0][0] = a00;
168 r[0][1] = a01;
169 r[0][2] = a02;
170 r[1][0] = a10;
171 r[1][1] = a11;
172 r[1][2] = a12;
173 Ok(())
174}
175
176pub fn eraRxp_safe(r: &[[f64; 3]; 3], p: &[f64; 3]) -> ErfaResult<[f64; 3]> {
178 let mut rp = [0.0_f64; 3];
179 for j in 0..3 {
180 let mut w = 0.0;
181 for i in 0..3 {
182 w += r[j][i] * p[i];
183 }
184 rp[j] = w;
185 }
186 Ok(rp)
187}
188
189pub fn eraRxpv_safe(r: &[[f64; 3]; 3], pv: &[[f64; 3]; 2]) -> ErfaResult<[[f64; 3]; 2]> {
191 let p = eraRxp_safe(r, &pv[0])?;
192 let v = eraRxp_safe(r, &pv[1])?;
193 Ok([p, v])
194}
195
196pub fn eraRxr_safe(a: &[[f64; 3]; 3], b: &[[f64; 3]; 3]) -> ErfaResult<[[f64; 3]; 3]> {
198 let mut atb = [[0.0_f64; 3]; 3];
199 for i in 0..3 {
200 for j in 0..3 {
201 let mut w = 0.0;
202 for k in 0..3 {
203 w += a[i][k] * b[k][j];
204 }
205 atb[i][j] = w;
206 }
207 }
208 Ok(atb)
209}