Files
VesiscanClinicalAndroid/tools/gen_anchor_cases.py
T
dw.jang 422af4c803 test(align): 폴백 규칙으로 정답지(anchor_cases.tsv)를 Python 에서 다시 뽑고 대조 테스트를 원래대로 되돌린다
입력 200개는 그대로 두고 답만 piezo-phantom-test select_supine_anchor(폴백 포함, 로컬 브랜치
no-ch3-fallback 54a25b7)로 다시 썼다 — 재부착 19 → 3, no_ch3_max_nch 16, 나머지 181개 불변.
대조 테스트의 임시 폴백 분기를 지우고 assertEquals 하나로 되돌렸다. 폴백 케이스 수(16)를
잠가 옛 파일이 섞이면 바로 깨지게 했다.

생성 절차가 어디에도 안 남아 있어 tools/gen_anchor_cases.py 로 넣었다. 패키지 __init__ 가 이
체크아웃에 없는 analysis 를 import 해 깨지므로 껍데기 모듈을 등록하고 상대 import 로 읽는다.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-14 15:17:31 +09:00

46 lines
2.3 KiB
Python

"""anchor_cases.tsv 정답 열 재생성 — 입력 200개는 그대로, 답만 Python select_supine_anchor 로 다시 뽑는다.
사용: python gen_anchor_cases.py <in.tsv> <out.tsv>
행 형식: best<TAB>cm,nch,ch3,hit,tot,cap|... (best='-' 는 재부착)
"""
import io, sys, math, os, types
# library/__init__.py 가 이 체크아웃에 없는 analysis 패키지를 import 해 깨진다 — 패키지 껍데기만 등록하고
# 필요한 모듈만 상대 import 로 읽는다(runners 등은 실제 파일에서 로드).
_root = r"C:\Projects\piezophantomtest\piezo-phantom-test"
for _name, _path in (("vesiscan_test", os.path.join(_root, "vesiscan_test")),
("vesiscan_test.library", os.path.join(_root, "vesiscan_test", "library"))):
_m = types.ModuleType(_name); _m.__path__ = [_path]; _m.__package__ = _name; sys.modules[_name] = _m
import vesiscan_test.library.alignment.alignment_selection as sel
src, dst = sys.argv[1], sys.argv[2]
raw = io.open(src, encoding="utf-8", newline="").read()
nl = "\r\n" if "\r\n" in raw else "\n" # 원본 줄바꿈 유지 — diff 가 답 열만 보이게
lines = raw.splitlines()
out, changed, null_before, null_after, fallback = [], 0, 0, 0, 0
for line in lines:
if not line.strip() or line.startswith("#"):
out.append(line)
continue
best_old, recs_raw = line.split("\t", 1)
recs = []
for f in recs_raw.split("|"):
cm, nch, ch3, hit, tot, cap = f.split(",")
capv = float(cap) if cap not in ("nan", "") else math.nan
recs.append(dict(align_cm=int(cm), nch=int(nch), ch3=ch3, ch3_hit=int(hit), ch3_tot=int(tot), cap_frac=capv))
d = sel.select_supine_anchor(recs, tie="cap", offset_cm=0)
best_new = "-" if d.align_cm is None else str(d.align_cm)
if best_old == "-":
null_before += 1
if best_new == "-":
null_after += 1
if d.reasons and d.reasons[0] == sel.NO_CH3_FALLBACK_TAG:
fallback += 1
if best_new != best_old:
changed += 1
assert best_old == "-", f"non-reattach answer changed: {line}"
out.append(best_new + "\t" + recs_raw)
io.open(dst, "w", encoding="utf-8", newline="").write(nl.join(out) + nl)
print(f"cases={sum(1 for l in lines if l.strip() and not l.startswith('#'))} reattach before={null_before} after={null_after} "
f"fallback={fallback} changed={changed} -> {dst}")