feat(clinical): 병원 임상만 최종 알고리즘으로 · 전역은 건드리지 않는다
병원 임상 화면은 최종 보고본(레퍼런스)이 기본이어야 하는데, AlgoMode.reference 는
프로세스 전역이라 그냥 켜면 **일반 측정 화면의 BV 까지** 바뀐다. 그쪽은 현행 임상에서
쓰이고 있어 임의로 건드리면 안 된다.
AlgoMode.withReference(ref) { } 범위 실행을 두고 ClinicalBv 가 그 안에서만 돈다.
계산이 끝나면 전역값은 원래대로다 — 임상 화면을 다녀왔다는 이유로 다른 화면의 값이
달라지지 않는다. 되돌리는지도 테스트로 고정했다. 임상 측정은 코루틴에서 돌아 두 계산이
겹칠 수 있으므로 동기화한다: 겹치면 한쪽의 복원이 다른 쪽의 설정을 지워 엉뚱한 경로로
계산된 값이 나오는데, 그 한 건이 검증 기록에 섞이면 나중에 찾아낼 방법이 없다.
ClinicalBv.compute(reference = true) 가 기본. BV 측정 화면의 스위치는 이제 전역을
쓰지 않고 그 화면의 계산에만 적용된다(두 경로 비교용).
**앞 커밋(21b0fca)의 숫자를 정정한다.** "align_cm1 기존 125.52 vs 레퍼런스 122.25 mL"
는 잘못된 측정이었다 — PiezoHW.activePreset 을 안 잡고 돌려 dps·delay 가 다른 프리셋
값으로 계산됐다(실측 자원은 VBT26050202=V1). 프리셋을 고정하면 이 데이터에서는 두
경로가 **같은 값**을 낸다(cm0 410.65 / cm1 490.63, 양쪽 동일).
두 경로가 같다는 뜻은 아니다. AlgoModeSwitchTest 실측으로 **cycle 44개 중 38개**의
검출·BV 가 갈린다. 여러 cycle 을 평균한 mean-scan 에서 차이가 묻힌 것이다. 즉 입력에
따라 같기도 다르기도 하므로, 값에 경로 표시를 붙이는 이유는 그대로 유효하다.
같은 함정을 테스트에도 반영했다 — ClinicalBvTest·AlgoPathReportTest 가 프리셋을 V1 로
고정한다. 다른 테스트가 남긴 전역 프리셋에 끌려가면 값이 통째로 흔들린다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -47,5 +47,32 @@ object AlgoMode {
|
||||
var reference: Boolean = false
|
||||
|
||||
/** 화면에 표시할 이름. */
|
||||
val label: String get() = if (reference) "레퍼런스 (Python 1:1)" else "기존 (현행 임상)"
|
||||
val label: String get() = labelOf(reference)
|
||||
|
||||
/** 전역 상태가 아니라 **그 계산에 실제로 쓰인** 값의 이름. */
|
||||
fun labelOf(ref: Boolean): String =
|
||||
if (ref) "레퍼런스 (Python 1:1)" else "기존 (현행 임상)"
|
||||
|
||||
private val lock = Any()
|
||||
|
||||
/**
|
||||
* [ref] 경로로 [block] 을 실행하고 **원래 값으로 되돌린다.**
|
||||
*
|
||||
* ## 왜 전역 토글을 그냥 켜지 않나
|
||||
* [reference] 는 프로세스 전역이라, 병원 임상 화면이 켜면 **일반 측정 화면의 BV 까지**
|
||||
* 바뀐다. 그쪽은 현행 임상에서 쓰이고 있어 임의로 바꾸면 안 된다.
|
||||
*
|
||||
* 그래서 임상 경로([ClinicalBv])만 이 범위 안에서 돌린다. 계산이 끝나면 전역값은
|
||||
* 원래대로다 — 임상 화면을 다녀왔다는 이유로 다른 화면의 값이 달라지지 않는다.
|
||||
*
|
||||
* ## 동기화하는 이유
|
||||
* 임상 화면의 측정은 코루틴에서 돈다. 두 계산이 겹치면 한쪽의 복원이 다른 쪽의
|
||||
* 설정을 지워 **엉뚱한 경로로 계산된 값**이 나온다. 겹칠 일이 드물어도, 그때 나온
|
||||
* 한 건이 검증 기록에 섞이면 나중에 찾아낼 방법이 없다.
|
||||
*/
|
||||
fun <T> withReference(ref: Boolean, block: () -> T): T = synchronized(lock) {
|
||||
val prev = reference
|
||||
reference = ref
|
||||
try { block() } finally { reference = prev }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user