Skip to main content

Interface to the Predict satellite tracking and orbital prediction library

Project description

ci

PyPredict

NOTE: To preserve compatibility with predict, pypredict uses north latitude and west longitude for terrestrial coordinates.

Do you want accurate and time-tested satellite tracking and pass prediction in a convenient python wrapper? You're in the right place.

PyPredict is a C Python extension directly adapted from the ubiquitous predict satellite tracking command line application. Originally written for the commodore 64, predict has a proven pedigree; We just aim to provide a convenient API. PyPredict is a port of the predict codebase and should yield identical results.

If you think you've found an error in pypredict, please include output from predict on same inputs to the bug report.
If you think you've found a bug in predict, please report and we'll coordinate with upstream.

Installation

sudo apt-get install python-dev
sudo python setup.py install

Usage

Observe a satellite (relative to a position on earth)

import predict
tle = """0 LEMUR 1
1 40044U 14033AL  15013.74135905  .00002013  00000-0  31503-3 0  6119
2 40044 097.9584 269.2923 0059425 258.2447 101.2095 14.72707190 30443"""
qth = (37.771034, 122.413815, 7)  # lat (N), long (W), alt (meters)
predict.observe(tle, qth) # optional time argument defaults to time.time()
# => {'altitude': 676.8782276657903,
#     'azimuth': 96.04762045174824,
#     'beta_angle': -27.92735429908726,
#     'decayed': 0,
#     'doppler': 1259.6041017128405,
#     'eci_obs_x': -2438.227652191655,
#     'eci_obs_y': -4420.154476060397,
#     'eci_obs_z': 3885.390601342013,
#     'eci_sun_x': 148633398.020844,
#     'eci_sun_y': -7451536.44122029,
#     'eci_sun_z': -3229999.50056359,
#     'eci_vx': 0.20076213530665032,
#     'eci_vy': -1.3282146055077213,
#     'eci_vz': 7.377067234096598,
#     'eci_x': 6045.827328897242,
#     'eci_y': -3540.5885778261277,
#     'eci_z': -825.4065096776636,
#     'eclipse_depth': -87.61858291647795,
#     'elevation': -43.711904591801726,
#     'epoch': 1521290038.347793,
#     'footprint': 5633.548906707907,
#     'geostationary': 0,
#     'has_aos': 1,
#     'latitude': -6.759563817939698,
#     'longitude': 326.1137007912563,
#     'name': '0 LEMUR 1',
#     'norad_id': 40044,
#     'orbit': 20532,
#     'orbital_model': 'SGP4',
#     'orbital_phase': 145.3256815318047,
#     'orbital_velocity': 26994.138671706416,
#     'slant_range': 9743.943478523843,
#     'sunlit': 1,
#     'visibility': 'D'
#    }

Show upcoming transits of satellite over ground station

# start and stop transit times as UNIX timestamp
transit_start = 1680775200
transit_stop = 1681034400

p = predict.transits(tle, qth, transit_start, transit_stop)

print("Start of Transit\tTransit Duration (s)\tPeak Elevation")
for transit in p:
    print(f"{transit.start}\t{transit.duration()}\t{transit.peak()['elevation']}")

Modeling an entire constellation

Generating transits for a lot of satellites over a lot of ground stations can be slow. Luckily, generating transits for each satellite-groundstation pair can be parallelized for a big speed-up.

import itertools
from multiprocessing.pool import Pool
import time

import predict
import requests

# Define a function that returns arguments for all the transits() calls you want to make
def _transits_call_arguments():
    now = time.time()
    tle = requests.get('http://tle.spire.com/25544').text.rstrip()
    for latitude in range(-90, 91, 15):
        for longitude in range(-180, 181, 15):
            qth = (latitude, longitude, 0)
            yield {'tle': tle, 'qth': qth, 'ending_before': now+60*60*24*7}

