scepter

Agent Guidelines for SCEPTer

These instructions apply to the entire repository and are the baseline quality bar for AI agents and automated helpers.

0) Project overview

SCEPTer (Satellite Constellation Emission Pattern simulator for radio Telescopes) models EPFD impact from non-GSO satellite systems on radio-astronomy stations. The toolkit covers TLE/orbit generation, antenna patterns (ITU-R S.1528), propagation, GPU-accelerated EPFD computation, and post-processing/visualisation.

Entry points

Entry point Purpose
gui.py Desktop GUI launcher (PySide6) — bootstrap, splash, then scepter_GUI
scepter/scepter_GUI.py Main GUI window — constellation editor, RAS geometry, grid analyser, 3-D viewer
Jupyter notebooks (xxx_*.ipynb, $4RSA_*.ipynb) Analysis / batch simulation workflows

Module map (scepter/)

Module Responsibility
angle_sampler.py Sky-grid angle sampling (S.1586)
antenna.py Satellite & RAS antenna patterns (S.1528 Rec 1.2 / Rec 1.4, M.2101, S.672, RA.1631), optional Numba
custom_antenna.py User-supplied LUT patterns, schema v1 (authoritative format in the module docstring) — loader, CPU evaluators, dump/inspect CLI
analytical_fixtures.py Helpers that sample any analytical pattern onto a user-chosen grid and produce a CustomAntennaPattern — used by tests and by users who want an LUT from an ITU formula
custom_antenna_preview.py Pure-matplotlib figure factory for loaded custom patterns (polar 1-D, heatmap + principal-plane cuts 2-D)
earthgrid.py Hex-grid generation, footprint geometry, optional Numba
gpu_accel.py GPU-accelerated SGP4, angular distance, CuPy kernels
nbeam.py Beam-cap sizing with visibility-aware pooling policies
obs.py Observation simulation (propagation + antenna → RFI)
satsim.py Link-selection helpers (CPU/GPU variants)
scenario.py Scenario orchestration, HDF5 streaming I/O, integration
skynet.py Sky-grid generation (S.1586 implementation)
tleforger.py Synthetic TLE generation from belt definitions
tlefinder.py TLE archive discovery and catalog helpers
visualise.py CDF/CCDF, hemispheres, sky maps, animation export
postprocess_recipes.py HDF5 inspection and plot recipes
gui_bootstrap.py App identity, splash screen (SVG icon via QSvgRenderer, rounded corners, fade-out, non-blocking), icon loading (lightweight; depends on PySide6.QtSvg)
scepter_GUI.py Full desktop GUI (~23 k lines)
appinfo.py Shared version/branding metadata

Assets (scepter/data/)

Environments and testing

Environment Python Scope
scepter-dev 3.10 Core simulation + GPU (CuPy, Numba); preferred for benchmarking
scepter-dev-full 3.13 Full stack: PySide6, PyVista, Numba, CuPy (may have issues)
conda env create -f environment.yml          # lite
conda env create -f environment-full.yml     # full
conda activate scepter-dev-full
python -m pytest --basetemp=.pytest-tmp -v   # run tests
python gui.py                                 # launch the GUI

Tests live in scepter/tests/. GUI tests use QT_QPA_PLATFORM=offscreen. No pytest-qt — event-loop management is manual via QEventLoop/QTimer. conftest.py forces matplotlib.use("Agg") for headless plot rendering.

Core dependencies

astropy (units/time), pycraf (ITU propagation), cysgp4 (SGP4/TLE), shapely (geometry), PySide6 (Qt GUI), PyVista/PyVistaQt (3-D), h5py (HDF5), Numba (optional JIT), CuPy (optional GPU arrays).

1) Start-up checks

1.1) Diff hygiene (avoid no-op churn)

2) Code quality requirements

3) Documentation and notebook requirements

4) Dependency and environment policy

5) Validation expectations

6) Agent response expectations

7) GPU performance tuning

When optimizing gpu_accel.py or scenario.py, follow these guidelines:

Benchmarking

Run python run_benchmark.py 20 for quick 20-batch tests; use python run_benchmark.py full for production validation. Results go to benchmark_log.txt. Batch 0 includes JIT warmup — use “steady state (skip 2 warmup)” avg for meaningful comparisons. Two configs are provided: benchmark_config.json (standard, no boresight) and benchmark_boresight_config.json (boresight avoidance).

Memory budgets

Set gpu_memory_budget_gb and host_memory_budget_gb in config files. 8 GB VRAM machines: use 6/6 GB. 16 GB VRAM machines: 12/12 GB.

Hot path architecture

Per-batch pipeline: propagate → derive_from_eci → link_library.add_chunk → beam_finalize → power → export_copy → write_enqueue.

Dominant stages (non-boresight): power (~36%), export_copy (~33%), finalize (~14%). See CLAUDE.md for exact timings and line references.

CuPy optimization principles

Key files and functions

Function File Role
_accumulate_ras_power_cp gpu_accel.py:~9852 Power computation (biggest single stage)
_evaluate_s1528_pattern_cp gpu_accel.py:~9695 Transmit pattern (uses LUT for phi=None)
_evaluate_ras_pattern_cp gpu_accel.py:~9667 Receive pattern (fused ElementwiseKernel)
_compute_gpu_direct_epfd_batch_device scenario.py:~6843 Batch orchestration
run_gpu_direct_epfd scenario.py:~7881 Top-level iteration driver
GpuScepterSession gpu_accel.py:~11432 Session lifecycle, caches, activation
prepare_peak_pfd_lut_context gpu_accel.py Builds the surface-PFD cap per-beam LUT. 1-D K(β, shell) for every pattern whose asymmetry rotates with the beam (S.1528 Rec 1.2, S.1528 Rec 1.4 both symmetric and asymmetric, Custom-1D, Custom-2D, isotropic); 2-D K(α, β, shell) for M.2101 whose element pattern is fixed in the sat body frame.
_compute_aggregate_surface_pfd_cap_cp gpu_accel.py Loop-free GPU-native per-satellite aggregate cap helper; supports the 3-D and 4-D paths and every TX-pattern family (S.1528 / M.2101 / Custom-1D / Custom-2D).

Surface-PFD cap (Service & Demand “Max PFD on Earth surface”)

Optional feature that bounds the peak PFD any beam (or any satellite in aggregate) can deposit on Earth’s surface. Enabled from the GUI Service & Demand tab. When editing or extending it, keep these invariants: