Skip to main content

sofars/
lib.rs

1//! # Sofa
2//! This project is a basic astronomy calculation library implemented purely in Rust, based on the official [Standards of Fundamental Astronomy (SOFA)](http://iausofa.org) by the International Astronomical Union.
3//!
4//! Refer to the [documentation](https://docs.rs/sofars/) for detail.
5//! ## License
6//! sofa-rs follows the MIT license.
7//!
8//! In addition to the MIT license, any use of this module must also comply with the SOFA license and terms of use, which are detailed in the license file.
9//!
10//! In particular (but not limited to), any published work or commercial product that includes results obtained using sofa-rs should acknowledge the use of algorithms provided by the SOFA ANSIC source code to obtain these results.
11//! ## Example
12//! ```
13//! use sofars::astro::*;
14//! use sofars::consts::*;
15//! use sofars::eph::epv00;
16//! use sofars::pnp::bpn2xy;
17//! use sofars::pnp::pnm00a;
18//! use sofars::pnp::s06;
19//! use sofars::ts;
20//! use sofars::vm;
21//!
22//! use std::thread;
23//!
24//! fn reprd(s: &str, ra: f64, dc: f64) {
25//!     let mut pm: char;
26//!     let mut i: [i32; 4] = [0; 4];
27//!
28//!     print!("{:25}", s);
29//!     (pm, i) = vm::a2tf(7, ra);
30//!     if pm == '+' {
31//!         pm = ' ';
32//!     }
33//!     print!("{}{:02} {:02} {:02}.{:07} ", pm, i[0], i[1], i[2], i[3]);
34//!     (pm, i) = vm::a2af(6, dc);
35//!     println!("{}{:02} {:02} {:02}.{:06}", pm, i[0], i[1], i[2], i[3]);
36//! }
37//!
38//! fn example() {
39//!
40//!     /* Site longitude, latitude (radians) and height above the geoid (m). */
41//!     let elong = vm::af2a('-', 5, 41, 54.2).unwrap();
42//!     let phi = vm::af2a('-', 15, 57, 42.8).unwrap();
43//!     let hm = 625.0;
44//!
45//!     /* Ambient pressure (HPa), temperature (C) and rel. humidity (frac). */
46//!     let phpa = 952.0;
47//!     let tc = 18.5;
48//!     let rh = 0.83;
49//!
50//!     /* Effective color (microns). */
51//!     let wl = 0.55;
52//!
53//!     /* UTC date */
54//!     let (utc1, utc2) = match ts::dtf2d("UTC", 2013, 4, 2, 23, 15, 43.55) {
55//!         Ok(t) => t,
56//!         Err(_) => return (),
57//!     };
58//!
59//!     /* TT date */
60//!     let (tai1, tai2) = match ts::utctai(utc1, utc2) {
61//!         Ok(t) => t,
62//!         Err(_) => return (),
63//!     };
64//!     let (tt1, tt2) = match ts::taitt(tai1, tai2) {
65//!         Ok(t) => t,
66//!         Err(_) => return (),
67//!     };
68//!
69//!     /* EOPs: polar motion in radians, UT1-UTC in seconds. */
70//!     let xp = 50.995e-3 * DAS2R;
71//!     let yp = 376.723e-3 * DAS2R;
72//!     let dut1 = 155.0675e-3;
73//!
74//!     /* Corrections to IAU 2000A CIP (radians). */
75//!     let dx = 0.269e-3 * DAS2R;
76//!     let dy = -0.274e-3 * DAS2R;
77//!
78//!     /* Star ICRS RA,Dec (radians). */
79//!     let rc = match vm::tf2a(' ', 14, 34, 16.81183) {
80//!         Ok(rc) => rc,
81//!         Err(_) => return (),
82//!     };
83//!     let dc = match vm::af2a('-', 12, 31, 10.3965) {
84//!         Ok(dc) => dc,
85//!         Err(_) => return (),
86//!     };
87//!     reprd("ICRS, epoch J2000.0:", rc, dc);
88//!     /* Annual proper motion: RA/Dec derivatives, epoch J2000.0. */
89//!     let pr = (-354.45e-3 * DAS2R).atan2(dc.cos());
90//!     let pd = 595.35e-3 * DAS2R;
91//!   
92//!     /* Parallax (arcsec) and recession speed (km/s). */
93//!     let px = 164.99e-3;
94//!     let rv = 0.0;
95//!  
96//!
97//!     /* ICRS catalog to astrometric place... */
98//!     let (rca, dca) = atcc13(rc, dc, pr, pd, px, rv, tt1, tt2);
99//!     reprd("catalog -> astrometric:", rca, dca);
100//!
101//!     /* ...then to CIRS (geocentric observer) */
102//!     let (ri, di, eo) = atci13(rca, dca, 0.0, 0.0, 0.0, 0.0, tt1, tt2);
103//!     reprd("astrometric -> CIRS:", ri, di);
104//!
105//!     /* ICRS catalog directly to CIRS (geocentric observer). */
106//!     let (ri, di, eo) = atci13(rc, dc, pr, pd, px, rv, tt1, tt2);
107//!     reprd("catalog -> CIRS:", ri, di);
108//!
109//!     /* Apparent place */
110//!     let ra = vm::anp(ri - eo);
111//!     let da = di;
112//!     reprd("geocentric apparent:", ra, da);
113//!
114//!     /* CIRS to topocentric. */
115//!     let (aot, zot, hot, dot, rot) = atio13(ri, di, utc1, utc2, dut1, elong, phi, hm, xp, yp, 0.0, 0.0, 0.0, 0.0).unwrap();
116//!     reprd("CIRS -> topocentric:", rot, dot);
117//!
118//!     /* CIRS to observed. */
119//!     let (aob, zob, hob, dob, rob)= atio13(ri, di, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl).unwrap();
120//!     reprd("CIRS -> observed:", rob, dob);
121//!
122//!     /* ICRS to observed. */
123//!     let (aob, zob, hob, dob, rob, eo) = atco13(rc, dc, pr, pd, px, rv, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl).unwrap();
124//!     reprd("ICRS -> observed:", rob, dob);
125//!
126//!     /* ICRS to CIRS using some user-supplied parameters. */
127//!     /* SOFA heliocentric Earth ephemeris. */
128//!     let (pvh, pvb) = &mut epv00(tt1, tt2).unwrap();
129//!
130//!     /* JPL DE405 barycentric Earth ephemeris. */
131//!     pvb[0][0] = -0.9741704366519668;
132//!     pvb[0][1] = -0.2115201000882231;
133//!     pvb[0][2] = -0.0917583114068277;
134//!     pvb[1][0] = 0.0036436589347388;
135//!     pvb[1][1] = -0.0154287318503146;
136//!     pvb[1][2] = -0.0066892203821059;
137//!
138//!     /* IAU 2000 CIP */
139//!     let r = &mut [[0.0; 3]; 3];
140//!     pnm00a(tt1, tt2, r);
141//!     let (mut x, mut y) = bpn2xy(r);
142//!
143//!     /* Apply IERS corrections */
144//!     x += dx;
145//!     y += dy;
146//!
147//!     /* SOFA CIO locator. */
148//!     let s = s06(tt1, tt2, x, y);
149//!
150//!     let astrom = &mut IauAstrom::default();
151//!     /* Populate the context. */
152//!     apci(tt1, tt2, &pvb, &pvh[0], x, y, s, astrom);
153//!
154//!     /* Carry out the transformation and report the results. */
155//!     let (ri, di) = atciq(rc, dc, pr, pd, px, rv, astrom);
156//!     reprd("ICRS -> CIRS (JPL, IERS):", ri, di);
157//!     
158//!     /* The same but with Saturn then Jupiter then Sun light deflection. */
159//!     let mut b = [
160//!         IauLdBody::new(0.00028574, 3e-10, [
161//!             [-7.8101442680818964, -5.6095668114887358, -1.9807981923749924],
162//!             [0.0030723248971152, -0.0040699547707598, -0.0018133584165345]
163//!         ]),
164//!         IauLdBody::new(0.00095435, 3e-9, [
165//!             [0.7380987962351833, 4.6365869247538951, 1.9693136030111202],
166//!             [-0.0075581692172088, 0.0012691372216750, 0.0007279990012801]
167//!         ]),
168//!         IauLdBody::new(1.0, 6e-6, [
169//!             [-0.0007121743770509, -0.0023047830339257, -0.0010586596574639],
170//!             [0.0000062923521264, -0.0000003308883872, -0.0000002964866231]
171//!         ])
172//!     ];
173//!
174//!     let (ri, di) = atciqn(rc, dc, pr, pd, px, rv, astrom, 3, &b);
175//!     reprd("ICRS -> CIRS (+ planets):", ri, di);
176//!
177//!     /* CIRS to ICRS (astrometric). */
178//!     let (rca, dca) = aticqn(ri, di, astrom, 3, &b);
179//!     reprd("CIRS -> astrometric:", rca, dca);
180//! }
181//!
182//! // Output:
183//! //
184//! // ICRS, epoch J2000.0:      14 34 16.8118300 -12 31 10.396500
185//! // catalog -> astrometric:   14 34 16.4960283 -12 31 02.523786
186//! // astrometric -> CIRS:      14 34 20.2370587 -12 34 36.381654
187//! // catalog -> CIRS:          14 34 20.2370587 -12 34 36.381654
188//! // geocentric apparent:      14 35 01.7725802 -12 34 36.381654
189//! // CIRS -> topocentric:      14 34 20.2570287 -12 34 36.141207
190//! // CIRS -> observed:         14 34 16.9649101 -12 34 44.643091
191//! // ICRS -> observed:         14 34 16.9649106 -12 34 44.643094
192//! // ICRS -> CIRS (JPL, IERS): 14 34 20.2370639 -12 34 36.381756
193//! // ICRS -> CIRS (+ planets): 14 34 20.2370658 -12 34 36.381784
194//! // CIRS -> astrometric:      14 34 16.4960283 -12 31 02.523786
195//! //
196//! fn main() {
197//!     let stack_size = 2 * 1024 * 1024;
198//!     let name = String::from("mycal thread");
199//!
200//!     let builder = thread::Builder::new().stack_size(stack_size).name(name);
201//!
202//!     let handler = builder.spawn(|| {
203//!         example();
204//!     }).unwrap();
205//!
206//!     handler.join().unwrap();
207//! }
208//! ```
209//!
210pub mod astro;
211pub mod cal;
212pub mod consts;
213pub mod coords;
214pub mod eph;
215pub mod erst;
216pub mod fundargs;
217pub mod gnomic;
218pub mod pnp;
219pub mod star;
220pub mod ts;
221pub mod vm;