Last revised on 2004 DEC 29 by B. V. Semenov.
This document describes generic SPICE routines for loading and
unloading text and binary SPICE kernels. It also describes the
SPICELIB ``kernel pool'' system, which provides a robust, flexible way
to load data into memory in a SPICE based program, either from SPICE
text kernel files or via a subroutine interface.
For the SPICE system to use kernel files, the files must be made known
to the system and opened at run time. This activity is called
``loading'' kernels. SPICELIB provides a simple subroutine interface
for this purpose. The principal kernel loading subroutine is called
FURNSH (pronounced ``furnish''). The kernel system also provides a
small set of routines that enable an application to find the names and
attributes of kernels that have been loaded via FURNSH. These routines
are all entry points of the subroutine KEEPER.
In earlier versions of SPICELIB, kernels were loaded via routines specific to various SPICELIB subsystems: SPK, CK, PCK, EK, kernel pool. The binary kernel systems also supported unloading kernels. All of the old loaders and unloaders are still provided in SPICELIB, but these routines should no longer be called directly. FURNSH should be called instead.
NAIF now recommends that instead of calling various kernel loaders, applications load kernels using a ``metakernel.'' A metakernel is a SPICE text kernel that lists the names of the kernels to be loaded. At run time, the application supplies the name of the metakernel as an input argument to FURNSH. For example, instead of loading kernels using the code fragment
CALL LDPOOL ( 'leapseconds.ker' ) CALL LDPOOL ( 'mgs.tsc' ) CALL SPKLEF ( 'generic.bsp', HANDLE1 ) CALL CKLPF ( 'mgs.bc', HANDLE2 ) CALL PCKLOF ( 'earth.bpc', HANDLE3 ) CALL EKLEF ( 'mgs.bes', HANDLE4 )one now may write
CALL FURNSH ( 'kernels.txt' )where the file kernels.txt is a SPICE text kernel containing the lines
\begindata KERNELS_TO_LOAD = ( 'leapseconds.ker', 'mgs.tsc', 'generic.bsp', 'mgs.bc', 'earth.bpc', 'mgs.bes' )This technique has the advantage of enabling a user to change the set of kernels loaded by the application without modifying source code.
It also possible to use FURNSH to load kernels in the older SPICELIB style: the names of kernels to load can be supplied as input arguments to FURNSH. For example, instead of using the series of loader calls shown earlier, one now may write
INTEGER FILEN PARAMETER ( FILEN = 255 ) INTEGER NKER PARAMETER ( NKER = 6 ) INTEGER I CHARACTER*FILEN KERNLS ( NKER ) DATA KERNLS / 'leapseconds.ker', . 'mgs.tsc', . 'generic.bsp', . 'mgs.bc', . 'earth.bpc', . 'mgs.bes' / DO I = 1, NKER CALL FURNSH ( KERNLS(I) ) END DO
The older SPICELIB loaders allow users to prioritize kernel files via
load order: kernels loaded later have higher priority than kernels
loaded earlier. FURNSH follows the same convention. When kernels are
listed in a metakernel, those appearing later in the list have higher
priority. The old prioritization scheme also applies to kernels
supplied directly as arguments to FURNSH.
Inside a metakernel, it is sometimes necessary to qualify file names
with their pathnames. To reduce both typing and the need to continue
file names over multiple lines, metakernels allow users to define
symbols for paths. This is done using the kernel variables
PATH_VALUES PATH_SYMBOLSTo create symbols for path names, one assigns an array of path names to the variable PATH_VALUES. Next, one assigns an array of corresponding symbol names to the variable PATH_SYMBOLS. The nth symbol in the second array represents the nth path name in the first.
Finally, one prefixes with path symbols the kernel names specified in the KERNELS_TO_LOAD variable. Each symbol is prefixed with a dollar sign to indicate that it is in fact a symbol.
Suppose in our example above that the MGS kernels reside in the path
/flight_projects/mgs/SPICE_kernelsand the other kernels reside in the path
/generic/SPICE_kernelsThen we can add paths to our metakernel as follows:
\begindata PATH_VALUES = ( '/flight_projects/mgs/SPICE_kernels', '/generic/SPICE_kernels' ) PATH_SYMBOLS = ( 'MGS', 'GEN' ) KERNELS_TO_LOAD = ( '$GEN/leapseconds.ker', '$MGS/mgs.tsc', '$GEN/generic.bsp', '$MGS/mgs.bc', '$GEN/earth.bpc', '$MGS/mgs.bes' )It is not required that paths be abbreviated using path symbols; it's simply a convenience.
Note the symbols defined here are not related to the symbols supported by a host shell or any other operating system interface.
FURNSH maintains a record of the load operations it has performed
during a program run. This record is implemented using data structures
of fixed size, so there is a limit on the number of the maximum number
of loaded kernels FURNSH can accommodate.
When a loaded kernel is loaded via FURNSH, a new entry is created in the record of loaded kernels, whether or not the kernel is already loaded.
All load or unload (see the discussion of UNLOAD below) operations affect the list of loaded files and therefore affect the results returned by the routines KTOTAL, KDATA, and KINFO, all of which are discussed below under ``Finding Out What's Loaded.''
Reloading an already loaded kernel decreases the available space in
FURNSH's list of loaded files. FURNSH's treatment of reloaded files is
thus slightly different from that performed by the SPICE low-level
kernel loaders such as SPKLEF, which handle a reload operation by
first unloading the kernel in question, then loading it.
The recommended method of increasing the priority of a loaded binary kernel, or of a metakernel containing binary kernels, is to unload it using UNLOAD (see below), then reload it using FURNSH. This technique helps reduce clutter in FURNSH's kernel list.
FURNSH can currently keep track of up to 1300 kernels. The list of
loaded kernels may contain multiple entries for a given physical file,
so the number of maximum number of distinct loaded files may be
smaller if some files have been reloaded. Unloading kernels via UNLOAD
frees room in the file list, so there is no limit on the total number
of load or unload operations performed in a program run.
The DAF/DAS handle manager system imposes its own lower limit on the number of DAF and DAS files that may be loaded simultaneously. This limit is currently set to a total of 1000 DAF and DAS files.
SPICELIB-based applications may need to determine at run time which
files have been loaded. Applications may need to find the DAF or DAS
handles of loaded binary kernels so that the kernels may be searched.
Some applications may need to unload kernels to make room for others,
or change the priority of loaded kernels at run time.
SPICELIB provides kernel access routines to support these needs. For every loaded kernel, an application can find the name of kernel, the kernel type (text or one of SPK, CK, PCK, or EK), the kernel's DAF or DAS handle if applicable, and the name of the metakernel used to load the kernel, again if applicable.
The routine KTOTAL returns the count of loaded kernels of a given type. The routine KDATA returns information on the nth kernel of a given type. The two routines are normally used together. Following is an example of how an application could retrieve summary information on the currently loaded SPK files:
CALL KTOTAL ( 'SPK', COUNT ) IF ( COUNT .EQ. 0 ) THEN WRITE (*,*) 'There are no SPK files loaded at this time.' ELSE WRITE (*,*) 'The loaded SPK files are: ' WRITE (*,*) END IF DO WHICH = 1, COUNT CALL KDATA( WHICH, 'SPK', FILE, FILTYP, . HANDLE, SOURCE, FOUND ) WRITE (*,*) FILE END DOAbove, the input argument 'SPK' is a kernel type specifier. The allowed set of values is
SPK --- All SPK files are counted in the total. CK --- All CK files are counted in the total. PCK --- All binary PCK files are counted in the total. EK --- All EK files are counted in the total. TEXT --- All text kernels that are not meta-text kernels are included in the total. META --- All meta-text kernels are counted in the total. ALL --- Every type of kernel is counted in the total.In this example, FILTYP is a string indicating the type of kernel. HANDLE is the file handle if the file is a binary SPICE kernel. SOURCE is the name of the metakernel used to load the file, if applicable. FOUND indicates whether a file having the specified type and index was found.
SPICELIB also contains the routine KINFO which returns summary information about a file whose name is already known. KINFO is called as follows:
CALL KINFO ( FILE, FILTYP, SOURCE, HANDLE, FOUND )
SPICELIB-based applications may need to remove loaded kernels.
Possible reasons for this are:
Text kernels and metakernels may be unloaded as well. Unloading a metakernel involves unloading the files referenced by the metakernel. Text kernels are unloaded by clearing the kernel pool and then reloading the other text kernels not designated for removal.
Note that unloading text kernels has the side effect of wiping out kernel variables that have been set via the kernel pool's subroutine write access interface. It is important to consider whether this side effect is acceptable when writing code that may unload text kernels or metakernels.
UNLOAD is called as follows:
CALL UNLOAD ( KERNEL )
SPICE data loading mechanism detects and prohibits loading text kernel
files containing lines terminated with EOF character(s) non-native to
the platform on which the Toolkit was compiled. If a non-native EOL
terminator is detected in the first 132 characters of a text kernel,
the execution is stopped and an error message is displayed. This
feature does not work with files that are smaller that 132 bytes or
have the first line longer that 132 characters.
Starting with the N0052 release of the SPICE Toolkit (January, 2002) certain supported platforms are able to read DAF-based binary files (SPK, CK and binary PCK) that were written using a different, or non-native, binary representation. This access is read-only; any operations requiring writing to the file (adding information to the comment area, or appending additional ephemeris data, for example) require prior conversion of the file to the native binary file format. See the Convert User's Guide for details.
A variety of SPICE text kernels that are read into and accessed
through the kernel pool. These include:
The kernel pool system interface is composed of two parts: a text file format and kernel pool access software. The software includes routines that read files conforming to the format, routines that allow direct insertion of data into the pool via subroutine calls, routines that fetch data from the kernel pool, routines that return information about the current state of the pool, and utilities that manipulate various aspects of the pool.
The SPICE text kernel format has a ``name = value'' structure similar to the format used to assign values to variables in languages such as C and FORTRAN. Details of the format are described below.
The kernel pool may be viewed abstractly as a repository of associative arrays which map names to lists of numeric or string values. The kernel pool allows SPICELIB-based programs to read data from SPICE text kernel files while maintaining the ``name = value'' associations established in the files. Alternatively, associative arrays may be inserted into the kernel pool via the pool's programming interface.
Once name-value associations have been stored in the kernel pool, you may access the stored data through kernel pool look-up routines. These look-up routines use the names as keys to find the associated values. The look-up and other access routines are described in detail below.
As the name implies, SPICE text kernel files contain only ASCII text.
An additional restriction on the contents of SPICE text kernel files
is that they contain no non-printing characters, such as tabs or
formfeeds.
We illustrate this format by way of example using an excerpt from a SPICE text planetary constants kernel (PCK) file. The format description given below applies to all SPICE text kernels; the specific data names shown below apply only to text PCK files.
Planets first. Each has quadratic expressions for the direction (RA, Dec) of the north pole and the rotation of the prime meridian. Planets with satellites (except Pluto) also have linear expressions for the auxiliary (phase) angles used in the nutation and libration expressions of their satellites. \begindata BODY399_POLE_RA = ( 0. -0.64061614 -0.00008386 ) BODY399_POLE_DEC = ( +90. -0.55675303 +0.00011851 ) BODY399_PM = ( 10.21 +360.98562970 +0. ) BODY399_LONG_AXIS = ( 0. ) BODY3_NUT_PREC_ANGLES = ( 125.045 -1935.53 249.390 -3871.06 196.694 -475263. 176.630 +487269.65 358.219 -36000. ) \begintext Each satellite has similar quadratic expressions for the pole and prime meridian. In addition, some satellites have nonzero nutation and libration amplitudes. (The number of amplitudes matches the number of auxiliary phase angles of the primary.) \begindata BODY301_POLE_RA = ( 270.000 -0.64061614 -0.00008386 ) BODY301_POLE_DEC = ( +66.534 -0.55675303 +0.00011851 ) BODY301_PM = ( 38.314 +13.1763581 0. ) BODY301_LONG_AXIS = ( 0. ) BODY301_NUT_PREC_RA = ( -3.878 -0.120 +0.070 -0.017 0. ) BODY301_NUT_PREC_DEC = ( +1.543 +0.024 -0.028 +0.007 0. ) BODY301_NUT_PREC_PM = ( +3.558 +0.121 -0.064 +0.016 +0.025 ) \begintext Finally, we include the radii of the satellites and planets. \begindata BODY399_RADII = ( 6378.140 6378.140 6356.755 ) BODY301_RADII = ( 1738. 1738. 1738. )In this example are several comment blocks. All are introduce by the control word:
\begintextA comment block may contain any number of comment lines. Once a comment block has begun, no special characters are required to introduce subsequent lines of comments within that block. A comment block is terminated by the control word
\begindataThis control word also serves to introduce a block of data that will be stored in the kernel pool. Each of these control words must appear on a line by itself.
Each variable definition consists of three components:
BODY301_NUT_PREC_RA = -3.878 BODY301_NUT_PREC_RA += -0.120 BODY301_NUT_PREC_RA += +0.070 BODY301_NUT_PREC_RA += -0.017 BODY301_NUT_PREC_RA += 0.has the same effect as the single assignment
BODY301_NUT_PREC_RA = ( -3.878 -0.120 +0.070 -0.017 0 )Dates, e.g.,
FOOBAR_CALIBRATION_DATES = ( @31-JAN-1987, @2/4/87, @March-7-1987-3:10:39.221 )may be entered in a wide variety of formats. There are two restrictions regarding the format of dates. They may not contain embedded blanks, and they must begin with the character
@Internally, dates are converted to TDB seconds past J2000 as they are read. As a result, dates, are treated as numeric data in the pool.
Strings may be supplied by quoting the string value.
MISSION_UNITS = ( 'KILOMETERS', 'SECONDS', 'KILOMETERS/SECOND' )If you need to include a quote in the string value, use the FORTRAN convention of "doubling" the quote.
MESSAGE = ( 'You can''t always get what you want.' )The maximum length of as string that can be assigned as the value of a scalar kernel variable, or as an element of an array-valued kernel variable, is 80 characters.
The types of values assigned to a kernel pool variable must all be the same. If you attempt to make an assignment such as the one shown here:
ERROR_EXAMPLE = ( 1, 2, 'THREE', 4, 'FIVE' )The kernel pool reader will regard the assignment as erroneous and reject it and any subsequent kernel pool assignments that appear in the text kernel.
It is possible to treat specified, consecutive components of a string
array as a single ``continued'' string. String continuation is
indicated by placing a user-specified sequence of non-blank characters
at the end (excluding trailing blanks) of each string value that is to
be concatenated to its successor. For example, if the character
sequence
//is used as a continuation mark, the assignment
CONTINUED_STRINGS = ( 'This // ', 'is // ', 'just //', 'one long //', 'string.', 'Here''s a second //', 'continued //' 'string.' )allows the string array elements on the right hand side of the assignment to be treated as the two strings
This is just one long string. Here's a second continued string.The SPICELIB routine STPOOL provides the capability of retrieving continued strings from the kernel pool. See the discussion below under ``Fetching Data from the Kernel Pool'' or the header of STPOOL for further information.
The values of variables stored in the kernel pool may be retrieved
using the subroutines:
CALL GCPOOL(NAME, FIRST, ROOM, NVALUES, VALUES, FOUND) CALL GDPOOL(NAME, FIRST, ROOM, NVALUES, VALUES, FOUND) CALL GIPOOL(NAME, FIRST, ROOM, NVALUES, VALUES, FOUND) CALL STPOOL(NAME, NTH, CONTIN, STRING, SIZE, FOUND)The meanings of the arguments are as follows:
Four routines are provided for retrieving general information about
the contents of the kernel pool.
The main way in which you change the contents of the kernel pool is by
``loading'' a SPICE text kernel with the routine FURNSH. However, the
kernel pool also provides a several other routines that allow you to
change the contents of the pool.
Below, BUFFER is a character array and N is the size of the array.
INTEGER LNSIZE PARAMETER ( LNSIZE = 80 ) CHARACTER*(LNSIZE) TEXT ( 27 ) TEXT( 1) = 'DELTET/DELTA_T_A = 32.184' TEXT( 2) = 'DELTET/K = 1.657D-3' TEXT( 3) = 'DELTET/EB = 1.671D-2' TEXT( 4) = 'DELTET/M = (6.239996D0 1.99096871D-7)' TEXT( 5) = 'DELTET/DELTA_AT = ( 10, @1972-JAN-1' TEXT( 6) = ' 11, @1972-JUL-1' TEXT( 7) = ' 12, @1973-JAN-1' TEXT( 8) = ' 13, @1974-JAN-1' TEXT( 9) = ' 14, @1975-JAN-1' TEXT(10) = ' 15, @1976-JAN-1' TEXT(11) = ' 16, @1977-JAN-1' TEXT(12) = ' 17, @1978-JAN-1' TEXT(13) = ' 18, @1979-JAN-1' TEXT(14) = ' 19, @1980-JAN-1' TEXT(15) = ' 20, @1981-JUL-1' TEXT(16) = ' 21, @1982-JUL-1' TEXT(17) = ' 22, @1983-JUL-1' TEXT(18) = ' 23, @1985-JUL-1' TEXT(19) = ' 24, @1988-JAN-1' TEXT(20) = ' 25, @1990-JAN-1' TEXT(21) = ' 26, @1991-JAN-1' TEXT(22) = ' 27, @1992-JUL-1' TEXT(23) = ' 28, @1993-JUL-1' TEXT(24) = ' 29, @1994-JUL-1' TEXT(25) = ' 30, @1996-JAN-1' TEXT(26) = ' 31, @1997-JUL-1' TEXT(27) = ' 32, @1999-JAN-1)' CALL LMPOOL ( TEXT, 27 )
Since loading SPICE text kernels tends to happen only at program
initialization, a routine that relies on data in the kernel pool may
run more efficiently if it can store a local copy of the values needed
and update these only when a change occurs in the kernel pool. Two
routines are available that allow a quick test to see whether kernel
pool variables have been updated.
If you need to capture a persistent copy of the contents of the kernel
pool. Use the routine WRPOOL.
The PCK kernel is SPICELIB's source of the planetary constants needed
to define the size, shape, and orientation of planets and satellites.
The PCK text file format and routines which access PCK data are
described in the PCK Required Reading.
Routines that retrieve leapseconds or SCLK data directly from the
kernel pool are documented in the TIME and SCLK Required reading
files, respectively.
See the FRAMES Required Reading for a discussion of frame definition
kernels.
Each kernel pool subroutine name consists of a mnemonic which
translates into a short description of the routine's purpose.
Many of the routines listed below are entry points to another subroutine. If they are, the parent routine's name will be listed inside brackets preceding the mnemonic translation.
BODFND ( Find values from the kernel pool ) BODVAR ( Return values from the kernel pool ) CLPOOL [POOL] ( Clear the pool of kernel variables ) CVPOOL [POOL] ( Check variable in the pool for update ) DTPOOL [POOL] ( Data for a kernel pool variable ) DVPOOL [POOL] ( Delete a variable from the kernel pool ) EXPOOL [POOL] ( Confirm the existence of a pool kernel variable ) FURNSH [KEEPER]( Furnish a program with SPICE kernels ) GCPOOL [POOL] ( Get character data from the kernel pool ) GDPOOL [POOL] ( Get d.p. values from the kernel pool ) GIPOOL [POOL] ( Get integers from the kernel pool ) GNPOOL [POOL] ( Get names of kernel pool variables ) KDATA [KEEPER]( Kernel Data ) KINFO [KEEPER]( Kernel Information ) KTOTAL [KEEPER]( Kernel Totals ) LDPOOL [POOL] ( Load variables from a kernel file into the pool ) LMPOOL [POOL] ( Load variables from memory into the pool ) PCPOOL [POOL] ( Put character strings into the kernel pool ) PDPOOL [POOL] ( Put d.p.'s into the kernel pool ) PIPOOL [POOL] ( Put integers into the kernel pool ) STPOOL [POOL] ( String from pool ) SWPOOL [POOL] ( Set watch on a pool variable ) SZPOOL [POOL] ( Get size limitations of the kernel pool) UNLOAD [KEEPER]( Unload a kernel )
BODFND ( BODY, ITEM ) BODVAR ( BODY, ITEM, DIM, VALUES ) CLPOOL () CVPOOL ( AGENT, UPDATE ) DTPOOL ( NAME, FOUND, N, TYPE ) DVPOOL ( NAME ) EXPOOL ( NAME, FOUND ) FURNSH ( FILE ) GCPOOL ( NAME, START, ROOM, N, CVALS, FOUND ) GDPOOL ( NAME, START, ROOM, N, DVALS, FOUND ) GIPOOL ( NAME, START, ROOM, N, IVALS, FOUND ) GNPOOL ( NAME, START, ROOM, N, KVARS, FOUND ) KDATA ( WHICH, KIND, FILTYP, SOURCE, HANDLE, FOUND ) KINFO ( FILE, FILTYP, SOURCE, HANDLE, FOUND ) KTOTAL ( KIND, COUNT ) LDPOOL ( NAME ) LMPOOL ( CVALS, N ) PCPOOL ( NAME, N, CVALS ) PDPOOL ( NAME, N, DVALS ) PIPOOL ( NAME, N, IVALS ) STPOOL ( ITEM, NTH, CONTIN, STRING, SIZE, FOUND ) SWPOOL ( AGENT, NNAMES, NAMES ) SZPOOL ( NAME, N, FOUND ) UNLOAD ( FILE )
Section providing information regarding detection of non-native
end-of-line terminators in text kernels at loading time and run-time
binary data translation for binary kernels was added to the document.
Erroneous meta-kernel keyword
PATH_NAMESwas changed to
PATH_VALUES
Discussion of string continuation and the routine STPOOL has been
added. Additional details on the behavior of UNLOAD have been added.
This document differs from the previous version of March 25, 1992 in
that it documents new features added to the kernel pool routines. The
principal ones are:
In addition some minor edits were performed to improve clarity.
Also, the quoting style was changed from British to American.