feat: render ">100" for above-range ZC Freq instead of "—"

BW writes ">100 Hz" for ZC Freq when the zero-crossing algorithm sees a
peak too fast to count — the device's reporting ceiling is 100 Hz on
V10.72.  Our parser fell back to None via _parse_number (which requires
a leading digit), so the PDF rendered "—" where BW shows ">100".

Mirrors the OORANGE/saturated pattern already used for PPV and PSPL:
parser stores the threshold (100.0) on zc_freq_hz + sets a new
zc_freq_above_range flag.  Projection carries the flag through to the
sidecar; PDF renderer prepends ">" when set.

Affects both per-channel stats tables (waveform + histogram variants)
and the mic block's ZC Freq row.

Verified on the real T190LD5Q.LK0W fixture: Tran zc_freq_hz=100.0
above_range=True; Vert/Long (normal values) above_range=False; "N/A"
still produces zc_freq_hz=None which renders as "—" (unchanged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-28 18:38:49 +00:00
parent f6abe3caa0
commit 780b45a371
4 changed files with 105 additions and 23 deletions
+34
View File
@@ -441,6 +441,40 @@ def test_real_oorange_event_t190_parses():
assert r.channels["Long"].ppv_ips == pytest.approx(2.83)
assert r.peak_vector_sum_saturated is True
assert r.peak_vector_sum_time_s == pytest.approx(0.007)
# Same fixture: Tran ZC Freq is ">100 Hz" — must parse as 100 +
# above_range flag, not None (which would render as "—" on the PDF).
assert r.channels["Tran"].zc_freq_hz == 100.0
assert r.channels["Tran"].zc_freq_above_range is True
# Vert/Long are normal numeric values; flag stays False.
assert r.channels["Vert"].zc_freq_above_range is False
assert r.channels["Long"].zc_freq_above_range is False
def test_above_range_marker_treated_as_zc_threshold():
"""BW writes '>100 Hz' for ZC Freq when the zero-crossing algorithm
sees a peak too fast to count (cuts off at the device's 100 Hz
reporting ceiling). Parser must store the threshold + flag, not
fall back to None.
"""
txt = """\
"Event Type : Full Waveform"
"Serial Number : BE18190"
"Tran ZC Freq : >100 Hz"
"Vert ZC Freq : 73 Hz"
"Long ZC Freq : N/A Hz"
"MicL ZC Freq : >100 Hz"
"""
r = parse_report(txt)
assert r.channels["Tran"].zc_freq_hz == 100.0
assert r.channels["Tran"].zc_freq_above_range is True
assert r.channels["Vert"].zc_freq_hz == 73.0
assert r.channels["Vert"].zc_freq_above_range is False
# N/A → None, flag stays False
assert r.channels["Long"].zc_freq_hz is None
assert r.channels["Long"].zc_freq_above_range is False
# Mic above-range
assert r.mic.zc_freq_hz == 100.0
assert r.mic.zc_freq_above_range is True
def test_real_histogram_fixture_populates_sensor_location():