EMBERS: HomeTable of ContentsAPI Reference

API Reference — Sat Utils

embers.sat_utils is used to compute various satellite orbital parameters

It contains sat_list, sat_ephemeris, chrono_ephem & sat_channels

Satellite List

Dictionary of satellite names and their NORAD Catalogue IDs. These satellites are active in the 137 to 139 MHz frequency window. Include ORBCOMM Communication satellites and NOAA & METEOR Weather satellites.

Includes a method to download TLE orbital parameters from Space-Track.org

Warning

To download TLEs from Space-Track.org, make an account and obtain login credentials.

embers.sat_utils.sat_list.norad_ids()

Dictionary of NORAD Satellite Catalogue IDs.

from embers.sat_utils.sat_list import norad_ids
sat_dict = norad_ids()
print(sat_dict)
>>> {'ORBCOMM-X': 21576, 'ORBCOMM FM 1': 23545, ...}
Returns:
  • norad_ids - satellite name : NORAD CATID dict
embers.sat_utils.sat_list.download_tle(start_date, stop_date, norad_ids, st_ident=None, st_pass=None, out_dir=None, sleep=20, mock=False)

Download TLEs from space-track.org.

Download satellite TLEs within a date interval for all sats in norad_ids()

from embers.sat_utils.sat_list import norad_ids, download_tle
n_ids = norad_ids()
download_tle(
    "2020-01-01", "2020-02-01", n_ids,
    st_ident="test.user@embers.com",
    st_pass="*******",
    out_dir="~/embers-data/TLE")
>>> Starting TLE download
>>> Grab a coffee, this may take a while
>>> downloading tle for ORBCOMM-X satellite [21576] from space-tracks.org
>>> ...
Parameters:
  • start_date – in YYYY-MM-DD format str
  • stop_date – in YYYY-MM-DD format str
  • norad_ids – sat_name: NORAD_ID dict
  • st_ident – space-track.org login identity str
  • st_pass – space-track.org login password str
  • out_dir – output dir to save TLE files str
  • sleep – The amount of time to sleep between downloads. Default is 20 so as not to exceed the space-track download limit
  • mock – For testing purposes. If True, will use a sample string to write test data to tle file
Returns:

  • tle file - saved to output directory

Satellite Ephemeris

A set of tools to calculate satellite ephemeris from TLE files.

embers.sat_utils.sat_ephemeris.load_tle(tle_file)

Extract orbital parameters from a TLE file.

Instantiate an EarthSatellite for each pair of TLE lines in the TLE file, Also return the ‘epoch’ of each EarthSatellite object, which is the date and time for which the set of TLE lines is most accurate.

from embers.sat_utils.sat_ephemeris import load_tle
sats, epochs = load_tle('~/embers-data/TLE/21576.txt')
Parameters:tle_file – path to TLE file str
Returns:A tuple (sats, epochs)
  • sats - list of EarthSatellite objects, one for each pair of TLE lines
  • epochs - Julian date at which each set of TLE lines is most accurate
embers.sat_utils.sat_ephemeris.epoch_ranges(epochs)

Optimise time intervals to make the most of different epochs of TLE pairs

Creates a list with of times [epoch_range], pairs of successive elements of which correspond to time intervals at which a particular epoch has best accuracy, before the next epoch becomes more accurate. This is done to ensure that the most relevanrt TLE is used in the analysis.

from embers.sat_utils.sat_ephemeris import load_tle, epoch_ranges
sats, epochs = load_tle('~/embers-data/TLE/21576.txt')
epoch_range = epoch_ranges(epochs)
Parameters:epochs – List of epochs from load_tle()
Returns:epoch_range: List of times, between which each pair of TLEs is most accurate
embers.sat_utils.sat_ephemeris.epoch_time_array(epoch_range, index_epoch=None, cadence=None)

Create a Skyfield Timescale object at which to evaluate satellite positions.

