Fluent API for constructing a Configuration.
Call setter methods in any order, then call build() to produce
a validated Configuration. All setter methods return self for chaining.
Example::
config = (
ConfigurationBuilder()
.set_facility(lat, lon, elev, name, Receiver(beamwidth=3))
.set_frequency_range(bandwidth=10, frequency=135)
.set_time_window(begin="2024-01-01T00:00:00", end="2024-01-01T01:00:00")
.set_observation_target(declination="7d24m25s", right_ascension="5h55m10s")
.load_satellites(tle_file="satellites.tle")
.build()
)
Source code in src/sopp/config/builder.py
| def __init__(
self,
):
self.facility: Facility | None = None
self.time_window: TimeWindow | None = None
self.frequency_range: FrequencyRange | None = None
self._filterer: Filterer = Filterer()
self.antenna_config: AntennaConfig | None = None
self.satellites: list[Satellite] | None = None
self.reservation: Reservation | None = None
self.runtime_settings: RuntimeSettings = RuntimeSettings()
|
Functions
set_facility
Set the observation facility location and receiver characteristics.
Source code in src/sopp/config/builder.py
| def set_facility(
self,
latitude: float,
longitude: float,
elevation: float,
name: str,
receiver: Receiver,
) -> ConfigurationBuilder:
"""Set the observation facility location and receiver characteristics."""
self.facility = Facility(
coordinates=Coordinates(latitude=latitude, longitude=longitude),
receiver=receiver,
elevation=elevation,
name=name,
)
return self
|
set_frequency_range
set_frequency_range(bandwidth: float, frequency: float)
Set the observation frequency band in MHz.
Source code in src/sopp/config/builder.py
| def set_frequency_range(self, bandwidth: float, frequency: float):
"""Set the observation frequency band in MHz."""
self.frequency_range = FrequencyRange(
bandwidth=bandwidth,
frequency=frequency,
)
return self
|
set_time_window
Set the observation time window. Strings are parsed as ISO 8601 UTC.
Source code in src/sopp/config/builder.py
| def set_time_window(
self,
begin: str | datetime,
end: str | datetime,
) -> ConfigurationBuilder:
"""Set the observation time window. Strings are parsed as ISO 8601 UTC."""
self.time_window = TimeWindow(
begin=parse_time_and_convert_to_utc(begin),
end=parse_time_and_convert_to_utc(end),
)
return self
|
set_observation_target
set_observation_target(
declination: str | None = None,
right_ascension: str | None = None,
altitude: float | None = None,
azimuth: float | None = None,
custom_antenna_trajectory: AntennaTrajectory
| None = None,
) -> ConfigurationBuilder
Set the antenna pointing mode.
Provide exactly one of
custom_antenna_trajectory: explicit az/alt path over time.
altitude and azimuth: fixed pointing direction.
declination and right_ascension: celestial target to track.
Source code in src/sopp/config/builder.py
| def set_observation_target(
self,
declination: str | None = None,
right_ascension: str | None = None,
altitude: float | None = None,
azimuth: float | None = None,
custom_antenna_trajectory: AntennaTrajectory | None = None,
) -> ConfigurationBuilder:
"""Set the antenna pointing mode.
Provide exactly one of:
- ``custom_antenna_trajectory``: explicit az/alt path over time.
- ``altitude`` and ``azimuth``: fixed pointing direction.
- ``declination`` and ``right_ascension``: celestial target to track.
"""
# Option 1: Custom
if custom_antenna_trajectory:
self.antenna_config = CustomTrajectoryConfig(custom_antenna_trajectory)
# Option 2: Static
elif altitude is not None and azimuth is not None:
self.antenna_config = StaticPointingConfig(
Position(altitude=altitude, azimuth=azimuth)
)
# Option 3: Tracking
elif declination is not None and right_ascension is not None:
target = ObservationTarget(
declination=declination, right_ascension=right_ascension
)
self.antenna_config = CelestialTrackingConfig(target)
else:
raise ValueError(
"Invalid observation target configuration. Provide one of: "
"(custom_antenna_trajectory), (altitude, azimuth), or (ra, dec)."
)
return self
|
set_satellites
Set the satellite list directly.
Source code in src/sopp/config/builder.py
| def set_satellites(self, satellites: list[Satellite]) -> ConfigurationBuilder:
"""Set the satellite list directly."""
self.satellites = satellites
return self
|
load_satellites
load_satellites(
tle_file: str | Path,
frequency_file: str | Path | None = None,
) -> ConfigurationBuilder
Load satellites from a TLE file, optionally attaching frequency data.
Source code in src/sopp/config/builder.py
| def load_satellites(
self, tle_file: str | Path, frequency_file: str | Path | None = None
) -> ConfigurationBuilder:
"""Load satellites from a TLE file, optionally attaching frequency data."""
self.satellites = load_satellites(
tle_file=Path(tle_file),
frequency_file=Path(frequency_file) if frequency_file else None,
)
return self
|
set_runtime_settings
set_runtime_settings(
time_resolution_seconds: float = 1,
concurrency_level: int = 1,
min_altitude: float = 0.0,
) -> ConfigurationBuilder
Set simulation resolution, parallelism, and minimum altitude.
Source code in src/sopp/config/builder.py
| def set_runtime_settings(
self,
time_resolution_seconds: float = 1,
concurrency_level: int = 1,
min_altitude: float = 0.0,
) -> ConfigurationBuilder:
"""Set simulation resolution, parallelism, and minimum altitude."""
self.runtime_settings = RuntimeSettings(
concurrency_level=concurrency_level,
time_resolution_seconds=time_resolution_seconds,
min_altitude=min_altitude,
)
return self
|
set_from_config_file
set_from_config_file(
config_file: Path,
loader_class: type[
ConfigFileLoaderBase
] = ConfigFileLoaderJson,
) -> ConfigurationBuilder
Load facility, frequency, time, and antenna settings from a config file.
Source code in src/sopp/config/builder.py
| def set_from_config_file(
self,
config_file: Path,
loader_class: type[ConfigFileLoaderBase] = ConfigFileLoaderJson,
) -> ConfigurationBuilder:
"""Load facility, frequency, time, and antenna settings from a config file."""
loader = loader_class(filepath=config_file)
self.frequency_range = loader.frequency_range
self.facility = loader.facility
self.time_window = loader.time_window
self.runtime_settings = loader.runtime_settings
self.antenna_config = loader.antenna_config
return self
|
set_satellites_filter
Replace the satellite filter with a pre-built Filterer.
Source code in src/sopp/config/builder.py
| def set_satellites_filter(self, filterer: Filterer) -> ConfigurationBuilder:
"""Replace the satellite filter with a pre-built Filterer."""
self._filterer = filterer
return self
|
add_filter
add_filter(filter_fn: Callable[[Satellite], bool])
Add a single satellite filter function.
Source code in src/sopp/config/builder.py
| def add_filter(self, filter_fn: Callable[[Satellite], bool]):
"""Add a single satellite filter function."""
self._filterer.add_filter(filter_fn)
return self
|
build
Validate all settings and produce a Configuration.
Raises:
| Type |
Description |
ValueError
|
If any required setting is missing.
|
Source code in src/sopp/config/builder.py
| def build(self) -> Configuration:
"""Validate all settings and produce a Configuration.
Raises:
ValueError: If any required setting is missing.
"""
facility = self.facility
time_window = self.time_window
frequency = self.frequency_range
satellites = self.satellites
antenna_config = self.antenna_config
if facility is None:
raise ValueError("Configuration invalid: Facility is not set.")
if time_window is None:
raise ValueError("Configuration invalid: Time Window is not set.")
if satellites is None:
raise ValueError("Configuration invalid: Satellites are not loaded.")
filtered_satellites = self._filterer.apply_filters(satellites)
reservation = Reservation(
facility=facility,
time=time_window,
frequency=frequency,
)
return Configuration(
reservation=reservation,
satellites=filtered_satellites,
antenna_config=antenna_config,
runtime_settings=self.runtime_settings,
)
|