SPK2OEM is one of many of SPICE tools available here:


I am trying to extract ephemeris from one of the SPK files listed here:


So I also downloaded a leap seconds file (LSK) from here as requested, and created an input file as requested, adapting an example for MRO taken from documentation:

     OBJECT_NAME          = 'MRO'
     INPUT_SPK_FILE       = 'spk_psp_rec0605_0601_1388_p-v1.bsp'
     OUTPUT_OEM_FILE      = 'spk_psp_rec0605_0601_1388_p-v1.oem'
     LEAPSECONDS_FILE     = '/kernels/gen/lsk/leapseconds.ker'

     STRING_MAPPING       = ( 'J2000',        'EME2000',
                              '<object_id>',  '074'        )

But I keep getting several different errors rgardless of how I change&tune my input parameters.

So I tried the above setup file with an MRO SPK/LSK couple; I didn't get any error... but the output file contains only comments, no ephemeris data!

Can anybody help figuring out how to get human readable ephemeris for this SPK file, for dates 2020-10-20 to 2020-10-21 ? I'd need (x,y,z) coordinates of Osiris Rex spacecraft with respect to a given point on the surface of Bennu asteroid.


Does it exist any other CLI tool than SPK2OEM?

Please note that SPK2OEM is just the best I was able to find, it's not the mandatory solution; my preferred solution would be a javascript library allowing me to extract/calculate such data from the SPICE kernel. Python is not an option as I should learn it quite from scratch, unlike javascript.

I found this javascript library which looks very promising:


Potentially it could be extended to implement spkezr_c function, which does extacly what I need.

From documentation:

   void spkezr_c ( ConstSpiceChar     *targ,
                   SpiceDouble         et,
                   ConstSpiceChar     *ref,
                   ConstSpiceChar     *abcorr,
                   ConstSpiceChar     *obs,
                   SpiceDouble         starg[6],
                   SpiceDouble        *lt        )
   Return the state (position and velocity) of a target body 
   relative to an observing body, optionally corrected for light 
   time (planetary aberration) and stellar aberration. 

But I have no idea about how to convert such function into javascript.

  • $\begingroup$ Not had a chance to look into SPICE much (ever growing todo list) but one thing to check is whether the time span you want the ephemeris for is covered between the start and stop times of all the linked SPICE kernels. Also is the HORIZONS system not able to give you want you want ? It has OSIRIS-REx (and other spacecraft) and can generate an ephemeris of nearly 50 quantities with time, relative to any pretty much any origin $\endgroup$ Oct 22, 2020 at 16:34
  • $\begingroup$ for some reasons NASA Horizons did not provide the trajectory for Osiris Rex TAG operation, nor before neither after the TAG, but I've found a page which shows such trajectory by calculating/extracting it directly from latest SPICE kernel available. It showed it in realtime during the TAG operation. cristianopi.altervista.org/as/sonde_orx/a_temporea.html , cristianopi.altervista.org/as/sonde_orx/19_sampcol.html $\endgroup$
    – jumpjack
    Oct 27, 2020 at 8:34
  • $\begingroup$ I found this timecraftjs library: github.com/NASA-AMMOS/timecraftjs . Its readme says "spice.js - This file contains the wrapper functions that allow access to the functionality in cspice.js and also adds some additional features. The version of spice.js here is entirely focused on time conversions, but the rest of the CSPICE functionality could be exposed if needed. If running in Node, import timecraft.js, not this file." So probably I should add this function: naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkezr_c.html But how? $\endgroup$
    – jumpjack
    Oct 27, 2020 at 8:46
  • $\begingroup$ There are a variety of wrappers that implement more or less of the SPICE infrastructure (since SPICE is very general); SpicePy is another one that's probably more suited for general investigations. Since SPICE is so general, can you edit your question and give more details about what quantities you want in the ephemeris and for what later purpose and we can see if spk2oem is the best fit ? $\endgroup$ Oct 27, 2020 at 17:56
  • $\begingroup$ added details to the question about what I need ( (x,y,z) coordinates) and how I am trying to get them. $\endgroup$
    – jumpjack
    Oct 28, 2020 at 8:05

2 Answers 2


So I am using the following layout for my SPICE kernels (not essential but matches tutorial recommendations, adjust paths in the spm2oek input file as needed)

├── bin
│   └── spk2oem
├── kernels
│   ├── naif0012.tls
│   ├── ORX
│   │   └── spk
│   │       └── orx_201020_201110_201021_od293-N_v1.bsp
├── osiris_rex.input
├── osiris_rex.oem

