feat(bv): 데모 lr_ratio_override=1.0 default — 사용자앱 (1add642) 동기화

algorithm 팀 최신 표준 (piezophantomtest 4830e7c) 반영.

- GreenZoneConstants.lrRatioOverride: Double? = 1.0 추가 (default 1.0)
- estimateBladderVolume6ch — override 있으면 computeLrRatio 스킵
- Dev panel toggle "lr=1.0 fixed" — ON/OFF 로 fixed vs computed 전환

Phantom 검증 (2533 scans, 150 mL):
- APP (기존): 147.6 mL (-1.6%)  ✓
- Config F (Python NEW lib + lr=1.0): 147.3 mL (-1.8%)  ← 완전 동일

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 11:18:57 +09:00
parent 29cda408a4
commit cd3efc5f24
3 changed files with 33 additions and 1 deletions
@@ -41,6 +41,17 @@ object GreenZoneConstants {
@Volatile var detectionMethod: DetectionMethod = DetectionMethod.METHOD_C @Volatile var detectionMethod: DetectionMethod = DetectionMethod.METHOD_C
@Volatile var bvMethod: BvMethod = BvMethod.V41 @Volatile var bvMethod: BvMethod = BvMethod.V41
/**
* lr_ratio 강제 override (algorithm 팀 최신 표준: piezophantomtest 4830e7c).
* - null : computed (기존 Python `compute_lr_ratio` 알고리즘)
* - Double : 강제 값 (algorithm 팀 default = 1.0)
*
* Phantom 실측 검증: computed lr=0.68 → BV -38%. lr=1.0 fixed → -1.6% (APP 일치).
* 6채널 hardware LR 분해능 한계로 computed lr 신뢰도 낮음. Dev toggle 전환 가능.
*/
@Volatile var lrRatioOverride: Double? = 1.0
@Volatile var placementGuideMode: PlacementGuideMode = PlacementGuideMode.SIMPLE @Volatile var placementGuideMode: PlacementGuideMode = PlacementGuideMode.SIMPLE
@Volatile var alignmentAlgo: AlignmentAlgo = AlignmentAlgo.V1 // default V1 (일반 사용자). V2 (Method D) 는 clinical alignment session 전용. @Volatile var alignmentAlgo: AlignmentAlgo = AlignmentAlgo.V1 // default V1 (일반 사용자). V2 (Method D) 는 clinical alignment session 전용.
@@ -398,7 +398,10 @@ fun estimateBladderVolume6ch(
var centerWalls = PiezoHW.centerCh.map { if (it < allWalls.size) allWalls[it] else null } var centerWalls = PiezoHW.centerCh.map { if (it < allWalls.size) allWalls[it] else null }
centerWalls = repairCenterWallsFor6ch(centerWalls) centerWalls = repairCenterWallsFor6ch(centerWalls)
val lateralWalls = PiezoHW.lateralCh.map { if (it < allWalls.size) allWalls[it] else null } val lateralWalls = PiezoHW.lateralCh.map { if (it < allWalls.size) allWalls[it] else null }
val lrRatio = computeLrRatio(centerWalls, lateralWalls, sensorZMm = PiezoHW.sensorZMmAll) // 2026-07-01: algorithm 팀 최신 표준 (piezophantomtest 4830e7c) — lr_ratio_override=1.0
// Phantom 검증: computed lr 은 6채널 HW 한계로 -38% 오차. Dev panel 로 전환 가능.
val lrRatio = com.example.medilightv2android.managers.GreenZoneConstants.lrRatioOverride
?: computeLrRatio(centerWalls, lateralWalls, sensorZMm = PiezoHW.sensorZMmAll)
return estimateBladderVolume( return estimateBladderVolume(
walls = centerWalls, walls = centerWalls,
lrRatio = lrRatio, lrRatio = lrRatio,
@@ -1905,6 +1905,24 @@ fun PiezoMonitoringView(appState: AppState) {
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding)) HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
// 2026-07-01: lr_ratio override (algorithm 팀 4830e7c 표준)
var lrFixed by remember {
mutableStateOf(com.example.medilightv2android.managers.GreenZoneConstants.lrRatioOverride != null)
}
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text("lr=1.0 fixed", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
Spacer(modifier = Modifier.weight(1f))
Switch(checked = lrFixed,
onCheckedChange = {
lrFixed = it
com.example.medilightv2android.managers.GreenZoneConstants.lrRatioOverride =
if (it) 1.0 else null
},
colors = SwitchDefaults.colors(checkedTrackColor = MlPrimary))
}
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
// SG Filter // SG Filter
var sgEnabled by remember { mutableStateOf(analyzer.useSgFilter) } var sgEnabled by remember { mutableStateOf(analyzer.useSgFilter) }
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {