Commit Graph

4 Commits

Author SHA1 Message Date
dw.jang 718016af7a feat: V2 alignment (Method D + alignment.py) demo-final 에 이식
feature/tab-navigation 의 V2 코드를 demo-final 로 가져와 임상 alignment session
에서 V1/V2 둘 다 선택 가능하도록.

복사된 파일 (feature/tab-navigation 그대로):
  walldetect/algo/SgSmoothGeneric.kt
  walldetect/algo/methodd/MethodDParams.kt
  walldetect/algo/methodd/MethodDPreprocessing.kt
  walldetect/algo/methodd/MethodDSpan.kt
  walldetect/algo/methodd/MethodDWallSelect.kt
  walldetect/algo/methodd/MethodDTgc.kt
  walldetect/MethodDDetector.kt
  walldetect/MethodDRunner.kt
  managers/AlignmentAdvisorV2.kt
    (RollingAligner + AlignGuide4Stage + AlignmentAdvice — alignment.py 1:1)

확장:
  walldetect/algo/Otsu.kt
    + otsu1dWithSeparability(values) — Python otsu_1d 의 (threshold, sep) tuple 호환
    method_d span fallback gate 에서 사용

  managers/GreenZoneConstants.kt
    + enum AlignmentAlgo { V1, V2 }
    + @Volatile var alignmentAlgo: AlignmentAlgo = V1 (default = legacy)

  ui/views/monitoring/PlacementGuideView.kt
    + val v2Aligner = remember { RollingAligner() }
    + V2 분기 (alignmentAlgo == V2 시): raw 6ch → push → state(accum/commit)
      → directionHint/directionIcon/placementScore/LED 설정
      → bleManager.debugLogger.info("ALIGN_V2 phase=... state=... bestSet=...")
    + ⚙ Settings overlay 에 V1 (legacy) / V2 (new) 토글 (보라색)
    + addAlignmentFrame 호출 시 V2 활성이면 v2Aligner.phase.name 사용 (4-stage)

  ui/views/clinical/ClinicalHomeView.kt
    + ClinicalSession.alignmentAlgo 를 현재 GreenZoneConstants.alignmentAlgo 값으로 채움
      (이전 demo-final 은 "V1" 하드코딩)
    → V2 토글 후 Sensor Alignment 진입 시 alignment_algo="V2" 가 json 에 기록

영향:
  - 기존 V1 동작 그대로 (default 가 V1, 토글 안 하면 동일)
  - V2 선택 시 demo-final 에서도 4-stage 진행 가능 + json 라벨 V2 명시
  - 알고리즘 토글은 dev 모드 (⚙ 버튼) 에서만 가능 — 일반 사용자 노출 X

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-17 14:03:34 +09:00
Charles KWON 833c110d2f feat: 측정 가로모드 대응 + Ant Offset + Scan Log + 다중 sanity check
## 측정 화면 (PiezoMonitoringView)
- BoxWithConstraints + donutFitSize: 가로/작은 화면에서도 donut+Bladdy+buttons
  모두 들어오도록 height-aware sizing (cap 120~360dp)
- nonDevSpacing: available height 기반 단계 (18/22/28/36) — 큰 화면 답답함 해소
- center 4 중 1개라도 missing → 즉시 realign prompt (이전: AutoMeasure 5회 누적)
- 6채널 중 3개 이상 missing 시 위치 이탈 알림 (모드 무관)
- 다이얼로그 문구: "Position Lost or Insufficient Gel"
- V41 결과 후처리 — walls를 PiezoEchoAnalyzer 기준으로 강제 (UI 차트와 일관)
  · ant = analyzer.result.ant
  · post = analyzer.result.lowEnd + 3
- CH3 secondary echo 잡힘 / CH4·CH5 lateral ant too-deep 문제 해결
- Bladdy 3-tap → Developer Mode toggle (측정 화면에서도)

## Placement 가이드 (PlacementGuideView)
- 가로 모드 대응: bodyW = min(w, h*0.7f) — 태블릿 가로에서 portrait 비율 유지
- Sensor 이미지를 Canvas drawImage 로 이동 — bladder oval 좌표계와 정확히 정렬
- Start Alignment 버튼: enabled = true 명시

## Settings overlay
- "Ant Offset" 숫자 입력 필드 (0~20mm, dev mode 전용)
  · BV 계산 시 ant 를 입력값만큼 probe 쪽으로 당김 (chord 증가 → BV 증가)
  · mm→samples 변환은 PiezoHW.distancePerSample
  · V41 SphereFit BV 는 offset≠0 일 때 우회 → 6ch estimate
- "Version" row 추가 (BuildConfig.VERSION_NAME)
- Save 버튼: 실제 UserStorage 영구 저장 + state 재전파
  · AppState.savePiezoSettingsNow() 추가
- 전체 overlay 에 verticalScroll + Card maxHeight 90% — dev 컨텐츠 길어도 Save 도달

## DPS 동기화 (긴급 수정)
설정의 DPS 변경이 V41Detector(Geometry/AnatomicalGate)에 반영 안 되던 문제:
- WdConfig.DPS_DEFAULT: const val → @Volatile @JvmField var
- PiezoHW.distancePerSample setter 가 WdConfig.DPS_DEFAULT 자동 동기화
- 시작 시점 1.968.also { WdConfig.DPS_DEFAULT = it } 로 두 값 일치

## 버전
- versionName: VBTAND0101 → 2026005-101
- versionCode: 2 → 3

## 신규 모듈
- services/ScanLogStore.kt — dev mode 진단 로그 (마지막 Single Scan summary)
  · WALLS CSV (ch,ant,post,urine), DATA CSV (raw ADC), antOffsetMm
- ui/components/ScanLogDialog.kt — 클립보드 복사 다이얼로그
  · xbench (CharlesKWONsLaw) MbbLogDialog 패턴 차용
  · SelectionContainer + monospace + Copy/Clear/Close
- 측정 화면 dev panel 에 "Scan Log (N)" 버튼 추가

## 데이터 모델
- PiezoSettings.antOffsetMm: Int = 0 필드 추가

## 단위 테스트
- V41DetectorCH4Test.kt — 2026-05-06 floating-signal 캡쳐 6채널 raw 를
  V41Detector.detect 에 통과시켜 결과 출력 (CH4 가짜 wall 진단용)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 18:01:33 +09:00
dw.jang 82634c2107 feat: Method C (V4.1) 대규모 업데이트 — 2-pass pipeline + ChordConsensus
새 알고리즘 모듈 (7개):
- ImpulseReject: 2-pass Hampel filter (lumen 내 impulse 제거)
- MedianFilter: running-median pre-filter (window=7, speckle 제거)
- MorphClose: morphological closing on lumen mask (disabled)
- StaLta: STA/LTA impulse detector (Allen 1978, wall edge vs reverberation)
- ChordConsensus: Tukey MAD outlier + Fischler-Bolles pair test
- DetectionSanity: detection sanity checks
- SweepStabilizer: sweep temporal stability

변경된 모듈 (9개):
- V41Detector: 2-pass pipeline (ImpulseReject.detectWithLumenClean),
  BModeScore V41_WEIGHTS (wamp+stalta), ChordConsensus filtering
- BvEstimation: ChordConsensus filter → trusted channel only
- DetectLumenFirst: running-median pre-filter, V41_PARAMS,
  mergeGapMax=5, Kremkau half-amplitude ant fallback
- AnatomicalGate: antDepthMin 22→10mm, strict threshold 제거
- BModeScore: V41_WEIGHTS (far=0.15, dark=0.10, wamp=0.45, stalta=0.20)
- WallSelect: MAX_PEAK_CANDIDATES_POST=64
- SpanUtils, Otsu, BvDispatchResult 업데이트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 17:01:55 +09:00
dw.jang c9cd3cb3ce feat: Method C (V4.1 CharlesKWON) 통합 + Placement 설정 패널
Method C (walldetect/ 패키지, 38파일):
- V41Detector: OS-CFAR threshold + wavelet denoise + anatomical gate + B-mode score
- Multi-method BV dispatch: frustum(≥2ch) / Verathon(1ch) / sphere fit(cross-check)
- Kasa→LM sphere fitting, sub-sample parabolic refinement
- 패키지 이동: com.medithings.charleskwonslaw → com.example.medilightv2android

통합:
- 설정 UI: A/B 스위치 → A/B/C 버튼 그룹 (A=보라, B=파랑, C=주황)
- Monitoring: Method C 선택 시 V41Detector.detect() → BV dispatch 결과 사용
- Placement: 선택된 Method(A/B/C) 반영 + 톱니바퀴 설정 패널 추가

Placement 그래프 개선:
- Threshold 수평선 (주황 점선)
- Y축 눈금 (0, 1k, 2k)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 11:06:22 +09:00