erfa_rust/
G26_safe.rs

1// G26
2//   pn06.c   → eraPn06_safe
3//   pn06a.c  → eraPn06a_safe
4//   pnm00a.c → eraPnm00a_safe
5//   pnm00b.c → eraPnm00b_safe
6//   pnm06a.c → eraPnm06a_safe
7//   pnm80.c  → eraPnm80_safe
8//   pom00.c  → eraPom00_safe
9//   ppp.c    → eraPpp_safe
10//   ppsp.c   → eraPpsp_safe
11//   pr00.c   → eraPr00_safe
12
13use crate::H1_safe::{ERFA_DAS2R, ERFA_DJ00, ERFA_DJC, ERFA_DJM0, ERFA_DJM00};
14
15use crate::G16_safe::eraFw2m_safe;
16use crate::G19_safe::eraIr_safe;
17use crate::G23_safe::{eraNut06a_safe, eraNutm80_safe};
18use crate::G24_safe::eraPfw06_safe;
19use crate::G25_safe::{eraPmat76_safe, eraPn00a_safe, eraPn00b_safe};
20use crate::G28_safe::{eraRx_safe, eraRxr_safe, eraRy_safe, eraRz_safe};
21use crate::G30_safe::eraSxp_safe;
22use crate::G33_safe::eraTr_safe;
23use crate::G8_safe::eraCr_safe;
24
25pub type ErfaResult<T> = Result<T, ()>;
26
27// G26/pn06.c
28// Precession-nutation products, IAU 2006 bias-precession with given dpsi,deps.
29pub fn eraPn06_safe(
30    date1: f64,
31    date2: f64,
32    dpsi: f64,
33    deps: f64,
34) -> ErfaResult<(
35    f64,           // epsa
36    [[f64; 3]; 3], // rb
37    [[f64; 3]; 3], // rp
38    [[f64; 3]; 3], // rbp
39    [[f64; 3]; 3], // rn
40    [[f64; 3]; 3], // rbpn
41)> {
42    // Frame-bias FukushimaWilliams angles of J2000.0
43    let (mut gamb, mut phib, mut psib, mut eps) = eraPfw06_safe(ERFA_DJM0, ERFA_DJM00)?;
44    let r1 = eraFw2m_safe(gamb, phib, psib, eps)?;
45    let mut rb = [[0.0_f64; 3]; 3];
46    eraCr_safe(&r1, &mut rb)?;
47
48    // Bias-precession angles of date
49    let (gd, pd, sd, ed) = eraPfw06_safe(date1, date2)?;
50    gamb = gd;
51    phib = pd;
52    psib = sd;
53    eps = ed;
54    let r2 = eraFw2m_safe(gamb, phib, psib, eps)?;
55    let mut rbp = [[0.0_f64; 3]; 3];
56    eraCr_safe(&r2, &mut rbp)?;
57
58    // Precession matrix:  rp = r2 × r1ᵀ
59    let rt = eraTr_safe(&r1)?;
60    let rp = eraRxr_safe(&r2, &rt)?;
61
62    // Full bias-precession-nutation
63    let rnp = eraFw2m_safe(gamb, phib, psib + dpsi, eps + deps)?;
64    let mut rbpn = [[0.0_f64; 3]; 3];
65    eraCr_safe(&rnp, &mut rbpn)?;
66
67    // Nutation matrix: rn = rnp × r2ᵀ
68    let rt2 = eraTr_safe(&r2)?;
69    let rn = eraRxr_safe(&rnp, &rt2)?;
70
71    // Mean obliquity of date
72    let epsa = eps;
73
74    Ok((epsa, rb, rp, rbp, rn, rbpn))
75}
76
77// G26/pn06a.c
78// Precession-nutation products using IAU 2006/2000A nutation.
79pub fn eraPn06a_safe(
80    date1: f64,
81    date2: f64,
82) -> ErfaResult<(
83    f64,           // dpsi
84    f64,           // deps
85    f64,           // epsa
86    [[f64; 3]; 3], // rb
87    [[f64; 3]; 3], // rp
88    [[f64; 3]; 3], // rbp
89    [[f64; 3]; 3], // rn
90    [[f64; 3]; 3], // rbpn
91)> {
92    let (dpsi, deps) = eraNut06a_safe(date1, date2)?;
93    let (epsa, rb, rp, rbp, rn, rbpn) = eraPn06_safe(date1, date2, dpsi, deps)?;
94    Ok((dpsi, deps, epsa, rb, rp, rbp, rn, rbpn))
95}
96
97// G26/pnm00a.c
98// Precession-nutation matrix, IAU 2000A.
99pub fn eraPnm00a_safe(date1: f64, date2: f64) -> ErfaResult<[[f64; 3]; 3]> {
100    let (_dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, rbpn) = eraPn00a_safe(date1, date2)?;
101    Ok(rbpn)
102}
103
104// G26/pnm00b.c
105// Precession-nutation matrix, IAU 2000B.
106pub fn eraPnm00b_safe(date1: f64, date2: f64) -> ErfaResult<[[f64; 3]; 3]> {
107    let (_dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, rbpn) = eraPn00b_safe(date1, date2)?;
108    Ok(rbpn)
109}
110
111// G26/pnm06a.c
112// Precession-nutation matrix, IAU 2006/2000A.
113pub fn eraPnm06a_safe(date1: f64, date2: f64) -> ErfaResult<[[f64; 3]; 3]> {
114    let (gamb, phib, psib, epsa) = eraPfw06_safe(date1, date2)?;
115    let (dp, de) = eraNut06a_safe(date1, date2)?;
116    let rbpn = eraFw2m_safe(gamb, phib, psib + dp, epsa + de)?;
117    Ok(rbpn)
118}
119
120// G26/pnm80.c
121// Precession-nutation matrix, IAU 1976/1980.
122pub fn eraPnm80_safe(date1: f64, date2: f64) -> ErfaResult<[[f64; 3]; 3]> {
123    let rmatp = eraPmat76_safe(date1, date2)?;
124    let rmatn = eraNutm80_safe(date1, date2)?;
125    let rmatpn = eraRxr_safe(&rmatn, &rmatp)?;
126    Ok(rmatpn)
127}
128
129// G26/pom00.c
130// Polar motion matrix (IAU 2000).
131pub fn eraPom00_safe(xp: f64, yp: f64, sp: f64) -> ErfaResult<[[f64; 3]; 3]> {
132    let mut rpom = [[0.0_f64; 3]; 3];
133    eraIr_safe(&mut rpom)?;
134    eraRz_safe(sp, &mut rpom)?;
135    eraRy_safe(-xp, &mut rpom)?;
136    eraRx_safe(-yp, &mut rpom)?;
137    Ok(rpom)
138}
139
140// G26/ppp.c
141// P-vector addition.
142pub fn eraPpp_safe(a: &[f64; 3], b: &[f64; 3]) -> ErfaResult<[f64; 3]> {
143    Ok([a[0] + b[0], a[1] + b[1], a[2] + b[2]])
144}
145
146// G26/ppsp.c
147// Compute a + s*b for p-vectors.
148pub fn eraPpsp_safe(a: &[f64; 3], s: f64, b: &[f64; 3]) -> ErfaResult<[f64; 3]> {
149    let sb = eraSxp_safe(s, b)?;
150    let apb = eraPpp_safe(a, &sb)?;
151    Ok(apb)
152}
153
154// G26/pr00.c
155// IAU 2000 precession-rate corrections (dpsipr, depspr) per century.
156pub fn eraPr00_safe(date1: f64, date2: f64) -> ErfaResult<(f64, f64)> {
157    const PRECOR: f64 = -0.29965 * ERFA_DAS2R;
158    const OBLCOR: f64 = -0.02524 * ERFA_DAS2R;
159    let t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
160    let dpsipr = PRECOR * t;
161    let depspr = OBLCOR * t;
162    Ok((dpsipr, depspr))
163}