Optical imaging access
Lox models passive (electro-optical) payloads via OpticalPayload
and OpticalAccessAnalysis. The payload declares a
nadir-centred swath width and an optional off-nadir pointing capability; the
analysis computes per-AOI access windows by scanning the circular ground
footprint under the satellite.
Sensor models
Nadir-only
For sensors that image straight down (e.g. Sentinel-2), the accessible ground range equals half the swath width:
import lox_space as lox
payload = lox.OpticalPayload.nadir_only(290.0 * lox.km)
Off-nadir pointing
For satellites that can slew away from nadir to image targets, the accessible range is the sum of the off-nadir ground range and half the swath width:
payload = lox.OpticalPayload.off_nadir(
swath_width=20.0 * lox.km,
max_off_nadir=30.0 * lox.deg,
)
The off-nadir ground range is computed geometrically from the spacecraft altitude, the maximum off-nadir angle, and the body's mean radius.
Attaching payloads to spacecraft
Pass the payload via the optical_payload keyword argument when constructing
a Spacecraft. Spacecraft without a payload are silently skipped during
analysis:
# With payload — included in optical access analysis
sc1 = lox.Spacecraft("imager", orbit, optical_payload=payload)
# Without payload — skipped
sc2 = lox.Spacecraft("relay", orbit)
scenario = lox.Scenario(t0, t1, spacecraft=[sc1, sc2])
# Only sc1 will produce imaging windows
Example: Sentinel-2 over Europe
import lox_space as lox
sentinel2a = lox.SGP4("""\
SENTINEL-2A
1 40697U 15028A 26079.19377485 -.00000072 00000+0 -11026-4 0 9994
2 40697 98.5642 155.3327 0001269 98.1407 261.9920 14.30816376561005""")
payload = lox.OpticalPayload.nadir_only(290.0 * lox.km)
sc = lox.Spacecraft("S2A", sentinel2a, optical_payload=payload)
t0 = sentinel2a.time()
t1 = t0 + 6 * lox.hours
scenario = lox.Scenario(t0, t1, spacecraft=[sc])
europe = lox.Aoi(
[(-10.0, 35.0), (20.0, 35.0), (20.0, 60.0), (-10.0, 60.0), (-10.0, 35.0)]
)
analysis = lox.OpticalAccessAnalysis(
scenario,
aois=[("europe", europe)],
step=30 * lox.seconds,
)
results = analysis.compute()
for window in results.windows("S2A", "europe"):
iv = window.interval()
print(f"{iv.start()} → {iv.end()} ({float(iv.duration()):.0f}s)")
print(window.direction())
OpticalPayload
Optical sensor payload describing a spacecraft's ground coverage capability.
Defines the sensor's swath width and optional off-nadir pointing capability.
Assign to a spacecraft via the optical_payload parameter.
Examples:
>>> payload = lox.OpticalPayload.nadir_only(20.0 * lox.km)
>>> payload = lox.OpticalPayload.off_nadir(20.0 * lox.km, 30.0 * lox.deg)
>>> sc = lox.Spacecraft("sat1", orbit, optical_payload=payload)
Methods:
-
nadir_only–Create a payload for a nadir-only sensor.
-
off_nadir–Create a payload for a sensor with off-nadir pointing capability.
nadir_only
classmethod
nadir_only(swath_width: Distance) -> Self
Create a payload for a nadir-only sensor.
Parameters:
-
(swath_widthDistance) –Full swath width as Distance.
off_nadir
classmethod
off_nadir(swath_width: Distance, max_off_nadir: Angle) -> Self
OpticalAccessAnalysis
AOI optical access analysis: computes imaging windows for spacecraft over AOIs.
Optical payloads are read from each spacecraft; spacecraft without a payload are silently skipped.
Parameters:
-
–scenarioScenario containing spacecraft with
optical_payload. -
–aoisList of (id, Aoi) tuples defining the areas of interest.
-
–ensembleOptional pre-computed Ensemble.
-
–stepOptional time step for event detection (default: 60s).
-
–body_fixed_frameOptional body-fixed frame override.
Examples:
>>> payload = lox.OpticalPayload.off_nadir(20.0 * lox.km, 30.0 * lox.deg)
>>> sc = lox.Spacecraft("sat1", orbit, optical_payload=payload)
>>> scenario = lox.Scenario(t0, t1, spacecraft=[sc])
>>> aoi = lox.Aoi.from_geojson('{"type":"Polygon","coordinates":[[[10,45],[11,45],[11,46],[10,46],[10,45]]]}')
>>> analysis = lox.OpticalAccessAnalysis(scenario, aois=[("rome", aoi)])
>>> results = analysis.compute()
Methods:
-
compute–Compute access intervals for all (spacecraft, AOI) pairs.
compute
compute() -> AccessResults
Compute access intervals for all (spacecraft, AOI) pairs.
If no ensemble was provided, the scenario is propagated automatically. Spacecraft without an optical payload are skipped.