I constructed an input file (osiris_rex.input) for spm2oek following the Users Guide which looks like:

      VERSION_NUMBER       = '1.0'
      ORIGINATOR           = 'astrosnapper'
      TIME_ZONE            = 'PDT'
      OBJECT_NAME          = 'ORX'
      INPUT_SPK_FILE       = 'kernels/ORX/spk/orx_201020_201110_201021_od293-N_v1.bsp'
      OUTPUT_OEM_FILE      = 'osiris_rex.oem'
      LEAPSECONDS_FILE     = 'kernels/naif0012.tls'
      START_TIME           = '2020-10-20T00:00:00'
      STOP_TIME            = '2020-10-21T00:00:00'
      TIME_FORMAT          = 'YYYY-MM-DD  HR:MN:SC.#### ::UTC'
      STRING_MAPPING       = ( 'J2000',         'EME2000',
                               '<object_id>',   '064' )
      SAMPLE_SPACING       = 60
      BLOCK_INSET          = 0

The customisible parts are as follows:

  • START_TIME and STOP_TIME are flexible; the formats accepted are documented in the STR2ET routine.
  • TIME_FORMAT controls the output in the OEM file. It is documented in the TIMOUT routine. Note that it must include a timesystem which normally should be ::TDB but I stuck with the more intuitive UTC without more details of what later use you will put this to
  • '<object_id>', '064' is the SPK id of the body/spacecraft of interest, in this case OSIRIS-REx. I got this from the HORIZONS website by searching for OSIRIS-REx as the target body. This returns Target Body [change] : OSIRIS-REx (spacecraft) [ORX] [-64] - the SPK id is the part in square brackets, without the minus sign (64 in this case, 74 in your MRO example). It's probably in the SPK header or docs that come with the kernels also.
  • INTERPOLATION_DEGREE can be between 1 and 15; I just used basic linear interpolation, higher orders may be better depending on how much acceleration/deceleration was going on
  • SAMPLE_SPACING is the spacing, in seconds, between the output entries in the OEM file

