fix(pdf): shared geo Y scale across Long/Vert/Tran (was per-trace)
The event-report waveform plot scaled each geo lane to its own peak, so a small channel filled its lane looking as big as a large one — and the "Geo: X in/s/div" footer only reflected whichever channel was checked first, so its div value was wrong for the other two. Now all three geo lanes share ONE symmetric scale = max |sample| across them (padded, 0.05 in/s floor), matching the event modal and BW's single amp/div; the footer reflects that shared scale. Mic keeps its own psi scale. Big events are unchanged (e.g. BE12844 stays 0.185 in/s/div). Test-first: tests/test_report_pdf_geo_scale.py (shared scale + floor), 2 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf
This commit is contained in:
+19
-10
@@ -777,6 +777,19 @@ def _draw_waveform_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
||||
dt_s = (rd.dt_ms or (1000.0 / sr)) / 1000.0
|
||||
t0_s = (rd.t0_ms if rd.t0_ms is not None else 0.0) / 1000.0
|
||||
|
||||
# Shared geo scale across Long/Vert/Tran (matches the event modal + BW's
|
||||
# single amp/div): all three geo lanes use ONE Y scale = the max |sample|
|
||||
# across them (padded, floored), so relative amplitudes stay honest instead
|
||||
# of each lane auto-zooming to its own peak. Mic keeps its own (psi) scale.
|
||||
GEO_FLOOR_INS = 0.05
|
||||
_geo_amax = 0.0
|
||||
for _gch in ("Long", "Vert", "Tran"):
|
||||
for _x in (rd.channels.get(_gch) or []):
|
||||
_a = abs(_x)
|
||||
if _a > _geo_amax:
|
||||
_geo_amax = _a
|
||||
geo_shared = max(_geo_amax * 1.10, GEO_FLOOR_INS)
|
||||
|
||||
last_idx = len(order) - 1
|
||||
for i, ch in enumerate(order):
|
||||
ax = fig.add_subplot(inner[i])
|
||||
@@ -786,10 +799,10 @@ def _draw_waveform_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
||||
if values:
|
||||
color = _channel_axis_color(ch)
|
||||
ax.plot(times, values, color=color, linewidth=0.5)
|
||||
# Symmetric y-axis for geo; zero-anchored for mic.
|
||||
# Geo: one shared symmetric scale (honest relative amplitudes).
|
||||
# Mic: symmetric on its own psi scale (different unit).
|
||||
if ch != "MicL":
|
||||
amax = max((abs(v) for v in values), default=0.001)
|
||||
ax.set_ylim(-amax * 1.10, amax * 1.10)
|
||||
ax.set_ylim(-geo_shared, geo_shared)
|
||||
else:
|
||||
amax = max((abs(v) for v in values), default=0.001)
|
||||
ax.set_ylim(-amax * 1.10, amax * 1.10)
|
||||
@@ -824,13 +837,9 @@ def _draw_waveform_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
||||
# and find peak geo amplitude for the geo amp/div setting.
|
||||
total_s = times[-1] - times[0] if values else 0
|
||||
div_s = total_s / 10 if total_s > 0 else 0
|
||||
geo_amp_div = "—"
|
||||
for ch in ("Tran", "Vert", "Long"):
|
||||
v = rd.channels.get(ch) or []
|
||||
if v:
|
||||
amax = max(abs(x) for x in v)
|
||||
geo_amp_div = f"{(amax * 1.1 * 2) / 10:.3f}"
|
||||
break
|
||||
# Footer div value reflects the SHARED geo scale (so it's correct for all
|
||||
# three lanes, not just whichever one happened to be checked first).
|
||||
geo_amp_div = f"{(geo_shared * 2) / 10:.3f}" if _geo_amax > 0 else "—"
|
||||
fig.text(
|
||||
0.11, 0.030,
|
||||
f"Time(Seconds) {div_s:.2f} sec/div Amplitude Geo: {geo_amp_div} in/s/div Mic: 0.001 psi(L)/div",
|
||||
|
||||
Reference in New Issue
Block a user