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:
+22
-14
@@ -99,6 +99,7 @@ class ReportData:
|
||||
mic_pspl_time_s: Optional[float] = None
|
||||
mic_pspl_when_str: Optional[str] = None # histogram absolute date+time, BW-formatted
|
||||
mic_zc_freq_hz: Optional[float] = None
|
||||
mic_zc_freq_above_range: bool = False
|
||||
mic_channel_test_result: Optional[str] = None
|
||||
mic_channel_test_freq_hz: Optional[float] = None
|
||||
mic_channel_test_amp_mv: Optional[float] = None
|
||||
@@ -216,7 +217,8 @@ def gather_report_data(
|
||||
# Inverse of the dBL formula → psi. Mirrors waveform_codec convention.
|
||||
rd.mic_pspl_psi = DBL_REF_PSI * (10 ** (rd.mic_pspl_dbl / 20))
|
||||
rd.mic_pspl_time_s = mic.get("time_of_peak_s")
|
||||
rd.mic_zc_freq_hz = mic.get("zc_freq_hz")
|
||||
rd.mic_zc_freq_hz = mic.get("zc_freq_hz")
|
||||
rd.mic_zc_freq_above_range = bool(mic.get("zc_freq_above_range"))
|
||||
sc_mic = (bw.get("sensor_check") or {}).get("mic") or {}
|
||||
rd.mic_channel_test_result = sc_mic.get("result")
|
||||
rd.mic_channel_test_freq_hz = sc_mic.get("freq_hz")
|
||||
@@ -236,15 +238,16 @@ def gather_report_data(
|
||||
ch_when_iso = peak_when.get(ch_label)
|
||||
peak_date, peak_time = _split_iso_to_date_time(ch_when_iso)
|
||||
rd.channel_stats.append({
|
||||
"name": ch_label,
|
||||
"ppv_ips": ch.get("ppv_ips"),
|
||||
"zc_freq_hz": ch.get("zc_freq_hz"),
|
||||
"time_of_peak_s": ch.get("time_of_peak_s"),
|
||||
"peak_accel_g": ch.get("peak_accel_g"),
|
||||
"peak_disp_in": ch.get("peak_disp_in"),
|
||||
"sensor_check": sc_ch.get("result"),
|
||||
"peak_date": peak_date,
|
||||
"peak_time": peak_time,
|
||||
"name": ch_label,
|
||||
"ppv_ips": ch.get("ppv_ips"),
|
||||
"zc_freq_hz": ch.get("zc_freq_hz"),
|
||||
"zc_freq_above_range": bool(ch.get("zc_freq_above_range")),
|
||||
"time_of_peak_s": ch.get("time_of_peak_s"),
|
||||
"peak_accel_g": ch.get("peak_accel_g"),
|
||||
"peak_disp_in": ch.get("peak_disp_in"),
|
||||
"sensor_check": sc_ch.get("result"),
|
||||
"peak_date": peak_date,
|
||||
"peak_time": peak_time,
|
||||
})
|
||||
|
||||
# MicL peak time (used in the mic block — "PSPL ... on DATE at TIME")
|
||||
@@ -612,7 +615,8 @@ def _mic_rows(rd: ReportData) -> list[tuple[str, Optional[str]]]:
|
||||
line += f" at {rd.mic_pspl_time_s:.3f} sec."
|
||||
rows.append(("PSPL", line))
|
||||
if rd.mic_zc_freq_hz is not None:
|
||||
rows.append(("ZC Freq", f"{rd.mic_zc_freq_hz:.0f} Hz"))
|
||||
prefix = ">" if rd.mic_zc_freq_above_range else ""
|
||||
rows.append(("ZC Freq", f"{prefix}{rd.mic_zc_freq_hz:.0f} Hz"))
|
||||
if rd.mic_channel_test_result:
|
||||
line = rd.mic_channel_test_result
|
||||
if rd.mic_channel_test_freq_hz is not None and rd.mic_channel_test_amp_mv is not None:
|
||||
@@ -684,13 +688,17 @@ def _draw_stats_table(ax, rd: ReportData, rows_spec: list[tuple[str, str, str]])
|
||||
ch_lookup = {c["name"]: c for c in rd.channel_stats}
|
||||
|
||||
def _cell(field, ch_name):
|
||||
val = ch_lookup.get(ch_name, {}).get(field)
|
||||
ch_rec = ch_lookup.get(ch_name, {})
|
||||
val = ch_rec.get(field)
|
||||
if val is None:
|
||||
return "—"
|
||||
if isinstance(val, float):
|
||||
# ZC Freq is integer-formatted in BW; everything else with 3 decimals
|
||||
# ZC Freq is integer-formatted in BW; ">100 Hz" sentinel
|
||||
# rendered as ">N" (val carries the threshold). Everything
|
||||
# else gets 3 decimals.
|
||||
if field == "zc_freq_hz":
|
||||
return f"{val:.0f}"
|
||||
prefix = ">" if ch_rec.get("zc_freq_above_range") else ""
|
||||
return f"{prefix}{val:.0f}"
|
||||
return f"{val:.3f}"
|
||||
return str(val)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user