Coverage Report

Created: 2026-05-16 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/pnp/s00.rs
Line
Count
Source
1
#![allow(non_upper_case_globals)]
2
use crate::consts::{DAS2R, DJ00, DJC};
3
use crate::fundargs::{fad03, fae03, faf03, fal03, falp03, faom03, fapa03, fave03};
4
5
struct TERM(
6
    [i32; 8], // nfa
7
    f64,
8
    f64, // s, c
9
);
10
11
const sp: [f64; 6] = [
12
    94.00e-6,
13
    3808.35e-6,
14
    -119.94e-6,
15
    -72574.09e-6,
16
    27.70e-6,
17
    15.61e-6,
18
];
19
20
/* Terms of order t^0 */
21
const s0: [TERM; 33] = [
22
    TERM([0, 0, 0, 0, 1, 0, 0, 0], -2640.73e-6, 0.39e-6),
23
    TERM([0, 0, 0, 0, 2, 0, 0, 0], -63.53e-6, 0.02e-6),
24
    TERM([0, 0, 2, -2, 3, 0, 0, 0], -11.75e-6, -0.01e-6),
25
    TERM([0, 0, 2, -2, 1, 0, 0, 0], -11.21e-6, -0.01e-6),
26
    TERM([0, 0, 2, -2, 2, 0, 0, 0], 4.57e-6, 0.00e-6),
27
    TERM([0, 0, 2, 0, 3, 0, 0, 0], -2.02e-6, 0.00e-6),
28
    TERM([0, 0, 2, 0, 1, 0, 0, 0], -1.98e-6, 0.00e-6),
29
    TERM([0, 0, 0, 0, 3, 0, 0, 0], 1.72e-6, 0.00e-6),
30
    TERM([0, 1, 0, 0, 1, 0, 0, 0], 1.41e-6, 0.01e-6),
31
    TERM([0, 1, 0, 0, -1, 0, 0, 0], 1.26e-6, 0.01e-6),
32
    TERM([1, 0, 0, 0, -1, 0, 0, 0], 0.63e-6, 0.00e-6),
33
    TERM([1, 0, 0, 0, 1, 0, 0, 0], 0.63e-6, 0.00e-6),
34
    TERM([0, 1, 2, -2, 3, 0, 0, 0], -0.46e-6, 0.00e-6),
35
    TERM([0, 1, 2, -2, 1, 0, 0, 0], -0.45e-6, 0.00e-6),
36
    TERM([0, 0, 4, -4, 4, 0, 0, 0], -0.36e-6, 0.00e-6),
37
    TERM([0, 0, 1, -1, 1, -8, 12, 0], 0.24e-6, 0.12e-6),
38
    TERM([0, 0, 2, 0, 0, 0, 0, 0], -0.32e-6, 0.00e-6),
39
    TERM([0, 0, 2, 0, 2, 0, 0, 0], -0.28e-6, 0.00e-6),
40
    TERM([1, 0, 2, 0, 3, 0, 0, 0], -0.27e-6, 0.00e-6),
41
    TERM([1, 0, 2, 0, 1, 0, 0, 0], -0.26e-6, 0.00e-6),
42
    TERM([0, 0, 2, -2, 0, 0, 0, 0], 0.21e-6, 0.00e-6),
43
    TERM([0, 1, -2, 2, -3, 0, 0, 0], -0.19e-6, 0.00e-6),
44
    TERM([0, 1, -2, 2, -1, 0, 0, 0], -0.18e-6, 0.00e-6),
45
    TERM([0, 0, 0, 0, 0, 8, -13, -1], 0.10e-6, -0.05e-6),
46
    TERM([0, 0, 0, 2, 0, 0, 0, 0], -0.15e-6, 0.00e-6),
47
    TERM([2, 0, -2, 0, -1, 0, 0, 0], 0.14e-6, 0.00e-6),
48
    TERM([0, 1, 2, -2, 2, 0, 0, 0], 0.14e-6, 0.00e-6),
49
    TERM([1, 0, 0, -2, 1, 0, 0, 0], -0.14e-6, 0.00e-6),
50
    TERM([1, 0, 0, -2, -1, 0, 0, 0], -0.14e-6, 0.00e-6),
51
    TERM([0, 0, 4, -2, 4, 0, 0, 0], -0.13e-6, 0.00e-6),
52
    TERM([0, 0, 2, -2, 4, 0, 0, 0], 0.11e-6, 0.00e-6),
53
    TERM([1, 0, -2, 0, -3, 0, 0, 0], -0.11e-6, 0.00e-6),
54
    TERM([1, 0, -2, 0, -1, 0, 0, 0], -0.11e-6, 0.00e-6),
55
];
56
57
/* Terms of order t^1 */
58
const s1: [TERM; 3] = [
59
    TERM([0, 0, 0, 0, 2, 0, 0, 0], -0.07e-6, 3.57e-6),
60
    TERM([0, 0, 0, 0, 1, 0, 0, 0], 1.71e-6, -0.03e-6),
61
    TERM([0, 0, 2, -2, 3, 0, 0, 0], 0.00e-6, 0.48e-6),
62
];
63
64
/* Terms of order t^2 */
65
const s2: [TERM; 25] = [
66
    TERM([0, 0, 0, 0, 1, 0, 0, 0], 743.53e-6, -0.17e-6),
67
    TERM([0, 0, 2, -2, 2, 0, 0, 0], 56.91e-6, 0.06e-6),
68
    TERM([0, 0, 2, 0, 2, 0, 0, 0], 9.84e-6, -0.01e-6),
69
    TERM([0, 0, 0, 0, 2, 0, 0, 0], -8.85e-6, 0.01e-6),
70
    TERM([0, 1, 0, 0, 0, 0, 0, 0], -6.38e-6, -0.05e-6),
71
    TERM([1, 0, 0, 0, 0, 0, 0, 0], -3.07e-6, 0.00e-6),
72
    TERM([0, 1, 2, -2, 2, 0, 0, 0], 2.23e-6, 0.00e-6),
73
    TERM([0, 0, 2, 0, 1, 0, 0, 0], 1.67e-6, 0.00e-6),
74
    TERM([1, 0, 2, 0, 2, 0, 0, 0], 1.30e-6, 0.00e-6),
75
    TERM([0, 1, -2, 2, -2, 0, 0, 0], 0.93e-6, 0.00e-6),
76
    TERM([1, 0, 0, -2, 0, 0, 0, 0], 0.68e-6, 0.00e-6),
77
    TERM([0, 0, 2, -2, 1, 0, 0, 0], -0.55e-6, 0.00e-6),
78
    TERM([1, 0, -2, 0, -2, 0, 0, 0], 0.53e-6, 0.00e-6),
79
    TERM([0, 0, 0, 2, 0, 0, 0, 0], -0.27e-6, 0.00e-6),
80
    TERM([1, 0, 0, 0, 1, 0, 0, 0], -0.27e-6, 0.00e-6),
81
    TERM([1, 0, -2, -2, -2, 0, 0, 0], -0.26e-6, 0.00e-6),
82
    TERM([1, 0, 0, 0, -1, 0, 0, 0], -0.25e-6, 0.00e-6),
83
    TERM([1, 0, 2, 0, 1, 0, 0, 0], 0.22e-6, 0.00e-6),
84
    TERM([2, 0, 0, -2, 0, 0, 0, 0], -0.21e-6, 0.00e-6),
85
    TERM([2, 0, -2, 0, -1, 0, 0, 0], 0.20e-6, 0.00e-6),
86
    TERM([0, 0, 2, 2, 2, 0, 0, 0], 0.17e-6, 0.00e-6),
87
    TERM([2, 0, 2, 0, 2, 0, 0, 0], 0.13e-6, 0.00e-6),
88
    TERM([2, 0, 0, 0, 0, 0, 0, 0], -0.13e-6, 0.00e-6),
89
    TERM([1, 0, 2, -2, 2, 0, 0, 0], -0.12e-6, 0.00e-6),
90
    TERM([0, 0, 2, 0, 0, 0, 0, 0], -0.11e-6, 0.00e-6),
91
];
92
93
/* Terms of order t^3 */
94
const s3: [TERM; 4] = [
95
    TERM([0, 0, 0, 0, 1, 0, 0, 0], 0.30e-6, -23.51e-6),
96
    TERM([0, 0, 2, -2, 2, 0, 0, 0], -0.03e-6, -1.39e-6),
97
    TERM([0, 0, 2, 0, 2, 0, 0, 0], -0.01e-6, -0.24e-6),
98
    TERM([0, 0, 0, 0, 2, 0, 0, 0], 0.00e-6, 0.22e-6),
99
];
100
101
/* Terms of order t^4 */
102
const s4: [TERM; 1] = [
103
    /* 1-1 */
104
    TERM([0, 0, 0, 0, 1, 0, 0, 0], -0.26e-6, -0.01e-6),
105
];
106
107
///  The CIO locator s, positioning the Celestial Intermediate Origin on
108
///  the equator of the Celestial Intermediate Pole, given the CIP's X,Y
109
///  coordinates.  Compatible with IAU 2000A precession-nutation.
110
///
111
///  Given:
112
///     date1,date2   f64       TT as a 2-part Julian Date (Note 1)
113
///     x,y           f64       CIP coordinates (Note 3)
114
///
115
///  Returned (function value):
116
///                   f64       the CIO locator s in radians (Note 2)
117
///
118
///  Notes:
119
///
120
///  1) The TT date date1+date2 is a Julian Date, apportioned in any
121
///     convenient way between the two arguments.  For example,
122
///     JD(TT)=2450123.7 could be expressed in any of these ways,
123
///     among others:
124
///
125
///            date1          date2
126
///
127
///         2450123.7           0.0       (JD method)
128
///         2451545.0       -1421.3       (J2000 method)
129
///         2400000.5       50123.2       (MJD method)
130
///         2450123.5           0.2       (date & time method)
131
///
132
///     The JD method is the most natural and convenient to use in
133
///     cases where the loss of several decimal digits of resolution
134
///     is acceptable.  The J2000 method is best matched to the way
135
///     the argument is handled internally and will deliver the
136
///     optimum resolution.  The MJD method and the date & time methods
137
///     are both good compromises between resolution and convenience.
138
///
139
///  2) The CIO locator s is the difference between the right ascensions
140
///     of the same point in two systems:  the two systems are the GCRS
141
///     and the CIP,CIO, and the point is the ascending node of the
142
///     CIP equator.  The quantity s remains below 0.1 arcsecond
143
///     throughout 1900-2100.
144
///
145
///  3) The series used to compute s is in fact for s+XY/2, where X and Y
146
///     are the x and y components of the CIP unit vector;  this series
147
///     is more compact than a direct series for s would be.  This
148
///     function requires X,Y to be supplied by the caller, who is
149
///     responsible for providing values that are consistent with the
150
///     supplied date.
151
///
152
///  4) The model is consistent with the IAU 2000A precession-nutation.
153
///
154
///  References:
155
///
156
///     Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
157
///     "Expressions for the Celestial Intermediate Pole and Celestial
158
///     Ephemeris Origin consistent with the IAU 2000A precession-
159
///     nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
160
///
161
///     n.b. The celestial ephemeris origin (CEO) was renamed "celestial
162
///          intermediate origin" (CIO) by IAU 2006 Resolution 2.
163
///
164
///     McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
165
///     IERS Technical Note No. 32, BKG (2004)
166
0
pub fn s00(date1: f64, date2: f64, x: f64, y: f64) -> f64 {
167
    /* Interval between fundamental epoch J2000.0 and current date (JC). */
168
0
    let t = ((date1 - DJ00) + date2) / DJC;
169
170
    /* Fundamental Arguments (from IERS Conventions 2003) */
171
172
0
    let mut fa: [f64; 8] = [0.0; 8];
173
    /* Mean anomaly of the Moon. */
174
0
    fa[0] = fal03(t);
175
176
    /* Mean anomaly of the Sun. */
177
0
    fa[1] = falp03(t);
178
179
    /* Mean longitude of the Moon minus that of the ascending node. */
180
0
    fa[2] = faf03(t);
181
182
    /* Mean elongation of the Moon from the Sun. */
183
0
    fa[3] = fad03(t);
184
185
    /* Mean longitude of the ascending node of the Moon. */
186
0
    fa[4] = faom03(t);
187
188
    /* Mean longitude of Venus. */
189
0
    fa[5] = fave03(t);
190
191
    /* Mean longitude of Earth. */
192
0
    fa[6] = fae03(t);
193
194
    /* General precession in longitude. */
195
0
    fa[7] = fapa03(t);
196
197
0
    let [mut w0, mut w1, mut w2, mut w3, mut w4, w5] = sp;
198
0
    for i in (0..s0.len()).rev() {
199
0
        let nfa = s0[i].0;
200
0
        let [s, c] = [s0[i].1, s0[i].2];
201
0
        let a = fa
202
0
            .iter()
203
0
            .zip(nfa.iter())
204
0
            .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64);
205
0
        w0 += s * a.sin() + c * a.cos();
206
    }
207
208
0
    for i in (0..s1.len()).rev() {
209
0
        let nfa = s1[i].0;
210
0
        let [s, c] = [s1[i].1, s1[i].2];
211
0
        let a = fa
212
0
            .iter()
213
0
            .zip(nfa.iter())
214
0
            .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64);
215
0
        w1 += s * a.sin() + c * a.cos();
216
    }
217
218
0
    for i in (0..s2.len()).rev() {
219
0
        let nfa = s2[i].0;
220
0
        let [s, c] = [s2[i].1, s2[i].2];
221
0
        let a = fa
222
0
            .iter()
223
0
            .zip(nfa.iter())
224
0
            .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64);
225
0
        w2 += s * a.sin() + c * a.cos();
226
    }
227
228
0
    for i in (0..s3.len()).rev() {
229
0
        let nfa = s3[i].0;
230
0
        let [s, c] = [s3[i].1, s3[i].2];
231
0
        let a = fa
232
0
            .iter()
233
0
            .zip(nfa.iter())
234
0
            .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64);
235
0
        w3 += s * a.sin() + c * a.cos();
236
    }
237
238
0
    for i in (0..s4.len()).rev() {
239
0
        let nfa = s4[i].0;
240
0
        let [s, c] = [s4[i].1, s4[i].2];
241
0
        let a = fa
242
0
            .iter()
243
0
            .zip(nfa.iter())
244
0
            .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64);
245
0
        w4 += s * a.sin() + c * a.cos();
246
    }
247
248
0
    let s = (w0 + (w1 + (w2 + (w3 + (w4 + w5 * t) * t) * t) * t) * t) * DAS2R - x * y / 2.0;
249
250
0
    s
251
0
}