Running this as spk2oem osiris_rex.input should produce the output in the file you specified in OUTPUT_OEM_FILE. This looks like (skipping the comments from the original input SPK file and the summary of the spk2oem run and input file and where I'm only including the first 2 lines):

OBJECT_ID            = 064
REF_FRAME            = EME2000
TIME_SYSTEM          = UTC
START_TIME           = 2020-10-20  21:51:03.8175
STOP_TIME            = 2020-10-21  00:00:00.0000
2020-10-20  21:51:03.8175      1.367840845765761E-01   1.218165406787556E-01  -1.395099184264020E-01   2.883487419112815E-04   1.099589836181624E-04  -1.984126091732104E-04
2020-10-20  21:52:03.7880      1.540042170104885E-01   1.283515240766471E-01  -1.513366871065357E-01   2.859550400519023E-04   1.079849017832104E-04  -1.960125107315868E-04

So each line contains the time in the format you specify in TIME_FORMAT and the 6 element state vector of x, y, z positions and $\dot{x}, \dot{y}, \dot{z}$ velocities. According to Section of CCSDS Orbit Data Messages Blue Book:

In an OEM ephemeris data line, units shall be km, km/s, and km/s**2 for position, velocity, and acceleration components, respectively, but the units shall not be displayed.

  • $\begingroup$ although this solution does not work on Window 10 "out of the box", with some slight modifications it worked: I added "..\" before the kernels path in the input file, and I used this command line: spk2oem -setup ..\osiris_rex.input I dont' understand if I can find somewhere a description of the output fields and how to change them: in NASA Horizons interface I can choose between 6 different output tables. I would also like to know if spacecraft orientation data are available. $\endgroup$
    – jumpjack
    Nov 3, 2020 at 13:17
  • $\begingroup$ I found that spacecraft orientation is given in CK kernels: "orientation (attitude) of a spacecraft or other structure (CK)" ( naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/…. ) $\endgroup$
    – jumpjack
    Nov 5, 2020 at 17:38
  • $\begingroup$ I am getting this error "The input string contains an unrecognizable substring beginning at the character marked by <C>: "2021-JAN-13 14:45:03 <C>EST" on this file: naif.jpl.nasa.gov/pub/naif/MSL/kernels/spk/… But there is not such a string in my input, it's dynamically generated somewhere, as it contains the time of command launch. How can I fix this? $\endgroup$
    – jumpjack
    Jan 13, 2021 at 13:48

Found another method/tool: "spy" from SPICE utilities, available for Windows (actually DOS), Unix and Mac.

User manual: link

Copy these data into a text file named "command.txt":

; Load leap seconds kernel (mandatory for dates calculation, standard for all missions):
LOAD ..\kernels\NAIF0012.TLS;

; Load reference kernels:
LOAD ..\kernels\MSL\spk\de425s.bsp;   (???)
LOAD ..\kernels\MSL\pck\pck00008.tpc; (Orientation constants for bodies: needed to calculate planetographic coordinates (lat, lon))

; load specific kernels: 
LOAD ..\kernels\MSL\spk\msl_edl_v01.bsp;                (MSL EDL data)
LOAD ..\kernels\MSL\fk\msl_v08.tf;                      (Reference frames, names vs IDs mapping)
LOAD ..\kernels\MSL\ck\msl_edl_v01.bc;                  (attitude of spacecraft structures or instruments)
LOAD ..\kernels\MSL\sclk\msl_76_sclkscet_00016.tsc;     (spacecraft clock)

; Set time interval and samples frequency: 
SET START TIME 2012-08-06 05:02.000;
SET STOP TIME 2012-08-06 05:17.000;
SET STEP SIZE 60;  (seconds)

; Set reference frame: 

; Set page width (not working above 80)
; SET PAGE WIDTH 66; Word wrap at each datum, to prevent line break  (OPTIONAL, see NUMBER FORMAT below)

; Set output format:
SET NUMBER FORMAT F8.2; (hint: use short numbers to prevent word wrapping; here we have max 8 integer figures and 2 decimal figures)



; Show covered period:
DUMP COVERAGE SPK ..\kernels\MSL\spk\msl_edl_v01.bsp;

; Calculate "states" (=coordinates") of target (command split into multiple lines for readability):


Allowed values for COORDINATES:

  • RECTANGULAR (also called Cartesian: x,y,z w.r.t center)
  • CYLINDRICAL (radius of cylinder, longitude, and height above XY plane)
  • SPHERICAL (radius, colatitude, and longitude)
  • LATITUDINAL ; (also known as planetoCENTRIC: longitude+latitude w.r.t prime meridian, and distance from planet center (=radius))
  • GEODETIC ; ( Also known as "planetoDETIC", i.e. longitude+latitude w.r.t prime meridian, and altitude above surface; available only if ellipsoid for the body is available)
  • PLANETOGRAPHIC ; ( Also known as "planetoDETIC", i.e. longitude+latitude w.r.t prime meridian, and altitude above surface; available only if ellipsoid for the body is available and spin direction is available (rotational model); it takes into account local time)

Possible values for "SAMPLE" command:

  • ACCELERATION (on 3 axes)
  • POSITION (pos1, pos2, pos3)
  • SPEED (longitudinal speed?)
  • STATE (pos1, pos2, pos3, DeltaPos1, DeltaPos2, DeltaPos3)
  • VELOCITY (DeltaPos1, DeltaPos2, DeltaPos3)

From a DOS window, enter in the proper folder and type:

spy -cl -start command.txt

The "proper folder" is "bin" in this folder structure:


Store in proper folders the needed SPICE kernels. Adapt for other platforms.

Note: "SAMPLE POSITION COORDINATES GEODETIC ANGULAR UNITS DEGREES;" command does output Lat, Lon and Altitude data, which could be possibly converted into KML format for viewing in GoogleEarth/GoogleMars.

Note for DOS/Windows users:

Some kernels are text files, but are stored on NASA sites with UNIX-style carriage returns; you must convert into DOS-style carriage return before usage, for example using PSPad tex editor.

Further explanations:

  • $\begingroup$ Cool! I've been afraid of SPICE for fear of attracting sand worms, but I see that MacOS is mentioned here. Can you help me figure out what to download in order to run these utilities in MacOS? Is this an actual application, or do I need to still use complied code somehow? I'm so confused (and afraid of those sand worms). $\endgroup$
    – uhoh
    Jan 26, 2021 at 1:45
  • 1
    $\begingroup$ @uhoh I don't know Mac world, I can only suggest to download this file and "launch" it (I don't know how to launch a commandline program in Mac). In Windows we have "executables" (spy.exe in this case): we open a DOSBOX by running CMD, and we type "spy -cl start command.txt" to run the executable with parameters. $\endgroup$
    – jumpjack
    Jan 26, 2021 at 8:52
  • $\begingroup$ Interesting! I've just asked How can I find out what's in this NASA JPL “Spy” command line program for macOS and how safe it is? in Security SE. $\endgroup$
    – uhoh
    Jan 26, 2021 at 9:30
  • $\begingroup$ don't you trust NASA?!? $\endgroup$
    – jumpjack
    Jan 26, 2021 at 14:32
  • 1
    $\begingroup$ Internet executable downloads are what they are! It has nothing to do with "trusting NASA". What information was stolen from JPL during the Raspberry Pi hack? and the 2020 United States federal government data breach come to mind. What do you think the security is on something written in 2012 to run on a platform in 2021? Of all the systems at JPL, how carefully do you think this repository is monitored for unauthorized activity? $\endgroup$
    – uhoh
    Jan 26, 2021 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.