From 4d1f6ea6802e4c8a67f908b5e8b4303871a514fd Mon Sep 17 00:00:00 2001 From: jjangddu Date: Wed, 30 Sep 2026 17:06:01 +0900 Subject: [PATCH] =?UTF-8?q?fix(hospital):=20=EC=9E=AC=EB=B6=80=EC=B0=A9=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=EC=9D=98=20=EA=B8=B0=EC=A4=80=EC=9D=84=20?= =?UTF-8?q?=EC=A2=8C=EC=9A=B0=20=ED=99=95=EC=9D=B8=20=EC=B0=BD(=EB=B6=80?= =?UTF-8?q?=EC=B0=A9=20=EC=9C=84=EC=B9=98=EC=99=80=20=EA=B0=99=EC=9D=80=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4)=EC=9C=BC=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 재부착 확인은 부착 위치(N+1cm)에서 재는데 기준은 확인 측정(N cm)이었다. 오프셋 자리는 설계상 지표가 다른 쪽이라(오프셋 위치는 측정하지 않는 이유) N cm 기준으로 대조하면 멀쩡한 재부착도 "채널 없음"이 될 수 있다. 좌우 확인 완료 순간의 마지막 프레임 창을 같은 조건(2.3MHz·c3·supine 분기)으로 mean-scan 해 잡힌 채널을 기준으로 쓴다 — 떼기 직전, 같은 높이의 신호다. 좌우를 안 하고 진행하면 종전대로 확인 측정(N cm)이 기준이다. Co-Authored-By: Claude Fable 5.1 --- .../ui/views/clinical/AnchorAlignView.kt | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/AnchorAlignView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/AnchorAlignView.kt index 1e0f1fb..904a5b0 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/AnchorAlignView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/AnchorAlignView.kt @@ -207,6 +207,12 @@ fun AnchorAlignView(appState: AppState) { var lrStreamIdx by remember { mutableIntStateOf(0) } /** [처음부터 다시 정렬] 횟수 + 1. 스트리밍 기록의 `attempt` 열. */ var lrAttempt by remember { mutableIntStateOf(1) } + /** + * 좌우 확인 완료 순간의 창(부착 위치 N+1cm)에서 잡힌 채널 CH0~3 — 재부착 확인의 기준. + * 확인 측정(N cm)이 아니라 **같은 높이**의 마지막 프레임으로 잡는다. 오프셋 자리는 설계상 + * 지표가 다른 쪽이라 N cm 기준으로 대조하면 멀쩡한 재부착도 "채널 없음"이 될 수 있다. + */ + var lrRefChannels by remember { mutableStateOf?>(null) } /** 간호사가 "좌우 확인 완료"를 누른 적이 있는가. 저장·다음 단계 안내에 쓴다. */ var lrConfirmed by remember { mutableStateOf(false) } @@ -900,6 +906,14 @@ fun AnchorAlignView(appState: AppState) { hasAlignData = true alignDirty = true } + // 같은 창의 mean-scan 으로 채널 검출 — 재부착 확인이 이것과 대조한다. + // 조건(2.3MHz·c3·supine 분기)이 재부착 확인 측정과 같다. + runCatching { + ClinicalBv.compute( + ClinicalBv.meanScan(lrRecent.map { it.first }), + supine = appState.clinicalPosture == ClinicalPosture.SUPINE, + ).walls.take(ReattachCheck.CENTER_CHANNELS).map { it != null } + }.getOrNull()?.let { lrRefChannels = it } } // 좌우 결과를 요약에 남긴다. 나중에 "이 세션은 좌우까지 맞춘 // 것인가"를 파일만 보고 답할 수 있어야 한다 — 재분석 때 @@ -947,8 +961,9 @@ fun AnchorAlignView(appState: AppState) { appState.anchorBasis = basis // 재부착 확인의 기준 — 확인 측정에서 잡힌 채널(CH0~3). 확인 측정 없이 // 진행하면 기준 없음(null)이다. 새 위치이므로 지난 재부착 결과는 비운다. - appState.anchorRefChannels = - if (confirmDone) bv?.walls?.take(ReattachCheck.CENTER_CHANNELS)?.map { it != null } else null + // 기준은 좌우 확인 창(부착 위치와 같은 높이)이 우선, 없으면 확인 측정(N cm). + appState.anchorRefChannels = lrRefChannels + ?: if (confirmDone) bv?.walls?.take(ReattachCheck.CENTER_CHANNELS)?.map { it != null } else null appState.anchorReattach = null // 근거를 요약에도 박는다. 화면에만 있으면 나중에 파일을 보는 사람이 // 이 위치가 어떻게 정해졌는지 알 길이 없다. @@ -1005,6 +1020,7 @@ fun AnchorAlignView(appState: AppState) { runStartedAt = Date() guide.reset(); cm = 0; last = null; records = emptyList(); error = null lateral.reset(); lrCommit = null; lrAccum = 0; lrRecent.clear(); lrAttempt++ + lrRefChannels = null lrConfirmed = false; lrError = null; lrRunning = false disconnectedMidRun = false decidedAtCm = null; sweepStopped = false; confirmDone = false