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;