init commit

This commit is contained in:
Ayzen
2026-03-05 14:42:33 +03:00
commit fd4618b20d
964 changed files with 325114 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
# Python App Documentation
## Назначение
Каталог `python_app/docs` содержит техническую документацию по Python-части радарной системы: GUI, orchestration, storage, hardware adapters и эксплуатационные сценарии.
## Карта документов
- `architecture_overview.md`: общая модульная архитектура и границы ответственности.
- `runtime_data_flow.md`: потоки данных от acquisition до отображения и snapshot.
- `gui_architecture.md`: структура GUI, mixin-контроллеры, plotting/runtime helpers.
- `hardware_layer.md`: слой работы с LibreVNA и переключателями.
- `storage_formats.md`: форматы NPZ/binary/numpy snapshot и naming.
- `shm_protocol_and_readers.md`: shared-memory ring контракт и декодирование payload.
- `preprocessing_and_capture_workflow.md`: калибровка/референс и последовательный захват.
- `operations_runbook.md`: запуск, диагностика, типовые инциденты.
- `module_reference.md`: справочник ключевых Python-модулей.
## Границы
- Документация описывает Python-часть проекта в `python_app`.
- C++ конвейер (`data_acq_and_processing`) описывается только в части интеграционных точек с Python.
## Версия документации
Актуально для состояния репозитория после рефакторинга: разделения `models`, `storage/npz`, `orchestration/shm`, `gui/plotting`, `gui/runtime`, `gui/controllers/sections`.
+46
View File
@@ -0,0 +1,46 @@
# Архитектурный обзор Python-части
## 1. Верхнеуровневая схема
Python-часть разделена на следующие пакеты:
- `gui`: desktop UI на PyQt6 + pyqtgraph.
- `models`: dataclass-модели runtime-конфига и датасетов.
- `orchestration`: управление runtime-конфигом, процессами и SHM-ридерами.
- `storage`: persistent storage для calibration/reference и runtime snapshots.
- `hardware_full`: Python-обертки над LibreVNA и switch drivers.
- `workflows`: сценарии калибровки/референса/последовательного захвата.
- `scripts`: эксплуатационные и отладочные скрипты.
## 2. Ключевые архитектурные решения
- GUI оставлен единой точкой входа (`AppWindow`), но тяжелая логика вынесена в `sections`, `plotting` и `runtime` helpers.
- Конфиг разделен на schema/codec/validation:
- `run_config_schema.py`
- `run_config_codec.py`
- `run_config_validation.py`
- `run_config_model.py` как фасадный модуль.
- Storage разделен на подпакет `storage/npz/*`:
- `paths.py`
- `serialize.py`
- `snapshot_numpy.py`
- `store.py`
- SHM-декодирование разделено на `orchestration/shm/*`:
- `binary_cursor.py`
- `decoder.py`
- `ring_reader.py`
- `shm_reader.py` как фасад.
- LibreVNA service переведен на backend-подход (`librevna_backends.py`) с orchestration-оберткой `librevna_service.py`.
## 3. Инварианты
- Формат `run_config.json` сохраняется совместимым с C++ pipeline.
- Форматы snapshot (`binary`, `numpy-directory-v1`) сохраняются.
- Сигнатуры ключевых пользовательских входов (`gui/main.py`, scripts) сохраняются.
- Данные в `python_app/data` и runtime-файлы в `python_app/runtime` не реорганизуются автоматически.
## 4. Основные зависимости
- GUI: `PyQt6`, `pyqtgraph`, `numpy`.
- Hardware: `libusb1` через драйвер в `hardware_full/librevna_driver`.
- Storage/processing tools: `numpy`, stdlib JSON/Path/mmap/subprocess.
## 5. Точки расширения
- Новые processing modes: через live-config + GUI section + C++ processor.
- Новые storage backends: реализовать `StoreApi`.
- Новые hardware adapters: добавить backend/driver и подключить в service/factory.
+43
View File
@@ -0,0 +1,43 @@
# Архитектура GUI
## 1. Состав
- `gui/main.py`: entrypoint приложения.
- `gui/app_window.py`: компоновка миксинов и базовой инфраструктуры.
- `gui/controllers/*`: orchestration-логика.
- `gui/controllers/sections/*`: построение UI-групп (Pipeline, Processing, Radar, Switches и т.д.).
- `gui/plotting/*`: чистая логика B-scan расчетов и cache helpers.
- `gui/runtime/*`: runtime history/constraint helpers.
- `gui/preprocess_dialog.py`: окно последовательного захвата calibration/reference.
## 2. Mixin роли
- `AppWindowUiMixin`: сборка виджетов и layout.
- `AppWindowConfigMixin`: сборка `RunConfigModel`, live settings и лимиты устройства.
- `AppWindowPipelineMixin`: старт/стоп процессов, polling ring readers, history lifecycle.
- `AppWindowPlotMixin`: выбор режима отрисовки и рендер.
- `AppWindowPreprocessMixin`: workflow для calibration/reference capture.
- `AppWindowSnapshotMixin`: сохранение runtime snapshot.
## 3. Состояния AppWindow
Ключевые поля состояния:
- readers: `_raw_reader`, `_pre_reader`, `_result_reader`
- history: `_raw_history`, `_pre_history`, `_result_history`
- bscan cache: `_bscan_history_by_combo`, `_bscan_depth_axis_by_combo`, `_bscan_render_signature`
- single capture flags: `_single_capture_*`
- radar limits: `_radar_limits`
## 4. UI composition
Секции строятся через builders в `gui/controllers/sections`:
- `build_pipeline_group`
- `build_hardware_actions_group`
- `build_data_actions_group`
- `build_preprocess_summary_group`
- `build_processing_group`
- `build_radar_group`
- `build_switch_group`
## 5. Рекомендации по расширению GUI
- Не добавлять тяжелую математику в mixin-файлы.
- Для новых параметров processing mode:
- добавить поле в live config,
- добавить controls в `processing_section`,
- добавить обработку в plotting/runtime helpers.
+35
View File
@@ -0,0 +1,35 @@
# Hardware layer
## 1. LibreVNA
- `hardware_full/librevna_service.py`: orchestration facade.
- `hardware_full/librevna_backends.py`:
- `NativeLibreVnaBackend`
- `MockLibreVnaBackend`
- `hardware_full/librevna_driver/*`: низкоуровневый USB/protocol stack.
### Native flow
1. `LibreVnaService.open()`
2. `configure(RadarSweepModel)`
3. `acquire_s21()`
4. `close()`
### Device limits
- `read_device_limits()` возвращает min/max frequency, IFBW, power и max points.
- GUI применяет лимиты для clamp/labels и live B-scan frequency bounds.
## 2. Switches
- `switch_service.py`: выбор mock/native драйвера по конфигурации.
- `switch_drivers/*`:
- `MockSwitchDriver`
- `H7992Driver`
- `HMC349ADriver`
- `gpio_uapi.py` (Linux GPIO v2 wrapper)
### Инварианты
- Позиции валидируются на уровне драйвера.
- Драйверы требуют `open()` перед `switch_to()`.
- Для native GPIO ошибки ОС конвертируются в Python `RuntimeError` с контекстом.
## 3. Расширение hardware слоя
- Новый радар: добавить backend с тем же контрактом, подключить в service.
- Новый switch: реализовать `SwitchDriverProtocol` и добавить ветку в `SwitchService._build_driver()`.
+50
View File
@@ -0,0 +1,50 @@
# Module reference
## `python_app.gui`
- `main.py`: GUI entrypoint.
- `app_window.py`: composition root.
- `controllers/app_window_*_mixin.py`: функциональные части окна.
- `controllers/sections/*`: построители UI-секций.
- `plotting/bscan_math.py`: математика B-scan.
- `plotting/bscan_history.py`: cache/signature для B-scan.
- `runtime/history.py`: сигнатуры run/history merge.
- `runtime/constraints.py`: режимные ограничения.
## `python_app.models`
- `dataset_model.py`: dataclass-модели sweep/result данных.
- `run_config_schema.py`: dataclass-schema run config.
- `run_config_codec.py`: encode/decode/load.
- `run_config_validation.py`: payload checks/parsing helpers.
- `run_config_model.py`: фасадный экспорт.
## `python_app.orchestration`
- `config_writer.py`: runtime config + bundle files.
- `live_processing_config.py`: live processing JSON writer.
- `process_supervisor.py`: управление процессами C++ pipeline.
- `shm/*`: shared-memory чтение и декодирование.
- `shm_reader.py`: фасадный экспорт.
## `python_app.storage`
- `store_api.py`: абстракция хранилища.
- `npz/store.py`: `NpzStore`.
- `npz/serialize.py`: binary serializers.
- `npz/snapshot_numpy.py`: snapshot selection/writers.
- `npz/paths.py`: naming/path helpers.
- `npz_store.py`: фасадный экспорт.
## `python_app.hardware_full`
- `librevna_service.py`: high-level service.
- `librevna_backends.py`: native/mock adapters.
- `librevna_driver/*`: USB/protocol/session/controller stack.
- `switch_service.py`: switch facade.
- `switch_drivers/*`: native/mock switch implementations.
## `python_app.workflows`
- `sequential_capture_workflow.py`: последовательный capture session.
- `calibration_workflow.py`, `reference_workflow.py`: helper workflows.
## `python_app.scripts`
- `check_snapshot_numpy.py`: snapshot validator + plots.
- `manual_smoke_run.py`: локальный smoke сценарий.
- `hardware_raw_orchestrator_test.py`: raw ring visualization utility.
- `vna_only_raw_test.py`: direct VNA check utility.
+49
View File
@@ -0,0 +1,49 @@
# Operations runbook
## 1. Подготовка
- Собрать C++ binaries (`make`).
- Проверить `run_config.json` и доступность hardware.
- Для native режима убедиться в правах на USB/GPIO.
## 2. Запуск GUI
```bash
python3 -m python_app.gui.main
```
## 3. Базовый сценарий live run
1. Проверить Radar/Switches config.
2. Выбрать calibration/reference sets.
3. Нажать `Start`.
4. Проверить обновление history и графика.
5. Нажать `Stop`.
## 4. Сохранение snapshot
1. Указать `Path`, `Name`, `Last N`.
2. Нажать `Save Numpy Snapshot`.
3. Проверить `manifest.json` и каталоги `raw/preprocessed/results`.
## 5. Проверка snapshot
```bash
python3 python_app/scripts/check_snapshot_numpy.py <snapshot_dir>
```
## 6. Конвертация snapshot для vna_system
```bash
python3 python_app/scripts/convert_snapshot_to_vna_history.py \
<snapshot_dir> \
-o <output_json> \
--input 0 \
--output-index 0
```
Полученный JSON содержит `sweep_history` и загружается в `vna_system` через кнопку загрузки истории у B-scan графика.
## 7. Типовые проблемы
- Пустой график: проверить processing mode и наличие trace payloads.
- Нет запуска в B-scan: проверить ограничение combo для native switches.
- Ошибки лимитов радара: проверить соединение с устройством и serial.
- Процессы не стартуют: смотреть crash reports в GUI log.
## 8. Безопасная остановка
- Использовать `Stop` в UI.
- При закрытии окна вызывается стоп всех процессов и закрытие dialogs/readers.
@@ -0,0 +1,32 @@
# Preprocessing and capture workflow
## 1. Назначение
До запуска live-pipeline необходимо выбрать calibration/reference set, покрывающие целевые run combos.
## 2. Процесс в GUI
1. Открыть `Preprocessing Panel`.
2. Выбрать или создать имя набора (`set_name`).
3. Запустить `Start Calibration Sequence` или `Start Reference Sequence`.
4. Для каждого combo нажимать `Capture Current Combo`.
5. По завершении данные сохраняются в `NpzStore`.
## 3. Internal flow
- `AppWindowPreprocessMixin` создает `SequentialCaptureSession`.
- Session управляет:
- `LibreVnaService`
- input/output `SwitchService`
- последовательным обходом full combo matrix.
- После полной матрицы вызывается `finalize(store)`.
## 4. Связь с live run
`_start_run()` проверяет:
- выбраны ли calibration/reference sets,
- покрывают ли выбранные sets все run combos (`has_combo_coverage`),
- доступны ли bundle-файлы для preprocessor.
## 5. Диагностика
Типовые ошибки:
- set already exists,
- incomplete capture sequence,
- hardware not available,
- mismatch requested combos vs stored combos.
+39
View File
@@ -0,0 +1,39 @@
# Потоки данных runtime
## 1. Непрерывный acquisition pipeline
1. `AppWindowPipelineMixin._start_run()` строит `RunConfigModel` из UI.
2. `ConfigWriter` пишет runtime config и bundles calibration/reference.
3. `ProcessSupervisor` запускает:
- `data_processor`
- `data_preprocessor`
- `sweep_orchestrator`
4. GUI открывает `ShmRingReader` для:
- raw tap
- preprocessed tap
- results
5. Таймер GUI (`QTimer`) вызывает `_poll_rings()`:
- чтение raw/preprocessed/results
- запись в history deques
- рендер либо trace-lines, либо B-scan heatmap.
## 2. B-scan path
- Источник: `preprocessed` history ring.
- Кэш-сигнатура: `build_bscan_signature()` учитывает live-параметры и tail history.
- Ребилд: `rebuild_bscan_history_from_preprocessed()` + `compute_bscan_profile()`.
- Рендер: `ImageItem` с LUT и уровнями (`bscan_lookup_table`, `bscan_levels`).
## 3. Single capture path
- `_start_single_capture()` запускает pipeline в non-continuous режиме.
- GUI ждет collection после стартового timestamp и валидного trace payload.
- По завершении выполняется `_stop_run()`.
## 4. Snapshot path
- `AppWindowSnapshotMixin._save_snapshot()` предварительно дренирует ring buffers.
- `NpzStore.save_runtime_snapshot_numpy()`:
- выбирает aligned histories (`select_aligned_histories`),
- пишет `raw/preprocessed/results` + `manifest.json`.
## 5. Failure handling
- Process crashes читаются через `ProcessSupervisor.collect_crash_reports()`.
- Reader/parsing errors логируются в GUI runtime log.
- Hardware/validation errors показываются через `_show_error()` и лог.
@@ -0,0 +1,28 @@
# SHM protocol and readers
## 1. Ring format
Python reader ожидает ring header:
- magic: `RDRRING2`
- version: `1`
- fields capacity/slot_size/write_seq/read_seq.
Ring files находятся в `/dev/shm/<ring_name_without_slash>`.
## 2. Reader components
- `orchestration/shm/binary_cursor.py`: primitive cursor API.
- `orchestration/shm/decoder.py`: decode trace/result payloads.
- `orchestration/shm/ring_reader.py`: mmap-based ring consumption.
- `orchestration/shm_reader.py`: фасад для импортов.
## 3. Consumption semantics
- `pop_payload()` возвращает `None`, если новых payload нет.
- При sequence mismatch reader выполняет fast-forward read pointer.
- `drop_all()` принудительно дропает unread payloads.
## 4. Error cases
- missing ring file -> `FileNotFoundError`
- magic/version mismatch -> `RuntimeError`
- bad payload magic/kind -> `ValueError`
## 5. Integration
`AppWindowPipelineMixin` использует по одному reader на raw/preprocessed/results ring.
+41
View File
@@ -0,0 +1,41 @@
# Storage formats
## 1. Calibration/reference sets
Хранятся в `python_app/data/{calibration|reference}/{radar_key}`:
- `<set_name>.npz`
- `<set_name>.json`
`radar_key` формируется из sweep и power параметров (`radar_key_from_config`).
## 2. Binary collection serialization
`storage/npz/serialize.py`:
- `RAW_MAGIC = 0x31574152`
- `PREPROC_MAGIC = 0x31525050`
- `RESULT_MAGIC = 0x314C5352`
Поддерживается сериализация:
- trace collections (`serialize_trace_collection`)
- result collections (`serialize_result_collection`)
## 3. Runtime numpy snapshot (`numpy-directory-v1`)
Структура:
- `manifest.json`
- `raw/<collection_dir>/...`
- `preprocessed/<collection_dir>/...`
- `results/<collection_dir>/block_*/...`
Коллекция: `0003_id22_ns11999302655222`.
## 4. History selection
Перед записью snapshot вызывается `select_aligned_histories()`:
- primary mode: `aligned_by_collection_and_occurrence`
- fallback: `independent_tail`
Это предотвращает рассинхронизацию raw/preprocessed/results при сохранении.
## 5. Обратное чтение
Для валидации snapshot используется `scripts/check_snapshot_numpy.py`:
- проверка shape/finite,
- сравнение коллекций,
- построение графиков сравнения,
- plot всех switch states для одной коллекции.