Models¶
Data structures used throughout SOPP.
Core Types¶
Position
dataclass
¶
A position in the local horizontal coordinate system.
Attributes:
| Name | Type | Description |
|---|---|---|
altitude |
float
|
Elevation angle in degrees. 0 is the horizon, 90 is zenith. Negative values mean the object is below the horizon. |
azimuth |
float
|
Azimuth angle in degrees, measured clockwise from geographic north (0) through east (90), south (180), and west (270). |
distance_km |
float | None
|
Slant range to the object in kilometers, or None. |
TimeWindow
dataclass
¶
A time interval defined by a start and end time (UTC).
Attributes:
| Name | Type | Description |
|---|---|---|
begin |
datetime
|
Start of the window. |
end |
datetime
|
End of the window. |
Coordinates
dataclass
¶
Geographic coordinates in decimal degrees.
Attributes:
| Name | Type | Description |
|---|---|---|
latitude |
float
|
Latitude in decimal degrees (positive north). |
longitude |
float
|
Longitude in decimal degrees (positive east). |
FrequencyRange
dataclass
¶
A frequency band defined by center frequency and bandwidth.
Used for both telescope observations and satellite transmissions.
Attributes:
| Name | Type | Description |
|---|---|---|
frequency |
float
|
Center frequency in MHz. |
bandwidth |
float
|
Total bandwidth in MHz. |
status |
str | None
|
Optional metadata (e.g. 'active', 'inactive'). |
Functions¶
overlaps ¶
overlaps(other: FrequencyRange) -> bool
Return True if this frequency range overlaps with another.
Ground Station¶
Facility
dataclass
¶
Facility(
coordinates: Coordinates,
receiver: Receiver = Receiver(),
elevation: float = 0,
name: str | None = "Unnamed Facility",
)
The Facility data class contains the observation parameters of the facility.
Attributes:
| Name | Type | Description |
|---|---|---|
coordinates |
Coordinates
|
Location of RA facility. |
receiver |
Receiver
|
Receive-side antenna characteristics. Defaults to Tier 0 with beamwidth=3. |
elevation |
float
|
Ground elevation of the telescope in meters. Defaults to 0. |
name |
str | None
|
Name of the facility. Defaults to 'Unnamed Facility'. |
Receiver
dataclass
¶
Receiver(
beamwidth: float = 3.0,
peak_gain_dbi: float | None = None,
antenna_pattern: AntennaPattern | None = None,
)
Receive-side antenna characteristics of a facility.
Supports three tiers of fidelity:
Tier 0 (geometric): Set only beamwidth for binary in/out-of-beam detection.
Tier 1 (simple link budget): Set peak_gain_dbi for worst-case constant gain.
Tier 1.5+ (detailed): Set antenna_pattern for angle-dependent gain lookup.
Attributes:
| Name | Type | Description |
|---|---|---|
beamwidth |
float
|
Beamwidth of the telescope in degrees. |
peak_gain_dbi |
float | None
|
Peak antenna gain in dBi (Tier 1). Defaults to None. |
antenna_pattern |
AntennaPattern | None
|
Full antenna gain pattern (Tier 1.5+). Defaults to None. |
AntennaTrajectory
dataclass
¶
AntennaTrajectory(
times: NDArray[object_],
azimuth: NDArray[float64],
altitude: NDArray[float64],
)
Time series of antenna azimuth/altitude positions.
Attributes:
| Name | Type | Description |
|---|---|---|
times |
NDArray[object_]
|
1D array of datetime objects (UTC). |
azimuth |
NDArray[float64]
|
1D array of azimuth angles in degrees. |
altitude |
NDArray[float64]
|
1D array of elevation angles in degrees. |
Functions¶
get_state_at ¶
Interpolate antenna az/alt at the given times.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query_times
|
ndarray
|
Array of datetime objects to interpolate at. |
required |
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
Tuple of (azimuth, altitude) arrays in degrees. |
Source code in src/sopp/models/ground/trajectory.py
ObservationTarget
dataclass
¶
A celestial target specified by equatorial coordinates.
Attributes:
| Name | Type | Description |
|---|---|---|
declination |
str
|
Declination string (e.g. '7d24m25.426s'). |
right_ascension |
str
|
Right ascension string (e.g. '5h55m10.3s'). |
Antenna Configuration¶
StaticPointingConfig
dataclass
¶
StaticPointingConfig(position: Position)
Fixed azimuth/elevation pointing for the entire observation.
CelestialTrackingConfig
dataclass
¶
CelestialTrackingConfig(target: ObservationTarget)
Track a celestial object (RA/Dec) across the sky.
CustomTrajectoryConfig
dataclass
¶
CustomTrajectoryConfig(trajectory: AntennaTrajectory)
User-provided antenna trajectory with explicit az/alt at each time step.
Satellite¶
Satellite
dataclass
¶
Satellite(
name: str,
tle_information: TleInformation | None = None,
frequency: list[FrequencyRange] = list(),
transmitter: Transmitter | None = None,
)
A satellite with a name and optional orbital/frequency data.
Satellites loaded from TLE files will have tle_information populated. Satellites reconstructed from trajectory files may not.
Attributes¶
orbits_per_day
property
¶
Calculate orbits per day from mean motion. Requires TLE data.
Functions¶
to_skyfield ¶
Convert to a Skyfield EarthSatellite. Requires TLE data.
Source code in src/sopp/models/satellite/satellite.py
SatelliteTrajectory
dataclass
¶
SatelliteTrajectory(
satellite: Satellite,
times: NDArray[object_],
azimuth: NDArray[float64],
altitude: NDArray[float64],
distance_km: NDArray[float64],
)
Represents the computed path (trajectory) of a satellite relative to a facility.
Attributes:
| Name | Type | Description |
|---|---|---|
satellite |
Satellite
|
The satellite object associated with this trajectory. |
times |
ndarray
|
1D array of datetime objects representing time steps. |
azimuth |
ndarray
|
1D array of azimuth angles in degrees. |
altitude |
ndarray
|
1D array of elevation/altitude angles in degrees. |
distance_km |
ndarray
|
1D array of distances to the satellite in kilometers. |
Example
Save a single trajectory¶
trajectory.save("path/to/file.arrow")
Save multiple trajectories to one file¶
from sopp.io import save_trajectories save_trajectories(trajectories, "batch.arrow")
Load trajectories (always returns a list)¶
trajectories = SatelliteTrajectory.load("path/to/file.arrow")
Attributes¶
overhead_time
property
¶
A TimeWindow representing the duration that the satellite is tracked within this trajectory (e.g., entering and exiting view). Returns None if the trajectory contains no data.
peak_time
cached
property
¶
Time at which the satellite reaches peak elevation.
azimuth_rate
cached
property
¶
Azimuth angular rate in degrees/second.
Returns an array with one fewer element than the input arrays. Each value represents the rate between consecutive time steps.
altitude_rate
cached
property
¶
Elevation angular rate in degrees/second.
Returns an array with one fewer element than the input arrays. Each value represents the rate between consecutive time steps.
is_complete
property
¶
True if the pass rose and set within the observation window.
A complete pass has its peak elevation roughly centered in time, meaning we captured the full rise-peak-set arc rather than catching just the beginning or tail end.
Functions¶
save ¶
save(
path: str | Path | None = None,
*,
directory: str | Path | None = None,
format: TrajectoryFormat | None = None,
observer_name: str | None = None,
observer_lat: float | None = None,
observer_lon: float | None = None,
) -> Path
Save this trajectory to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path | None
|
Output file path. If None, directory must be provided. |
None
|
directory
|
str | Path | None
|
Directory for auto-generated filename. Ignored if path is set. |
None
|
format
|
TrajectoryFormat | None
|
File format handler. Defaults to ArrowFormat. |
None
|
observer_name
|
str | None
|
Optional name of the observing facility. |
None
|
observer_lat
|
float | None
|
Optional latitude of the observer. |
None
|
observer_lon
|
float | None
|
Optional longitude of the observer. |
None
|
Returns:
| Type | Description |
|---|---|
Path
|
Path to the saved file. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither path nor directory is provided. |
Source code in src/sopp/models/satellite/trajectory.py
load
classmethod
¶
load(
path: str | Path,
*,
format: TrajectoryFormat | None = None,
time_range: tuple[datetime, datetime] | None = None,
) -> TrajectorySet
Load trajectories from a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to the trajectory file. |
required |
format
|
TrajectoryFormat | None
|
File format handler. Defaults to ArrowFormat. |
None
|
time_range
|
tuple[datetime, datetime] | None
|
Optional tuple of (start, end) to filter trajectory data. |
None
|
Returns:
| Type | Description |
|---|---|
TrajectorySet
|
TrajectorySet of loaded trajectories. |
Source code in src/sopp/models/satellite/trajectory.py
TrajectorySet ¶
TrajectorySet(trajectories: list[SatelliteTrajectory])
An iterable, filterable collection of satellite trajectories.
Returned by Sopp.get_satellites_above_horizon() and related methods.
Supports filtering, observation scheduling, and plotting.
Construct from a list of trajectories::
ts = TrajectorySet(trajectories)
Filter, select, and chain::
selected = ts.filter(min_el=25, complete_only=True).select(min_separation_min=14)
Source code in src/sopp/models/satellite/trajectory_set.py
Functions¶
to_list ¶
to_list() -> list[SatelliteTrajectory]
filter ¶
filter(
min_el: float | None = None,
max_el: float | None = None,
complete_only: bool = False,
name: str | None = None,
max_az_rate: float | None = None,
max_el_rate: float | None = None,
) -> TrajectorySet
Return a filtered copy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_el
|
float | None
|
Minimum peak elevation in degrees. |
None
|
max_el
|
float | None
|
Maximum peak elevation in degrees. |
None
|
complete_only
|
bool
|
Only include complete rise-peak-set passes. |
False
|
name
|
str | None
|
Only include satellites whose name contains this string (case-insensitive). |
None
|
max_az_rate
|
float | None
|
Maximum azimuth rate in deg/sec (antenna slew limit). |
None
|
max_el_rate
|
float | None
|
Maximum elevation rate in deg/sec (antenna slew limit). |
None
|
Source code in src/sopp/models/satellite/trajectory_set.py
select ¶
select(min_separation_min: float = 14) -> TrajectorySet
Select non-overlapping passes with minimum time separation.
Walks through passes in time order and picks each one that is
far enough from the last selected pass. Apply filter() first
to control which passes are candidates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_separation_min
|
float
|
Minimum minutes between selected pass peaks. |
14
|
Source code in src/sopp/models/satellite/trajectory_set.py
TleInformation
dataclass
¶
TleInformation(
argument_of_perigee: float,
drag_coefficient: float,
eccentricity: float,
epoch_days: float,
inclination: float,
mean_anomaly: float,
mean_motion: MeanMotion,
revolution_number: int,
right_ascension_of_ascending_node: float,
satellite_number: int,
classification: str = "U",
international_designator: InternationalDesignator
| None = None,
)
Parsed orbital elements from a Two-Line Element set.
All angular values are in radians (SGP4 convention).
Transmitter
dataclass
¶
Transmitter(
eirp_dbw: float | None = None,
power_dbw: float | None = None,
antenna_pattern: AntennaPattern | None = None,
)
RF transmission characteristics of a satellite.
Supports two modes of operation:
Tier 1 (simple): Set only eirp_dbw for a worst-case constant EIRP.
This assumes main beam alignment and is useful for quick screening.
Tier 2 (detailed): Set power_dbw and antenna_pattern separately.
This allows calculating angle-dependent EIRP based on where the
receiver is relative to the satellite's antenna boresight.
Attributes:
| Name | Type | Description |
|---|---|---|
eirp_dbw |
float | None
|
Effective Isotropic Radiated Power in dBW (Tier 1). Combined P_t * G_t as a single scalar. Use this for simple worst-case estimates. |
power_dbw |
float | None
|
Transmitter power in dBW, before antenna gain (Tier 2). Use with antenna_pattern for angle-dependent calculations. |
antenna_pattern |
AntennaPattern | None
|
Satellite antenna gain pattern (Tier 2). If provided with power_dbw, enables angle-dependent EIRP. |
Attributes¶
Functions¶
get_eirp_dbw ¶
Get EIRP at a given off-axis angle from the satellite's boresight.
For Tier 1 (eirp_dbw set): Returns constant EIRP regardless of angle. For Tier 2 (power_dbw + pattern): Returns P_t + G_t(angle).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
off_axis_deg
|
float | ndarray
|
Angle from satellite antenna boresight in degrees. Can be scalar or array. Ignored for Tier 1. |
0.0
|
Returns:
| Type | Description |
|---|---|
float | ndarray
|
EIRP in dBW. Scalar if input is scalar, array if input is array. |
Source code in src/sopp/models/satellite/transmitter.py
Antenna Pattern¶
AntennaPattern
dataclass
¶
Antenna gain as a function of off-axis angle.
Represents a rotationally symmetric antenna pattern where gain depends only on the angular distance from boresight (the pointing direction).
Attributes:
| Name | Type | Description |
|---|---|---|
angles_deg |
ndarray
|
Off-axis angles in degrees, must start at 0 (boresight). Should be monotonically increasing. |
gains_dbi |
ndarray
|
Corresponding gain values in dBi. First value is peak gain. |
Attributes¶
Functions¶
get_gain ¶
Interpolate gain at given off-axis angle(s).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
off_axis_deg
|
float | ndarray
|
Off-axis angle(s) in degrees. Can be scalar or array. |
required |
Returns:
| Type | Description |
|---|---|
float | ndarray
|
Gain in dBi at the specified angle(s). Same shape as input. |
Source code in src/sopp/models/antenna.py
Simulation¶
Reservation
dataclass
¶
Reservation(
facility: Facility,
time: TimeWindow,
frequency: FrequencyRange | None = None,
)
A scheduled observation at a facility.
Attributes:
| Name | Type | Description |
|---|---|---|
facility |
Facility
|
The radio astronomy facility. |
time |
TimeWindow
|
Time window of the observation. |
frequency |
FrequencyRange | None
|
Frequency band being observed. Optional for horizon-only queries. |
Configuration
dataclass
¶
Configuration(
reservation: Reservation,
satellites: list[Satellite],
antenna_config: AntennaConfig | None = None,
runtime_settings: RuntimeSettings = RuntimeSettings(),
)
Complete simulation configuration.
Combines the observation reservation, satellite list, antenna pointing mode, and runtime settings. Validates all fields on construction.
Attributes:
| Name | Type | Description |
|---|---|---|
reservation |
Reservation
|
Facility, time window, and frequency. |
satellites |
list[Satellite]
|
List of satellites to analyze. |
antenna_config |
AntennaConfig | None
|
How the antenna is pointed during the observation. |
runtime_settings |
RuntimeSettings
|
Execution parameters (resolution, concurrency, etc.). |
RuntimeSettings
dataclass
¶
RuntimeSettings(
time_resolution_seconds: float = 1,
concurrency_level: int = 1,
min_altitude: float = 0.0,
)
Controls execution and precision of the simulation.
Attributes:
| Name | Type | Description |
|---|---|---|
time_resolution_seconds |
float
|
Step size of the simulation grid in seconds. |
concurrency_level |
int
|
Number of parallel processes for satellite calculations. |
min_altitude |
float
|
Minimum elevation angle in degrees for a satellite to be considered above the horizon. |
Results¶
InterferenceResult
dataclass
¶
InterferenceResult(
trajectory: SatelliteTrajectory,
interference_level: ndarray | None = None,
level_units: str | None = None,
metadata: dict | None = None,
)
The output of any interference strategy.
Wraps a SatelliteTrajectory (the interfering segment) with optional quantitative interference data. All strategies produce this same structure, making them interchangeable.