""" Create some common kernel files.
For some case, one may need to reproduce the kernel files.
"""
import os as _os
import sys as _sys
import re as _re
import logging as _logging
import datetime as _datetime
import spiceypy as _spice
from irfpy.spice import __version__
_logger = _logging.getLogger(__name__)
def _irfpy_trail():
s = ('',
'',
'irfpy-spice-localized-mk',
'------------------------------------------------------',
'',
'The "localized" version of this mk file was',
' Created by: {}'.format('irfpy-spice-localized-mk'),
' Version: {}'.format(__version__),
' Created on: {}'.format(_datetime.datetime.now()),
)
return '\n'.join(s)
[docs]def localize_mkfile(metakernel, local_dir=False, output=None, kernel_path=None):
""" Localize the MK (meta kernel) file, with PATH_VALUE replaced.
Background: The MK file, ending with '.tm', contains the actual kernels
to be loaded for a specific project.
It frequently contains a "hard-coded" path, "PATH_VALUES", that points to
the parent path ('..'), while this refers to the parent path of the current directory.
Therefore, the PATH_VALUES should be modified manually to load the actual kernels to load.
This function creates a new mk file based on the given metakernel, with
PATH_VALUE replaced.
You can use the CLI ``irfpy-spice-localize-mk`` command.
:param metakernel: The meta kernel (input)
:keyword local_dir: If set True, the output file is in the same directory as
the given meta kernel, with "_local" added. The ``output`` is ignored
if this is set True.
:keyword output: The output file name. If *None* given, stdout is used.
:keyword kernel_path: The actual path name where the kernel is stored.
If *None* given (default), the kernel path is deduced from the ``metakernel`` file.
Example:
Let us localize ``/path/to/kernels/mk/mex_ops.tm``.
Localize and output to stdout
>>> from irfpy.spice import localize
>>> localize_mkfile('/path/to/kernels/mk/mex_ops.tm') # doctest: +SKIP
Localize and output to a specific file
>>> localize_mkfile('/path/to/kernels/mk/mex_ops.tm', output="./mex_ops_local.tm") # doctest: +SKIP
Localize and output to the original path
(``/path/to/kernels/mk/mex_ops_local.tm`` is created.)
>>> localize_mkfile('/path/to/kernels/mk/mex_ops.tm', local_dir=True) # doctest: +SKIP
Localize but with specific path name (but this option is not recommended to use)
>>> localize_mkfile('/path/to/kernels/mk/mex_ops.tm', kernel_path='..') # doctest: +SKIP
"""
if local_dir:
tm0, tm1 = _os.path.splitext(metakernel)
if tm1 == ".TM":
local = "_LOCAL"
else:
local = "_local"
output = tm0 + local + tm1
if output is None:
fp = _sys.stdout
else:
fp = open(output, 'w')
_logger.debug(f'file={fp}')
if kernel_path is None:
kernel_path = _os.path.abspath(_os.path.join(_os.path.dirname(metakernel), '..'))
_logger.debug(f'kernel_path={kernel_path}')
with open(metakernel, 'r') as fp_mk:
contents = make_localized_meta_kernel(fp_mk.read(), kernel_path)
contents = contents + _irfpy_trail()
fp.write(contents)
if output is not None:
fp.close()
[docs]def naif0010(filename):
""" Create naif0010.tls for furnsh
"""
content = r'''KPL/LSK
LEAPSECONDS KERNEL FILE
===========================================================================
\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 )
\begintext
'''
with open(filename, 'w') as fp:
fp.write(content)
return filename
_naif0012_contents = r'''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
'''
[docs]def naif0012(filename):
""" Create naif0012.tls
"""
with open(filename, 'w') as fp:
fp.write(_naif0012_contents)
return filename
[docs]def furnsh_tls(version=12):
""" Furnsh a leapseconds kernel.
>>> from irfpy.spice.localize import furnsh_tls
>>> furnsh_tls() # Silent furnsh leapsec file.
"""
import tempfile as _tempfile
tf = _tempfile.NamedTemporaryFile(suffix='.tls')
_logger.debug(tf.name)
tf.seek(0)
tf.write(_naif0012_contents.encode())
tf.flush()
_spice.furnsh(tf.name)