sgp4


Namesgp4 JSON
Version 2.23 PyPI version JSON
download
home_pagehttps://github.com/brandon-rhodes/python-sgp4
SummaryTrack Earth satellites given TLE data, using up-to-date 2020 SGP4 routines.
upload_time2023-11-11 13:45:32
maintainer
docs_urlNone
authorBrandon Rhodes
requires_python
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
This package compiles the official C++ code from `Revisiting Spacetrack
Report #3`_ (AIAA 2006-6753) — specifically, the 2023 May 09 release
from David Vallado’s `Fundamentals of Astrodynamics and Applications`_
webpage — and uses it to compute the positions of satellites in Earth
orbit.  Satellite orbital elements can be loaded from either a legacy
TLE file or from a modern OMM element set, both of which you can fetch
from a site like `CelesTrak <https://celestrak.com/>`_.

.. _Revisiting Spacetrack Report #3: https://celestrak.org/publications/AIAA/2006-6753/

.. _Fundamentals of Astrodynamics and Applications: https://celestrak.org/software/vallado-sw.php

If your machine can’t install or compile the C++ code, then this package
falls back to using a slower pure-Python implementation of SGP4.  Tests
make sure that its positions **agree to within 0.1 mm** with the
standard version of the algorithm — an error far less than the
1–3 km/day by which satellites themselves deviate from the ideal orbits
described in TLE files.

An accelerated routine is available that, given a series of times and of
satellites, computes a whole array of output positions using a fast C++
loop.  See the “Array Acceleration” section below.

Note that the SGP4 propagator returns raw *x,y,z* Cartesian coordinates
in a “True Equator Mean Equinox” (TEME) reference frame that’s centered
on the Earth but does not rotate with it — an “Earth centered inertial”
(ECI) reference frame.  The SGP4 propagator itself does not implement
the math to convert these positions into more official ECI frames like
J2000 or the ICRS, nor into any Earth-centered Earth-fixed (ECEF) frames
like the ITRS, nor into latitudes and longitudes through an Earth
ellipsoid like WGS84.  For conversions into these other coordinate
frames, look for a comprehensive astronomy library, like the `Skyfield
<https://rhodesmill.org/skyfield/>`_ library that is built atop this one
(see the `section on Earth satellites
<https://rhodesmill.org/skyfield/earth-satellites.html>`_ in its
documentation).

Usage
-----

You will probably first want to to check whether your machine has
successfully installed the fast SGP4 C++ code, or is using the slow
Python version (in which case this value will be false):

>>> from sgp4.api import accelerated
>>> print(accelerated)
True

This library uses the same function names as the official C++ code, to
help users who are already familiar with SGP4 in other languages.  Here
is how to compute the x,y,z position and velocity for the International
Space Station at 20:42:00 on 2019 December 9:

>>> from sgp4.api import Satrec
>>>
>>> s = '1 25544U 98067A   19343.69339541  .00001764  00000-0  38792-4 0  9991'
>>> t = '2 25544  51.6439 211.2001 0007417  17.6667  85.6398 15.50103472202482'
>>> satellite = Satrec.twoline2rv(s, t)
>>>
>>> jd, fr = 2458826.5, 0.8625
>>> e, r, v = satellite.sgp4(jd, fr)
>>> e
0
>>> print(r)  # True Equator Mean Equinox position (km)
(-6088.92..., -936.13..., -2866.44...)
>>> print(v)  # True Equator Mean Equinox velocity (km/s)
(-1.525..., -5.538..., 5.068...)

As input, you can provide either:

* A simple floating-point Julian Date for ``jd`` and the value 0.0 for
  ``fr``, if you are happy with the precision of a 64-bit floating point
  number.  Note that modern Julian Dates are greater than 2,450,000
  which means that nearly half of the precision of a 64-bit float will
  be consumed by the whole part that specifies the day.  The remaining
  digits will provide a precision for the fraction of around 20.1 µs.
  This should be no problem for the accuracy of your result — satellite
  positions usually off by a few kilometers anyway, far less than a
  satellite moves in 20.1 µs — but if you run a solver that dives down
  into the microseconds while searching for a rising or setting time,
  the solver might be bothered by the 20.1 µs plateau between each jump
  in the satellite’s position.

* Or, you can provide a coarse date ``jd`` plus a very precise fraction
  ``fr`` that supplies the rest of the value.  The Julian Date for which
  the satellite position is computed is the sum of the two values.  One
  common practice is to provide the whole number as ``jd`` and the
  fraction as ``fr``; another is to have ``jd`` carry the fraction 0.5
  since UTC midnight occurs halfway through each Julian Date.  Either
  way, splitting the value allows a solver to run all the way down into
  the nanoseconds and still see SGP4 respond smoothly to tiny date
  adjustments with tiny changes in the resulting satellite position.

Here is how to intrepret the results:

* ``e`` will be a non-zero error code if the satellite position could
  not be computed for the given date.  You can ``from sgp4.api import
  SGP4_ERRORS`` to access a dictionary mapping error codes to error
  messages explaining what each code means.

* ``r`` measures the satellite position in **kilometers** from the
  center of the earth in the idiosyncratic True Equator Mean Equinox
  coordinate frame used by SGP4.

* ``v`` velocity is the rate at which the position is changing,
  expressed in **kilometers per second**.

If your application does not natively handle Julian dates, you can
compute ``jd`` and ``fr`` from calendar dates using ``jday()``.

>>> from sgp4.api import jday
>>> jd, fr = jday(2019, 12, 9, 20, 42, 0)
>>> jd
2458826.5
>>> fr
0.8625

Double-checking your TLE lines
------------------------------

Because TLE is an old punch-card fixed-width format, it’s very sensitive
to whether exactly the right number of spaces are positioned in exactly
the right columns.  If you suspect that your satellite elements aren’t
getting loaded correctly, try calling the slow pure-Python version of
``twoline2rv()``, which performs extra checks that the fast C++ doesn’t:

>>> from sgp4.earth_gravity import wgs72
>>> from sgp4.io import twoline2rv
>>> assert twoline2rv(s, t, wgs72)

Any TLE formatting errors will be raised as a ``ValueError``.

Using OMM elements instead of TLE
---------------------------------

The industry is migrating away from the original TLE format, because it
will soon run out of satellite numbers.

* Some TLE files now use a new “Alpha-5” convention that expands the
  range of satellite numbers by using an initial letter; for example,
  “E8493” means satellite 148493.  This library supports the Alpha-5
  convention and should return the correct integer in Python.

* Some authorities are now distributing satellite elements in an “OMM”
  Orbit Mean Elements Message format that replaces the TLE format.  You
  can learn about OMM in Dr. T.S. Kelso’s `“A New Way to Obtain GP Data”
  <https://celestrak.com/NORAD/documentation/gp-data-formats.php>`_ at
  the CelesTrak site.

You can already try out experimental support for OMM:

>>> from sgp4 import omm

Reading OMM data takes two steps, because OMM supports several different
text formats.  First, parse the input text to recover the field names
and values that it stores; second, build a Python satellite object from
those field values.  For example, to load OMM from XML:

>>> with open('sample_omm.xml') as f:
...     fields = next(omm.parse_xml(f))
>>> sat = Satrec()
>>> omm.initialize(sat, fields)

Or, to load OMM from CSV:

>>> with open('sample_omm.csv') as f:
...     fields = next(omm.parse_csv(f))
>>> sat = Satrec()
>>> omm.initialize(sat, fields)

Either way, the satellite object should wind up properly initialized and
ready to start producing positions.

If you are interested in saving satellite parameters using the new OMM
format, then read the section on “Export” below.

Epoch
-----

Over a given satellite’s lifetime, dozens or hundreds of different TLE
records will be produced as its orbit evolves.  Each TLE record
specifies the “epoch date” for which it is most accurate.  Typically a
TLE is only useful for a couple of weeks to either side of its epoch
date, beyond which its predictions become unreliable.

Satellite objects natively provide their epoch as a two-digit year and
then a fractional number of days into the year:

>>> satellite.epochyr
19
>>> satellite.epochdays
343.69339541

Because Sputnik was launched in 1957, satellite element sets will never
refer to an earlier year, so years 57 through 99 mean 1957–1999 while 0
through 56 mean 2000–2056.  The TLE format will presumably be obsolete
in 2057 and have to be upgraded to 4-digit years.

To turn the number of days and its fraction into a calendar date and
time, use the ``days2mdhms()`` function.

>>> from sgp4.api import days2mdhms
>>> month, day, hour, minute, second = days2mdhms(19, 343.69339541)
>>> month
12
>>> day
9
>>> hour
16
>>> minute
38
>>> second
29.363424

The SGP4 library also translates those two numbers into a Julian date
and fractional Julian date, since Julian dates are more commonly used in
astronomy.

>>> satellite.jdsatepoch
2458826.5
>>> satellite.jdsatepochF
0.69339541

Finally, a convenience function is available in the library if you need
the epoch date and time as Python ``datetime``.

>>> from sgp4.conveniences import sat_epoch_datetime
>>> sat_epoch_datetime(satellite)
datetime.datetime(2019, 12, 9, 16, 38, 29, 363423, tzinfo=UTC)

Array Acceleration
------------------

To avoid the expense of running a Python loop when you have many dates
and times for which you want a position, you can pass your Julian dates
as arrays.  The array routine is only faster if your machine has
successfully installed or compiled the SGP4 C++ code, so you might want
to check first:

>>> from sgp4.api import accelerated
>>> print(accelerated)
True

To call the array routine, make NumPy arrays for ``jd`` and ``fr`` that
are the same length:

>>> import numpy as np
>>> np.set_printoptions(precision=2)

>>> jd = np.array((2458826, 2458826, 2458826, 2458826))
>>> fr = np.array((0.0001, 0.0002, 0.0003, 0.0004))

>>> e, r, v = satellite.sgp4_array(jd, fr)

>>> print(e)
[0 0 0 0]
>>> print(r)
[[-3431.31  2620.15 -5252.97]
 [-3478.86  2575.14 -5243.87]
 [-3526.09  2529.89 -5234.28]
 [-3572.98  2484.41 -5224.19]]
>>> print(v)
[[-5.52 -5.19  1.02]
 [-5.49 -5.22  1.08]
 [-5.45 -5.25  1.14]
 [-5.41 -5.28  1.2 ]]

To avoid the expense of Python loops when you have many satellites and
dates, build a ``SatrecArray`` from several individual satellites.  Its
``sgp4()`` method will expect both ``jd`` and ``fr`` to be NumPy arrays,
so if you only have one date, be sure to provide NumPy arrays of length
one.  Here is a sample computation for 2 satellites and 4 dates:

>>> u = '1 20580U 90037B   19342.88042116  .00000361  00000-0  11007-4 0  9996'
>>> w = '2 20580  28.4682 146.6676 0002639 185.9222 322.7238 15.09309432427086'
>>> satellite2 = Satrec.twoline2rv(u, w)

>>> from sgp4.api import SatrecArray
>>> a = SatrecArray([satellite, satellite2])
>>> e, r, v = a.sgp4(jd, fr)

>>> np.set_printoptions(precision=2)
>>> print(e)
[[0 0 0 0]
 [0 0 0 0]]
>>> print(r)
[[[-3431.31  2620.15 -5252.97]
  [-3478.86  2575.14 -5243.87]
  [-3526.09  2529.89 -5234.28]
  [-3572.98  2484.41 -5224.19]]
<BLANKLINE>
 [[ 5781.85  2564.   -2798.22]
  [ 5749.36  2618.59 -2814.63]
  [ 5716.35  2672.94 -2830.78]
  [ 5682.83  2727.05 -2846.68]]]
>>> print(v)
[[[-5.52 -5.19  1.02]
  [-5.49 -5.22  1.08]
  [-5.45 -5.25  1.14]
  [-5.41 -5.28  1.2 ]]
<BLANKLINE>
 [[-3.73  6.33 -1.91]
  [-3.79  6.3  -1.88]
  [-3.85  6.28 -1.85]
  [-3.91  6.25 -1.83]]]

Export
------

If you have a ``Satrec`` you want to share with friends or persist to a
file, there’s an export routine that will turn it back into a TLE:

>>> from sgp4 import exporter
>>> line1, line2 = exporter.export_tle(satellite)
>>> line1
'1 25544U 98067A   19343.69339541  .00001764  00000-0  38792-4 0  9991'
>>> line2
'2 25544  51.6439 211.2001 0007417  17.6667  85.6398 15.50103472202482'

Happily, these are exactly the two TLE lines that we used to create this
satellite object:

>>> (s == line1) and (t == line2)
True

Another export routine is available that produces the fields defined by
the new OMM format (see the “OMM” section above):

>>> from pprint import pprint
>>> fields = exporter.export_omm(satellite, 'ISS (ZARYA)')
>>> pprint(fields)
{'ARG_OF_PERICENTER': 17.6667,
 'BSTAR': 3.8792e-05,
 'CENTER_NAME': 'EARTH',
 'CLASSIFICATION_TYPE': 'U',
 'ECCENTRICITY': 0.0007417,
 'ELEMENT_SET_NO': 999,
 'EPHEMERIS_TYPE': 0,
 'EPOCH': '2019-12-09T16:38:29.363423',
 'INCLINATION': 51.6439,
 'MEAN_ANOMALY': 85.6398,
 'MEAN_ELEMENT_THEORY': 'SGP4',
 'MEAN_MOTION': 15.501034720000002,
 'MEAN_MOTION_DDOT': 0.0,
 'MEAN_MOTION_DOT': 1.764e-05,
 'NORAD_CAT_ID': 25544,
 'OBJECT_ID': '1998-067A',
 'OBJECT_NAME': 'ISS (ZARYA)',
 'RA_OF_ASC_NODE': 211.2001,
 'REF_FRAME': 'TEME',
 'REV_AT_EPOCH': 20248,
 'TIME_SYSTEM': 'UTC'}

Gravity
-------

The SGP4 algorithm operates atop a set of constants specifying how
strong the Earth’s gravity is.  The most recent official paper on SGP4
(see below) specifies that “We use WGS-72 as the default value”, so this
Python module uses the same default.  But in case you want to use either
the old legacy version of the WGS-72 constants, or else the non-standard
but more modern WGS-84 constants, the ``twoline2rv()`` constructor takes
an optional argument:

>>> from sgp4.api import WGS72OLD, WGS72, WGS84
>>> satellite3 = Satrec.twoline2rv(s, t, WGS84)

You will in general get less accurate results if you choose WGS-84.
Even though it reflects more recent and accurate measures of the Earth,
satellite TLEs across the industry are most likely generated with WGS-72
as their basis.  The positions you generate will better agree with the
real positions of each satellite if you use the same underlying gravity
constants as were used to generate the TLE.

Providing your own elements
---------------------------

If instead of parsing a TLE you want to specify orbital elements
directly, you can pass them as floating point numbers to a satellite
object’s ``sgp4init()`` method.  For example, here’s how to build the
same International Space Station orbit that we loaded from a TLE in the
first code example above:

>>> satellite2 = Satrec()
>>> satellite2.sgp4init(
...     WGS72,                # gravity model
...     'i',                  # 'a' = old AFSPC mode, 'i' = improved mode
...     25544,                # satnum: Satellite number
...     25545.69339541,       # epoch: days since 1949 December 31 00:00 UT
...     3.8792e-05,           # bstar: drag coefficient (1/earth radii)
...     0.0,                  # ndot: ballistic coefficient (radians/minute^2)
...     0.0,                  # nddot: mean motion 2nd derivative (radians/minute^3)
...     0.0007417,            # ecco: eccentricity
...     0.3083420829620822,   # argpo: argument of perigee (radians)
...     0.9013560935706996,   # inclo: inclination (radians)
...     1.4946964807494398,   # mo: mean anomaly (radians)
...     0.06763602333248933,  # no_kozai: mean motion (radians/minute)
...     3.686137125541276,    # nodeo: R.A. of ascending node (radians)
... )

These numbers don’t look the same as the numbers in the TLE, because the
underlying ``sgp4init()`` routine uses different units: radians rather
than degrees.  But this is the same orbit and will produce the same
positions.

Note that ``ndot`` and ``nddot`` are ignored by the SGP4 propagator, so
you can leave them ``0.0`` without any effect on the resulting satellite
positions.  But they do at least get saved to the satellite object, and
written out if you write the parameters to a TLE or OMM file (see the
“Export” section, above).

To compute the “epoch” argument, take the epoch’s Julian date and
subtract 2433281.5 days.

While the underlying ``sgp4init()`` routine leaves the attributes
``epochyr``, ``epochdays``, ``jdsatepoch``, and ``jdsatepochF`` unset,
this library goes ahead and sets them anyway for you, using the epoch
you provided.

See the next section for the complete list of attributes that are
available from the satellite record once it has been initialized.

Attributes
----------

There are several dozen ``Satrec`` attributes that expose data from the
underlying C++ SGP4 record.  They fall into the following categories.

*Identification*

These are copied directly from the TLE record but aren’t used by the
propagation math.

| ``satnum_str`` — Satellite number, as a 5-character string.
| ``satnum`` — Satellite number, converted to an integer.
| ``classification`` — ``'U'``, ``'C'``, or ``'S'``
  indicating the element set is Unclassified, Classified, or Secret.
| ``ephtype`` — Integer “ephemeris type”, used internally by space
  agencies to mark element sets that are not ready for publication;
  this field should always be ``0`` in published TLEs.
| ``elnum`` — Element set number.
| ``revnum`` — Satellite’s revolution number at the moment of the epoch,
  presumably counting from 1 following launch.

*Orbital Elements*

These are the orbital parameters, copied verbatim from the text of the
TLE record.  They describe the orbit at the moment of the TLE’s epoch
and so remain constant even as the satellite record is used over and
over again to propagate positions for different times.

| ``epochyr`` — Epoch date: the last two digits of the year.
| ``epochdays`` — Epoch date: the number of days into the year,
  including a decimal fraction for the UTC time of day.
| ``ndot`` — First time derivative of the mean motion
  (loaded from the TLE, but otherwise ignored).
| ``nddot`` — Second time derivative of the mean motion
  (loaded from the TLE, but otherwise ignored).
| ``bstar`` — Ballistic drag coefficient B* (1/earth radii).
| ``inclo`` — Inclination (radians).
| ``nodeo`` — Right ascension of ascending node (radians).
| ``ecco`` — Eccentricity.
| ``argpo`` — Argument of perigee (radians).
| ``mo`` — Mean anomaly (radians).
| ``no_kozai`` — Mean motion (radians/minute).
| ``no`` — Alias for ``no_kozai``, for compatibility with old code.

You can also access the epoch as a Julian date:

| ``jdsatepoch`` — Whole part of the epoch’s Julian date.
| ``jdsatepochF`` — Fractional part of the epoch’s Julian date.

*Computed Orbit Properties*

These are computed when the satellite is first loaded,
as a convenience for callers who might be interested in them.
They aren’t used by the SGP4 propagator itself.

| ``a`` — Semi-major axis (earth radii).
| ``altp`` — Altitude of the satellite at perigee
  (earth radii, assuming a spherical Earth).
| ``alta`` — Altitude of the satellite at apogee
  (earth radii, assuming a spherical Earth).
| ``argpdot`` — Rate at which the argument of perigee is changing
  (radians/minute).
| ``gsto`` — Greenwich Sidereal Time at the satellite’s epoch (radians).
| ``mdot`` — Rate at which the mean anomaly is changing (radians/minute)
| ``nodedot`` — Rate at which the right ascension of the ascending node
  is changing (radians/minute).

*Propagator Mode*

| ``operationmode`` — A single character that directs SGP4
  to either operate in its modern ``'i'`` improved mode
  or in its legacy ``'a'`` AFSPC mode.
| ``method`` — A single character, chosen automatically
  when the orbital elements were loaded, that indicates whether SGP4
  has chosen to use its built-in ``'n'`` Near Earth
  or ``'d'`` Deep Space mode for this satellite.

*Result of Most Recent Propagation*

| ``t`` —
  The time you gave when you most recently asked SGP4
  to compute this satellite’s position,
  measured in minutes before (negative) or after (positive)
  the satellite’s epoch.
| ``error`` —
  Error code produced by the most recent SGP4 propagation
  you performed with this element set.

The possible ``error`` codes are:

0. No error.
1. Mean eccentricity is outside the range 0 ≤ e < 1.
2. Mean motion has fallen below zero.
3. Perturbed eccentricity is outside the range 0 ≤ e ≤ 1.
4. Length of the orbit’s semi-latus rectum has fallen below zero.
5. (No longer used.)
6. Orbit has decayed: the computed position is underground.
   (The position is still returned, in case the vector is helpful
   to software that might be searching for the moment of re-entry.)

*Mean Elements From Most Recent Propagation*

Partway through each propagation, the SGP4 routine saves a set of
“singly averaged mean elements” that describe the orbit’s shape at the
moment for which a position is being computed.  They are averaged with
respect to the mean anomaly and include the effects of secular gravity,
atmospheric drag, and — in Deep Space mode — of those pertubations from
the Sun and Moon that SGP4 averages over an entire revolution of each of
those bodies.  They omit both the shorter-term and longer-term periodic
pertubations from the Sun and Moon that SGP4 applies right before
computing each position.

| ``am`` — Average semi-major axis (earth radii).
| ``em`` — Average eccentricity.
| ``im`` — Average inclination (radians).
| ``Om`` — Average right ascension of ascending node (radians).
| ``om`` — Average argument of perigee (radians).
| ``mm`` — Average mean anomaly (radians).
| ``nm`` — Average mean motion (radians/minute).

*Gravity Model Parameters*

When the satellite record is initialized, your choice of gravity model
results in a slate of eight constants being copied in:

| ``tumin`` — Minutes in one “time unit”.
| ``xke`` — The reciprocal of ``tumin``.
| ``mu`` — Earth’s gravitational parameter (km³/s²).
| ``radiusearthkm`` — Radius of the earth (km).
| ``j2``, ``j3``, ``j4`` — Un-normalized zonal harmonic values J₂, J₃, and J₄.
| ``j3oj2`` — The ratio J₃/J₂.

Printing satellite attributes
-----------------------------

If you want to print out a satellite, this library provides a convenient
“attribute dump” routine that takes a satellite and generates lines that
list its attributes::

    from sys import stdout
    from sgp4.conveniences import dump_satrec

    stdout.writelines(dump_satrec(satellite))

If you want to compare two satellites, then simply pass a second
argument; the second satellite’s attributes will be printed in a second
column next to those of the first. ::

    stdout.writelines(dump_satrec(satellite, satellite2))

Validation against the official algorithm
-----------------------------------------

This implementation passes all of the automated tests in the August 2010
release of the reference implementation of SGP4 by Vallado et al., who
originally published their revision of SGP4 in 2006:

    Vallado, David A., Paul Crawford, Richard Hujsak, and T.S. Kelso,
    “Revisiting Spacetrack Report #3,” presented at the AIAA/AAS
    Astrodynamics Specialist Conference, Keystone, CO, 2006 August
    21–24.

If you would like to review the paper, it is `available online
<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
<https://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753.zip>`_.

For developers
--------------

Developers can check out this full project from GitHub:

https://github.com/brandon-rhodes/python-sgp4

To run its unit tests, install Python 2, Python 3, and the ``tox``
testing tool.  The tests runing in Python 2 will exercise the fallback
pure-Python version of the routines, while Python 3 exercises the fast
new C++ accelerated code::

    cd python-sgp4
    tox

Legacy API
----------

Before this library pivoted to wrapping Vallado's official C++ code and
was operating in pure Python only, it had a slightly quirkier API, which
is still supported for compatibility with older clients.  You can learn
about it by reading the documentation from version 1.4 or earlier:

https://pypi.org/project/sgp4/1.4/

Changelog
---------

2023-10-01 — 2.23

* Tweaked tests to resolve breakage introduced by Python 3.12.

2023-04-27 — 2.22

* Added a ``satnum_str`` attribute, exposing the fact that the C++ now
  stores the satellite number as a string; and check that ``satnum`` is
  never greater than 339999.

* Fixed the units of the ``nddot`` attribute when the value is loaded
  from an OMM record.  (Since the TLE computation itself ignores this
  attribute, this did not affect any satellite positions.)

* Enhanced the fallback Python version of ``twoline2rv()`` to verify
  that TLE lines are ASCII, and added documentation using it to
  double-check TLEs that might suffer from non-ASCII characters.

* If the user doesn’t set a satellite’s ``classification``, it now
  defaults to ``'U'`` for ‘unclassified’.

2022-04-06 — 2.21

* Added ``dump_satrec()`` to the ``sgp4.conveniences`` module.

* Fixed the ``Satrec`` attribute ``.error``, which was previously
  building a nonsense integer from the wrong data in memory.

* Removed ``.whichconst`` from Python ``Satrec``, to help users avoid
  writing code that will break when the C++ extension is available.

2021-07-01 — 2.20

* Taught ``sgp4init()`` to round both ``epochdays`` and ``jdsatepochF``
  to the same 8 decimal places used for the date fraction in a TLE, if
  the user-supplied ``epoch`` itself has 8 or fewer digits behind the
  decimal point.  This should make it easier to build satellites that
  round-trip to TLE format with perfect accuracy.

* Fixed how ``export_tle()`` formats the BSTAR field when its value, if
  written in scientific notation, has a positive exponent.

* Fixed the ``epochyr`` assigned by ``sgp4init()`` so years before 2000
  have two digits instead of three (for example, so that 1980 produces
  an ``epochyr`` of 80 instead of 980).

2021-04-22 — 2.19

* Extended the documentation on the Python Package Index and in the
  module docstring so it lists every ``Satrec`` attribute that this
  library exposes; even the more obscure ones might be useful to folks
  working to analyze satellite orbits.

2021-03-08 — 2.18

* If a TLE satellite number lacks the required 5 digits,
  ``twoline2rv()`` now gives the underlying C++ library a little help so
  it can still parse the classification and international designator
  correctly.

* The ``Satrec`` attributes ``jdsatepoch``, ``jdsatepochF``,
  ``epochyr``, and ``epochdays`` are now writeable, so users can adjust
  their values manually — which should make up for the fact that the
  ``sgp4init()`` method can’t set them with full floating point
  precision.