Begins by downloading up-to-date time files, using the skyfield Loader class, needed to accurate converted between various time formats. See Dates and Time for more info. The files are saved to ./embers_out/sat_utils/skyfield-data.

For a particular time inverval in epoch_range, chosen by index_epoch, a Skyfield Timescale array object is generated, at a given time cadence. This time array will be used by sat_pass() to compute the position of satellites at each time.

from embers.sat_utils.sat_ephemeris import load_tle, epoch_ranges, epoch_time_array
sats, epochs = load_tle('~/embers-data/TLE/21576.txt')
epoch_range = epoch_ranges(epochs)
index_epoch = 0     # select first time interval from epoch_range
cadence = 10        # evaluate satellite position every 10 seconds

t_arr, index_epoch = epoch_time_array(epoch_range, index_epoch, cadence)
Parameters:
  • index_epoch – Index of epoch_range to be converted to time array int
  • epoch_range – List of time intervals where an epoch is most accurate, from embers.sat_utils.sat_ephemeris.epoch_ranges()
  • cadence – Time cadence at which to evaluate sat position, in seconds int
Returns:

A tuple of (t_arr, index_epoch)

  • t_arr: Skyfield Timescale object with array of times at given cadence
  • index_epoch: Index of epoch_range to be converted to time array int

embers.sat_utils.sat_ephemeris.sat_pass(sats, t_arr, index_epoch, location=None)

Find when a satellite passes above the horizon at a gps location.

Calculate the Altitude & Azimuth of a EarthSatellite object from load_tle() at every instant of time in t_arr from epoch_time_array(). Determine all the times that the satellite is above the horizon, at a given gps location and returns the pair of indices of t_arr at which the satellite rose and set.

from embers.sat_utils.sat_ephemeris import load_tle, epoch_ranges, epoch_time_array, sat_pass
sats, epochs = load_tle('~/embers-data/TLE/21576.txt')
epoch_range = epoch_ranges(epochs)
index_epoch = 0     # select first time interval from epoch_range
cadence = 10        # evaluate satellite position every 10 seconds
t_arr, index_epoch = epoch_time_array(epoch_range, index_epoch, cadence)
MWA = (-26.703319, 116.670815, 337.83)   # gps coordinates of MWA Telescope

passes, alt, az = sat_pass(sats, t_arr, index_epoch, location=MWA)
Parameters:
  • sats – list of EarthSatellite objects
  • t_arr – skyfield Timescale object with array of times
  • index_epoch – Index of epoch_range int
  • location – The gps coordinates of the location at which satellite passes are to be computed. location is a tuple in the format (latitude, longitude, elevation), with elevation given in meters
Returns:

A tuple of (passes, alt, az)

  • passes: 2D array with pairs of indicies of t_arr corresponding to rise/set of satellite ndarray
  • alt: Array of Altitudes of sat at t_arr times ndarray
  • az: Array of Azimuths of sat at t_arr times ndarray

embers.sat_utils.sat_ephemeris.ephem_data(t_arr, pass_index, alt, az)

Satellite Ephemeris data (time, alt, az arrays ) for a single satellite pass.

from embers.sat_utils.sat_ephemeris import load_tle, epoch_ranges, epoch_time_array, sat_pass, ephem_data
sats, epochs = load_tle('~/embers-data/TLE/21576.txt')
epoch_range = epoch_ranges(epochs)
index_epoch = 0     # select first time interval from epoch_range
cadence = 10        # evaluate satellite position every 10 seconds
t_arr, index_epoch = epoch_time_array(epoch_range, index_epoch, cadence)
MWA = (-26.703319, 116.670815, 337.83)   # gps coordinates of MWA Telescope
passes, alt, az = sat_pass(sats, t_arr, index_epoch, location=MWA)

time_array, sat_alt, sat_az = ephem_data(t_arr, passes[0], alt, az)
Parameters:
  • t_arr – skyfield Timescale object with array of times
  • pass_index – One pair of sat indicies from passes
  • alt – Array of altitudes of sat at t_arr times
  • az – Array of azimuths of sat at t_arr times
