1 /*
2 
3 -Procedure spkw20_c ( Write SPK segment, type 20 )
4 
5 -Abstract
6 
7    Write a type 20 segment to an SPK file.
8 
9 -Disclaimer
10 
11    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
12    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
13    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
14    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
15    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
16    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
17    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
18    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
19    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
20    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
21 
22    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
23    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
24    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
25    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
26    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
27    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
28 
29    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
30    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
31    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
32    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
33 
34 -Required_Reading
35 
36    DAF
37    NAIF_IDS
38    TIME
39    SPK
40 
41 -Keywords
42 
43    EPHEMERIS
44 
45 */
46 
47    #include "SpiceUsr.h"
48    #include "SpiceZfc.h"
49    #include "SpiceZmc.h"
50    #undef spkw20_c
51 
52 
spkw20_c(SpiceInt handle,SpiceInt body,SpiceInt center,ConstSpiceChar * frame,SpiceDouble first,SpiceDouble last,ConstSpiceChar * segid,SpiceDouble intlen,SpiceInt n,SpiceInt polydg,ConstSpiceDouble cdata[],SpiceDouble dscale,SpiceDouble tscale,SpiceDouble initjd,SpiceDouble initfr)53    void spkw20_c  ( SpiceInt            handle,
54                     SpiceInt            body,
55                     SpiceInt            center,
56                     ConstSpiceChar    * frame,
57                     SpiceDouble         first,
58                     SpiceDouble         last,
59                     ConstSpiceChar    * segid,
60                     SpiceDouble         intlen,
61                     SpiceInt            n,
62                     SpiceInt            polydg,
63                     ConstSpiceDouble    cdata[],
64                     SpiceDouble         dscale,
65                     SpiceDouble         tscale,
66                     SpiceDouble         initjd,
67                     SpiceDouble         initfr  )
68 /*
69 
70 -Brief_I/O
71 
72  Variable  I/O  Description
73    --------  ---  --------------------------------------------------
74    handle     I   Handle of SPK file open for writing.
75    body       I   NAIF code for ephemeris object.
76    center     I   NAIF code for the center of motion of the body.
77    frame      I   Reference frame name.
78    first      I   Start time of interval covered by segment.
79    last       I   End time of interval covered by segment.
80    segid      I   Segment identifier.
81    intlen     I   Length of time covered by logical record (days).
82    n          I   Number of logical records in segment.
83    polydg     I   Chebyshev polynomial degree.
84    cdata      I   Array of Chebyshev coefficients and positions.
85    dscale     I   Distance scale of data.
86    tscale     I   Time scale of data.
87    initjd     I   Integer part of begin time (TDB Julian date) of
88                   first record.
89    initfr     I   Fractional part of begin time (TDB Julian date) of
90                   first record.
91    MAXDEG     P   Maximum allowed degree of Chebyshev expansions.
92    DTOL       P   Absolute tolerance for coverage bound checking.
93    TOLSCL     P   Tolerance scale for coverage bound checking.
94 
95 -Detailed_Input
96 
97    handle         is the DAF handle of an SPK file to which a type 20
98                   segment is to be added.  The SPK file must be open
99                   for writing.
100 
101    body           is the NAIF integer code for an ephemeris object
102                   whose state relative to another body is described
103                   by the segment to be created.
104 
105    center         is the NAIF integer code for the center of motion
106                   of the object identified by `body'.
107 
108    frame          is the NAIF name for a reference frame relative to
109                   which the state information for `body' is specified.
110 
111    first,
112    last           are the start and stop times of the time interval
113                   over which the segment defines the state of the
114                   object identified by `body'.
115 
116    segid          is a segment identifier. An SPK segment identifier
117                   may contain up to 40 characters, not counting the
118                   terminating null character.
119 
120    intlen         is the length of time, in TDB Julian days, covered
121                   by each set of Chebyshev polynomial coefficients
122                   (each logical record).
123 
124    n              is the number of number of logical records to be
125                   stored in the segment. There is one logical record
126                   for each time period. Each logical record contains
127                   three sets of Chebyshev coefficients---one for each
128                   coordinate---and three position vector components.
129 
130    polydg         is the degree of each set of Chebyshev
131                   polynomials, i.e. the number of Chebyshev
132                   coefficients per coordinate minus one. `polydg' must
133                   be less than or equal to the parameter MAXDEG.
134 
135    cdata          is an array containing all the sets of Chebyshev
136                   polynomial coefficients and position components to
137                   be placed in the new segment of the SPK file.
138                   There are three sets of coefficients and position
139                   components for each time interval covered by the
140                   segment.
141 
142                   The coefficients and position components are
143                   stored in `cdata' in order as follows:
144 
145                      the (degree + 1) coefficients for the first
146                      coordinate of the first logical record,
147                      followed by the X component of position at the
148                      first interval midpoint.
149 
150                      the coefficients for the second coordinate,
151                      followed by the Y component of position at the
152                      first interval midpoint.
153 
154                      the coefficients for the third coordinate,
155                      followed by the Z component of position at the
156                      first interval midpoint.
157 
158                      the coefficients for the first coordinate for
159                      the second logical record, followed by the X
160                      component of position at the second interval
161                      midpoint.
162 
163                      and so on.
164 
165 
166                   A diagram follows:
167 
168                      +--------------------------------------+
169                      | Coeff set for X velocity component   |
170                      +--------------------------------------+
171                      | X position component                 |
172                      +--------------------------------------+
173                      | Coeff set for Y velocity component   |
174                      +--------------------------------------+
175                      | Y position component                 |
176                      +--------------------------------------+
177                      | Coeff set for Z velocity component   |
178                      +--------------------------------------+
179                      | Z position component                 |
180                      +--------------------------------------+
181 
182                  Each coefficient set has the structure:
183 
184                      +--------------------------------------+
185                      | Coefficient of T_0                   |
186                      +--------------------------------------+
187                      | Coefficient of T_1                   |
188                      +--------------------------------------+
189                                        ...
190                      +--------------------------------------+
191                      | Coefficient of T_POLYDG              |
192                      +--------------------------------------+
193 
194                   Where T_n represents the Chebyshev polynomial
195                   of the first kind of degree n.
196 
197 
198    dscale,
199    tscale         are, respectively, the distance scale of the input
200                   position and velocity data in km, and the time
201                   scale of the input velocity data in TDB seconds.
202 
203                   For example, if the input distance data have units
204                   of astronomical units (AU), `dscale' should be set
205                   to the number of km in one AU. If the input
206                   velocity data have time units of Julian days, then
207                   `tscale' should be set to the number of seconds per
208                   Julian day (86400).
209 
210 
211    initjd         is the integer part of the Julian ephemeris date of
212                   initial epoch of the first record. `initjd' may be
213                   less than, equal to, or greater than the initial
214                   epoch.
215 
216    initfr         is the fractional part of the Julian ephemeris date
217                   of initial epoch of the first record. `initfr' has
218                   units of Julian days. `initfr' has magnitude strictly
219                   less than 1 day. The sum
220 
221                      initjd + initfr
222 
223                   equals the Julian ephemeris date of the initial
224                   epoch of the first record.
225 
226 
227 -Detailed_Output
228 
229    None. This routine writes data to an SPK file.
230 
231 -Parameters
232 
233    The parameters listed below are not used directly in this
234    routine; they are used by the underlying SPICELIB code that
235    has been translated to C via f2c.
236 
237    MAXDEG         is the maximum allowed degree of the input
238                   Chebyshev expansions. MAXDEG is declared in the
239                   SPICELIB Fortran INCLUDE file spk20.inc.
240 
241                   The current value of MAXDEG is 50.
242 
243 
244    TOLSCL         is a tolerance scale factor (also called a
245                   "relative tolerance") used for time coverage
246                   bound checking. TOLSCL is unitless. TOLSCL
247                   produces a tolerance value via the formula
248 
249                      TOL = TOLSCL * MAX( ABS(FIRST), ABS(LAST) )
250 
251                   where FIRST and LAST are the coverage time bounds
252                   of a type 20 segment, expressed as seconds past
253                   J2000 TDB.
254 
255                   The resulting parameter TOL is used as a tolerance
256                   for comparing the input segment descriptor time
257                   bounds to the first and last epoch covered by the
258                   sequence of time intervals defined by the inputs
259 
260                      initjd
261                      initfr
262                      intlen
263                      n
264 
265                   See the Exceptions section below for a description
266                   of the error check using this tolerance.
267 
268                   The current value of TOLSCL is 1e-13.
269 
270 -Exceptions
271 
272    1)  If the number of sets of coefficients is not positive
273        SPICE(INVALIDCOUNT) is signaled.
274 
275    2)  If the interval length is not positive, SPICE(INTLENNOTPOS)
276        is signaled.
277 
278    3)  If the name of the reference frame is not recognized,
279        SPICE(INVALIDREFFRAME) is signaled.
280 
281    4)  If segment stop time is not greater then the begin time,
282        SPICE(BADDESCRTIMES) is signaled.
283 
284    5)  If the start time of the first record exceeds the descriptor
285        begin time by more than a computed tolerance, or if the end
286        time of the last record precedes the descriptor end time by
287        more than a computed tolerance, the error SPICE(COVERAGEGAP)
288        is signaled. See the Parameters section above for a
289        description of the tolerance.
290 
291    6)  If the input degree `polydg' is less than 0 or greater than
292        MAXDEG, the error SPICE(INVALIDDEGREE) is signaled.
293 
294    7)  If the last non-blank character of `segid' occurs past index
295        40, or if `segid' contains any nonprintable characters, the
296        error will be diagnosed by a routine in the call tree of this
297        routine.
298 
299    8)  If either the distance or time scale is non-positive, the
300        error SPICE(NONPOSITIVESCALE) will be signaled.
301 
302    9)  The error SPICE(EMPTYSTRING) is signaled if any input string
303        does not contain at least one character, since the input strings
304        cannot be converted to a Fortran-style string in this case.
305 
306    10) The error SPICE(NULLPOINTER) is signaled if any input string
307        pointer is null.
308 
309 -Files
310 
311    A new type 20 SPK segment is written to the SPK file attached
312    to `handle'.
313 
314 -Particulars
315 
316    This routine writes an SPK type 20 data segment to the designated
317    SPK file, according to the format described in the SPK Required
318    Reading.
319 
320    Each segment can contain data for only one target, central body,
321    and reference frame. The Chebyshev polynomial degree and length
322    of time covered by each logical record are also fixed. However,
323    an arbitrary number of logical records of Chebyshev polynomial
324    coefficients can be written in each segment.  Minimizing the
325    number of segments in an SPK file will help optimize how the
326    SPICE system accesses the file.
327 
328 -Examples
329 
330    Suppose that you have in an array `cdata' sets of Chebyshev
331    polynomial coefficients and position vectors representing the state
332    of the moon (NAIF ID = 301), relative to the Earth-moon barycenter
333    (NAIF ID = 3), in the J2000 reference frame, and you want to put
334    these into a type 20 segment in an existing SPK file. The following
335    code could be used to add one new type 20 segment. To add multiple
336    segments, put the call to spkw20_c in a loop.
337 
338       #include "SpiceUsr.h"
339            .
340            .
341            .
342 
343       /.
344       First open the SPK file and get a handle for it.
345       ./
346       spkopa_c ( spknam, &handle );
347 
348       /.
349       Create a segment identifier.
350       ./
351       segid = "MY_SAMPLE_SPK_TYPE_20_SEGMENT";
352 
353       /.
354       Note that the interval length `intlen' has units
355       of Julian days. The start time of the first record
356       is expressed using two inputs: integer and fractional
357       portions of the Julian ephemeris date of the start
358       time.
359 
360       Write the segment.
361       ./
362       spkw20_c ( handle, 301,    3,      "J2000",
363                  first,  last,   segid,  intlen,
364                  n,      polydg, cdata,  dscale,
365                  tscale, initjd, initfr          );
366 
367       /.
368       Close the file.
369       ./
370       spkcls_c ( handle );
371 
372 -Restrictions
373 
374    None.
375 
376 -Literature_References
377 
378    None.
379 
380 -Author_and_Institution
381 
382    N.J. Bachman (JPL)
383 
384 -Version
385 
386    -CSPICE Version 1.0.0, 23-DEC-2013 (NJB)
387 
388 -Index_Entries
389 
390    write spk type_20 data segment
391 
392 -&
393 */
394 
395 { /* Begin spkw20_c */
396 
397 
398    /*
399    Participate in error tracing.
400    */
401    chkin_c ( "spkw20_c" );
402 
403    /*
404    Check the input strings to make sure the pointers
405    are non-null and the string lengths are non-zero.
406    */
407    CHKFSTR ( CHK_STANDARD, "spkw20_c", frame );
408    CHKFSTR ( CHK_STANDARD, "spkw20_c", segid );
409 
410 
411    /*
412    Write the segment.
413    */
414    spkw20_ ( ( integer    * ) &handle,
415              ( integer    * ) &body,
416              ( integer    * ) &center,
417              ( char       * ) frame,
418              ( doublereal * ) &first,
419              ( doublereal * ) &last,
420              ( char       * ) segid,
421              ( doublereal * ) &intlen,
422              ( integer    * ) &n,
423              ( integer    * ) &polydg,
424              ( doublereal * ) cdata,
425              ( doublereal * ) &dscale,
426              ( doublereal * ) &tscale,
427              ( doublereal * ) &initjd,
428              ( doublereal * ) &initfr,
429              ( ftnlen       ) strlen(frame),
430              ( ftnlen       ) strlen(segid)  );
431 
432 
433    chkout_c ( "spkw20_c" );
434 
435 } /* End spkw20_c */
436