Disclaimer

All the SPICE tools in this package should not be considered has a replacement of the SPICE toolkit. They follow NAIF documentation as closely as possible, however, if you accounter an error with one of these functions, please contact us to report your issue so it can be fixed for everyone.

SPICE kernel#

Text kernel parser#

from planetary_coverage.spice import kernel_parser

The function kernel_parse() allows the user to inspect quickly the content and the data in a text-kernel, without having to load it into the SPICE pool:

content, data = kernel_parser('naif0012.tls')

Here, the content variable is a full dump of the kernel content (text and data):

print(content)
KPL/LSK


LEAPSECONDS KERNEL FILE
===========================================================================

Modifications:
--------------

2016, Jul. 14   NJB  Modified file to account for the leapsecond that
                     will occur on December 31, 2016.

2015, Jan. 5    NJB  Modified file to account for the leapsecond that
                     will occur on June 30, 2015.

2012, Jan. 5    NJB  Modified file to account for the leapsecond that
                     will occur on June 30, 2012.
                     
2008, Jul. 7    NJB  Modified file to account for the leapsecond that
                     will occur on December 31, 2008.
                     
2005, Aug. 3    NJB  Modified file to account for the leapsecond that
                     will occur on December 31, 2005.
                     
1998, Jul  17   WLT  Modified file to account for the leapsecond that
                     will occur on December 31, 1998.
                     
1997, Feb  22   WLT  Modified file to account for the leapsecond that
                     will occur on June 30, 1997.
                     
1995, Dec  14   KSZ  Corrected date of last leapsecond from 1-1-95
                     to 1-1-96.

1995, Oct  25   WLT  Modified file to account for the leapsecond that
                     will occur on Dec 31, 1995.

1994, Jun  16   WLT  Modified file to account for the leapsecond on
                     June 30, 1994.

1993, Feb. 22  CHA   Modified file to account for the leapsecond on
                     June 30, 1993.

1992, Mar. 6   HAN   Modified file to account for the leapsecond on
                     June 30, 1992.

1990, Oct. 8   HAN   Modified file to account for the leapsecond on 
                     Dec. 31, 1990.  


Explanation:
------------

The contents of this file are used by the routine DELTET to compute the 
time difference

[1]       DELTA_ET  =  ET - UTC                                         
          
the increment to be applied to UTC to give ET. 

The difference between UTC and TAI,

[2]       DELTA_AT  =  TAI - UTC

is always an integral number of seconds. The value of DELTA_AT was 10
seconds in January 1972, and increases by one each time a leap second
is declared. Combining [1] and [2] gives

[3]       DELTA_ET  =  ET - (TAI - DELTA_AT)

                    =  (ET - TAI) + DELTA_AT

The difference (ET - TAI) is periodic, and is given by

[4]       ET - TAI  =  DELTA_T_A  + K sin E 

where DELTA_T_A and K are constant, and E is the eccentric anomaly of the 
heliocentric orbit of the Earth-Moon barycenter. Equation [4], which ignores 
small-period fluctuations, is accurate to about 0.000030 seconds.

The eccentric anomaly E is given by 

[5]       E = M + EB sin M

where M is the mean anomaly, which in turn is given by 

[6]       M = M  +  M t
               0     1

where t is the number of ephemeris seconds past J2000.

Thus, in order to compute DELTA_ET, the following items are necessary.

          DELTA_TA
          K
          EB
          M0
          M1
          DELTA_AT      after each leap second.

The numbers, and the formulation, are taken from the following sources.

     1) Moyer, T.D., Transformation from Proper Time on Earth to 
        Coordinate Time in Solar System Barycentric Space-Time Frame
        of Reference, Parts 1 and 2, Celestial Mechanics 23 (1981),
        33-56 and 57-68.

     2) Moyer, T.D., Effects of Conversion to the J2000 Astronomical
        Reference System on Algorithms for Computing Time Differences
        and Clock Rates, JPL IOM 314.5--942, 1 October 1985.

The variable names used above are consistent with those used in the 
Astronomical Almanac.

\begindata

DELTET/DELTA_T_A       =   32.184
DELTET/K               =    1.657D-3
DELTET/EB              =    1.671D-2
DELTET/M               = (  6.239996D0   1.99096871D-7 )

