API Python
Kshana livre une interface de programmation d'application (API) Python de premier plan, construite avec PyO3 et maturin. Ses wheels abi3 sont construits sur l'interface binaire d'application (ABI) stable de Python, de sorte qu'un seul wheel par plateforme fonctionne avec CPython ≥ 3,9 ; les wheels couvrent Linux, macOS et Windows, chacun en x86-64 et en ARM 64 bits (voir WHEEL_TAGS.md). Un stub de types fourni (kshana.pyi + py.typed) donne aux éditeurs et à mypy/pyright toute l'information de typage.
pip install kshana # from the Python Package Index, PyPI (release wheels)
# or, from a checkout:
pip install maturin && maturin develop --features python
Démarrage rapide#
Exécutez ces extraits depuis la racine d'une copie du dépôt : ils lisent des fichiers de scénario sous scenarios/. La ligne NumPy nécessite 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
Surface#
| Symbole | Signature | Renvoie |
|---|---|---|
run_typed |
(toml: str) -> RunOutput |
résultat typé (.json, .svg, .summary, .csv, .data(), .array(), .columns(), .series(), .write_csv()) |
run |
(toml: str) -> str |
document de résultat sous forme de chaîne JSON (JavaScript Object Notation) |
run_full |
(toml: str) -> tuple[str, str, str] |
(json, svg, summary) |
scenario_kinds |
() -> list[dict] |
types de scénario disponibles + métadonnées (analysées) |
list_kinds |
() -> str |
les mêmes métadonnées sous forme d'UNE chaîne de tableau JSON, et non d'une liste (conservée pour les appelants existants ; utilisez scenario_kinds pour la liste analysée) |
validate_toml |
(toml: str) -> list[str] |
messages d'erreur (vide si valide) |
error_kind |
(toml: str) -> str | None |
étiquette de catégorie d'échec (invalid_input, non_convergence, unsupported ou io_error), ou None en cas de succès |
version / __version__ |
() -> str / str |
version du moteur |
receiver_trust |
(toml: str) -> RunOutput |
évaluer un véritable journal de récepteur décrit par un scénario receiver-trust : document de résultat, CSV de confiance par époque, graphique et synthèse ; une table [platform] kind = "vessel" ajoute les moniteurs maritimes et le score de confiance de 0 à 100 avec ses motifs (à titre consultatif) |
receiver_trust_replay |
(session_toml, nmea) -> dict |
un extrait NMEA borné évalué comme le mode en direct l'évalue : état par époque, score de 0 à 100 et motifs, une synthèse (ni socket ni passerelle ; à titre consultatif) |
assess_vessel_log |
(session_toml, log) -> dict |
un journal NMEA de navire en exécution par lot : le modèle de score et le score de chaque époque avec ses déductions (à titre consultatif) |
jammertest_import |
(catalog_json, plans, log_start_utc, location=None, local_offset_h=2.0, year=None) -> dict |
le catalogue et le plan Jammertest publiés sous forme d'événements de vérité planifiée (events_toml, events) ; créneaux prévus, et non heures d'émission réellement enregistrées |
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 |
un journal de récepteur évalué par rapport à ce calendrier : latence par essai, manqués, temps de récupération, fausses alarmes (MODELLED ; un paquet signé nécessite la ligne de commande) |
evidence_create |
(session_toml, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
un paquet de preuves signé pour une fenêtre du journal, en mémoire : files, public_key, seed_hex (à garder privé) ; un dossier technique, non un avis juridique |
evidence_verify |
(files, public_key=None, full_log=None, require_timestamp=False) -> dict |
vérifier un paquet : hachages, chaîne, signature, éventuellement le signataire de confiance, le journal complet et un horodatage ; verdict vaut verified, intact-signer-not-pinned (aucune clé publique fournie : intact, signataire non établi) ou failed |
export_sp3, export_omm, export_oem |
(toml) -> str |
les artefacts --export-sp3/-omm/-oem de la CLI sous forme de texte |
export_formats |
(toml) -> list[dict] |
quels formats d'interopérabilité s'appliquent à un scénario, sans l'exécuter |
export_scenario |
(toml, format) -> dict |
czml, kml, geojson, stk ou sigmf en mémoire : {format, spec_url, files}, chaque fichier {suffix, bytes, sha256, encoding, content} (texte utf-8 ou base64) |
import_route |
(toml, geojson) -> str |
un itinéraire GeoJSON écrit dans un scénario de trajectoire à points de passage (--import-route) |
animate_scenario |
(toml, format="svg", fps=None, duration_s=None, width=None) -> dict |
les séries temporelles de l'exécution sous forme de SVG animé, de lecteur HTML ou d'un maximum de 120 images SVG : {summary, files} |
list_examples, get_example |
(kind=None) -> dict, (name) -> str |
les scénarios de référence fournis et leur TOML |
evidence_attach_timestamp |
(files, token, replace=False) -> dict |
lier un jeton RFC 3161 (octets ou base64) à un paquet en mémoire : {files, notes} ; le paquet doit toujours se vérifier ; la signature de l'autorité n'est pas contrôlée |
evidence_keygen |
() -> dict |
une nouvelle clé de signature en mémoire : seed_hex (PRIVÉE), public_key, fingerprint, warning ; Python uniquement |
iq_sweep |
(i, q, fs_hz, signal, prns, ..., pll_bws=None, dll_bws=None, spacings=None, coherents=None, design=None) -> dict |
rejouer un enregistrement sur plusieurs conceptions de boucle (iq sweep) : par conception et par PRN, gigue en régime permanent, fractions de verrouillage et C/N0 ; une acquisition par PRN, chaque canal sur les mêmes échantillons |
iq_info, iq_inventory |
(path, hash=False) -> dict, (directory, recursive=False, hash=False) -> list |
décrire un enregistrement, ou chaque enregistrement d'un dossier (lit les fichiers ; hash les lit en entier) |
bench_export |
(toml, epoch=None) -> dict |
le mouvement du véhicule et les événements d'un scénario pour un simulateur GNSS de laboratoire, en mémoire : {files: {suffix: text}, notes, notice} ; types de scénario gnss-ins, jamming, gnss-sim ; aucun signal n'est écrit, gardez notice avec les fichiers |
compliance_report |
(runs) -> dict |
le rapprochement avec les cadres publics rempli à partir de textes de résultats : runs est une liste de dictionnaires {label, result, scenario?} (texte, au plus 64) ; renvoie {report, markdown} ; le status de chaque ligne indique que les exécutions apportent des éléments de preuve en faveur de ses capacités, non qu'un cadre est atteint ; conservez report["statement"] avec tout affichage |
compliance_mapping |
(sources=False) -> str |
les tables de rapprochement statiques (ou les documents sources) en Markdown, ouvertes par la déclaration |
standards_pack_list |
() -> dict |
les paquets de normes (identifiant, titre, cadre, nombre de tests) et un avis ; un paquet mesure des scénarios modélisés par rapport à des seuils énoncés avant l'exécution |
standards_pack_run |
(pack_id) -> dict |
une exécution de paquet : chaque test MET, NOT MET ou NEEDS INPUT avec les valeurs mesurées et attendues, plus le rapport en Markdown sous markdown ; lève ValueError pour un identifiant inconnu |
lunanet_afs_check_spec |
() -> dict |
l'implémentation LunaNet AFS vérifiée par rapport aux tables imprimées et aux exemples résolus de LSIS-AFS V1.0 (seuils B1 à B10 ; B4 rapporte un échec consigné) |
lunanet_afs_check_symbols |
(symbols, max_sp_errors=0) -> dict |
un flux de symboles AFS (texte de 0 et de 1) contrôlé pour le motif de synchronisation, le décodage SB1, le FID, la continuité et l'espacement du TOI ; le LDPC et le CRC-24Q des sous-trames 2 à 4 ne sont pas vérifiés |
lunanet_afs_generate |
(frames=1, toi0=0) -> str |
un flux de symboles d'essai avec des sous-trames fictives (pas une forme d'onde) |
evidence_round_trip |
(scoring_toml, scenario_toml, conditions, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
le paquet signé d'aller-retour de laboratoire reliant par hachage le scénario, les conditions d'essai (docs/spec/TEST-CONDITIONS.md), le journal du récepteur et le score ; sous la forme evidence_create |
bench_score |
(truth_json, predictions_json, threshold=None) -> str |
un fichier de résultat kshana-bench (texte JSON) à partir d'un fichier de vérité et d'un fichier de prédictions ; MODELLED |
bench_leaderboard |
(results: list[str]) -> str |
des fichiers de résultat kshana-bench rendus sous forme de page de classement statique (HTML) |
osnma_verify |
(data, format="", start_gst=None, merkle_root_hex="", public_keys=None, reference_time=None, max_time_error=None) -> dict |
authentification OSNMA de Galileo de pages I/NAV ou d'un flux UBX en mémoire : le dictionnaire que kshana osnma verify --json affiche, avec la mention à titre consultatif dans son champ advisory ; à titre consultatif seulement, pas un service d'intégrité de la navigation |
sky_geometry |
(request) -> dict |
les satellites qu'un site voit sous un horizon dépendant de l'azimut : par satellite visible / masked, GDOP, PDOP, HDOP, VDOP, TDOP, le cofacteur et la covariance est-nord-haut et les ellipses d'erreur horizontale ; request est un texte JSON ou TOML ou un dictionnaire (site, time_s, systems, tle, satellites, mask_deg, skyline, clock, sigma_uere_m, confidence) ; la décision de visibilité et l'ellipse sont vérifiées par rapport à des bibliothèques indépendantes, le reste est MODELLED, et le résultat porte la mention à titre consultatif (sky_source, sky_statement disent si le ciel est représentatif ou issu de jeux d'éléments) |
sky_monte_carlo |
(request, seed=0, n=1000) -> dict |
n (1 à 5000) erreurs de moindres carrés à graine fixée sur l'ensemble visible de request, avec leur covariance empirique, leur RMS et la fraction à l'intérieur de l'ellipse à 95 % |
skyline_presets |
() -> list[dict] |
les préréglages d'horizon (city-street, harbour-approach, fjord, container-terminal) avec leur étiquette REPRESENTATIVE, leur provenance et la coupure à chaque degré d'azimut ; des géométries représentatives, non des relevés |
skyline_profile |
(skyline) -> dict |
une section d'horizon (table, canyon urbain, secteurs, terrain) ramenée à la table normalisée de 360 entrées qu'utilise le moteur |
skyplot_svg |
(request) -> str |
le diagramme du ciel de request sous forme de texte SVG statique |
trust_telemetry |
(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0) -> str |
un flux de confiance (jsonl) ou un résultat receiver-trust sous forme de texte Prometheus, de lignes syslog CEF ou LEEF ou de charge utile JSON OTLP, avec les encodeurs kshana trust-telemetry ; rien n'est envoyé et aucune horloge n'est lue (les lignes syslog ne portent pas d'horodatage) |
interference_map |
(source, csv, dataset, cell_deg=None, licence=None, licence_url=None, attribution=None, land_geojson=None) -> list[dict] |
une carte d'interférences GNSS à partir de texte CSV ADS-B ou AIS : un dictionnaire par jour UTC avec du GeoJSON kshana-interference-map/v1 (agrégat uniquement ; une cellule dégradée ne désigne pas l'interférence comme cause) |
interference_emitter_regions |
(source, csv, dataset, licence=None, licence_url=None, attribution=None, land_geojson=None) -> dict |
régions d'émetteurs estimées à partir de texte CSV ADS-B ou AIS : {stem, geojson, summary, csv, svg, sessions_published, sessions_withheld}, chacune étiquetée MODELLED ; des régions à un niveau de confiance déclaré avec un centroïde et une ellipse d'incertitude, jamais un simple point ; agrégat seulement, et une région n'est la position de personne ni un constat de la cause |
route_exposure |
(route, maps, date_from=None, date_to=None) -> str |
part d'un itinéraire traversant des cellules dégradées de ces cartes, en texte JSON (pas une prévision ; des cellules non observées ne prouvent pas qu'un itinéraire est dégagé) |
nmea_training |
(toml, seed=None) -> dict |
NMEA de passerelle synthétiques pour la formation des équipages plus le journal de l'instructeur (nmea, log_json, log_text) ; texte seulement, jamais pour les systèmes de navigation réels d'un navire |
iq_signals |
() -> list[str] |
les noms de signaux IQ GNSS qu'acceptent iq_scene, iq_acquire et iq_track (gps-l1ca, galileo-e1b, glonass-l1of, ...) |
iq_scene |
(fs_hz, duration_s, signal, prns, **options) -> dict |
une scène IQ GNSS multi-satellites en mémoire : samples_i / samples_q et truth par époque |
iq_scene_broadcast |
(fs_hz, window_s, nav_text, rx_lat, rx_lon, rx_alt, **options) -> dict |
la même, avec chaque satellite GPS selon sa géométrie d'éphéméride diffusée tirée d'un message de navigation RINEX (Receiver Independent Exchange Format) |
iq_acquire |
(i, q, fs_hz, signal, prns, **options) -> list[dict] |
acquisition par FFT (transformée de Fourier rapide) de chaque PRN (code pseudo-aléatoire) : Doppler, phase de code, statistique, seuil |
iq_acq_surface |
(i, q, fs_hz, signal, prn, **options) -> dict |
toute la surface d'acquisition d'un PRN (kshana.acq-surface/1) : puissance de corrélation rows[doppler][lag], le pic et deux affinements fins du Doppler (parabolic, fine_search) |
iq_track |
(i, q, fs_hz, signal, prns, **options) -> dict |
acquérir, puis suivre chaque PRN : Doppler par époque, phase de code, indicateurs de verrouillage, C/N0, corrélateur ponctuel |
iq_frontend |
(i, q, fs_hz, **options) -> dict |
la chaîne frontale du récepteur (passe-bande, réjecteur, blanking, excision, AGC (commande automatique de gain), quantificateur) sur des échantillons complexes |
iq_labfit |
(toml: str) -> dict |
ajuster le modèle de perte de verrouillage de la boucle de poursuite à une chronologie de confiance du récepteur (un scénario iq-labfit) |
iq_loop_designs |
(toml) -> list[dict] |
analyser un fichier kshana.loop-design/1 (un chemin ou du texte TOML) en ses conceptions résolues, chacune avec son name et son hash ; ValueError sur un fichier invalide |
iq_read_epochs |
(path) -> dict |
lire un fichier binaire d'époques de poursuite (kshana.track-epoch/1, tel que l'écrit kshana iq track --epochs) : le header et un dictionnaire par époque dans records |
iq_monitor |
(path, signal=None, prns=None, power=False, spectral=False, settings=None, ...) -> dict |
les moniteurs de détection IQ sur un enregistrement en un seul passage en flux (iq monitor) : series, events, spectra et notes ; lit un fichier |
iq_test_conditions |
(conditions) -> dict |
valider un fichier de conditions d'essai de laboratoire (kshana.test-conditions/1, TOML ou JSON, un chemin ou du texte) et le renvoyer résolu, avec son hash |
iq_campaign |
(campaign, out_dir, workers=0, resume=True, max_cells=None, dry_run=False) -> dict |
exécuter une campagne de rejeu de laboratoire (kshana.campaign/1) dans out_dir comme le fait kshana iq campaign ; les cellules terminées sont ignorées ; renvoie le nombre de cellules, les échecs et le digest une fois toutes les cellules terminées |
iq_campaign_report |
(out_dir) -> dict |
reconstruire les fiches de score, le rapport HTML et le condensé d'une campagne à partir de ses cellules : le nombre de cellules et de lignes, les lignes qui échouent à un seuil et le digest |
Signatures de l'IQ GNSS et de la confiance du récepteur#
Les signatures complètes, telles que kshana.pyi les énonce (chaque mot-clé après les arguments obligatoires a une valeur par défaut ; les docstrings du stub donnent le sens de chacun). Encapsulez les listes samples_i / samples_q et les entrées i / q avec numpy.asarray(...) pour obtenir des tableaux.
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]: ...
Une campagne de rejeu de laboratoire depuis Python, puis son rapport (le fichier de campagne et ses enregistrements sont les vôtres ; une cellule terminée est ignorée à l'appel suivant ; iq_read_epochs lit un fichier d'époques de poursuite écrit par une exécution de 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
Le acq_coherent de iq_track fixe le nombre de périodes de code que l'acquisition de transfert intègre de façon cohérente. À partir de 0.33.0, il vaut par défaut None, ce qui signifie automatique : environ 4 ms (4 périodes pour un code de 1 ms comme le GPS L1 C/A, 1 pour un code de 4 ms ou plus), de sorte que le canal démarre assez près pour que la boucle de fréquence s'accroche ; acq_coherent=1 conserve la recherche à une période de 0,32.
Types#
kshana.pyi type les vocabulaires fermés pour les vérificateurs (mypy, pyright) : ScenarioKind (chaque nom de type de scénario, un Literal), ErrorKind (les quatre étiquettes que renvoie error_kind), ProvenanceClass, et les TypedDict KindMeta (dont scenario_kinds() renvoie une liste) et FieldUnit (une entrée du bloc units d'un résultat, qui étend la base de clés obligatoires _FieldUnitBase). Ils n'existent que pour les vérificateurs de types et ne sont pas importables à l'exécution ; tests/typed_api_sync.rs les maintient égaux aux listes du moteur.
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#
| Membre | Type | Notes |
|---|---|---|
.json |
str |
document de résultat complet (JSON) |
.svg |
str |
SVG (Scalable Vector Graphics) autonome du graphique |
.summary |
str |
résumé lisible d'une ligne |
.csv |
str | None |
la table de reproductibilité, pour les types de scénario qui en émettent une (voir ci-dessous) |
.data() |
dict |
le résultat analysé en dictionnaire Python (voir la note sur la forme ci-dessous) |
.array(path) |
numpy.ndarray |
la liste numérique à path (pointée, "points.0.coords", ou pointeur JSON, "/points/0/coords") : 1D pour des nombres, 2D pour des listes numériques de même longueur |
.columns(path) |
dict[str, numpy.ndarray] |
la liste d'enregistrements à path (une série temporelle), un tableau par champ qui est un nombre dans chaque enregistrement |
.series() |
dict[str, dict[str, numpy.ndarray]] |
chaque liste d'enregistrements avec un champ numérique, indexée par chemin pointé, chacune sous la forme .columns |
.write_csv(path) |
int |
écrire cette table dans path ; renvoie le nombre d'octets écrits, ou 0 (et n'écrit rien) lorsque le type de scénario n'émet aucune table |
La table de reproductibilité#
realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing et leo-navmsg publient toujours une table ; moonlight-service-volume en publie une lorsqu'un site d'export (export_site_lat_deg + export_site_lon_deg) est configuré. Tout autre type de scénario renvoie csv = None. Le texte est constitué des mêmes octets que ceux que la CLI (interface en ligne de commande) écrit sous <scenario>.table.csv, de sorte qu'un relecteur qui reproduit une table publiée à partir du wheel n'a jamais à passer à la ligne de commande :
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")
Forme du résultat#
Les indicateurs de performance et les séries temporelles se trouvent par côté d'exécution, et non au niveau supérieur. Pour une exécution d'horloge, le document est :
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
de sorte que les indicateurs de performance sont data["quantum"]["fom"], jamais data["figures_of_merit"]. D'autres types de scénario émettent leurs propres paquets ; la référence complète champ par champ, avec unités et pointeur vers la source, est field-units-schema.json et le guide du lecteur est SCHEMA.md.
Notes#
validate_tomleterror_kindexécutent le scénario, de sorte qu'ils font remonter les erreurs d'analyse, de configuration et d'exécution. Ils ne lèvent jamais d'exception.run/run_typedlèventValueErrorsur un scénario invalide.- Les résultats sont reproductibles : un scénario porte sa
seedet le moteur enregistre unscenario_hash, de sorte que la même entrée donne une sortie identique octet pour octet sur la même plateforme (voirREPRODUCIBILITY.md). .array,.columnset.seriesrenvoient exactementnumpy.asarray(...)des mêmes valeurs que donne.data()(même dtype, identiques au bit près ;tests/python/test_numpy_runoutput.py). Ils importent NumPy lorsqu'on les appelle et lèventImportErrorsans lui ; NumPy reste en dehors des dépendances d'exécution du paquet.KeyErrorsignifie que le chemin est absent,ValueErrorque la valeur qui s'y trouve n'est pas un tableau numérique (ou pas une liste d'enregistrements). Des notebooks exécutables se trouvent dansnotebooks/.
Pas en Python : les processus de longue durée#
kshana receiver-trust live (un processus de flux avec une passerelle et un serveur TCP --listen facultatif) et les exportateurs de télémétrie (Prometheus, OTLP, syslog ; docs/TRUST-TELEMETRY.md) et le flux kshana nmea-scenario --tcp/--udp relèvent uniquement de la ligne de commande : une liaison rend la main quand l'appel se termine et ne garde pas de socket ouvert. Python couvre la forme par lot de chacun : receiver_trust pour un journal, receiver_trust_replay pour un extrait de flux (scores et états ; la passerelle n'est pas appliquée), nmea_training pour le texte généré.