# 開発ステップ (Development Steps)

## 全体方針 (Overall Policy)

実装は **核計算ロジックから外側に向かって積み上げる**：

1. **数値計算（評価指標）** が先．既知のテストデータで動作する状態を作る
2. **入力スキーマと I/O** を整える
3. **シーン構築 → 最小レンダー** で物理シミュレーションを動かす
4. **CLI として 2 段階パイプラインを完成**
5. **基準設計でキャリブレーション**
6. **設計バリエーションを比較**

各ステップ完了時に [GUIDE_04](../01_GUIDE/GUIDE_04_Git運用ルール.md) に従ってコミット・PR を作成する．`/implement <ステップ>` でコーディング → テスト → リファクタの自動パイプラインを通す．

## ステップ一覧 (Steps)

| Step | 名前 | 成果物 | 依存 |
| --- | --- | --- | --- |
| 1 | 均一性評価モジュールの移植 | `uniformity.py`, `evaluation/zones.py`, `evaluation/radial.py` + テスト | なし |
| 2 | YAML スキーマ定義 | `scene/schema.py` + バリデーションテスト | Step 1 |
| 3 | ジオメトリ層 | `geometry/loader.py`, `geometry/transforms.py` + テスト | Step 2 |
| 4 | シーン構築 + 最小レンダー | `scene/builder.py`, `scene/lights.py`, `scene/materials.py`, `scene/sensors.py`, `render/runner.py`, `render/output.py` | Step 3 |
| 5 | render CLI | `cli/render.py` + 統合テスト | Step 4 |
| 6 | evaluate CLI + 可視化 | `cli/evaluate.py`, `evaluation/roi.py`, `evaluation/visualize.py` | Step 1, 5 |
| 7 | 基準設計のキャリブレーション | `configs/scene_baseline.yaml`, `configs/meshes/*.stl`, キャリブ報告 | Step 5, 6 |
| 8 | 設計バリエーション比較 | バリエーション YAML 複数 + 比較レポート | Step 7 |

## 各ステップの詳細

### Step 1: 均一性評価モジュールの移植

- **目的**: 評価ロジックを最初に確定．ステップ 7 で「実測との比較」をするための物差しを先に作る
- **やること**:
  - `MiniTias-Evaluation/src/uniformity.py` を `src/sm_tias_lightsim/uniformity.py` にコピー
  - 元の SHA を docstring に明記（取得元: `https://github.com/rintoHasegawa/MiniTias-Evaluation`）
  - `evaluation/zones.py`：3 ゾーン分析（中心 d<0.33 / 中間 / 周辺 d≥0.66）
  - `evaluation/radial.py`：放射状プロファイル
  - テスト：合成輝度マップ（既知の CoV）に対して期待値が出ること
- **完了条件**: `uv run pytest tests/test_uniformity.py` が通る

### Step 2: YAML スキーマ定義

- **目的**: 設計ファイルの形式を確定し，不正入力を早期に弾く
- **やること**:
  - 依存追加: `uv add pydantic pyyaml`
  - `scene/schema.py`：[SPEC_02_シーン定義仕様](../04_SPEC/SPEC_02_シーン定義仕様.md) のトップレベル構造を Pydantic モデルで定義
  - 参照整合性チェック（meshes が存在しない materials を参照していないか等）
  - YAML loader（PyYAML）でファイル → dict → Pydantic model
  - テスト：正常 YAML がパースできる／不正 YAML が `ValidationError` を投げる
- **完了条件**: 各種異常系（必須欠落・型違反・参照不整合）でテストが通る

### Step 3: ジオメトリ層

- **目的**: STL を Mitsuba が扱える単位・座標系で読めるようにする
- **やること**:
  - `geometry/loader.py`：trimesh で STL 読込．頂点・面・単位タグを保持
  - `geometry/transforms.py`：mm → m 変換等
  - テスト：単位変換が可逆／簡単な四面体 STL を読み頂点数が一致する
- **完了条件**: テストフィクスチャの STL が正しく読める

### Step 4: シーン構築 + 最小レンダー

- **目的**: 実物のシミュレーションが動く最小構成を作る
- **やること**:
  - `scene/lights.py`：YAML 光源定義 → Mitsuba emitter
  - `scene/materials.py`：YAML 材料 → Mitsuba BSDF
  - `scene/sensors.py`：YAML センサ → Mitsuba sensor
  - `scene/builder.py`：上記を統合．YAML 全体 → Mitsuba scene dict
  - `render/runner.py`：variant 設定 + `mi.render` 実行．輝度配列を返す
  - `render/output.py`：HDR 配列 → PNG / `luminance.npy` 出力
  - 最小シーン（1 LED + 白板 + センサ）でレンダリングが成功すること
  - テスト：scene dict 構造の正しさ，最小レンダーの smoke test（`@pytest.mark.slow`）