Returns:

A tuple (time_array, sat_alt, sat_az)

  • time_array: times at which sat position is calculated ndarray
  • sat_alt: Altitude of satellite while it is above the horizon ndarray
  • sat_az: Azimuth of satellite while it is above the horizon ndarray

embers.sat_utils.sat_ephemeris.sat_plot(sat_id, alt, az, alpha=0.5)

Plots satellite passes

Parameters:
  • sat_id – Norad catalogue ID str
  • altAltitude list
  • azAzimuth list
  • alpha – transparency of individual passes, default=0.5
Returns:

embers.sat_utils.sat_ephemeris.save_ephem(sat, tle_dir, cadence, location, alpha, out_dir)

Save ephemeris of all satellite passes and plot sky coverage.

This function brings everything in sat_ephemeris home. It converts a downloaded TLE file into arrays of times, Altitudes & Azimuths of when the satellite was above the horizon at a particular geographic location. These arrays are saved to the out_dir as an savez_compressed file. A plot of all satellite passes detected within the TLE file is also saved to the out_dir.

from embers.sat_utils.sat_ephemeris import save_ephem
sat="21576"
cadence = 4
tle_dir="~/embers-data/TLE"
out_dir = "./embers_out/sat_utils"
location = (-26.703319, 116.670815, 337.83) # MWA Telescope

sat_ephem(sat, tle_dir, cadence=cadence, location, out_dir)
Saved sky-coverage plot of sat [21576] to ./embers_out/sat_utils/ephem_plots
Saved ephemeris of sat [21576] to ./embers_out/sat_utils/ephem_data
Parameters:
  • sat – NORAD Catalogue ID of satellite str
  • tle_dir – path to directory where TLE files are saved str
  • cadence – time cadence at which to evaluate sat position, in seconds int
  • location – The gps coordinates of the location at which satellite passes are to be computed. location is a tuple in the format (latitude, longitude, elevation), with elevation given in meters
  • alpha – transparency of individual passes in sat_plot() default=0.5
  • out_dir – path to output directory str
Returns:

  • satellite ephemeris at location and sky coverage ephemeris plot, saved to out_dir

Raises:

FileNotFoundError – an input TLE file does not exist

embers.sat_utils.sat_ephemeris.ephem_batch(tle_dir, cadence, location, alpha, out_dir, max_cores=None)

Process ephemeris for multiple satellites in parallel.

Parameters:
  • tle_dir – Path to directory where TLE files are saved str
  • cadence – Time cadence at which to evaluate sat position, in seconds int
  • location – The gps coordinates of the location at which satellite passes are to be computed. location is a tuple in the format (latitude, longitude, elevation), with elevation given in meters
  • alpha – Transparency of individual passes in sat_plot() default=0.5
  • out_dir – Path to output directory str
  • max_cores – Maximum number of cores to be used by this script. Default=None, which means that all available cores are used
Returns:

  • satellite ephemeris at location and sky coverage ephemeris plot, saved to out_dir

Chronological Ephemeris

Collate ephemeris data generated by sat_ephemeris for multiple satellites and determine all ephemeris present in 30 minute observation windows.

embers.sat_utils.chrono_ephem.obs_times(time_zone, start_date, stop_date)

Time conversion tools for 30 minute observations

Given a time_zone, start_date, stop_date, create lists of human readable start times in YYYY-MM-DD-HH:MM format, and start and stop UNIX times for 30 minute rf observations.

from embers.sat_utils.chrono_ephem import obs_times
time_tuple = obs_times("Australia/Perth", "2020-01-01", "2020-01-02")
obs_time, obs_unix, obs_unix_end - time_tuple

print(obs_time)
>>> ["2020-01-01-00:00", "2020-01-01-00:30", ....]

print(obs_unix)
>>> [1577809800.0, 1577811600.0, 1577813400.0, ...]

print(obs_unix_end)
>>> [1577809800.0, 1577811600.0, 1577813400.0, ...]
Parameters:
  • time_zone – A str representing a pytz timezones.
  • start_date – in YYYY-MM-DD format str
  • stop_date – in YYYY-MM-DD format str
Returns:

A tuple (obs_time, obs_unix, obs_unix_end)

  • obs_time: list of start times of 30 min observations in YYYY-MM-DD-HH::MM format
  • obs_unix: list of start times of 30 min observations in unix time
  • obs_unix_end: list of end times of 30 min observations in unix time

embers.sat_utils.chrono_ephem.interp_ephem(t_array, s_alt, s_az, interp_type, interp_freq)

Interpolates satellite ephemeris from sat_ephemeris

Satellite ephemeris is interpolated to the same freq as used in align_data. This ensures that each point of rf data, will have an corresponding ephemeris. Time, Altitude & Azimuth ephemeris arrays are interpolated.

Parameters:
  • t_array – Time array of on satellite pass ndarray
  • s_alt – Satellite Altitude at the t_array ndarray
  • s_az – Satellite Azimuth at the t_array ndarray
  • interp_type – Type of interpolation. Ex: cubic, linear str
  • interp_freq – Frequency at which to interpolate, in Hertz. int
Returns:

A tuple (time_interp, sat_alt, sat_az)

  • time_interp: Interpolated t_array
  • sat_alt: Interpolated s_alt
  • sat_az: Interpolated s_az

embers.sat_utils.chrono_ephem.write_json(data, filename=None, out_dir=None)

writes data to json file in output dir

Parameters:
  • data – Data to be written to json file
  • filename – Json filename str
  • out_dir – Path to output directory str
embers.sat_utils.chrono_ephem.save_chrono_ephem(time_zone, start_date, stop_date, interp_type, interp_freq, ephem_dir, out_dir)

Save 30 minute ephem from all satellites to file.

Native skyfiled gps timestamps are converted to unix timestamps to match the output of the rf explorers. The alt, az data is interpolated to match the cadence of align_data. Make a json file with all the passes from each 30 min observation. This will help in the next stage, where we identify all sats in each obs.

Parameters:
  • time_zone

    A str representing a pytz timezones.

  • start_date – in YYYY-MM-DD format str
  • stop_date – in YYYY-MM-DD format str
  • interp_type – Type of interpolation. Ex: cubic, linear str
  • interp_freq – Frequency at which to interpolate, in Hertz. int
  • ephem_dir – Directory where npz ephemeris files from save_ephem() are saved str
  • out_dir – Path to output directory where chronological ephemeris files will be saved str

Satellite Channels

A set of tools to determine the transmission channel of various satellites in 30 minute observation by using rf data in conjunctin with chronological satellite ephemeris data.

embers.sat_utils.sat_channels.read_aligned(ali_file=None)

Read aligned data from save_aligned() npz file

Parameters:ali_file – path to a save_aligned() npz file str
Returns:A tuple (power, times)
  • ref_pow: a smoothed reference power array ndarry
  • tile_pow: a smoothed tile power array ndarry
  • times: a regular time array ndarry
embers.sat_utils.sat_channels.noise_floor(sat_thresh, noi_thresh, power)

Computes the noise floor of a rf power array

Exclude channels with signal above sat_thresh multiplied by standard deviation of power array. The Median Absolute Deviation MAD is used to quantify the noise level of the remaining channels. The noise floor noi_thresh is defined to be the median of noisy data + noi_thresh multiplied by the MAD of noisy data.

Parameters:
  • sat_thresh – An integer multiple of standard deviation of rf power array, used to exclude channels with potential satellites. int
  • noi_thresh – An integer multiple of the noisy data MAD, used to compute a noise floor. int
  • power – Rf power array ndarry
Returns:

noise_threshold: The power level of the noise floor in dBm int

embers.sat_utils.sat_channels.time_filter(s_rise, s_set, times)

