Coverage Report

Created: 2026-07-30 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/astro/ldn.rs
Line
Count
Source
1
use crate::astro::ld;
2
use crate::consts::{AULT, DAYSEC};
3
use crate::vm::{cp, pdp, pmp, pn, ppsp};
4
5
use super::IauLdBody;
6
7
///  Light deflection by multiple solar−system bodies
8
///
9
///  For a star, apply light deflection by multiple solar-system bodies,
10
///  as part of transforming coordinate direction into natural direction.
11
///
12
///  This function is part of the International Astronomical Union's
13
///  SOFA (Standards of Fundamental Astronomy) software collection.
14
///
15
///  Status:  support function.
16
///
17
///  Given:
18
///  ```
19
///     n    int           number of bodies (note 1)
20
///     b    iauLDBODY[n]  data for each of the n bodies (Notes 1,2):
21
///      bm   double         mass of the body (solar masses, Note 3)
22
///      dl   double         deflection limiter (Note 4)
23
///      pv   [2][3]         barycentric PV of the body (au, au/day)
24
///     ob   double[3]     barycentric position of the observer (au)
25
///     sc   double[3]     observer to star coord direction (unit vector)
26
///  ```
27
///  Returned:
28
///  ```
29
///     sn    double[3]      observer to deflected star (unit vector)
30
///  ```
31
///  1) The array b contains n entries, one for each body to be
32
///     considered.  If n = 0, no gravitational light deflection will be
33
///     applied, not even for the Sun.
34
///
35
///  2) The array b should include an entry for the Sun as well as for
36
///     any planet or other body to be taken into account.  The entries
37
///     should be in the order in which the light passes the body.
38
///
39
///  3) In the entry in the b array for body i, the mass parameter
40
///     b[i].bm can, as required, be adjusted in order to allow for such
41
///     effects as quadrupole field.
42
///
43
///  4) The deflection limiter parameter b[i].dl is phi^2/2, where phi is
44
///     the angular separation (in radians) between star and body at
45
///     which limiting is applied.  As phi shrinks below the chosen
46
///     threshold, the deflection is artificially reduced, reaching zero
47
///     for phi = 0.   Example values suitable for a terrestrial
48
///     observer, together with masses, are as follows:
49
///  ```
50
///        body i     b[i].bm        b[i].dl
51
///
52
///        Sun        1.0            6e-6
53
///        Jupiter    0.00095435     3e-9
54
///        Saturn     0.00028574     3e-10
55
///  ```
56
///  5) For cases where the starlight passes the body before reaching the
57
///     observer, the body is placed back along its barycentric track by
58
///     the light time from that point to the observer.  For cases where
59
///     the body is "behind" the observer no such shift is applied.  If
60
///     a different treatment is preferred, the user has the option of
61
///     instead using the iauLd function.  Similarly, iauLd can be used
62
///     for cases where the source is nearby, not a star.
63
///
64
///  6) The returned vector sn is not normalized, but the consequential
65
///     departure from unit magnitude is always negligible.
66
///
67
///  7) The arguments sc and sn can be the same array.
68
///
69
///  8) For efficiency, validation is omitted.  The supplied masses must
70
///     be greater than zero, the position and velocity vectors must be
71
///     right, and the deflection limiter greater than zero.
72
///
73
///  Reference:
74
///
75
///     Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
76
///     the Astronomical Almanac, 3rd ed., University Science Books
77
///     (2013), Section 7.2.4.
78
///
79
///  Called:
80
///  ```
81
///     iauCp        copy p-vector
82
///     iauPdp       scalar product of two p-vectors
83
///     iauPmp       p-vector minus p-vector
84
///     iauPpsp      p-vector plus scaled p-vector
85
///     iauPn        decompose p-vector into modulus and direction
86
///     iauLd        light deflection by a solar-system body
87
///  ```
88
0
pub fn ldn(n: i32, b: &[IauLdBody], ob: &[f64; 3], sc: &[f64; 3]) -> [f64; 3] {
89
0
    let mut sn = [0.0; 3];
90
    /* Light time for 1 au (days) */
91
    const CR: f64 = AULT / DAYSEC;
92
93
    // int i;
94
    // double  v[3], dt, ev[3], em, e[3];
95
96
    /* Star direction prior to deflection. */
97
0
    cp(&sc, &mut sn);
98
99
    /* Body by body. */
100
0
    for i in 0..n {
101
0
        /* Body to observer vector at epoch of observation (au). */
102
0
        let v = pmp(ob, &b[i as usize].pv[0]);
103
0
104
0
        /* Minus the time since the light passed the body (days). */
105
0
        let dt = pdp(&mut sn, &v) * CR;
106
0
107
0
        /* Neutralize if the star is "behind" the observer. */
108
0
        let dt = dt.min(0.0);
109
0
110
0
        /* Backtrack the body to the time the light was passing the body. */
111
0
        let ev = ppsp(&v, -dt, &b[i as usize].pv[1]);
112
0
113
0
        /* Body to observer vector as magnitude and direction. */
114
0
        let (em, e) = pn(&ev);
115
0
116
0
        /* Apply light deflection for this body. */
117
0
        sn = ld(b[i as usize].bm, sn, sn, e, em, b[i as usize].dl);
118
0
        /* Next body. */
119
0
    }
120
121
0
    sn
122
0
}