API Pythona
Kshana dostarcza w pełni rozwinięty interfejs programistyczny (API) w Pythonie, zbudowany przy użyciu PyO3 i maturin. Jego pakiety wheel abi3 są budowane względem stabilnego binarnego interfejsu aplikacji (ABI) Pythona, więc jeden pakiet na platformę działa z CPython ≥ 3,9; pakiety obejmują Linuksa, macOS i Windows, każdy na architekturach x86-64 i 64-bitowym ARM (zob. WHEEL_TAGS.md). Dołączony plik typów (kshana.pyi + py.typed) daje edytorom oraz narzędziom mypy/pyright pełne informacje o typach.
pip install kshana # from the Python Package Index, PyPI (release wheels)
# or, from a checkout:
pip install maturin && maturin develop --features python
Szybki start#
Uruchamiaj te fragmenty z katalogu głównego kopii repozytorium: odczytują one pliki scenariuszy z scenarios/. Wiersz z NumPy wymaga pip install numpy.
import kshana
toml = open("scenarios/clock-holdover.toml").read()
# Typed result with a parsed-dict accessor:
out = kshana.run_typed(toml)
print(out.summary)
data = out.data() # a Python dict — no JSON re-parsing
fom = data["quantum"]["fom"] # figures of merit, quantum side
classical_fom = data["classical"]["fom"] # … and the classical baseline
print(out.json[:80], "...") # raw JSON also available
open("chart.svg", "w").write(out.svg) # the chart SVG
# NumPy arrays straight from the result (NumPy is imported on call; it is not a
# dependency of the package):
curve = out.columns("quantum.adev_curve") # {"tau_s": ndarray, "adev": ndarray, ...}
adev = curve["adev"]
everything = out.series() # every record series, keyed by path
Powierzchnia#
| Symbol | Sygnatura | Zwraca |
|---|---|---|
run_typed |
(toml: str) -> RunOutput |
wynik typowany (.json, .svg, .summary, .csv, .data(), .array(), .columns(), .series(), .write_csv()) |
run |
(toml: str) -> str |
dokument wynikowy jako ciąg JSON (JavaScript Object Notation) |
run_full |
(toml: str) -> tuple[str, str, str] |
(json, svg, summary) |
scenario_kinds |
() -> list[dict] |
dostępne rodzaje scenariuszy i metadane (po sparsowaniu) |
list_kinds |
() -> str |
te same metadane jako JEDEN ciąg z tablicą JSON, a nie lista (zachowane dla dotychczasowych wywołań; do sparsowanej listy służy scenario_kinds) |
validate_toml |
(toml: str) -> list[str] |
komunikaty o błędach (puste, jeśli dane są poprawne) |
error_kind |
(toml: str) -> str | None |
znacznik kategorii błędu (invalid_input, non_convergence, unsupported lub io_error) albo None w razie powodzenia |
version / __version__ |
() -> str / str |
wersja silnika |
receiver_trust |
(toml: str) -> RunOutput |
ocena rzeczywistego dziennika odbiornika opisanego scenariuszem receiver-trust: dokument wynikowy, CSV wskaźnika zaufania dla każdej epoki, wykres i podsumowanie; tabela [platform] kind = "vessel" dodaje monitory morskie oraz wskaźnik zaufania 0-100 z uzasadnieniami (wyłącznie doradczo) |
receiver_trust_replay |
(session_toml, nmea) -> dict |
ograniczony fragment NMEA oceniony tak, jak ocenia go tryb na żywo: stan w każdej epoce, wskaźnik 0-100 z uzasadnieniami, podsumowanie (bez gniazda, bez bramki; wyłącznie doradczo) |
assess_vessel_log |
(session_toml, log) -> dict |
dziennik NMEA statku jako przebieg wsadowy: model wskaźnika i wskaźnik każdej epoki wraz z odliczeniami (wyłącznie doradczo) |
jammertest_import |
(catalog_json, plans, log_start_utc, location=None, local_offset_h=2.0, year=None) -> dict |
opublikowany katalog i plan Jammertest jako zdarzenia z harmonogramu wzorcowego (events_toml, events); są to zaplanowane sloty, a nie zarejestrowane czasy emisji |
jammertest_score |
(session_toml, log, catalog_json, plans, location=None, local_offset_h=2.0, log_start_utc=None, year=None, recover_hold_s=10.0, guard_s=60.0) -> dict |
dziennik odbiornika oceniony względem tego harmonogramu: opóźnienie, niewykryte zdarzenia, czas odzyskania i fałszywe alarmy dla każdego testu (MODELLED; podpisany pakiet wymaga wiersza poleceń) |
evidence_create |
(session_toml, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
podpisany pakiet dowodowy dla okna dziennika, w pamięci: files, public_key, seed_hex (zachowaj prywatnie); zapis techniczny, a nie opinia prawna |
evidence_verify |
(files, public_key=None, full_log=None, require_timestamp=False) -> dict |
weryfikacja pakietu: skróty, łańcuch, podpis, opcjonalnie zaufany podpisujący, pełny dziennik i znacznik czasu; verdict ma wartość verified, intact-signer-not-pinned (nie podano klucza publicznego: pakiet nienaruszony, podpisujący niepotwierdzony) lub failed |
export_sp3, export_omm, export_oem |
(toml) -> str |
artefakty --export-sp3/-omm/-oem z wiersza poleceń jako tekst |
export_formats |
(toml) -> list[dict] |
które formaty interoperacyjne mają zastosowanie do scenariusza, bez jego uruchamiania |
export_scenario |
(toml, format) -> dict |
czml, kml, geojson, stk lub sigmf w pamięci: {format, spec_url, files}, każdy plik jako {suffix, bytes, sha256, encoding, content} (tekst utf-8 lub base64) |
import_route |
(toml, geojson) -> str |
trasa GeoJSON zapisana w scenariuszu toru z punktami trasy (--import-route) |
animate_scenario |
(toml, format="svg", fps=None, duration_s=None, width=None) -> dict |
szereg czasowy przebiegu jako animowany SVG, odtwarzacz HTML lub do 120 klatek SVG: {summary, files} |
list_examples, get_example |
(kind=None) -> dict, (name) -> str |
dołączone scenariusze referencyjne i ich TOML |
evidence_attach_timestamp |
(files, token, replace=False) -> dict |
powiązanie tokenu RFC 3161 (bajty lub base64) z pakietem w pamięci: {files, notes}; pakiet nadal musi przejść weryfikację; podpis urzędu nie jest sprawdzany |
evidence_keygen |
() -> dict |
nowy klucz podpisujący w pamięci: seed_hex (PRYWATNY), public_key, fingerprint, warning; tylko Python |
iq_sweep |
(i, q, fs_hz, signal, prns, ..., pll_bws=None, dll_bws=None, spacings=None, coherents=None, design=None) -> dict |
odtworzenie jednego nagrania w różnych projektach pętli (iq sweep): dla każdego projektu i PRN jitter w stanie ustalonym, ułamki zaczepienia i C/N0; jedna akwizycja na PRN, każdy kanał na tych samych próbkach |
iq_info, iq_inventory |
(path, hash=False) -> dict, (directory, recursive=False, hash=False) -> list |
opis jednego nagrania lub wszystkich nagrań w folderze (odczytuje pliki; hash odczytuje je w całości) |
bench_export |
(toml, epoch=None) -> dict |
ruch pojazdu i zdarzenia scenariusza dla laboratoryjnego symulatora GNSS, w pamięci: {files: {suffix: text}, notes, notice}; rodzaje gnss-ins, jamming, gnss-sim; żaden sygnał nie jest zapisywany, notice należy zachować razem z plikami |
compliance_report |
(runs) -> dict |
mapowanie jawnych ram odniesienia wypełnione na podstawie tekstów wyników: runs to lista słowników {label, result, scenario?} (tekst, co najwyżej 64); zwraca {report, markdown}; pole status w każdym wierszu mówi, że przebiegi dostarczają dowodów na (supports evidence for) jego możliwości, a nie że ramy odniesienia są spełnione; przy każdym wyświetleniu należy dołączać report["statement"] |
compliance_mapping |
(sources=False) -> str |
statyczne tabele mapowania (lub dokumenty źródłowe) jako Markdown, z oświadczeniem na początku |
standards_pack_list |
() -> dict |
pakiety norm (identyfikator, tytuł, ramy odniesienia, liczba testów) oraz uwaga; pakiet mierzy modelowane scenariusze względem progów podanych przed przebiegiem |
standards_pack_run |
(pack_id) -> dict |
jeden przebieg pakietu: każdy test MET, NOT MET lub NEEDS INPUT z wartościami zmierzonymi i oczekiwanymi, a także raport w Markdown pod markdown; zgłasza ValueError dla nieznanego identyfikatora |
lunanet_afs_check_spec |
() -> dict |
implementacja LunaNet AFS sprawdzona względem wydrukowanych tabel i przykładów obliczeniowych z LSIS-AFS V1.0 (progi B1 do B10; B4 zgłasza jedno zapisane niespełnienie) |
lunanet_afs_check_symbols |
(symbols, max_sp_errors=0) -> dict |
strumień symboli AFS (tekst z 0 i 1) sprawdzony pod kątem wzorca synchronizacji, dekodowania SB1, FID, ciągłości i odstępów TOI; LDPC i CRC-24Q podramek od 2 do 4 nie są weryfikowane |
lunanet_afs_generate |
(frames=1, toi0=0) -> str |
testowy strumień symboli z podramkami zastępczymi (nie jest to przebieg sygnału) |
evidence_round_trip |
(scoring_toml, scenario_toml, conditions, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
podpisany laboratoryjny pakiet pełnego obiegu, łączący skrótami scenariusz, warunki testu (docs/spec/TEST-CONDITIONS.md), dziennik odbiornika i wynik; jako evidence_create |
bench_score |
(truth_json, predictions_json, threshold=None) -> str |
plik wyników kshana-bench (tekst JSON) z pliku prawdy i pliku predykcji; MODELLED |
bench_leaderboard |
(results: list[str]) -> str |
pliki wyników kshana-bench wyrenderowane jako statyczna strona rankingu (HTML) |
osnma_verify |
(data, format="", start_gst=None, merkle_root_hex="", public_keys=None, reference_time=None, max_time_error=None) -> dict |
uwierzytelnianie Galileo OSNMA stron I/NAV lub strumienia UBX w pamięci: słownik, który wypisuje kshana osnma verify --json, z informacją doradczą w polu advisory; wyłącznie doradczo, nie jest to usługa integralności nawigacji |
sky_geometry |
(request) -> dict |
satelity widoczne z punktu przy skyline zależnym od azymutu: dla każdego satelity visible / masked, GDOP, PDOP, HDOP, VDOP, TDOP, kofaktor i kowariancja we współrzędnych wschód-północ-góra oraz poziome elipsy błędów; request to tekst JSON lub TOML albo słownik (site, time_s, systems, tle, satellites, mask_deg, skyline, clock, sigma_uere_m, confidence); decyzja o widoczności i elipsa są sprawdzane względem niezależnych bibliotek, reszta jest MODELLED, a wynik zawiera informację doradczą (sky_source, sky_statement mówią, czy niebo jest reprezentatywne, czy pochodzi z zestawów elementów orbitalnych) |
sky_monte_carlo |
(request, seed=0, n=1000) -> dict |
n (1 do 5000) błędów metody najmniejszych kwadratów z ziarnem na widocznym zbiorze request, wraz z ich kowariancją empiryczną, RMS i ułamkiem mieszczącym się w elipsie 95 % |
skyline_presets |
() -> list[dict] |
gotowe skyline (city-street, harbour-approach, fjord, container-terminal) z etykietą REPRESENTATIVE, pochodzeniem i przesłonięciem dla każdego stopnia azymutu; geometrie reprezentatywne, a nie pomiary terenowe |
skyline_profile |
(skyline) -> dict |
sekcja skyline (tabela, kanion uliczny, sektory, teren) sprowadzona do znormalizowanej 360-elementowej tabeli używanej przez silnik |
skyplot_svg |
(request) -> str |
skyplot dla request jako statyczny tekst SVG |
trust_telemetry |
(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0) -> str |
strumień wskaźnika zaufania (jsonl) lub wynik receiver-trust jako tekst Prometheus, wiersze syslog CEF lub LEEF albo ładunek OTLP JSON, z koderami kshana trust-telemetry; nic nie jest wysyłane i nie jest odczytywany żaden zegar (wiersze syslog nie zawierają znacznika czasu) |
interference_map |
(source, csv, dataset, cell_deg=None, licence=None, licence_url=None, attribution=None, land_geojson=None) -> list[dict] |
mapa zakłóceń GNSS z tekstu CSV z ADS-B lub AIS: jeden słownik na dobę UTC z GeoJSON kshana-interference-map/v1 (tylko dane zagregowane; zdegradowana komórka nie wskazuje zakłóceń jako przyczyny) |
interference_emitter_regions |
(source, csv, dataset, licence=None, licence_url=None, attribution=None, land_geojson=None) -> dict |
szacowane obszary emitera z tekstu CSV ADS-B lub AIS: {stem, geojson, summary, csv, svg, sessions_published, sessions_withheld}, każdy oznaczony MODELLED; obszary na podanej ufności z centroidem i elipsą niepewności, nigdy goły punkt; tylko zbiorczo, a obszar nie jest pozycją niczyją ani ustaleniem przyczyny |
route_exposure |
(route, maps, date_from=None, date_to=None) -> str |
udział trasy przebiegającej przez zdegradowane komórki tych map, jako tekst JSON (nie jest to prognoza; nieobserwowane komórki nie są dowodem, że trasa jest wolna od zakłóceń) |
nmea_training |
(toml, seed=None) -> dict |
syntetyczne NMEA mostka do szkolenia załóg oraz dziennik instruktora (nmea, log_json, log_text); wyłącznie tekst, nigdy do systemów nawigacyjnych statku działających na żywo |
iq_signals |
() -> list[str] |
nazwy sygnałów IQ GNSS akceptowane przez iq_scene, iq_acquire i iq_track (gps-l1ca, galileo-e1b, glonass-l1of, ...) |
iq_scene |
(fs_hz, duration_s, signal, prns, **options) -> dict |
wielosatelitarna scena IQ GNSS w pamięci: samples_i / samples_q oraz truth dla każdej epoki |
iq_scene_broadcast |
(fs_hz, window_s, nav_text, rx_lat, rx_lon, rx_alt, **options) -> dict |
to samo, przy czym każdy satelita GPS ma geometrię z efemeryd nadawanych, pochodzącą z komunikatu nawigacyjnego RINEX (Receiver Independent Exchange Format) |
iq_acquire |
(i, q, fs_hz, signal, prns, **options) -> list[dict] |
akwizycja FFT (fast Fourier transform) każdego PRN (pseudorandom noise code): Doppler, faza kodu, statystyka, próg |
iq_acq_surface |
(i, q, fs_hz, signal, prn, **options) -> dict |
cała powierzchnia akwizycji jednego PRN (kshana.acq-surface/1): moc korelacji rows[doppler][lag], szczyt i dwa uściślenia Dopplera (parabolic, fine_search) |
iq_track |
(i, q, fs_hz, signal, prns, **options) -> dict |
akwizycja, a następnie śledzenie każdego PRN: Doppler, faza kodu, wskaźniki zaczepienia, C/N0 i korelator prompt w każdej epoce |
iq_frontend |
(i, q, fs_hz, **options) -> dict |
tor wejściowy odbiornika (filtr pasmowy, filtr wycinający, blanking, wycinanie, AGC (automatic gain control), kwantyzator) na próbkach zespolonych |
iq_labfit |
(toml: str) -> dict |
dopasowanie modelu utraty zaczepienia pętli śledzenia do osi czasu wskaźnika zaufania odbiornika (scenariusz iq-labfit) |
iq_loop_designs |
(toml) -> list[dict] |
sparsowanie pliku kshana.loop-design/1 (ścieżka lub tekst TOML) do rozwiązanych projektów, każdy z polami name i hash; ValueError przy niepoprawnym pliku |
iq_read_epochs |
(path) -> dict |
odczyt binarnego pliku epok śledzenia (kshana.track-epoch/1, tak jak zapisuje go kshana iq track --epochs): header i jeden słownik na epokę w records |
iq_monitor |
(path, signal=None, prns=None, power=False, spectral=False, settings=None, ...) -> dict |
monitory detekcji IQ dla nagrania w jednym przebiegu strumieniowym (iq monitor): series, events, spectra i notes; odczytuje plik |
iq_test_conditions |
(conditions) -> dict |
walidacja laboratoryjnego pliku warunków testu (kshana.test-conditions/1, TOML lub JSON, ścieżka lub tekst) i zwrócenie go w postaci rozwiązanej, z polem hash |
iq_campaign |
(campaign, out_dir, workers=0, resume=True, max_cells=None, dry_run=False) -> dict |
uruchomienie kampanii odtwarzania laboratoryjnego (kshana.campaign/1) do out_dir tak, jak robi to kshana iq campaign; ukończone komórki są pomijane; zwraca liczby komórek, niepowodzenia i digest, gdy wszystkie komórki są gotowe |
iq_campaign_report |
(out_dir) -> dict |
odbudowanie kart wyników kampanii, raportu HTML i skrótu z jej komórek: liczby komórek i wierszy, wiersze niespełniające progu oraz digest |
Sygnatury IQ GNSS i zaufania do odbiornika#
Pełne sygnatury, tak jak podaje je kshana.pyi (każde słowo kluczowe po wymaganych argumentach ma wartość domyślną; docstringi w pliku typów wyjaśniają znaczenie każdego z nich). Listy samples_i / samples_q oraz wejścia i / q należy dla tablic opakować w numpy.asarray(...).
def receiver_trust(toml: str) -> RunOutput: ...
def receiver_trust_replay(session_toml: str, nmea: str | bytes) -> dict: ...
def assess_vessel_log(session_toml: str, log: str | bytes) -> dict: ...
def jammertest_import(catalog_json: str, plans: list[str], log_start_utc: str, location: int | None = None,
local_offset_h: float = 2.0, year: int | None = None) -> dict: ...
def jammertest_score(session_toml: str, log: str | bytes, catalog_json: str, plans: list[str],
location: int | None = None, local_offset_h: float = 2.0,
log_start_utc: str | None = None, year: int | None = None,
recover_hold_s: float = 10.0, guard_s: float = 60.0) -> dict: ...
def evidence_create(session_toml: str, log: str | bytes, from_s: float, to_s: float,
title: str | None = None, created_utc: str | None = None,
seed_hex: str | None = None) -> dict: ...
def evidence_verify(files: dict[str, str | bytes], public_key: str | None = None,
full_log: str | bytes | None = None,
require_timestamp: bool = False) -> dict: ...
def interference_map(source: str, csv: str, dataset: str, cell_deg: float | None = None,
licence: str | None = None, licence_url: str | None = None,
attribution: str | None = None, land_geojson: str | None = None) -> list[dict]: ...
def route_exposure(route: str, maps: list[str], date_from: str | None = None,
date_to: str | None = None) -> str: ...
def export_sp3(toml: str) -> str: ...
def export_omm(toml: str) -> str: ...
def export_oem(toml: str) -> str: ...
def export_formats(toml: str) -> list[dict]: ...
def export_scenario(toml: str, format: str) -> dict: ...
def import_route(toml: str, geojson: str) -> str: ...
def animate_scenario(toml: str, format: str = "svg", fps: int | None = None,
duration_s: float | None = None, width: int | None = None) -> dict: ...
def list_examples(kind: str | None = None) -> dict: ...
def get_example(name: str) -> str: ...
def evidence_attach_timestamp(files: dict[str, str | bytes], token: str | bytes,
replace: bool = False) -> dict: ...
def evidence_keygen() -> dict: ...
def iq_sweep(i: list[float], q: list[float], fs_hz: float, signal: str, prns: list[int],
**options) -> dict: ...
def iq_info(path: str, hash: bool = False) -> dict: ...
def iq_inventory(directory: str, recursive: bool = False, hash: bool = False) -> list[dict]: ...
def bench_export(toml: str, epoch: str | None = None) -> dict: ...
def compliance_report(runs: list[dict[str, str]]) -> dict: ...
def compliance_mapping(sources: bool = False) -> str: ...
def standards_pack_list() -> dict[str, Any]: ...
def standards_pack_run(pack_id: str) -> dict[str, Any]: ...
def lunanet_afs_check_spec() -> dict[str, Any]: ...
def lunanet_afs_check_symbols(symbols: str, max_sp_errors: int = 0) -> dict[str, Any]: ...
def lunanet_afs_generate(frames: int = 1, toi0: int = 0) -> str: ...
def evidence_round_trip(scoring_toml: str, scenario_toml: str, conditions: str, log: str | bytes, from_s: float, to_s: float, title: Optional[str] = None, created_utc: Optional[str] = None, seed_hex: Optional[str] = None) -> dict[str, Any]: ...
def bench_score(truth_json: str, predictions_json: str, threshold: float | None = None) -> str: ...
def bench_leaderboard(results: list[str]) -> str: ...
def osnma_verify(data: bytes | str, format: str = "", start_gst: int | None = None,
merkle_root_hex: str = "", public_keys: list[str] | None = None,
reference_time: int | None = None, max_time_error: int | None = None) -> dict: ...
def sky_geometry(request: str | dict[str, Any]) -> dict[str, Any]: ...
def sky_monte_carlo(request: str | dict[str, Any], seed: int = 0, n: int = 1000) -> dict[str, Any]: ...
def skyline_presets() -> list[dict[str, Any]]: ...
def skyline_profile(skyline: str | dict[str, Any]) -> dict[str, Any]: ...
def skyplot_svg(request: str | dict[str, Any]) -> str: ...
def trust_telemetry(input: str, format: str, host: str = "", input_kind: str = "jsonl",
expose_position: bool = False, syslog_all: bool = False,
unix_nano: int = 0) -> str: ...
def nmea_training(toml: str, seed: int | None = None) -> dict[str, str]: ...
def iq_signals() -> list[str]: ...
def iq_scene(
fs_hz: float,
duration_s: float,
signal: str,
prns: list[int],
dopplers: Optional[list[float]] = ...,
cn0_dbhz: Optional[float] = ...,
center_hz: Optional[float] = ...,
if_hz: float = ...,
noise: bool = ...,
noise_figure_db: float = ...,
seed: int = ...,
data: bool = ...,
threads: int = ...,
iono_stec: Optional[float] = ...,
iono_vtec: Optional[float] = ...,
iono_klobuchar: bool = ...,
tropo: bool = ...,
tropo_doy: float = ...,
s4: Optional[float] = ...,
scint_tau0: float = ...,
sigma_phi: float = ...,
multipath_height: Optional[float] = ...,
multipath_ground: str = ...,
land_mobile: bool = ...,
nlos: bool = ...,
) -> dict[str, Any]: ...
def iq_scene_broadcast(
fs_hz: float,
window_s: float,
nav_text: str,
rx_lat: float,
rx_lon: float,
rx_alt: float,
prns: Optional[list[int]] = ...,
start_tow: float = ...,
cn0_dbhz: Optional[float] = ...,
center_hz: Optional[float] = ...,
if_hz: float = ...,
noise: bool = ...,
noise_figure_db: float = ...,
seed: int = ...,
mask_deg: float = ...,
threads: int = ...,
) -> dict[str, Any]: ...
def iq_acquire(
i: list[float],
q: list[float],
fs_hz: float,
signal: str,
prns: list[int],
if_hz: float = ...,
center_hz: Optional[float] = ...,
coherent: int = ...,
noncoherent: int = ...,
doppler_max: float = ...,
doppler_step: Optional[float] = ...,
pfa: float = ...,
) -> list[dict[str, Any]]: ...
def iq_acq_surface(
i: list[float],
q: list[float],
fs_hz: float,
signal: str,
prn: int,
if_hz: float = ...,
center_hz: Optional[float] = ...,
coherent: int = ...,
noncoherent: int = ...,
doppler_max: float = ...,
doppler_step: Optional[float] = ...,
pfa: float = ...,
) -> dict[str, Any]: ...
def iq_track(
i: list[float],
q: list[float],
fs_hz: float,
signal: str,
prns: list[int],
if_hz: float = ...,
center_hz: Optional[float] = ...,
pll_bw: Optional[float] = ...,
fll_bw: Optional[float] = ...,
dll_bw: Optional[float] = ...,
spacing: Optional[float] = ...,
coherent: Optional[int] = ...,
periods_per_bit: Optional[int] = ...,
acq_coherent: Optional[int] = ...,
acq_noncoherent: int = ...,
doppler_max: float = ...,
max_seconds: Optional[float] = ...,
) -> dict[str, Any]: ...
def iq_frontend(
i: list[float],
q: list[float],
fs_hz: float,
bandpass_lo: Optional[float] = ...,
bandpass_hi: Optional[float] = ...,
bandpass_transition: Optional[float] = ...,
bandpass_atten: float = ...,
notch: bool = ...,
notch_r: float = ...,
notch_mu: float = ...,
blank: Optional[float] = ...,
blank_hold: int = ...,
excise: bool = ...,
excise_fft: int = ...,
excise_pfa: float = ...,
agc: bool = ...,
agc_tau: float = ...,
bits: Optional[int] = ...,
quant_step: Optional[float] = ...,
no_agc: bool = ...,
) -> dict[str, Any]: ...
def iq_labfit(toml: str) -> dict[str, Any]: ...
def iq_loop_designs(toml: str) -> list[dict[str, Any]]: ...
def iq_read_epochs(path: str) -> dict[str, Any]: ...
def iq_monitor(path: str, signal: Optional[str] = ..., prns: Optional[list[int]] = ...,
power: bool = ..., spectral: bool = ..., settings: Optional[str] = ...,
**options) -> dict[str, Any]: ...
def iq_test_conditions(conditions: str) -> dict[str, Any]: ...
def iq_campaign(campaign: str, out_dir: str, workers: int = 0, resume: bool = True,
max_cells: Optional[int] = None, dry_run: bool = False) -> dict[str, Any]: ...
def iq_campaign_report(out_dir: str) -> dict[str, Any]: ...
Kampania odtwarzania laboratoryjnego z poziomu Pythona, a potem jej raport (plik kampanii i nagrania są Twoje; ukończona komórka jest pomijana przy następnym wywołaniu; iq_read_epochs odczytuje plik epok śledzenia zapisany przez przebieg kshana iq track --epochs):
import kshana
summary = kshana.iq_campaign("lab.campaign.toml", "campaign-out", workers=4)
report = kshana.iq_campaign_report("campaign-out")
print(report["digest"]) # None until every cell is done
Parametr acq_coherent w iq_track ustala, ile okresów kodu integruje koherentnie akwizycja przekazująca. Od wersji 0.33.0 domyślnie ma wartość None, czyli auto: około 4 ms (4 okresy dla kodu 1 ms, takiego jak GPS L1 C/A, 1 dla kodu o długości 4 ms lub większej), dzięki czemu kanał startuje dość blisko, by pętla częstotliwości mogła go wciągnąć; acq_coherent=1 zachowuje wyszukiwanie jednookresowe z wersji 0,32.
Typy#
kshana.pyi typuje zamknięte słowniki dla narzędzi sprawdzających (mypy, pyright): ScenarioKind (każda nazwa rodzaju, Literal), ErrorKind (cztery znaczniki zwracane przez error_kind), ProvenanceClass oraz typy TypedDict KindMeta (lista takich elementów jest zwracana przez scenario_kinds()) i FieldUnit (wpis bloku units wyniku, który rozszerza bazę wymaganych kluczy _FieldUnitBase). Istnieją wyłącznie dla narzędzi sprawdzających typy i nie można ich importować w czasie działania; tests/typed_api_sync.rs utrzymuje ich zgodność z listami silnika.
from typing import TYPE_CHECKING
import kshana
if TYPE_CHECKING:
from kshana import ScenarioKind
names: "list[ScenarioKind]" = [k["name"] for k in kshana.scenario_kinds()]
RunOutput#
| Składowa | Typ | Uwagi |
|---|---|---|
.json |
str |
pełny dokument wynikowy (JSON) |
.svg |
str |
samodzielny wykres SVG (Scalable Vector Graphics) |
.summary |
str |
jednowierszowe podsumowanie dla człowieka |
.csv |
str | None |
tabela odtwarzalności, dla rodzajów, które ją emitują (zob. niżej) |
.data() |
dict |
wynik sparsowany do słownika Pythona (zob. uwaga o kształcie poniżej) |
.array(path) |
numpy.ndarray |
lista liczbowa pod path (ze znakiem kropki, "points.0.coords", lub jako JSON Pointer, "/points/0/coords"): 1-D dla liczb, 2-D dla list liczbowych o równej długości |
.columns(path) |
dict[str, numpy.ndarray] |
lista rekordów pod path (szereg czasowy), jedna tablica na każde pole, które w każdym rekordzie jest liczbą |
.series() |
dict[str, dict[str, numpy.ndarray]] |
każda lista rekordów z polem liczbowym, indeksowana ścieżką z kropkami, każda jako .columns |
.write_csv(path) |
int |
zapis tej tabeli do path; zwraca liczbę zapisanych bajtów albo 0 (i nic nie zapisuje), gdy rodzaj nie emituje tabeli |
Tabela odtwarzalności#
realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing i leo-navmsg zawsze publikują tabelę; moonlight-service-volume publikuje ją, gdy skonfigurowano punkt eksportu (export_site_lat_deg + export_site_lon_deg). Każdy inny rodzaj zwraca csv = None. Tekst to te same bajty, które interfejs wiersza poleceń (CLI) zapisuje jako <scenario>.table.csv, więc recenzent odtwarzający opublikowaną tabelę z pakietu wheel nigdy nie musi schodzić do wiersza poleceń:
import kshana
out = kshana.run_typed(open("scenarios/realtime-frame-eop.toml").read())
if out.csv is not None:
print(out.write_csv("table.csv"), "bytes written")
Kształt wyniku#
Wskaźniki jakości i szeregi czasowe znajdują się osobno dla każdej strony przebiegu, a nie na najwyższym poziomie. Dla przebiegu zegara dokument wygląda tak:
schema_version engine_version scenario_hash seed threshold_ns units figure_tiers
quantum → spec · series · fom · adev_curve · filter_health
classical → spec · series · fom · adev_curve · filter_health
więc wskaźniki jakości to data["quantum"]["fom"], nigdy data["figures_of_merit"]. Inne rodzaje emitują własne pakiety; pełna dokumentacja pól, z jednostkami i wskaźnikiem źródła, to field-units-schema.json, a przewodnik dla czytelnika to SCHEMA.md.
Uwagi#
validate_tomlierror_kindwykonują scenariusz, więc ujawniają błędy parsowania, konfiguracji oraz błędy czasu działania. Nigdy nie zgłaszają wyjątku.run/run_typedzgłaszająValueErrorprzy niepoprawnym scenariuszu.- Wyniki są odtwarzalne: scenariusz zawiera swoje
seed, a silnik zapisujescenario_hash, więc te same dane wejściowe dają na tej samej platformie identyczne co do bajta dane wyjściowe (zob.REPRODUCIBILITY.md). .array,.columnsi.serieszwracają dokładnienumpy.asarray(...)tych samych wartości, które daje.data()(ten sam dtype, identyczne co do bitu;tests/python/test_numpy_runoutput.py). Importują NumPy w chwili wywołania i zgłaszająImportError, gdy go brak; NumPy nie należy do wymagań czasu działania pakietu.KeyErroroznacza, że ścieżki brakuje, aValueError, że wartość pod nią nie jest tablicą liczbową (ani listą rekordów). Notatniki do uruchomienia znajdują się wnotebooks/.
Nie w Pythonie: procesy długotrwałe#
kshana receiver-trust live (proces strumieniowy z bramką i opcjonalnym serwerem TCP --listen), eksportery telemetrii (Prometheus, OTLP, syslog; docs/TRUST-TELEMETRY.md) oraz strumieniowanie kshana nmea-scenario --tcp/--udp są dostępne wyłącznie z wiersza poleceń: powiązanie kończy działanie wraz z zakończeniem wywołania i nie trzyma otwartego gniazda. Python obejmuje wsadową postać każdego z nich: receiver_trust dla dziennika, receiver_trust_replay dla fragmentu strumienia (wskaźniki i stany; bramka nie jest stosowana), nmea_training dla wygenerowanego tekstu.