# 回帰テスト用フィクスチャ形式 (Regression Fixture Format)

旧実装 exe（`org/src` のビルド成果物）で採取した入出力ペアを置く場所．
PLAN_02 ステップ 5「回帰テスト」で使用し，`tests/test_regression.py` が本ディレクトリを読む．

採取の手順（旧 exe の操作方法・採取すべきケース）は
[docs/06_TEST/TEST_01_回帰テスト採取手順.md](../../../docs/06_TEST/TEST_01_回帰テスト採取手順.md) を参照する．
**CSV が 1 件も無い間，回帰テストは skip される**（置いた瞬間に有効化される）．

## ディレクトリ構成 (Layout)

```text
tests/fixtures/regression/
├── README.md          # 本ファイル（形式定義）
├── matrices/          # 採取時に使った変換行列 CSV（17 行 × 3 列・ヘッダなし）
│   └── <任意の名前>.csv
├── rgb_to_lab.csv     # ① RGB → L*a*b* のペア
├── rgb_to_scores.csv  # ② RGB → 5 色スコアのペア（パイプライン全体）
└── lab_to_scores.csv  # ③ L*a*b* → 5 色スコアのペア（任意．下記の注意を参照）
```

## 共通ルール (Common Rules)

- 文字コード: UTF-8（BOM なし）．改行は CRLF / LF どちらでもよい
- 1 行目はヘッダ行とし，列名は本書のとおりに書く（列の順序は自由．列名で対応付ける）
- `#` で始まる行と空行は無視される（メモを書いてよい）
- 数値は半角．旧 exe の表示をそのまま転記する（表示は整数なので小数点は付かない）
- `matrix` 列には `matrices/` に置いた変換行列 CSV のファイル名を書く（例: `translateMatrix.csv`）
- `note` 列は任意．採取日・撮影環境・ケースの意図等を自由に書く

## 旧 exe の表示精度 (Display Precision of the Legacy exe)

`org/src/tonguediagnosisMFC2/tonguediagnosisMFC2Dlg.cpp` の `Text()` は，
L\*a\*b\* もスコアも **`Format(_T("%3.0lf"), ...)`** で整形している．
すなわち**どちらも小数点以下 0 桁（整数に丸めた値）しか画面に出ない**．
これを前提に，照合の許容誤差を次のように定める．

| 項目 | 旧 exe の表示 | 照合方法 | 許容誤差 |
| --- | --- | --- | --- |
| L\*, a\*, b\* | `%3.0lf`（整数・四捨五入相当） | 新実装の計算値と表示値を直接比較 | 絶対値 0.51 以内（表示丸め幅 0.5 + 微小マージン） |
| 5 色スコア（%） | `%3.0lf`（整数） | 新実装の `percentages`（int）と**完全一致** | 0（不一致は即失敗） |
| 診断失敗 | 結果画面の「Diagnosis failed」表示 | 新実装の `DiagnosisResult.failed` と**完全一致** | 0 |

※ スコアを完全一致で照合できる理由: スコアは `k / 38 × 100`（k は 0〜38 の整数）の値しか取らず，
`x.5` ちょうどになる k が存在しないため，丸め方（printf の偶数丸め / Python の `round`）の
違いで結果が変わらない．したがって整数どうしの厳密比較が安全である．

※ L\*a\*b\* を 0.51 以内としているのは，旧 exe が整数しか表示しないためである．
より厳しい照合が必要になった場合は，旧実装をデバッグビルドして `TRACE` 出力（`%lf`）を
採取する必要がある（TEST_01「精度を上げたい場合」参照）．

## ① rgb_to_lab.csv

ROI 平均 RGB（= 単色画像の色）と，旧 exe が表示した L\*a\*b\* の組．

| 列名 | 内容 |
| --- | --- |
| `matrix` | 使用した変換行列 CSV のファイル名（`matrices/` 内） |
| `r`, `g`, `b` | 入力 RGB（0〜255．単色画像の画素値そのまま） |
| `l_star`, `a_star`, `b_star` | 旧 exe のメイン画面に表示された `L*` / `a*` / `b*` の値 |
| `note` | 任意のメモ |

```csv
matrix,r,g,b,l_star,a_star,b_star,note
translateMatrix.csv,156,102,98,55,22,7,基準色（旧実装コメントの平均 BGR 由来）
```

## ② rgb_to_scores.csv

同じ入力 RGB と，旧 exe が表示した 5 色スコア（%）・診断失敗の有無の組．
新実装では `rgb_to_lab` → `diagnose` の**パイプライン全体**を通して照合する
（ステップ 5 の完了条件はこのファイルで判定する）．

| 列名 | 内容 |
| --- | --- |
| `matrix` | 使用した変換行列 CSV のファイル名 |
| `r`, `g`, `b` | 入力 RGB（0〜255） |
| `purple` | 「紫」の表示値（%．整数） |
| `dark_red` | 「暗赤」の表示値（%） |
| `crimson` | 「紅」の表示値（%） |
| `pink` | 「淡紅」の表示値（%） |
| `pale` | 「淡白」の表示値（%） |
| `failed` | 結果画面に「Diagnosis failed」が出たら `yes`，出なければ `no` |
| `note` | 任意のメモ |

```csv
matrix,r,g,b,purple,dark_red,crimson,pink,pale,failed,note
translateMatrix.csv,156,102,98,16,61,11,5,0,no,基準色
```

※ `failed` は `yes` / `no`（`true` / `false`・`1` / `0` も可．空欄は `no` 扱い）．

## ③ lab_to_scores.csv（任意）

L\*a\*b\* を直接入力としたスコアのペア．**旧 exe には Lab の直接入力手段が無い**ため，
通常は採取できない．次のような «L\*a\*b\* が厳密に分かっている» ケースがある場合にのみ使う．

- 旧実装をデバッグビルドし，`CalcSVM()` へ渡る `m_tongueL/a/b` を直接与えて実行した場合
- 旧実装のソースを改造して Lab 入力版を作った場合

| 列名 | 内容 |
| --- | --- |
| `l_star`, `a_star`, `b_star` | 入力 L\*a\*b\*（**整数丸めではない厳密値**） |
| `purple`, `dark_red`, `crimson`, `pink`, `pale` | 5 色スコアの表示値（%） |
| `failed` | 「Diagnosis failed」が出たら `yes` |
| `note` | 任意のメモ |

※ 旧 exe の画面から読んだ**整数丸めの L\*a\*b\* をここに書いてはならない**．
丸めた Lab を SVM に入れると境界付近で予測が変わり，偽の不一致（または偽の一致）を招く．
RGB から採取した組は必ず ② に書く．

## matrices/

採取時にユーザーが旧 exe に読ませた変換行列 CSV をそのまま置く（17 行 × 3 列・ヘッダなし）．
撮影環境ごとに異なるファイルなので，複数置いて `matrix` 列で使い分けてよい．
変換行列が変われば Lab もスコアも変わるため，**採取に使ったファイルを必ず同梱する**こと．
