Jpl time 2.0 - #3
Open
FloraRidenhour wants to merge 14 commits into
Open
Conversation
Captures exact outputs of the current SPICE-based implementation: UTC/ET/TAI across 1900-2299 including every leap second, all supported input string formats, GPS/timezone/ISO-week conversions, and per-mission LMST/LTST/SCLK/OWLT samples (M2020, MSL, InSight, Psyche). These files are the compatibility contract for the 2.0 refactor. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 82fed0c7394df7c99a1f3ec71b7a1929de9d4d1c)
- UTC parsing/formatting, TAI/ET/GPS conversions, time zones and all time/duration math now run in pure Python using a built-in leap second table plus the full DELTET formula, matching SPICE outputs exactly. Loading a .tls kernel updates the table; SCLK/OWLT/LTST still use SPICE. - New Time.set_lmst_epoch() enables kernel-free linear LMST (rate 88775.244 s/sol, identical to single-record mission LMST kernels); a loaded LMST kernel always takes precedence. - Implementation split into _time, _duration, _epoch_relative, _leapseconds, _lmst, _spice, _config, _cli and _exceptions; jpl_time.jpl_time remains as a shim so all 1.x imports keep working. - The epoch-relative epochs feature (#1) carries into _epoch_relative.py, with three robustness fixes: CVF epochs may reference epochs defined later in the file (write_epoch_cvf sorts by time, which can place a negative-offset child before its parent), set_epochs fully rebuilds the parents map, and remove_epoch cannot recurse forever on a malformed parent cycle. - Python 3 only: import fallbacks, Duration.__div__ and py2 remnants removed; pytz replaced with stdlib zoneinfo; regexes made raw strings. - CLI degrades gracefully without kernels (kernel-dependent outputs N/A). (cherry picked from commit 0e2cc0e6f45402d385938adc48808572bcbee31a) Co-authored-by: Carolyn Ortega <carolyn.ortega@jpl.caltech.edu> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per-area test files with shared mission-kernel fixtures, automatic state isolation, and skip markers when kernels are unavailable. Most tests run with no kernels loaded to exercise the SPICE-free paths. test_regression_baseline.py replays the v1.4.5 baselines to pin exact output compatibility, including linear-vs-kernel LMST equivalence. Replaces time_test.py and duration_test.py (all cases ported, including the epoch-relative epoch tests from #1, which gain coverage for CVF round trips, any-order references, and chained removal). (cherry picked from commit 50fb7e9f4b5847c4926de83925652b026021a021) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces setup.py/setup.cfg. The only runtime dependency is spiceypy; unused dependencies (numpy, six, nose, tornado, wheel, certifi, pytz) are dropped. Adds pytest configuration and expands .gitignore with build artifacts and virtualenvs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit a91d667d5cc3c274f1d67330edbc750f936c5ec0)
README: Python 2 instructions removed, kernel-free scope documented, LMST-without-kernels section and a 2.0 changelog added. Sphinx docs rebuilt with a user guide, developer guide (architecture, leap second math, LMST models, regression baseline rules) and an autodoc API reference. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit af40426e5d4f2b68ba8c72cf33e729f0096f73e2)
spiceypy 8.1.1 dropped Python 3.10 (and 7.0 dropped 3.9) without updating its requires-python metadata, so pip on 3.10 resolves a release with no compatible wheel. Cap spiceypy below 8.1.1 for python_version < 3.11 so all supported Pythons install cleanly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit fd43797878069e8f437f003fb6c83f472181f226)
Runs the test suite on Python 3.9-3.13 (the mission kernels in test/inputs enable the full suite, including the regression baselines), and verifies the wheel builds, installs, and runs the CLI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit d4e082689e10963a96ef7cd96a728c63b87c97a4)
Annotates Time, Duration, EpochRelativeTime, the config/CLI helpers and the exception hierarchy. Arithmetic operators get @overload declarations so type checkers resolve Time - Time -> Duration, Time - Duration -> Time, Duration / number -> Duration, etc. without false positives. Annotations use typing.Optional/Union so they stay valid at runtime on Python 3.9. The py.typed marker lets mypy/pyright consume the hints. No runtime behavior changes; all 193 tests pass on 3.9 and 3.11. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit d1c0954a6041b7e0ced5b860960da098c05636c1)
The test kernels live in git-lfs, and actions/checkout leaves them as pointer files. furnsh silently accepts a pointer file (a text file with no begindata block is a valid comment-only kernel), so kernel-dependent tests failed with confusing conversion errors instead of load errors. CI now downloads the kernels (~0.5 GB) in a single job, cached by LFS content so matrix jobs and later runs never re-download. conftest detects pointer files and skips kernel-dependent tests with a clear reason, so checkouts without 'git lfs pull' degrade to the SPICE-free subset (138 tests) instead of failing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This updates jpl_time to 2.0.0. The main change: SPICE kernels are no longer needed for most operations. UTC parsing/formatting, ET/TAI/GPS conversions, time zones, and all time and duration math now run in pure Python using a built-in leap second table and the DELTET formula from the LSK. Loading a newer leapseconds kernel still takes precedence over the built-in table. SCLK, LMST, LTST, and light-time conversions use kernels exactly as before. LMST can now also work without kernels by setting the sol-0 epoch (
Time.set_lmst_epoch()); this matches kernel LMST exactly because mission LMST kernels are a single linear segment at 88775.244 s/sol.No public interface changed: same methods, signatures, input formats, and output strings, and
from jpl_time.jpl_time import Timestill works. This isn't just asserted —test/regression_data/holds ~6,700 conversions captured from v1.4.5 (every leap second 1900–2299, all input formats, and M2020/MSL/InSight/Psyche kernel conversions), and the test suite replays them with no kernels loaded. All of the old unit tests were ported and pass unchanged.Also in this PR:
Two known behavior differences, both intentional: string outputs at precision 6 beyond ~year 2100 can differ from SPICE by 1 µs (SPICE's own double-precision rounding; the new integer math is exact), and the CLI without kernels now prints N/A for kernel-dependent formats instead of refusing to run.