Skip to content

Commit

Permalink
Merge pull request #118 from astrojuanlu/make-tle-predictor-pickleable
Browse files Browse the repository at this point in the history
Make TLEPredictor pickleable
  • Loading branch information
astrojuanlu authored Dec 19, 2020
2 parents 748bf10 + 46213b3 commit 3bec8b4
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
if [ $(python -c "import sys; print(sys.version[:3])") != 3.4 ]; then python -m pip install --prefer-binary --editable .[fast]; fi
- name: Lint with flake8
run: |
flake8 orbit_predictor
flake8 orbit_predictor tests
- name: Test with pytest
run: |
pytest -v --cov-report= --cov=orbit_predictor tests/
30 changes: 16 additions & 14 deletions orbit_predictor/predictors/accurate.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"""
import datetime as dt
from functools import lru_cache
import warnings

from sgp4 import ext, model
from sgp4.api import Satrec, SGP4_ERRORS
Expand Down Expand Up @@ -88,6 +87,22 @@ def __init__(self, sate_id, source):
self._sate_id = sate_id
self._source = source
self.tle = self._source.get_tle(self.sate_id, dt.datetime.utcnow())
self._propagator = self._get_propagator()

def _get_propagator(self):
tle_line_1, tle_line_2 = self.tle.lines
return Satrec.twoline2rv(tle_line_1, tle_line_2, WGS84)

def __getstate__(self):
# See https://docs.python.org/3/library/pickle.html#handling-stateful-objects
state = self.__dict__.copy()
del state["_propagator"]
return state

def __setstate__(self, state):
# See https://docs.python.org/3/library/pickle.html#handling-stateful-objects
self.__dict__.update(state)
self._propagator = self._get_propagator()

@property
def sate_id(self):
Expand All @@ -97,19 +112,6 @@ def sate_id(self):
def source(self):
return self._source

@reify
def _propagator(self):
tle_line_1, tle_line_2 = self.tle.lines
return Satrec.twoline2rv(tle_line_1, tle_line_2, WGS84)

@reify
def propagator(self):
warnings.warn(
"The .propagator property will be made private in a future release",
DeprecationWarning
)
return self._propagator

@reify
def mean_motion(self):
"""Mean motion, in radians per minute"""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ def setUp(self):

with open(self.filename, "w") as fd:
fd.write(SATE_ID + "\n")
for l in SAMPLE_TLE:
fd.write(l + "\n")
for line in SAMPLE_TLE:
fd.write(line + "\n")

def test_add_tle(self):
db = sources.EtcTLESource(self.filename)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_sun.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,5 @@ def test_ltan_from_raan(when_utc, raan, ltan):
[winter_equinox, 180, 12],
[winter_equinox, 270, 18],
])
def test_ltan_from_raan(when_utc, raan, ltan):
def test_raan_from_ltan(when_utc, raan, ltan):
assert pytest.approx(raan_from_ltan(when_utc, ltan), abs=1/3600) == raan
19 changes: 19 additions & 0 deletions tests/test_tle_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

import datetime as dt
import unittest
import os
import pickle
import tempfile
from unittest.mock import patch

from orbit_predictor.coordinate_systems import llh_to_ecef
Expand Down Expand Up @@ -201,6 +204,22 @@ def test_off_nadir_computable_and_reasonable(self):
pass_ = self.predictor.get_next_pass(ARG, date)
self.assertLessEqual(abs(pass_.off_nadir_deg), 90)

def test_tle_predictor_is_pickleable(self):
# See https://github.com/satellogic/orbit-predictor/issues/117
with tempfile.TemporaryDirectory() as tmpdir:
pickle_file = os.path.join(tmpdir, "predictor.pkl")
with open(pickle_file, "wb") as fp:
pickle.dump(self.predictor, fp)

with open(pickle_file, "rb") as fp:
predictor = pickle.load(fp)

when_utc = dt.datetime.utcnow()

assert predictor.tle == self.predictor.tle
assert predictor.mean_motion == self.predictor.mean_motion
assert predictor.get_position(when_utc) == self.predictor.get_position(when_utc)


class OffNadirAngleTests(unittest.TestCase):
def setUp(self):
Expand Down

0 comments on commit 3bec8b4

Please sign in to comment.