SPK Required Reading 
Table of ContentsSPK Required Reading Abstract Purpose Intended Audience References DAF RunTime Binary File Format Translation Detection of Nonnative Text Files If you're in a hurry High Level Functions Foundation Functions Utility Programs Introduction SPK Files Use of SPK files between computers Examining SPK files Meta Data in the SPK file Terminology The SPK Family of Functions Computing States Computing States using ConstantVelocity or ConstantPosition Objects The Computation of Light Time Precision of Light Time Computations Light Time Corrected NonInertial States An example Integer ID Codes Used in SPK spkez_c and spkgeo_c Loading Files Data Precedence Unloading Files Getting Coverage Summary Loading Auxiliary Files SPK File Structure SegmentsThe Fundamental SPK Building Blocks Segment Order and Priority The Comment Area SPK Data Types Primitive States Examples of Using SPK Readers Example 1: Computing Latitude and Longitude Example 2: Occultation or Transit Supported Data Types Type 1: Modified Difference Arrays Type 2: Chebyshev (position only) Type 3: Chebyshev (position and velocity) Type 5: Discrete states (two body propagation) Type 8: Lagrange Interpolation  Equal Time Steps Type 9: Lagrange Interpolation  Unequal Time Steps Type 10: Space Command TwoLine Elements Type 12: Hermite Interpolation  Equal Time Steps Type 13: Hermite Interpolation  Unequal Time Steps Type 14: Chebyshev Polynomials  Unequal Time Steps Type 15: Precessing Conic Propagation Type 17: Equinoctial Elements Type 18: ESOC/DDID Hermite/Lagrange Interpolation Type 19: ESOC/DDID Piecewise Interpolation Type 20: Chebyshev (velocity only) Type 21: Extended Modified Difference Arrays Appendix A  Summary of SPkernel Functions Summary of Mnemonics Summary of Calling Sequences Appendix B  A Template for SPK Comments Constraints The Basic Template Objects in the Ephemeris Approximate Time Coverage Status Pedigree Usage Accuracy Special Notes References Contacts Appendix CRevision History March 29, 2017 July 14, 2014 April 15, 2009 February 28, 2008 November 17, 2005 December 22, 2004 February 2, 2004 September 04, 2002 July 21, 2001 March 1, 2000 October 14, 1999 SPK Required Reading
Abstract
Purpose
Intended Audience
References
DAF RunTime Binary File Format Translation
Detection of Nonnative Text Files
If you're in a hurry
High Level Functions
furnsh_c ( <file> ) unload_c ( <file> )Getting coverage summary
spkobj_c ( <file>, ids ) spkcov_c ( <file>, <idcode>, cover )Retrieving states (position and velocity) using names of objects
spkezr_c ( <object>, <et>, <frame>, <corr>, <observer>, state, < )Retrieving positions using names of objects
spkpos_c ( <object>, <et>, <frame>, <corr>, <observer>, postn, < )Retrieving states using NAIF ID codes
spkez_c ( <obj_id>, <et>, <frame>, <corr>, <obj_id>, state, < ) spkgeo_c ( <obj_id>, <et>, <frame>, <obj_id>, state, < )Retrieving positions using NAIF ID codes
spkezp_c ( <obj_id>, <et>, <frame>, <corr>, <obj_id>, postn, < ) spkgps_c ( <obj_id>, <et>, <frame>, <obj_id>, postn, < )Calculating ``Uplink and Downlink'' Light Time
ltime_c ( <etobs>, <obs_id>, <dir>, <targ_id>, &ettarg, &elapsd )Loading/Unloading Binary PCK files (see PCK Required Reading, pck.req)
furnsh_c ( <binary_pck> ) unload_c ( <binary_pck> )Loading Text based kernelsPCK, SCLK, etc.
furnsh_c ( <text_kernel> )Loading/Unloading Ckernels (see CK Required Reading, ck.req)
furnsh_c ( <ckernel> ) unload_c ( <ckernel> ) Foundation Functions
Selecting files and segments
spksfs_c ( <target>, <et>, &handle, descr, ident, &found )Computing states from segment descriptors
spkpvn_c ( <handle>, <descr>, <et>, ref, state, ¢er )Correcting for stellar aberration
stelab_c ( pobj, vobs, appobj )Translating between object names and object ID codes (see NAIF_IDS Required Reading, naif_ids.req)
bodn2c_c ( <name>, &idcode, &found ) bodc2n_c ( <idcode>, name, &found )Translating between frame names and frame ID codes (see Frames Required Reading, frames.req)
frmnam_c ( <idcode>, name ) namfrm_c ( <name>, &idcode )State transformation matrices (see Frames Required Reading, frames.req)
sxform_c ( <from_name>, <to_name>, <et>, mat6x6 )Classifying frames (see Frames Required Reading, frames.req)
frinfo_c ( <idcode>, ¢er, &class, &clssid, &found ) Utility Programs
brief commnt spacitConverting to and from transfer format
spacit tobin toxfr Introduction
Historically, ephemerides for spacecraft have been organized differently from those for planets and satellites. They are usually generated through different processes and using different representations. However, there is no essential reason for keeping them separate. A spacecraft, planet, satellite, comet, or asteroid has a position and velocity relative to some center of mass and reference frame. Consequently all of these objects can be represented in an SPK file. Consider the Galileo mission. Some of the objects of special interest to the Galileo mission are:
Galileo Spacecraft Galileo Probe Earth Moon Earth Moon Barycenter Venus Sun Solar System Barycenter (S.S.B.) Asteroid Ida Ida's Satellite Dactyl Asteroid Gaspra Comet ShoemakerLevy Jupiter System Barycenter (J.B.) Jupiter Io Ganymede Europa Callysto Goldstone Tracking Station.Each of these objects has a position and velocity (state) relative to some other object. The graph below illustrates which objects will be used as reference objects for representing the states of others.
+Gll / probe /  o Comet Gaspra / Gll+ / Shoemaker Levy Gll +o / \ /  / Venus Jupiter oprobe  / o+  Gll +  / / Gll  Io   / /  o+Gll  / / J.B. / Ida oooo o+Gll / Sun S.S.B. / \ Europa o \ Ganymede / \ Dactyl \ o \ \  o Callisto EarthMoon Barycenter oo +   Moon Gll   + Gll o Earth / \ / \ / + Gll o GoldstoneThis graph is somewhat complicated. Nevertheless, the complete ephemeris history for all of these objects can be captured in a single SPK file. (Although we can store the entire ephemeris history illustrated above in a single SPK file, for the sake of data management a project is likely to use several SPK files. However, even in this case, all of the SPK files can be used simultaneously.) The SPK format is supported by a collection of functions that are part of the CSPICE librarythe major component of the SPICE Toolkit. This family of SPK functions provides the following capabilities:
SPK Files
Since SPKs are written as binary files, the specific binary format depends on the computer architecture on which the SPK was created, in the case of SPICE either bigendian or littleendian (NAIF no longer supports DEC platforms). Use of SPK files between computers
NAIF provides two utility programsTOXFR and SPACIT for converting SPICE binary kernels to a ``transfer format'' suitable for text copying from one computer to another. Once the transfer format file has been copied, the SPICE utilities TOBIN and SPACIT are available for converting the transfer format file to the binary format suitable for the new machine. The utilities TOXFR and TOBIN are ``command line'' programs. To convert a binary kernel to transfer format you simply type TOXFR followed by the name of the binary kernel at your terminal prompt.
prompt> toxfr spk_fileTo convert a transfer format to binary format, you type TOBIN followed by the name of the transfer format kernel.
prompt> tobin transfer_fileThe utility SPACIT is an interactive program that allows you to select a function from a menu to perform on a file. This program can also be used to convert to or from transfer format files. Note that transfer format files cannot be ``loaded'' into a SPICE based program to retrieve ephemeris data. Only binary format files can be used for retrieving ephemeris data with SPICE software. CSPICE (and by extension Icy and Mice) uses the same binary kernels as does SPICELIB. Examining SPK files
BRIEF gives a quick summary of the contents of the file and supports a wide set of summary options. SPACIT on the other hand, provides summaries that are more detailed and reflect closely the actual internal structure of the file. Unless you need the more detailed summary, you'll probably find BRIEF to be a better tool for examining the contents of an SPK file. Meta Data in the SPK file
We've already introduced SPACIT. COMMNT is similar to SPACIT in that it too is an interactive program. However, COMMNT also allows you to modify the comments of an SPK file. Using COMMNT you can delete the comments of an SPK file, extract the comments to a text file, or append the text from some text file to the comments already present in the kernel. If you create SPK files, we strongly recommend that you add comments to the kernel that describe who created it, expected usage of the kernel, and the expected accuracy of the position/velocity information contained in the kernel. A comment template is provided in the appendix ``COMMENTS''. Warning: If you add comments to an SPK (or other binary kernel) using COMMNT, you must wait for the program to complete the task before exiting the program. Failure to wait for COMMNT to finish its work will result in irreparable corruption of the binary kernel. (See the COMMNT User's Guide, commnt.ug, [212] for details on the use of COMMNT). Terminology
The SPK Family of Functions
Each function is prefaced by a complete CSPICE header, which describes inputs, outputs, restrictions, and exceptions, discusses the context in which the function can be used, and shows typical examples of its use. Any discussion of the functions in this document is intended as an introduction: the final documentation for any function is its header. Whenever an SPK function appears in an example, the translation of the mnemonic part of its name will appear to the right of the reference, in braces. We also continue with the convention of distinguishing between input and output arguments by enclosing input arguments in angle brackets. For example,
spkezr_c ( <targ>, <et>, <frame>, <aberr>, <obs>, state, < ); { Easier state }All C functions, including those whose names do not begin with `SPK', are from CSPICE or the standard ANSI C library. SPK readers are available to perform the following functions.
Computing States
spkezr_c ( <targ>, <et>, <frame>, <aberr>, <obs>, state, < ); { Easier state }The function accepts five inputstarget body, epoch, reference frame, aberration correction type, and observing bodyand returns two outputsstate of the target body as seen from the observing body, and oneway lighttime from the target body to the observing body. The target body, observing body and frame are identified by strings that contain the names of these items. For example, to determine the state of Triton as seen from the Voyager2 spacecraft relative to the J2000 reference frame
spkezr_c ( "triton", et, "j2000", aberr, "voyager2", state, < ); { Easier state }By definition, the ephemerides in SPK files are continuous: the user can obtain states at any epoch within the interval of coverage. Epochs are always specified in ephemeris seconds past the epoch of the J2000 reference system (Julian Ephemeris Date 2451545.0 ) For example, to determine the state of Triton as seen from Voyager2 at Julian Ephemeris Date 2447751.8293,
et = ( 2447751.8293  j2000_c() ) * spd_c(); spkezr_c ( "triton", et, "j2000", <aberr>, "voyager2", state, < ); { Easier state }where the function j2000_c returns the epoch of the J2000 frame (Julian Ephemeris Date 2451545.0) and the function spd_c returns the number of seconds per Julian day (86400.0). The ephemeris data in an SPK file may be referenced to a number of different reference frames. States returned by spkezr_c do not have to be referenced to any of these ``native'' frames. The user can specify that states are to be returned in any of the frames recognized by the frame subsystem. For example, to determine the state of Triton as seen from Voyager2, referenced to the J2000 ecliptic reference frame,
spkezr_c ( "triton", et, "eclipj2000", aberr, "voyager2", state, < ); { Easier state }spkezr_c returns apparent, true, or geometric states depending on the value of the aberration correction type flag `aberr'. Apparent states are corrected for planetary aberration, which is the composite of the apparent angular displacement produced by motion of the observer (stellar aberration) and the actual motion of the target body (correction for lighttime). True states are corrected for lighttime only. Geometric states are uncorrected. Instead of using the potentially confusing terms `true' and `geometric' to specify the type of state to be returned, spkezr_c requires the specific corrections to be named. To compute apparent states, specify correction for both lighttime and stellar aberration: `LT+S'. To compute true states, specify correction for lighttime only: `LT'. To compute geometric states, specify no correction: `NONE'. In all cases, the oneway lighttime from the target to the observer is returned along with the state. Computing States using ConstantVelocity or ConstantPosition Objects
However, it is not always convenient to create an SPK file to provide data for an ephemeris object, particularly when that object's location is known only at run time. For an object that has constant velocity, relative to a specified center of motion, in a specified reference frame, CSPICE offers a set of functions to compute states relative to other ephemeris objects, where the other objects have ephemeris data provided by SPK files:
spkcpo_c {SPK, constant position observer state} spkcpt_c {SPK, constant position target state} spkcvo_c {SPK, constant velocity observer state} spkcvt_c {SPK, constant velocity target state}The ``constant position'' routines have simplified interfaces; these handle the special case where the constant velocity is zero. Each of the above functions requires that sufficient SPK data be available to compute the state of the center of motion, relative to the other ephemeris object, of the constantvelocity or constantposition object. States computed by SPK functions for constantvelocity or constantposition objects optionally can be corrected for light time and stellar aberration, just as is done by spkezr_c. A limitation of representing objects using constant velocities or positions, instead of creating SPK files to provide the ephemerides of those objects, is that highlevel CSPICE geometry routines such as sincpt_c or subpt_c cannot work with such objectsthese functions require SPK data for all ephemeris objects participating in the computations they perform. The Computation of Light Time
TARGET_SSB ( ET + S*LT )  OBSERVER_SSB ( ET )where TARGET_SSB and OBSERVER_SSB give the position of the target and observer relative to the solar system barycenter, and where S is 1 for reception corrections (where light travels from the target to the observer) and 1 for transmission corrections (where light travels from the observer to the target). LT is the unique number that satisfies:
 TARGET_SSB ( ET + S*LT )  OBSERVER_SSB ( ET )  LT =  Speed of Lightwhere
 position indicates the length of a position vector. The velocity portion of the returned state is the derivative with respect to the observation time ET of the light time corrected position. Mathematically, LT can be computed to arbitrary precision via the following algorithm:
LT_0 = 0  TARGET_SSB ( ET  LT_(i1) )  OBSERVER_SSB ( ET )  LT_i =  Speed of Light for i = 1, ...It can be shown that the sequence LT_0, LT_1, LT_2, ... converges to LT geometrically. Moreover, it can be shown that the difference between LT_i and LT satisfies the following inequality.
i  LT  LT_i  < LT_i * ( V/C ) / ( 1  V/C ) for i = 1, ...where V is the maximum speed of the target body with respect to the solar system barycenter and C is the speed of light. Precision of Light Time Computations
For nearly all objects in the solar system V is less than 60 km/sec. The value of C is approximately 300000 km/sec. Thus V/C is 2.0E4, and the one iteration solution for LT (in which the targetSSB vector is corrected once) has a potential relative error of not more than 4.0E8. This is a potential light time error of approximately 2.0E5 seconds per astronomical unit of distance separating the observer and target. Thus as long as the observer and target are separated by less than 50 Astronomical Units, the error in the light time returned using option `LT' is less than 1 millisecond. For this reason, CSPICE uses LT_2 to approximate LT when you request a light time corrected state by setting the aberration correction argument in spkezr_c to any of `LT', `XLT', `LT+S', `XLT+S'. The maximum error in the light time corrected targetSSB position vector is larger by a factor of C/V than V times the maximum relative light time error. This is because the (i1)st light time estimate is used to compute the ith estimate of targetSSB position vector. Given the assumptions above, the maximum position error for the `LT'style correction is bounded by
60 km/s * (1/(2.0E4)) * 2*1.0E5 s / AUor 6 km per astronomical unit of distance separating the observer and target. In practice, the difference between positions obtained using oneiteration and converged light time is usually much smaller than the value computed above and can be insignificant. For example, for the spacecraft Mars Reconnaissance Orbiter and Mars Express, the position error for the oneiteration light time correction, applied to the spacecrafttoMars center vector, is approximately 2 cm. You can make spkezr_c (and other applicable SPK functions) compute a better approximation to LT and compute more accurate lighttime corrected states by commanding that it compute a ``converged Newtonian'' value for LT. To do this set the light time portion of the aberration correction specification to `CN' (the possible such aberration correction specifications are`CN', `XCN', `CN+S', or `XCN+S'). spkezr_c will then return a converged value, usually equal to LT_4, as the approximation for light time; the returned state will be converged as well. Then the maximum error in LT_4 is less than
1.0E3 * (V/C)**2 secondswhich is less than 4e11 seconds for any observer/target pair in the solar system that satisfies the assumptions above. The corresponding position error bound is 1.2 cm at a separation of 50 AU. However, you should note that this is a purely Newtonian approximation to the light time. To model the actual light time between target and observer one must take into account effects due to General relativity. These may be as high as a few hundredths of a millisecond for some geometric cases. The functions in the SPK family do not attempt to perform either general or special relativistic corrections in computing the various aberration corrections. For many applications relativistic corrections are not worth the expense of added computation cycles. If, however, your application requires these additional corrections we suggest you consult the astronomical almanac (page B36) for a discussion of how to carry out these corrections. Light Time Corrected NonInertial States
Suppose that a large balloon has been launched into the Martian atmosphere and we want to determine the Mars bodyfixed state of the balloon as seen from Earth at the epoch ET. We need to determine both the light time corrected position of the balloon, and the light time corrected orientation of Mars. To do this we compute two light times. The light time to the center of the Mars bodyfixed frame (i.e. the center of Mars) and the light time to the balloon. Call the light time to the center of the Mars frame LT_F and call the light time to the balloon LT_T. The light time corrected state of the balloon relative to the Mars bodyfixed frame is the location of the balloon at ET  LT_T in the bodyfixed frame of Mars as oriented at ET  LT_F. spkezr_c carries out all of these computations automatically. In this case the computation would be computed by a function call similar to this:
spkezr_c ( "mars_balloon", <et>, "iau_mars", "lt", "earth", state, < );spkezr_c uses the following rules when computing states.
An example
We will need the lengths of the axes of the triaxial ellipsoid that is used to model the surface of Mars. Either of the CSPICE functions bodvcd_c or bodvrd_c will retrieve this information from a loaded PCK file. bodvrd_c uses the name of the body, while bodvcd_c uses the NAIF ID code for Mars (499) to retrieve the lengths of the axes. We may call bodvcd_c as shown:
bodvcd_c ( 499, "RADII", 3, &nvals, axes ); a = axes[0]; b = axes[1]; c = axes[2];Next we compute the state of Mars relative to Earth and the state of MGS relative to Earth in the Mars bodyfixed frame.
spkezr_c ( "mars", et, "iau_mars", "lt+s", "earth", marsst, < ); spkezr_c ( "mgs", et, "iau_mars", "lt+s", "earth", mgsst, < ); {Easier State}Compute the apparent position of the Earth relative to Mars in the apparent Mars bodyfixed frame. This means simply negating the components of `marsst'. The CSPICE function vminus_c carries out this task.
vminus_c ( marsst, estate );Determine if the line of sight from Earth to MGS intersects the surface of Mars. The CSPICE function surfpt_c will find this intersection point if it exists.
surfpt_c ( estate, mgsst, a, b, c, point, &found );Finally, if a point of intersection was found, was it between the Earth and the MGS spacecraft. To find out we can compare the distances between the intersection point and the spacecraft. The CSPICE function vnorm_c computes the length of the vector from Earth to MGS. The function vdist_c computes the distance between the point and the Earth.
if ( found ) { betwn = ( vdist_c ( estate, point ) < vnorm_c ( mgsst ) ); } else { betwn = SPICEFALSE; } if ( betwn ) { printf ( "mgs is behind mars\n" ); } else { printf ( "mgs is not behind mars\n" ); } Integer ID Codes Used in SPK
Highlevel SPICE software uses names (character strings) to refer to the various SPICE objects and translates between names and integer codes. Thus to some extent you can disregard the integer codes used by the SPICE internals. However, occasionally, due to the introduction of new ephemeris objects, the name translation software will be unable to find a name associated with an ID code. To retrieve states for such an object you will need to use the integer code for the object in question. If you are using spkezr_c, you can supply this integer code as a quoted string. For example the following two function calls will both return the state of TRITON as seen from Voyager2. (The NAIF integer code for TRITON is 801; the NAIF integer code for Voyager 2 is 32).
spkezr_c ( "triton", et, "eclipJ2000", aberr, "voyager2", state, < ); { Easier state } spkezr_c ( "801", et, "eclipJ2000", aberr, "32", state, < ); { Easier state }Consult the NAIF IDS Required Reading file, naif_ids.req, for the current list of body codes recognized by the SPICE Toolkit software. spkez_c and spkgeo_c
The function spkez_c performs the same functions as spkezr_c. The only difference is the means by which objects are specified. spkez_c requires that the target and observing bodies be specified using the NAIF integer ID codes for those bodies.
spkez_c ( <targ_id>, <et>, <frame>, <corr>, <obj_id>, state, < ); { SPK Easy }The NAIFID codes for ephemeris objects are listed in the NAIF_IDS required reading file, naif_ids.req. spkez_c is useful in those situations when you have ID codes for objects stored as integers. There is also a modest efficiency gain when using integer ID codes instead of character strings to specify targets and observers. The function spkgeo_c returns only geometric (uncorrected) states. The following two function calls are equivalent.
spkez_c ( <targ_id>, <et>, <frame>, "none", <obj_id>, state, < ); {SPK Easy} spkgeo_c ( <targ_id>, <et>, <frame>, <obj_id>, state, < ); {SPK Geometric }spkgeo_c involves slightly less overhead than does spkez_c and thus may be marginally faster than calling spkez_c. Loading Files
for ( i = 0; i < N; i++ ) { furnsh_c ( ephem[i] ); { Load kernel file } }In general, a state returned by spkezr_c is built from several more primitive states. Consider the following diagram, which shows some of the states that might be needed to determine the state of the Galileo spacecraft as seen from Earth:
Jupiter_Barycenter  Europa / \ / \ / Spacecraft / / / / SSB \ \ \ EMB  Earth(SSB and EMB are the solar system and EarthMoon barycenters.) Each state is computed from a distinct segment. The segments may reside in a single SPK file, or may be contained in as many as five separate files. For example, the segments needed to compute the Earthspacecraft state shown above might come from the following set of files:
furnsh_c ( "barycenters.bsp" ); { Load kernel file } furnsh_c ( "planetcenters.bsp" ); { Load kernel file } furnsh_c ( "satellites.bsp" ); { Load kernel file } furnsh_c ( "spacecraft.bsp" ); { Load kernel file }or from the following set:
furnsh_c ( "earth.bsp" ); { Load kernel file } furnsh_c ( "jupiter.bsp" ); { Load kernel file } furnsh_c ( "spacecraft.bsp" ); { Load kernel file } Data Precedence
Unloading Files
furnsh_c ( "file.a" ); { Load kernel file } furnsh_c ( "file.b" ); { Load kernel file } furnsh_c ( "file.c" ); { Load kernel file } unload_c ( "file.b" ); { Unload kernel file } furnsh_c ( "file.d" ); { Load kernel file } unload_c ( "file.c" ); { Unload kernel file }is equivalent to the following (shorter) sequence:
furnsh_c ( "file.a" ); { Load kernel file } furnsh_c ( "file.d" ); { Load kernel file } Getting Coverage Summary
The spkobj_c function provides an API via which an application can find the set of bodies for which a specified SPK file contains data. The body IDs are returned in a SPICE ``set'' data structure (see sets.req). The spkcov_c function provides an API via which an application can find the time periods for which a specified SPK file provides data for an body of interest. The coverage information is a set of disjoint time intervals returned in a SPICE ``window'' data structure (see windows.req). Refer to the headers of spkobj_c and spkcov_c for details on the use of those routines. Loading Auxiliary Files
On the other hand, the orientation of noninertial frames with respect to other frames are almost always the result of observation. They are improved and extended as further observations are made. For some of these frames (such as spacecraft fixed frames) very large data sets are needed to express the orientation of the frame with respect to other frames. Frame transformations that are a function of time and require megabytes of data are not suitable for encapsulation in C or FORTRAN source code. As a result, in the SPICE system, the computation of noninertial frame transformations depends upon data stored in other SPICE kernels. If you request states relative to a noninertial frame or use ephemerides that are represented relative to noninertial frames you must load additional SPICE kernels. The method by which an auxiliary kernel is loaded depends upon the type of the kernel. There are currently five classes of reference frames that are supported by the SPICE system. We give a brief overview of these frames here. For a more thorough discussion of the various types of frames see the recommended reading file ``frames.req.'' Inertial frames
furnsh_c ( <file> );
unload_c ( <file> );
furnsh_c ( <file> )CK Frames
furnsh_c ( <file> );
unload_c ( <file> );
furnsh_c ( <sclk_file_name> );TK Frames
furnsh_c ( <TK_frame_file> );Dynamic Frames
furnsh_c ( <Dynamic_frame_file> );In addition to the files mentioned above, it may be necessary to load a ``frame definition'' file along with the one of the SPICE kernels listed above. (If the producer of the file has done his or her homework this step should be unnecessary.) The frame definition file is a SPICE text kernel that specifies the type of the frame, the center of the frame, the name of the frame, and its ID code. (See frames.req for more details concerning frame definitions.) As is evident from the above discussion, the use of noninertial frames requires more data management on the part of the user of the SPICE system. However, this data management problem is not a new problem. In previous versions of the SPICE system the same kernels would have been required. Moreover, in previous versions of the SPICE system, you would have been required to perform all noninertial transformations in your own code. With the inclusion of noninertial frames in the SPK system, we have relieved you of some of the tasks associated with noninertial frames. SPK File Structure
SegmentsThe Fundamental SPK Building Blocks
Either body may be a spacecraft, a planet or planet barycenter, a satellite, a comet, an asteroid, a tracking station, a roving vehicle, or an arbitrary point for which an ephemeris has been calculated. Each body in the solar system is associated with a unique integer code. A list of names and codes for the planets, major satellites, spacecraft, asteroids and comets can be found in the document naif_ids.req The states computed from the ephemeris data in a segment must be referenced to a single, recognized reference frame. The data in each segment are stored as an array of double precision numbers. The summary for the array, called a `descriptor', has two double precision components:
Segment Order and Priority
However, segment order does imply priority. For a given target body, segment priority increases with distance from the start of the file: segments closer to the end of the file have higher priority than segments for the same target body that occur earlier in the file. When a data request for a specified target body is made, the segment for that target body with highest priority, and whose time interval includes the request time, will be selected to satisfy the request. SPK producers should note that this priority scheme would cause a higher priority segment for a target body to mask a lower priority segment for the same body over the intersection of the coverage intervals of the two segments, if two such segments were written to an SPK file. In particular, if an SPK file contained two segments for the same target body and time interval, where the segments had different central bodies, the lower priority segment would be invisible to the SPK system. The Comment Area
The utility programs COMMNT and SPACIT may be used to examine and manipulate the comments in an SPK file. In addition to these utilities, CSPICE provides a family of functions for handling this Comment Area. The name of each function in this family begins with the letters `SPC' which stand for `SPk and Ck' because this feature is common to both types of files. The SPC software provides the ability to add, extract, read, and delete comments and convert commented files from binary format to SPICE transfer format and back to binary again. The SPC functions and their functions are described in detail in the SPC Required Reading, spc.req. SPK Data Types
For purposes of determining the segment best suited to fulfill a particular request, all segments are treated equally. It is only when the data in a segment are to be evaluatedwhen a state vector is to be computedthat the type of data used to represent the ephemeris becomes important. Because this step is isolated within a single lowlevel reader, spkpvn_c, new data types can be added to the SPK format without affecting application programs that use the higher level readers. spkpvn_c is designed so that the changes required to implement a new data type are minimal. There are no real limits on the possible representations that can be used for ephemeris data. Users with access to data suitable for creating an ephemeris may choose to invent their own representations, adapting spkpvn_c accordingly. (We recommend that you consult with NAIF prior to implementing a new data type.) The data types currently supported by CSPICE software are listed under ``Supported Data Types'' later in this document. Primitive States
spkpvn_c ( <handle>, <descr>, <et>, ref, state, center ); { Position, velocity, native frame }spkpvn_c is the most basic SPK reader. It returns states relative to the frame in which they are stored in the SPK file. It does not rotate or combine them: it returns a state relative to the center whose integer code is stored in the descriptor for the segment. This state is relative to the frame whose integer ID code is also stored in the descriptor of the segment. The user is responsible for using that state correctly. The user is also responsible for using DAF functions to determine the particular file and segment from which each state is to be computed. Note that to use the state returned by spkpvn_c in any frame other than the ``native frame'' of the segment, you must convert the state to the frame of interest. If files have been loaded by previous calls to furnsh_c, it is possible to use the same segments that would normally be used by spkezr_c, spkez_c, spkssb_c, and spkgeo_c. Function spksfs_c selects, from the database of loaded files, the file handle and segment descriptor for the segment best suited to the request. If two segments from different files are suitable, spksfs_c selects the one from the file that was loaded later. If two segments from the same file are suitable, spksfs_c selects the one that is stored later in the file. The call
spksfs_c ( <801>, <et>, idlen, &handle, descr, segnam, &found ); { Select file and segment }returns the handle, descriptor, and segment name for the latest segment containing data for Triton at the specified epoch. spksfs_c maintains a buffer of segment descriptors and segment names, so it doesn't waste time searching the database for bodies it already knows about. Examples of Using SPK ReadersExample 1: Computing Latitude and Longitude
All functions used in the examples are from CSPICE. The convention of expanding SPK function names will be dropped for these examples. The first example program computes the planetocentric latitude and longitude of the subobserver point on a target body for any combination of observer, target, and epoch. (Note that planetocentric coordinates differ from planetographic and cartographic coordinates in that they are always righthanded, regardless of the rotation of the body. Also note that for this example we define the subobserver point to be the point on the ``surface'' of the target that lies on the ray from the center of the target to the observer. )
/* PROGRAM LATLON */ /* Standard includes */ #include <stdio.h> #include <string.h> #include <stdlib.h> /* CSPICE prototypes and definitions. */ #include "SpiceUsr.h" int main() { /* Constants */ #define BDNMLN 37 #define FRNMLN 33 #define TIMLEN 51 /* Variables */ SpiceChar time [ TIMLEN ]; SpiceChar obs [ BDNMLN ]; SpiceChar targ [ BDNMLN ]; SpiceChar frame [ FRNMLN ]; SpiceDouble et; SpiceDouble lat; SpiceDouble lon; SpiceDouble lt; SpiceDouble radius; SpiceDouble state [6]; /* Load constants into the kernel pool. Two files are needed. The first ("leapseconds.ker") contains the dates of leap seconds and values for constants needed to compute the difference between UTC and ET at any epoch. The second ("pck.ker") contains IAU values needed to compute transformations from inertial (J2000) coordinates to bodyfixed (pole and prime meridian) coordinates for the major bodies of the solar system. (These files, or their equivalents, are normally distributed along with CSPICE.) */ furnsh_c ( "leapseconds.ker" ); furnsh_c ( "pck.ker" ); /* Several ephemeris files are used. Most contain data for a single planetary system ("jupiter.bsp", "saturn.bsp", and so on). Some contain data for spacecraft ("vgr1.bsp", "mgn.bsp"). */ furnsh_c ( "mercury.bsp" ); furnsh_c ( "venus.bsp" ); furnsh_c ( "earth.bsp" ); furnsh_c ( "mars.bsp" ); furnsh_c ( "jupiter.bsp" ); furnsh_c ( "saturn.bsp" ); furnsh_c ( "uranus.bsp" ); furnsh_c ( "neptune.bsp" ); furnsh_c ( "pluto.bsp" ); furnsh_c ( "vgr1.bsp" ); furnsh_c ( "vgr2.bsp" ); furnsh_c ( "mgn.bsp" ); furnsh_c ( "gll.bsp" ); /* Inputs are entered interactively. The user enters three items: the name for the observer , the name for the target, and the UTC epoch at which the subobserver point is to be computed (a freeformat string). The epoch must be converted to ephemeris time (ET). */ while ( SPICETRUE ) { prompt_c ( "Observer? ", BDNMLN, obs ); prompt_c ( "Target? ", BDNMLN, targ ); prompt_c ( "Epoch? ", TIMLEN, time ); str2et_c ( time, &et ); sprintf ( frame, "IAU_%s", targ ); /* Compute the true state (corrected for lighttime) of the target as seen from the observer at the specified epoch in the target fixed reference frame. */ spkezr_c ( targ, et, frame, "lt", obs, state, < ); /* We need the vector FROM the target TO the observer to compute latitude and longitude. So reverse it. */ vminus_c ( state, state ); /* Convert from rectangular coordinates to latitude and longitude, then from radians to degrees for output. */ reclat_c ( state, &radius, &lon, &lat ); printf ( "\n" "Subobserver latitude (deg): %f\n" " longitude : %f\n" "\n" "Range to target (km) : %f\n" "Lighttime (sec) : %f\n" "\n", lat * dpr_c(), lon * dpr_c(), radius, lt ); /* Get the next set of inputs. */ } return ( 0 ); } Example 2: Occultation or Transit
/* PROGRAM OCCTRN */ /* Standard includes */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> /* CSPICE prototypes and definitions. */ #include "SpiceUsr.h" int main() { /* Constants */ #define NSPKS 2 #define NTARG 2 #define BDNMLN 37 #define FRNMLN 33 #define TIMLEN 51 /* Variables */ SpiceBoolean found; SpiceChar time [ TIMLEN ]; SpiceChar obs [ BDNMLN ]; SpiceChar targ [NTARG][ BDNMLN ]; SpiceDouble avg; SpiceDouble d [NTARG]; SpiceDouble et; SpiceDouble lt; SpiceDouble r [NTARG]; SpiceDouble radii [3]; SpiceDouble s [NTARG][6]; SpiceDouble sep; SpiceInt dim; SpiceInt i; SpiceInt j; SpiceInt k; SpiceInt t [NTARG]; /* Load constants into the kernel pool. Two files are needed. The first ("leapseconds.ker") contains the dates of leap seconds and values for constants needed to compute the difference between UTC and ET at any epoch. The second ("radii.tpc") contains values for the triaxial ellipsoids used to model the major major bodies of the solar system. */ furnsh_c ( "leapseconds.ker" ); furnsh_c ( "radii.tpc" ); /* Several ephemeris files are needed. Most contain data for a single planetary system ("jupiter.ker", "saturn.ker", and so on). Some contain data for spacecraft ("vgr1.ker", "mgn.ker"). */ furnsh_c ( "mercury.bsp" ); furnsh_c ( "venus.bsp" ); furnsh_c ( "earth.bsp" ); furnsh_c ( "mars.bsp" ); furnsh_c ( "jupiter.bsp" ); furnsh_c ( "saturn.bsp" ); furnsh_c ( "uranus.bsp" ); furnsh_c ( "neptune.bsp" ); furnsh_c ( "pluto.bsp" ); furnsh_c ( "vgr1.bsp" ); furnsh_c ( "vgr2.bsp" ); furnsh_c ( "mgn.bsp" ); furnsh_c ( "gll.bsp" ); /* Inputs are entered interactively. The user enters four items: the code for the observer (an integer), the codes for two target bodies (integers), and the epoch at which check for occultation or transit is to be computed (a freeformat string). The epoch must be converted to ephemeris time (ET). */ while ( SPICETRUE ) { prompt_c ( "Observer? ", BDNMLN, obs ); prompt_c ( "Target 1? ", BDNMLN, targ[0] ); prompt_c ( "Target 2? ", BDNMLN, targ[1] ); prompt_c ( "Epoch? ", TIMLEN, time ); str2et_c ( time, &et ); /* Get the ID codes associated with the targets */ bodn2c_c ( targ[0], &t[0], &found ); bodn2c_c ( targ[1], &t[1], &found ); /* Get the apparent states of the target objects as seen from the observer. Also get the apparent radius of each object from the kernel pool. (Use zero radius for any spacecraft; use average radius for anything else.) t[i] is the ID code of the i'th target, i = 0, 1. s[i][0..5] is the apparent state of the i'th target. d[i] is the apparent distance to the i'th target. r[i] is the apparent radius of the i'th target. Function vnorm_c returns the Euclidean norm (magnitude) of a threevector. Function sumad_c returns the sum of the elements in a double precision array. */ for ( i = 0; i < 2; i++ ) { spkezr_c ( targ[i], et, "J2000", "LT+S", obs, s[i], < ); d[i] = vnorm_c( s[i] ); if ( t[i] < 0 ) { r[i] = 0.; } else { bodvcd_c ( t[i], "RADII", 3, &dim, radii ); avg = sumad_c ( radii, 3 ) / 3.0; r[i] = asin ( avg / d[i] ); } } /* Determine the separation between the two bodies. If the separation between the centers is greater than the sum of the apparent radii, then the target bodies are clear of each other. Function vsep_c returns the angle of separation between two threevectors. */ sep = vsep_c ( s[0], s[1] )  ( r[0] + r[1] ); if ( sep > 0. ) { printf ( "\nClear.\n" ); /* Otherwise, the smaller body is either occulted or in transit. We compare ranges to decide which. */ } else { /* Let index j indicate the target of smaller radius; let k indicate the larger target. */ ( r[0] < r[1] ) ? (j = 0) : (j = 1); k = 1j; if ( d[j] < d[k] ) { printf ( "\n%s is in transit across %s\n", targ[j], targ[k] ); } else { printf ( "\n%s is occulted by %s\n", targ[j], targ[k] ); } } /* Get the next set of inputs. */ } return ( 0 ); }Additional, working examples of using the principal SPK functions may be found in the ``Cookbook'' programs distributed with the SPICE Toolkit. Supported Data Types
Type 1: Modified Difference Arrays
Each segment containing Modified Difference Arrays contains an arbitrary number of logical records. Each record contains difference line coefficients valid up to some final epoch, along with the state at that epoch. The contents of the records themselves are described in [163]. The function spke01_ contains the algorithm used to construct a state from a particular record and epoch. The records within a segment are ordered by increasing final epoch. The final epochs associated with the records must be distinct. A segment of this type is structured as follows:
++  Record 1 (difference line coefficients)  ++  Record 2 (difference line coefficients)  ++ . . . ++  Record N (difference line coefficients)  ++  Epoch 1  ++  Epoch 2  ++ . . . ++  Epoch N  ++  Epoch 100  (First directory epoch) ++  Epoch 200  (Second directory epoch) ++ . . . ++  Epoch (N/100)*100  (Final directory epoch) ++  N  ++The number of records in a segment, N, can be arbitrarily large. Records 1 through N contain the difference line coefficients and other constants needed to compute state data. Each one of these records contains 71 double precision numbers. The list of final epochs for the records is stored immediately after the last record. Following the list of epochs is a second list, the `directory', containing every 100th epoch from the previous list. If there are N epochs, there will be N/100 directory epochs. If there are fewer than 100 epochs, then the segment will not contain any directory epochs. Directory epochs are used to speed up access to desired records. The final element in the segment is the number of records contained in the segment, N. The index of the record corresponding to a particular epoch is the index of the first epoch not less than the target epoch. Type 2: Chebyshev (position only)
Each segment contains an arbitrary number of logical records. Each record contains a set of Chebyshev coefficients valid throughout an interval of fixed length. The function spke02_ contains the algorithm used to construct a state from a particular record and epoch. The records within a segment are ordered by increasing initial epoch. All records contain the same number of coefficients. A segment of this type is structured as follows:
++  Record 1  ++  Record 2  ++ . . . ++  Record N  ++  INIT  ++  INTLEN  ++  RSIZE  ++  N  ++A fournumber `directory' at the end of the segment contains the information needed to determine the location of the record corresponding to a particular epoch.
++  MID  ++  RADIUS  ++  X coefficients  ++  Y coefficients  ++  Z coefficients  ++The first two elements in the record, MID and RADIUS, are the midpoint and radius of the time interval covered by coefficients in the record. These are used as parameters to perform transformations between the domain of the record (from MID  RADIUS to MID + RADIUS) and the domain of Chebyshev polynomials (from 1 to 1 ). The same number of coefficients is always used for each component, and all records are the same size (RSIZE), so the degree of each polynomial is
( RSIZE  2 ) / 3  1To facilitate the creation of Type 2 segments, a segment writing function called spkw02_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 3: Chebyshev (position and velocity)
The structure of the segment is nearly identical to that of the SPK data Type 2 (Chebyshev polynomials for position only). The only difference is that each logical record contains six sets of coefficients instead of three. The function spke03_ contains the algorithm used to construct a state from a particular record and epoch. Each record is structured as follows:
++  MID  ++  RADIUS  ++  X coefficients  ++  Y coefficients  ++  Z coefficients  ++  X' coefficients  ++  Y' coefficients  ++  Z' coefficients  ++The same number of coefficients is always used for each component, and all records are the same size (RSIZE), so the degree of each polynomial is
( RSIZE  2 ) / 6  1To facilitate the creation of Type 3 segments, a segment writing function called spkw03_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 5: Discrete states (two body propagation)
Each segment contains of a number of logical records. Each record consists of an epoch (ephemeris seconds past J2000) and the geometric state of the body at that epoch (x, y, z, dx/dt, dy/dt, dz/dt, in kilometers and kilometers per second). Records are ordered with respect to increasing time. The records that correspond to an epoch for which a state is desired are the ones whose associated epochs bracket that epoch. The state in each record is used as the initial state in a twobody propagation; a weighted average of the propagated states gives the position of the body at the specified epoch. The velocity is given by the derivative of the position. Thus the position and velocity at the specified epoch are given by:
P = W(t) * P1(t) + (1W(t)) * P2(t) V = W(t) * V1(t) + (1W(t)) * V2(t) + W'(t) * ( P1(t)  P2(t) )where P1, V1, P2, and V2 are the position and velocity components of the propagated states and W is the weighting function. The weighting function used is:
W(t) = 0.5 + 0.5 * cos [ PI * ( t  t1 ) / ( t2  t1 ) ]where t1 and t2 are the epochs that bracket the specified epoch t. Physically, the epochs and states are stored separately, so that the epochs can be searched as an ordered array. Thus, the initial part of each segment looks like this:
++  State 1  ++ . . . ++  State N  ++  Epoch 1  ++ . . . ++  Epoch N  ++The number of records in a segment can be arbitrarily large. In order to avoid the file reads required to search through a large array of epochs, each segment contains a simple directory immediately after the final epoch. This directory contains every 100th epoch in the epoch array. If there are N epochs, there will be N/100 directory epochs. (If there are fewer than 100 epochs, no directory epochs are stored.) The final items in the segment are GM, the gravitational parameter of the central body (kilometers and seconds), and N, the number of states in the segment. Thus, the complete segment looks like this:
++  State 1  ++ . . . ++  Epoch 1  ++ . . . ++  Epoch N  ++  Epoch 100  (First directory epoch) ++  Epoch 200  ++ . . . ++  Epoch (N/100)*100  (Final directory epoch) ++  GM  ++  N  ++To facilitate the creation of Type 5 segments, a segment writing function called spkw05_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 8: Lagrange Interpolation  Equal Time Steps
The SPK system can also represent an ephemeris using unequally spaced discrete states and Lagrange interpolation; SPK Type 9 does this. SPK Type 9 sacrifices some runtime speed and economy of storage in order to achieve greater flexibility. The states in a Type 8 segment are geometric: they do not take into account aberration corrections. The six components of each state vector represent the position and velocity (x, y, z, dx/dt, dy/dt, dz/dt, in kilometers and kilometers per second) of the body to which the ephemeris applies, relative to the center specified by the segment's descriptor. The epochs corresponding to the states are barycentric dynamical times (TDB), expressed as seconds past J2000. Each segment also has a polynomial degree associated with it; this is the degree of the interpolating polynomials to be used in evaluating states based on the data in the segment. The identical degree is used for interpolation of each state component. Type 8 SPK segments have the structure shown below:
++  x(1)  / ++ /  y(1)  / ++ /  z(1)  ++ / ++  State 1  < dx(1)/dt ++ \ ++  State 2  \ dy(1)/dt ++ \ ++ . \ dz(1)/dt . ++ . ++  State N  ++  Epoch of state 1 (TDB) ++  Step size  ++  Polynomial degree  ++  Number of states  ++In the diagram, each box representing a state vector corresponds to six double precision numbers; the other boxes represent individual double precision numbers. Since the epochs of the states are evenly spaced, they are represented by a start epoch and a step size. The number of states must be greater than the interpolating polynomial degree. The Type 8 interpolation method works as follows: given an epoch at which a state is requested and a segment having coverage for that epoch, the Type 8 reader finds a group of states whose epochs are `centered' about the epoch. The size of the group is one greater than the polynomial degree associated with the segment. If the group size N is even, then the group will consist of N consecutive states such that the request time is between the epochs of the members of the group having indices, relative to the start of the group, of N/2 and (N/2 + 1), inclusive. When N is odd, the group will contain a central state whose epoch is closest to the request time, and will also contain (N1)/2 neighboring states on either side of the central one. The Type 8 evaluator will then use Lagrange interpolation on each component of the states to produce a state corresponding to the request time. For the jth state component, the interpolation algorithm is mathematically equivalent to finding the unique polynomial of degree N1 that interpolates the ordered pairs
( epoch(i), state(j,i) ), i = k , k , ... , k 1 2 Nand evaluating the polynomial at the requested epoch. Here
k , k , ... , k 1 2 Nare the indices of the states in the interpolation group,
epoch(i)is the epoch of the ith state and
state(j,i)is the jth component of the ith state. There is an exception to the state selection algorithm described above: the request time may be too near the first or last state of the segment to be properly bracketed. In this case, the set of states selected for interpolation still has size N, and includes either the first or last state of the segment. To facilitate the creation of Type 8 segments, a segment writing function called spkw08_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 9: Lagrange Interpolation  Unequal Time Steps
The states in a Type 9 segment are geometric: they do not take into account aberration corrections. The six components of each state vector represent the position and velocity (x, y, z, dx/dt, dy/dt, dz/dt, in kilometers and kilometers per second) of the body to which the ephemeris applies, relative to the center specified by the segment's descriptor. The epochs corresponding to the states are barycentric dynamical times (TDB), expressed as seconds past J2000. Each segment also has a polynomial degree associated with it; this is the degree of the interpolating polynomials to be used in evaluating states based on the data in the segment. The identical degree is used for interpolation of each state component. Type 9 SPK segments have the structure shown below:
++  x(1)  / ++ /  y(1)  / ++ /  z(1)  ++ / ++  State 1  < dx(1)/dt ++ \ ++  State 2  \ dy(1)/dt ++ \ ++ . \ dz(1)/dt . ++ . ++  State N  ++  Epoch 1  ++  Epoch 2  ++ . . . ++  Epoch N  ++  Epoch 100  (First directory) ++ . . . ++  Epoch ((N1)/100)*100  (Last directory) ++  Polynomial degree  ++  Number of states  ++In the diagram, each box representing a state vector corresponds to six double precision numbers; the other boxes represent individual double precision numbers. The number of states must be greater than the interpolating polynomial degree. The set of time tags is augmented by a series of directory entries; these entries allow the Type 9 reader to search for states more efficiently. The directory entries contain time tags whose indices are multiples of 100. The set of indices of time tags stored in the directories ranges from 100 to
( (N1) / 100 ) * 100where N is the total number of time tags. Note that if N is
Q * 100then only
Q  1directory entries are stored, and in particular, if there are only 100 states in the segment, there are no directories. The Type 9 interpolation algorithm is virtually identical to the Type 8 algorithm; see the discussion of SPK Type 8 for details. However, the Type 9 algorithm executes more slowly than the Type 8 algorithm, since the Type 9 reader must search through tables of time tags to find appropriates states to interpolate, while the Type 8 reader can locate the correct set of states to interpolate by a direct computation. To facilitate the creation of Type 9 segments, a segment writing function called spkw09_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 10: Space Command TwoLine Elements
The SPICE generic segment software handles storage, arrangement, and retrieval of the TLEs. We review only the pertinent points about generic segments here. A generic SPK segment contains several logical data partitions:
+============================+  Constants  +============================+  Packet 1    Packet 2    .   .   .    Packet N  +============================+  Reference Epochs  +============================+  Packet Directory  +============================+  Epoch Directory  +============================+  Reserved Area  +============================+  Segment Meta Data  ++Each ``packet'' of a Type 10 segment contains a set of twoline elements, the nutations in longitude and obliquity of the Earth's pole, and the rates of these nutations. Each packet is arranged as shown below. (The notation below is taken from the description that accompanies the code available from Space Command for the evaluation of twoline elements.)
A single SPK Type 10 segment packet ++ 1  NDT20  ++ 2  NDD60  ++ 3  BSTAR  ++ 4  INCL  ++ 5  NODE0  Twoline element packet ++ 6  ECC  ++ 7  OMEGA  ++ 8  MO  ++ 9  NO  ++ 10  EPOCH  ++ 11  NU.OBLIQUITY  ++ 12  NU.LONGITUDE  ++ 13  dOBLIQUITY/dt  ++ 14  dLONGITUDE/dt  ++The constants partition of the Type 10 segment contains the following eight constants.
++ 1  J2 gravitational harmonic for Earth  ++ 2  J3 gravitational harmonic for Earth  ++ 3  J4 gravitational harmonic for Earth  ++  Square root of the GM for Earth where GM  4  is expressed in Earth radii cubed per   minutes squared  ++ 5  Equatorial radius of the Earth in km  ++ 6  Low altitude bound for atmospheric   model in km  ++ 7  High altitude bound for atmospheric   model in km  ++ 8  Distance units/Earth radius (normally 1)  ++The reference epochs partition contains an ordered collection of epochs. The i'th reference epoch is equal to the epoch in the i'th packet. The ``epoch directory'' contains every 100th reference epoch. The epoch directory is used to efficiently locate an the reference epoch that should be associated with a two line element packet. The ``packet directory'' is empty. Access to the data should be made via the SPK Type 10 readerspkr10_ or via the SPICELIB generic segment functions. Use the function spkw10_c to write a Type 10 generic segment. Type 12: Hermite Interpolation  Equal Time Steps
The SPK system can also represent an ephemeris using unequally spaced discrete states and Hermite interpolation; SPK type 13 does this. SPK type 13 sacrifices some runtime speed and economy of storage in order to achieve greater flexibility. The states in a type 12 segment are geometric: they do not take into account aberration corrections. The six components of each state vector represent the position and velocity (x, y, z, dx/dt, dy/dt, dz/dt, in kilometers and kilometers per second) of the body to which the ephemeris applies, relative to the center specified by the segment's descriptor. The epochs corresponding to the states are barycentric dynamical times (TDB), expressed as seconds past J2000. Each segment also has a polynomial degree associated with it; this is the degree of the interpolating polynomials to be used in evaluating states based on the data in the segment. The identical degree is used for interpolation of each state component. Type 12 SPK segments have the structure shown below:
++  x(1)  / ++ /  y(1)  / ++ /  z(1)  ++ / ++  State 1  < dx(1)/dt ++ \ ++  State 2  \ dy(1)/dt ++ \ ++ . \ dz(1)/dt . ++ . ++  State N  ++  Epoch of state 1 (TDB) ++  Step size  ++  Window size  1  ++  Number of states  ++In the diagram, each box representing a state vector corresponds to six double precision numbers; the other boxes represent individual double precision numbers. Since the epochs of the states are evenly spaced, they are represented by a start epoch and a step size. The number of states must be greater than or equal to the window size, which is related to the polynomial degree as shown:
DEGREE = 2 * WINDOW_SIZE  1The type 12 interpolation method works as follows: given an epoch at which a state is requested and a segment having coverage for that epoch, the type 12 reader finds a window of states whose epochs are "centered" about the epoch. If the window size S is even, then the window will consist of S consecutive states such that the request time is between the epochs of the members of the group having indices, relative to the start of the group, of S/2 and (S/2 + 1), inclusive. When S is odd, the group will contain a central state whose epoch is closest to the request time, and will also contain (S1)/2 neighboring states on either side of the central one. For each of the x, y, and zcoordinates, the type 12 evaluator will fit an Hermite polynomial to the corresponding position and velocity values of the states in the selected window. Each polynomial is evaluated at the request time to yield the interpolated position components. The derivatives of these polynomials are evaluated at the request time to yield the interpolated velocity components. For the jth coordinate, the interpolation algorithm is mathematically equivalent to finding the unique polynomial of degree 2*S1 that interpolates the ordered pairs
( epoch(i), position(j,i) ), i = k , k , ... , k 1 2 Sand whose derivative interpolates the ordered pairs
( epoch(i), velocity(j,i) ), i = k , k , ... , k 1 2 Sand evaluating the polynomial and its derivative at the requested epoch. Here
k , k , ... , k 1 2 Sare the indices of the states in the interpolation window,
epoch(i)is the epoch of the ith state and
position(j,i) velocity(j,i)are, respectively, the jth components of the position and velocity comprising the ith state. There is an exception to the state selection algorithm described above: the request time may be too near the first or last state of the segment to be properly bracketed. In this case, the set of states selected for interpolation still has size S, and includes either the first or last state of the segment. To facilitate the creation of type 12 segments, a segment writing routine called spkw12_c has been provided. This routine takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the subroutine provides a complete description of the input arguments and an example of its usage. Type 13: Hermite Interpolation  Unequal Time Steps
The states in a type 13 segment are geometric: they do not take into account aberration corrections. The six components of each state vector represent the position and velocity (x, y, z, dx/dt, dy/dt, dz/dt, in kilometers and kilometers per second) of the body to which the ephemeris applies, relative to the center specified by the segment's descriptor. The epochs corresponding to the states are barycentric dynamical times (TDB), expressed as seconds past J2000. Each segment also has a polynomial degree associated with it; this is the degree of the interpolating polynomials to be used in evaluating states based on the data in the segment. The identical degree is used for interpolation of each state component. Type 13 SPK segments have the structure shown below:
++  x(1)  / ++ /  y(1)  / ++ /  z(1)  ++ / ++  State 1  < dx(1)/dt ++ \ ++  State 2  \ dy(1)/dt ++ \ ++ . \ dz(1)/dt . ++ . ++  State N  ++  Epoch 1  ++  Epoch 2  ++ . . . ++  Epoch N  ++  Epoch 100  (First directory) ++ . . . ++  Epoch ((N1)/100)*100  (Last directory) ++  Window size  1  ++  Number of states  ++In the diagram, each box representing a state vector corresponds to six double precision numbers; the other boxes represent individual double precision numbers. The number of states must be greater than or equal to the window size, which is related to the polynomial degree as shown:
DEGREE = 2 * WINDOW_SIZE  1The set of time tags is augmented by a series of directory entries; these entries allow the type 13 reader to search for states more efficiently. The directory entries contain time tags whose indices are multiples of 100. The set of indices of time tags stored in the directories ranges from 100 to
( (N1) / 100 ) * 100where N is the total number of time tags. Note that if N is
Q * 100then only
Q  1directory entries are stored, and in particular, if there are only 100 states in the segment, there are no directories. The type 13 interpolation algorithm is virtually identical to the type 12 algorithm; see the discussion of SPK type 12 for details. However, the type 13 algorithm executes more slowly than the type 12 algorithm, since the type 13 reader must search through tables of time tags to find appropriates states to interpolate, while the type 12 reader can locate the correct set of states to interpolate by a direct computation. To facilitate the creation of type 13 segments, a segment writing routine called spkw13_c has been provided. This routine takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the subroutine provides a complete description of the input arguments and an example of its usage. Type 14: Chebyshev Polynomials  Unequal Time Steps
The storage, arrangement and retrieval of packets is handled by the SPICE generic segment software. That software is documented in the document genseg.req. (The document genseg.req is currently in preparation.) We only review the pertinent points about generic segments here. A generic SPK segment contains several logical data partitions:
+============================+  Constants  +============================+  Packet 1    Packet 2    .   .   .    Packet N  +============================+  Reference Epochs  +============================+  Packet Directory  +============================+  Epoch Directory  +============================+  Reserved Area  +============================+  Segment Meta Data  ++Only the placement of the meta data at the end of a generic segment is required. The other data partitions may occur in any order in the generic segment because the meta data will contain pointers to their appropriate locations within the generic segment. In the case of Type 14 SPK segments each ``packet'' contains an epoch, EPOCH, an allowed time offset, OFFSET, from the epoch, and 6 sets of Chebyshev polynomial coefficients which are used to evaluate the x,y,z, dx/dt, dy/dt, and dz/dt components of the state for epochs within OFFSET seconds of the EPOCH. Each packet is organized with the following structure:
  The midpoint of the approximation interval    The radius of the approximation interval    CHBDEG+1 coefficients for the X coordinate    CHBDEG+1 coefficients for the Y coordinate    CHBDEG+1 coefficients for the Z coordinate    CHBDEG+1 coefficients for the X velocity    CHBDEG+1 coefficients for the Y velocity    CHBDEG+1 coefficients for the Z velocity  The maximum degree Chebyshev representation that can currently be accommodated is 18. Packets are stored in increasing order of the midpoint of the approximation interval. The ``constants'' partition contains a single value, the degree of the Chebyshev representation. The reference epochs partition contains an ordered collection of epochs. The i'th reference epoch corresponds to the beginning of the interval for which the i'th packet can be used to determine the state of the object modeled by this segment. The ``epoch directory'' contains every 100th reference epoch. The epoch directory is used to efficiently locate an the reference epoch that should be associated with an epoch for which a state has been requested. The ``packet directory'' is empty. As noted above the exact location of the various partitions must be obtained from the Meta data contained at the end of the segment. Access to the data should be made via the CSPICE generic segment functions. Type 14 segments should be created using the functions spk14b_c, spk14a_c, and spk14e_c. The usage of these functions is discussed in spk14b_c. Type 15: Precessing Conic Propagation
Type 15 SPK segments have the structure shown below:
++  Epoch of Periapsis  ++  Trajectory pole_x  ++  Trajectory pole_y  ++  Trajectory pole_z  ++  Periapsis Unit Vector_x  ++  Periapsis Unit Vector_y  ++  Periapsis Unit Vector_z  ++  SemiLatus Rectum  ++  Eccentricity  ++  J2 Processing Flag  ++  Central Body Pole_x  ++  Central Body Pole_y  ++  Central Body Pole_z  ++  Central Body GM  ++  Central Body J2  ++  Central Body Equatorial Radius  ++It is important to note that the epoch must be that of periapsis passage. Precession of the line of apsides and regression of the line of nodes is computed relative to this epoch. The effects of the J2 term are not applied if the eccentricity is greater than or equal to 1. To facilitate the creation of Type 15 segments, a segment writing function called spkw15_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 17: Equinoctial Elements
Type 17 SPK segments have the structure shown below:
++ 1  Epoch of Periapsis  ++ 2  SemiMajor Axis  ++ 3  H term of equinoctial elements  ++ 4  K term of equinoctial elements  ++ 5  Mean longitude at epoch  ++ 6  P term of equinoctial elements  ++ 7  Q term of equinoctial elements  ++ 8  rate of longitude of periapse  ++ 9  mean longitude rate  ++ 10  longitude of ascending node rate  ++ 11  equatorial pole right ascension  ++ 12  equatorial pole declination  ++To facilitate the creation of Type 17 segments, a segment writing function called spkw17_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 18: ESOC/DDID Hermite/Lagrange Interpolation
Because of the possibility of evolution of the mathematical representations of ephemerides used by ESA, SPK type 18 is designed to accommodate multiple representations, thereby avoiding a proliferation of SPK data types. SPK type 18 refers to each supported mathematical representation of ephemeris data as a ``subtype.'' Currently SPK type 18 supports two subtypes:
When the request time is near a segment boundary, the window is truncated if necessary on the side closest to the boundary. If a segment contains too few packets to form a window of nominal size, as many packets as are needed and available are used to construct the window. In this case the window size may be odd. In any case the window never includes more than WNDSIZ/2 time tags on either side of the request time, where WNDSIZ is the nominal window size. The states in a type 18 segment are geometric: they do not take into account aberration corrections. The position and velocity components of each packet represent the position (x, y, z, in kilometers and kilometers per second) of the body to which the ephemeris applies, relative to the center specified by the segment's descriptor. The epochs corresponding to the states are barycentric dynamical times (TDB), expressed as seconds past J2000. Type 18 SPK segments have the structure shown below:
++  Packet 1  ++  Packet 2  ++ . . . ++  Packet N  ++  Epoch 1  ++  Epoch 2  ++ . . . ++  Epoch N  ++  Epoch 100  (First directory) ++ . . . ++  Epoch ((N1)/100)*100  (Last directory) ++  Subtype code  ++  Window size  ++  Number of packets  ++In the diagram, each box representing a packet corresponds to either twelve or six double precision numbers; the other boxes represent individual double precision numbers. The number of states normally should be greater than or equal to the window size, which is related to the polynomial degree as shown:
Subtype 0: DEGREE = 2 * WINDOW_SIZE  1 Subtype 1: DEGREE = WINDOW_SIZE  1The set of time tags is augmented by a series of directory entries; these entries allow the type 18 reader to search for states more efficiently. The directory entries contain time tags whose indices are multiples of 100. The set of indices of time tags stored in the directories ranges from 100 to
( (N1) / 100 ) * 100where N is the total number of time tags. Note that if N is
Q * 100then only
Q  1directory entries are stored, and in particular, if there are only 100 states in the segment, there are no directories. To facilitate the creation of type 18 segments, a segment writing routine called spkw18_c has been provided. This routine takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the subroutine provides a complete description of the input arguments and an example of its usage. Type 19: ESOC/DDID Piecewise Interpolation
SPK type 19 is an enhanced version of SPK type 18. Type 19 enables creation of SPK files representing the same ephemerides that can be represented using type 18, but containing far fewer segments. Data from multiple type 18 segments can be stored in a single type 19 segment, as long as those segments satisfy certain restrictions:
Each minisegment contains a time ordered, strictly increasing sequence of epochs (no two epochs of the same minisegment may coincide) and an associated sequence of ephemeris data sets called ``packets.'' The composition of a packet depends on the subtype of the minisegment to which the packet belongs; subtypes are discussed in more detail below. The time coverage of a minisegment is called an ``interpolation interval.'' The endpoints (boundaries) of each interpolation interval must be contained in the time interval bounded by the first and last members of the epoch sequence of the corresponding minisegment. If the Ith minisegment's epoch sequence is
E_I1, ..., E_IMand the minisegment's interpolation interval bounds are
IV_IB, IV_IEthen it is required that
E_I1 < IV_IB < IV_IE < E_IM  Minisegments are allowed to contain ``padding'' epochs and packets beyond both ends of their interpolation intervals. Padding epochs on the left of an interpolation interval are less than the interval start time; padding epochs on the right exceed the interval stop time. Padding enables control of interpolation behavior at and near interpolation interval boundaries. Padding does not contribute to a type 19 segment's time coverage. The use of padding is discussed in greater detail below. The interpolation intervals of a type 19 segment have no intervening gaps and overlap only at single points. The end time of each interpolation interval is the start time of the next. The start time of a type 19 segment is greater than or equal to the start time of the first interval, and the segment's end time is less than or equal to the stop time of the last interval. Interpolation intervals must have strictly positive length. When type 19 data are interpolated to produce a state vector for a given request time, only data from a single minisegment whose interpolation interval contains the request time are used. When a request time coincides with the boundary between two interpolation intervals, there is a choice as to which interval will provide ephemeris data. The creator of a type 19 segment can control this behavior via a parameter passed to the type 19 segment writer spkw19_c. For a given type 19 segment, depending on the value of this parameter, either the earlier interval is always selected, or the later interval is always selected. Because of the possibility of evolution of the mathematical representations of ephemerides used by ESA, SPK type 19 is designed to accommodate multiple representations of state data, thereby avoiding a proliferation of SPK data types. SPK type 19 refers to each supported mathematical representation of ephemeris data as a ``subtype.'' Currently SPK type 19 supports three subtypes:
{ 3, 7, 11, ..., MAXDEG }
{ 3, 7, 11, ..., MAXDEG }
Although type 19 interpolation intervals support padding, padding is not required. Below we'll discuss the role of padding, but the reader should keep in mind that the size of the pads at either end of an interpolation interval could be zero. In SPK type 19, interpolation interval padding boundaries (the start time of the padding preceding the interval's coverage and the stop time of the padding following the coverage) affect interpolation in the same way that segment boundaries affect type 18 interpolation. When the request time is near a padding boundary, the window is truncated if necessary on the side closest to the boundary. If an interpolation interval, including padding, contains too few packets to form a window of nominal size, as many packets as are needed and available are used to construct the window. In this case the window size may be odd. In any case the window never includes more than WNDSIZ/2 time tags on either side of the request time, where WNDSIZ is the nominal window size. The minisegments of a type 19 segment need not use the same subtypes and interpolation degrees. The states in a type 19 segment are geometric: they do not take into account aberration corrections. The position and velocity components of each packet represent the position (x, y, z, in kilometers and kilometers per second) of the body to which the ephemeris applies, relative to the center specified by the segment's descriptor. The epochs corresponding to the states are barycentric dynamical times (TDB), expressed as seconds past J2000. Type 19 SPK segments have the structure shown below:
++  Interval 1 minisegment  ++ . . . ++  Interval N minisegment  ++  Interval 1 start time  ++ . . . ++  Interval N start time  ++  Interval N stop time  ++  Interval start 100  (First interval directory) ++ . . . ++  Interval start (N/100)*100  (Last interval directory) ++  Minisegment 1 start pointer  ++ . . . ++  Minisegment N start pointer  ++  Minisegment N stop pointer  ++  Boundary choice flag  ++  Number of intervals  ++Below we first describe the overall segment structure, then we cover the minisegment structure. The array of interval boundaries contains the start time of each interval, plus the stop time of the final interval. The list of interpolation interval boundary times has its own directory, which has the same structure as the time tag directories of type 18 segments. Let the interval count be N. As with time tag directories, the start time directory contains boundary times whose indices are multiples of 100, except that if N+1 is a multiple of 100, the last boundary time is not included. The array of minisegment pointers contains a pointer to the start of each minisegment, plus a final ``stop'' pointer for the final minisegment. The stop pointer points to the location immediately following the last address of the final minisegment. The minisegment pointers are 1based indices relative to the start address of the segment. For example, a pointer value of 1 indicates the first address of the segment. Following the minisegment pointers is the interval selection flag. When this flag has the value 1.D0, the later interpolation interval is used when a request time falls on the common boundary between two interpolation intervals. If the selection flag is 0, the earlier interval is used. Each minisegment has the structure of a type 18 SPK segment. The structure is shown below:
++  Packet 1  ++ . . . ++  Packet M  ++  Epoch 1  ++ . . . ++  Epoch M  ++  Epoch 100  (First time tag directory) ++ . . . ++  Epoch ((M1)/100)*100  (Last time tag directory) ++  Subtype code  ++  Window size  ++  Number of packets  ++In the minisegment diagram, each box representing a packet corresponds to either twelve or six double precision numbers; the other boxes represent individual double precision numbers. The number of packets normally should be greater than or equal to the window size, which is related to the polynomial degree as shown:
Subtype 0: DEGREE = 2 * WINDOW_SIZE  1 Subtype 1: DEGREE = WINDOW_SIZE  1 Subtype 2: DEGREE = 2 * WINDOW_SIZE  1The minisegment's set of time tags is augmented by a series of directory entries; these entries allow the type 19 reader to search for packets more efficiently. The directory entries contain time tags whose indices are multiples of 100. The set of indices of time tags stored in the directories ranges from 100 to
( (M1) / 100 ) * 100where M is the total number of time tags. Note that if M is
Q * 100then only
Q  1directory entries are stored, and in particular, if there are only 100 states in the segment, there are no directories. Following the time tag directory are three parameters associated with the minisegment: the subtype, the interpolation window size, and the packet count. To facilitate the creation of type 19 segments, a segment writing routine called spkw19_c has been provided. This routine takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the subroutine provides a complete description of the input arguments and an example of its usage. Type 20: Chebyshev (velocity only)
This data type is provided to accurately represent ``EPM'' ephemerides developed by the Institute of Applied Astronomy (IAA), Russian Academy of Sciences (RAS). Each type 20 segment contains an arbitrary number of logical records. Each record contains a set of Chebyshev coefficients valid throughout an interval of fixed length. Each record also contains a position vector applicable at the midpoint of its coverage interval. The records within a segment are ordered by increasing initial epoch. All records contain the same number of coefficients. A segment of this type is structured as
++  Record 1  ++  Record 2  ++ . . . ++  Record N  ++  DSCALE  ++  TSCALE  ++  INITJD  ++  INITFR  ++  INTLEN  ++  RSIZE  ++  N  ++A set of seven parameters at the end of the segment provides the information needed to determine the location of the record corresponding to a particular epoch and to determine the units associated with the data:
++  X data  ++  Y data  ++  Z data  ++where each data section for coordinate I contains
++  Chebyshev coefficients for velocity component I  ++  Position component I at interval midpoint  ++The velocity coefficients have units of DSCALE km/TSCALE seconds: multiplying a Chebyshev expansion's value by DSCALE/TSCALE converts velocity to units of km/s. The position at a record's midpoint epoch is given in units of DSCALE km: multiplying the position by DSCALE converts the position to units of km. Type 20 data are used to compute states as follows: for a given time T seconds past J2000 TDB, let MID and RADIUS be the midpoint and radius, expressed as seconds past J2000 TDB, of the record coverage interval that contains T: the coverage interval is the time span
MID  RADIUS : MID + RADIUSThe velocity at T of the body relative to its center of motion is given by the value of the corresponding record's Chebyshev expansions at S, where
S = (T  MID) / RADIUSThe position of the body relative to its center of motion at T is given by
S (Position at MID) + RADIUS*( Integral ( Velocity ) ) 0The function spke20_ contains the algorithm used to construct a state from a particular logical record. To facilitate the creation of Type 20 segments, a segment writing function called spkw20_c has been provided. This function takes as input arguments the handle of an SPK file that is open for writing, the information needed to construct the segment descriptor, and the data to be stored in the segment. The header of the function provides a complete description of the input arguments and an example of its usage. Type 21: Extended Modified Difference Arrays
This data type is normally used for spacecraft whose ephemerides are produced by JPL's principal trajectory integratorDPTRAJ. Difference lines are extracted from spacecraft trajectory files (``Pfiles'' and ``PVfiles'') created by DPTRAJ. Each segment containing Modified Difference Arrays contains an arbitrary number of logical records. Each record contains difference line coefficients applicable over a time interval containing a reference epoch, along with the state at that epoch. The time intervals of adjacent records overlap at their common endpoints. The contents of the records themselves are described in [163]. The function spke21_ contains the algorithm used to construct a state from a particular record and epoch. The records within a segment are ordered by increasing final epoch. The final epochs associated with the records must be distinct. A segment of this type is structured as follows:
++  Record 1 (difference line coefficients)  ++  Record 2 (difference line coefficients)  ++ . . . ++  Record N (difference line coefficients)  ++  Epoch 1  ++  Epoch 2  ++ . . . ++  Epoch N  ++  Epoch 100  (First directory epoch) ++  Epoch 200  (Second directory epoch) ++ . . . ++  Epoch (N/100)*100  (Final directory epoch) ++  Difference line size  ++  N  ++The number of records in a segment, N, can be arbitrarily large. Records 1 through N contain the difference line coefficients and other constants needed to compute state data. Each one of these records contains DLSIZE double precision numbers, where DLSIZE is in the range
71 : (4*MAXTRM) + 1inclusive. MAXTRM is declared in the SPICELIB include file spk21.inc. A list of the final epochs of the records is stored immediately after the last record. Following the list of epochs is a second list, the ``directory,'' containing every 100th epoch from the previous list. If there are N epochs, there will be N/100 directory epochs. If there are fewer than 100 epochs, then the segment will not contain any directory epochs. Directory epochs are used to speed up access to desired records. The penultimate element of the segment is the difference line size. The final element in the segment is the number of records contained in the segment, N. The index of the record providing ephemeris data for a userspecified epoch is the index of the first epoch in the segment's epoch list not less than the specified epoch. Appendix A  Summary of SPkernel FunctionsSummary of Mnemonics
Many of the lowerlevel CSPICE functions have SPICELIB counterparts implemented in Fortran as entry points of another function. The following is a complete list of mnemonics and translations, in alphabetical order.
Implemented CSPICE wrappers: furnsh_c ( Load kernel file ) spk14a_c ( S/Pkernel, add to a Type 14 segment ) spk14b_c ( S/Pkernel, begin a Type 14 segment ) spk14e_c ( S/Pkernel, end a Type 14 segment ) spkacs_c ( S/P Kernel, aberration corrected state ) spkapo_c ( S/PKernel, "apparent" position only ) spkaps_c ( S/Pkernel, apparent state ) spkcls_c ( S/Pkernel, close after write ) spkcov_c ( S/Pkernel, coverage for a body ) spkcpo_c ( SPK, constant position observer state ) spkcpt_c ( SPK, constant position target state ) spkcvo_c ( SPK, constant velocity observer state ) spkcvt_c ( SPK, constant velocity target state ) spkez_c ( S/Pkernel, Easy state ) spkezp_c ( S/P Kernel, easy position ) spkezr_c ( S/Pkernel, Easier state ) spkgeo_c ( S/Pkernel, Geometric state ) spkgps_c ( S/P Kernel, geometric position ) spklef_c ( S/Pkernel, Load ephemeris file ) spkltc_c ( S/P Kernel, light time corrected state ) spkobj_c ( S/P Kernel, bodies in a file ) spkopa_c ( S/Pkernel, open for addition ) spkopn_c ( S/Pkernel, open new file ) spkpds_c ( S/Pkernel, pack descriptor ) spkpos_c ( S/P Kernel, position ) spkpvn_c ( S/P Kernel, position and velocity in native frame ) spksfs_c ( S/P Kernel, Select file and segment ) spkssb_c ( S/Pkernel, Solar system barycenter ) spksub_c ( S/Pkernel, Subset a segment ) spkuds_c ( S/Pkernel, unpack descriptor ) spkuef_c ( S/Pkernel, Unload ephemeris file ) spkw02_c ( S/Pkernel, Write segment, Type 02 ) spkw03_c ( S/Pkernel, Write segment, Type 03 ) spkw05_c ( S/Pkernel, Write segment, Type 05 ) spkw08_c ( S/Pkernel, Write segment, Type 08 ) spkw09_c ( S/Pkernel, Write segment, Type 09 ) spkw10_c ( S/Pkernel, Write segment, Type 10 ) spkw12_c ( S/Pkernel, Write segment, Type 12 ) spkw13_c ( S/Pkernel, Write segment, Type 13 ) spkw15_c ( S/Pkernel, Write segment, Type 15 ) spkw17_c ( S/Pkernel, Write segment, Type 17 ) spkw18_c ( S/Pkernel, Write segment, Type 18 ) spkw20_c ( S/Pkernel, Write segment, Type 20 ) unload_c ( Unload kernel file ) Unimplemented CSPICE wrappers: spkpv_c ( S/Pkernel, Position, velocity ) Lowlevel routines converted via f2c: spke01_ ( S/Pkernel, Evaluate record, Type 01 ) spke02_ ( S/Pkernel, Evaluate record, Type 02 ) spke03_ ( S/Pkernel, Evaluate record, Type 03 ) spke05_ ( S/Pkernel, Evaluate record, Type 05 ) spke08_ ( S/Pkernel, Evaluate record, Type 08 ) spke09_ ( S/Pkernel, Evaluate record, Type 09 ) spke10_ ( S/Pkernel, Evaluate record, Type 10 ) spke12_ ( S/Pkernel, Evaluate record, Type 12 ) spke13_ ( S/Pkernel, Evaluate record, Type 13 ) spke14_ ( S/Pkernel, Evaluate record, Type 14 ) spke15_ ( S/Pkernel, Evaluate record, Type 15 ) spke17_ ( S/Pkernel, Evaluate record, Type 17 ) spke18_ ( S/Pkernel, Evaluate record, Type 18 ) spke19_ ( S/Pkernel, Evaluate record, Type 19 ) spke20_ ( S/Pkernel, Evaluate record, Type 20 ) spke21_ ( S/Pkernel, Evaluate record, Type 21 ) spkr01_ ( S/Pkernel, Read record, Type 01 ) spkr02_ ( S/Pkernel, Read record, Type 02 ) spkr03_ ( S/Pkernel, Read record, Type 03 ) spkr05_ ( S/Pkernel, Read record, Type 05 ) spkr08_ ( S/Pkernel, Read record, Type 08 ) spkr09_ ( S/Pkernel, Read record, Type 09 ) spkr10_ ( S/Pkernel, Read record, Type 10 ) spkr12_ ( S/Pkernel, Read record, Type 12 ) spkr13_ ( S/Pkernel, Read record, Type 13 ) spkr14_ ( S/Pkernel, Read record, Type 14 ) spkr15_ ( S/Pkernel, Read record, Type 15 ) spkr17_ ( S/Pkernel, Read record, Type 17 ) spkr18_ ( S/Pkernel, Read record, Type 18 ) spkr19_ ( S/Pkernel, Read record, Type 19 ) spkr20_ ( S/Pkernel, Read record, Type 20 ) spkr21_ ( S/Pkernel, Read record, Type 21 ) spks01_ ( S/Pkernel, Subset data, Type 01 ) spks02_ ( S/Pkernel, Subset data, Type 02 ) spks03_ ( S/Pkernel, Subset data, Type 03 ) spks05_ ( S/Pkernel, Subset data, Type 05 ) spks08_ ( S/Pkernel, Subset data, Type 08 ) spks09_ ( S/Pkernel, Subset data, Type 09 ) spks10_ ( S/Pkernel, Subset data, Type 10 ) spks12_ ( S/Pkernel, Subset data, Type 12 ) spks13_ ( S/Pkernel, Subset data, Type 13 ) spks14_ ( S/Pkernel, Subset data, Type 14 ) spks15_ ( S/Pkernel, Subset data, Type 15 ) spks17_ ( S/Pkernel, Subset data, Type 17 ) spks18_ ( S/Pkernel, Subset data, Type 18 ) spks19_ ( S/Pkernel, Subset data, Type 19 ) spks20_ ( S/Pkernel, Subset data, Type 20 ) spks21_ ( S/Pkernel, Subset data, Type 21 ) Summary of Calling Sequences
High level routines for loading, unloading files:
furnsh_c ( fname ) unload_c ( fname )Lower level routines for loading, unloading files:
spklef_c ( fname, &handle ) spkuef_c ( handle )Getting coverage summary:
spkobj_c ( <file>, ids ) spkcov_c ( <file>, <idcode>, cover )Computing states and positions:
spkezr_c ( tname, et, ref, aberr, oname, state, < ) spkpos_c ( tname, et, ref, aberr, oname, postn, < ) spkez_c ( target, et, ref, aberr, obs, state, < ) spkezp_c ( target, et, ref, aberr, obs, postn, < ) spkapo_c ( target, et, ref, stobs, aberr, postn, < ) spkpvn_c ( handle, descr, et, &ref, state, ¢er ) spkssb_c ( target, et, ref, state ) spkgeo_c ( target, et, ref, obs, state, < ) spkgps_c ( target, et, ref, obs, postn, < )Lowlevel routines for computing states and positions:
spkacs_c ( targ, et, ref, abcorr, obs, starg, lt, dlt ) spkaps_c ( targ, et, ref, abcorr, stobs, accobs, starg, lt, dlt ) spkltc_c ( targ, et, ref, abcorr, stobs, starg, lt, dlt )Computing states using constantvelocity or constantposition objects:
spkcpo_c ( target, et, outref, refloc, abcorr, obspos, obsctr, obsref, state, lt ) spkcpt_c ( trgpos, trgctr, trgref, et, outref, refloc, abcorr, obsrvr, state, lt ) spkcvo_c ( target, et, outref, refloc, abcorr, obssta, obsepc, obsctr, obsref, state, lt ) spkcvt_c ( trgsta, trgepc, trgctr, trgref, et, outref, refloc, abcorr, obsrvr, state, < )Selecting files, segments:
spksfs_c ( target, et, idlen, &handle, descr, ident, &found )Reading, evaluating records:
spkr01_ ( handle, descr, et, record ) spke01_ ( et, record, state ) spkr02_ ( handle, descr, et, record ) spke02_ ( et, record, state ) spkr03_ ( handle, descr, et, record ) spke03_ ( et, record, state ) spkr05_ ( handle, descr, et, record ) spke05_ ( et, record, state ) spkr08_ ( handle, descr, et, record ) spke08_ ( et, record, state ) spkr09_ ( handle, descr, et, record ) spke09_ ( et, record, state ) spkr10_ ( handle, descr, et, record ) spke10_ ( et, record, state ) spkr12_ ( handle, descr, et, record ) spke12_ ( et, record, state ) spkr13_ ( handle, descr, et, record ) spke13_ ( et, record, state ) spkr14_ ( handle, descr, et, record ) spke14_ ( et, record, state ) spkr15_ ( handle, descr, et, record ) spke15_ ( et, record, state ) spkr17_ ( handle, descr, et, record ) spke17_ ( et, record, state ) spkr18_ ( handle, descr, et, record ) spke18_ ( et, record, state ) spkr19_ ( handle, descr, et, record ) spke19_ ( et, record, state ) spkr20_ ( handle, descr, et, record ) spke20_ ( et, record, state ) spkr21_ ( handle, descr, et, record ) spke21_ ( et, record, state )Writing segments to files:
spkpds_c ( body, center, frame, type, first, last, descr ) spkw02_c ( handle, body, center, frame, first, last, segid, intlen, n, polydg, cdata, btime ) spkw03_c ( handle, body, center, frame, first, last, segid, intlen, n, polydg, cdata, btime ) spkw05_c ( handle, body, center, frame, first, last, segid, gm, n, states, epochs ) spkw08_c ( handle, body, center, frame, first, last, segid, degree, n, states, epoch1, step ) spkw09_c ( handle, body, center, frame, first, last, segid, degree, n, states, epochs ) spkw10_c ( handle, body, center, frame, first, last, segid, consts, n, elems, epochs ) spkw12_c ( handle, body, center, frame, first, last, segid, degree, n, states, epoch0, step ) spkw13_c ( handle, body, center, frame, first, last, segid, degree, n, states, epochs ) spk14b_c ( handle, segid, body, center, frame, first, last, chbdeg ) spk14a_c ( handle, ncsets, coeffs, epochs ) spk14e_c ( handle ) spkw15_c ( handle, body, center, frame, first, last, segid, epoch, tpole, peri, p, ecc, j2flg, cpole, gm, j2, radius ) spkw17_c ( handle, body, center, frame, first, last, segid, epoch, eqel, rapol, decpol ) spkw18_c ( handle, subtyp, body, center, frame, first, last, segid, degree, n, packts, epochs ) spkw20_c ( handle, body, center, frame, first, last, segid, intlen, n, polydg, cdata, dscale, tscale, initjd, initfr )Examining segment descriptors:
spkuds_c ( descr, &body, ¢er, frame, &type, &first, &last, &begin, &end )Extracting subsets of data from a segment:
spks01_ ( handle, baddr, eaddr, begin, end ) spks02_ ( handle, baddr, eaddr, begin, end ) spks03_ ( handle, baddr, eaddr, begin, end ) spks05_ ( handle, baddr, eaddr, begin, end ) spks08_ ( handle, baddr, eaddr, begin, end ) spks09_ ( handle, baddr, eaddr, begin, end ) spks10_ ( handle, baddr, eaddr, begin, end ) spks12_ ( handle, baddr, eaddr, begin, end ) spks13_ ( handle, baddr, eaddr, begin, end ) spks14_ ( handle, baddr, eaddr, begin, end ) spks15_ ( handle, baddr, eaddr, begin, end ) spks17_ ( handle, baddr, eaddr, begin, end ) spks18_ ( handle, baddr, eaddr, begin, end ) spks19_ ( handle, baddr, eaddr, begin, end ) spks20_ ( handle, baddr, eaddr, begin, end ) spks21_ ( handle, baddr, eaddr, begin, end ) spksub_c ( handle, descr, ident, begin, end, newh )To write new or append segments to SPK files:
spkopn_c ( name, ifname, ncomch, handle ) spkopa_c ( file, handle ) spkcls_c ( handle ) Appendix B  A Template for SPK Comments
If you create SPK files NAIF strongly recommends that you include descriptive documentation in the comments portion of the SPK file. You can use the utility program COMMNT to insert comments into the file, or you may use the functions in the SPC family to insert the comments when you create the SPK file. (See commnt.ug or spc.req for further details.) This appendix addresses the contents of your comments. What will others (or yourself) want to know about the SPK file weeks, months or years after it has been created? Providing this information can be a challenge. It's difficult to know in advance all the questions someone might ask about an ephemeris you've created. To assist with this task NAIF has devised a ``template'' that you may wish to use as a starting point when creating the comments for an SPK file. Constraints
The Basic Template
Objects in the Ephemeris
Approximate Time Coverage
Status
Pedigree
Usage
Accuracy
Special Notes
References
Contacts
Appendix CRevision HistoryMarch 29, 2017
July 14, 2014
The light time computation section was updated. The discussion of frame classes was updated to include a description of dynamic frames. C wrappers for SPKSFS and SPKPVN are now mentioned. Added mention of SXFORM and STLABX. Removed discussion of C wrapper for SPKPV. April 15, 2009
Added a note about the SPICE file identification word for SPK files. February 28, 2008
Deleted entire subsection on lowlevel readers. An entry for type 18 was added to the list of supported data types. (The description of type 18 was already present.) The discussion of SPK file structure now states that segments need not be listed in increasing time order. November 17, 2005
Calls/references to the deprecated routine bodvar_c were replaced with calls/references to bodvcd_c. bodvrd_c is mentioned as another routine superseding bodvar_c. C examples showing incorrect calling sequences for prompt_c were corrected. December 22, 2004
February 2, 2004
Performed a spellcheck on text. Edited description of type 10 segments. September 04, 2002
Added a brief discussion of the DAF runtime binary file format translation capability now present in the SPICE Toolkit. July 21, 2001
March 1, 2000
October 14, 1999
The SPICE system has been extended to include CSPICEa version of the SPICE Toolkit software coded in the ANSI C programming language. To better accommodate CSPICE users, NAIF translated the Fortran SPK Required Reading document into this "CSPICE edition." This document closely parallels the current Fortran edition but contains C versions of illustrations of source code, including listings of calling sequences and example programs. The CSPICE librarythe C counterpart of SPICELIBconsists of two categories of functions:
_cFunctions created by f2c have names ending with the suffix
_In this first version of CSPICE, wrappers are provided for the principal SPK application interface functions. Handcoded versions of other, less frequently used interface functions will be supplied in a later version of CSPICE. The remaining, lowerlevel functions will not be provided with wrappers. The set of currently available CSPICE SPK wrapper functions:
spk14a_c spk14b_c spk14e_c spkapo_c spkapp_c spkcls_c spkez_c spkezp_c spkezr_c spkgeo_c spkgps_c spklef_c spkopa_c spkopn_c spkpds_c spkpos_c spkssb_c spksub_c spkuds_c spkuef_c spkw02_c spkw03_c spkw05_c spkw08_c spkw09_c spkw10_c spkw12_c spkw13_c spkw15_c spkw17_cLess frequently used application interfacelevel functions referenced here but for which wrappers are not yet implemented are:
frmchg_c spkpv_c Portions of the DAF family of functions The SPC family of functionsWhen the SPK system was introduced, states of objects (positions and velocities) were stored relative to inertial frames and retrieved relative to inertial frames. Beginning with version 41 of the SPICE Toolkit, states can be stored relative to both inertial and noninertial frames. Moreover, states may be retrieved relative to both inertial and noninertial frames. Noninertial frames may be tied to the rotation of a planet, the orientation of some structure on a spacecraft, an Earth based telescope, etc. By expanding the SPK system in this way, computation that previously required dozens lines of code may now be reduced to three or four lines of code. This version of the ``SPK Required Reading'' documents for the first time this important expansion of the SPK system. Also in this version, we document:
