SOPP - Satellite Orbit Prediction Processor
SOPP is a high-performance Python library and CLI tool designed to predict satellite interference for radio astronomy observations.
It uses vectorized orbital mechanics (via Skyfield/SGP4) to simulate thousands of satellites against observation schedules, identifying when a satellite crosses a telescope's main beam or rises above the horizon.
Installation
Install via pip:
# Core library only
pip install sopp
# With CLI tools
pip install "sopp[cli]"
CLI Usage
SOPP provides a command-line interface for running simulations and managing data.
1. Download Data
First, download the latest satellite orbital data. By default, this pulls active satellites from Celestrak in OMM CSV format.
sopp download-tles
Other formats are available with --format (csv, json, xml, tle). Note that the legacy TLE format cannot represent NORAD IDs above 99999, so it omits every satellite cataloged since July 2026 (see Celestrak's GP data formats page).
2. Run a Simulation
Run a simulation using a configuration file (see below).
sopp run --config my_config.json
3. Ad-Hoc Analysis
You can override configuration parameters directly from the CLI without editing the file.
# Check for Starlink interference in the next 30 minutes
sopp run --config my_config.json \
--search STARLINK \
--orbit leo \
--start 2025-01-01T12:00:00 \
--duration 30
Common Options:
--mode [all|horizon|interference]: Choose what to calculate.--limit 10: Only show the first 10 results.--local-time: Display timestamps in your system's local timezone.--format json: Output machine-readable JSON.
Configuration
SOPP uses a JSON configuration file to define the observation parameters.
Example config.json
{
"facility": {
"name": "HCRO",
"latitude": 40.8178049,
"longitude": -121.4695413,
"elevation": 986,
"beamwidth": 3.0
},
"frequencyRange": {
"frequency": 135.0,
"bandwidth": 10.0
},
"reservationWindow": {
"startTimeUtc": "2026-01-13T12:00:00",
"endTimeUtc": "2026-01-13T13:00:00"
},
"observationTarget": {
"declination": "-38d6m50.8s",
"rightAscension": "4h42m"
},
"runtimeSettings": {
"concurrency_level": 4,
"time_resolution_seconds": 1.0,
"min_altitude": 0.0
}
}
Configuration Sections
| Section | Description |
|---|---|
| facility | Defines the ground station location (Lat/Lon/Elev) and antenna beamwidth (degrees). |
| frequencyRange | Defines the observation frequency (MHz). Satellites transmitting outside this range are ignored. |
| reservationWindow | The start and end time of the observation. |
| runtimeSettings | Controls simulation fidelity. time_resolution_seconds determines the step size (default 1.0s). |
Antenna Pointing Modes
You must provide one of the following sections to define where the antenna is pointing:
observationTarget: Tracks a celestial object (RA/Dec)."observationTarget": { "declination": "...", "rightAscension": "..." }
staticAntennaPosition: Points at a fixed Azimuth/Elevation."staticAntennaPosition": { "azimuth": 180.0, "altitude": 45.0 }
antennaPositionTimes: A custom trajectory (list of time/az/el points).
Python Library Usage
SOPP is designed to be imported and used directly in Python scripts/projects.
from sopp.config.builder import ConfigurationBuilder
from sopp.filtering.presets import filter_name_does_not_contain
from sopp.models.ground.receiver import Receiver
from sopp.sopp import Sopp
# Build Configuration
config = (
ConfigurationBuilder()
.set_facility(
latitude=40.8,
longitude=-121.4,
elevation=986,
name="HCRO",
receiver=Receiver(beamwidth=3),
)
.set_runtime_settings(concurrency_level=4)
.set_time_window(begin="2026-01-13T19:00:00", end="2026-01-13T20:00:00")
.set_frequency_range(bandwidth=10, frequency=135)
# Cygnus A
.set_observation_target(declination="40d44m", right_ascension="19h59m")
.load_satellites(tle_file="satellites.csv")
.add_filter(filter_name_does_not_contain("STARLINK"))
.build()
)
print(f"Running interference simulation for {len(config.satellites)} satellites:")
# Run Engine
engine = Sopp(config)
interference_events = engine.get_satellites_crossing_main_beam()
# Analyze Results
print(f"Found {len(interference_events)} interference events:")
for event in interference_events:
print(f"--- {event.satellite.name} ---")
print(f" Window: {event.overhead_time.begin} -> {event.overhead_time.end}")
print(f" Duration: {event.duration_seconds:.1f} seconds")
print(f" Peak Elev: {event.peak_elevation:.1f} deg")
Data Sources
- Orbital Data: OMM (csv/json/xml) or TLE, sourced from Celestrak (public) or Space-Track.org (requires account/env vars).
- Frequency Data: Optional CSV file to populate satellite transmission frequency. SSDB Format:
ID, Name, Frequency, Bandwidth.
Metadata
Release files for sopp 0.10.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sopp-0.10.0.tar.gz | 105.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sopp-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 180.5 kB
Release files / sopp-0.10.0.tar.gz
| Download URL | sopp-0.10.0.tar.gz |
|---|---|
| Size | 105.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
13d41be11019699ff31f132ab74ce0c50eb1c19e0da600aa3aad94232d2a778a
|
|
BLAKE2b-256 checksum How to use checksums |
3cae0233df49c3cf15390f6481c13d005dddc28d1c9e8cb3ccd8aec997e3e978
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / sopp-0.10.0-py3-none-any.whl
| Download URL | sopp-0.10.0-py3-none-any.whl |
|---|---|
| Size | 75.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e5ebf889c9c37141edae236a5df6ae11f4af01f7dd64294d461045691ebf7933
|
|
BLAKE2b-256 checksum How to use checksums |
3e793265bcd52b92301f2f571808222933bb40f5adb57bc53f567c3d78e5b547
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency log