# キャリブレーション検証履歴 (Calibration Verification History)

本ドキュメントは MiniTIAS 実機（baseline 1 枚 `MiniTIAS_20260408_144434`）に対するシミュレーション結果の **キャリブレーション** と **検証イテレーション** を時系列で記録する．

目的:

- 「どの仮説で何を変え，何が起きたか」を残し，**後から経緯を辿れる**ようにする．
- **失敗・予想外も同等に記録**し，方向性のドリフトと「うろ覚えで同じ仮説を試し直す」事態を防ぐ．
- 各イテレーションの **学び** を明示し，次の意思決定の根拠を蓄積する．

関連ドキュメント:

- 現状の物理仕様: [SPEC_03_基準設計の物理構成](../04_SPEC/SPEC_03_基準設計の物理構成.md)
- 開発ステップ全体: [PLAN_02_開発ステップ](../03_PLAN/PLAN_02_開発ステップ.md)
- 実測リファレンス: `reference_measurement/MiniTIAS_20260408_144434/`

## 実測ターゲット (Measurement Target)

baseline 1 枚（`MiniTIAS_20260408_144434`，ROI 1400×1409，sRGB 符号化済み Y' luma）:

| 指標 | 値 |
| --- | --- |
| mean | 146.71 |
| CoV | 0.0427 |
| 勾配 % | 6.10 |
| 中心/周辺比 (C/P) | 1.0650 |
| std | 6.26 |
| max/min 比 | 1.392 |

評価は `sm-evaluate` で実施．シミュ側の比較は OETF 順方向適用後（Step 8-3 以降）に sRGB ドメインで行うのが正式．linear ドメイン比較は Step 8-3 以前または同一条件シミュ間の検証用．

## 俯瞰サマリ (Overall Progression)

時系列での主要指標推移．**残差倍率** = (シミュ - 実測) / (初期残差 - 実測) として「初期からどれだけ縮まったか」を見る．

| Step | 設定 | 空間 | mean | CoV | 勾配% | C/P | CoV 残差倍率 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 実測 TARGET | — | sRGB | 146.71 | 0.0427 | 6.10 | 1.065 | 1.0× |
| 8-1 spp=128 | R0.85, d8, linear | linear | 151.79 | 0.236 | 24.83 | 1.330 | 5.5× |
| 8-1 spp=1024 (基準確定) | R0.85, d8, linear | linear | 152.02 | 0.183 | 24.72 | 1.328 | 4.3× |
| 8-2 R=0.92 sweep | R0.92, d12, linear | linear | — | 0.170 | 19.42 | 1.241 | 4.0× |
| 8-3 OETF 適用 | R0.85, d8, spp1024 | **sRGB** | 146.71* | **0.089** | **12.57** | **1.144** | **2.1×** |
| 8-3 OETF + R=0.92 + d=12 | R0.92, d12 | sRGB | 146.71* | 0.081 | 9.72 | 1.108 | 1.9× |
| 8-7 size 1.5×1.5 (Φe 保存) | linear, R0.85, d8 | linear | 429.99 | 0.186 | 26.21 | 1.355 | (形状指標 ≈ 8-1) |

\* mean アンカー固定．R, d, spp は `reflectance`, `max_depth`, `samples_per_pixel`．

最大の跳躍は **8-3 OETF（残差 4.3× → 2.1×）**．現時点の確定基準は **R=0.85, d=8, spp=1024, OETF=on** で残差 2.1×．残る 1.6〜1.9× の残差は **LSC（ISP レンズシェーディング補正）** が主因候補（未対処，[Step 8-N 候補](#step-8-n-候補-lsc-順方向モデル未着手) 参照）．

## イテレーション履歴 (Iteration Log)

### Step 8-1: spp 校正 (128 → 1024)

- **日付**: 2026-05-18
- **背景・問題意識**: 初期シミュ（spp=128）と実測の差が CoV 0.236 vs 0.0427 ≈ **5.5 倍** と大きすぎる．これは MC ノイズなのか，物理モデルの構造的勾配なのか，**切り分けないと方向性が定まらない**．
- **仮説（物理動機）**: モンテカルロノイズは `1/√spp` で減衰する独立成分．一方，物理由来の空間勾配は spp 非依存．spp を 8 倍にすればノイズ成分の寄与が `1/√8 ≈ 35%` に減るので，残った差が「物理」だと確定できる．
- **試した変更**: `configs/scene_baseline.yaml` の `render.spp` を 128 → 1024（8 倍）．他は据え置き．
- **期待した効果**: ノイズ系指標（max/min, std, CoV の量子化的外れ値成分）は減少．勾配や中心/周辺比は spp 非依存なら不変．
- **実際の結果**:

  | 指標 | spp=128 | spp=1024 | 動いた量 |
  | --- | --- | --- | --- |
  | CoV | 0.236 | 0.183 | -22% |
  | std | 35.83 | 27.85 | -22% |
  | max/min 比 | 11.59 | 4.27 | **-63%**（極端な外れ値が消えた） |
  | mean | 151.79 | 152.02 | ≈ 不変 |
  | 中心/周辺比 | 1.330 | 1.328 | ≈ 不変 |
  | 勾配 % | 24.83 | 24.72 | ≈ 不変 |

- **解釈**: max/min, std, CoV はノイズ由来成分を含んで動いた．中心/周辺比と勾配 % は spp 非依存 → **物理由来の構造的勾配**．ノイズ分解 `std² = 信号² + ノイズ²`，`ノイズ ∝ 1/√spp` で逆算すると spp=1024 の残留ノイズ std ≈ 8.5，真の物理信号 std ≈ 26.5．**spp→∞（ノイズゼロ）でも CoV は ≈ 0.174 までしか下がらない**（実測 0.0427 の約 4 倍）．
- **学び**: spp を増やしても CoV は 0.183 → 0.174 程度で頭打ち．**spp 増加は費用対効果なし**．残差 4.3× は物理モデル要因と確定．spp=1024 を基準として確定．
- **次のアクション**: 物理モデル側を疑う．最も効きそうな反射率を振る → [Step 8-2](#step-8-2-反射率スイープ-r075092) へ．

### Step 8-2: 反射率スイープ (R=0.75〜0.92)

- **日付**: 2026-05-18
- **背景・問題意識**: 8-1 で「物理モデル要因」と確定．MiniTIAS は白筐体内壁の多重反射で照明を均一化する設計なので，**内壁反射率**が直接効くはず．暫定 0.85 が低めの可能性．
- **仮説（物理動機）**: 反射率↑ → 多重反射光（より均一な ambient 成分）↑ → 評価板全体が均一に近づく．インテグレーティングスフィア近似 `1/(1-R)` で R=0.85 → 0.92 で実効反射が 6.7 → 12.5（+88%）．
- **試した変更**: `materials.printer_white.reflectance` を 0.75, 0.80, 0.85（基準）, 0.90, 0.92 の 5 点で振る．spp=256, depth=12, linear ドメイン評価．
- **期待した効果**: 単調改善．実測 (CoV=0.0427) に近づける R を見つける．
- **実際の結果**:

  | R | CoV | 勾配 % | C/P |
  | --- | --- | --- | --- |
  | 0.75 | 0.2173 | 25.91 | 1.350 |
  | 0.80 | 0.2034 | 24.00 | 1.316 |
  | 0.85（基準） | 0.1893 | 22.08 | 1.283 |
  | 0.90 | 0.1753 | 20.15 | 1.252 |
  | 0.92（マット白プラ実用上限） | 0.1697 | 19.42 | 1.241 |

- **解釈**: 全指標が R に対し単調・線形に改善するが**感度が低い**（∂勾配/∂R ≈ −38 %/単位，linear）．実測 (CoV=0.0427) 到達には外挿で **R ≈ 1.2〜1.4** が必要 ＝ **物理範囲外**．
- **学び**: 反射率は**弱い二次レバー**．これ単独では差を閉じられない．構造的に違う何か（評価方法・座標系・ドメイン）を疑うべき．
- **次のアクション**: もっと大きな自由度を持つレバーを探す．**評価方法自体を疑う** → [Step 8-3](#step-8-3-oetf-順方向適用手法訂正) へ．

### Step 8-3: OETF 順方向適用（手法訂正）

- **日付**: 2026-05-18 頃（コミット `26904da`）
- **背景・問題意識**: 反射率スイープでも残差 4× を解消できない．「シミュ linear と実測 sRGB を直接比較」が成立しているか改めて疑った．実測データ提供側 README にも「シミュを線形のまま比較すると勾配/CoV の絶対値は変わる」と明示されていた（**見落としていた**）．
- **仮説（物理動機）**: 実測 PNG は実機 ISP の **sRGB ガンマ（OETF, IEC 61966-2-1）** が掛かった非線形符号化値（Camera2 `YUV_420_888` → BT.601 は定義上ガンマ済み R'G'B' 上の量）．シミュは linear．**「無次元指標はスケール不変」は線形変換のみ成立**，非線形 OETF 下では成立しない（`Σwᵢ·f(xᵢ) ≠ f(Σwᵢ·xᵢ)`）．OETF を順方向適用してドメインを揃えれば，物理量差ではなく「符号化ドメイン不一致」だった分が消える．
- **試した変更**:
  - `src/sm_tias_lightsim/evaluation/oetf.py` を新規実装（標準 sRGB OETF + 露出ソルバ）．
  - `EvaluationConfig.oetf` スキーマ追加（[SPEC_02 参照](../04_SPEC/SPEC_02_シーン定義仕様.md)）．
  - `sm-evaluate` に統合．ROI 抽出後・指標算出前に OETF を順方向適用．
  - `configs/eval_baseline.yaml` で有効化．`configs/eval_real.yaml` は非適用（実測 PNG への二重適用禁止）．
  - 露出は AE が制御する量＝実測 ROI mean (146.71) に対数二分でアンカー（線形ゲインなので形状指標には自由度を持ち込まない；OETF が非線形なため「曲線上の動作点」を合わせる原理的アンカーとして必須）．
- **期待した効果**: ガンマ非線形性で「同じ物理だが見かけが違う」分が解消，残差が大きく縮む．データに合わせて回す係数はゼロ．
- **実際の結果**:

  | ソース | 空間 | CoV | 勾配 % | C/P |
  | --- | --- | --- | --- | --- |
  | R0.85, d8, spp1024 | linear | 0.183 | 24.65 | 1.327 |
  | 〃 | **sRGB** | **0.089** | **12.57** | **1.144** |
  | R0.85, d12, spp256 | sRGB | 0.091 | 11.16 | 1.126 |
  | R0.92, d12, spp256 | sRGB | 0.081 | 9.72 | 1.108 |
  | **実測 TARGET** | sRGB | **0.0427** | **6.10** | **1.0650** |

  - CoV 0.183 → 0.089（残差 4.3× → 2.1×，**67% 解消**）
  - 勾配 24.65 → 12.57（残差差 18.6 → 6.5，**65% 解消**）
- **解釈**: **見かけ差の約 2/3 が符号化ドメイン不一致**だったと判明．無彩色シーンでは「linear RGB → チャネル別 OETF → Rec.709 加重和」と「luminance 直接 OETF」が厳密一致（Rec.709 重みは合計 1，R=G=B の無彩色画素では `Σwᵢ·f(x) = f(x) = f(x·Σwᵢ)`）．OETF は不整合を作るのではなく **消す操作**．OETF 前のシミュ linear luma と実測 sRGB luma は別ドメインだった．
- **学び**:
  - 寄与順を訂正: **OETF（最大・約 2/3）＞ ISP LSC（残差主因候補）＞ 反射率（弱い）**．旧版「主因は ISP レンズシェーディング (83%)」は OETF を抜かした交絡判断で誤りだった．
  - 「データに合わせて回す係数はゼロ」が成立する標準変換は **overfitting なしで残差を大きく縮められる**．
  - 標準仕様（IEC 61966-2-1, Rec.709）の存在を前提として常に確認すべき．「実機カメラ出力は例外なくガンマ符号化」が標準前提．
- **次のアクション**:
  - OETF 順方向適用を sm-evaluate へ正規実装（コミット `26904da`）．
  - 残差 1.6〜1.9× は LSC で対処予定（[Step 8-N](#step-8-n-候補-lsc-順方向モデル未着手) 未着手）．**残差はガンマ曲線いじりで消さず正直に保持**．

### Step 8-4: max_depth 検証 (8 → 12)

- **日付**: 2026-05-18 頃
- **背景・問題意識**: `max_depth=8` で打ち切ると `0.85^8 ≈ 27%` のエネルギーが「未追跡」のまま残る．均一化に効く **後段多重反射** を取りこぼしている可能性．
- **仮説（物理動機）**: 後段反射光は「均一な ambient 成分」（部屋の壁が消灯後も薄明るく見える理屈，閉じた拡散面でのインテグレーティングスフィア応答）．これを取りこぼすと勾配が **系統的に過大評価** される．
- **試した変更**: 同条件で `render.max_depth` を 8 と 12 で比較レンダ．
- **期待した効果**: depth↑ で勾配 ↓．
- **実際の結果**: 同一 R=0.85, spp=1024 で
  - 勾配 (linear): 24.65 → 22.08 = **-2.6 pt**
  - 勾配 (sRGB): 12.57 → 11.16 = **-1.4 pt**
  - CoV (sRGB, R0.85): 0.089 → 0.091（誤差レベル，方向は spp ノイズに埋もれる）
- **解釈**: depth=8 は系統的に勾配を **過大評価**．エネルギー 27% 未追跡分のうち均一寄与分が効いていた．
- **学び**:
  - **キャリブ用途は depth≥12 推奨**．
  - レンダコスト ~1.5× になるので，確定 `configs/scene_baseline.yaml` の `render.max_depth` は **現状 8 のまま**（既知差分 #8）．
  - 3D ベイクは可視化用途で **均一性をなるべく忠実に**見せたいので，`--bake-max-depth 16` で render 設定から独立化（コミット `a0fe07d`）．**「2D 校正都合」と「3D 可視化忠実性」を分離**．
- **次のアクション**: 確定 YAML の depth 変更は保留．3D ベイクのみ独立化で適用．

### Step 8-5: 3D 可視化改善（path ベイク・テクスチャ投影・幾何カリング etc.）

- **日付**: 2026-05-18 〜 2026-05-XX（コミット `7181efa`, `c32ccd6`, `a0fe07d`）
- **背景・問題意識**: 内部キャリブ調整は 8-3 までで頭打ち感．並行して **シミュ結果の「見せ方」**（3D ビュー）が分かりにくい問題が浮上．特に「評価板はテクスチャ投影で正確，壁は per-vertex ベイクで荒い」という **手法非対称** が，物理判断の混乱を生んでいた．
- **仮説（物理動機，複数）**:
  - per-vertex ベイク（直接光 + cos） → **path ベイク（多重反射込み per-face MC）** にすれば物理的に正確になる．
  - 評価板・壁・カバーをすべて同じ手法（path ベイク）で計算し，**共有 clim・統一着色** で見せれば，相対比較が物理に基づく．
  - 隣接内壁の「見かけ 100 倍段差」は物理ではなく，**法線が外を向く「外向き面（≈ 0 入射）」の混在** が主因では？
- **試した変更**:
  - `src/sm_tias_lightsim/visualize/baker.py` に `mode="path"`（scalar_rgb，コサイン重点 hemisphere MC，多重反射込み per-face 照度）追加．`exclude_mesh_ids` 対応．`max_depth` 引数で render 設定から独立．
  - `src/sm_tias_lightsim/visualize/viewer.py` 全メッシュ統一着色（共有 lit-clim・log/linear・単一カラーバー・viridis・depth peeling）を既定化．
  - `--render <luminance.npy>` で評価板への任意テクスチャ投影（E = π · L / ρ で壁と同一 W/m² スケール）．
  - `--bake-cache <npz>` で 1 回計算 → 以後即時．
  - `--cull-outward`（既定 ON）で外向き ≈ 0 面を非描画．
  - `--bake-max-depth`（既定 16）で render 設定から独立．
  - `--no-sensor-marker` / `--no-led-markers` / `--no-markers` でマーカー個別非表示．
- **期待した効果**: 評価板も壁も多重反射込みで正しく着色，共有 clim で物理どおりの相対比較が可能になる．外向き面除外で「暗殻の濁り」「見かけ段差」が消える．
- **実際の結果**:
  - 評価板を path ベイクで多重反射込み着色．壁・カバーとも統一 clim でほぼ均一に見える（物理どおり）．
  - 外向き面除外で「隣接内壁の見かけ 100 倍段差」が解消．内壁照度自体は同一手法ベイクで ~1〜2 倍以内 ＝ **物理どおりほぼ均一**だった．
  - 一方，per-face MC ベイク特有の **シーム/粒状感/scalar_rgb の遅さ**（高 samples 非現実的）は残る．
- **解釈**:
  - 「見え方の問題」と「物理の問題」を **厳格に分離**: 同一手法で計算すれば物理は均一．見かけ段差は **手法非対称**（評価板＝テクスチャ・壁＝ベイク）と **外向き面の混入** で説明できた．
  - per-face MC ベイクの原理的天井（粒状感・継ぎ目）は **対症療法で消えない**．
- **学び**:
  - **物理量と計算手法の対称性を常に問う**: 同じ物理量を異なる手法で計算してはいけない．
  - **見え方 ≠ 物理**: 見かけ 100 倍段差が出ても，同手法で再計算すれば 1〜2 倍以内なら物理は均一．
  - per-face シーム/粒状感の解消は **全メッシュ UV 統合シームレスライトマップベイク** が必要 ＝ 別プロジェクト規模．
- **次のアクション**:
  - 精細な評価は引き続き 2D `sm-render`/`sm-evaluate`（path tracer）で（**校正済みの定量結果**，不変）．
  - シーム解消は別タスク（必要時に `/implement`）．
  - path ベイク高速化（wavefront/GPU 化）も別タスク．

### Step 8-6: LED 物性確定 (LP-2835D90VW)

- **日付**: 2026-05-27（コミット `f5048a4`）
- **背景・問題意識**: SPEC_03 既知差分 #3「LED 1 個あたりの実 W 値が未検証」を残していた．現状 `radiance=2807.247` は実測 mean アンカーで決まった校正値で，**規格値からの導出ではない**．LED 物性が確定すれば，独立に検証できる．
- **仮説（物理動機）**: 規格値から radiance を独立推定し，現校正値と並べる．大きく合えば **物理妥当性の担保**，合わなければ何かのレバーの不確かさを炙り出せる（縮退の所在が分かる）．
- **試した変更**: LED Paradise 商品ページから物性取得．SPEC_03 LED セクションを拡張．
  - 型番: **LP-2835D90VW**（Ra98 SunLightLED 2835 チップ LED 4000K）
  - 電気: Vf 3.1 V (typ), If 60 mA (max)，駆動条件は **規格通り 60 mA フル**（ユーザー確認）
  - 光学: Φv 16–19 lm @ 60 mA（中央値 17.5 lm），配光角 120°（半値全幅，Lambertian と整合），Ra 98，色温度 4000 K
  - 詳細 IES プロファイル：**未提供**（LED Paradise は公開せず）
- **期待した効果**: 校正値 2807 と規格推定が大きく合うか，どこに不確かさが残るかを明確化．
- **実際の結果**: 規格値から radiance を独立計算

  | ステップ | 値 |
  | --- | --- |
  | Φv（typ 中央値） | 17.5 lm |
  | LER（4000K Ra98 典型値） | ≈ 280 lm/W |
  | Φe = Φv / LER | **0.0625 W** |
  | A = 2.8 × 3.5 mm | 9.8 × 10⁻⁶ m² |
  | **規格推定 L = Φe / (A·π)** | **≈ 2030 W/(m²·sr)** |
  | 現状校正値 | 2807 W/(m²·sr) |
  | **比** | **1.38×** |

  - サニティチェック: ウォールプラグ効率 = Φe / (Vf·If) = 0.0625 / 0.186 ≈ **33.6%**（実用 LED として妥当範囲，Cree 等で 40%・廉価品で 25–30%）．
  - integrating sphere 近似で 1.38× を反射率に帰着: R=0.85 → 0.89 で `(1-0.85)/(1-0.89) = 1.36×`（観測 1.38× とほぼ一致）．R=0.89 はマット白プラ実用上限 0.92 の範囲内．
- **解釈**:
  - **規格 → radiance の換算は物理的に整合**（桁・係数とも）．
  - 校正値が 1.38× 高い差分は **反射率の不確かさに帰着可能**（物理範囲内 R≈0.89 で説明可）．LED 側が大きくおかしいわけではない．
  - 形状指標への影響なし（線形ゲイン）．
- **学び**:
  - 物理レバーを 1 個ずつ独立化する作業は，絶対値が動かなくても **不確かさの所在を局所化する** 価値がある．
  - 既知差分 #3 をクローズ（LED 物性確定・物理整合確認済み）．残課題は反射率の実フィラメント分光データでの再校正（既知差分 #1）に帰着．
  - 配光は「データシート記載が配光角 120° のみ，IES 未提供」．Lambertian 仮定は数学的に整合だが厳密検証は不可．実 SMD 2835 はやや前方凸の可能性があり ISP LSC と打ち消し合う近似として現状妥当．
- **次のアクション**: 次は LED 周辺幾何の検証（発光面サイズの妥当性）→ [Step 8-7](#step-8-7-発光面サイズ検証-2835-vs-1515φe-保存) へ．

### Step 8-7: 発光面サイズ検証 (2.8×3.5 vs 1.5×1.5，Φe 保存)

- **日付**: 2026-05-27
- **背景・問題意識**: 「現実装はパッケージ外形 2.8 × 3.5 mm を発光面として使う」仮定が物理的に正しいか疑問．実 SMD 2835 の真の発光部は **チップ + 蛍光体 ~1.5 × 1.5 mm**（パッケージ面積の ~23%）のみで，周りは白プラスチック筐体（光らない）．
- **仮説（物理動機，複数）**:
  - 評価板まで 65 mm vs 発光面 ~1.5〜2.8 mm → distance/size ≈ 25〜40 で **遠方界点光源近似**が成立．形状指標は発光面サイズに不変のはず．
  - 絶対値（mean）は校正で吸収済みなので変化しないはず．
- **試した変更**: `configs/scene_baseline_emitter_real.yaml` を Python ワンライナーで自動生成．
  - 全 18 LED の `size`: [2.8, 3.5] → [1.5, 1.5] mm
  - 全 18 LED の `radiance`: 2807.247 → **12227.12** W/(m²·sr)（スケール係数 4.356 = 元面積 / 新面積）
  - **Φe = L · A · π は厳密に保存**（0.0864 W per LED で同一）．
  - linear ドメインで `sm-evaluate` 比較（OETF 経由しない直接比較）．
- **期待した効果**: mean ≈ 不変，CoV/勾配/C/P/max-min/radial profile ≈ 不変（点光源近似が成立する遠方界）．
- **実際の結果**（linear，同条件）:

  | 指標 | 元 (2.8×3.5) | 検証 (1.5×1.5) | 比 | 評価 |
  | --- | --- | --- | --- | --- |
  | mean | 152.52 | 429.99 | **2.82×** | ⚠️ 予想外に大きく変化 |
  | std | 27.85 | 80.12 | 2.88× | mean スケールに比例 |
  | CoV | 0.1826 | 0.1863 | 1.02× | ✅ 形状指標 ≈ 不変 |
  | 勾配 % | 24.65 | 26.21 | 1.06× | ✅ 形状指標 ≈ 不変 |
  | C/P | 1.327 | 1.355 | 1.02× | ✅ 形状指標 ≈ 不変 |
  | max/min | 4.28 | 4.36 | 1.02× | ✅ 形状指標 ≈ 不変 |
  | 放射プロファイル中心/端 | 1.63 | 1.68 | 1.03× | ✅ 形状指標 ≈ 不変 |

  画像保存先: `output/baseline_linear_npy/` と `output/emitter_real/`（各 `figures/luminance_map.png`, `radial_profile.png`, `histogram.png`, `zone_map.png`）．放射プロファイルの曲線形は**目視で瓜二つ**，色スケールのみ違う．
- **追跡調査**: 予想外の 2.83× mean 上昇の機序を STL 幾何分析で追跡．
  - LED 基板カバー（`meshes/LED基板カバー.stl`）は z=-66.6〜-64.1 の 2 階建て構造（天井梁 + 底板）．
  - LED 中心 z=-65.3 は底板 z=-65.5 の上面から **0.2 mm の至近距離**．
  - 底板には LED ごとに **複雑な曲線形の穴**あり（trimesh の euler_number=-4 ＝ genus 3 と整合）．LED は穴の中に位置．
  - 仮説: 厚みゼロの面光源（z=-65.3）と固体（z=-65.5〜-66.6）の **0.2 mm coplanar 状態**で Mitsuba 上に予期しない遮蔽相互作用が起きている可能性．完全機序解明には Mitsuba のレイトレース内部追跡が必要（時間 vs 効果が合わないので深入りせず）．
- **解釈**:
  - **形状指標**については仮説（点光源近似）が **実証成立**: CoV/勾配/C/P/max-min/radial profile すべて 1〜6% 以内（spp=1024 の MC ノイズ範囲程度）．
  - **絶対値**については仮説が **不成立**: mean が 2.83× も動いた．発光面サイズと **LED 周辺幾何（カバー）の縮退**で，両者は分離できない．
  - 校正値 2807 は「2.8 × 3.5 mm 発光面 + 現カバー幾何」の組み合わせで決まる縮退値．発光面サイズだけ変えると mean が大きく動くが，それを校正で吸収させれば形状指標は変わらない．
- **学び**:
  - 「点光源近似で発光面サイズは結果に効かない」は **不完全な命題**：**形状指標**については成立，**絶対値**については局所幾何との縮退で不成立．
  - 現実装は「発光面が物理的には不正確（パッケージ外形を使用）」だが，**シミュ目的（相対分布評価）の妥当性は守られている**．
  - 厚みゼロ面光源と固体の coplanar/near-coplanar 配置は，**Mitsuba 上での挙動が直感に反する**ことがある．将来 LED 周辺幾何（カバー設計）を変更する場合は，発光面サイズも同時に見直す必要がある．
  - 完全機序解明より「**確認できた事実を正直に記録**」を優先する判断は，時間 vs 効果のトレードオフで妥当．
- **次のアクション**:
  - SPEC_03 LED セクションに「発光面サイズの近似と検証」記述を追加（本ドキュメント完成後）．
  - 検証用ファイル `configs/scene_baseline_emitter_real.yaml`, `configs/eval_baseline_linear.yaml`, `output/emitter_real/`, `output/baseline_linear_npy/` は **検証アーティファクト**として保持（後から再現できるように）．
  - 本筋 LSC モデル化（[Step 8-N](#step-8-n-候補-lsc-順方向モデル未着手)）に進む．

## Step 8-N 候補: LSC 順方向モデル（未着手）

- **位置付け**: 8-3 OETF 適用後の残差 **1.6〜1.9×**（CoV 0.089 vs 実測 0.043，勾配 12.57 vs 6.10）の **主因候補**．
- **仮説（物理動機）**: 実測 PNG は実機 ISP の **レンズシェーディング補正**（周辺光量低下の電子補正）が掛かっており，**周辺を持ち上げて中央を相対的に押し下げる**．これは残差の符号（シミュ側の方が勾配・C/P が大きい）と整合．シミュ側で同じ補正を順方向に適用すれば消える可能性が高い．
- **設計方針**: **overfitting 回避**のため，自由多項式ではなく **物理動機づけ低自由度形** に限定する．
  - cos⁴ 則（典型的なレンズ周辺減光則）をベースに，平滑な動径多項式 2〜3 パラメータ
  - 適用順: ROI 抽出後・OETF 順方向適用の **後段** にフックを追加するのが筋（実機 ISP の処理順と整合）
  - パラメータ推定は実測 1 枚での fit ではなく，**物理パラメータ（センサ位置・レンズ F 値・撮像距離）から導出**できる範囲で
- **未確定事項**:
  - 実機カメラ（SH-02M）の正確なレンズ仕様（F 値，焦点距離）
  - ISP のレンズシェーディング補正テーブルの直接取得は不可（メーカー独自）
  - スマホ独自トーンマップ（残差の一部，さらに不確実）も同時に推定するか分離するか
- **想定される結果**:
  - 残差が 1.6〜1.9× → **1.0〜1.2×** まで縮まる可能性
  - 残らない場合: スマホ独自トーンマップ・反射率の実フィラメント精緻化・LED 配光詳細化 などへ
- **要する作業量**: コード（`evaluation/lsc.py` 新規・eval スキーマ拡張・テスト）＋ パラメータ推定（実機写真からの動径フィット）で 1〜2 日相当．

## 改善ストーリーの要約 (Takeaways)

イテレーション全体を俯瞰したときに残る**判断指針**:

- **MC ノイズ vs 物理勾配の切り分けは spp スイープが安価で有効**（8-1）．これを早期に行うとその後の方向性が決まる．
- **弱いレバーで攻めて手詰まりになったら，「評価方法そのもの」を疑う**（8-2 → 8-3）．非線形変換下では無次元指標は不変ではない．
- **標準仕様（OETF, Rec.709 等）の見落としは最大の交絡源になりうる**（8-3）．データに合わせて回す係数ゼロで残差の 2/3 を消した事例．
- **「校正都合」と「物理忠実性」を独立パラメータで分離する**（8-4 max_depth 独立化，8-5 path ベイク独立化）．校正に最適な depth と可視化に最適な depth は違って良い．
- **同じ物理量を異なる手法で計算しない**（8-5）．手法非対称は混乱の源．
- **物理レバーは 1 個ずつ独立化する**．絶対値が動かなくても **不確かさの所在を局所化** する価値がある（8-6 LED 物性，8-7 発光面サイズ）．
- **予想外の結果は仮説より雄弁**．完全機序解明より「確認できた事実を正直に記録」を優先（8-7）．
- **形状指標と絶対値は別物**として扱う．多くのレバーは形状指標には不変（線形ゲイン）だが，絶対値は局所幾何との縮退で動きうる．
- **失敗・予想外の記録は学びの宝庫**．方向性ドリフトを防ぐ核は「失敗を消さずに残す」こと．

## 輝度マップ形状の追跡 (→ TEST_03)

数値指標と独立に **輝度マップの「形」** を実機に近づける観点は [TEST_03_輝度マップ形状追跡](TEST_03_輝度マップ形状追跡.md) に独立化した．要点のみ:

- これまで実施した 7 つの改善ステップ (8-1〜8-7) は **すべて「形を変えない変更」** だった（線形ゲイン・単調変換・局所幾何依存のいずれか）．シミュは初期から **Y 軸単調勾配**のままで，実機の **中央付近ピーク**には近づいていない．
- 実機の形 = シミュの Y 軸勾配 + カメラ系の動径補正．**LSC モデル化（[Step 8-N 候補](#step-8-n-候補-lsc-順方向モデル未着手)）は数値残差縮小だけでなく形の構造的改善を担う**．
- 以後の改善判断は **「数値 + 形」の 2 軸** で行う．

比較パネル・観察事実・物理的解釈の詳細は TEST_03 参照．

## 参照 (References)

- [SPEC_03_基準設計の物理構成](../04_SPEC/SPEC_03_基準設計の物理構成.md)
- [SPEC_04_評価仕様](../04_SPEC/SPEC_04_評価仕様.md)（評価パイプライン・ROI・OETF・メトリクス・可視化の方法論）
- [SPEC_02_シーン定義仕様](../04_SPEC/SPEC_02_シーン定義仕様.md)
- [PLAN_02_開発ステップ](../03_PLAN/PLAN_02_開発ステップ.md)
- [TEST_02_シミュレーション実行記録](TEST_02_シミュレーション実行記録.md)（各 Step に対応する `output/` ディレクトリの索引）
- [TEST_03_輝度マップ形状追跡](TEST_03_輝度マップ形状追跡.md)（数値と独立に「形」を実機に近づける観点）
- 実装エントリ:
  - `src/sm_tias_lightsim/evaluation/oetf.py`（Step 8-3）
  - `src/sm_tias_lightsim/visualize/baker.py`（Step 8-5）
  - `src/sm_tias_lightsim/visualize/viewer.py`（Step 8-5）
- 検証アーティファクト:
  - `configs/scene_baseline_emitter_real.yaml`（Step 8-7）
  - `configs/eval_baseline_linear.yaml`（Step 8-7）
  - `output/emitter_real/`（Step 8-7 検証レンダ）
  - `output/baseline_linear_npy/`（Step 8-7 比較基準）
- 輝度マップ形状の追跡関連は [TEST_03_輝度マップ形状追跡](TEST_03_輝度マップ形状追跡.md) に集約
- 関連コミット: `26904da`（OETF 正規実装），`7181efa` / `c32ccd6` / `a0fe07d`（3D ビュー改善），`f5048a4`（LED 物性反映）
