From 4d8744e7db88632084ce9d60398bf3b711362e7d Mon Sep 17 00:00:00 2001 From: Scaxlibur <51772892+Scaxlibur@users.noreply.github.com> Date: Sat, 8 Aug 2026 01:29:55 +0800 Subject: [PATCH 01/26] feat: close frequency response evidence workflow --- README.md | 4 +- .../WaveBench_CLI\345\275\242\346\200\201.md" | 11 +- ...77\347\224\250\346\214\207\345\215\227.md" | 36 + ...23\345\207\272\346\240\274\345\274\217.md" | 12 +- src/wavebench/cli.py | 64 ++ src/wavebench/cli_parser.py | 53 ++ src/wavebench/report/html.py | 52 +- src/wavebench/services/frequency_response.py | 427 ++++++++- .../frequency_response_calibration.py | 48 +- .../services/frequency_response_evidence.py | 174 ++++ .../services/frequency_response_resume.py | 189 ++++ src/wavebench/services/run_artifacts.py | 3 + src/wavebench/services/run_compare.py | 811 ++++++++++++++++++ src/wavebench/services/run_plan.py | 35 + src/wavebench/services/run_service.py | 516 ++++++++++- tests/test_cli_frequency_tools.py | 69 ++ tests/test_frequency_response_evidence.py | 192 +++++ tests/test_frequency_response_resume.py | 68 ++ .../test_frequency_response_resume_service.py | 89 ++ ...test_frequency_response_stop_conditions.py | 27 + tests/test_run_compare.py | 212 +++++ 21 files changed, 3053 insertions(+), 39 deletions(-) create mode 100644 src/wavebench/services/frequency_response_evidence.py create mode 100644 src/wavebench/services/frequency_response_resume.py create mode 100644 src/wavebench/services/run_compare.py create mode 100644 tests/test_cli_frequency_tools.py create mode 100644 tests/test_frequency_response_evidence.py create mode 100644 tests/test_frequency_response_resume.py create mode 100644 tests/test_frequency_response_resume_service.py create mode 100644 tests/test_frequency_response_stop_conditions.py create mode 100644 tests/test_run_compare.py diff --git a/README.md b/README.md index c44aa62..71d080f 100644 --- a/README.md +++ b/README.md @@ -132,11 +132,13 @@ DP800 的设定值、保护和输出是三类独立操作。示例计划见 [pla 使用 `source-scope-frequency-response` 模板可以生成 reference / response 双通道扫频 plan。基础频响采集不要求额外依赖;PCHIP、平滑样条和二维校准需要 `analysis`,PDF 报告需要 `pdf`,交互式三维 HTML 需要 `report3d`。详细说明见 [run plan 使用指南](docs/project/guides/WaveBench_run_plan_使用指南.md);执行前仍需确认真实接线。 +频响结果可用 `run compare` 离线比较多个 run,并用 `run resume` 生成缺失点补测清单;两条命令都不会连接仪器。每个已生成采集包的频响点会保存 `case_id`、`acquisition_id`、请求 Vpp 与参考通道实测 Vpp,便于复查测量来源。 + ## 命令的安全边界 | 类别 | 例子 | 说明 | | --- | --- | --- | -| 离线 | `run schema`、`run template`、`run check`、`run report`、`capture inspect`、`tui --fake` | 不连接仪器;TUI 可能写本地日志 | +| 离线 | `run schema`、`run template`、`run check`、`run report`、`run compare`、`run resume`、`capture inspect`、`tui --fake` | 不连接仪器;TUI 可能写本地日志 | | 连接读取 | `doctor`、`idn`、`status`、`run verify` | 会查询设备;仍应把它当作有状态的 I/O | | 修改设备 | `scope fetch/capture/autoscale`、source/power setter、output、`run plan`、非 fake TUI | 可能改变设置、触发采集或切换输出 | diff --git "a/docs/project/guides/WaveBench_CLI\345\275\242\346\200\201.md" "b/docs/project/guides/WaveBench_CLI\345\275\242\346\200\201.md" index 401f629..27aba78 100644 --- "a/docs/project/guides/WaveBench_CLI\345\275\242\346\200\201.md" +++ "b/docs/project/guides/WaveBench_CLI\345\275\242\346\200\201.md" @@ -29,7 +29,7 @@ wavebench run --help | 类别 | 示例 | 行为 | |---|---|---| -| 离线 | `run schema`、`run template`、`run check`、`run report`、`capture inspect`、`tui --fake` | 不连接仪器;报告和检查只读取本地产物 | +| 离线 | `run schema`、`run template`、`run check`、`run report`、`run compare`、`run resume`、`capture inspect`、`tui --fake` | 不连接仪器;报告、比较和检查只读取本地产物 | | 连接读取 | `doctor`、`net`、`scope idn`、`scope status`、`run verify` | 查询资源、身份或状态,不应修改实验设置 | | 显式写入或触发 | `scope auto`、`scope fetch/capture`、source / power setter、`run plan` | 可能改变设置、触发采集或切换输出 | @@ -56,6 +56,15 @@ wavebench run report data/runs/ `run check` 只解析 TOML 和字段,不连接仪器;`run verify` 做执行前的只读预检;`run plan` 才会执行真实实验。 +频响结果的离线处理使用以下命令: + +```bash +wavebench run compare data/runs/ data/runs/ --format json +wavebench run resume data/runs/ --plan plans/.toml +``` + +`run compare` 按 `case_id` 比较增益、相位和测量状态;`run resume` 生成可复用点与待补测点清单。两条命令都不会打开仪器 session。 + ## 示波器命令 ### 查询和状态 diff --git "a/docs/project/guides/WaveBench_run_plan_\344\275\277\347\224\250\346\214\207\345\215\227.md" "b/docs/project/guides/WaveBench_run_plan_\344\275\277\347\224\250\346\214\207\345\215\227.md" index 4884c72..2b61010 100644 --- "a/docs/project/guides/WaveBench_run_plan_\344\275\277\347\224\250\346\214\207\345\215\227.md" +++ "b/docs/project/guides/WaveBench_run_plan_\344\275\277\347\224\250\346\214\207\345\215\227.md" @@ -197,6 +197,19 @@ max_slope_db_per_octave = 6 频响点的首次采集若出现质量 warning,默认会执行一次「autoscale → 等待 `settle_s` → 同频同幅值重测」。重测成功时,CSV 的最终值来自第二次采集;首次证据保存在 `quality_retry_count`、`initial_warnings`、`initial_capture_package` 和 `initial_metadata_path` 中。重测仍出现 warning 时,该点标为 `failed`,原因设为 `quality_retry_exhausted`,不参与拟合、软件校正或二维 LUT。可在 step 中设置 `retry_warning_with_autoscale = false` 关闭此策略。 +每个频响点还会写入稳定的 `case_id`、本次物理采集的 `acquisition_id`、`plan_hash` 和 `capture_sync_grade`。`case_id` 由计划语义、频率、请求 Vpp、通道角色生成,适合跨 run 比较;重测会保留不同的 `acquisition_id`。`reference_vpp_v` 是参考示波器通道的实测值,`requested_source_vpp` 是信号源请求值;系统不会根据输入阻抗自动换算电压。`signal_level_evidence` 会记录参考平面和未执行换算的说明。 + +频响点级采集或分析失败仍会保留行并继续扫描,这是为了保留完整网格证据。需要在异常累计时停止整组扫描时,可显式设置 `stop_conditions`: + +```toml +[steps.stop_conditions] +max_failed_points = 2 +max_consecutive_failed_points = 1 +max_gain_jump_db = 6 +``` + +达到任一条件后,当前 response 步骤停止,并在 `artifact.frequency_response.stop_conditions` 中保存触发条件;信号源设频、输出状态或通信失败仍会立即停止该步骤。 + 默认 20 mVpp 的门限是保守质量保护,不是仪器限制。对已确认稳定的低幅值扫频,可只在该 `sweep.frequency_response` 中设置 `min_signal_vpp = 0.005`;这会在采集分析阶段生效,因此 `metadata.json`、CSV 状态和报告审计使用同一个判断依据。全局 `[waveform]` 也可设同名默认值,但不建议为了一个低幅值实验而永久降低所有普通采集的门限。 完整矩阵的点数为 `幅值数 × 频点数`;每个点至少消耗 `settle_s`,每个幅值切片还会增加一次 autoscale 与稳定等待。先用少量幅值和稀疏频点执行 `run check`、只读 `run verify`、再做实机小矩阵确认量程和耗时,别拿 5 mV 步进和 500 Hz 步进直接开 13 小时以上的盲扫,没必要给仪器和人都上强度。 @@ -227,6 +240,26 @@ python -m wavebench run calibrate data/runs/ --config plans/calibration python -m wavebench run calibrate data/runs/ --config plans/calibration.toml --response dut_path ``` +### 跨 run 比较与缺失点补测 + +`run compare` 是离线命令,按 `case_id` 优先、按频率和请求 Vpp 回退,对比增益、相位、参考 Vpp、状态和缺失点。不同通道角色、参考平面或计划哈希会被标记为不兼容,不会静默合并: + +```powershell +python -m wavebench run compare data/runs/baseline data/runs/current --gain-tolerance-db 0.5 --phase-tolerance-deg 5 --output reports/frequency_compare.json +``` + +使用 `--format json` 可将结果直接写到标准输出。比较命令只读取已有 run artifact,不打开仪器。 + +需要补测缺失点时,先生成离线清单: + +```powershell +python -m wavebench run resume data/runs/current --plan plans/lowpass_frequency_response.toml --response dut_path --output reports/frequency_resume.json +``` + +清单会列出可复用、待补测和被拒绝的点。新 plan 可在对应 response step 中设置 `resume_from = "../data/runs/current/frequency_response.csv"`;WaveBench 只复用计划哈希和案例标识均匹配且状态为 `ok` 的点,原 run 目录不会被改写。 + +补测清单先覆盖计划声明的初始频率网格;启用自适应加点时,新的中点仍按当前 plan 的自适应规则重新判断。 + ### 直通基线、软件 deskew 与自适应频率 直通基线必须是**独立 run**:操作者先把 CH1/CH2 手动直通、确认高阻与安全幅度,再按普通 `sweep.frequency_response` 采集。DUT step 只读引用该证据;它不改示波器 deskew 或前面板设置,且 `run check` 会在连接仪器前离线检查基线 response、Vpp 切片和初始频率有效域。 @@ -452,6 +485,9 @@ data/runs/YYYYMMDD_HHMMSS_