| 2021-02-17 — 2.17 — Fixed where in the output array the ``sgp4_array()`` method writes NaN values when an SGP4 propagation fails.
| 2021-02-12 — 2.16 — Fixed ``days2mdhms()`` rounding to always match TLE epoch.
| 2021-01-08 — 2.15 — Fixed parsing of the ``satnum`` TLE field in the Python fallback code, when the field has a leading space; added OMM export routine.
| 2020-12-16 — 2.14 — New data formats: added OMM message support for both XML and CSV, and added support for the new Alpha-5 extension to TLE files.
| 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.
| 2020-05-21 — 2.9 — Added ``sat_epoch_datetime()``, expanded documentation around converting a satellite epoch to a date and time, and started rounding the epoch to exactly the digits provided in the TLE; and removed the ``Satrec.epoch`` attribute from Python fallback code to better match the C++ version.
| 2020-05-07 — 2.8 — New function ``jday_datetime()`` is now available in the ``sgp4.conveniences`` module, thanks to Egemen Imre.
| 2020-04-24 — 2.7 — New method ``sgp4init()`` (thank you, Chris Lewicki!) is available.
| 2020-04-20 — 2.6 — New routine ``export_tle()`` (thank you, Egemen Imre!) is available. Improved how the accelerated C++ backend parses the ``intldesg`` string and the ``revnum`` integer.
| 2020-03-22 — 2.5 — Gave the new accelerated ``twoline2rv()`` an optional argument that lets the user choose a non-standard set of gravity constants.
| 2020-02-25 — 2.4 — Improved the ``jday()`` docstring; made the old legacy Python resilient if the day of the month is out-of-range (past the end of the month) in a TLE; and Mark Rutten fixed the C++ so it compiles on Windows!
| 2020-02-04 — 2.3 — Removed experimental code that caused performance problems for users with Numba installed.
| 2020-02-02 — 2.2 — A second release on Palindrome Day: fix the Satrec ``.epochyr`` attribute so it behaves the same way in Python as it does in the official C library, where it is only the last 2 digits of the year; and make ``.no`` available in the Python fallback case as well.
| 2020-02-02 — 2.1 — Add vectorized array method to Satrec object; add ``.no`` attribute to new Satrec object to support old code that has not migrated to the new name ``.no_kozai``; gave Python wrapper classes ``__slots__`` to avoid the expense of a per-object attribute dictionary.
| 2020-01-30 — 2.0 — Rewrite API to use genuine Vallado C++ code on those systems where it can be compiled; add accelerated vectorized array interface; make ``gstime()`` a public function; clarify format error message.
| 2015-01-15 — 1.4 — Display detailed help when TLE input does not match format.
| 2014-06-26 — 1.3 — Return ``(NaN,NaN,NaN)`` vectors on error and set ``.error_message``
| 2013-11-29 — 1.2 — Made ``epochyr`` 4 digits; add ``datetime`` for ``.epoch``
| 2012-11-22 — 1.1 — Python 3 compatibility; more documentation
| 2012-08-27 — 1.0 — Initial release


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/brandon-rhodes/python-sgp4",
    "name": "sgp4",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "Brandon Rhodes",
    "author_email": "brandon@rhodesmill.org",
    "download_url": "https://files.pythonhosted.org/packages/14/c2/ed46e67105a95acf4f06e2811f4381198a5acef57a960d98a74011a797cc/sgp4-2.23.tar.gz",
    "platform": null,
    "description": "\nThis package compiles the official C++ code from `Revisiting Spacetrack\nReport #3`_ (AIAA 2006-6753) \u2014 specifically, the 2023 May\u00a009 release\nfrom David Vallado\u2019s `Fundamentals of Astrodynamics and Applications`_\nwebpage \u2014 and uses it to compute the positions of satellites in Earth\norbit.  Satellite orbital elements can be loaded from either a legacy\nTLE file or from a modern OMM element set, both of which you can fetch\nfrom a site like `CelesTrak <https://celestrak.com/>`_.\n\n.. _Revisiting Spacetrack Report #3: https://celestrak.org/publications/AIAA/2006-6753/\n\n.. _Fundamentals of Astrodynamics and Applications: https://celestrak.org/software/vallado-sw.php\n\nIf your machine can\u2019t install or compile the C++ code, then this package\nfalls back to using a slower pure-Python implementation of SGP4.  Tests\nmake sure that its positions **agree to within 0.1\u00a0mm** with the\nstandard version of the algorithm \u2014 an error far less than the\n1\u20133\u00a0km/day by which satellites themselves deviate from the ideal orbits\ndescribed in TLE files.\n\nAn accelerated routine is available that, given a series of times and of\nsatellites, computes a whole array of output positions using a fast C++\nloop.  See the \u201cArray Acceleration\u201d section below.\n\nNote that the SGP4 propagator returns raw *x,y,z* Cartesian coordinates\nin a \u201cTrue Equator Mean Equinox\u201d (TEME) reference frame that\u2019s centered\non the Earth but does not rotate with it \u2014 an \u201cEarth centered inertial\u201d\n(ECI) reference frame.  The SGP4 propagator itself does not implement\nthe math to convert these positions into more official ECI frames like\nJ2000 or the ICRS, nor into any Earth-centered Earth-fixed (ECEF) frames\nlike the ITRS, nor into latitudes and longitudes through an Earth\nellipsoid like WGS84.  For conversions into these other coordinate\nframes, look for a comprehensive astronomy library, like the `Skyfield\n<https://rhodesmill.org/skyfield/>`_ library that is built atop this one\n(see the `section on Earth satellites\n<https://rhodesmill.org/skyfield/earth-satellites.html>`_ in its\ndocumentation).\n\nUsage\n-----\n\nYou will probably first want to to check whether your machine has\nsuccessfully installed the fast SGP4 C++ code, or is using the slow\nPython version (in which case this value will be false):\n\n>>> from sgp4.api import accelerated\n>>> print(accelerated)\nTrue\n\nThis library uses the same function names as the official C++ code, to\nhelp users who are already familiar with SGP4 in other languages.  Here\nis how to compute the x,y,z position and velocity for the International\nSpace Station at 20:42:00 on 2019\u00a0December\u00a09:\n\n>>> from sgp4.api import Satrec\n>>>\n>>> s = '1 25544U 98067A   19343.69339541  .00001764  00000-0  38792-4 0  9991'\n>>> t = '2 25544  51.6439 211.2001 0007417  17.6667  85.6398 15.50103472202482'\n>>> satellite = Satrec.twoline2rv(s, t)\n>>>\n>>> jd, fr = 2458826.5, 0.8625\n>>> e, r, v = satellite.sgp4(jd, fr)\n>>> e\n0\n>>> print(r)  # True Equator Mean Equinox position (km)\n(-6088.92..., -936.13..., -2866.44...)\n>>> print(v)  # True Equator Mean Equinox velocity (km/s)\n(-1.525..., -5.538..., 5.068...)\n\nAs input, you can provide either:\n\n* A simple floating-point Julian Date for ``jd`` and the value 0.0 for\n  ``fr``, if you are happy with the precision of a 64-bit floating point\n  number.  Note that modern Julian Dates are greater than 2,450,000\n  which means that nearly half of the precision of a 64-bit float will\n  be consumed by the whole part that specifies the day.  The remaining\n  digits will provide a precision for the fraction of around 20.1\u00a0\u00b5s.\n  This should be no problem for the accuracy of your result \u2014 satellite\n  positions usually off by a few kilometers anyway, far less than a\n  satellite moves in 20.1\u00a0\u00b5s \u2014 but if you run a solver that dives down\n  into the microseconds while searching for a rising or setting time,\n  the solver might be bothered by the 20.1\u00a0\u00b5s plateau between each jump\n  in the satellite\u2019s position.\n\n* Or, you can provide a coarse date ``jd`` plus a very precise fraction\n  ``fr`` that supplies the rest of the value.  The Julian Date for which\n  the satellite position is computed is the sum of the two values.  One\n  common practice is to provide the whole number as ``jd`` and the\n  fraction as ``fr``; another is to have ``jd`` carry the fraction 0.5\n  since UTC midnight occurs halfway through each Julian Date.  Either\n  way, splitting the value allows a solver to run all the way down into\n  the nanoseconds and still see SGP4 respond smoothly to tiny date\n  adjustments with tiny changes in the resulting satellite position.\n\nHere is how to intrepret the results:\n\n* ``e`` will be a non-zero error code if the satellite position could\n  not be computed for the given date.  You can ``from sgp4.api import\n  SGP4_ERRORS`` to access a dictionary mapping error codes to error\n  messages explaining what each code means.\n\n* ``r`` measures the satellite position in **kilometers** from the\n  center of the earth in the idiosyncratic True Equator Mean Equinox\n  coordinate frame used by SGP4.\n\n* ``v`` velocity is the rate at which the position is changing,\n  expressed in **kilometers per second**.\n\nIf your application does not natively handle Julian dates, you can\ncompute ``jd`` and ``fr`` from calendar dates using ``jday()``.\n\n>>> from sgp4.api import jday\n>>> jd, fr = jday(2019, 12, 9, 20, 42, 0)\n>>> jd\n2458826.5\n>>> fr\n0.8625\n\nDouble-checking your TLE lines\n------------------------------\n\nBecause TLE is an old punch-card fixed-width format, it\u2019s very sensitive\nto whether exactly the right number of spaces are positioned in exactly\nthe right columns.  If you suspect that your satellite elements aren\u2019t\ngetting loaded correctly, try calling the slow pure-Python version of\n``twoline2rv()``, which performs extra checks that the fast C++ doesn\u2019t:\n\n>>> from sgp4.earth_gravity import wgs72\n>>> from sgp4.io import twoline2rv\n>>> assert twoline2rv(s, t, wgs72)\n\nAny TLE formatting errors will be raised as a ``ValueError``.\n\nUsing OMM elements instead of TLE\n---------------------------------\n\nThe industry is migrating away from the original TLE format, because it\nwill soon run out of satellite numbers.\n\n* Some TLE files now use a new \u201cAlpha-5\u201d convention that expands the\n  range of satellite numbers by using an initial letter; for example,\n  \u201cE8493\u201d means satellite 148493.  This library supports the Alpha-5\n  convention and should return the correct integer in Python.\n\n* Some authorities are now distributing satellite elements in an \u201cOMM\u201d\n  Orbit Mean Elements Message format that replaces the TLE format.  You\n  can learn about OMM in Dr.\u00a0T.S. Kelso\u2019s `\u201cA New Way to Obtain GP Data\u201d\n  <https://celestrak.com/NORAD/documentation/gp-data-formats.php>`_ at\n  the CelesTrak site.\n\nYou can already try out experimental support for OMM:\n\n>>> from sgp4 import omm\n\nReading OMM data takes two steps, because OMM supports several different\ntext formats.  First, parse the input text to recover the field names\nand values that it stores; second, build a Python satellite object from\nthose field values.  For example, to load OMM from XML:\n\n>>> with open('sample_omm.xml') as f:\n...     fields = next(omm.parse_xml(f))\n>>> sat = Satrec()\n>>> omm.initialize(sat, fields)\n\nOr, to load OMM from CSV:\n\n>>> with open('sample_omm.csv') as f:\n...     fields = next(omm.parse_csv(f))\n>>> sat = Satrec()\n>>> omm.initialize(sat, fields)\n\nEither way, the satellite object should wind up properly initialized and\nready to start producing positions.\n\nIf you are interested in saving satellite parameters using the new OMM\nformat, then read the section on \u201cExport\u201d below.\n\nEpoch\n-----\n\nOver a given satellite\u2019s lifetime, dozens or hundreds of different TLE\nrecords will be produced as its orbit evolves.  Each TLE record\nspecifies the \u201cepoch date\u201d for which it is most accurate.  Typically a\nTLE is only useful for a couple of weeks to either side of its epoch\ndate, beyond which its predictions become unreliable.\n\nSatellite objects natively provide their epoch as a two-digit year and\nthen a fractional number of days into the year:\n\n>>> satellite.epochyr\n19\n>>> satellite.epochdays\n343.69339541\n\nBecause Sputnik was launched in 1957, satellite element sets will never\nrefer to an earlier year, so years 57 through 99 mean 1957\u20131999 while 0\nthrough 56 mean 2000\u20132056.  The TLE format will presumably be obsolete\nin 2057 and have to be upgraded to 4-digit years.\n\nTo turn the number of days and its fraction into a calendar date and\ntime, use the ``days2mdhms()`` function.\n\n>>> from sgp4.api import days2mdhms\n>>> month, day, hour, minute, second = days2mdhms(19, 343.69339541)\n>>> month\n12\n>>> day\n9\n>>> hour\n16\n>>> minute\n38\n>>> second\n29.363424\n\nThe SGP4 library also translates those two numbers into a Julian date\nand fractional Julian date, since Julian dates are more commonly used in\nastronomy.\n\n>>> satellite.jdsatepoch\n2458826.5\n>>> satellite.jdsatepochF\n0.69339541\n\nFinally, a convenience function is available in the library if you need\nthe epoch date and time as Python ``datetime``.\n\n>>> from sgp4.conveniences import sat_epoch_datetime\n>>> sat_epoch_datetime(satellite)\ndatetime.datetime(2019, 12, 9, 16, 38, 29, 363423, tzinfo=UTC)\n\nArray Acceleration\n------------------\n\nTo avoid the expense of running a Python loop when you have many dates\nand times for which you want a position, you can pass your Julian dates\nas arrays.  The array routine is only faster if your machine has\nsuccessfully installed or compiled the SGP4 C++ code, so you might want\nto check first:\n\n>>> from sgp4.api import accelerated\n>>> print(accelerated)\nTrue\n\nTo call the array routine, make NumPy arrays for ``jd`` and ``fr`` that\nare the same length:\n\n>>> import numpy as np\n>>> np.set_printoptions(precision=2)\n\n>>> jd = np.array((2458826, 2458826, 2458826, 2458826))\n>>> fr = np.array((0.0001, 0.0002, 0.0003, 0.0004))\n\n>>> e, r, v = satellite.sgp4_array(jd, fr)\n\n>>> print(e)\n[0 0 0 0]\n>>> print(r)\n[[-3431.31  2620.15 -5252.97]\n [-3478.86  2575.14 -5243.87]\n [-3526.09  2529.89 -5234.28]\n [-3572.98  2484.41 -5224.19]]\n>>> print(v)\n[[-5.52 -5.19  1.02]\n [-5.49 -5.22  1.08]\n [-5.45 -5.25  1.14]\n [-5.41 -5.28  1.2 ]]\n\nTo avoid the expense of Python loops when you have many satellites and\ndates, build a ``SatrecArray`` from several individual satellites.  Its\n``sgp4()`` method will expect both ``jd`` and ``fr`` to be NumPy arrays,\nso if you only have one date, be sure to provide NumPy arrays of length\none.  Here is a sample computation for 2 satellites and 4 dates:\n\n>>> u = '1 20580U 90037B   19342.88042116  .00000361  00000-0  11007-4 0  9996'\n>>> w = '2 20580  28.4682 146.6676 0002639 185.9222 322.7238 15.09309432427086'\n>>> satellite2 = Satrec.twoline2rv(u, w)\n\n>>> from sgp4.api import SatrecArray\n>>> a = SatrecArray([satellite, satellite2])\n>>> e, r, v = a.sgp4(jd, fr)\n\n>>> np.set_printoptions(precision=2)\n>>> print(e)\n[[0 0 0 0]\n [0 0 0 0]]\n>>> print(r)\n[[[-3431.31  2620.15 -5252.97]\n  [-3478.86  2575.14 -5243.87]\n  [-3526.09  2529.89 -5234.28]\n  [-3572.98  2484.41 -5224.19]]\n<BLANKLINE>\n [[ 5781.85  2564.   -2798.22]\n  [ 5749.36  2618.59 -2814.63]\n  [ 5716.35  2672.94 -2830.78]\n  [ 5682.83  2727.05 -2846.68]]]\n>>> print(v)\n[[[-5.52 -5.19  1.02]\n  [-5.49 -5.22  1.08]\n  [-5.45 -5.25  1.14]\n  [-5.41 -5.28  1.2 ]]\n<BLANKLINE>\n [[-3.73  6.33 -1.91]\n  [-3.79  6.3  -1.88]\n  [-3.85  6.28 -1.85]\n  [-3.91  6.25 -1.83]]]\n\nExport\n------\n\nIf you have a ``Satrec`` you want to share with friends or persist to a\nfile, there\u2019s an export routine that will turn it back into a TLE:\n\n>>> from sgp4 import exporter\n>>> line1, line2 = exporter.export_tle(satellite)\n>>> line1\n'1 25544U 98067A   19343.69339541  .00001764  00000-0  38792-4 0  9991'\n>>> line2\n'2 25544  51.6439 211.2001 0007417  17.6667  85.6398 15.50103472202482'\n\nHappily, these are exactly the two TLE lines that we used to create this\nsatellite object:\n\n>>> (s == line1) and (t == line2)\nTrue\n\nAnother export routine is available that produces the fields defined by\nthe new OMM format (see the \u201cOMM\u201d section above):\n\n>>> from pprint import pprint\n>>> fields = exporter.export_omm(satellite, 'ISS (ZARYA)')\n>>> pprint(fields)\n{'ARG_OF_PERICENTER': 17.6667,\n 'BSTAR': 3.8792e-05,\n 'CENTER_NAME': 'EARTH',\n 'CLASSIFICATION_TYPE': 'U',\n 'ECCENTRICITY': 0.0007417,\n 'ELEMENT_SET_NO': 999,\n 'EPHEMERIS_TYPE': 0,\n 'EPOCH': '2019-12-09T16:38:29.363423',\n 'INCLINATION': 51.6439,\n 'MEAN_ANOMALY': 85.6398,\n 'MEAN_ELEMENT_THEORY': 'SGP4',\n 'MEAN_MOTION': 15.501034720000002,\n 'MEAN_MOTION_DDOT': 0.0,\n 'MEAN_MOTION_DOT': 1.764e-05,\n 'NORAD_CAT_ID': 25544,\n 'OBJECT_ID': '1998-067A',\n 'OBJECT_NAME': 'ISS (ZARYA)',\n 'RA_OF_ASC_NODE': 211.2001,\n 'REF_FRAME': 'TEME',\n 'REV_AT_EPOCH': 20248,\n 'TIME_SYSTEM': 'UTC'}\n\nGravity\n-------\n\nThe SGP4 algorithm operates atop a set of constants specifying how\nstrong the Earth\u2019s gravity is.  The most recent official paper on SGP4\n(see below) specifies that \u201cWe use WGS-72 as the default value\u201d, so this\nPython module uses the same default.  But in case you want to use either\nthe old legacy version of the WGS-72 constants, or else the non-standard\nbut more modern WGS-84 constants, the ``twoline2rv()`` constructor takes\nan optional argument:\n\n>>> from sgp4.api import WGS72OLD, WGS72, WGS84\n>>> satellite3 = Satrec.twoline2rv(s, t, WGS84)\n\nYou will in general get less accurate results if you choose WGS-84.\nEven though it reflects more recent and accurate measures of the Earth,\nsatellite TLEs across the industry are most likely generated with WGS-72\nas their basis.  The positions you generate will better agree with the\nreal positions of each satellite if you use the same underlying gravity\nconstants as were used to generate the TLE.\n\nProviding your own elements\n---------------------------\n\nIf instead of parsing a TLE you want to specify orbital elements\ndirectly, you can pass them as floating point numbers to a satellite\nobject\u2019s ``sgp4init()`` method.  For example, here\u2019s how to build the\nsame International Space Station orbit that we loaded from a TLE in the\nfirst code example above:\n\n>>> satellite2 = Satrec()\n>>> satellite2.sgp4init(\n...     WGS72,                # gravity model\n...     'i',                  # 'a' = old AFSPC mode, 'i' = improved mode\n...     25544,                # satnum: Satellite number\n...     25545.69339541,       # epoch: days since 1949 December 31 00:00 UT\n...     3.8792e-05,           # bstar: drag coefficient (1/earth radii)\n...     0.0,                  # ndot: ballistic coefficient (radians/minute^2)\n...     0.0,                  # nddot: mean motion 2nd derivative (radians/minute^3)\n...     0.0007417,            # ecco: eccentricity\n...     0.3083420829620822,   # argpo: argument of perigee (radians)\n...     0.9013560935706996,   # inclo: inclination (radians)\n...     1.4946964807494398,   # mo: mean anomaly (radians)\n...     0.06763602333248933,  # no_kozai: mean motion (radians/minute)\n...     3.686137125541276,    # nodeo: R.A. of ascending node (radians)\n... )\n\nThese numbers don\u2019t look the same as the numbers in the TLE, because the\nunderlying ``sgp4init()`` routine uses different units: radians rather\nthan degrees.  But this is the same orbit and will produce the same\npositions.\n\nNote that ``ndot`` and ``nddot`` are ignored by the SGP4 propagator, so\nyou can leave them ``0.0`` without any effect on the resulting satellite\npositions.  But they do at least get saved to the satellite object, and\nwritten out if you write the parameters to a TLE or OMM file (see the\n\u201cExport\u201d section, above).\n\nTo compute the \u201cepoch\u201d argument, take the epoch\u2019s Julian date and\nsubtract 2433281.5 days.\n\nWhile the underlying ``sgp4init()`` routine leaves the attributes\n``epochyr``, ``epochdays``, ``jdsatepoch``, and ``jdsatepochF`` unset,\nthis library goes ahead and sets them anyway for you, using the epoch\nyou provided.\n\nSee the next section for the complete list of attributes that are\navailable from the satellite record once it has been initialized.\n\nAttributes\n----------\n\nThere are several dozen ``Satrec`` attributes that expose data from the\nunderlying C++ SGP4 record.  They fall into the following categories.\n\n*Identification*\n\nThese are copied directly from the TLE record but aren\u2019t used by the\npropagation math.\n\n| ``satnum_str`` \u2014 Satellite number, as a 5-character string.\n| ``satnum`` \u2014 Satellite number, converted to an integer.\n| ``classification`` \u2014 ``'U'``, ``'C'``, or ``'S'``\n  indicating the element set is Unclassified, Classified, or Secret.\n| ``ephtype`` \u2014 Integer \u201cephemeris type\u201d, used internally by space\n  agencies to mark element sets that are not ready for publication;\n  this field should always be ``0`` in published TLEs.\n| ``elnum`` \u2014 Element set number.\n| ``revnum`` \u2014 Satellite\u2019s revolution number at the moment of the epoch,\n  presumably counting from 1 following launch.\n\n*Orbital Elements*\n\nThese are the orbital parameters, copied verbatim from the text of the\nTLE record.  They describe the orbit at the moment of the TLE\u2019s epoch\nand so remain constant even as the satellite record is used over and\nover again to propagate positions for different times.\n\n| ``epochyr`` \u2014 Epoch date: the last two digits of the year.\n| ``epochdays`` \u2014 Epoch date: the number of days into the year,\n  including a decimal fraction for the UTC time of day.\n| ``ndot`` \u2014 First time derivative of the mean motion\n  (loaded from the TLE, but otherwise ignored).\n| ``nddot`` \u2014 Second time derivative of the mean motion\n  (loaded from the TLE, but otherwise ignored).\n| ``bstar`` \u2014 Ballistic drag coefficient B* (1/earth\u00a0radii).\n| ``inclo`` \u2014 Inclination (radians).\n| ``nodeo`` \u2014 Right ascension of ascending node (radians).\n| ``ecco`` \u2014 Eccentricity.\n| ``argpo`` \u2014 Argument of perigee (radians).\n| ``mo`` \u2014 Mean anomaly (radians).\n| ``no_kozai`` \u2014 Mean motion (radians/minute).\n| ``no`` \u2014 Alias for ``no_kozai``, for compatibility with old code.\n\nYou can also access the epoch as a Julian date:\n\n| ``jdsatepoch`` \u2014 Whole part of the epoch\u2019s Julian date.\n| ``jdsatepochF`` \u2014 Fractional part of the epoch\u2019s Julian date.\n\n*Computed Orbit Properties*\n\nThese are computed when the satellite is first loaded,\nas a convenience for callers who might be interested in them.\nThey aren\u2019t used by the SGP4 propagator itself.\n\n| ``a`` \u2014 Semi-major axis (earth\u00a0radii).\n| ``altp`` \u2014 Altitude of the satellite at perigee\n  (earth\u00a0radii, assuming a spherical Earth).\n| ``alta`` \u2014 Altitude of the satellite at apogee\n  (earth\u00a0radii, assuming a spherical Earth).\n| ``argpdot`` \u2014 Rate at which the argument of perigee is changing\n  (radians/minute).\n| ``gsto`` \u2014 Greenwich Sidereal Time at the satellite\u2019s epoch (radians).\n| ``mdot`` \u2014 Rate at which the mean anomaly is changing (radians/minute)\n| ``nodedot`` \u2014 Rate at which the right ascension of the ascending node\n  is changing (radians/minute).\n\n*Propagator Mode*\n\n| ``operationmode`` \u2014 A single character that directs SGP4\n  to either operate in its modern ``'i'`` improved mode\n  or in its legacy ``'a'`` AFSPC mode.\n| ``method`` \u2014 A single character, chosen automatically\n  when the orbital elements were loaded, that indicates whether SGP4\n  has chosen to use its built-in ``'n'`` Near Earth\n  or ``'d'`` Deep Space mode for this satellite.\n\n*Result of Most Recent Propagation*\n\n| ``t`` \u2014\n  The time you gave when you most recently asked SGP4\n  to compute this satellite\u2019s position,\n  measured in minutes before (negative) or after (positive)\n  the satellite\u2019s epoch.\n| ``error`` \u2014\n  Error code produced by the most recent SGP4 propagation\n  you performed with this element set.\n\nThe possible ``error`` codes are:\n\n0. No error.\n1. Mean eccentricity is outside the range 0\u00a0\u2264\u00a0e\u00a0<\u00a01.\n2. Mean motion has fallen below zero.\n3. Perturbed eccentricity is outside the range 0\u00a0\u2264\u00a0e\u00a0\u2264\u00a01.\n4. Length of the orbit\u2019s semi-latus rectum has fallen below zero.\n5. (No longer used.)\n6. Orbit has decayed: the computed position is underground.\n   (The position is still returned, in case the vector is helpful\n   to software that might be searching for the moment of re-entry.)\n\n*Mean Elements From Most Recent Propagation*\n\nPartway through each propagation, the SGP4 routine saves a set of\n\u201csingly averaged mean elements\u201d that describe the orbit\u2019s shape at the\nmoment for which a position is being computed.  They are averaged with\nrespect to the mean anomaly and include the effects of secular gravity,\natmospheric drag, and \u2014 in Deep Space mode \u2014 of those pertubations from\nthe Sun and Moon that SGP4 averages over an entire revolution of each of\nthose bodies.  They omit both the shorter-term and longer-term periodic\npertubations from the Sun and Moon that SGP4 applies right before\ncomputing each position.\n\n| ``am`` \u2014 Average semi-major axis (earth\u00a0radii).\n| ``em`` \u2014 Average eccentricity.\n| ``im`` \u2014 Average inclination (radians).\n| ``Om`` \u2014 Average right ascension of ascending node (radians).\n| ``om`` \u2014 Average argument of perigee (radians).\n| ``mm`` \u2014 Average mean anomaly (radians).\n| ``nm`` \u2014 Average mean motion (radians/minute).\n\n*Gravity Model Parameters*\n\nWhen the satellite record is initialized, your choice of gravity model\nresults in a slate of eight constants being copied in:\n\n| ``tumin`` \u2014 Minutes in one \u201ctime unit\u201d.\n| ``xke`` \u2014 The reciprocal of ``tumin``.\n| ``mu`` \u2014 Earth\u2019s gravitational parameter (km\u00b3/s\u00b2).\n| ``radiusearthkm`` \u2014 Radius of the earth (km).\n| ``j2``, ``j3``, ``j4`` \u2014 Un-normalized zonal harmonic values J\u2082, J\u2083, and J\u2084.\n| ``j3oj2`` \u2014 The ratio J\u2083/J\u2082.\n\nPrinting satellite attributes\n-----------------------------\n\nIf you want to print out a satellite, this library provides a convenient\n\u201cattribute dump\u201d routine that takes a satellite and generates lines that\nlist its attributes::\n\n    from sys import stdout\n    from sgp4.conveniences import dump_satrec\n\n    stdout.writelines(dump_satrec(satellite))\n\nIf you want to compare two satellites, then simply pass a second\nargument; the second satellite\u2019s attributes will be printed in a second\ncolumn next to those of the first. ::\n\n    stdout.writelines(dump_satrec(satellite, satellite2))\n\nValidation against the official algorithm\n-----------------------------------------\n\nThis implementation passes all of the automated tests in the August 2010\nrelease of the reference implementation of SGP4 by Vallado et\u00a0al., who\noriginally published their revision of SGP4 in\u00a02006:\n\n    Vallado, David A., Paul Crawford, Richard Hujsak, and T.S. Kelso,\n    \u201cRevisiting Spacetrack Report #3,\u201d presented at the AIAA/AAS\n    Astrodynamics Specialist Conference, Keystone, CO, 2006 August\n    21\u201324.\n\nIf you would like to review the paper, it is `available online\n<https://www.celestrak.com/publications/AIAA/2006-6753/>`_.  You can\nalways download the latest version of their code for comparison against\nthis Python module (or other implementations) at `AIAA-2006-6753.zip\n<https://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753.zip>`_.\n\nFor developers\n--------------\n\nDevelopers can check out this full project from GitHub:\n\nhttps://github.com/brandon-rhodes/python-sgp4\n\nTo run its unit tests, install Python\u00a02, Python\u00a03, and the ``tox``\ntesting tool.  The tests runing in Python\u00a02 will exercise the fallback\npure-Python version of the routines, while Python\u00a03 exercises the fast\nnew C++ accelerated code::\n\n    cd python-sgp4\n    tox\n\nLegacy API\n----------\n\nBefore this library pivoted to wrapping Vallado's official C++ code and\nwas operating in pure Python only, it had a slightly quirkier API, which\nis still supported for compatibility with older clients.  You can learn\nabout it by reading the documentation from version 1.4 or earlier:\n\nhttps://pypi.org/project/sgp4/1.4/\n\nChangelog\n---------\n\n2023-10-01 \u2014 2.23\n\n* Tweaked tests to resolve breakage introduced by Python\u00a03.12.\n\n2023-04-27 \u2014 2.22\n\n* Added a ``satnum_str`` attribute, exposing the fact that the C++ now\n  stores the satellite number as a string; and check that ``satnum`` is\n  never greater than 339999.\n\n* Fixed the units of the ``nddot`` attribute when the value is loaded\n  from an OMM record.  (Since the TLE computation itself ignores this\n  attribute, this did not affect any satellite positions.)\n\n* Enhanced the fallback Python version of ``twoline2rv()`` to verify\n  that TLE lines are ASCII, and added documentation using it to\n  double-check TLEs that might suffer from non-ASCII characters.\n\n* If the user doesn\u2019t set a satellite\u2019s ``classification``, it now\n  defaults to ``'U'`` for \u2018unclassified\u2019.\n\n2022-04-06 \u2014 2.21\n\n* Added ``dump_satrec()`` to the ``sgp4.conveniences`` module.\n\n* Fixed the ``Satrec`` attribute ``.error``, which was previously\n  building a nonsense integer from the wrong data in memory.\n\n* Removed ``.whichconst`` from Python ``Satrec``, to help users avoid\n  writing code that will break when the C++ extension is available.\n\n2021-07-01 \u2014 2.20\n\n* Taught ``sgp4init()`` to round both ``epochdays`` and ``jdsatepochF``\n  to the same 8 decimal places used for the date fraction in a TLE, if\n  the user-supplied ``epoch`` itself has 8 or fewer digits behind the\n  decimal point.  This should make it easier to build satellites that\n  round-trip to TLE format with perfect accuracy.\n\n* Fixed how ``export_tle()`` formats the BSTAR field when its value, if\n  written in scientific notation, has a positive exponent.\n\n* Fixed the ``epochyr`` assigned by ``sgp4init()`` so years before 2000\n  have two digits instead of three (for example, so that 1980 produces\n  an ``epochyr`` of 80 instead of 980).\n\n2021-04-22 \u2014 2.19\n\n* Extended the documentation on the Python Package Index and in the\n  module docstring so it lists every ``Satrec`` attribute that this\n  library exposes; even the more obscure ones might be useful to folks\n  working to analyze satellite orbits.\n\n2021-03-08 \u2014 2.18\n\n* If a TLE satellite number lacks the required 5 digits,\n  ``twoline2rv()`` now gives the underlying C++ library a little help so\n  it can still parse the classification and international designator\n  correctly.\n\n* The ``Satrec`` attributes ``jdsatepoch``, ``jdsatepochF``,\n  ``epochyr``, and ``epochdays`` are now writeable, so users can adjust\n  their values manually \u2014 which should make up for the fact that the\n  ``sgp4init()`` method can\u2019t set them with full floating point\n  precision.\n\n| 2021-02-17 \u2014 2.17 \u2014 Fixed where in the output array the ``sgp4_array()`` method writes NaN values when an SGP4 propagation fails.\n| 2021-02-12 \u2014 2.16 \u2014 Fixed ``days2mdhms()`` rounding to always match TLE epoch.\n| 2021-01-08 \u2014 2.15 \u2014 Fixed parsing of the ``satnum`` TLE field in the Python fallback code, when the field has a leading space; added OMM export routine.\n| 2020-12-16 \u2014 2.14 \u2014 New data formats: added OMM message support for both XML and CSV, and added support for the new Alpha-5 extension to TLE files.\n| 2020-10-14 \u2014 2.13 \u2014 Enhanced ``sgp4init()`` with custom code that also sets the ``epochdays`` and ``epochyr`` satellite attributes.\n| 2020-05-28 \u2014 2.12 \u2014 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.\n| 2020-05-24 \u2014 2.11 \u2014 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.\n| 2020-05-22 \u2014 2.10 \u2014 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.\n| 2020-05-21 \u2014 2.9 \u2014 Added ``sat_epoch_datetime()``, expanded documentation around converting a satellite epoch to a date and time, and started rounding the epoch to exactly the digits provided in the TLE; and removed the ``Satrec.epoch`` attribute from Python fallback code to better match the C++ version.\n| 2020-05-07 \u2014 2.8 \u2014 New function ``jday_datetime()`` is now available in the ``sgp4.conveniences`` module, thanks to Egemen Imre.\n| 2020-04-24 \u2014 2.7 \u2014 New method ``sgp4init()`` (thank you, Chris Lewicki!) is available.\n| 2020-04-20 \u2014 2.6 \u2014 New routine ``export_tle()`` (thank you, Egemen Imre!) is available. Improved how the accelerated C++ backend parses the ``intldesg`` string and the ``revnum`` integer.\n| 2020-03-22 \u2014 2.5 \u2014 Gave the new accelerated ``twoline2rv()`` an optional argument that lets the user choose a non-standard set of gravity constants.\n| 2020-02-25 \u2014 2.4 \u2014 Improved the ``jday()`` docstring; made the old legacy Python resilient if the day of the month is out-of-range (past the end of the month) in a TLE; and Mark Rutten fixed the C++ so it compiles on Windows!\n| 2020-02-04 \u2014 2.3 \u2014 Removed experimental code that caused performance problems for users with Numba installed.\n| 2020-02-02 \u2014 2.2 \u2014 A second release on Palindrome Day: fix the Satrec ``.epochyr`` attribute so it behaves the same way in Python as it does in the official C library, where it is only the last 2 digits of the year; and make ``.no`` available in the Python fallback case as well.\n| 2020-02-02 \u2014 2.1 \u2014 Add vectorized array method to Satrec object; add ``.no`` attribute to new Satrec object to support old code that has not migrated to the new name ``.no_kozai``; gave Python wrapper classes ``__slots__`` to avoid the expense of a per-object attribute dictionary.\n| 2020-01-30 \u2014 2.0 \u2014 Rewrite API to use genuine Vallado C++ code on those systems where it can be compiled; add accelerated vectorized array interface; make ``gstime()`` a public function; clarify format error message.\n| 2015-01-15 \u2014 1.4 \u2014 Display detailed help when TLE input does not match format.\n| 2014-06-26 \u2014 1.3 \u2014 Return ``(NaN,NaN,NaN)`` vectors on error and set ``.error_message``\n| 2013-11-29 \u2014 1.2 \u2014 Made ``epochyr`` 4 digits; add ``datetime`` for ``.epoch``\n| 2012-11-22 \u2014 1.1 \u2014 Python\u00a03 compatibility; more documentation\n| 2012-08-27 \u2014 1.0 \u2014 Initial release\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Track Earth satellites given TLE data, using up-to-date 2020 SGP4 routines.",
    "version": "2.23",
    "project_urls": {
        "Homepage": "https://github.com/brandon-rhodes/python-sgp4"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "078d2eef1f49a1328dd2b3a48b38212005a6b80c1f74d442ae6426e7d5ddcbfd",
                "md5": "2e108d47b28234985c6179909bed493b",
                "sha256": "ebf585c09bebf7f7b9c89cff42e0f097654c4c5e092181fbbbee29c338dc11ed"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-macosx_10_9_universal2.whl",
            "has_sig": false,
            "md5_digest": "2e108d47b28234985c6179909bed493b",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 184170,
            "upload_time": "2023-11-11T13:44:27",
            "upload_time_iso_8601": "2023-11-11T13:44:27.075888Z",
            "url": "https://files.pythonhosted.org/packages/07/8d/2eef1f49a1328dd2b3a48b38212005a6b80c1f74d442ae6426e7d5ddcbfd/sgp4-2.23-cp310-cp310-macosx_10_9_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c621e7628040de626eed36195c62a43bb2d8b1a9ccc6af6bb94d2696748c6691",
                "md5": "6644e2fe8cbb8bc161739fcb1d053721",
                "sha256": "9c71fec3278274a0edd5bb93ba83b22db5407040d95d62166e81fbd97633d756"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "6644e2fe8cbb8bc161739fcb1d053721",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 160021,
            "upload_time": "2023-11-11T13:44:29",
            "upload_time_iso_8601": "2023-11-11T13:44:29.058935Z",
            "url": "https://files.pythonhosted.org/packages/c6/21/e7628040de626eed36195c62a43bb2d8b1a9ccc6af6bb94d2696748c6691/sgp4-2.23-cp310-cp310-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "004ef03a7d4328ed90f4e38d81e477809759d20d218f05334a4fd6e56416e73d",
                "md5": "3b2d61dd1deaae237326597e04480add",
                "sha256": "f07f11fc70fa76ad7f538bcff4ee960faab270279cbb2d1149b15cbb37696e86"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "3b2d61dd1deaae237326597e04480add",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 158580,
            "upload_time": "2023-11-11T13:44:30",
            "upload_time_iso_8601": "2023-11-11T13:44:30.258355Z",
            "url": "https://files.pythonhosted.org/packages/00/4e/f03a7d4328ed90f4e38d81e477809759d20d218f05334a4fd6e56416e73d/sgp4-2.23-cp310-cp310-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0310d090b516abf042fdf032f92201ba8fe08cfd88708927cae23398e9c582ed",
                "md5": "9e9e5525217ef0e352e3198f9c0d99d0",
                "sha256": "d9a777e4173194965ec9466b307c3a929770d058be303ead8179c251fc37ed2e"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "9e9e5525217ef0e352e3198f9c0d99d0",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 232904,
            "upload_time": "2023-11-11T13:44:31",
            "upload_time_iso_8601": "2023-11-11T13:44:31.790808Z",
            "url": "https://files.pythonhosted.org/packages/03/10/d090b516abf042fdf032f92201ba8fe08cfd88708927cae23398e9c582ed/sgp4-2.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4c5d4537a6a24a44599daf533c5f087acf38b394833c9d8b4d63076a1022c300",
                "md5": "caa7571ac0a2b8b98aafea95098a26c1",
                "sha256": "3884d50cba79f4dbeda16b4eb1d768bd3400b7a2c137a8c88eca056738bab94d"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "caa7571ac0a2b8b98aafea95098a26c1",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 232344,
            "upload_time": "2023-11-11T13:44:33",
            "upload_time_iso_8601": "2023-11-11T13:44:33.248417Z",
            "url": "https://files.pythonhosted.org/packages/4c/5d/4537a6a24a44599daf533c5f087acf38b394833c9d8b4d63076a1022c300/sgp4-2.23-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "855a03db579c9a538b52d34d13ecf644bd2c2eb0099ad52f9e8e21f18daa0537",
                "md5": "5a482128263c1e3598c508f617686128",
                "sha256": "ce19d23a4276bab2bbba03ce5bbcc308c5472be69219d877f83d4b12c07f5ea1"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-win32.whl",
            "has_sig": false,
            "md5_digest": "5a482128263c1e3598c508f617686128",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 158859,
            "upload_time": "2023-11-11T13:44:34",
            "upload_time_iso_8601": "2023-11-11T13:44:34.504145Z",
            "url": "https://files.pythonhosted.org/packages/85/5a/03db579c9a538b52d34d13ecf644bd2c2eb0099ad52f9e8e21f18daa0537/sgp4-2.23-cp310-cp310-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "40fad433c219b78f1f18299af4bfa5b2e74a8248a5c2a2053ea45728d49a003e",
                "md5": "cdd913ca6848ff4b329ab315192371bd",
                "sha256": "2d6b56adb8771f3092ff5d59697d19f6f3bf2510fcca03795eedae41a42624b2"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "cdd913ca6848ff4b329ab315192371bd",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 160827,
            "upload_time": "2023-11-11T13:44:36",
            "upload_time_iso_8601": "2023-11-11T13:44:36.198010Z",
            "url": "https://files.pythonhosted.org/packages/40/fa/d433c219b78f1f18299af4bfa5b2e74a8248a5c2a2053ea45728d49a003e/sgp4-2.23-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9a6ef3cabda68aa28f770a161894c1d1210e5c489c2ecf454d6e0a338f42fd87",
                "md5": "0f1f901dc63c0c8a56ef3c5156afa63b",
                "sha256": "90dbea63ea1f288ce90448b3d7a1e9728292f1b9c9fa61839053e9277d98e96f"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-macosx_10_9_universal2.whl",
            "has_sig": false,
            "md5_digest": "0f1f901dc63c0c8a56ef3c5156afa63b",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 184169,
            "upload_time": "2023-11-11T13:44:37",
            "upload_time_iso_8601": "2023-11-11T13:44:37.793247Z",
            "url": "https://files.pythonhosted.org/packages/9a/6e/f3cabda68aa28f770a161894c1d1210e5c489c2ecf454d6e0a338f42fd87/sgp4-2.23-cp311-cp311-macosx_10_9_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1a25a47d0c39260f34577a49ca139ccd99d45b51fcdaf524434761ba1089bc53",
                "md5": "d5bf178bdf9912493f3e5248605e08c3",
                "sha256": "e7b043fb0f628a3759ef649ee12b6e76ee65a0ec86b94dc41dfc90129fcbc81e"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "d5bf178bdf9912493f3e5248605e08c3",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 160023,
            "upload_time": "2023-11-11T13:44:39",
            "upload_time_iso_8601": "2023-11-11T13:44:39.502092Z",
            "url": "https://files.pythonhosted.org/packages/1a/25/a47d0c39260f34577a49ca139ccd99d45b51fcdaf524434761ba1089bc53/sgp4-2.23-cp311-cp311-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ddfc27496962d238fc18b9a005035141373307267830e3cf2b3bb04de7dfbebe",
                "md5": "770e0177048084eaecfdf8c4de35609e",
                "sha256": "7d55529102283821054ece00f95dd2b82843d1c72c80e39026c78e2f400ac9b9"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "770e0177048084eaecfdf8c4de35609e",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 158584,
            "upload_time": "2023-11-11T13:44:40",
            "upload_time_iso_8601": "2023-11-11T13:44:40.744054Z",
            "url": "https://files.pythonhosted.org/packages/dd/fc/27496962d238fc18b9a005035141373307267830e3cf2b3bb04de7dfbebe/sgp4-2.23-cp311-cp311-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a88fa21128c2919ae10d00f1df81c9e39b850a73694b2e083d1597209731bfa5",
                "md5": "6f93780f9c9b2496a2f2de8e2653eb2f",
                "sha256": "4d9f4f39be2b85a4772a184cd4d160f9ed345116afcda79a0a1852ccfa12b030"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "6f93780f9c9b2496a2f2de8e2653eb2f",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 232875,
            "upload_time": "2023-11-11T13:44:42",
            "upload_time_iso_8601": "2023-11-11T13:44:42.053081Z",
            "url": "https://files.pythonhosted.org/packages/a8/8f/a21128c2919ae10d00f1df81c9e39b850a73694b2e083d1597209731bfa5/sgp4-2.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9b6f4970dffe5c44a92370c2c7fff9a443901ac8daf3ddf3cf00586485ec84c4",
                "md5": "c924c362c1ddaf9404f525355129aea6",
                "sha256": "72868cd01169f45562954cdaaa9f1a2f738cac3c9ba3fdbd12b07a5f99bcb9d1"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c924c362c1ddaf9404f525355129aea6",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 232337,
            "upload_time": "2023-11-11T13:44:43",
            "upload_time_iso_8601": "2023-11-11T13:44:43.342263Z",
            "url": "https://files.pythonhosted.org/packages/9b/6f/4970dffe5c44a92370c2c7fff9a443901ac8daf3ddf3cf00586485ec84c4/sgp4-2.23-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "24df46e5de2cf8ac54eb757ce7ce29f348716e83b76fb839d979bb364582c38f",
                "md5": "9a4debad4cf601f87b6c8e8424c03a20",
                "sha256": "137adf0e0fbe4d9a514284bb809590c5a2c52dc506b977ec7896165df8bc2a5e"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-win32.whl",
            "has_sig": false,
            "md5_digest": "9a4debad4cf601f87b6c8e8424c03a20",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 158868,
            "upload_time": "2023-11-11T13:44:45",
            "upload_time_iso_8601": "2023-11-11T13:44:45.192456Z",
            "url": "https://files.pythonhosted.org/packages/24/df/46e5de2cf8ac54eb757ce7ce29f348716e83b76fb839d979bb364582c38f/sgp4-2.23-cp311-cp311-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f6fbd9d513dcb6c8898504e8c32cc95bc60435ddc1de27583ca6d2063c72471b",
                "md5": "86e48447db75f6972e67ea411f9a7430",
                "sha256": "34efb27f9f281c76b5650c9a39a0b8f43d383d5575a4f7b3d4d597c9b7ff3d75"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "86e48447db75f6972e67ea411f9a7430",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 160829,
            "upload_time": "2023-11-11T13:44:46",
            "upload_time_iso_8601": "2023-11-11T13:44:46.702156Z",
            "url": "https://files.pythonhosted.org/packages/f6/fb/d9d513dcb6c8898504e8c32cc95bc60435ddc1de27583ca6d2063c72471b/sgp4-2.23-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9a9709f19c4ea8cef4b384002b2c40c1a7a98484799d3a534a02712140ffaea9",
                "md5": "fd7ed0289c2698428516764bca1b8474",
                "sha256": "c45fa362763b5ae955a52bfdf05fee8d98351d1fa9db8fd1809b4f380cd9b0c6"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-macosx_10_9_universal2.whl",
            "has_sig": false,
            "md5_digest": "fd7ed0289c2698428516764bca1b8474",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 184223,
            "upload_time": "2023-11-11T13:44:48",
            "upload_time_iso_8601": "2023-11-11T13:44:48.341036Z",
            "url": "https://files.pythonhosted.org/packages/9a/97/09f19c4ea8cef4b384002b2c40c1a7a98484799d3a534a02712140ffaea9/sgp4-2.23-cp312-cp312-macosx_10_9_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e1dff2e9029e7a14129ae7e6c280a44dafc725fcf997d40fc5bd121e81bb9186",
                "md5": "366eb4d07c933e3946891c2ba649a974",
                "sha256": "3765d0efae2c537228311591691a8fd7d44686d5322810be15eb7f204688f336"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "366eb4d07c933e3946891c2ba649a974",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 160036,
            "upload_time": "2023-11-11T13:44:49",
            "upload_time_iso_8601": "2023-11-11T13:44:49.724730Z",
            "url": "https://files.pythonhosted.org/packages/e1/df/f2e9029e7a14129ae7e6c280a44dafc725fcf997d40fc5bd121e81bb9186/sgp4-2.23-cp312-cp312-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5029389cf5b4429c83799e721b29fbc1b46bcbe8065e9dcac7d349be4e717ca7",
                "md5": "bde0c07f9c2b9df6f4d9a150a8d45d16",
                "sha256": "b80dd3c3ee73a1bc24c0f63316889b3eff32e623ca67a91774c9c92ac663e98c"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "bde0c07f9c2b9df6f4d9a150a8d45d16",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 158619,
            "upload_time": "2023-11-11T13:44:50",
            "upload_time_iso_8601": "2023-11-11T13:44:50.953453Z",
            "url": "https://files.pythonhosted.org/packages/50/29/389cf5b4429c83799e721b29fbc1b46bcbe8065e9dcac7d349be4e717ca7/sgp4-2.23-cp312-cp312-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b8962da259097de4e7c5da09d559e5819f96631e496517c343300136a4975502",
                "md5": "d377ace63263e5588869b6793c5c3d00",
                "sha256": "b1ec001c6b5bd9a330ffa40d29ebf85f1cc2bfa558ba8f330efcb1aa50a8b733"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "d377ace63263e5588869b6793c5c3d00",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 233487,
            "upload_time": "2023-11-11T13:44:52",
            "upload_time_iso_8601": "2023-11-11T13:44:52.326269Z",
            "url": "https://files.pythonhosted.org/packages/b8/96/2da259097de4e7c5da09d559e5819f96631e496517c343300136a4975502/sgp4-2.23-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cdaf79f7f661c2baf1b2db54166ec2e6cefa2d1eab0825fc4ac21b058ecc8bc8",
                "md5": "7c591ddac6c565cca2b3e8a37a3b0dfe",
                "sha256": "7424adc1d5f8cf93bf6ddeb079a9122af25c8a6b9234e7ed71d1868e128afe4a"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7c591ddac6c565cca2b3e8a37a3b0dfe",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 232868,
            "upload_time": "2023-11-11T13:44:54",
            "upload_time_iso_8601": "2023-11-11T13:44:54.330573Z",
            "url": "https://files.pythonhosted.org/packages/cd/af/79f7f661c2baf1b2db54166ec2e6cefa2d1eab0825fc4ac21b058ecc8bc8/sgp4-2.23-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "be747a8c5c19b10949f1d588ff23ad25161390ad0431c80dba3055b941fd6a41",
                "md5": "8493ddb09d75a51a5267aa42bd69a4ed",
                "sha256": "4d954aa01a9f8c68a7b20e91ea6b5e0a195bb42b25e63698ea770d12c01927ea"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-win32.whl",
            "has_sig": false,
            "md5_digest": "8493ddb09d75a51a5267aa42bd69a4ed",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 158905,
            "upload_time": "2023-11-11T13:44:56",
            "upload_time_iso_8601": "2023-11-11T13:44:56.156038Z",
            "url": "https://files.pythonhosted.org/packages/be/74/7a8c5c19b10949f1d588ff23ad25161390ad0431c80dba3055b941fd6a41/sgp4-2.23-cp312-cp312-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3e4d378e647b0607919db275d584ff362475714e574fa8e2e1aab1146580e01b",
                "md5": "3660f77a8efb11aecfaeb6aba6d7caef",
                "sha256": "cc08bc23327f7b3cd052e79b026f02a1da885a273f10fa2a78734e5fa5ccfddd"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "3660f77a8efb11aecfaeb6aba6d7caef",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 160874,
            "upload_time": "2023-11-11T13:44:57",
            "upload_time_iso_8601": "2023-11-11T13:44:57.969980Z",
            "url": "https://files.pythonhosted.org/packages/3e/4d/378e647b0607919db275d584ff362475714e574fa8e2e1aab1146580e01b/sgp4-2.23-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e88718fc4ec485fbff86336050326ae364a5b42a027a6e9eff466493f438fc36",
                "md5": "6cb617474e102c97274adefd3e4776e6",
                "sha256": "0312155fe5ec1f224510508c2298ee810821e66cd075686b041d921fba2f5b3b"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp37-cp37m-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "6cb617474e102c97274adefd3e4776e6",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 159951,
            "upload_time": "2023-11-11T13:44:59",
            "upload_time_iso_8601": "2023-11-11T13:44:59.591387Z",
            "url": "https://files.pythonhosted.org/packages/e8/87/18fc4ec485fbff86336050326ae364a5b42a027a6e9eff466493f438fc36/sgp4-2.23-cp37-cp37m-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8071919270ae7c731c7758a17a783bc550207e449ed54d90d1a1114bb56be8b3",
                "md5": "f21b32479251296e6698e186493b2d48",
                "sha256": "ec6922c6086e3a6dec71a2df0e9c884ffa3edb7276daff36c6c8aa1e4fe711de"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "f21b32479251296e6698e186493b2d48",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 232441,
            "upload_time": "2023-11-11T13:45:01",
            "upload_time_iso_8601": "2023-11-11T13:45:01.123479Z",
            "url": "https://files.pythonhosted.org/packages/80/71/919270ae7c731c7758a17a783bc550207e449ed54d90d1a1114bb56be8b3/sgp4-2.23-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5c316d663299d2ee41421fe04fde67949209a81506871f26186daf738a2ce458",
                "md5": "2cd1e759c722c7381426af2fb374d31b",
                "sha256": "77db876e61e5740ad10deb368041411ec1be8d885b0890f37cd81fb12d294dd4"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
            "has_sig": false,
            "md5_digest": "2cd1e759c722c7381426af2fb374d31b",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 229377,
            "upload_time": "2023-11-11T13:45:02",
            "upload_time_iso_8601": "2023-11-11T13:45:02.714362Z",
            "url": "https://files.pythonhosted.org/packages/5c/31/6d663299d2ee41421fe04fde67949209a81506871f26186daf738a2ce458/sgp4-2.23-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "13eae5127b1bcabbeb0cc4fba9f6589343b124a1e719280d6ae5ff961aa77cdd",
                "md5": "6449947b6241b995339d8693db3eca62",
                "sha256": "2e7b9c513efbdf2e27d88e2cd72599f5c2a930e6e8b2dd18ec7a1b62ad57ed58"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "6449947b6241b995339d8693db3eca62",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 231877,
            "upload_time": "2023-11-11T13:45:04",
            "upload_time_iso_8601": "2023-11-11T13:45:04.090187Z",
            "url": "https://files.pythonhosted.org/packages/13/ea/e5127b1bcabbeb0cc4fba9f6589343b124a1e719280d6ae5ff961aa77cdd/sgp4-2.23-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a14d4a84f1109e75128ee08359587cc92aad004822f69868d8920fd5e597d045",
                "md5": "4e25ee5ba4b623e88c2f86683863443a",
                "sha256": "f612f8f33ba22425bf9975170586ad1b61648abe113f5b82e35a07a426597107"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp37-cp37m-win32.whl",
            "has_sig": false,
            "md5_digest": "4e25ee5ba4b623e88c2f86683863443a",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 158854,
            "upload_time": "2023-11-11T13:45:05",
            "upload_time_iso_8601": "2023-11-11T13:45:05.619347Z",
            "url": "https://files.pythonhosted.org/packages/a1/4d/4a84f1109e75128ee08359587cc92aad004822f69868d8920fd5e597d045/sgp4-2.23-cp37-cp37m-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f1421c7ed7fec94c35ca1852e6b8df376d193a72f59b273353c6a54a77663e49",
                "md5": "bb9ac5631e0d9baacce999cf9fd10273",
                "sha256": "4f49aae8dff21747c5605d924f92149a4613b981ae13b31499390526cbcd2dba"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp37-cp37m-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "bb9ac5631e0d9baacce999cf9fd10273",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 160793,
            "upload_time": "2023-11-11T13:45:07",
            "upload_time_iso_8601": "2023-11-11T13:45:07.071541Z",
            "url": "https://files.pythonhosted.org/packages/f1/42/1c7ed7fec94c35ca1852e6b8df376d193a72f59b273353c6a54a77663e49/sgp4-2.23-cp37-cp37m-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6c78e4e385b543eae03fed6e3c3874af30af5e850bad84602bbb3aee458b7541",
                "md5": "a505701faf33ba753c9ee9fcfa5538f6",
                "sha256": "081aa74d55ee2d5c8c6a89e24915af069499ec66fe3ef01b58c4a93a741c4f47"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-macosx_10_9_universal2.whl",
            "has_sig": false,
            "md5_digest": "a505701faf33ba753c9ee9fcfa5538f6",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 184174,
            "upload_time": "2023-11-11T13:45:08",
            "upload_time_iso_8601": "2023-11-11T13:45:08.840622Z",
            "url": "https://files.pythonhosted.org/packages/6c/78/e4e385b543eae03fed6e3c3874af30af5e850bad84602bbb3aee458b7541/sgp4-2.23-cp38-cp38-macosx_10_9_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d496b5f4f25a23977138407c50196d9d0cc05b524f63e41893844dfca779ed3b",
                "md5": "7d9bb64515448a9b00fc148311f94b9b",
                "sha256": "80eb86ebb66938542eb4b2fb660884538e48e14362e7b50313a6ecc888a93638"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7d9bb64515448a9b00fc148311f94b9b",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 160011,
            "upload_time": "2023-11-11T13:45:10",
            "upload_time_iso_8601": "2023-11-11T13:45:10.734675Z",
            "url": "https://files.pythonhosted.org/packages/d4/96/b5f4f25a23977138407c50196d9d0cc05b524f63e41893844dfca779ed3b/sgp4-2.23-cp38-cp38-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ffa4cf5fa46899f9e62eb6a757f89231e9eff5e534d675c882715bef73f23bc2",
                "md5": "21255e647d17076ca1922324dc1bf436",
                "sha256": "ff8797c36e7dff0b13c7f6bc4c9bf6ad31590dc4509e6b9cfac26819e7a61769"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "21255e647d17076ca1922324dc1bf436",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 158585,
            "upload_time": "2023-11-11T13:45:12",
            "upload_time_iso_8601": "2023-11-11T13:45:12.110647Z",
            "url": "https://files.pythonhosted.org/packages/ff/a4/cf5fa46899f9e62eb6a757f89231e9eff5e534d675c882715bef73f23bc2/sgp4-2.23-cp38-cp38-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d6628c144895d69fc849f1a94b2be550588f9b8c2f4911de7158ec0695780dfe",
                "md5": "e9255e330298b82762040944b6ba58de",
                "sha256": "a1a67628ca344e1abaf6ff447ccfc1e5ea3d0d829cecf07aa05dea21b0119470"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "e9255e330298b82762040944b6ba58de",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 232998,
            "upload_time": "2023-11-11T13:45:13",
            "upload_time_iso_8601": "2023-11-11T13:45:13.585169Z",
            "url": "https://files.pythonhosted.org/packages/d6/62/8c144895d69fc849f1a94b2be550588f9b8c2f4911de7158ec0695780dfe/sgp4-2.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "584d709f231d1dc7019f3c004fd85ef0b56271e7c63f7bbef94549ba8b475b83",
                "md5": "208c624ef877bd84e986286a998bef97",
                "sha256": "cf18eee8ce8dddee047785b3fb399ff45d1907e4d1e581a7466ac00798993d7e"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
            "has_sig": false,
            "md5_digest": "208c624ef877bd84e986286a998bef97",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 229988,
            "upload_time": "2023-11-11T13:45:15",
            "upload_time_iso_8601": "2023-11-11T13:45:15.069321Z",
            "url": "https://files.pythonhosted.org/packages/58/4d/709f231d1dc7019f3c004fd85ef0b56271e7c63f7bbef94549ba8b475b83/sgp4-2.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6f079a5db0f7250ad9285474735338653c1a4455a2e43cd7ca0e3be1c00b47d3",
                "md5": "d412c0473c076dcae3bb7f9e401b4af8",
                "sha256": "e7688173441f97680f4804e482e6ed47fb3a6341715f280ce38783fef7120c7c"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "d412c0473c076dcae3bb7f9e401b4af8",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 232424,
            "upload_time": "2023-11-11T13:45:16",
            "upload_time_iso_8601": "2023-11-11T13:45:16.351752Z",
            "url": "https://files.pythonhosted.org/packages/6f/07/9a5db0f7250ad9285474735338653c1a4455a2e43cd7ca0e3be1c00b47d3/sgp4-2.23-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "77a558d3aa5fd1bfeade80745b0f6deadb5efbe585972d49960dc43ddd3497f3",
                "md5": "d5217dc3335d810b96dcfa4c56d4ba26",
                "sha256": "5be9be672ad810f01db18f4515fca47e3e4502139642d077d06a187e0c9dc312"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-win32.whl",
            "has_sig": false,
            "md5_digest": "d5217dc3335d810b96dcfa4c56d4ba26",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 158858,
            "upload_time": "2023-11-11T13:45:17",
            "upload_time_iso_8601": "2023-11-11T13:45:17.830351Z",
            "url": "https://files.pythonhosted.org/packages/77/a5/58d3aa5fd1bfeade80745b0f6deadb5efbe585972d49960dc43ddd3497f3/sgp4-2.23-cp38-cp38-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4d22999da8122ec93e0409e58a1089da11516d8483c19c544c675e9b0ff16fe1",
                "md5": "d6ce15023ac1378bfccddbe8e8140786",
                "sha256": "7277523e83115d5e0c37bdb3d05fec924b6fdf0af0b1679bbb66455b8d00da61"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp38-cp38-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "d6ce15023ac1378bfccddbe8e8140786",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 160820,
            "upload_time": "2023-11-11T13:45:19",
            "upload_time_iso_8601": "2023-11-11T13:45:19.239329Z",
            "url": "https://files.pythonhosted.org/packages/4d/22/999da8122ec93e0409e58a1089da11516d8483c19c544c675e9b0ff16fe1/sgp4-2.23-cp38-cp38-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "885e6d3c4e98182c107f14858662857ff4d6f276cfbab4463e7416c230c33313",
                "md5": "f9bb61413b40ea776ce1674e8c28d7ab",
                "sha256": "474598a642b77b2f2243ccdfb6204c92219f5182a261b8a89c09b9fef840fbd1"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-macosx_10_9_universal2.whl",
            "has_sig": false,
            "md5_digest": "f9bb61413b40ea776ce1674e8c28d7ab",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 184164,
            "upload_time": "2023-11-11T13:45:20",
            "upload_time_iso_8601": "2023-11-11T13:45:20.944046Z",
            "url": "https://files.pythonhosted.org/packages/88/5e/6d3c4e98182c107f14858662857ff4d6f276cfbab4463e7416c230c33313/sgp4-2.23-cp39-cp39-macosx_10_9_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2e131fffd11551dfaf9d41cf48ebdc17f3fac50108b0848d8fcdf7a3dd90c660",
                "md5": "a7eb721c0cc7e51a2a0b5036ed0f55f7",
                "sha256": "3423c1f7efcc72fb7bd92bd549812add1a8712fa7d9c3d475c187817ef844e77"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "a7eb721c0cc7e51a2a0b5036ed0f55f7",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 160013,
            "upload_time": "2023-11-11T13:45:22",
            "upload_time_iso_8601": "2023-11-11T13:45:22.167968Z",
            "url": "https://files.pythonhosted.org/packages/2e/13/1fffd11551dfaf9d41cf48ebdc17f3fac50108b0848d8fcdf7a3dd90c660/sgp4-2.23-cp39-cp39-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2fe8d648e8681bd4b18b5cc156aaeb69585268926c0b6c5c6a996212193728dc",
                "md5": "6ae5b85527d4de6b467d120af95c0e92",
                "sha256": "54e77baeb145e77884754e4c6cbc92b008d00f12563e5175c3197b484b61a651"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "6ae5b85527d4de6b467d120af95c0e92",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 158583,
            "upload_time": "2023-11-11T13:45:23",
            "upload_time_iso_8601": "2023-11-11T13:45:23.942953Z",
            "url": "https://files.pythonhosted.org/packages/2f/e8/d648e8681bd4b18b5cc156aaeb69585268926c0b6c5c6a996212193728dc/sgp4-2.23-cp39-cp39-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a5a9a7f3d185a39f6225d9e2cbc22b4dc6375f98833c275bd4231277ef3229d7",
                "md5": "a120d3a42f777bf7cd90ff93f8efa4af",
                "sha256": "6da74f4d0710445595ad8635bf29a608a6ef51d0ffdb5ae137d09fb7e32ac916"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "a120d3a42f777bf7cd90ff93f8efa4af",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 232722,
            "upload_time": "2023-11-11T13:45:25",
            "upload_time_iso_8601": "2023-11-11T13:45:25.310057Z",
            "url": "https://files.pythonhosted.org/packages/a5/a9/a7f3d185a39f6225d9e2cbc22b4dc6375f98833c275bd4231277ef3229d7/sgp4-2.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3b29497a8500da71dea1c48d2cce9f3dbfdf0785725f65ce03ae97840913788a",
                "md5": "fc21b347332b791a781051622d555ccd",
                "sha256": "6cd67a3eee025d62fff045807134ea4b1d377e0d88bea43a1e3153239b5d533b"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
            "has_sig": false,
            "md5_digest": "fc21b347332b791a781051622d555ccd",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 229731,
            "upload_time": "2023-11-11T13:45:27",
            "upload_time_iso_8601": "2023-11-11T13:45:27.008675Z",
            "url": "https://files.pythonhosted.org/packages/3b/29/497a8500da71dea1c48d2cce9f3dbfdf0785725f65ce03ae97840913788a/sgp4-2.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3168b111b5268bfba809be60389ca3236aa4db12dade6655936c4a8f865924b7",
                "md5": "f40282f7972697d4f9d39e8d8c2f1c94",
                "sha256": "e5bb5e59ee41bdeb0beec5c9a156e82e4f5d9c8b7b5e950083f04ef66a8a7b61"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "f40282f7972697d4f9d39e8d8c2f1c94",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 232205,
            "upload_time": "2023-11-11T13:45:28",
            "upload_time_iso_8601": "2023-11-11T13:45:28.479033Z",
            "url": "https://files.pythonhosted.org/packages/31/68/b111b5268bfba809be60389ca3236aa4db12dade6655936c4a8f865924b7/sgp4-2.23-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "160297ac48176a04a1ee7b61ecf619f05295f5be4e723c4a1127d484b77279ca",
                "md5": "347928f3e25d496dcbed4f0f5bf79f05",
                "sha256": "11962eee12a7422ebee88ef1b569851cd2db41830737f8c4669b2b5204ce2b39"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-win32.whl",
            "has_sig": false,
            "md5_digest": "347928f3e25d496dcbed4f0f5bf79f05",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 158857,
            "upload_time": "2023-11-11T13:45:29",
            "upload_time_iso_8601": "2023-11-11T13:45:29.783471Z",
            "url": "https://files.pythonhosted.org/packages/16/02/97ac48176a04a1ee7b61ecf619f05295f5be4e723c4a1127d484b77279ca/sgp4-2.23-cp39-cp39-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3a4d78c019b28e4a69ec2eeb7e035b817342c4a140956494545133b0a51b83a7",
                "md5": "ec08ed42b38e11ab67fcf05bb5e8e943",
                "sha256": "4536de17b1a501ca94a9d7ea336de0efc5bb22eb358d88d29a080d1c03d39326"
            },
            "downloads": -1,
            "filename": "sgp4-2.23-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "ec08ed42b38e11ab67fcf05bb5e8e943",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 160822,
            "upload_time": "2023-11-11T13:45:31",
            "upload_time_iso_8601": "2023-11-11T13:45:31.533045Z",
            "url": "https://files.pythonhosted.org/packages/3a/4d/78c019b28e4a69ec2eeb7e035b817342c4a140956494545133b0a51b83a7/sgp4-2.23-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "14c2ed46e67105a95acf4f06e2811f4381198a5acef57a960d98a74011a797cc",
                "md5": "caee2b14ee19df3add8a99974b867350",
                "sha256": "d8addc53a2fb9f88dee6bfd401d2865b014cc0b57bf2cee69bdee8d9685d5429"
            },
            "downloads": -1,
            "filename": "sgp4-2.23.tar.gz",
            "has_sig": false,
            "md5_digest": "caee2b14ee19df3add8a99974b867350",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 176937,
            "upload_time": "2023-11-11T13:45:32",
            "upload_time_iso_8601": "2023-11-11T13:45:32.839630Z",
            "url": "https://files.pythonhosted.org/packages/14/c2/ed46e67105a95acf4f06e2811f4381198a5acef57a960d98a74011a797cc/sgp4-2.23.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-11 13:45:32",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "brandon-rhodes",
    "github_project": "python-sgp4",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "sgp4"
}
        
Elapsed time: 2.74958s