Skip to main content

The C++ SGP4 routine that, given an Earth satellite TLE, computes its position.

Project description

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.

What we today call ‘SGP4’ in fact merges together what in the 1970s were originally two separate satellite propagation routines, but which are now selected automatically:

  • SGP4 — the ‘Simplified General Perturbations’ model is used for satellites close enough to Earth that their orbit takes less than 225 minutes (3 hours 45 minutes) to complete.

  • SDP4 — the ‘Simplified Deep Space Perturbations’ model is used for satellites farther from Earth, which take 225 minutes or longer to compete an orbit.

If your machine can’t install or compile the C++ code, then this package falls back to using a slower pure-Python implementation of the library. 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 library that is built atop this one (see the section on Earth satellites 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 are 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” 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. The fastest and most efficient format is usually CSV, since the column names are only given once, on the first line:

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

The JSON format is more verbose because it repeats the field names over again in every single record:

>>> import json
>>> with open('sample_omm.json') as f:
...     record_list = json.load(f)
>>> for fields in record_list:
...     sat = Satrec()
...     omm.initialize(sat, fields)

The most verbose format is XML:

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

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

The omm.initialize() routine uses the standard WGS72 gravity model by default. To make your own choice of model, supply a third argument that is one of the three constants WGS72OLD, WGS72, or WGS84 (which are shown below in the section on ‘Gravity’).

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..2pi)
...     0.9013560935706996,   # inclo: inclination (radians 0..pi)
...     1.4946964807494398,   # mo: mean anomaly (radians 0..2pi)
...     0.06763602333248933,  # no_kozai: mean motion (radians/minute)
...     3.686137125541276,    # nodeo: R.A. of ascending node (radians 0..2pi)
... )

You might notice that these numbers don’t look the same as the numbers in the TLE above. For example, the inclination was 51.6439 in the TLE, but is 0.901356 here. That’s because sgp4init() uses different units than the TLE format: angles are in radians rather than degrees. But this is the same orbit and will produce the same positions.

If you want to double-check that your elements are valid, you can run the function check_satrec(), which will raise a ValueError with an informative error message if any of the angles are out of bounds. If the satellite is fine, it simply returns, without raising an exception:

>>> from sgp4.conveniences import check_satrec
>>> check_satrec(satellite2)

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 0 ≤ i < pi).
nodeo — Right ascension of ascending node (radians 0 ≤ Ω < 2pi).
ecco — Eccentricity.
argpo — Argument of perigee (radians 0 ≤ ω < 2pi).
mo — Mean anomaly (radians 0 ≤ M < 2pi).
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:

  1. No error.

  2. Mean eccentricity is outside the range 0 ≤ e < 1.

  3. Mean motion has fallen below zero.

  4. Perturbed eccentricity is outside the range 0 ≤ e ≤ 1.

  5. Length of the orbit’s semi-latus rectum has fallen below zero.

  6. (No longer used.)

  7. 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

Each time the SGP4 routine generates a satellite position, it also saves a set of “singly averaged mean elements” that describe shape of the satellite’s orbit at that moment. 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. You can always download the latest version of their code for comparison against this Python module (or other implementations) at 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

2026-07-03 — 2.27

  • Moved the project documentation out of the __init__.py docstring and into the source code README file, which should hopefully make the documentation reappear on the project’s PyPI page.

2026-06-26 — 2.26

  • The C++ module now limits itself to calling the Python Limited API and can therefore link against the Python Stable ABI, producing a binary wheel that’s compatible with multiple versions of Python. Hopefully this means that new Python releases no longer require sgp4 to be immediately re-released to support them.

2025-08-04 — 2.25

  • Added a gravconst parameter to the omm.initialize() routine for folks using gravity models other than WGS72, or who at least want to make that choice explicit in their code.

  • Added a revnum attribute to satellites built with sgp4init() (it defaults to the dummy value of zero), so they can be passed to export_tle() without raising an exception.

2024-02-15 — 2.24

  • The documentation now specifies the acceptable range for orbital element angles like inclination and mean anomaly, and a new function check_satrec(sat) will tell the caller if any of the angles are out of bounds.

  • The documentation now gives an example of loading elements from JSON.

  • Tweaked the fallback Python code to accept TLE lines without a final checksum character in the 69th column, to match the C++ code.

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sgp4-2.27.tar.gz (180.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sgp4-2.27-py3-none-any.whl (123.3 kB view details)

Uploaded Python 3

sgp4-2.27-cp311-abi3-win_amd64.whl (148.9 kB view details)

Uploaded CPython 3.11+Windows x86-64

sgp4-2.27-cp311-abi3-win32.whl (147.3 kB view details)

Uploaded CPython 3.11+Windows x86

sgp4-2.27-cp311-abi3-musllinux_1_2_x86_64.whl (214.9 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

sgp4-2.27-cp311-abi3-musllinux_1_2_aarch64.whl (215.6 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

sgp4-2.27-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (219.4 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

sgp4-2.27-cp311-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (218.1 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ x86-64manylinux: glibc 2.5+ x86-64

sgp4-2.27-cp311-abi3-macosx_11_0_arm64.whl (147.7 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

sgp4-2.27-cp311-abi3-macosx_10_9_x86_64.whl (148.9 kB view details)

Uploaded CPython 3.11+macOS 10.9+ x86-64

sgp4-2.27-cp310-cp310-win_amd64.whl (148.9 kB view details)

Uploaded CPython 3.10Windows x86-64

sgp4-2.27-cp310-cp310-win32.whl (147.3 kB view details)

Uploaded CPython 3.10Windows x86

sgp4-2.27-cp310-cp310-musllinux_1_2_x86_64.whl (217.3 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

sgp4-2.27-cp310-cp310-musllinux_1_2_aarch64.whl (217.8 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ ARM64

sgp4-2.27-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (221.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

sgp4-2.27-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (220.4 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64manylinux: glibc 2.5+ x86-64

sgp4-2.27-cp310-cp310-macosx_11_0_arm64.whl (147.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

sgp4-2.27-cp310-cp310-macosx_10_9_x86_64.whl (149.0 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

File details

Details for the file sgp4-2.27.tar.gz.

File metadata

  • Download URL: sgp4-2.27.tar.gz
  • Upload date:
  • Size: 180.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27.tar.gz
Algorithm Hash digest
SHA256 06d37247c6985739b707b8b39b6b83e06e8af783b2531e31965501ba983985f9
MD5 513f7a4745061b1a4ca06371b498536a
BLAKE2b-256 a862e1282ea86299c76159e182cd36046e6d7980b120fef14c101757e1f650b3

See more details on using hashes here.

File details

Details for the file sgp4-2.27-py3-none-any.whl.

File metadata

  • Download URL: sgp4-2.27-py3-none-any.whl
  • Upload date:
  • Size: 123.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.4.24

File hashes

Hashes for sgp4-2.27-py3-none-any.whl
Algorithm Hash digest
SHA256 5f3f5716649988b638fbe7fcda592830e0956f548ca273b93cfa5f75917b9087
MD5 89310df5e58e34192cbe664db204bbd4
BLAKE2b-256 78cd06dc91b31f2b919e788396c2cb5ad313d5ce0754321165343fd585c4be53

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: sgp4-2.27-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 148.9 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 827c63feb60987ad177c2c80f3a927e721ead2f444d6560cd2a4337ca90d2490
MD5 f3846f0fbd524b9354d1015296af5fab
BLAKE2b-256 d5b56e76ddece37a130c1c4c33a0ca2ae381c7aad733ca8e3d9b451594711fc0

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-win32.whl.

File metadata

  • Download URL: sgp4-2.27-cp311-abi3-win32.whl
  • Upload date:
  • Size: 147.3 kB
  • Tags: CPython 3.11+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp311-abi3-win32.whl
Algorithm Hash digest
SHA256 951ec95ea7f0fe0b5307fc2cd9d28c8923048bcf376b11c6cd93739e15b4722d
MD5 51d9660131ef4a6a399b3f2755f87356
BLAKE2b-256 5662c14d2aaa36ff6e749189e3576c70f3ed21f3ba72fa69e924f20581e760c1

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: sgp4-2.27-cp311-abi3-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 214.9 kB
  • Tags: CPython 3.11+, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 63d30826ebd303e66f184b1e3feba30524d01a379e50baacd47732dd447d97ab
MD5 c47e05780a8abb254bcc0beabfd65db5
BLAKE2b-256 f45de7f4a9035cc62e4d10e35f22477498458520cb32b20eed5b4a9e7854d15d

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: sgp4-2.27-cp311-abi3-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 215.6 kB
  • Tags: CPython 3.11+, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 26cfb6b8ace44e56b71cba79294da61af083b96c6b12f6229dc761c4d8c833eb
MD5 d3b2022699fc2f5ae4dbbe3e60603e50
BLAKE2b-256 30848eebceb87dee7e7095d78375c473b57471c964d87b676c138e2da3e901bb

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for sgp4-2.27-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ef915c124cdd9807a4eae0abe655ade89076c2cee5df0392cad172aef456cd0e
MD5 bd989041b1b454b3e6aac234d01fa2c6
BLAKE2b-256 bcbfa279758ff3eb290cc5658f035845d3107d9728e1d2d52629c9683845313a

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for sgp4-2.27-cp311-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 4d3775313120dcb6239535fa0c94cb6d5b089fd84bbfb15220923ae38dec7296
MD5 35fa085222e7ef46ebb93bced236dc2c
BLAKE2b-256 d675633ad7874db149df164168090951e676cdc3541a12d43b2cbb9d20ecb721

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: sgp4-2.27-cp311-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 147.7 kB
  • Tags: CPython 3.11+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ee68f73cb2383bc950eada2ca1b10357b0165dbf5ab75185962009375bab8761
MD5 01ddccc7a67dea63d4fa3d46edc2431f
BLAKE2b-256 36d905fd166d8f74b326590e78bb13148d6b359ae32be5cd39082fd8a292bf50

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp311-abi3-macosx_10_9_x86_64.whl.

File metadata

  • Download URL: sgp4-2.27-cp311-abi3-macosx_10_9_x86_64.whl
  • Upload date:
  • Size: 148.9 kB
  • Tags: CPython 3.11+, macOS 10.9+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp311-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5ae1394cf0d91f54418530b02a797b14c10bb28e3f4ab616cad79a3fd67e2399
MD5 751db8c282e0217efb7a7b6e6b51ee2b
BLAKE2b-256 c10601c556ab39ef9c161b44d171fbb0990f59d5079d77959409c1f97685d269

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: sgp4-2.27-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 148.9 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 bc6b0a70f7bbe816af6a7f8deebec4d091e49b72498cb5d5b19850fd36219e63
MD5 4a93cb5bb7ec96a713d740a306ec6c89
BLAKE2b-256 327ddc98fc30ce968a5739875f5118e0d1bbb8e92041fe78187c8405b858469a

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-win32.whl.

File metadata

  • Download URL: sgp4-2.27-cp310-cp310-win32.whl
  • Upload date:
  • Size: 147.3 kB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 00de539ce409011e2671031c3ab2f46d4dba17ca96c7db68d593851613bd68df
MD5 e254a0bf4e63ba4bf3a60e88f81c1dc4
BLAKE2b-256 3491768468cb182d1e16917f5795fb76cfc40a363e0b75456b837c37c651a8a7

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: sgp4-2.27-cp310-cp310-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 217.3 kB
  • Tags: CPython 3.10, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d6d0457252357db7546938b803ef207f1be8915887c229bf61e1714c4005412e
MD5 9bf07563cd44e8ca44605f92a41f9471
BLAKE2b-256 6c38aef037f0b0af7d6b87e00b0a4d1b17a496b8840d0c1c45c5b91f5a87ef0d

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for sgp4-2.27-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1bce996676f2f7abca1a6b941a1c9b1dbbc18965c4b1d3e144a52176e717b915
MD5 2660d2b5192e8d8616331d541f3fedd9
BLAKE2b-256 8c8e7ecb9ebf4e613f3a139cdd3b8683a8a59fb751743dc6d5d7eb8f4bb35db5

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for sgp4-2.27-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 37f1c4d88ab89d9d1a6984b5a71126f3d65326df6f9b4df9dd6b3137633272d7
MD5 e94a41fdbab226939c8c495b6815b541
BLAKE2b-256 4a0df52ae73298839c77ac854c8e174ae812ca06934726b4e483abb1859fb133

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for sgp4-2.27-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 d2fc2f68421b50757b7960199a0a7907b9b9807a1b78b9c70fa3523a8a63b630
MD5 f283b20617935b1b0f65531c7f81113a
BLAKE2b-256 68eb874cbbf049adb6e61d1e156c64002ce82874a370b3bb02e0ad89284f4162

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

  • Download URL: sgp4-2.27-cp310-cp310-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 147.8 kB
  • Tags: CPython 3.10, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sgp4-2.27-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cfd220b587d4f8fd999312c0b53488a37b45126b5c09b6b8d8b930fcb3558728
MD5 b3d3c9f558a570c894c93845dff75c90
BLAKE2b-256 0bc01c71b951b39ca9edf9c9f6c7d852f2edae244ca63e7f6a7d5ad115eae535

See more details on using hashes here.

File details

Details for the file sgp4-2.27-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for sgp4-2.27-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 89146bc62ec8c880ef991968ba2820c218d5c917ccc3291747aff2da4eccc30d
MD5 fd5748e628907de44ac539e159325035
BLAKE2b-256 19ca69b562fb626fc2485f30aef64e31c1fbee9fca8f6d848e4545f34116c22f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page