v0.20.0 -- Full s3 event parse and PDF creation. #28
+38
-8
@@ -796,11 +796,31 @@ def _draw_waveform_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _nice_geo_step(amax: float) -> float:
|
||||||
|
"""Pick a "nice" per-division step for the geo y-axis.
|
||||||
|
|
||||||
|
Geo LSB is 0.005 in/s — sub-LSB steps like 0.003/div are nonsense.
|
||||||
|
Quantize to the BW-style 1-2-5 sequence (0.005, 0.01, 0.025, 0.05,
|
||||||
|
…) and return the smallest step where 5 divisions >= amax, so the
|
||||||
|
top of the chart lands on a tick.
|
||||||
|
"""
|
||||||
|
if amax <= 0:
|
||||||
|
return 0.005
|
||||||
|
for step in (0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0):
|
||||||
|
if step * 5 >= amax:
|
||||||
|
return step
|
||||||
|
return 10.0
|
||||||
|
|
||||||
|
|
||||||
def _draw_histogram_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
def _draw_histogram_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
||||||
"""4-channel stacked histogram bar chart — per-interval peaks.
|
"""4-channel stacked histogram bar chart — per-interval peaks.
|
||||||
|
|
||||||
X-axis labeled with the actual times from rd.histogram_interval_times
|
X-axis labeled with the actual times from rd.histogram_interval_times
|
||||||
when available; otherwise interval index.
|
when available; otherwise interval index.
|
||||||
|
|
||||||
|
The three geo channels share a single y-axis scale (a BW-style nice
|
||||||
|
multiple of the 0.005 in/s LSB) so bar heights are directly
|
||||||
|
comparable across channels. MicL has its own auto-scale.
|
||||||
"""
|
"""
|
||||||
inner = gridspec_cell.subgridspec(4, 1, hspace=0.0)
|
inner = gridspec_cell.subgridspec(4, 1, hspace=0.0)
|
||||||
order = ["MicL", "Long", "Vert", "Tran"]
|
order = ["MicL", "Long", "Vert", "Tran"]
|
||||||
@@ -809,6 +829,16 @@ def _draw_histogram_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
|||||||
# X-axis: use absolute time labels if we have them, else interval index
|
# X-axis: use absolute time labels if we have them, else interval index
|
||||||
have_times = bool(rd.histogram_interval_times)
|
have_times = bool(rd.histogram_interval_times)
|
||||||
|
|
||||||
|
# Shared geo scale: max across Tran/Vert/Long, quantized to a nice
|
||||||
|
# tick step. Used for ylim + the footer "Amplitude Geo: X in/s/div".
|
||||||
|
geo_amax = 0.0
|
||||||
|
for gch in ("Tran", "Vert", "Long"):
|
||||||
|
gv = rd.channels.get(gch) or []
|
||||||
|
if gv:
|
||||||
|
geo_amax = max(geo_amax, max(abs(x) for x in gv if x is not None))
|
||||||
|
geo_step = _nice_geo_step(geo_amax)
|
||||||
|
geo_top = geo_step * 5 # 5 divisions — top tick lands at this value
|
||||||
|
|
||||||
for i, ch in enumerate(order):
|
for i, ch in enumerate(order):
|
||||||
ax = fig.add_subplot(inner[i])
|
ax = fig.add_subplot(inner[i])
|
||||||
values = rd.channels.get(ch) or []
|
values = rd.channels.get(ch) or []
|
||||||
@@ -821,6 +851,10 @@ def _draw_histogram_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
|||||||
xs = np.arange(len(abs_vals))
|
xs = np.arange(len(abs_vals))
|
||||||
color = _channel_axis_color(ch)
|
color = _channel_axis_color(ch)
|
||||||
ax.bar(xs, abs_vals, color=color, width=0.85, linewidth=0)
|
ax.bar(xs, abs_vals, color=color, width=0.85, linewidth=0)
|
||||||
|
if ch in ("Tran", "Vert", "Long"):
|
||||||
|
ax.set_ylim(0, geo_top)
|
||||||
|
ax.set_yticks([j * geo_step for j in range(6)])
|
||||||
|
else:
|
||||||
amax = max(abs_vals, default=0)
|
amax = max(abs_vals, default=0)
|
||||||
if amax > 0:
|
if amax > 0:
|
||||||
ax.set_ylim(0, amax * 1.10)
|
ax.set_ylim(0, amax * 1.10)
|
||||||
@@ -846,15 +880,11 @@ def _draw_histogram_subplot(fig, gridspec_cell, rd: ReportData) -> None:
|
|||||||
ax.tick_params(axis="x", labelsize=7)
|
ax.tick_params(axis="x", labelsize=7)
|
||||||
ax.tick_params(axis="y", labelsize=6)
|
ax.tick_params(axis="y", labelsize=6)
|
||||||
|
|
||||||
# Footer scale info — histograms use minute/div
|
# Footer scale info — histograms use minute/div. Reuses the shared
|
||||||
|
# geo_step computed above so the label matches the actual y-axis
|
||||||
|
# tick spacing on every subplot.
|
||||||
interval_str = rd.histogram_interval_size or "—"
|
interval_str = rd.histogram_interval_size or "—"
|
||||||
geo_amp_div = "—"
|
geo_amp_div = f"{geo_step:.3f}"
|
||||||
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 / 5:.3f}"
|
|
||||||
break
|
|
||||||
fig.text(
|
fig.text(
|
||||||
0.11, 0.030,
|
0.11, 0.030,
|
||||||
f"Time {interval_str} /div Amplitude Geo: {geo_amp_div} in/s/div Mic: 0.001 psi(L)/div",
|
f"Time {interval_str} /div Amplitude Geo: {geo_amp_div} in/s/div Mic: 0.001 psi(L)/div",
|
||||||
|
|||||||
Reference in New Issue
Block a user