DELTET/DELTA_AT        = ( 10,   @1972-JAN-1
                           11,   @1972-JUL-1     
                           12,   @1973-JAN-1     
                           13,   @1974-JAN-1     
                           14,   @1975-JAN-1          
                           15,   @1976-JAN-1          
                           16,   @1977-JAN-1          
                           17,   @1978-JAN-1          
                           18,   @1979-JAN-1          
                           19,   @1980-JAN-1          
                           20,   @1981-JUL-1          
                           21,   @1982-JUL-1          
                           22,   @1983-JUL-1          
                           23,   @1985-JUL-1          
                           24,   @1988-JAN-1 
                           25,   @1990-JAN-1
                           26,   @1991-JAN-1 
                           27,   @1992-JUL-1
                           28,   @1993-JUL-1
                           29,   @1994-JUL-1
                           30,   @1996-JAN-1 
                           31,   @1997-JUL-1
                           32,   @1999-JAN-1
                           33,   @2006-JAN-1
                           34,   @2009-JAN-1
                           35,   @2012-JUL-1
                           36,   @2015-JUL-1 
                           37,   @2017-JAN-1 )

\begintext

The data variable on the other hand, only contains the parsed data in the kernel (between the \begindata and \begintext tags). The values are stored in a simple dict with the matching key:

data
{'DELTET/DELTA_T_A': 32.184,
 'DELTET/K': 0.001657,
 'DELTET/EB': 0.01671,
 'DELTET/M': [6.239996, 1.99096871e-07],
 'DELTET/DELTA_AT': [10,
  numpy.datetime64('1972'),
  11,
  numpy.datetime64('1972-07'),
  12,
  numpy.datetime64('1973'),
  13,
  numpy.datetime64('1974'),
  14,
  numpy.datetime64('1975'),
  15,
  numpy.datetime64('1976'),
  16,
  numpy.datetime64('1977'),
  17,
  numpy.datetime64('1978'),
  18,
  numpy.datetime64('1979'),
  19,
  numpy.datetime64('1980'),
  20,
  numpy.datetime64('1981-07'),
  21,
  numpy.datetime64('1982-07'),
  22,
  numpy.datetime64('1983-07'),
  23,
  numpy.datetime64('1985-07'),
  24,
  numpy.datetime64('1988'),
  25,
  numpy.datetime64('1990'),
  26,
  numpy.datetime64('1991'),
  27,
  numpy.datetime64('1992-07'),
  28,
  numpy.datetime64('1993-07'),
  29,
  numpy.datetime64('1994-07'),
  30,
  numpy.datetime64('1996'),
  31,
  numpy.datetime64('1997-07'),
  32,
  numpy.datetime64('1999'),
  33,
  numpy.datetime64('2006'),
  34,
  numpy.datetime64('2009'),
  35,
  numpy.datetime64('2012-07'),
  36,
  numpy.datetime64('2015-07'),
  37,
  numpy.datetime64('2017')]}

As you can see above, the decimal value are parsed as int and float. When multiple value are present, an parsed array is returned:

data['DELTET/M']
[6.239996, 1.99096871e-07]

When a datetime is present (starting with a @ symbol), it will be parsed as a numpy.datetime64 object:

data['DELTET/DELTA_AT'][1]
numpy.datetime64('1972')

This function also supports, line continuation (i.e. the string ending with //) and multi-values assignments (scattered in multiple lines or with the += symbol).

Text kernel formatter#

from planetary_coverage.spice import format_data

The function format_data() is a handy shortcut to format your raw-data into a string that could be copy-pasted into your text-kernel:

format_data(single_float=1.2)
'    SINGLE_FLOAT = 1.2'

By default is indentation is set at 4 spaces, but you can use your own:

format_data(single_int=-1, indent=0)
'SINGLE_INT = -1'

You can define the format of your output:

format_data(single_float_d=1.657e-3, fmt='.3E')
'    SINGLE_FLOAT_D = 1.657E-03'

The datetime are converted to SPICE time keys:

format_data(
    single_date=np.datetime64('1987-01-31'),
    fmt=r'%d-%b-%Y',
)
'    SINGLE_DATE = @31-Jan-1987'

If you provide multiple values, the = signs will the aligned:

print(format_data(
    vec_int_comma=(1, 3, 2),
    vec_float_comma=np.array([0., 0., 90.]),
    vec_str_comma=['FOO', 'BAR'],
    indent=2,
))
  VEC_INT_COMMA   = ( 1, 3, 2 )
  VEC_FLOAT_COMMA = ( 0.0, 0.0, 90.0 )
  VEC_STR_COMMA   = ( 'FOO', 'BAR' )

You can change the separation, if needed:

format_data(
    arr_int_space=(4, 5, 6),
    sep=' ',
)
'    ARR_INT_SPACE = ( 4 5 6 )'

The SPICE line constrains are enforce by default and if the value is too long (> 132 characters), the result will be split in multiple lines:

print(format_data(long_string=150 * 'a'))
    LONG_STRING = ( 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa//',
                    'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'          )