Hello community, here is the log from the commit of package python-sgp4 for openSUSE:Factory checked in at 2020-10-16 16:16:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sgp4 (Old) and /work/SRC/openSUSE:Factory/.python-sgp4.new.3486 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sgp4" Fri Oct 16 16:16:53 2020 rev:2 rq:842091 version:2.13 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sgp4/python-sgp4.changes 2020-07-14 08:00:20.329993475 +0200 +++ /work/SRC/openSUSE:Factory/.python-sgp4.new.3486/python-sgp4.changes 2020-10-16 16:17:05.864742556 +0200 @@ -1,0 +2,7 @@ +Fri Oct 16 09:49:21 UTC 2020 - Benjamin Greiner <c...@bnavigator.de> + +- Update to version 2.13 + * Enhanced sgp4init() with custom code that also sets the + epochdays and epochyr satellite attributes. + +------------------------------------------------------------------- Old: ---- sgp4-2.12.tar.gz New: ---- sgp4-2.13.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sgp4.spec ++++++ --- /var/tmp/diff_new_pack.epjOvh/_old 2020-10-16 16:17:08.852743473 +0200 +++ /var/tmp/diff_new_pack.epjOvh/_new 2020-10-16 16:17:08.856743474 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-sgp4 -Version: 2.12 +Version: 2.13 Release: 0 Summary: Track earth satellite TLE orbits using up-to-date 2010 version of SGP4 License: MIT @@ -52,8 +52,8 @@ %prep %setup -q -n sgp4-%{version} cp %{SOURCE99} . -# ease precision tolerances for flaky platforms -sed -i 's/GRAVITY_DIGITS = 12/GRAVITY_DIGITS = 10/' sgp4/tests.py +# ease precision tolerances https://github.com/brandon-rhodes/python-sgp4/issues/69 +sed -i 's/GRAVITY_DIGITS = (/GRAVITY_DIGITS = 10\nGRAVITY_DIGITS_UPSTREAM =(/' sgp4/tests.py sed -i 's/error = 2e-7/error = 2e-5/' sgp4/tests.py %build @@ -72,7 +72,6 @@ # Only the doctests acually import the compiled extension and fail if it is not present %pytest_arch --pyargs sgp4 --doctest-modules - %files %{python_files} %license LICENSE %{python_sitearch}/sgp4 ++++++ sgp4-2.12.tar.gz -> sgp4-2.13.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/PKG-INFO new/sgp4-2.13/PKG-INFO --- old/sgp4-2.12/PKG-INFO 2020-05-28 20:12:01.000000000 +0200 +++ new/sgp4-2.13/PKG-INFO 2020-10-15 01:51:09.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: sgp4 -Version: 2.12 +Version: 2.13 Summary: Track earth satellite TLE orbits using up-to-date 2010 version of SGP4 Home-page: https://github.com/brandon-rhodes/python-sgp4 Author: Brandon Rhodes @@ -9,7 +9,7 @@ Description: This Python package computes the position and velocity of an earth-orbiting satellite, given the satellite's TLE orbital elements - from a source like `Celestrak <http://celestrak.com/>`_. It implements + from a source like `Celestrak <https://celestrak.com/>`_. It implements the most recent version of SGP4, and is regularly run against the SGP4 test suite to make sure that its satellite position predictions **agree to within 0.1 mm** with the predictions of the standard distribution of @@ -37,9 +37,9 @@ For conversions into other coordinate frames, look for a comprehensive astronomy library that is built atop this one, like the `Skyfield - <http://rhodesmill.org/skyfield/>`_ library: + <https://rhodesmill.org/skyfield/>`_ library: - http://rhodesmill.org/skyfield/earth-satellites.html + https://rhodesmill.org/skyfield/earth-satellites.html Usage ----- @@ -59,9 +59,9 @@ >>> e, r, v = satellite.sgp4(jd, fr) >>> e 0 - >>> print(r) + >>> print(r) # True Equator Mean Equinox position (km) (-6102.44..., -986.33..., -2820.31...) - >>> print(v) + >>> print(v) # True Equator Mean Equinox velocity (km/s) (-1.45..., -5.52..., 5.10...) As input, you can provide either: @@ -234,6 +234,9 @@ [-3.85 6.28 -1.85] [-3.91 6.25 -1.83]]] + Attributes + ---------- + The attributes of a ``Satrec`` object carry the data loaded from the TLE entry. Most of this class's hundred-plus attributes are intermediate values @@ -331,6 +334,10 @@ To compute the “epoch” value, simply take a normal Julian date and subtract ``2433281.5`` days. + In addition to setting the attributes natively set by the underlying + ``sgp4init()`` routine, this library also goes ahead and sets the date + fields ``epochyr``, ``epochdays``, ``jdsatepoch``, and ``jdsatepochF``. + The character provided as the second argument can be ``'a'`` to run the computations so that they are compatible with the old Air Force Space Command edition of the library, or ``'i'`` to run the new and improved @@ -353,10 +360,10 @@ 21–24. If you would like to review the paper, it is `available online - <http://www.celestrak.com/publications/AIAA/2006-6753/>`_. You can + <https://www.celestrak.com/publications/AIAA/2006-6753/>`_. You can always download the latest version of their code for comparison against this Python module (or other implementations) at `AIAA-2006-6753.zip - <http://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753.zip>`_. + <https://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753.zip>`_. For developers -------------- @@ -386,6 +393,7 @@ Changelog --------- + | 2020-10-14 — 2.13 — Enhanced ``sgp4init()`` with custom code that also sets the ``epochdays`` and ``epochyr`` satellite attributes. | 2020-05-28 — 2.12 — Moved the decision of whether to set the locale during ``twoline2rv()`` from import time to runtime, for users who change locales after their application is up and running. | 2020-05-24 — 2.11 — Fixed a regression in how dates are split into hours, minutes, and seconds that would sometimes produce a time whose second=60, crashing the pure-Python version of the library. | 2020-05-22 — 2.10 — Switch the locale temporarily to ``C`` during the C++ accelerated ``twoline2rv()``, since it does not protect its ``sscanf()`` calls from locales that, like German, expect comma decimal points instead of the period decimal points always used in a TLE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/extension/wrapper.cpp new/sgp4-2.13/extension/wrapper.cpp --- old/sgp4-2.12/extension/wrapper.cpp 2020-05-28 20:08:47.000000000 +0200 +++ new/sgp4-2.13/extension/wrapper.cpp 2020-10-15 01:36:35.000000000 +0200 @@ -179,7 +179,13 @@ bstar, ndot, nddot, ecco, argpo, inclo, mo, no_kozai, nodeo, satrec); - /* Populate jdsatepoch and jdsatepochF as SGP4Funcs::twoline2rv does */ + /* Populate date fields that SGP4Funcs::twoline2rv would set. */ + int y, m, d, H, M; + double S, jan0jd, jan0fr /* always comes out 0.0 */; + SGP4Funcs::invjday(2433281.5, epoch, y, m, d, H, M, S); + SGP4Funcs::jday(y, 1, 0, 0, 0, 0.0, jan0jd, jan0fr); + satrec.epochyr = y % 1000; + satrec.epochdays = 2433281.5 - jan0jd + epoch; satrec.jdsatepochF = modf(epoch, &satrec.jdsatepoch); satrec.jdsatepoch += 2433281.5; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/setup.py new/sgp4-2.13/setup.py --- old/sgp4-2.12/setup.py 2020-05-28 20:08:47.000000000 +0200 +++ new/sgp4-2.13/setup.py 2020-10-15 01:36:35.000000000 +0200 @@ -34,7 +34,7 @@ )) setup(name = 'sgp4', - version = '2.12', + version = '2.13', description = description, long_description = long_description, license = 'MIT', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/sgp4/__init__.py new/sgp4-2.13/sgp4/__init__.py --- old/sgp4-2.12/sgp4/__init__.py 2020-05-28 20:08:47.000000000 +0200 +++ new/sgp4-2.13/sgp4/__init__.py 2020-10-15 01:36:35.000000000 +0200 @@ -3,7 +3,7 @@ This Python package computes the position and velocity of an earth-orbiting satellite, given the satellite's TLE orbital elements -from a source like `Celestrak <http://celestrak.com/>`_. It implements +from a source like `Celestrak <https://celestrak.com/>`_. It implements the most recent version of SGP4, and is regularly run against the SGP4 test suite to make sure that its satellite position predictions **agree to within 0.1 mm** with the predictions of the standard distribution of @@ -31,9 +31,9 @@ For conversions into other coordinate frames, look for a comprehensive astronomy library that is built atop this one, like the `Skyfield -<http://rhodesmill.org/skyfield/>`_ library: +<https://rhodesmill.org/skyfield/>`_ library: -http://rhodesmill.org/skyfield/earth-satellites.html +https://rhodesmill.org/skyfield/earth-satellites.html Usage ----- @@ -53,9 +53,9 @@ >>> e, r, v = satellite.sgp4(jd, fr) >>> e 0 ->>> print(r) +>>> print(r) # True Equator Mean Equinox position (km) (-6102.44..., -986.33..., -2820.31...) ->>> print(v) +>>> print(v) # True Equator Mean Equinox velocity (km/s) (-1.45..., -5.52..., 5.10...) As input, you can provide either: @@ -228,6 +228,9 @@ [-3.85 6.28 -1.85] [-3.91 6.25 -1.83]]] +Attributes +---------- + The attributes of a ``Satrec`` object carry the data loaded from the TLE entry. Look at the class's documentation for details. @@ -292,6 +295,10 @@ To compute the “epoch” value, simply take a normal Julian date and subtract ``2433281.5`` days. +In addition to setting the attributes natively set by the underlying +``sgp4init()`` routine, this library also goes ahead and sets the date +fields ``epochyr``, ``epochdays``, ``jdsatepoch``, and ``jdsatepochF``. + The character provided as the second argument can be ``'a'`` to run the computations so that they are compatible with the old Air Force Space Command edition of the library, or ``'i'`` to run the new and improved @@ -314,10 +321,10 @@ 21–24. If you would like to review the paper, it is `available online -<http://www.celestrak.com/publications/AIAA/2006-6753/>`_. You can +<https://www.celestrak.com/publications/AIAA/2006-6753/>`_. You can always download the latest version of their code for comparison against this Python module (or other implementations) at `AIAA-2006-6753.zip -<http://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753.zip>`_. +<https://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753.zip>`_. For developers -------------- @@ -347,6 +354,7 @@ Changelog --------- +| 2020-10-14 — 2.13 — Enhanced ``sgp4init()`` with custom code that also sets the ``epochdays`` and ``epochyr`` satellite attributes. | 2020-05-28 — 2.12 — Moved the decision of whether to set the locale during ``twoline2rv()`` from import time to runtime, for users who change locales after their application is up and running. | 2020-05-24 — 2.11 — Fixed a regression in how dates are split into hours, minutes, and seconds that would sometimes produce a time whose second=60, crashing the pure-Python version of the library. | 2020-05-22 — 2.10 — Switch the locale temporarily to ``C`` during the C++ accelerated ``twoline2rv()``, since it does not protect its ``sscanf()`` calls from locales that, like German, expect comma decimal points instead of the period decimal points always used in a TLE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/sgp4/model.py new/sgp4-2.13/sgp4/model.py --- old/sgp4-2.12/sgp4/model.py 2020-05-21 20:03:40.000000000 +0200 +++ new/sgp4-2.13/sgp4/model.py 2020-10-15 01:36:35.000000000 +0200 @@ -1,7 +1,7 @@ """The Satellite class.""" from sgp4.earth_gravity import wgs72old, wgs72, wgs84 -from sgp4.ext import days2mdhms, jday +from sgp4.ext import days2mdhms, invjday, jday from sgp4.functions import jday as jday2 from sgp4.io import twoline2rv from sgp4.propagation import sgp4, sgp4init @@ -70,8 +70,15 @@ def sgp4init(self, whichconst, opsmode, satnum, epoch, bstar, ndot, nddot, ecco, argpo, inclo, mo, no_kozai, nodeo): whichconst = gravity_constants[whichconst] + + y, m, d, H, M, S = invjday(epoch + 2433281.5) + jan0epoch = jday(y, 1, 0, 0, 0, 0.0) - 2433281.5 + + self.epochyr = y % 1000 + self.epochdays = epoch - jan0epoch self.jdsatepoch, self.jdsatepochF = divmod(epoch, 1.0) self.jdsatepoch += 2433281.5 + sgp4init(whichconst, opsmode, satnum, epoch, bstar, ndot, nddot, ecco, argpo, inclo, mo, no_kozai, nodeo, self) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/sgp4/omm.py new/sgp4-2.13/sgp4/omm.py --- old/sgp4-2.12/sgp4/omm.py 1970-01-01 01:00:00.000000000 +0100 +++ new/sgp4-2.13/sgp4/omm.py 2020-10-15 01:36:35.000000000 +0200 @@ -0,0 +1,44 @@ +"""Support for the new Orbit Mean-Elements Message format for TLE data.""" + +import csv +import xml.etree.ElementTree as ET +from datetime import datetime +from math import pi +from sgp4.api import WGS72 + +def parse_csv(file): + return csv.DictReader(file) + +def parse_xml(file): + root = ET.parse(file).getroot() + for segment in root.findall('.//segment'): + metadata = segment.find('metadata') + data = segment.find('data') + meanElements = data.find('meanElements') + tleParameters = data.find('tleParameters') + fields = {} + for element in metadata, meanElements, tleParameters: + fields.update((field.tag, field.text) for field in element) + yield fields + +_epoch0 = datetime(1949, 12, 31) +_to_radians = pi / 180.0 +_ndot_units = 1036800.0 / pi # See SGP4.cpp for details. + +def initialize(sat, fields): + epoch_datetime = datetime.strptime(fields['EPOCH'], '%Y-%m-%dT%H:%M:%S.%f') + epoch = (epoch_datetime - _epoch0).total_seconds() / 86400.0 + + argpo = float(fields['ARG_OF_PERICENTER']) * _to_radians + bstar = float(fields['BSTAR']) + ecco = float(fields['ECCENTRICITY']) + inclo = float(fields['INCLINATION']) * _to_radians + mo = float(fields['MEAN_ANOMALY']) * _to_radians + nddot = float(fields['MEAN_MOTION_DDOT']) + ndot = float(fields['MEAN_MOTION_DOT']) / _ndot_units + no_kozai = float(fields['MEAN_MOTION']) / 720.0 * pi + nodeo = float(fields['RA_OF_ASC_NODE']) * _to_radians + satnum = int(fields['NORAD_CAT_ID']) + + sat.sgp4init(WGS72, 'i', satnum, epoch, bstar, ndot, nddot, ecco, + argpo, inclo, mo, no_kozai, nodeo) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sgp4-2.12/sgp4/tests.py new/sgp4-2.13/sgp4/tests.py --- old/sgp4-2.12/sgp4/tests.py 2020-05-25 03:00:56.000000000 +0200 +++ new/sgp4-2.13/sgp4/tests.py 2020-10-15 01:36:35.000000000 +0200 @@ -6,18 +6,24 @@ from unittest import TestCase, main import datetime as dt +import platform import re import sys from doctest import DocTestSuite, ELLIPSIS from math import pi, isnan from pkgutil import get_data +try: + from io import StringIO +except ImportError: + from StringIO import StringIO + from sgp4.api import WGS72OLD, WGS72, WGS84, Satrec, jday, accelerated from sgp4.earth_gravity import wgs72 from sgp4.ext import invjday, newtonnu, rv2coe from sgp4.functions import days2mdhms, _day_of_year_to_month_day from sgp4.propagation import sgp4, sgp4init -from sgp4 import conveniences, io +from sgp4 import conveniences, io, omm from sgp4.exporter import export_tle import sgp4.model as model @@ -38,6 +44,7 @@ 'satnum': 5, 'operationmode': 'i', # Time + 'epochyr': 0, 'jdsatepoch': 2451722.5, # Orbit 'bstar': 2.8098e-05, @@ -51,7 +58,6 @@ 'nodeo': 6.08638547138321, } VANGUARD_EPOCH = 18441.7849506199999894 -VANGUARD_EPOCHDAYS = 179.78495062 # Handle deprecated assertRaisesRegexp, but allow its use Python 2.6 and 2.7 if sys.version_info[:2] == (2, 7) or sys.version_info[:2] == (2, 6): @@ -64,12 +70,10 @@ def test_satrec_built_with_twoline2rv(): sat = Satrec.twoline2rv(LINE1, LINE2) verify_vanguard_1(sat) - assertEqual(sat.epochdays, VANGUARD_EPOCHDAYS) def test_legacy_built_with_twoline2rv(): sat = io.twoline2rv(LINE1, LINE2, wgs72) verify_vanguard_1(sat, legacy=True) - assertEqual(sat.epochdays, VANGUARD_EPOCHDAYS) def test_satrec_initialized_with_sgp4init(): # epochyr and epochdays are not set by sgp4init @@ -232,7 +236,14 @@ sat.sgp4init(WGS84, 'i', VANGUARD_ATTRS['satnum'], VANGUARD_EPOCH, *args) assert_wgs84(sat) -GRAVITY_DIGITS = 12 if accelerated else 4 +GRAVITY_DIGITS = ( + # Why don't Python and C agree more closely? + 4 if not accelerated + # See https://github.com/conda-forge/sgp4-feedstock/pull/19 for details. + else 11 if platform.system() != 'Linux' + # Insist on very high precision on my Linux laptop. + else 12 +) def assert_wgs72old(sat): e, r, v = sat.sgp4_tsince(309.67110720001529) @@ -377,6 +388,7 @@ if legacy: attrs = attrs.copy() + del attrs['epochyr'] del attrs['jdsatepoch'] for name, value in attrs.items(): @@ -388,6 +400,7 @@ raise e if not legacy: + assertAlmostEqual(sat.epochdays, 179.78495062, delta=3e-14) assertAlmostEqual(sat.jdsatepochF, 0.78495062, delta=1e-13) def sgp4init_args(d): @@ -605,6 +618,73 @@ ) # ---------------------------------------------------------------------- +# NEW "OMM" FORMAT TESTS + + +# https://celestrak.com/satcat/tle.php?CATNR=5 +VANGUARD_TLE = """\ +VANGUARD 1 \n\ +1 00005U 58002B 20287.20333880 -.00000016 00000-0 -22483-4 0 9998 +2 00005 34.2443 225.5254 1845686 162.2516 205.2356 10.84869164218149 +""" + +# https://celestrak.com/NORAD/elements/gp.php?CATNR=00005&FORMAT=XML +VANGUARD_XML = """\ +<?xml version="1.0" encoding="UTF-8"?> +<ndm xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://sanaregistry.org/r/ndmxml/ndmxml-1.0-master.xsd"> +<omm id="CCSDS_OMM_VERS" version="2.0"> +<header><CREATION_DATE/><ORIGINATOR/></header><body><segment><metadata><OBJECT_NAME>VANGUARD 1</OBJECT_NAME><OBJECT_ID>1958-002B</OBJECT_ID><CENTER_NAME>EARTH</CENTER_NAME><REF_FRAME>TEME</REF_FRAME><TIME_SYSTEM>UTC</TIME_SYSTEM><MEAN_ELEMENT_THEORY>SGP4</MEAN_ELEMENT_THEORY></metadata><data><meanElements><EPOCH>2020-10-13T04:52:48.472320</EPOCH><MEAN_MOTION>10.84869164</MEAN_MOTION><ECCENTRICITY>.1845686</ECCENTRICITY><INCLINATION>34.2443</INCLINATION><RA_OF_ASC_NODE>225.5254</RA_OF_ASC_NODE><ARG_OF_PERICENTER>162.2516</ARG_OF_PERICENTER><MEAN_ANOMALY>205.2356</MEAN_ANOMALY></meanElements><tleParameters><EPHEMERIS_TYPE>0</EPHEMERIS_TYPE><CLASSIFICATION_TYPE>U</CLASSIFICATION_TYPE><NORAD_CAT_ID>5</NORAD_CAT_ID><ELEMENT_SET_NO>999</ELEMENT_SET_NO><REV_AT_EPOCH>21814</REV_AT_EPOCH><BSTAR>-.22483E-4</BSTAR><MEAN_MOTION_DOT>-1.6E-7</MEAN_MOTION_DOT><MEAN_MOTION_DDOT>0</MEAN_MOTION_DDOT></tleParameters></data></segment></body></omm> +</ndm> +""" + +# https://celestrak.com/NORAD/elements/gp.php?CATNR=00005&FORMAT=CSV +VANGUARD_CSV = """\ +OBJECT_NAME,OBJECT_ID,EPOCH,MEAN_MOTION,ECCENTRICITY,INCLINATION,RA_OF_ASC_NODE,ARG_OF_PERICENTER,MEAN_ANOMALY,EPHEMERIS_TYPE,CLASSIFICATION_TYPE,NORAD_CAT_ID,ELEMENT_SET_NO,REV_AT_EPOCH,BSTAR,MEAN_MOTION_DOT,MEAN_MOTION_DDOT +VANGUARD 1,1958-002B,2020-10-13T04:52:48.472320,10.84869164,.1845686,34.2443,225.5254,162.2516,205.2356,0,U,5,999,21814,-.22483E-4,-1.6E-7,0 +""" + +def test_omm_xml_matches_old_tle(): + line0, line1, line2 = VANGUARD_TLE.splitlines() + sat1 = Satrec.twoline2rv(line1, line2) + + fields = next(omm.parse_xml(StringIO(VANGUARD_XML))) + sat2 = Satrec() + omm.initialize(sat2, fields) + + assert_satellites_match(sat1, sat2) + +def test_omm_csv_matches_old_tle(): + line0, line1, line2 = VANGUARD_TLE.splitlines() + sat1 = Satrec.twoline2rv(line1, line2) + + fields = next(omm.parse_csv(StringIO(VANGUARD_CSV))) + sat2 = Satrec() + omm.initialize(sat2, fields) + + assert_satellites_match(sat1, sat2) + +def assert_satellites_match(sat1, sat2): + julian_fractions = {'epochdays', 'jdsatepochF'} + todo = {'classification', 'elnum', 'ephtype', 'intldesg', 'revnum', + 'whichconst'} + + for attr in dir(sat1): + if attr.startswith('_'): + continue + if attr in todo: + continue + value1 = getattr(sat1, attr, None) + if value1 is None: + continue + if callable(value1): + continue + value2 = getattr(sat2, attr) + if attr in julian_fractions: + value1 = round(value1, 10) + value2 = round(value2, 10) + assertEqual(value1, value2) + +# ---------------------------------------------------------------------- def load_tests(loader, tests, ignore): """Run our main documentation as a test, plus all test functions."""