Tradução automática, não revista por um falante nativo. O inglês é a referência.

APIs e integraçõesEditar no GitHubFonte: docs/PYTHON_API.md

API Python

O Kshana distribui uma interface de programação de aplicações (API) Python de primeira classe, construída com PyO3 e maturin. Suas wheels abi3 são compiladas contra a interface binária de aplicação (ABI) estável do Python, de modo que uma wheel por plataforma funciona em todo CPython ≥ 3,9; as wheels cobrem 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á a editores e a mypy/pyright informações de tipo completas.

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 trechos a partir da raiz de um checkout do repositório: eles leem arquivos 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 Retorna
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 uma string 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 string de matriz JSON, não uma lista (mantida 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 sucesso
version / __version__ () -> str / str versão do motor
receiver_trust (toml: str) -> RunOutput avaliar um registro real de receptor 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 a 100 com os motivos (consultivo)
receiver_trust_replay (session_toml, nmea) -> dict um trecho limitado de NMEA pontuado do modo como o modo ao vivo o pontua: estado por época, pontuação de 0 a 100 e motivos, um resumo (sem socket, sem gate; consultivo)
assess_vessel_log (session_toml, log) -> dict o registro NMEA de uma embarcação como execução em lote: o modelo de pontuação e a pontuação de cada época com 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 verdade agendada (events_toml, events); slots planejados, não horários de transmissão registrados
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 registro de receptor pontuado em relação a esse cronograma: latência por teste, perdidos, tempo de recuperação, falsos alarmes (MODELLED; um pacote assinado exige a linha de comando)
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 registro, em memória: files, public_key, seed_hex (mantenha-a privada); um registro 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 confiável, o registro completo e um carimbo de tempo; verdict é verified, intact-signer-not-pinned (sem chave pública informada: íntegro, signatário não estabelecido) ou failed
export_sp3, export_omm, export_oem (toml) -> str os artefatos --export-sp3/-omm/-oem da CLI como texto
export_formats (toml) -> list[dict] quais formatos de interoperabilidade se aplicam a um cenário, sem executá-lo
export_scenario (toml, format) -> dict czml, kml, geojson, stk ou sigmf em memória: {format, spec_url, files}, cada arquivo {suffix, bytes, sha256, encoding, content} (texto utf-8 ou base64)
import_route (toml, geojson) -> str uma rota GeoJSON gravada em um cenário de trilha 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 um SVG animado, um player HTML ou até 120 quadros SVG: {summary, files}
list_examples, get_example (kind=None) -> dict, (name) -> str os cenários de referência incluídos e seu TOML
evidence_attach_timestamp (files, token, replace=False) -> dict vincular um token RFC 3161 (bytes ou base64) a um pacote em memória: {files, notes}; o pacote ainda precisa ser verificado; a assinatura da autoridade não é conferida
evidence_keygen () -> dict uma nova chave de assinatura em memória: seed_hex (PRIVADA), public_key, fingerprint, warning; somente 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 em vários projetos de malha (iq sweep): por projeto e PRN, jitter em regime permanente, frações de travamento 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ê arquivos; hash os lê por completo)
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 de cenário gnss-ins, jamming, gnss-sim; nenhum sinal é gravado, mantenha notice junto com os arquivos
compliance_report (runs) -> dict o mapeamento do referencial público preenchido a partir de textos de resultado: runs é uma lista de dicts {label, result, scenario?} (texto, no máximo 64); retorna {report, markdown}; o status de cada linha diz que as execuções fornecem evidências em apoio de suas capacidades, não que um referencial seja atendido; leve report["statement"] junto com qualquer exibição
compliance_mapping (sources=False) -> str as tabelas estáticas de mapeamento (ou os documentos de origem) em Markdown, iniciadas pela declaração
standards_pack_list () -> dict os pacotes de normas (id, título, referencial, contagens de testes) e um aviso; um pacote mede cenários modelados em relação a limiares declarados 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; levanta ValueError para um id desconhecido
lunanet_afs_check_spec () -> dict a implementação do AFS do LunaNet conferida com as tabelas impressas e os exemplos práticos do LSIS-AFS V1.0 (limiares B1 a B10; B4 relata uma falha fixada)
lunanet_afs_check_symbols (symbols, max_sp_errors=0) -> dict um fluxo de símbolos AFS (texto de 0 e 1) conferido quanto a padrão de sincronismo, decodificação de SB1, FID, continuidade e espaçamento de TOI; o LDPC e o CRC-24Q dos subquadros 2 a 4 não são verificados
lunanet_afs_generate (frames=1, toi0=0) -> str um fluxo de símbolos de teste com subquadros provisórios (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 de ida e volta em laboratório que vincula por hash o cenário, as condições de teste (docs/spec/TEST-CONDITIONS.md), o registro do receptor e a pontuação; como evidence_create
bench_score (truth_json, predictions_json, threshold=None) -> str um arquivo de resultado do kshana-bench (texto JSON) a partir de um arquivo de verdade e um arquivo de previsões; MODELLED
bench_leaderboard (results: list[str]) -> str arquivos de resultado do 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 OSNMA do Galileo 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 em 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 enxerga sob um horizonte dependente do azimute: por satélite visible / masked, GDOP, PDOP, HDOP, VDOP, TDOP, o cofator e a covariância leste-norte-cima e as elipses de erro horizontal; request é um 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 conferidas em relação a bibliotecas independentes, o restante é MODELLED, e o resultado traz o aviso consultivo (sky_source, sky_statement dizem se o céu é representativo ou vem de conjuntos de elementos)
sky_monte_carlo (request, seed=0, n=1000) -> dict n (1 a 5000) erros de mínimos quadrados com semente no conjunto visível de request, com sua covariância empírica, 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 seu rótulo REPRESENTATIVE, procedência e o corte a cada grau de azimute; geometrias representativas, não levantamentos
skyline_profile (skyline) -> dict uma seção de horizonte (tabela, cânion urbano, 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 carimbo de tempo)
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 aponta 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 rotulada 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 parcela de uma rota por células degradadas desses mapas, como texto JSON (não é uma previsão; células não observadas não são evidência de uma rota livre)
nmea_training (toml, seed=None) -> dict NMEA sintético de ponte para treinamento de tripulação mais o registro do instrutor (nmea, log_json, log_text); somente texto, nunca para os sistemas de navegação reais 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 com vários satélites 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 geometria de suas efemérides transmitidas 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 (transformada rápida de Fourier) 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 a superfície de aquisição inteira 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 rastrear cada PRN: Doppler por época, fase do código, indicadores de travamento, C/N0, correlador prompt
iq_frontend (i, q, fs_hz, **options) -> dict a cadeia de front-end do receptor (passa-faixa, notch, blanking, excisão, AGC (controle automático de ganho), quantizador) sobre amostras complexas
iq_labfit (toml: str) -> dict ajustar o modelo de perda de travamento da malha de rastreamento a uma linha do tempo de confiança do receptor (um cenário iq-labfit)
iq_loop_designs (toml) -> list[dict] analisar um arquivo kshana.loop-design/1 (um caminho ou texto TOML) em seus projetos resolvidos, cada um com seu name e hash; ValueError em um arquivo inválido
iq_read_epochs (path) -> dict ler um arquivo binário de épocas de rastreamento (kshana.track-epoch/1, como kshana iq track --epochs o grava): 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 detecção IQ sobre uma gravação em uma única passagem de fluxo (iq monitor): series, events, spectra e notes; lê um arquivo
iq_test_conditions (conditions) -> dict validar um arquivo de condições de teste de laboratório (kshana.test-conditions/1, TOML ou JSON, um caminho ou texto) e devolvê-lo resolvido, com seu hash
iq_campaign (campaign, out_dir, workers=0, resume=True, max_cells=None, dry_run=False) -> dict executar uma campanha de replay em laboratório (kshana.campaign/1) em out_dir como kshana iq campaign faz; as células concluídas são puladas; devolve as contagens de células, as falhas e o digest quando todas as células estiverem prontas
iq_campaign_report (out_dir) -> dict reconstruir os painéis de pontuação, o relatório HTML e o resumo de uma campanha a partir de suas células: as contagens de células e de linhas, as linhas que falham em um limiar e o digest

Assinaturas de IQ GNSS e de confiança do receptor#

As assinaturas completas, como kshana.pyi as declara (toda palavra-chave após os argumentos obrigatórios tem um valor padrão; as docstrings no stub dão o significado de cada uma). Envolva as listas samples_i / samples_q, e as entradas i / q, com numpy.asarray(...) para obter matrizes.

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 replay em laboratório a partir de Python e depois o seu relatório (o arquivo da campanha e suas gravações são seus; uma célula concluída é pulada na chamada seguinte; iq_read_epochs lê um arquivo de épocas de rastreamento que uma execução de kshana iq track --epochs gravou):

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

O acq_coherent de iq_track define quantos períodos de código a aquisição de transferência integra de forma coerente. A partir da 0.33.0 o padrão é None, 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), de modo que o canal comece perto o bastante para a malha de frequência fazer a captura; acq_coherent=1 mantém a busca de um período da 0,32.

Tipos#

kshana.pyi tipa os vocabulários fechados para verificadores (mypy, pyright): ScenarioKind (o nome de cada tipo de cenário, um Literal), ErrorKind (as quatro etiquetas que error_kind devolve), ProvenanceClass, e os TypedDicts KindMeta (do 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). Eles existem apenas para verificadores de tipos e não podem ser importados em tempo de execução; tests/typed_api_sync.rs os mantém 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 Observações
.json str documento de resultado completo (JSON)
.svg str SVG (Scalable Vector Graphics) de gráfico autônomo
.summary str resumo humano de uma linha
.csv str | None a tabela de reprodutibilidade, para os tipos de cenário que a emitem (veja abaixo)
.data() dict o resultado analisado em um dict Python (veja 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 mesmo comprimento
.columns(path) dict[str, numpy.ndarray] a lista de registros em path (uma série temporal), uma matriz por campo que seja número em todos os registros
.series() dict[str, dict[str, numpy.ndarray]] toda lista de registros com um campo numérico, indexada por caminho com pontos, cada uma como .columns
.write_csv(path) int gravar essa tabela em path; devolve os bytes gravados, ou 0 (e não grava nada) quando o tipo de cenário não emite tabela

A tabela de reprodutibilidade#

realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing e leo-navmsg sempre publicam uma tabela; moonlight-service-volume publica uma quando um local de exportação (export_site_lat_deg + export_site_lon_deg) está configurado. Todos os outros tipos de cenário devolvem csv = None. O texto são os mesmos bytes que a CLI (interface de linha de comando) grava como <scenario>.table.csv, de modo que um revisor que reproduz uma tabela publicada a partir da wheel nunca precise recorrer à linha de comando:

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 no 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

de modo que as figuras de mérito são data["quantum"]["fom"], nunca data["figures_of_merit"]. Os outros tipos de cenário emitem seus próprios pacotes; a referência completa por campo, com unidades e uma indicação da fonte, é field-units-schema.json e o guia do leitor é SCHEMA.md.

Observações#

  • validate_toml e error_kind executam o cenário, de modo que revelam erros de análise, de configuração e de execução. Eles nunca levantam exceção.
  • run / run_typed levantam ValueError em um cenário inválido.
  • Os resultados são reproduzíveis: um cenário carrega sua seed e o motor registra um scenario_hash, de modo que a mesma entrada produz uma saída idêntica byte a byte na mesma plataforma (consulte REPRODUCIBILITY.md).
  • .array, .columns e .series devolvem exatamente numpy.asarray(...) dos mesmos valores que .data() fornece (mesmo dtype, idêntico bit a bit; tests/python/test_numpy_runoutput.py). Elas importam o NumPy quando chamadas e levantam ImportError sem ele; o NumPy fica fora dos requisitos de execução do pacote. KeyError significa que o caminho não existe, ValueError que o valor ali não é uma matriz numérica (ou não é uma lista de registros). Notebooks executáveis estão em notebooks/.

Fora do Python: processos de longa duração#

kshana receiver-trust live (um processo de fluxo com um gate 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 são exclusivos da linha de comando: uma ligação retorna quando a chamada retorna e não mantém um socket aberto. O Python cobre a forma em lote de cada um: receiver_trust para um registro, receiver_trust_replay para um trecho de fluxo (pontuações e estados; o gate não é aplicado), nmea_training para o texto gerado.