- **完了条件**: 64×64 程度の合成シーンを最後までレンダリングできる

### Step 5: render CLI

- **目的**: コマンドラインから 1 行でシミュレーションを動かす
- **やること**:
  - `cli/render.py`：`sm-render --scene <yaml> --output <dir>` を実装
  - `pyproject.toml` の `[project.scripts]` に登録（`sm-render = "sm_tias_lightsim.cli.render:main"`）
  - テスト: 1 LED + 白板の最小シーン YAML から PNG が生成されること
- **完了条件**: `uv run sm-render --scene tests/fixtures/minimal.yaml --output /tmp/test/` が動く

### Step 6: evaluate CLI + 可視化

- **目的**: シミュ画像と実測画像の両方に同じ評価コマンドを使える状態にする
- **やること**:
  - `evaluation/roi.py`：`image_pixel` 型 ROI 抽出（最初は矩形のみ．`scene_face` は後回し可）
  - `evaluation/visualize.py`：輝度マップ / ヒストグラム / 放射プロファイル / ゾーンマップを matplotlib で出力
  - `cli/evaluate.py`：`sm-evaluate --image <png> --config <yaml> --output <dir>` を実装
  - テスト: 実測 PNG（MiniTias-Evaluation サンプル）と既知の指標値が一致すること
- **完了条件**: シミュ PNG と実測 PNG の両方で同じ指標 CSV が出る

### Step 7: 基準設計のキャリブレーション

- **目的**: シミュレーションの妥当性を実測値で検証．以降の改良案の基準を作る
- **やること**:
  - 現行 MiniTIAS のジオメトリを Fusion 360 から STL でエクスポート
  - LED の配置（位置・向き・個数）を `configs/scene_baseline.yaml` に記述
  - 材料パラメータの初期値を仮置き（ディフューザー透過率・筐体内壁反射率）
  - `sm-render → sm-evaluate` で指標を算出
  - 実測値（CoV ≈ 0.0426, 中心/周辺比 ≈ 1.064, 勾配 ≈ 6%）と比較
  - 差分が大きい場合は SPEC_01 の「キャリブレーション戦略」順で原因切り分け
  - 一致したら **許容範囲を確定**：
    - 仮置き目標：CoV ±0.005，中心/周辺比 ±0.02，勾配 ±1.5%
    - データを見て調整．確定値を本ファイルの末尾に追記
- **完了条件**: 実測値と仮置き許容範囲内で一致．数値を本ファイルに記録

### Step 8: 設計バリエーション比較

- **目的**: 改良案を複数試して，実装に進む候補を絞る
- **やること**:
  - LED 個数・配置を変えた YAML を 3〜5 パターン作成（例: リング 4 → 6 → 8 個）
  - ディフューザー散乱パラメータを変えた YAML を 2〜3 パターン作成
  - 各パターンを `sm-render → sm-evaluate` で評価
  - 比較表（pandas DataFrame → CSV / Markdown）を生成
  - 有望な候補を Fusion 360 へフィードバック
- **完了条件**: 比較表が生成され，最低 1 つの改良案がベースラインより CoV 低下を達成

## キャリブレーション目標値（暫定）

Step 7 で実数値を見てから確定する．それまでの仮置き：

| 指標 | 実測値（参考） | 仮置き許容範囲 |
| --- | --- | --- |
| CoV | 0.0426 | ±0.005 |
| 中心/周辺比 | 1.064 | ±0.02 |
| 勾配 (%) | 6.23 | ±1.5 |

確定値は Step 7 完了時に本表を上書きする．

## マイルストーン (Milestones)

- **M1（Step 1〜2 完了）**: 評価ロジック + スキーマが動く．まだ実物シミュは動かない
- **M2（Step 4〜5 完了）**: シミュレーションの 1 周（YAML → PNG）が動く
- **M3（Step 6 完了）**: シミュ・実測の同一評価パイプラインが完成
- **M4（Step 7 完了）**: 基準設計と実測の整合が取れた．ここまでが「環境完成」
- **M5（Step 8）**: 改良案が複数比較できる．プロジェクトの本来目的を達成
