64c15a8d46
Python source: piezo-phantom-test commit 02bed02 (= 4494098 vesiscan-test PR).
Kotlin V2 alignment 결과가 Python 과 1:1 일치하도록 포팅 (값·로직 동일).
[1] MethodDParams (config_d.py 매칭)
- oscfarWin: 5 → 9
heavy median 강화로 span_e 안정화 → post 벽 검출 일관성
(CH0 post SD 1.45→0.36, v2 cycle CV ↓)
- shoulderPromGamma: 1.0 → 1.5
peak(promGamma=1.5) 와 정렬해 강한 shoulder 가 약한 peak 에 지지 않음
peak↔shoulder 재분류 토글 제거 (v2 cycle CV 12.8→9.5%)
[2] MethodDResult (detector.py 매칭)
- 신규 필드: antCandidates: List<Pair<Int, Double>>
detect() 가 recovery 전 wall_select 후보를 score 내림차순으로 노출
Python: tuple((int(c[0]), float(c[4])) for c in sorted(ant_res['candidates'], key=-x[4]))
- ant / antRefined / urineLen 을 var 로 (tie-break post-process 가 in-place 갱신)
[3] AlignmentConstants (config_6ch.py 매칭)
- ANT_TIEBREAK_RATIO = 1.3
- ANT_NEARFIELD_TOL_MM = 8.0
[4] MethodDRunner.applyAntTiebreak() (runners.py _apply_ant_tiebreak 매칭)
- cross-channel 전벽 보정 (in-place):
(1) 동률 (top1/top2 < 1.3) → 이웃 center 채널 ant z 합의 median 으로 선택
(2) near-field 아티팩트 (cz - 8mm 보다 얕음) → 압승이어도 후보 교체
- 방향성: urine 쪽(깊은) 이탈은 dome 곡률로 정상이라 보존, near-field 만 기각
- detectMultichannel() 끝에 호출 — Python method_d() 와 동일 순서
- z(ch, idx) = (DELAY_OFFSET_MM + idx * DISTANCE_PER_SAMPLE) * cos(angle_ch)
- median 은 numpy.median 동작 매칭 (짝수 길이면 두 가운데 평균)
[5] PiezoBVEstimator.distancePerSample (config_6ch.py 매칭)
- default 1.968 → 1.936 (HW 샘플링레이트 변경, FW VBTFW118+)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>