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 * ) ¢er, 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