API Python
O Kshana distribui uma interface de programação de aplicações (API) Python de primeira classe, construída com PyO3 e maturin. As suas wheels abi3 são compiladas face à interface binária de aplicações (ABI) estável do Python, pelo que uma wheel por plataforma funciona em CPython ≥ 3,9; as wheels abrangem Linux, macOS e Windows, cada um em x86-64 e ARM de 64 bits (consulte WHEEL_TAGS.md). Um stub de tipos incluído (kshana.pyi + py.typed) dá aos editores e a mypy/pyright informação de tipos completa.
pip install kshana # from the Python Package Index, PyPI (release wheels)
# or, from a checkout:
pip install maturin && maturin develop --features python
Início rápido#
Execute estes excertos a partir da raiz de uma cópia de trabalho do repositório: leem ficheiros de cenário em scenarios/. A linha do NumPy precisa de 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
Superfície#
| Símbolo | Assinatura | Devolve |
|---|---|---|
run_typed |
(toml: str) -> RunOutput |
resultado tipado (.json, .svg, .summary, .csv, .data(), .array(), .columns(), .series(), .write_csv()) |
run |
(toml: str) -> str |
documento de resultado como cadeia JSON (JavaScript Object Notation) |
run_full |
(toml: str) -> tuple[str, str, str] |
(json, svg, summary) |
scenario_kinds |
() -> list[dict] |
tipos de cenário disponíveis + metadados (analisados) |
list_kinds |
() -> str |
os mesmos metadados como UMA cadeia de lista JSON, não uma lista (mantido para chamadores existentes; use scenario_kinds para a lista analisada) |
validate_toml |
(toml: str) -> list[str] |
mensagens de erro (vazio se válido) |
error_kind |
(toml: str) -> str | None |
etiqueta de categoria de falha (invalid_input, non_convergence, unsupported ou io_error), ou None em caso de êxito |
version / __version__ |
() -> str / str |
versão do motor |
receiver_trust |
(toml: str) -> RunOutput |
avaliar um registo real de recetor descrito por um cenário receiver-trust: documento de resultado, CSV de confiança por época, gráfico e resumo; uma tabela [platform] kind = "vessel" acrescenta os monitores marítimos e a pontuação de confiança de 0-100 com motivos (consultivo) |
receiver_trust_replay |
(session_toml, nmea) -> dict |
um excerto NMEA limitado pontuado da forma como o modo em tempo real pontua: estado por época, pontuação de 0-100 e motivos, um resumo (sem socket, sem barreira; consultivo) |
assess_vessel_log |
(session_toml, log) -> dict |
o registo NMEA de uma embarcação como execução em lote: o modelo de pontuação e a pontuação de cada época com as suas deduções (consultivo) |
jammertest_import |
(catalog_json, plans, log_start_utc, location=None, local_offset_h=2.0, year=None) -> dict |
o catálogo e o plano publicados do Jammertest como eventos de referência agendados (events_toml, events); janelas planeadas, não horas de emissão registadas |
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 |
um registo de recetor pontuado face a esse calendário: latência por teste, falhas, tempo de recuperação, falsos alarmes (MODELLED; um pacote assinado precisa da linha de comandos) |
evidence_create |
(session_toml, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
um pacote de evidências assinado para uma janela do registo, em memória: files, public_key, seed_hex (mantenha-o privado); um registo técnico, não um parecer jurídico |
evidence_verify |
(files, public_key=None, full_log=None, require_timestamp=False) -> dict |
verificar um pacote: hashes, cadeia, assinatura, opcionalmente o signatário de confiança, o registo completo e uma marca temporal; verdict é verified, intact-signer-not-pinned (sem chave pública indicada: íntegro, signatário não estabelecido) ou failed |
export_sp3, export_omm, export_oem |
(toml) -> str |
os artefactos --export-sp3/-omm/-oem da CLI como texto |
export_formats |
(toml) -> list[dict] |
que formatos de interoperabilidade se aplicam a um cenário, sem o executar |
export_scenario |
(toml, format) -> dict |
czml, kml, geojson, stk ou sigmf em memória: {format, spec_url, files}, cada ficheiro {suffix, bytes, sha256, encoding, content} (texto utf-8 ou base64) |
import_route |
(toml, geojson) -> str |
uma rota GeoJSON escrita num cenário de trajeto de pontos de passagem (--import-route) |
animate_scenario |
(toml, format="svg", fps=None, duration_s=None, width=None) -> dict |
a série temporal da execução como SVG animado, um leitor HTML ou até 120 imagens SVG: {summary, files} |
list_examples, get_example |
(kind=None) -> dict, (name) -> str |
os cenários de referência incluídos e o respetivo TOML |
evidence_attach_timestamp |
(files, token, replace=False) -> dict |
associar um token RFC 3161 (bytes ou base64) a um pacote em memória: {files, notes}; o pacote tem de continuar a verificar-se; a assinatura da autoridade não é verificada |
evidence_keygen |
() -> dict |
uma nova chave de assinatura em memória: seed_hex (PRIVADA), public_key, fingerprint, warning; apenas em Python |
iq_sweep |
(i, q, fs_hz, signal, prns, ..., pll_bws=None, dll_bws=None, spacings=None, coherents=None, design=None) -> dict |
reproduzir uma gravação com vários projetos de malhas (iq sweep): por projeto e PRN, jitter em regime estacionário, frações de bloqueio e C/N0; uma aquisição por PRN, todos os canais sobre as mesmas amostras |
iq_info, iq_inventory |
(path, hash=False) -> dict, (directory, recursive=False, hash=False) -> list |
descrever uma gravação, ou todas as gravações de uma pasta (lê ficheiros; hash lê-os por inteiro) |
bench_export |
(toml, epoch=None) -> dict |
o movimento do veículo e os eventos de um cenário para um simulador GNSS de laboratório, em memória: {files: {suffix: text}, notes, notice}; tipos gnss-ins, jamming, gnss-sim; nenhum sinal é escrito, mantenha notice junto com os ficheiros |
compliance_report |
(runs) -> dict |
o mapeamento do quadro público preenchido a partir de textos de resultados: runs é uma lista de dicts {label, result, scenario?} (texto, no máximo 64); devolve {report, markdown}; o status de cada linha diz que as execuções fornecem elementos de prova em apoio das suas capacidades, não que um quadro seja satisfeito; leve report["statement"] consigo em qualquer apresentação |
compliance_mapping |
(sources=False) -> str |
as tabelas de mapeamento estáticas (ou os documentos de origem) em Markdown, encabeçadas pela declaração |
standards_pack_list |
() -> dict |
os pacotes de normas (id, título, quadro, contagens de testes) e um aviso; um pacote mede cenários modelados face a limiares indicados antes da execução |
standards_pack_run |
(pack_id) -> dict |
uma execução de pacote: cada teste MET, NOT MET ou NEEDS INPUT com valores medidos e esperados, mais o relatório em Markdown em markdown; gera ValueError para um id desconhecido |
lunanet_afs_check_spec |
() -> dict |
a implementação LunaNet AFS verificada face às tabelas impressas e aos exemplos resolvidos da LSIS-AFS V1.0 (limiares B1 a B10; B4 comunica uma falha fixada) |
lunanet_afs_check_symbols |
(symbols, max_sp_errors=0) -> dict |
um fluxo de símbolos AFS (texto de 0 e 1) verificado quanto a padrão de sincronização, descodificação de SB1, FID, continuidade e espaçamento de TOI; o LDPC e o CRC-24Q das subtramas 2 a 4 não são verificados |
lunanet_afs_generate |
(frames=1, toi0=0) -> str |
um fluxo de símbolos de teste com subtramas provisórias (não é uma forma de onda) |
evidence_round_trip |
(scoring_toml, scenario_toml, conditions, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
o pacote assinado do circuito de laboratório que liga por hash o cenário, as condições de ensaio (docs/spec/TEST-CONDITIONS.md), o registo do recetor e a pontuação; como evidence_create |
bench_score |
(truth_json, predictions_json, threshold=None) -> str |
um ficheiro de resultados kshana-bench (texto JSON) a partir de um ficheiro de referência e de um ficheiro de previsões; MODELLED |
bench_leaderboard |
(results: list[str]) -> str |
ficheiros de resultados kshana-bench renderizados como a página estática de classificação (HTML) |
osnma_verify |
(data, format="", start_gst=None, merkle_root_hex="", public_keys=None, reference_time=None, max_time_error=None) -> dict |
autenticação Galileo OSNMA de páginas I/NAV ou de um fluxo UBX em memória: o dict que kshana osnma verify --json imprime, com o aviso consultivo no seu campo advisory; apenas consultivo, não é um serviço de integridade de navegação |
sky_geometry |
(request) -> dict |
os satélites que um local vê sob um horizonte dependente do azimute: por satélite visible / masked, GDOP, PDOP, HDOP, VDOP, TDOP, o cofator e a covariância este-norte-cima e as elipses de erro horizontal; request é texto JSON ou TOML ou um dict (site, time_s, systems, tle, satellites, mask_deg, skyline, clock, sigma_uere_m, confidence); a decisão de visibilidade e a elipse são verificadas face a bibliotecas independentes, o resto é MODELLED, e o resultado traz o aviso consultivo (sky_source, sky_statement dizem se o céu é representativo ou proveniente de conjuntos de elementos) |
sky_monte_carlo |
(request, seed=0, n=1000) -> dict |
n (1 a 5000) erros de mínimos quadrados com semente sobre o conjunto visível de request, com a sua covariância empírica, o RMS e a fração dentro da elipse de 95 % |
skyline_presets |
() -> list[dict] |
as predefinições de horizonte (city-street, harbour-approach, fjord, container-terminal) com o seu rótulo REPRESENTATIVE, a proveniência e o corte a cada grau de azimute; geometrias representativas, não levantamentos |
skyline_profile |
(skyline) -> dict |
uma secção de horizonte (tabela, canyon de rua, setores, terreno) reduzida à tabela normalizada de 360 entradas que o motor usa |
skyplot_svg |
(request) -> str |
o skyplot de request como texto SVG estático |
trust_telemetry |
(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0) -> str |
um fluxo de confiança (jsonl) ou um resultado de receiver-trust como texto Prometheus, linhas de syslog CEF ou LEEF ou uma carga JSON OTLP, com os codificadores de kshana trust-telemetry; nada é enviado e nenhum relógio é lido (as linhas de syslog não trazem marca temporal) |
interference_map |
(source, csv, dataset, cell_deg=None, licence=None, licence_url=None, attribution=None, land_geojson=None) -> list[dict] |
um mapa de interferência GNSS a partir de texto CSV de ADS-B ou AIS: um dict por dia UTC com GeoJSON kshana-interference-map/v1 (apenas agregado; uma célula degradada não nomeia a interferência como causa) |
interference_emitter_regions |
(source, csv, dataset, licence=None, licence_url=None, attribution=None, land_geojson=None) -> dict |
regiões estimadas de emissores a partir de texto CSV de ADS-B ou AIS: {stem, geojson, summary, csv, svg, sessions_published, sessions_withheld}, cada uma etiquetada MODELLED; regiões com confiança declarada com um centroide e uma elipse de incerteza, nunca um ponto isolado; apenas agregados, e uma região não é a posição de ninguém nem uma constatação da causa |
route_exposure |
(route, maps, date_from=None, date_to=None) -> str |
a proporção de uma rota através de células degradadas desses mapas, como texto JSON (não é uma previsão; as células não observadas não são prova de uma rota livre) |
nmea_training |
(toml, seed=None) -> dict |
NMEA sintético de ponte para formação de tripulações mais o registo do instrutor (nmea, log_json, log_text); apenas texto, nunca para os sistemas de navegação em tempo real de uma embarcação |
iq_signals |
() -> list[str] |
os nomes de sinais IQ GNSS que iq_scene, iq_acquire e iq_track aceitam (gps-l1ca, galileo-e1b, glonass-l1of, ...) |
iq_scene |
(fs_hz, duration_s, signal, prns, **options) -> dict |
uma cena IQ GNSS multissatélite em memória: samples_i / samples_q e truth por época |
iq_scene_broadcast |
(fs_hz, window_s, nav_text, rx_lat, rx_lon, rx_alt, **options) -> dict |
o mesmo, com cada satélite GPS na sua geometria de efemérides difundidas a partir de uma mensagem de navegação RINEX (Receiver Independent Exchange Format) |
iq_acquire |
(i, q, fs_hz, signal, prns, **options) -> list[dict] |
aquisição por FFT (fast Fourier transform) de cada PRN (código de ruído pseudoaleatório): Doppler, fase do código, estatística, limiar |
iq_acq_surface |
(i, q, fs_hz, signal, prn, **options) -> dict |
toda a superfície de aquisição de um PRN (kshana.acq-surface/1): potência de correlação rows[doppler][lag], o pico e dois refinamentos de Doppler fino (parabolic, fine_search) |
iq_track |
(i, q, fs_hz, signal, prns, **options) -> dict |
adquirir e depois seguir cada PRN: Doppler por época, fase do código, indicadores de bloqueio, C/N0, correlador prompt |
iq_frontend |
(i, q, fs_hz, **options) -> dict |
a cadeia de front-end do recetor (passa-banda, notch, blanking, excisão, AGC (controlo automático de ganho), quantizador) sobre amostras complexas |
iq_labfit |
(toml: str) -> dict |
ajustar o modelo de perda de bloqueio das malhas de seguimento a uma cronologia de confiança do recetor (um cenário iq-labfit) |
iq_loop_designs |
(toml) -> list[dict] |
analisar um ficheiro kshana.loop-design/1 (um caminho ou texto TOML) nos seus projetos resolvidos, cada um com o seu name e hash; ValueError num ficheiro inválido |
iq_read_epochs |
(path) -> dict |
ler um ficheiro binário de épocas de seguimento (kshana.track-epoch/1, tal como kshana iq track --epochs o escreve): o header e um dict por época em records |
iq_monitor |
(path, signal=None, prns=None, power=False, spectral=False, settings=None, ...) -> dict |
os monitores de deteção IQ sobre uma gravação numa única passagem em contínuo (iq monitor): series, events, spectra e notes; lê um ficheiro |
iq_test_conditions |
(conditions) -> dict |
validar um ficheiro de condições de ensaio de laboratório (kshana.test-conditions/1, TOML ou JSON, um caminho ou texto) e devolvê-lo resolvido, com o seu hash |
iq_campaign |
(campaign, out_dir, workers=0, resume=True, max_cells=None, dry_run=False) -> dict |
executar uma campanha de reprodução em laboratório (kshana.campaign/1) para out_dir tal como kshana iq campaign faz; as células concluídas são ignoradas; devolve as contagens de células, as falhas e o digest quando todas as células estão concluídas |
iq_campaign_report |
(out_dir) -> dict |
reconstruir os quadros de pontuação, o relatório HTML e o resumo de uma campanha a partir das suas células: as contagens de células e de linhas, as linhas que falham um limiar e o digest |
Assinaturas de IQ GNSS e de confiança do recetor#
As assinaturas completas, tal como kshana.pyi as indica (cada argumento nomeado após os argumentos obrigatórios tem um valor predefinido; as docstrings no stub dão o significado de cada um). Envolva as listas samples_i / samples_q, e as entradas i / q, com numpy.asarray(...) para obter arrays.
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]: ...
Uma campanha de reprodução em laboratório a partir de Python e depois o seu relatório (o ficheiro da campanha e as suas gravações são seus; uma célula concluída é ignorada na chamada seguinte; iq_read_epochs lê um ficheiro de épocas de seguimento que uma execução de kshana iq track --epochs escreveu):
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 de iq_track define quantos períodos de código a aquisição de transição integra de forma coerente. A partir da 0.33.0 tem por predefinição None, o que significa automático: cerca de 4 ms (4 períodos para um código de 1 ms como o GPS L1 C/A, 1 para um código de 4 ms ou mais longo), para que o canal comece suficientemente perto para a malha de frequência o puxar para a captura; acq_coherent=1 mantém a pesquisa de um período da 0,32.
Tipos#
kshana.pyi tipa os vocabulários fechados para os verificadores (mypy, pyright): ScenarioKind (cada nome de tipo de cenário, um Literal), ErrorKind (as quatro etiquetas que error_kind devolve), ProvenanceClass, e os TypedDict KindMeta (de que scenario_kinds() devolve uma lista) e FieldUnit (uma entrada do bloco units de um resultado, que estende a base de chaves obrigatórias _FieldUnitBase). Existem apenas para verificadores de tipos e não são importáveis em tempo de execução; tests/typed_api_sync.rs mantém-nos iguais às listas do motor.
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#
| Membro | Tipo | Notas |
|---|---|---|
.json |
str |
documento de resultado completo (JSON) |
.svg |
str |
SVG (Scalable Vector Graphics) autónomo do gráfico |
.summary |
str |
resumo humano de uma linha |
.csv |
str | None |
a tabela de reprodutibilidade, para os tipos que a emitem (consulte abaixo) |
.data() |
dict |
o resultado analisado para um dict de Python (consulte a nota sobre a forma abaixo) |
.array(path) |
numpy.ndarray |
a lista numérica em path (com pontos, "points.0.coords", ou um JSON Pointer, "/points/0/coords"): 1-D para números, 2-D para listas numéricas de igual comprimento |
.columns(path) |
dict[str, numpy.ndarray] |
a lista de registos em path (uma série temporal), um array por cada campo que é um número em todos os registos |
.series() |
dict[str, dict[str, numpy.ndarray]] |
cada lista de registos com um campo numérico, indexada por caminho com pontos, cada uma como .columns |
.write_csv(path) |
int |
escrever essa tabela em path; devolve os bytes escritos, ou 0 (e não escreve nada) quando o tipo não emite nenhuma tabela |
A tabela de reprodutibilidade#
realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing e leo-navmsg publicam sempre uma tabela; moonlight-service-volume publica uma quando está configurado um local de exportação (export_site_lat_deg + export_site_lon_deg). Todos os outros tipos devolvem csv = None. O texto é composto pelos mesmos bytes que a CLI (command-line interface) escreve como <scenario>.table.csv, pelo que um revisor que reproduza uma tabela publicada a partir da wheel nunca precisa de recorrer à linha de comandos:
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")
Forma do resultado#
As figuras de mérito e a série temporal ficam por lado da execução, não ao nível superior. Para uma execução de relógio, o documento é:
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
pelo que as figuras de mérito estão em data["quantum"]["fom"], nunca em data["figures_of_merit"]. Os outros tipos emitem os seus próprios pacotes; a referência completa por campo, com unidades e uma indicação da origem, é field-units-schema.json e o guia do leitor é SCHEMA.md.
Notas#
validate_tomleerror_kindexecutam o cenário, pelo que revelam erros de análise, de configuração e de execução. Nunca geram exceções.run/run_typedgeramValueErrorperante um cenário inválido.- Os resultados são reprodutíveis: um cenário traz a sua
seede o motor regista umscenario_hash, pelo que a mesma entrada produz uma saída idêntica ao byte na mesma plataforma (consulteREPRODUCIBILITY.md). .array,.columnse.seriesdevolvem exatamentenumpy.asarray(...)dos mesmos valores que.data()dá (mesmo dtype, idênticos bit a bit;tests/python/test_numpy_runoutput.py). Importam o NumPy quando chamados e geramImportErrorsem ele; o NumPy fica fora dos requisitos de execução do pacote.KeyErrorsignifica que o caminho não existe,ValueErrorque o valor aí não é um array numérico (ou não é uma lista de registos). Há notebooks executáveis emnotebooks/.
Não existe em Python: processos de longa duração#
kshana receiver-trust live (um processo de fluxo com uma barreira e um servidor TCP --listen opcional) e os exportadores de telemetria (Prometheus, OTLP, syslog; docs/TRUST-TELEMETRY.md) e o fluxo de kshana nmea-scenario --tcp/--udp existem apenas na linha de comandos: uma ligação devolve quando a chamada devolve e não mantém um socket aberto. O Python cobre a forma em lote de cada um: receiver_trust para um registo, receiver_trust_replay para um excerto de fluxo (pontuações e estados; a barreira não é aplicada), nmea_training para o texto gerado.