Skip to main content

Simple and light-weight JPL ephemeris parser and tracking engine for astronomy and telescope guidance. Provides simple lists of ephemeris data for any Target Body available through the JPL Horizons App. Also provides real-time tracking of those data for the duration of an ephemeris.

Project description

Simple and light-weight JPL ephemeris parser and tracking engine for astronomy and telescope guidance. Provides simple lists of ephemeris data for any Target Body available through the JPL Horizons App. Also provides real-time tracking of those data for the duration of an ephemeris.

Sunspot

Sunspot recovers ephemerides using JPL's back-end HTML interface. As a result, no need to load binary SPK files (.bsp). A user must only identify a Target Body and Observer Quantities from the JPL Horizons App. Any planet, satellite, spacecraft, asteroid, or comet available in the JPL Horizons App is available through Sunspot. Sunspot provides simple parsed lists of strings for each quantity, e.g., a list of azimuth and elevation values where a Target Body can be found in the sky. Because all data are computed and furnished from JPL, Sunspot incurs very little computational overhead aside from initial parsing.

In addition to data recovery from JPL, Sunspot provides a client tool for tracking Observer Quantities. For situations where a user wishes to update a web server as a function of Target Body status, guide a telescope over time, orchestrate hardware control based upon the sun's position, and the like, Sunspot provides a Tracker class to execute user-defined methods with sub-second precision. A user can elect to execute methods before ("setup"), at ("test"), and/or after ("clean-up") individual ephemeris events, for the duration of that ephemeris.

Create Ephemeris

One can create an ephemeris for our Sun with a call to the Ephemeris constructor:

>>> import sunspot
>>> e = sunspot.Ephemeris(  '2023-06-18 19:26:00',          # start time as 'YYYY-MM-DD HH:MM:SS' (24h clock)
                            '2023-06-21 19:28:00',          # stop time as 'YYYY-MM-DD HH:MM:SS' (24h clock)
                            '-71.332597,42.458790,0.041',   # 'longitude, latitude, elevation [kilometers]' for observer
                            '1 minute',                     # 'n t', where 1 <= n <= 90024 and t is a unit of time, e.g., 'minute', 'hour', 'day', 'month', 'year'
                            '10',                           # Target body code for our Sun, see below
                            '4')                            # Observer Quantity for apparent azimuth and elevation, see below

In this example, the Target Body azimuth and elevation was requested. Those Observer Quantities can be checked:

>>> titles = e.DATA_TITLES
>>> titles
['Date__(UT)__HR:MN:SS', 'Azimuth_(a-app)', 'Elevation_(a-app)']

And one can simply view a list of those data:

>>> azimuth = titles[1]
>>> e.get_ephemeris_data( azimuth )
['252.781222419', '253.019121568', ... , '252.896492970', '253.133817632']

For each data point in every list, there is a corresponding time stamp. One can use the convenience method to view the time stamps:

>>> e.dates()
['2023-06-18 19:26:00', '2023-06-18 19:27:00', ... , '2023-06-21 19:27:00', '2023-06-21 19:28:00']

Each list is always in chronological order such that the nth azimuth entry corresponds to the nth e.dates() entry.

One can also use one list of data to identify value(s) in another. For example, one can find at what time(s) the sun can be found at a specific azimuthal angle:

>>> dates = titles[0]
>>> azimuth = titles[1]
>>> east = '90.128595258' 
>>> e.find_corresponding_data(  dates,      # we wish to find a value from this list
                                azimuth,    # using a value from this list
                                east )      # with this specific 'azimuth' value
'2023-06-21 12:41:00'                             

Identify Observer Quantities and Target Bodies

Sunspot acquires and parses data from the JPL Horizons App. As such, Target Bodies and Observer Quantities available through the web app are also valid arguments for the Sunspot Ephemeris. However, there are a few things to keep in mind.

  • In general, Sunspot will throw errors and print something descriptive if a user attempts to pass an invalid parameter.
  • The surest way to identify a Target Body is to first generate that ephemeris in the JPL Horizons App. To do this, select Edit at the Target Body row item (row item 2). Use the search function to find your target. Then, Generate Ephemeris. The numerical code that prints at the top of the ephemeris can be passed to Sunspot to achieve the same result in python. For example, searching "sun" returns 'Sun [Sol]'. However, the correct Sunspot argument is '10', which can only be seen at the top of the generated ephemeris.
  • Similarly, Observer Quantities are best identified using the JPL Horizons App. Select Edit at the Table Settings row item (row item 5). Any combination of Observer Quantities can be requested from a Sunspot Ephemeris by passing the integer value as a comma-deliminated string. In the example above, the Ephemeris e uses Observer Quantity = '4' to recover target apparent azimuth and elevation. To recover the first five Observer Quantities listed in the App, use '1,2,3,4,5', and so on.

Track Ephemeris data over time

Sunspot includes a Tracker class to allow a user to execute a function before, at, or immediately after an Ephemeris event with sub-second precision.

Tracker accepts user-defined functions like the following:

def before( args: list ):
    # method executes before Ephemeris entry, 
    # e.g., do 'setup' stuff here
    ...

def on_time( args: list ):
    # method executes at instant of Ephemeris entry, 
    # e.g., do data capture or event confirmation exactly at the moment of an Ephemeris time stamp
    ...

def after( args: list ):
    # method executes after Ephemeris entry, 
    # e.g., do 'clean-up' stuff here
    ...