# Define a function that calls the transit function on a set of arguments and does per-transit processing
def _transits_call_fx(kwargs):
    try:
        transits = list(predict.transits(**kwargs))
        return [t.above(10) for t in transits]
    except predict.PredictException:
        pass

# Map the transit() caller across all the arguments you want, then flatten results into a single list
pool = Pool(processes=10)
array_of_results = pool.map(_transits_call_fx, _transits_call_arguments())
flattened_results = list(itertools.chain.from_iterable(filter(None, array_of_results)))
transits = flattened_results

NOTE: If precise accuracy isn't necessary (for modeling purposes, for example) setting the tolerance argument to the above call to a larger value, say 1 degree, can provide a significant performance boost.

Call predict analogs directly

predict.quick_find(tle.split('\n'), time.time(), (37.7727, 122.407, 25))
predict.quick_predict(tle.split('\n'), time.time(), (37.7727, 122.407, 25))

API

observe(tle, qth[, at=None])  
    Return an observation of a satellite relative to a groundstation.
    qth groundstation coordinates as (lat(N),long(W),alt(m))
    If at is not defined, defaults to current time (time.time())
    Returns an "observation" or dictionary containing:  
        altitude _ altitude of satellite in kilometers
        azimuth - azimuth of satellite in degrees from perspective of groundstation.
        beta_angle
        decayed - 1 if satellite has decayed out of orbit, 0 otherwise.
        doppler - doppler shift between groundstation and satellite.
        eci_obs_x
        eci_obs_y
        eci_obs_z
        eci_sun_x
        eci_sun_y
        eci_sun_z
        eci_vx
        eci_vy
        eci_vz
        eci_x
        eci_y
        eci_z
        eclipse_depth
        elevation - elevation of satellite in degrees from perspective of groundstation.
        epoch - time of observation in seconds (unix epoch)
        footprint
        geostationary - 1 if satellite is determined to be geostationary, 0 otherwise.
        has_aos - 1 if the satellite will eventually be visible from the groundstation
        latitude - north latitude of point on earth directly under satellite.
        longitude - west longitude of point on earth directly under satellite.
        name - name of satellite from first line of TLE.
        norad_id - NORAD id of satellite.
        orbit
        orbital_phase
        orbital_model
        orbital_velocity
        slant_range - distance to satellite from groundstation in meters.
        sunlit - 1 if satellite is in sunlight, 0 otherwise.
        visibility
transits(tle, qth[, ending_after=None][, ending_before=None])  
    Returns iterator of Transit objects representing passes of tle over qth.  
    If ending_after is not defined, defaults to current time  
    If ending_before is not defined, the iterator will yield until calculation failure.

NOTE: We yield passes based on their end time. This means we'll yield currently active passes in the two-argument invocation form, but their start times will be in the past.

Transit(tle, qth, start, end)  
    Utility class representing a pass of a satellite over a groundstation.
    Instantiation parameters are parsed and made available as fields.
    duration()  
        Returns length of transit in seconds
    peak(epsilon=0.1)  
        Returns epoch time where transit reaches maximum elevation (within ~epsilon)
    at(timestamp)  
        Returns observation during transit via quick_find(tle, timestamp, qth)
    aboveb(elevation, tolerance)
        Returns portion of transit above elevation. If the entire transit is below the target elevation, both
        endpoints will be set to the peak and the duration will be zero. If a portion of the transit is above
        the elevation target, the endpoints will be between elevation and elevation + tolerance (unless
        endpoint is already above elevation, in which case it will be unchanged)
quick_find(tle[, time[, (lat, long, alt)]])  
    time defaults to current time   
    (lat, long, alt) defaults to values in ~/.predict/predict.qth  
    Returns observation dictionary equivalent to observe(tle, time, (lat, long, alt))
quick_predict(tle[, time[, (lat, long, alt)]])  
        Returns an array of observations for the next pass as calculated by predict.
        Each observation is identical to that returned by quick_find.

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