Determine indices of time array when a satellite is above the horizon.

Isolate the portion of a rf power array where a satellite is above the horizon using the rise and set times of a satellite’s ephemeris. This function returns a pair of indices which can be used to slice the rf power and times arrays to precisely only include the satellite.

Parameters:
  • s_rise – satellite rise time from ephemeris float
  • s_set – satellite set time from ephemeris float
  • times – time array corresponding to the rf power array ndarry
Returns:

intvl: None if satellite is not above the horizon within the times array intvl: [i_0, i_1], pair of indices of times array, when satellite is above the horizon

embers.sat_utils.sat_channels.plt_window_chans(power, sat_id, start, stop, cmap, chs=None, good_ch=None)

Waterfall plot with sat window and occupied channels highlighted.

Parameters:
  • power – Rf power array ndarry
  • sat_id – Norad catalogue ID str
  • start – Index of power array when sat_id is above the horizon int
  • stop – Index of power array when sat_id is above the horizon int
  • cmap – Colormap for plotting waterfall ListedColormap
  • chs – Occupied channels list of int
  • good_ch – Most probable channel int
Returns:

embers.sat_utils.sat_channels.plt_channel(times, channel_power, pow_med, chan_num, y_range, noi_thresh, pow_thresh)

Plot power in channel, with various thresholds

Parameters:
  • times – times 1D array ndarry
  • channel_power – Rf channel power 1D array ndarry
  • pow_med – Median of rf power array float
  • chan_num – Channel number str
  • y_range – Plot min, max yrange list list
  • noi_thresh – Noise floor in dBm. float
  • pow_thresh – Power threshold in dBm float
Returns:

embers.sat_utils.sat_channels.plt_sats(ids, chrono_file, timestamp)

Polar plot of satellite passes in a 30 minute observation

Parameters:
  • idslist of Norad catalogue IDs
  • chrono_file – path to chrono ephemeris json file str
  • timestamp – Time at start of 30 minute observation in YYYY-MM-DD-HH:MM format str
Returns:

embers.sat_utils.sat_channels.good_chans(ali_file, chrono_file, sat_id, sat_thresh, noi_thresh, pow_thresh, occ_thresh, timestamp, out_dir, plots=None)

Determine the channels a satellite could occupy, in a 30 minute observation

Ephemeris from chrono_file is used to select a temporal window of the rf power array, within which the satellite is above the horizon. Looping through the frequency channels, a noi_thresh, pow_thresh, occ_thresh are used to identify possible channels occupied by the sat_id. If more than one channel passes the three thresholds, the channel with the highest window occupancy is selected.

from embers.sat_utils.sat_channels import good_chans

ali_file = "~/embers_out/rf0XX_S06XX_2019-10-10-02:30_aligned.npz"
chrono_file = "~/embers_out/2019-10-10-02:30.json"
sat_id = "44387"
sat_thresh = 1
noi_thresh = 3
pow_thresh = 20
occ_thresh = 0.80
timestamp = "2019-10-10-02:30"
out_dir = "./embers_out"
plots = True

good_chan = good_chans(
                ali_file,
                chrono_file,
                sat_id,
                sat_thresh,
                noi_thresh,
                pow_thresh,
                occ_thresh,
                timestamp,
                out_dir,
                plots=plots)

print(good_chan)
>>> 59
Parameters:
  • ali_file – Path to a npz aligned file from save_aligned() str
  • chrono_file – Path to chrono ephem json file from save_chrono_ephem() str
  • sat_id – Norad catalogue ID str
  • sat_thresh – Satellite threshold from noise_floor() int
  • noi_thresh – Noise threshold from noise_floor() int
  • pow_thresh – Minimum power threshold in dBm float
  • occ_thresh – Window occupation threshold. Minimum fractional signal above the noise floor in window float
  • timestamp – Time at start of observation in format YYYY-MM-DD-HH:MM str
  • out_dir – Path to output directory to save plots str
  • plots – If True, disagnostic plots are generated and saved to out_dir
