/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/astro/starpm.rs
Line | Count | Source |
1 | | use crate::{ |
2 | | consts::DC, |
3 | | vm::{pdp, pm, pvu}, |
4 | | }; |
5 | | |
6 | | use super::{pvstar, starpv}; |
7 | | |
8 | | /// Star proper motion: update star catalog data for space motion. |
9 | | /// |
10 | | /// This function is part of the International Astronomical Union's |
11 | | /// SOFA (Standards of Fundamental Astronomy) software collection. |
12 | | /// |
13 | | /// Status: support function. |
14 | | /// |
15 | | /// Given: |
16 | | /// ra1 double right ascension (radians), before |
17 | | /// dec1 double declination (radians), before |
18 | | /// pmr1 double RA proper motion (radians/year), before |
19 | | /// pmd1 double Dec proper motion (radians/year), before |
20 | | /// px1 double parallax (arcseconds), before |
21 | | /// rv1 double radial velocity (km/s, +ve = receding), before |
22 | | /// ep1a double "before" epoch, part A (Note 1) |
23 | | /// ep1b double "before" epoch, part B (Note 1) |
24 | | /// ep2a double "after" epoch, part A (Note 1) |
25 | | /// ep2b double "after" epoch, part B (Note 1) |
26 | | /// |
27 | | /// Returned: |
28 | | /// ra2 double right ascension (radians), after |
29 | | /// dec2 double declination (radians), after |
30 | | /// pmr2 double RA proper motion (radians/year), after |
31 | | /// pmd2 double Dec proper motion (radians/year), after |
32 | | /// px2 double parallax (arcseconds), after |
33 | | /// rv2 double radial velocity (km/s, +ve = receding), after |
34 | | /// |
35 | | /// Returned (function value): |
36 | | /// int status: |
37 | | /// -1 = system error (should not occur) |
38 | | /// 0 = no warnings or errors |
39 | | /// 1 = distance overridden (Note 6) |
40 | | /// 2 = excessive velocity (Note 7) |
41 | | /// 4 = solution didn't converge (Note 8) |
42 | | /// else = binary logical OR of the above warnings |
43 | | /// |
44 | | /// Notes: |
45 | | /// |
46 | | /// 1) The starting and ending TDB dates ep1a+ep1b and ep2a+ep2b are |
47 | | /// Julian Dates, apportioned in any convenient way between the two |
48 | | /// parts (A and B). For example, JD(TDB)=2450123.7 could be |
49 | | /// expressed in any of these ways, among others: |
50 | | /// |
51 | | /// epNa epNb |
52 | | /// |
53 | | /// 2450123.7 0.0 (JD method) |
54 | | /// 2451545.0 -1421.3 (J2000 method) |
55 | | /// 2400000.5 50123.2 (MJD method) |
56 | | /// 2450123.5 0.2 (date & time method) |
57 | | /// |
58 | | /// The JD method is the most natural and convenient to use in cases |
59 | | /// where the loss of several decimal digits of resolution is |
60 | | /// acceptable. The J2000 method is best matched to the way the |
61 | | /// argument is handled internally and will deliver the optimum |
62 | | /// resolution. The MJD method and the date & time methods are both |
63 | | /// good compromises between resolution and convenience. |
64 | | /// |
65 | | /// 2) In accordance with normal star-catalog conventions, the object's |
66 | | /// right ascension and declination are freed from the effects of |
67 | | /// secular aberration. The frame, which is aligned to the catalog |
68 | | /// equator and equinox, is Lorentzian and centered on the SSB. |
69 | | /// |
70 | | /// The proper motions are the rate of change of the right ascension |
71 | | /// and declination at the catalog epoch and are in radians per TDB |
72 | | /// Julian year. |
73 | | /// |
74 | | /// The parallax and radial velocity are in the same frame. |
75 | | /// |
76 | | /// 3) Care is needed with units. The star coordinates are in radians |
77 | | /// and the proper motions in radians per Julian year, but the |
78 | | /// parallax is in arcseconds. |
79 | | /// |
80 | | /// 4) The RA proper motion is in terms of coordinate angle, not true |
81 | | /// angle. If the catalog uses arcseconds for both RA and Dec proper |
82 | | /// motions, the RA proper motion will need to be divided by cos(Dec) |
83 | | /// before use. |
84 | | /// |
85 | | /// 5) Straight-line motion at constant speed, in the inertial frame, |
86 | | /// is assumed. |
87 | | /// |
88 | | /// 6) An extremely small (or zero or negative) parallax is interpreted |
89 | | /// to mean that the object is on the "celestial sphere", the radius |
90 | | /// of which is an arbitrary (large) value (see the iauStarpv |
91 | | /// function for the value used). When the distance is overridden in |
92 | | /// this way, the status, initially zero, has 1 added to it. |
93 | | /// |
94 | | /// 7) If the space velocity is a significant fraction of c (see the |
95 | | /// constant VMAX in the function iauStarpv), it is arbitrarily set |
96 | | /// to zero. When this action occurs, 2 is added to the status. |
97 | | /// |
98 | | /// 8) The relativistic adjustment carried out in the iauStarpv function |
99 | | /// involves an iterative calculation. If the process fails to |
100 | | /// converge within a set number of iterations, 4 is added to the |
101 | | /// status. |
102 | | /// |
103 | | /// Called: |
104 | | /// iauStarpv star catalog data to space motion pv-vector |
105 | | /// iauPvu update a pv-vector |
106 | | /// iauPdp scalar product of two p-vectors |
107 | | /// iauPvstar space motion pv-vector to star catalog data |
108 | | /// |
109 | 0 | pub fn starpm( |
110 | 0 | ra1: f64, |
111 | 0 | dec1: f64, |
112 | 0 | pmr1: f64, |
113 | 0 | pmd1: f64, |
114 | 0 | px1: f64, |
115 | 0 | rv1: f64, |
116 | 0 | ep1a: f64, |
117 | 0 | ep1b: f64, |
118 | 0 | ep2a: f64, |
119 | 0 | ep2b: f64, |
120 | 0 | ) -> Result<([f64; 6], i32), i32> { |
121 | | /* RA,Dec etc. at the "before" epoch to space motion pv-vector. */ |
122 | 0 | let (pv1, j1) = starpv(ra1, dec1, pmr1, pmd1, px1, rv1); |
123 | | |
124 | | /* Light time when observed (days). */ |
125 | 0 | let tl1 = pm(pv1[0]) / DC; |
126 | | |
127 | | /* Time interval, "before" to "after" (days). */ |
128 | 0 | let dt = (ep2a - ep1a) + (ep2b - ep1b); |
129 | | |
130 | | /* Move star along track from the "before" observed position to the */ |
131 | | /* "after" geometric position. */ |
132 | 0 | let pv = pvu(dt + tl1, &pv1); |
133 | | |
134 | | /* From this geometric position, deduce the observed light time (days) */ |
135 | | /* at the "after" epoch (with theoretically unneccessary error check). */ |
136 | 0 | let r2 = pdp(&pv[0], &pv[0]); |
137 | 0 | let rdv = pdp(&pv[0], &pv[1]); |
138 | 0 | let v2 = pdp(&pv[1], &pv[1]); |
139 | 0 | let c2mv2 = DC * DC - v2; |
140 | 0 | if c2mv2 <= 0.0 { |
141 | 0 | return Err(-1); |
142 | 0 | } |
143 | 0 | let tl2 = (-rdv + (rdv * rdv + c2mv2 * r2).sqrt()) / c2mv2; |
144 | | |
145 | | /* Move the position along track from the observed place at the */ |
146 | | /* "before" epoch to the observed place at the "after" epoch. */ |
147 | 0 | let pv2 = pvu(dt + (tl1 - tl2), &pv1); |
148 | | |
149 | | /* Space motion pv-vector to RA,Dec etc. at the "after" epoch. */ |
150 | 0 | let (j2, ra2, dec2, pmr2, pmd2, px2, rv2) = match pvstar(&pv2) { |
151 | 0 | Ok(res) => (0, res[0], res[1], res[2], res[3], res[4], res[5]), |
152 | 0 | Err(_) => (-1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), |
153 | | }; |
154 | | |
155 | | /* Final status. */ |
156 | 0 | let j = if j2 == 0 { j1 } else { -1 }; |
157 | | |
158 | 0 | if j < 0 { |
159 | 0 | Err(j) |
160 | | } else { |
161 | 0 | Ok(([ra2, dec2, pmr2, pmd2, px2, rv2], j)) |
162 | | } |
163 | 0 | } |