User-defined functions must accept a list of strings. This list corresponds to the Observer Quantities for a given Ephemeris entry. For the example Ephemeris above, Tracker methods will be called with a list of three strings: 'Date__(UT)__HR:MN:SS', 'Azimuth_(a-app)', and 'Elevation_(a-app)'. The order of the arguments in the list are the same order as e.DATA_TITLES.

Tracker has a simple constructor to begin tracking:

>>> t = sunspot.Tracker(    e,                                  # an Ephemeris object
                            track_before_method = before,       # user-generated method runs BEFORE Ephemeris event
                            track_on_time_method = on_time,     # user-generated method runs AT Ephemeris event
                            track_after_method = after )        # user-generated method runs AFTER Ephemeris event

User-defined functions can have any name. A user can choose to implement one, two, or all three functions.

API Reference

sunspot.Ephemeris

Ephemeris(  start_time: str, 
            stop_time: str, 
            observer_location: str, 
            step_size: str, 
            target_body: str, 
            quantities: str = '1,2,4' ):
'''
:param start_time: 'YYYY-MM-DD HH:MM:SS'
:param stop_time: 'YYYY-MM-DD HH:MM:SS'
:param observer_location: '00,00,00' as 'latitude [fractional degrees], longitude [fractional degrees], elevation [kilometers]'
:param step_size: 'n t', where 1 <= n <= 90024 (the maximum number of entries) and t is a unit of time, e.g., 'minute', 'hour', 'day', 'month', 'year'
:param target_body: observable target from JPL index, here: https://ssd.jpl.nasa.gov/horizons/app.html#/
:param quantities: observer quantities from JPL index, here: https://ssd.jpl.nasa.gov/horizons/app.html#/ . Default includes right ascension, declination, and altitude/azimuth
'''
Ephemeris.dates( )
'''
:return: A list of ephemeris dates, in chronological order.
'''
Ephemeris.find_corresponding_data(     target_data_column_title: str, 
                                        source_data_column_title: str, 
                                        source_data_point: str ):
'''
Retrieve data point from within target_data_column, corresponding to source_data_point from within source_data_column.
:param target_data_column_title: String title corresponding to a column of ephemeris data in which to search, e.g., "Azi____(a-app)___Elev"
:param source_data_column_title: String title corresponding to a column of ephemeris data from where search datum originates, e.g., "Date__(UT)__HR:MN:SS"
:param source_data_point: String datum found within source_data_column for which a corresponding row returns.
:return: None if source_data_point not found in source_data. If source_data_point appears only once, return corresponding datum from target_data. If source_data_point appears more than once, return a list of corresponding data in chronological order.
'''
Ephemeris.get_ephemeris_data( column_title: str )
'''
:param column_title: String title corresponding to a column of ephemeris data, e.g., "Date__(UT)__HR:MN:SS" or Ephemeris.DATA_TITLES[n] where n is a valid index.
:return: A list of data corresponding to an ephemeris data column title. Entries in this list are in chronological order.
'''

Ephemeris.DATA_TITLES -> list : List of column headers associated with Observer Quantities requested by user.

Ephemeris.RAW_DATA -> str : Unparsed data output from JPL.

sunspot.Tracker

Tracker(    e: Ephemeris,
            track_before_method: callable( list ) = None,
            track_on_time_method: callable( list ) = None,
            track_after_method: callable( list ) = None,
            verbose: bool = False )
'''
Create Tracker object. Tracking begins automatically upon object creation. Tracker objects will automatically track beginning with the next-soonest date. If no next-soonest date, e.g., all dates are in past, SystemError results.
:param e: Ephemeris object.
:param track_before_method: User-defined method. Must accept list of strings corresponding to Ephemeris _Observer Quantities_. Optional argument.
:param track_on_time_method: User-defined method. Must accept list of strings corresponding to Ephemeris _Observer Quantities_. Optional argument.
:param track_after_method: User-defined method. Must accept list of strings corresponding to Ephemeris _Observer Quantities_. Optional argument.
:param verbose: If True, prints method execution time stamps to terminal.
'''
Tracker.terminate_tracking( )
'''
Terminate tracking for a current Tracker object.
:return: None
'''

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

sunspot-0.71.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

sunspot-0.71-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file sunspot-0.71.tar.gz.

File metadata

  • Download URL: sunspot-0.71.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.0

File hashes

Hashes for sunspot-0.71.tar.gz
Algorithm Hash digest
SHA256 22c961e31845c71bcb80aae0bd34c584d8c1f05b3529323d5ca60a2ba3091b79
MD5 d5438570eb682afeaed1c027751f37b7
BLAKE2b-256 96b291d797b2a0920a8277dd14d4a850a816d3aeed48ee631b345ba0f610f60d

See more details on using hashes here.

File details

Details for the file sunspot-0.71-py3-none-any.whl.

File metadata

  • Download URL: sunspot-0.71-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.0

File hashes

Hashes for sunspot-0.71-py3-none-any.whl
Algorithm Hash digest
SHA256 d7630b90713929b346879fe6724f6aa6a99ac39e3c4e7745d68ea9c6489f72ae
MD5 545e266be3db108d27cddda1f0a99314
BLAKE2b-256 11bf9c3a326fe7405bdcf93667e58f70392358438324a8b699dbd7245672cee9

See more details on using hashes here.

Supported by

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