# GlyceSurrogate-Kor (글라이스서로게이트코어)

> ⚠️ **연구용·참고용 (RESEARCH / REFERENCE USE ONLY) — NOT FOR CLINICAL DECISION-MAKING.**
> 번들된 데모 수치는 합성·예시(synthetic / illustrative)값이며, 실제 임상시험 공식 결과가 아닙니다.
> Bundled demo numbers are synthetic/illustrative — **not** official trial readouts. Do not cite them.

**Domain (도메인):** DM — 당뇨병 (diabetes)
**Category (카테고리):** 연구 아이디어 생성 — research-hypothesis generation
**Mode:** 100% **offline**, stdlib + numpy + scipy + pandas (+ optional matplotlib/streamlit). No network, no external/paid APIs, no EMR.

---

## What it does (한 줄 요약)

당뇨병 RCT에서 추출한 **(Δ혈당 대리지표, Δ경성결과)** 효과크기 쌍을 입력받아, 약물 계열별로
**시험수준 대리성(trial-level surrogacy)** — R²\_trial, 대리역치효과(STE), 치료효과 설명비율(PTE) —
을 가중 메타회귀로 계산하고, 약하거나 검증되지 않은 *대리지표–결과–계열* 조합을 자동 플래그하여
**검증연구 가설 + 표본수 제안**을 생성하는 독립 실행형 도구.

A standalone tool that ingests trial-level (Δ glycemic surrogate, Δ hard outcome)
effect-size pairs from diabetes RCTs, computes by-drug-class trial-level surrogacy
(R²\_trial, surrogate threshold effect [STE], proportion of treatment effect explained
[PTE]) via weighted meta-regression, auto-flags weak/unvalidated surrogate–outcome–class
pairs, and generates validation-study hypotheses with sample-size suggestions.

---

## 5 core features

1. **By-class trial-level surrogacy table** — weighted (inverse-variance) meta-regression
   of the hard-outcome treatment effect (log-HR) on the surrogate treatment effect
   (ΔHbA1c / ΔTIR / ΔFPG) across trials within each drug class → **R²\_trial** + 95% CI.
2. **Surrogate Threshold Effect (STE)** — the minimum favorable surrogate effect at which
   the 95% prediction band of the predicted log-HR crosses the null (benefit). Returned
   only when the fitted slope actually points toward benefit (direction-guarded).
3. **PTE (proportion of treatment effect explained)** — `PTE = 1 − β_adjusted / β_unadjusted`
   from a simple mediation framing; clamped to [0, 1] with an *implausible/undetermined* flag.
4. **Surrogate-paradox detection** — flags trials/classes where the surrogate **improves**
   yet the hard outcome **worsens** (HR > 1) — the ACCORD-style failure of glycemic surrogacy.
5. **Unvalidated-pair mining + hypothesis generation** — sweeps the
   *surrogate × outcome × class* grid for weak/under-powered/missing cells and emits
   validation hypotheses (e.g. *"Is TIR a valid surrogate for DKD progression in SGLT2i?"*)
   with transparent sample-size suggestions.

---

## Run commands

From inside `projects/2026-05-22-1-glyce-surrogate-kor/`:

```bash
# CLI (primary entry point) ---------------------------------------------------
python3 main.py                 # default summary
python3 main.py --surrogacy     # by-class R²_trial / STE / PTE / grade table
python3 main.py --paradox       # surrogate-paradox flags (ACCORD-style)
python3 main.py --gaps          # mined unvalidated pairs + validation hypotheses
python3 main.py --hypotheses    # alias of --gaps
python3 main.py --all           # summary + surrogacy + paradox + gaps
python3 main.py --top 5         # limit rows / hypotheses
python3 main.py --data my.csv --surrogacy        # use your own CSV
python3 main.py --csv-out out.csv                # export the surrogacy table
python3 main.py --help

# Optional Streamlit UI (mirrors the CLI) -------------------------------------
streamlit run app.py
```

The CLI runs from any directory (it resolves the bundled demo CSV by absolute path).

---

## Methodology (in brief)

Implements the **Buyse–Molenberghs / Daniels–Hughes** *trial-level* surrogacy approach
in pure numpy/scipy (statsmodels is **not** required / not installed):

- **Weighted least squares (WLS):** within each (class × surrogate × outcome) cell, fit
  `log-HR_i = β0 + β1·Δsurrogate_i`, weighting each trial by `w_i = 1/Var(log-HR_i)`
  (inverse variance of the hard-outcome effect).
- **R²\_trial:** weighted coefficient of determination of that fit. 95% CI via the
  Fisher-z transform of `r = √R²` (needs n ≥ 4 trials).
- **STE:** sweep the surrogate axis; using the WLS **prediction band**
  `s² · ( x₀ᵀ(XᵀWX)⁻¹x₀ + 1/w_med )` with a Student-t critical value, find the
  least-favorable surrogate value whose entire 95% band still sits below the null
  (log-HR < 0). Only returned when `β1` points toward benefit.
- **PTE:** mediation framing — `β_unadjusted` = inverse-variance-weighted mean log-HR;
  `β_adjusted` = WLS intercept (predicted log-HR at zero surrogate change);
  `PTE = 1 − β_adjusted/β_unadjusted`, clamped to [0, 1] with an implausibility flag.
- **Grade:** `strong ≥ 0.70`, `moderate ≥ 0.50`, `weak < 0.50`, `invalid` if any
  surrogate paradox in the cell. Thresholds are configurable constants in `surrogacy.py`.
- **Sample-size suggestion:** total events ≈ `4·(z_{α/2}+z_β)² / logHR²` (1:1 allocation,
  80% power, two-sided α 0.05), converted to participants via an event-rate proxy derived
  from the observed `loghr_se`. **Transparent heuristic, not a formal power calculation.**

### Configurable constants (`surrogacy.py`)
`R2_STRONG=0.70`, `R2_MODERATE=0.50`, `MIN_TRIALS_FOR_REGRESSION=3`,
`MIN_TRIALS_FOR_VALIDATION=3`, `WIDE_CI_WIDTH=0.50`, `SURROGATE_FAVORABLE_SIGN`
(HbA1c/FPG = −1 lower-is-better, TIR = +1 higher-is-better).

### What the demo encodes (well-established clinical lesson)
- **Surrogates:** HbA1c (Δ%), CGM Time-in-Range (ΔTIR pp), Fasting Plasma Glucose (ΔFPG mg/dL).
- **Hard outcomes:** MACE, HF hospitalization, DKD progression, microvascular composite,
  all-cause death.
- **Teaching cases:** ACCORD / ADVANCE / VADT intensive HbA1c lowering did **not** improve
  (ACCORD **increased**) mortality → surrogate paradox. SGLT2i / GLP-1RA show CV & renal
  benefit largely **independent** of HbA1c magnitude → HbA1c surrogacy is **class- and
  outcome-dependent**. The demo reproduces both lessons: SU/intensive-control cells are
  flagged `invalid` (paradox), and SGLT2i HbA1c→hard-outcome R²\_trial is **weak**.

---

## Data schema (`data/demo_trials.csv`)

`#`-prefixed lines are comments. One row = one trial × one hard-outcome contrast.

| column | meaning |
|---|---|
| `trial` | trial identifier |
| `drug_class` | `SGLT2i` / `GLP1RA` / `DPP4i` / `SU_Intensive` / `Tirzepatide` |
| `surrogate` | `HbA1c` / `TIR` / `FPG` |
| `delta_surrogate` | treatment-vs-control change in surrogate (HbA1c Δ% & FPG Δmg/dL: negative=good; TIR Δpp: positive=good) |
| `delta_surrogate_se` | standard error of `delta_surrogate` |
| `hard_outcome` | `MACE` / `HF_hosp` / `DKD_progression` / `microvascular` / `all_cause_death` |
| `loghr` | log hazard ratio for the hard outcome (negative=benefit, HR<1) |
| `loghr_se` | standard error of `loghr` (drives inverse-variance weighting) |

To use your own data: `python3 main.py --data path/to/your.csv --all`.

---

## Data sources / citations (described, not fetched — offline)

The demo dataset is **synthetic/curated** but the *structure and directional lessons* are
grounded in the public evidence base. For real analyses, populate the CSV from:

- **ClinicalTrials.gov** registrations & posted results (EMPA-REG OUTCOME, DECLARE-TIMI 58,
  CANVAS, CREDENCE, DAPA-CKD, LEADER, SUSTAIN-6, REWIND, FLOW, SAVOR-TIMI 53, EXAMINE,
  TECOS, ACCORD, ADVANCE, VADT, SURPASS-CVOT).
- **Published trial reports & meta-analyses** (e.g. NEJM/Lancet primary papers; CVOT and
  renal-outcome meta-analyses) for ΔHbA1c, log-HR, and confidence intervals.
- **FDA / EMA review documents** for adjudicated outcome definitions and effect estimates.
- **Surrogacy methodology:** Buyse & Molenberghs (1998); Buyse et al. (2000) *Biostatistics*;
  Daniels & Hughes (1997) *Stat Med*; Prentice (1989) surrogate criteria; FDA/EMA surrogate
  validation guidance.
- **Korean / international guidelines for context:** KDA 2023, ADA 2025.

> No numbers in `data/demo_trials.csv` should be quoted as a real trial result.

---

## 검수 체크리스트 (QA checklist)

- [x] `main.py` 와 `app.py` 가 `ast.parse` 로 구문 오류 없이 파싱됨.
- [x] `python3 main.py --help` 정상 동작.
- [x] `--surrogacy` / `--paradox` / `--gaps` / `--all` 모두 합리적 수치 출력 (R² ∈ [0,1], grade 부여, 가설 생성).
- [x] 데모 CSV 가 정상 파싱되고 필수 컬럼 검증이 동작함.
- [x] ACCORD/VADT 계열이 surrogate paradox 로, SGLT2i HbA1c→경성결과가 weak 로 분류됨 (임상 교훈 재현).
- [x] STE 방향 가드: 기울기가 이득 방향일 때만 STE 산출.
- [x] PTE [0,1] 클램프 + implausible 플래그.
- [x] 잘못된 파일/스키마에 대해 exit code 2 와 명확한 에러 메시지.
- [x] `app.py` 가 streamlit 런타임 없이 import 되고, headless 로 부팅됨. matplotlib `Agg` 백엔드 사용.
- [x] 네트워크 호출 없음 / 외부 API 없음 / 전역 설치 없음.
- [x] 모든 출력 헤더와 README 상단에 연구용·참고용 면책 문구 포함.

Full verification log: see `QA.md`.

---

## Files

```
2026-05-22-1-glyce-surrogate-kor/
├── main.py              # PRIMARY CLI entry point
├── surrogacy.py         # pure numpy/scipy meta-regression engine (shared by CLI + UI)
├── app.py               # optional Streamlit UI (mirrors the CLI)
├── data/
│   └── demo_trials.csv  # synthetic/illustrative curated demo dataset (documented schema)
├── README.md            # this file
└── QA.md                # verification log
```
