# QA.md — 검수 로그

프로젝트: MetaCalorimetria-Kor
검수일: 2026-06-02
환경: Python 3.9, numpy 2.0.2(검수환경) / pandas 2.3.3 / scipy 1.13.1 / pyyaml 6.0
(requirements.txt 는 배포용 pinned 버전; 검수는 로컬 python3 패키지로 수행, 전역 설치 없음)

---

## 1. 구문 검사 (AST parse) — PASS

`python3 -c "import ast; ast.parse(open(파일).read())"` 전 .py 파일:

```
OK  calorimetry.py
OK  steady_state.py
OK  predictive.py
OK  importers.py
OK  demo_data.py
OK  app.py
```

결과: **6/6 PASS**

---

## 2. 계산 로직 단위 테스트 (손계산 비교) — PASS

알려진 입력 VO₂=0.25 L/min, VCO₂=0.20 L/min:

| 지표 | 코드 출력 | 손계산 | 판정 |
|------|-----------|--------|------|
| RQ | 0.8000 | 0.20/0.25 = 0.8000 | PASS |
| Weir REE | 1737.29 kcal/day | (3.941·250+1.106·200)·1440/1000 = 1737.29 | PASS |
| Frayn CHO | 0.1075 g/min | 4.55·0.20 − 3.21·0.25 = 0.1075 | PASS |
| Frayn FAT | 0.0835 g/min | 1.67·(0.25−0.20) = 0.0835 | PASS |
| 단백보정 REE(UN=10) | 1715.59 | 1737.29 − 2.17·10 = 1715.59 | PASS |

모든 값 NaN/에러 없음. assert 전부 통과.

---

## 3. 합성 데모 CSV 로드 + 단위 자동인식 — PASS

`pandas.read_csv` + `importers.normalize` (mL/min 저장 → L/min 변환):

```
demo_cosmed_steady.csv : unit=mL/min rows=30 VO2med=0.250 L/min
demo_unstable.csv      : unit=mL/min rows=30 VO2med=0.27x L/min
demo_dit_postprandial.csv: unit=mL/min rows=48 VO2med=0.248 L/min
```

단위 자동인식 mL/min 정확, 결측 없음. **PASS**

---

## 4. 안정상태 검출 (CV) — PASS

- `demo_cosmed_steady.csv` (warmup=5, window=5, CV임계=10%) → **found=True, 구간 5–10분**.
- `demo_unstable.csv` (CV임계=10%) → **found=False** (의도대로 안정 미도달).
  - 1차 생성 곡선은 짧은 5점 윈도우에서 우연히 CV 가 낮아 검출됨 → 진폭·드리프트·노이즈
    증가로 곡선 재생성 후 10%·15% 임계 모두 found=False 확인 (재시도 1회, 해결).
- 검출 구간 `summarize_steady`: REE 1751 kcal/day, RQ 0.804, QC 플래그 없음 — 생리 타당범위.

**PASS**

---

## 5. DIT AUC — PASS

`demo_dit_postprandial.csv`, baseline_end=30분, meal=500 kcal:

```
baseline EE ≈ 1668 kcal/day
DIT incremental AUC ≈ 14.5 kcal  (>0, non-NaN)
% thermogenesis ≈ 2.9 %
peak 증분 @ 30분
```

AUC 양수·non-NaN, % thermogenesis 산출 정상. **PASS**

---

## 6. 예측식 + 대사적응 — PASS

(체중 80kg, 신장 170cm, 40세, 남, FFM 60kg)

```
Mifflin-St Jeor 1667.5 / Harris-Benedict 1747.0 /
Henry/Schofield 1694.7 / Cunningham(FFM) 1820.0  (kcal/day)
```

전부 non-NaN. 측정/예측 비 및 adapted 플래그 산출 정상. **PASS**

---

## 7. QC 플래그 — PASS

```
RQ=1.2 → ['RQ_ABOVE_PHYS']
RQ=0.6 → ['RQ_BELOW_PHYS']
음수 VO2 → ['NONPOS_VO2']
```

생리범위(0.67–1.0) 밖·음수 가스 정상 감지. **PASS**

---

## 8. Streamlit app.py — PASS (구문)

`ast.parse` 통과. 계산 함수들은 모듈(`calorimetry`, `steady_state`, `predictive`,
`importers`)로 분리되어 위 테스트로 직접 호출 검증 완료. UI 런타임은 검수 범위 외
(`streamlit run app.py` 로 수동 확인 권장).

---

## 종합

| 항목 | 결과 |
|------|------|
| 구문 검사 | PASS (6/6) |
| 손계산 일치 | PASS (5/5) |
| 데모 로드·단위 | PASS |
| 안정상태 검출 | PASS (재시도 1회로 unstable 데모 보정) |
| DIT AUC | PASS |
| 예측식·대사적응 | PASS |
| QC 플래그 | PASS |

**전체 판정: PASS** (경고/실패 없음). 재시도: unstable 데모 곡선 1회 재생성.
