API Python
Kshana постачається з повноцінним програмним інтерфейсом (API) для Python, створеним за допомогою PyO3 і maturin. Її колеса abi3 збираються проти стабільного двійкового інтерфейсу застосунків Python (ABI), тож одне колесо на платформу працює з CPython ≥ 3,9; колеса охоплюють Linux, macOS і Windows, кожне для x86-64 та 64-бітного ARM (див. WHEEL_TAGS.md). Вбудований файл типових заглушок (kshana.pyi + py.typed) дає редакторам і mypy/pyright повну інформацію про типи.
pip install kshana # from the Python Package Index, PyPI (release wheels)
# or, from a checkout:
pip install maturin && maturin develop --features python
Швидкий старт#
Запускайте ці фрагменти з кореня копії репозиторію: вони читають файли сценаріїв у scenarios/. Рядок із NumPy потребує 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
Поверхня#
| Символ | Сигнатура | Повертає |
|---|---|---|
run_typed |
(toml: str) -> RunOutput |
типізований результат (.json, .svg, .summary, .csv, .data(), .array(), .columns(), .series(), .write_csv()) |
run |
(toml: str) -> str |
документ результату як рядок JSON (JavaScript Object Notation) |
run_full |
(toml: str) -> tuple[str, str, str] |
(json, svg, summary) |
scenario_kinds |
() -> list[dict] |
доступні типи сценаріїв + метадані (розібрані) |
list_kinds |
() -> str |
ті самі метадані як ОДИН рядок із масивом JSON, а не список (збережено для наявних викликачів; для розібраного списку використовуйте scenario_kinds) |
validate_toml |
(toml: str) -> list[str] |
повідомлення про помилки (порожньо, якщо коректно) |
error_kind |
(toml: str) -> str | None |
тег категорії збою (invalid_input, non_convergence, unsupported або io_error) або None у разі успіху |
version / __version__ |
() -> str / str |
версія рушія |
receiver_trust |
(toml: str) -> RunOutput |
оцінити реальний журнал приймача, описаний сценарієм receiver-trust: документ результату, CSV довіри за епохами, діаграма та підсумок; таблиця [platform] kind = "vessel" додає морські монітори та оцінку довіри 0–100 із причинами (консультативно) |
receiver_trust_replay |
(session_toml, nmea) -> dict |
обмежений фрагмент NMEA, оцінений так, як його оцінює живий режим: стан за епохами, оцінка 0–100 і причини, підсумок (без сокета, без шлюзу; консультативно) |
assess_vessel_log |
(session_toml, log) -> dict |
журнал NMEA судна як пакетний прогін: модель оцінки та оцінка кожної епохи з її відрахуваннями (консультативно) |
jammertest_import |
(catalog_json, plans, log_start_utc, location=None, local_offset_h=2.0, year=None) -> dict |
опублікований каталог і план Jammertest як події запланованої істини (events_toml, events); заплановані слоти, а не записані часи в ефірі |
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 |
журнал приймача, оцінений за цим розкладом: затримка за кожним випробуванням, пропущені, час відновлення, хибні тривоги (MODELLED; для підписаного пакета потрібен командний рядок) |
evidence_create |
(session_toml, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
підписаний пакет доказів для вікна журналу, у пам'яті: files, public_key, seed_hex (тримайте приватним); технічний запис, а не юридичний висновок |
evidence_verify |
(files, public_key=None, full_log=None, require_timestamp=False) -> dict |
перевірити пакет: хеші, ланцюжок, підпис, за потреби довірений підписувач, повний журнал і позначку часу; verdict — це verified, intact-signer-not-pinned (відкритий ключ не надано: цілісність збережена, підписувача не встановлено) або failed |
export_sp3, export_omm, export_oem |
(toml) -> str |
артефакти --export-sp3/-omm/-oem з CLI як текст |
export_formats |
(toml) -> list[dict] |
які формати interoperability застосовні до сценарію, без його запуску |
export_scenario |
(toml, format) -> dict |
czml, kml, geojson, stk або sigmf у пам'яті: {format, spec_url, files}, кожен файл {suffix, bytes, sha256, encoding, content} (текст utf-8 або base64) |
import_route |
(toml, geojson) -> str |
маршрут GeoJSON, записаний у сценарій із треком шляхових точок (--import-route) |
animate_scenario |
(toml, format="svg", fps=None, duration_s=None, width=None) -> dict |
часовий ряд прогону як анімований SVG, програвач HTML або до 120 кадрів SVG: {summary, files} |
list_examples, get_example |
(kind=None) -> dict, (name) -> str |
вбудовані еталонні сценарії та їхній TOML |
evidence_attach_timestamp |
(files, token, replace=False) -> dict |
прив'язати токен RFC 3161 (байти або base64) до пакета в пам'яті: {files, notes}; пакет усе одно має пройти перевірку; підпис органу не перевіряється |
evidence_keygen |
() -> dict |
новий ключ підпису в пам'яті: seed_hex (ПРИВАТНИЙ), public_key, fingerprint, warning; лише Python |
iq_sweep |
(i, q, fs_hz, signal, prns, ..., pll_bws=None, dll_bws=None, spacings=None, coherents=None, design=None) -> dict |
відтворити один запис за різними проєктами петель (iq sweep): для кожного проєкту й PRN — стале тремтіння, частки утримання та C/N0; одне захоплення на PRN, кожен канал на тих самих відліках |
iq_info, iq_inventory |
(path, hash=False) -> dict, (directory, recursive=False, hash=False) -> list |
описати один запис або кожен запис у теці (читає файли; hash читає їх повністю) |
bench_export |
(toml, epoch=None) -> dict |
рух транспортного засобу та події сценарію для лабораторного симулятора GNSS, у пам'яті: {files: {suffix: text}, notes, notice}; типи gnss-ins, jamming, gnss-sim; сигнал не записується, зберігайте notice разом із файлами |
compliance_report |
(runs) -> dict |
зіставлення з публічними рамками, заповнене з текстів результатів: runs — список словників {label, result, scenario?} (текст, щонайбільше 64); повертає {report, markdown}; status кожного рядка каже, що прогони підтримують докази для його можливостей, а не що рамку виконано; супроводжуйте будь-яке відображення рядком report["statement"] |
compliance_mapping |
(sources=False) -> str |
статичні таблиці зіставлення (або вихідні документи) як Markdown, із заявою на початку |
standards_pack_list |
() -> dict |
пакети стандартів (id, назва, рамка, кількість тестів) і повідомлення; пакет вимірює змодельовані сценарії відносно порогів, заявлених до прогону |
standards_pack_run |
(pack_id) -> dict |
прогін одного пакета: кожен тест MET, NOT MET або NEEDS INPUT із виміряними й очікуваними значеннями та звіт у форматі Markdown під markdown; для невідомого id викликає ValueError |
lunanet_afs_check_spec |
() -> dict |
реалізація LunaNet AFS, звірена з надрукованими таблицями та розв'язаними прикладами LSIS-AFS V1.0 (пороги B1–B10; B4 повідомляє про один зафіксований промах) |
lunanet_afs_check_symbols |
(symbols, max_sp_errors=0) -> dict |
потік символів AFS (текст із 0 і 1), перевірений на шаблон синхронізації, декодування SB1, FID, безперервність і інтервали TOI; LDPC і CRC-24Q підкадрів від 2 до 4 не перевіряються |
lunanet_afs_generate |
(frames=1, toi0=0) -> str |
тестовий потік символів із підкадрами-заповнювачами (не форма сигналу) |
evidence_round_trip |
(scoring_toml, scenario_toml, conditions, log, from_s, to_s, title=None, created_utc=None, seed_hex=None) -> dict |
підписаний лабораторний пакет кругового проходу, що пов'язує за хешем сценарій, умови випробувань (docs/spec/TEST-CONDITIONS.md), журнал приймача та оцінку; як evidence_create |
bench_score |
(truth_json, predictions_json, threshold=None) -> str |
файл результату kshana-bench (текст JSON) з файлу істини та файлу прогнозів; MODELLED |
bench_leaderboard |
(results: list[str]) -> str |
файли результатів kshana-bench, подані як статична сторінка рейтингу (HTML) |
osnma_verify |
(data, format="", start_gst=None, merkle_root_hex="", public_keys=None, reference_time=None, max_time_error=None) -> dict |
автентифікація Galileo OSNMA сторінок I/NAV або потоку UBX у пам'яті: словник, який друкує kshana osnma verify --json, із консультативним застереженням у його полі advisory; лише консультативно, це не служба цілісності навігації |
sky_geometry |
(request) -> dict |
супутники, які бачить пункт за азимутально залежним обрієм: для кожного супутника visible / masked, GDOP, PDOP, HDOP, VDOP, TDOP, кофактор і коваріація у системі схід-північ-вгору та горизонтальні еліпси похибок; request — це текст JSON або TOML чи словник (site, time_s, systems, tle, satellites, mask_deg, skyline, clock, sigma_uere_m, confidence); рішення про видимість і еліпс перевіряються за незалежними бібліотеками, решта є MODELLED, а результат несе консультативне застереження (sky_source, sky_statement показують, чи небо є репрезентативним, чи отримане з наборів елементів) |
sky_monte_carlo |
(request, seed=0, n=1000) -> dict |
n (від 1 до 5000) похибок найменших квадратів із зерном на видимій множині request з їхньою емпіричною коваріацією, RMS і часткою всередині еліпса 95 % |
skyline_presets |
() -> list[dict] |
пресети обрію (city-street, harbour-approach, fjord, container-terminal) з їхньою позначкою REPRESENTATIVE, походженням і зрізом для кожного градуса азимута; репрезентативні геометрії, а не обстеження |
skyline_profile |
(skyline) -> dict |
розділ обрію (таблиця, міський каньйон, сектори, рельєф), зведений до нормалізованої таблиці з 360 записів, яку використовує рушій |
skyplot_svg |
(request) -> str |
скайплот request як статичний текст SVG |
trust_telemetry |
(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0) -> str |
потік довіри (jsonl) або результат receiver-trust як текст Prometheus, рядки syslog CEF чи LEEF або корисне навантаження OTLP JSON, із кодувальниками kshana trust-telemetry; нічого не надсилається і годинник не читається (рядки syslog не містять позначки часу) |
interference_map |
(source, csv, dataset, cell_deg=None, licence=None, licence_url=None, attribution=None, land_geojson=None) -> list[dict] |
карта завад GNSS з тексту CSV ADS-B або AIS: один словник на добу UTC із GeoJSON kshana-interference-map/v1 (лише сукупно; деградована комірка не називає завади причиною) |
interference_emitter_regions |
(source, csv, dataset, licence=None, licence_url=None, attribution=None, land_geojson=None) -> dict |
оцінені області випромінювачів за текстом CSV ADS-B або AIS: {stem, geojson, summary, csv, svg, sessions_published, sessions_withheld}, кожна має позначку MODELLED; області із заявленою довірчою ймовірністю з центроїдом і еліпсом невизначеності, ніколи не окрема точка; лише агреговано, і область — це не положення будь-кого, а також не встановлення причини |
route_exposure |
(route, maps, date_from=None, date_to=None) -> str |
частка маршруту через деградовані комірки цих карт, як текст JSON (не прогноз; неспостережені комірки не є доказом чистого маршруту) |
nmea_training |
(toml, seed=None) -> dict |
синтетичний мостовий NMEA для навчання екіпажу разом із журналом інструктора (nmea, log_json, log_text); лише текст, ніколи для живих навігаційних систем судна |
iq_signals |
() -> list[str] |
назви сигналів GNSS IQ, які приймають iq_scene, iq_acquire і iq_track (gps-l1ca, galileo-e1b, glonass-l1of, ...) |
iq_scene |
(fs_hz, duration_s, signal, prns, **options) -> dict |
багатосупутникова сцена GNSS IQ у пам'яті: samples_i / samples_q і truth за епохами |
iq_scene_broadcast |
(fs_hz, window_s, nav_text, rx_lat, rx_lon, rx_alt, **options) -> dict |
те саме, але кожен супутник GPS — з геометрією за бортовими ефемеридами з навігаційного повідомлення RINEX (Receiver Independent Exchange Format) |
iq_acquire |
(i, q, fs_hz, signal, prns, **options) -> list[dict] |
FFT-захоплення (швидке перетворення Фур'є) кожного PRN (псевдовипадковий шумовий код): Доплер, фаза коду, статистика, поріг |
iq_acq_surface |
(i, q, fs_hz, signal, prn, **options) -> dict |
уся поверхня захоплення одного PRN (kshana.acq-surface/1): кореляційна потужність rows[doppler][lag], пік і два уточнення дрібного Доплера (parabolic, fine_search) |
iq_track |
(i, q, fs_hz, signal, prns, **options) -> dict |
захопити, потім відстежувати кожен PRN: Доплер, фаза коду, індикатори утримання, C/N0, оперативний корелятор за епохами |
iq_frontend |
(i, q, fs_hz, **options) -> dict |
ланцюг вхідної частини приймача (смуговий фільтр, режекторний фільтр, бланкування, вирізання, AGC (автоматичне регулювання підсилення), квантувач) над комплексними відліками |
iq_labfit |
(toml: str) -> dict |
підігнати модель втрати утримання петлі стеження до часової шкали довіри до приймача (сценарій iq-labfit) |
iq_loop_designs |
(toml) -> list[dict] |
розібрати файл kshana.loop-design/1 (шлях або текст TOML) у його визначені проєкти, кожен із name і hash; ValueError для некоректного файлу |
iq_read_epochs |
(path) -> dict |
прочитати двійковий файл епох стеження (kshana.track-epoch/1, як його записує kshana iq track --epochs): header і один словник на епоху в records |
iq_monitor |
(path, signal=None, prns=None, power=False, spectral=False, settings=None, ...) -> dict |
монітори виявлення IQ над записом за один потоковий прохід (iq monitor): series, events, spectra і notes; читає файл |
iq_test_conditions |
(conditions) -> dict |
перевірити файл лабораторних умов випробувань (kshana.test-conditions/1, TOML або JSON, шлях або текст) і повернути його у визначеному вигляді з hash |
iq_campaign |
(campaign, out_dir, workers=0, resume=True, max_cells=None, dry_run=False) -> dict |
запустити кампанію лабораторного відтворення (kshana.campaign/1) у out_dir, як це робить kshana iq campaign; завершені комірки пропускаються; повертає кількості комірок, збої та digest, коли всі комірки завершено |
iq_campaign_report |
(out_dir) -> dict |
перебудувати карти показників кампанії, звіт HTML і дайджест з її комірок: кількості комірок і рядків, рядки, що не відповідають порогу, і digest |
Сигнатури GNSS IQ і довіри до приймача#
Повні сигнатури, як їх подає kshana.pyi (кожне ключове слово після обов'язкових аргументів має значення за замовчуванням; рядки документації в заглушці пояснюють значення кожного). Обгорніть списки samples_i / samples_q і входи i / q за допомогою 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]: ...
Кампанія лабораторного відтворення з Python, а потім її звіт (файл кампанії та її записи — ваші; завершена комірка пропускається під час наступного виклику; iq_read_epochs читає файл епох стеження, записаний запуском 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
Параметр acq_coherent функції iq_track задає, скільки періодів коду когерентно інтегрує захоплення під час передавання. Починаючи з 0.33.0 його значення за замовчуванням — None, тобто авто: близько 4 мс (4 періоди для коду 1 мс, як-от GPS L1 C/A, 1 для коду 4 мс або довшого), щоб канал стартував достатньо близько для втягування частотною петлею; acq_coherent=1 зберігає одноперіодний пошук 0,32.
Типи#
kshana.pyi типізує закриті словники для перевірників (mypy, pyright): ScenarioKind (кожна назва типу, Literal), ErrorKind (чотири теги, які повертає error_kind), ProvenanceClass, а також TypedDict KindMeta (список чого повертає scenario_kinds()) і FieldUnit (запис блока units результату, що розширює базу обов'язкових ключів _FieldUnitBase). Вони існують лише для перевірників типів і не імпортуються під час виконання; tests/typed_api_sync.rs тримає їх рівними спискам рушія.
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#
| Член | Тип | Примітки |
|---|---|---|
.json |
str |
повний документ результату (JSON) |
.svg |
str |
окремий SVG діаграми (Scalable Vector Graphics) |
.summary |
str |
однорядковий підсумок для людини |
.csv |
str | None |
таблиця відтворюваності для типів, що її видають (див. нижче) |
.data() |
dict |
результат, розібраний у словник Python (див. примітку про структуру нижче) |
.array(path) |
numpy.ndarray |
числовий список за path (через крапки, "points.0.coords", або вказівник JSON, "/points/0/coords"): 1-D для чисел, 2-D для числових списків однакової довжини |
.columns(path) |
dict[str, numpy.ndarray] |
список записів за path (часовий ряд), один масив на поле, що є числом у кожному записі |
.series() |
dict[str, dict[str, numpy.ndarray]] |
кожен список записів із числовим полем, із ключем у вигляді шляху через крапки, кожен як .columns |
.write_csv(path) |
int |
записати цю таблицю в path; повертає кількість записаних байтів або 0 (і нічого не записує), якщо тип не видає таблиці |
Таблиця відтворюваності#
realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing і leo-navmsg завжди публікують таблицю; moonlight-service-volume публікує її, коли налаштовано пункт експорту (export_site_lat_deg + export_site_lon_deg). Кожен інший тип повертає csv = None. Текст — це ті самі байти, що їх CLI (інтерфейс командного рядка) записує як <scenario>.table.csv, тож рецензентові, який відтворює опубліковану таблицю з колеса, ніколи не доводиться переходити до командного рядка:
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")
Структура результату#
Показники якості та часові ряди містяться окремо для кожної сторони прогону, а не на верхньому рівні. Для прогону годинника документ такий:
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
тож показники якості — це data["quantum"]["fom"], а ніколи не data["figures_of_merit"]. Інші типи видають власні пакети; повний довідник за полями з одиницями та вказівником на джерело — field-units-schema.json, а посібник для читача — SCHEMA.md.
Примітки#
validate_tomlіerror_kindвиконують сценарій, тож виявляють помилки розбору, конфігурації та виконання. Вони ніколи не викликають винятку.run/run_typedвикликаютьValueErrorдля некоректного сценарію.- Результати відтворювані: сценарій несе свій
seed, а рушій записуєscenario_hash, тож той самий вхід дає побайтово ідентичний вихід на тій самій платформі (див.REPRODUCIBILITY.md). .array,.columnsі.seriesповертають самеnumpy.asarray(...)тих самих значень, що й.data()(той самий dtype, побітово ідентично;tests/python/test_numpy_runoutput.py). Вони імпортують NumPy під час виклику і викликаютьImportErrorбез нього; NumPy не входить до вимог середовища виконання пакета.KeyErrorозначає, що шлях відсутній,ValueError— що значення там не є числовим масивом (або не є списком записів). Запускні блокноти — уnotebooks/.
Немає в Python: довготривалі процеси#
kshana receiver-trust live (потоковий процес зі шлюзом і необов'язковим TCP-сервером --listen) та експортери телеметрії (Prometheus, OTLP, syslog; docs/TRUST-TELEMETRY.md) і потокова передача kshana nmea-scenario --tcp/--udp доступні лише з командного рядка: прив'язка повертається, коли повертається виклик, і не тримає сокет відкритим. Python охоплює пакетну форму кожного: receiver_trust для журналу, receiver_trust_replay для фрагмента потоку (оцінки та стани; шлюз не застосовується), nmea_training для згенерованого тексту.