Release v0.31.0 — report parity + the inverted rescue (0.29.0 → 0.31.0) #40

Merged
serversdown merged 31 commits from dev into main 2026-09-18 16:46:45 -04:00
Showing only changes of commit 95f926c318 - Show all commits
+20 -11
View File
@@ -396,9 +396,27 @@ def _render_waveform_layout(fig, rd: ReportData) -> None:
ax_stats = fig.add_subplot(gs[2]); ax_stats.axis("off") ax_stats = fig.add_subplot(gs[2]); ax_stats.axis("off")
_draw_channel_stats_waveform(ax_stats, rd) _draw_channel_stats_waveform(ax_stats, rd)
_draw_compliance_panel(fig, gs, rd)
_draw_waveform_subplot(fig, gs[3], rd) _draw_waveform_subplot(fig, gs[3], rd)
def _draw_compliance_panel(fig, gs, rd: ReportData) -> None:
"""Large square USBM RI8507 compliance chart in the upper-right, spanning the
mic (row 1) and stats (row 2) rows — matching Blastware's Event Report."""
bottoms, tops, _lefts, rights = gs.get_grid_positions(fig)
y0, y1 = bottoms[2], tops[1] # bottom of stats row → top of mic row
x0, x1 = 0.64, rights[0] # clear of the stats columns → page right margin
fig.text((x0 + x1) / 2, y1 + 0.004, "USBM RI8507", fontsize=9, weight="bold",
color="#333", ha="center", va="bottom")
if rd.channels and rd.sample_rate_sps:
from sfm.compliance import draw_compliance_chart
ax = fig.add_axes([x0, y0, x1 - x0, y1 - y0])
draw_compliance_chart(ax, rd.channels, rd.sample_rate_sps)
else:
fig.text((x0 + x1) / 2, (y0 + y1) / 2, "(no waveform data)", fontsize=8,
color="#bbb", ha="center", va="center", style="italic")
def _render_histogram_layout(fig, rd: ReportData) -> None: def _render_histogram_layout(fig, rd: ReportData) -> None:
"""Histogram layout: header / mic-only / per-channel stats / bar plot. """Histogram layout: header / mic-only / per-channel stats / bar plot.
@@ -577,17 +595,8 @@ def _draw_mic_and_usbm(ax, rd: ReportData) -> None:
for label, value in rows: for label, value in rows:
_kv(ax, 0.0, y, label, value, label_w=0.18) _kv(ax, 0.0, y, label, value, label_w=0.18)
y -= 0.15 y -= 0.15
# The USBM compliance chart is drawn as its own large square panel spanning
# USBM RI8507 compliance chart — inset axes in the right half of this band. # the mic + stats rows on the right — see _draw_compliance_panel().
ax.text(0.74, 1.00, "USBM RI8507", fontsize=9, weight="bold", color="#333",
ha="center", va="top", transform=ax.transAxes)
if rd.channels and rd.sample_rate_sps:
from sfm.compliance import draw_compliance_chart
inset = ax.inset_axes([0.52, 0.02, 0.46, 0.82])
draw_compliance_chart(inset, rd.channels, rd.sample_rate_sps)
else:
ax.text(0.74, 0.48, "(no waveform data)", fontsize=8, color="#bbb",
ha="center", va="center", transform=ax.transAxes, style="italic")
def _mic_rows(rd: ReportData) -> list[tuple[str, Optional[str]]]: def _mic_rows(rd: ReportData) -> list[tuple[str, Optional[str]]]: