# spectrum-white-studio —— KSF CR 白光合成总控工程

> 状态：阶段 3（Agent JSON API + 中文字体 + 发布打包）完成 · 2026-09-09 立项
> 本文档是方案讨论（2026-09-09）的最终口径记录，后续开发以本文为准；改口径必须先改本文。
> **最终交付形态（用户确认）**：三阶段完成后交付一个独立文件夹，内含可双击运行的单体 exe
> （egui 原生渲染、资产全部内嵌、无 DLL/运行时依赖）；阶段 3 做 release 构建与打包。

## 1. 任务目标

把四个既有工程打通为一条自动化链路：

**输入**：蓝光峰值波长、绿光峰值波长、电流（可不填，默认 20 mA）
**输出**：满足 CIE xy 白点 (0.27 ± 0.005, 0.26 ± 0.005)（**目标白点可键入调整**，如 (0.3, 0.3)）的 B-G-R（KSF CR 方案）白光光谱，
并给出色域覆盖率与 TUV 莱茵四项判定（✓/✗）。

四个子程序（全部已有，本工程只做串联）：

1. **光谱生成**：`ingan-spectrum-generator`（crates/spectrum-core + spectrum-io）——由峰值 + 电流生成 B、G 光谱；
2. **光谱合成**：`spectrum-synthesizer`——按占比 a:b:c 加权合成 + max 归一化；
3. **色度/色域计算**：`spectrum-colorimeter`——xy 色点、NTSC / BT.2020 三点与四点覆盖率；
4. **莱茵四项判定**：`spectrum-checker`——白光光谱逐项 ✓/✗。

## 2. 已锁定口径（用户逐条确认）

| # | 口径 | 结论 |
|---|------|------|
| 1 | R（KSF）光谱来源 | 内置实测谱，支持 GUI 导入替换 |
| 2 | 合成前提 | B/G/R 三通道**先各自 max 归一化**，再按占比加权合成 |
| 3 | 电流作用域 | B、G **都重算**（ingan 公式天然满足：FWHM_target = FWHM_blue(I)·(峰值/447.53)²） |
| 4 | 白点寻优 | **目标白点可键入调整**（JSON `target`，缺省 0.27/0.26，容差 0.005）；xy 落入区域即停；占比设下限 **0.01**；无可行解仅报错、不做调参建议 |
| 5 | 三点色域 | B×CF_B、G×CF_G、R×CF_R 三条"接收端"光谱各算色点 → 三角形面积比 |
| 6 | 四点色域 | 三点 + **B2 = R×CF_B** → 四点凸包面积比 |
| 7 | 四点触发 | **R 通道谱本身**归一化后 420–500 nm 峰值 > 0.1（内置红谱实测 ≈0.198，触发；若按 R×CF_R 后判定仅 ≈0.00084 永不触发） |
| 8 | 白点计算 | 合成白光谱**不过 CF** 直接算 xy（白点=总发光，色域色点=过屏谱，两层并存） |
| 9 | CF 屏谱来源 | 程序内置实测 CF_R / CF_G / CF_B（三份全部使用），支持替换 |
| 10 | 莱茵四项 | 即 spectrum-checker 现有四项（RG0+UV 简化 / 蓝峰±10nm≤18% / 蓝峰/绿峰、蓝峰/红峰**均**≤1.8（绿峰 500–580 nm、红峰 580–780 nm）/ 415–460 占 400–500 <45%），判定对象=最终合成白光；GUI ✓ 不加"简化"标注（报告 notes 里保留说明） |
| 11 | 网格与观察者 | 380–780 nm、1 nm、401 点；CIE 1931 2°（与 colorimeter cie.rs 同源的 5nm 表线性插值） |
| 12 | 色域口径 | xy 平面面积比（与 colorimeter gamut.rs 一致） |

## 3. 资源池清单

### 3.1 光谱资产（全部实测原样保留，含噪声，不许删改）

| 资产 | 位置 | 说明 |
|---|---|---|
| KSF 红通道谱 | `../spectrum-synthesizer-gui/assets/builtin_red.json` | 实测，峰 0.0041@630nm，含 440nm 蓝峰≈19.8%，27 个负值 |
| 绿光 LED 谱（备用/对照） | `../spectrum-synthesizer-gui/assets/builtin_green.json` | ingan 派生 G530@20mA，峰值归一化 |
| 蓝光 LED 谱（备用/对照） | `../spectrum-synthesizer-gui/assets/builtin_blue.json` | ingan 派生 B460@20mA，峰值归一化 |
| InGaN 蓝光基准模板 | `../ingan-spectrum-generator/assets/baseline_spectrum.json` | 实测 448nm@20mA，FWHM 12.8367，B/G 生成的唯一模板 |
| 蓝屏 CF_B | `assets/builtin_cf_blue.json` | 实测，峰 0.0949@472nm |
| 红屏 CF_R | `assets/builtin_cf_r.json` | 实测，红发射带峰 0.1333@628nm（⚠ 744–780 噪声带最大 0.1374@764 高于真实峰，勿对其做全谱峰搜） |
| 绿屏 CF_G | `assets/builtin_cf_g.json` | 实测，峰 0.1071@527nm |

> 资产引用方式：KSF 红谱与 InGaN 模板用 `include_str!` 相对路径引用**原工程文件**（单一数据源）；
> 三份 CF 屏谱为本工程自有资产。替换资产 = 保持 `{name, description, wavelengths, intensities}` 四键 JSON 结构。

### 3.2 依赖库 API 速查（已核对源码）

- **spectrum-core**（ingan）：`BaselineSpectrum::from_json_str` → `validate` → `PreparedTemplate::prepare(&to_template_data())` → `InGanBlueV1Model::new` → `predict(&SpectrumRequest::new(峰值, 电流))` → `SpectrumResult.spectrum`（401 点，峰值归一化；峰值范围 440–540、电流 1–500，<20mA 有警告）。
- **spectrum-synthesizer**：`Spectrum::from_values(vec![…;401])`；`Coefficients::new(a..f)`（非负校验）；`synthesize(&[Spectrum], &Coefficients) → SynthesisReport{raw, max, normalized}`。
- **spectrum-colorimeter**：`cie::{compute_xyz, xyz_to_xy, observer_1nm}`；`gamut::{NTSC_1953, BT_2020, coverage_both, convex_hull_area, Triangle}`；本工程新增 `channels::analyze_channels`（见 §4）。
- **spectrum-checker**：`judge_text(&json, &CheckConfig) → Report`，JSON 兼容 synthesizer 导出格式（`{"wavelengths":[…401 整数…], "spectrum":[…]}`）。

### 3.3 基准数值（2026-09-09 手算，作为集成测试断言基准）

B460/G530/KSF 红各自归一化过 CF（CMF 与 cie.rs 同源）：

| 点 | 光谱 | 峰值 | xy |
|---|---|---|---|
| B1 | B×CF_B | 0.086573@460 | (0.1383, 0.0425) |
| G1 | G×CF_G | 0.106016@530 | (0.1994, 0.7569) |
| R1 | R×CF_R | 0.116696@630 | (0.6934, 0.3028) |
| B2 | R×CF_B | 0.007546@444 | (0.1537, 0.0251) |

三点三角形面积 0.190351；加 B2 后凸包 0.197162（**B2 在三角形外，四点色域扩展 ≈ +3.6%**）。
参考覆盖率（面积口径）：三点 NTSC ≈120.3%、BT.2020 ≈89.8%。

## 4. 数据流与算法

```
蓝峰值/绿峰值/电流 ──► ingan 生成 B、G（401 点，峰值归一化）
内置 KSF 红 R ────────┐
                      ▼
        三通道各自 max 归一化（口径 2）
                      ▼
  synthesizer：raw = a·B + b·G + c·R → max 归一化 = 白光光谱
                      ▼
  白点寻优（不过 CF，口径 8）：坐标下降
    - 目标 (0.27, 0.26) ± 0.005，区域内即停（口径 4）
    - 每轮：固定 (a,b) 一维搜索 c 打 x；固定 (a,c) 一维搜索 b 打 y；交替 2–3 轮
    - 约束 a,b,c ≥ 0.01；无解仅报错；迭代上限 50 次目标函数评估
                      ▼
  colorimeter/channels：B×CF_B / G×CF_G / R×CF_R → 三点
    R 通道归一化蓝峰(420–500) > 0.1 → 加 B2 = R×CF_B → 四点凸包
    输出：NTSC / BT.2020 三点 + 四点覆盖率
                      ▼
  checker：白光光谱 JSON → 四项判定 ✓/✗
                      ▼
  输出：白光光谱、最终占比、白点 xy、四点色度、覆盖率、判定报告
```

## 5. 阶段规划

- **阶段 1 ✅——核心计算库**：
  1. colorimeter 新增 `channels::analyze_channels(B, G, R, CF_R, CF_G, CF_B, white: Option<&[f64]>)`；
  2. 本工程 lib：`assets`（资产内嵌校验）、`generate`（ingan 封装）、`optimize`（坐标下降）、`pipeline`（全链路）、`error`；
  3. 端到端测试：以 §3.3 数值为断言基准。
- **阶段 2 ✅——egui 总控界面**（eframe/egui 0.29 + egui_plot 0.29 + rfd 0.15）：
  - bin 目标 `ksf-white-studio`（src/main.rs + src/app.rs）；
  - 参数区（蓝/绿峰值 440–540、电流 1–500、自动寻优/手动占比切换）；
  - 白光光谱图（可叠加 B/G/R 通道曲线）+ CIE 色度图（光谱轨迹+紫线、NTSC/BT.2020 参考三角形、
    本方案色域折线、B1/G1/R1/B2 色点、白点标记），坐标固定不可缩放拖动；
  - 结果面板（份额、白点 xy、命中标记、触发比、三点/四点覆盖率、扩展百分比、四项 ✓/✗）；
  - 1 秒防抖后台线程重算（channel 回传）；红谱与三份 CF 导入替换（rfd 对话框、四键 JSON 校验）；
  - 白光 JSON 导出（rfd 保存对话框，含光谱/份额/色点/覆盖率/判定）。
- **阶段 3 ✅——Agent API + 中文字体 + 发布打包**：
  - `api::run_json(input_json) -> String`：Agent 直调入口，输入字段全可缺省（缺省 B460/G530/20mA/自动/内置），
    输出恒为 UTF-8 JSON：成功 `{"ok":true,"api_version":"1.0","report":{…全量结果…}}`，
    失败 `{"ok":false,"error":"…"}`（不 panic；exit code 0/1）；
  - CLI：`ksf-white-studio.exe --json [内联JSON] [--input 文件] [--output 文件]`（release 下 AttachConsole）；
  - GUI 中文支持：启动时注入系统 CJK 字体（msyh/simhei/Deng/simsun/simkai 优先级），
    全部中文以 UTF-8 正常渲染；导出/输出文件均为 UTF-8；
  - 发布包 `dist/ksf-white-studio/`：ksf-white-studio.exe（单体）+ 使用说明.txt +
    示例输入/输出.json；**已在工程无关位置实测独立运行**（GUI + API，加载模块
    除 Windows 系统组件外无任何外部依赖，可整文件夹拷走即用）；
  - 另有要求2旧口径版本 `dist/ksf-white-studio_蓝峰±20nm/`（同一 exe 的 ±20nm 构建，
    与主版唯一区别，源码默认值仍为 ±10nm，见该文件夹 版本说明.txt）；
    release GUI 与 API 均冒烟验证通过；
  - .gitignore、编译告警清零。

## 6. Agent JSON API 速查

```text
ksf-white-studio.exe --json '{"blue_peak_nm":448,"green_peak_nm":530,"current_ma":20}'
ksf-white-studio.exe --json --input in.json --output out.json
echo {} | ksf-white-studio.exe --json        # 空对象 = 全默认（B460/G530/20mA/自动/内置资产）
```

输入字段（均可缺省）：`blue_peak_nm`、`green_peak_nm`、`current_ma`、
`mode`（"auto" 或 {"manual":[B,G,R]}）、`overrides`（red/cf_r/cf_g/cf_b 数组）、
`target`（{"x":0.27,"y":0.26,"tolerance":0.005}，**目标白点可键入调整**）。
输出：`report` 含 blue/green 通道（含警告）、三条归一化通道谱、white_spectrum（401 点）、
shares、white_xy、target（本次目标）、target_hit、channels（B1/G1/R1/B2 光谱+xy、coverage_three/four、quad_effect）、
check（四项判定+metrics+notes）。库调用入口：`spectrum_white_studio::run_json`。

## 7. 构建约定

- K 盘 cargo 锁会间歇性 EACCES：构建一律 `CARGO_TARGET_DIR=C:\Users\NS\.workbuddy\cargo-target\white-studio`（**Windows 风格路径**，POSIX `/c/...` 会被 cargo 拼成 `K:\c\...`）。
- 本工程已通过 `.cargo/config.toml` 关闭增量编译（规避 os error 5 缓存复制告警）；报 os error 5 时先杀残留 cargo/rustc 进程。
- serde_json 必须 `features = ["float_roundtrip"]`。
- 阶段 2 起 bin 目标为 `ksf-white-studio`（src/main.rs + src/app.rs）；示例：`cargo run --example quick_report`。
- 快速验证：`cargo run --example quick_report`（全链路数值报告）；
  API 冒烟：`ksf-white-studio.exe --json '{}' --output out.json`。
