Python-API
Kshana liefert eine erstklassige Python-Programmierschnittstelle (API, application programming interface), gebaut mit PyO3 und maturin. Ihre abi3-Wheels werden gegen die stabile Python-Binärschnittstelle (ABI, application binary interface) gebaut, sodass ein Wheel je Plattform über CPython ≥ 3,9 hinweg funktioniert; die Wheels decken Linux, macOS und Windows ab, jeweils auf x86-64 und 64-Bit-ARM (siehe WHEEL_TAGS.md). Ein mitgeliefertes Typ-Stub (kshana.pyi + py.typed) gibt Editoren und mypy/pyright vollständige Typinformationen.
pip install kshana # from the Python Package Index, PyPI (release wheels)
# or, from a checkout:
pip install maturin && maturin develop --features python
Schnellstart#
Führen Sie diese Snippets aus dem Wurzelverzeichnis eines Repository-Checkouts aus: Sie lesen Szenariodateien unter scenarios/. Die NumPy-Zeile braucht 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
Oberfläche#
| Symbol | Signatur | Rückgabe |
|---|---|---|
run_typed |
(toml: str) -> RunOutput |
typisiertes Ergebnis (.json, .svg, .summary, .csv, .data(), .array(), .columns(), .series(), .write_csv()) |
run |
(toml: str) -> str |
Ergebnisdokument als JSON-String (JavaScript Object Notation) |
run_full |
(toml: str) -> tuple[str, str, str] |
(json, svg, summary) |
scenario_kinds |
() -> list[dict] |
verfügbare Szenarioarten + Metadaten (geparst) |
list_kinds |
() -> str |
dieselben Metadaten als EIN JSON-Array-String, keine Liste (für bestehende Aufrufer beibehalten; verwenden Sie scenario_kinds für die geparste Liste) |
validate_toml |
(toml: str) -> list[str] |
Fehlermeldungen (leer, wenn gültig) |
error_kind |
(toml: str) -> str | None |
Tag der Fehlerkategorie (invalid_input, non_convergence, unsupported oder io_error), oder None bei Erfolg |
version / __version__ |
() -> str / str |
Engine-Version |
receiver_trust |
(toml: str) -> RunOutput |
ein reales Empfänger-Log bewerten, das durch ein Szenario receiver-trust beschrieben wird: Ergebnisdokument, CSV mit Vertrauenswert je Epoche, Diagramm und Zusammenfassung; eine Tabelle [platform] kind = "vessel" fügt die maritimen Monitore und den Vertrauenswert von 0 bis 100 mit Gründen hinzu (beratend) |
receiver_trust_replay |
(session_toml, nmea) -> dict |
ein begrenzter NMEA-Auszug, so bewertet, wie der Live-Modus bewertet: Zustand je Epoche, Wert von 0 bis 100 und Gründe, eine Zusammenfassung (kein Socket, kein Gate; beratend) |
assess_vessel_log |
(session_toml, log) -> dict |
das NMEA-Log eines Schiffes als Batch-Lauf: das Bewertungsmodell und der Wert jeder Epoche mit ihren Abzügen (beratend) |
jammertest_import |
(catalog_json, plans, log_start_utc, location=None, local_offset_h=2.0, year=None) -> dict |
der veröffentlichte Jammertest-Katalog und -Plan als Ereignisse der geplanten Wahrheit (events_toml, events); geplante Slots, keine aufgezeichneten Sendezeiten |
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 |
ein Empfänger-Log, bewertet gegen diesen Zeitplan: Latenz je Test, verpasst, Zeit bis zur Erholung, Fehlalarme (MODELLED; ein signiertes Paket braucht die Kommandozeile) |
evidence_create |
(session_toml, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
ein signiertes Nachweispaket für ein Fenster des Logs, im Speicher: files, public_key, seed_hex (privat halten); eine technische Aufzeichnung, keine Rechtsauffassung |
evidence_verify |
(files, public_key=None, full_log=None, require_timestamp=False) -> dict |
ein Paket verifizieren: Hashes, Kette, Signatur, optional den vertrauenswürdigen Unterzeichner, das vollständige Log und einen Zeitstempel; verdict ist verified, intact-signer-not-pinned (kein öffentlicher Schlüssel angegeben: intakt, Unterzeichner nicht festgestellt) oder failed |
export_sp3, export_omm, export_oem |
(toml) -> str |
die Artefakte --export-sp3/-omm/-oem der CLI als Text |
export_formats |
(toml) -> list[dict] |
welche Interoperabilitätsformate für ein Szenario gelten, ohne es auszuführen |
export_scenario |
(toml, format) -> dict |
czml, kml, geojson, stk oder sigmf im Speicher: {format, spec_url, files}, jede Datei {suffix, bytes, sha256, encoding, content} (utf-8-Text oder base64) |
import_route |
(toml, geojson) -> str |
eine in ein Wegpunktkurs-Szenario geschriebene GeoJSON-Route (--import-route) |
animate_scenario |
(toml, format="svg", fps=None, duration_s=None, width=None) -> dict |
die Zeitreihe des Laufs als animiertes SVG, HTML-Player oder bis zu 120 SVG-Bilder: {summary, files} |
list_examples, get_example |
(kind=None) -> dict, (name) -> str |
die mitgelieferten Referenzszenarien und ihr TOML |
evidence_attach_timestamp |
(files, token, replace=False) -> dict |
ein RFC-3161-Token (Bytes oder Base64) im Speicher an ein Paket binden: {files, notes}; das Paket muss weiterhin verifizieren; die Signatur der Autorität wird nicht geprüft |
evidence_keygen |
() -> dict |
ein neuer Signaturschlüssel im Speicher: seed_hex (PRIVAT), public_key, fingerprint, warning; nur Python |
iq_sweep |
(i, q, fs_hz, signal, prns, ..., pll_bws=None, dll_bws=None, spacings=None, coherents=None, design=None) -> dict |
eine Aufzeichnung über mehrere Schleifenentwürfe abspielen (iq sweep): je Entwurf und PRN Jitter im eingeschwungenen Zustand, Lock-Anteile und C/N0; eine Akquisition je PRN, jeder Kanal auf denselben Samples |
iq_info, iq_inventory |
(path, hash=False) -> dict, (directory, recursive=False, hash=False) -> list |
eine Aufzeichnung oder jede Aufzeichnung in einem Ordner beschreiben (liest Dateien; hash liest sie vollständig) |
bench_export |
(toml, epoch=None) -> dict |
die Fahrzeugbewegung und die Ereignisse eines Szenarios für einen GNSS-Laborsimulator, im Speicher: {files: {suffix: text}, notes, notice}; Arten gnss-ins, jamming, gnss-sim; es wird kein Signal geschrieben, behalten Sie notice bei den Dateien |
compliance_report |
(runs) -> dict |
die Zuordnung zum öffentlichen Rahmenwerk, ausgefüllt aus Ergebnistexten: runs ist eine Liste von {label, result, scenario?}-Dicts (Text, höchstens 64); gibt {report, markdown} zurück; der status jeder Zeile besagt, dass die Läufe Belege für ihre Fähigkeiten liefern, nicht dass ein Rahmenwerk erfüllt ist; führen Sie report["statement"] bei jeder Anzeige mit |
compliance_mapping |
(sources=False) -> str |
die statischen Zuordnungstabellen (oder die Quelldokumente) als Markdown, angeführt von der Aussage |
standards_pack_list |
() -> dict |
die Standards-Packs (ID, Titel, Rahmenwerk, Testanzahlen) und ein Hinweis; ein Pack misst modellierte Szenarien an vor dem Lauf festgelegten Zielwerten |
standards_pack_run |
(pack_id) -> dict |
ein Pack-Lauf: jeder Test MET, NOT MET oder NEEDS INPUT mit gemessenen und erwarteten Werten, plus der Bericht als Markdown unter markdown; löst ValueError bei einer unbekannten ID aus |
lunanet_afs_check_spec |
() -> dict |
die LunaNet-AFS-Implementierung, geprüft gegen die gedruckten Tabellen und durchgerechneten Beispiele von LSIS-AFS V1.0 (Zielwerte B1 bis B10; B4 meldet eine festgehaltene Verfehlung) |
lunanet_afs_check_symbols |
(symbols, max_sp_errors=0) -> dict |
ein AFS-Symbolstrom (Text aus 0 und 1), geprüft auf Synchronisationsmuster, SB1-Dekodierung, FID, TOI-Kontinuität und -Abstand; LDPC und CRC-24Q der Unterrahmen 2 bis 4 sind nicht verifiziert |
lunanet_afs_generate |
(frames=1, toi0=0) -> str |
ein Test-Symbolstrom mit Platzhalter-Unterrahmen (keine Wellenform) |
evidence_round_trip |
(scoring_toml, scenario_toml, conditions, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
das signierte Labor-Round-Trip-Paket, das Szenario, Testbedingungen (docs/spec/TEST-CONDITIONS.md), Empfänger-Log und Bewertung per Hash verknüpft; als evidence_create |
bench_score |
(truth_json, predictions_json, threshold=None) -> str |
eine Ergebnisdatei von kshana-bench (JSON-Text) aus einer Wahrheitsdatei und einer Vorhersagedatei; MODELLED |
bench_leaderboard |
(results: list[str]) -> str |
Ergebnisdateien von kshana-bench, dargestellt als statische Bestenlisten-Seite (HTML) |
osnma_verify |
(data, format="", start_gst=None, merkle_root_hex="", public_keys=None, reference_time=None, max_time_error=None) -> dict |
Galileo-OSNMA-Authentifizierung von I/NAV-Seiten oder eines UBX-Streams im Speicher: das Dict, das kshana osnma verify --json ausgibt, mit dem Hinweis in seinem Feld advisory; nur beratend, kein Dienst für Navigationsintegrität |
sky_geometry |
(request) -> dict |
die Satelliten, die ein Standort unter einer azimutabhängigen Horizontlinie sieht: je Satellit visible / masked, GDOP, PDOP, HDOP, VDOP, TDOP, der Ost-Nord-Oben-Kofaktor und die Kovarianz sowie die horizontalen Fehlerellipsen; request ist JSON- oder TOML-Text oder ein Dict (site, time_s, systems, tle, satellites, mask_deg, skyline, clock, sigma_uere_m, confidence); die Sichtbarkeitsentscheidung und die Ellipse sind gegen unabhängige Bibliotheken geprüft, der Rest ist MODELLED, und das Ergebnis trägt den Hinweis (sky_source, sky_statement sagen, ob der Himmel repräsentativ ist oder aus Elementesätzen stammt) |
sky_monte_carlo |
(request, seed=0, n=1000) -> dict |
n (1 bis 5000) Kleinste-Quadrate-Fehler mit Seed auf der sichtbaren Menge von request, mit ihrer empirischen Kovarianz, ihrem RMS und dem Anteil innerhalb der 95-%-Ellipse |
skyline_presets |
() -> list[dict] |
die Horizontlinien-Presets (city-street, harbour-approach, fjord, container-terminal) mit ihrem Label REPRESENTATIVE, ihrer Herkunft und dem Schnitt für jedes Grad Azimut; repräsentative Geometrien, keine Vermessungen |
skyline_profile |
(skyline) -> dict |
ein Horizontlinien-Abschnitt (Tabelle, Straßenschlucht, Sektoren, Gelände), reduziert auf die normalisierte Tabelle mit 360 Einträgen, die die Engine verwendet |
skyplot_svg |
(request) -> str |
der Skyplot von request als statischer SVG-Text |
trust_telemetry |
(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0) -> str |
ein Vertrauens-Stream (jsonl) oder ein Ergebnis receiver-trust als Prometheus-Text, CEF- oder LEEF-Syslog-Zeilen oder OTLP-JSON-Nutzlast, mit den kshana trust-telemetry-Encodern; es wird nichts gesendet und keine Uhr gelesen (Syslog-Zeilen tragen keinen Zeitstempel) |
interference_map |
(source, csv, dataset, cell_deg=None, licence=None, licence_url=None, attribution=None, land_geojson=None) -> list[dict] |
eine GNSS-Störungskarte aus ADS-B- oder AIS-CSV-Text: ein Dict je UTC-Tag mit kshana-interference-map/v1-GeoJSON (nur aggregiert; eine degradierte Zelle nennt keine Störung als Ursache) |
interference_emitter_regions |
(source, csv, dataset, licence=None, licence_url=None, attribution=None, land_geojson=None) -> dict |
geschätzte Senderregionen aus ADS-B- oder AIS-CSV-Text: {stem, geojson, summary, csv, svg, sessions_published, sessions_withheld}, jede als MODELLED gekennzeichnet; Regionen bei genannter Konfidenz mit einem Schwerpunkt und einer Unsicherheitsellipse, nie ein bloßer Punkt; nur aggregiert, und eine Region ist nicht die Position von irgendjemandem und kein Befund der Ursache |
route_exposure |
(route, maps, date_from=None, date_to=None) -> str |
Anteil einer Route durch degradierte Zellen dieser Karten, als JSON-Text (keine Vorhersage; nicht beobachtete Zellen sind kein Beleg für eine freie Route) |
nmea_training |
(toml, seed=None) -> dict |
synthetisches Brücken-NMEA für die Besatzungsausbildung plus das Ausbilder-Log (nmea, log_json, log_text); nur Text, nie für die Live-Navigationssysteme eines Schiffes |
iq_signals |
() -> list[str] |
die GNSS-IQ-Signalnamen, die iq_scene, iq_acquire und iq_track akzeptieren (gps-l1ca, galileo-e1b, glonass-l1of, ...) |
iq_scene |
(fs_hz, duration_s, signal, prns, **options) -> dict |
eine GNSS-IQ-Szene mit mehreren Satelliten im Speicher: samples_i / samples_q und truth je Epoche |
iq_scene_broadcast |
(fs_hz, window_s, nav_text, rx_lat, rx_lon, rx_alt, **options) -> dict |
dasselbe, mit jedem GPS-Satelliten in der Geometrie seiner Broadcast-Ephemeride aus einer RINEX-Navigationsnachricht (Receiver Independent Exchange Format) |
iq_acquire |
(i, q, fs_hz, signal, prns, **options) -> list[dict] |
FFT-Akquisition (fast Fourier transform) jedes PRN (pseudorandom noise code): Doppler, Codephase, Statistik, Schwelle |
iq_acq_surface |
(i, q, fs_hz, signal, prn, **options) -> dict |
die gesamte Akquisitionsfläche eines PRN (kshana.acq-surface/1): Korrelationsleistung rows[doppler][lag], der Peak und zwei Feinverfeinerungen des Dopplers (parabolic, fine_search) |
iq_track |
(i, q, fs_hz, signal, prns, **options) -> dict |
akquirieren, dann jeden PRN nachführen: Doppler je Epoche, Codephase, Lock-Indikatoren, C/N0, Prompt-Korrelator |
iq_frontend |
(i, q, fs_hz, **options) -> dict |
die Front-End-Kette des Empfängers (Bandpass, Notch, Blanking, Excision, AGC (automatic gain control), Quantisierer) über komplexe Samples |
iq_labfit |
(toml: str) -> dict |
das Verlust-der-Nachführung-Modell der Nachführschleife an eine Zeitleiste des Empfängervertrauens anpassen (ein Szenario iq-labfit) |
iq_loop_designs |
(toml) -> list[dict] |
eine Datei kshana.loop-design/1 (einen Pfad oder TOML-Text) in ihre aufgelösten Entwürfe parsen, jeder mit seinem name und hash; ValueError bei einer ungültigen Datei |
iq_read_epochs |
(path) -> dict |
eine binäre Nachführ-Epochendatei lesen (kshana.track-epoch/1, wie kshana iq track --epochs sie schreibt): den header und ein Dict je Epoche in records |
iq_monitor |
(path, signal=None, prns=None, power=False, spectral=False, settings=None, ...) -> dict |
die IQ-Detektionsmonitore über eine Aufzeichnung in einem Streaming-Durchlauf (iq monitor): series, events, spectra und notes; liest eine Datei |
iq_test_conditions |
(conditions) -> dict |
eine Labor-Testbedingungsdatei validieren (kshana.test-conditions/1, TOML oder JSON, ein Pfad oder Text) und sie aufgelöst zurückgeben, mit ihrem hash |
iq_campaign |
(campaign, out_dir, workers=0, resume=True, max_cells=None, dry_run=False) -> dict |
eine Lab-Replay-Kampagne (kshana.campaign/1) nach out_dir ausführen, wie es kshana iq campaign tut; abgeschlossene Zellen werden übersprungen; gibt die Zellanzahlen, Fehler und den digest zurück, sobald jede Zelle fertig ist |
iq_campaign_report |
(out_dir) -> dict |
die Scorecards, den HTML-Bericht und den Digest einer Kampagne aus ihren Zellen neu aufbauen: die Zell- und Zeilenanzahlen, die Zeilen, die einen Zielwert verfehlen, und den digest |
Signaturen für GNSS-IQ und Empfängervertrauen#
Die vollständigen Signaturen, wie kshana.pyi sie angibt (jedes Schlüsselwort nach den erforderlichen Argumenten hat einen Standardwert; die Docstrings im Stub geben jeweils die Bedeutung an). Umhüllen Sie die Listen samples_i / samples_q und die Eingaben i / q für Arrays mit 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]: ...
Eine Lab-Replay-Kampagne aus Python, dann ihr Bericht (die Kampagnendatei und ihre Aufzeichnungen sind Ihre; eine abgeschlossene Zelle wird beim nächsten Aufruf übersprungen; iq_read_epochs liest eine Nachführ-Epochendatei, die ein Lauf von kshana iq track --epochs geschrieben hat):
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
acq_coherent von iq_track legt fest, über wie viele Codeperioden die Übergabe-Akquisition kohärent integriert. Ab 0.33.0 ist der Standardwert None, also automatisch: etwa 4 ms (4 Perioden bei einem Code von 1 ms wie GPS L1 C/A, 1 bei einem Code von 4 ms oder länger), sodass der Kanal nahe genug startet, damit die Frequenzschleife einrasten kann; acq_coherent=1 behält die Ein-Perioden-Suche von 0,32 bei.
Typen#
kshana.pyi typisiert die geschlossenen Vokabulare für Prüfprogramme (mypy, pyright): ScenarioKind (jeder Artname, ein Literal), ErrorKind (die vier Tags, die error_kind zurückgibt), ProvenanceClass und die TypedDicts KindMeta (wovon scenario_kinds() eine Liste zurückgibt) und FieldUnit (ein Eintrag im Block units eines Ergebnisses, der die Basis _FieldUnitBase mit den Pflichtschlüsseln erweitert). Sie existieren nur für Typprüfer und sind zur Laufzeit nicht importierbar; tests/typed_api_sync.rs hält sie gleich mit den Listen der Engine.
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#
| Mitglied | Typ | Hinweise |
|---|---|---|
.json |
str |
vollständiges Ergebnisdokument (JSON) |
.svg |
str |
eigenständiges Diagramm-SVG (Scalable Vector Graphics) |
.summary |
str |
einzeilige Zusammenfassung für Menschen |
.csv |
str | None |
die Reproduzierbarkeitstabelle, für die Arten, die eine ausgeben (siehe unten) |
.data() |
dict |
das in ein Python-Dict geparste Ergebnis (siehe den Hinweis zur Form unten) |
.array(path) |
numpy.ndarray |
die numerische Liste bei path (gepunktet, "points.0.coords", oder ein JSON-Pointer, "/points/0/coords"): 1D für Zahlen, 2D für numerische Listen gleicher Länge |
.columns(path) |
dict[str, numpy.ndarray] |
die Liste von Datensätzen bei path (eine Zeitreihe), ein Array je Feld, das in jedem Datensatz eine Zahl ist |
.series() |
dict[str, dict[str, numpy.ndarray]] |
jede Liste von Datensätzen mit einem numerischen Feld, nach gepunktetem Pfad geschlüsselt, jede als .columns |
.write_csv(path) |
int |
diese Tabelle nach path schreiben; gibt die geschriebenen Bytes zurück, oder 0 (und schreibt nichts), wenn die Art keine Tabelle ausgibt |
Die Reproduzierbarkeitstabelle#
realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing und leo-navmsg veröffentlichen immer eine Tabelle; moonlight-service-volume veröffentlicht eine, wenn ein Exportstandort (export_site_lat_deg + export_site_lon_deg) konfiguriert ist. Jede andere Art gibt csv = None zurück. Der Text hat dieselben Bytes, die die CLI (command-line interface) als <scenario>.table.csv schreibt, sodass ein Prüfer, der eine veröffentlichte Tabelle aus dem Wheel reproduziert, nie auf die Kommandozeile wechseln muss:
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")
Form des Ergebnisses#
Die Gütemaße und die Zeitreihen liegen je Lauf-Seite, nicht auf oberster Ebene. Für einen Uhrenlauf lautet das Dokument:
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
die Gütemaße sind also data["quantum"]["fom"], nie data["figures_of_merit"]. Andere Arten geben ihre eigenen Packs aus; die vollständige Referenz je Feld, mit Einheiten und einem Quellverweis, ist field-units-schema.json, und der Leitfaden für Leser ist SCHEMA.md.
Hinweise#
validate_tomlunderror_kindführen das Szenario aus, sodass sie Parse-, Konfigurations- und Laufzeitfehler sichtbar machen. Sie lösen nie eine Ausnahme aus.run/run_typedlösen bei einem ungültigen SzenarioValueErroraus.- Ergebnisse sind reproduzierbar: Ein Szenario trägt seinen
seed, und die Engine erfasst einenscenario_hash, sodass dieselbe Eingabe auf derselben Plattform byte-identische Ausgabe liefert (sieheREPRODUCIBILITY.md). .array,.columnsund.seriesgeben genaunumpy.asarray(...)derselben Werte zurück, die.data()liefert (gleicher dtype, bit-identisch;tests/python/test_numpy_runoutput.py). Sie importieren NumPy beim Aufruf und lösen ohne esImportErroraus; NumPy bleibt aus den Laufzeitanforderungen des Pakets heraus.KeyErrorbedeutet, dass der Pfad fehlt,ValueError, dass der Wert dort kein numerisches Array ist (oder keine Liste von Datensätzen). Lauffähige Notebooks stehen innotebooks/.
Nicht in Python: langlaufende Prozesse#
kshana receiver-trust live (ein Stream-Prozess mit einem Gate und einem optionalen TCP-Server --listen) und die Telemetrie-Exporter (Prometheus, OTLP, Syslog; docs/TRUST-TELEMETRY.md) sowie das Streaming von kshana nmea-scenario --tcp/--udp gibt es nur auf der Kommandozeile: Ein Binding kehrt zurück, wenn der Aufruf zurückkehrt, und hält keinen Socket offen. Python deckt die Batch-Form von jedem ab: receiver_trust für ein Log, receiver_trust_replay für einen Stream-Auszug (Werte und Zustände; das Gate wird nicht angewendet), nmea_training für den erzeugten Text.