pypredict-1.8.0.tar.gz (48.5 kB view details)

Uploaded Source

Built Distributions

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

pypredict-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (124.9 kB view details)

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

pypredict-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (124.8 kB view details)

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

pypredict-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (124.2 kB view details)

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

pypredict-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (124.2 kB view details)

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

pypredict-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (124.0 kB view details)

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

pypredict-1.8.0-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (124.0 kB view details)

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

pypredict-1.8.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl (108.2 kB view details)

Uploaded CPython 2.7mumanylinux: glibc 2.5+ x86-64

pypredict-1.8.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (108.2 kB view details)

Uploaded CPython 2.7mmanylinux: glibc 2.5+ x86-64

File details

Details for the file pypredict-1.8.0.tar.gz.

File metadata

  • Download URL: pypredict-1.8.0.tar.gz
  • Upload date:
  • Size: 48.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for pypredict-1.8.0.tar.gz
Algorithm Hash digest
SHA256 5bc6f4f2a3a295e1a5b5067666aba1cc1478dcf28783246a25b65e7a444c1352
MD5 a2c4356dbdb4424acaf7aafd295642bd
BLAKE2b-256 e93e971f65f4800de8ee62c65643f790064c322cd006ec76bdcb2223fec531b3

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 dda26285b8ff5a2b4e78ad9a92feee6b474017dbde6f1f6fd6c7f79f71f0f1a1
MD5 34ec8e97c83e6dd0b1b1a813da759635
BLAKE2b-256 2f4a82f240f8ed78173e311ec295c55f76ce1d32194c56e88e0e0ca3b4c05431

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 96b4a96b64442db8bfad780ef166ebf5dc6ee415b26ba31d099b5f9e1a4b881a
MD5 f626c71486a481d5e4658aee9437c99e
BLAKE2b-256 ad2e2b5a70e83669b679d713218977c2967323feee879a2f90265b1e7714a19f

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 21c1d51f71408c77286b81df22632a4f508bbbfc1977bc9e2a4d05a174af77f0
MD5 1dc3dae4a350935a9845613532400aee
BLAKE2b-256 846b59c9853cc5155dc0129586cadbf9d00531f21874f421dc3512a23b26b3da

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 57b241f6dddbc4c0b84912f57cdb5da1b5b1eac54bec7ae7abfa54870ea0e234
MD5 da866d19212150f7b53ab26d0b875619
BLAKE2b-256 2f35b0b5f2d457c8a2ce6d6d157ea0ebc4a7ae852cb51ecc0208b19df363326f

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 1b48fa7f88410e8e760b29ab4f20df2ab402c14c0bbf26d9e1be81b5d13f1aff
MD5 5500bec0b26754e57b65f9ddfd404887
BLAKE2b-256 e339b0e024595d236a967abd83aabccbd9c80ae13092e350ca44968b5b72290e

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 97e876e88ccb6849bbd98b475046d53fe92e7da1aed8e3227d6663da49abc4a6
MD5 25c8afa4dd73e0843820f7481e297763
BLAKE2b-256 0b7d809bf727b97ddbb967281209792f397399fa31a1e88ec3d8938ded317865

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 d94690713699446b780af653d1529bb97fb510318ccc3060e673383d582907d3
MD5 77bc0f09dc0afb6aa9cca53ad22ab927
BLAKE2b-256 4d2ee9b7b23a04797d3770ab9fafdd7384ec1750e0573ae83fefade5217b3674

See more details on using hashes here.

File details

Details for the file pypredict-1.8.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pypredict-1.8.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 e36e88239f5e1c35ac2fef3f962f3581afd6b3673a20e7d93f3cbdf604e30b75
MD5 f894e4fff3a3ed6fdc89dd5cb95d2e22
BLAKE2b-256 f7938673ad1f56a26d3ca038a42d98cb7e342025e99236d8a2d8d0cc96212778

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