rsspice/generated/spicelib/spks03.rs
1//
2// GENERATED FILE
3//
4
5use super::*;
6use crate::SpiceContext;
7use f2rust_std::*;
8
9/// S/P Kernel, subset, type 3
10///
11/// Extract a subset of the data in a SPK segment of type 3 (Chebyshev
12/// polynomials, position and velocity) into a new segment.
13///
14/// # Required Reading
15///
16/// * [SPK](crate::required_reading::spk)
17///
18/// # Brief I/O
19///
20/// ```text
21///  VARIABLE  I/O  DESCRIPTION
22///  --------  ---  --------------------------------------------------
23///  HANDLE     I   Handle of source segment.
24///  BADDR      I   Beginning address of source segment.
25///  EADDR      I   Ending address of source segment.
26///  BEGIN      I   Beginning (initial epoch) of subset.
27///  END        I   End (final epoch) of subset.
28/// ```
29///
30/// # Detailed Input
31///
32/// ```text
33///  HANDLE,
34///  BADDR,
35///  EADDR    are the file handle assigned to a SPK file, and the
36///           beginning and ending addresses of a segment within
37///           the file. Together they determine a complete set of
38///           ephemeris data, from which a subset is to be
39///           extracted.
40///
41///  BEGIN,
42///  END      are the initial and final epochs (ephemeris time)
43///           of the subset to be extracted.
44/// ```
45///
46/// # Exceptions
47///
48/// ```text
49///  1)  If an error occurs while reading data from the source SPK
50///      file, the error is signaled by a routine in the call tree of
51///      this routine.
52///
53///  2)  If an error occurs while writing data to the output SPK file,
54///      the error is signaled by a routine in the call tree of this
55///      routine.
56/// ```
57///
58/// # Files
59///
60/// ```text
61///  See argument HANDLE.
62/// ```
63///
64/// # Particulars
65///
66/// ```text
67///  The exact structure of a segment of data type 3 (Chebyshev
68///  polynomials, position and velocity) is detailed in the SPK
69///  Required Reading file.
70///
71///  On not so close inspection, it will be noted that SPKS03 is
72///  identical to SPKS02.
73/// ```
74///
75/// # Author and Institution
76///
77/// ```text
78///  N.J. Bachman       (JPL)
79///  J. Diaz del Rio    (ODC Space)
80///  H.A. Neilan        (JPL)
81///  W.L. Taber         (JPL)
82///  R.E. Thurman       (JPL)
83///  E.D. Wright        (JPL)
84/// ```
85///
86/// # Version
87///
88/// ```text
89/// -    SPICELIB Version 1.1.2, 14-APR-2021 (JDR)
90///
91///         Edited the header to comply with NAIF standard. Moved SPK
92///         required reading from $Literature_References to
93///         $Required_Reading section.
94///
95/// -    SPICELIB Version 1.1.1, 31-DEC-2013 (NJB)
96///
97///         Enhanced header documentation.
98///
99/// -    SPICELIB Version 1.1.0, 07-SEP-2001 (EDW)
100///
101///         Replaced DAFRDA call with DAFGDA.
102///         Added IMPLICIT NONE.
103///
104/// -    SPICELIB Version 1.0.3, 10-MAR-1992 (WLT)
105///
106///         Comment section for permuted index source lines was added
107///         following the header.
108///
109/// -    SPICELIB Version 1.0.2, 23-AUG-1991 (HAN)
110///
111///         SPK03 was removed from the $Required_Reading section of the
112///         header. The information in the SPK03 Required Reading file
113///         is now part of the SPK Required Reading file.
114///
115/// -    SPICELIB Version 1.0.1, 22-MAR-1990 (HAN)
116///
117///         Literature references added to the header.
118///
119/// -    SPICELIB Version 1.0.0, 31-JAN-1990 (RET)
120/// ```
121pub fn spks03(
122    ctx: &mut SpiceContext,
123    handle: i32,
124    baddr: i32,
125    eaddr: i32,
126    begin: f64,
127    end: f64,
128) -> crate::Result<()> {
129    SPKS03(handle, baddr, eaddr, begin, end, ctx.raw_context())?;
130    ctx.handle_errors()?;
131    Ok(())
132}
133
134//$Procedure SPKS03 ( S/P Kernel, subset, type 3 )
135pub fn SPKS03(
136    HANDLE: i32,
137    BADDR: i32,
138    EADDR: i32,
139    BEGIN: f64,
140    END: f64,
141    ctx: &mut Context,
142) -> f2rust_std::Result<()> {
143    let mut DATA = StackArray::<f64, 50>::new(1..=50);
144    let mut INIT: f64 = 0.0;
145    let mut INTLEN: f64 = 0.0;
146    let mut RECSIZ: i32 = 0;
147    let mut NREC: i32 = 0;
148    let mut FIRST: i32 = 0;
149    let mut LAST: i32 = 0;
150    let mut REMAIN: i32 = 0;
151    let mut ADDR: i32 = 0;
152    let mut MOVE: i32 = 0;
153
154    //
155    // SPICELIB functions
156    //
157
158    //
159    // Local variables
160    //
161
162    //
163    // Standard SPICE error handling.
164    //
165    if RETURN(ctx) {
166        return Ok(());
167    } else {
168        CHKIN(b"SPKS03", ctx)?;
169    }
170
171    //
172    // The segment is made up of a number of logical records, each
173    // having the same size, and covering the same length of time.
174    //
175    // We can determine which records to extract by comparing the input
176    // epochs with the initial time of the segment and the length of the
177    // interval covered by each record.  These final two constants are
178    // located at the end of the segment, along with the size of each
179    // logical record and the total number of records.
180    //
181    DAFGDA(HANDLE, (EADDR - 3), EADDR, DATA.as_slice_mut(), ctx)?;
182
183    INIT = DATA[1];
184    INTLEN = DATA[2];
185    RECSIZ = (DATA[3] as i32);
186    NREC = (DATA[4] as i32);
187
188    FIRST = ((((BEGIN - INIT) / INTLEN) as i32) + 1);
189    FIRST = intrinsics::MIN0(&[FIRST, NREC]);
190
191    LAST = ((((END - INIT) / INTLEN) as i32) + 1);
192    LAST = intrinsics::MIN0(&[LAST, NREC]);
193
194    //
195    // The number of records to be moved.
196    //
197    NREC = ((LAST - FIRST) + 1);
198
199    //
200    // We're going to move the data in chunks of 50 d.p. words.  Compute
201    // the number of words left to move, the address of the beginning
202    // of the records to move, and the number to move this time.
203    //
204    REMAIN = (NREC * RECSIZ);
205    ADDR = (BADDR + ((FIRST - 1) * RECSIZ));
206    MOVE = intrinsics::MIN0(&[50, REMAIN]);
207
208    while (REMAIN > 0) {
209        DAFGDA(HANDLE, ADDR, ((ADDR + MOVE) - 1), DATA.as_slice_mut(), ctx)?;
210        DAFADA(DATA.as_slice(), MOVE, ctx)?;
211        REMAIN = (REMAIN - MOVE);
212        ADDR = (ADDR + MOVE);
213        MOVE = intrinsics::MIN0(&[50, REMAIN]);
214    }
215
216    //
217    // That's all the records we have to move. But there are still four
218    // final numbers left to write:
219    //
220    //    1)  The initial time for the polynomials (INIT).
221    //    2)  The time interval length for each polynomial (INTLEN).
222    //    3)  The record size (RECSIZ).
223    //    4)  The number of records (NREC).
224    //
225    // INIT and NREC will probably be different for the new segment (in
226    // fact, NREC has already been changed), the other two will not.
227    //
228    INIT = (INIT + (((FIRST - 1) as f64) * INTLEN));
229
230    DATA[1] = INIT;
231    DATA[2] = INTLEN;
232    DATA[3] = (RECSIZ as f64);
233    DATA[4] = (NREC as f64);
234    DAFADA(DATA.as_slice(), 4, ctx)?;
235
236    CHKOUT(b"SPKS03", ctx)?;
237    Ok(())
238}