Returns:

  • good_chan: The channel number of most probable channel for sat_id
  • good_chan may be None, if no possible channels were identified

embers.sat_utils.sat_channels.window_chan_map(ali_dir, chrono_dir, sat_thresh, noi_thresh, pow_thresh, occ_thresh, timestamp, out_dir, plots)

Find all satellite channels in a 30 minute rf observation

Loops over all sat_ids in a chrono_file and uses good_chans() to find occupied channels. All occupied channels are saved to out_dir/window_maps/timestamp.json

from embers.sat_utils.sat_channels import window_chan_map

ali_dir = "~/embers_out/rf_tools/align_data"
chrono_dir = "~/embers_out/sat_utils/ephem_chrono"
sat_thresh = 1
noi_thresh = 3
pow_thresh = 20
occ_thresh = 0.80
timestamp = "2019-10-10-02:30"
out_dir = "./embers_out"
plots = True

window_chan_map(
   ali_dir,
   chrono_dir,
   sat_thresh,
   noi_thresh,
   pow_thresh,
   occ_thresh,
   timestamp,
   out_dir,
   plots)
Parameters:
  • ali_dir – Path to directory containing npz aligned file from save_aligned() str
  • chrono_dir – Path to directory containg chrono ephem json file from save_chrono_ephem() str
  • sat_thresh – Satellite threshold from noise_floor() int
  • noi_thresh – Noise threshold from noise_floor() int
  • pow_thresh – Minimum power threshold in dBm float
  • occ_thresh – Window occupation threshold. Minimum fractional signal above the noise floor in window float
  • timestamp – Time at start of observation in format YYYY-MM-DD-HH:MM str
  • out_dir – Path to output directory to save plots str
  • plots – If True, disagnostic plots are generated and saved to out_dir
Returns:

  • window_chan_map json file saved to out_dir/window_maps/timestamp.json
  • Diagonistic plots created and saved to out_dir/window_plots if plots is True

embers.sat_utils.sat_channels.batch_window_map(start_date, stop_date, ali_dir, chrono_dir, sat_thresh, noi_thresh, pow_thresh, occ_thresh, out_dir, plots=None, max_cores=None)

Find satellite channels for all rfobservations in a date interval

Use time_tree() to create a list os 30 minute timestamps between start_date and stop_date. window_chan_map() is used to find all satellites in each 30 minute observation.

from embers.sat_utils.sat_channels import batch_window_map

start_date = "2019-10-01"
stop_date = "2019-10-10"
ali_dir = "~/embers_out/rf_tools/align_data"
chrono_dir = "~/embers_out/sat_utils/ephem_chrono"
sat_thresh = 1
noi_thresh = 3
pow_thresh = 20
occ_thresh = 0.80
out_dir = "./embers_out"
plots = True

batch_window_map(
    start_date,
    stop_date,
    ali_dir,
    chrono_dir,
    sat_thresh,
    noi_thresh,
    pow_thresh,
    occ_thresh,
    out_dir,
    plots)
Parameters:
  • start_date – In format YYYY-MM-DD str
  • stop_date – In format YYYY-MM-DD str
  • ali_dir – Path to directory containing npz aligned file from save_aligned() str
  • chrono_dir – Path to directory containg chrono ephem json file from save_chrono_ephem() str
  • sat_thresh – Satellite threshold from noise_floor() int
  • noi_thresh – Noise threshold from noise_floor() int
  • pow_thresh – Minimum power threshold in dBm float
  • occ_thresh – Window occupation threshold. Minimum fractional signal above the noise floor in window float
  • out_dir – Path to output directory to save plots str
  • plots – If True, disagnostic plots are generated and saved to out_dir
  • max_cores – Maximum number of cores to be used by this script. Default=None, which means that all available cores are used
Returns:

  • window_chan_map json file saved to out_dir/window_maps/.json
  • Diagonistic plots created and saved to out_dir/window_plots if plots is True