test new variant

This commit is contained in:
awe
2026-04-28 19:32:10 +03:00
parent ffb7dc3f25
commit 9ff97bf737
11 changed files with 813 additions and 33 deletions

View File

@ -8,7 +8,7 @@ import sys
import threading
import time
from queue import Empty, Queue
from typing import Dict, List, Optional, Sequence, Tuple
from typing import Any, Dict, List, Optional, Sequence, Tuple
import numpy as np
@ -67,6 +67,7 @@ TTY_RANGE_DEFAULT_V = 5.0
TTY_RANGE_MIN_V = 1e-6
TTY_RANGE_MAX_V = 1_000_000.0
LOGDET_EXP_INPUT_LIMIT = 80.0
DO1_TAGGED_INFO_KEY = "_do1_tagged_payload"
def sanitize_curve_data_for_display(
@ -491,6 +492,50 @@ def resolve_visible_aux_curves(aux_curves: SweepAuxCurves, enabled: bool) -> Swe
return aux_1_arr, aux_2_arr
def compute_do1_tagged_aggregate(
raw_low: Optional[np.ndarray],
raw_high: Optional[np.ndarray],
) -> Optional[np.ndarray]:
"""Build a merged raw series from LOW/HIGH tagged curves using nan-aware averaging."""
if raw_low is None and raw_high is None:
return None
if raw_low is None:
return np.asarray(raw_high, dtype=np.float32).reshape(-1)
if raw_high is None:
return np.asarray(raw_low, dtype=np.float32).reshape(-1)
low_arr = np.asarray(raw_low, dtype=np.float32).reshape(-1)
high_arr = np.asarray(raw_high, dtype=np.float32).reshape(-1)
width = min(low_arr.size, high_arr.size)
if width <= 0:
return np.zeros((0,), dtype=np.float32)
low_arr = low_arr[:width]
high_arr = high_arr[:width]
out = np.full((width,), np.nan, dtype=np.float32)
low_valid = np.isfinite(low_arr)
high_valid = np.isfinite(high_arr)
both_valid = low_valid & high_valid
low_only = low_valid & (~high_valid)
high_only = high_valid & (~low_valid)
out[low_only] = low_arr[low_only]
out[high_only] = high_arr[high_only]
out[both_valid] = (low_arr[both_valid] + high_arr[both_valid]) * 0.5
return out
def resolve_visible_do1_tagged_aux_curves(
aux_low: SweepAuxCurves,
aux_high: SweepAuxCurves,
enabled: bool,
) -> Tuple[SweepAuxCurves, SweepAuxCurves]:
"""Return visible LOW/HIGH CH1/CH2 pairs for the DO1 tagged raw mode."""
if not enabled:
return (None, None)
return (
resolve_visible_aux_curves(aux_low, enabled=True),
resolve_visible_aux_curves(aux_high, enabled=True),
)
def compute_aux_phase_curve(aux_curves: SweepAuxCurves) -> Optional[np.ndarray]:
"""Compute phase-like curve atan2(aux_2, aux_1) for raw CH2/CH1 display."""
if aux_curves is None:
@ -508,6 +553,17 @@ def compute_aux_phase_curve(aux_curves: SweepAuxCurves) -> Optional[np.ndarray]:
return phase
def compute_do1_tagged_phase_curves(
aux_low: SweepAuxCurves,
aux_high: SweepAuxCurves,
) -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]:
"""Compute separate phase curves for DO1 LOW/HIGH tagged auxiliary data."""
return (
compute_aux_phase_curve(aux_low),
compute_aux_phase_curve(aux_high),
)
def sanitize_tty_voltage_range(range_v: float, default: float = TTY_RANGE_DEFAULT_V) -> float:
"""Return a finite positive full-scale voltage range for tty int16 conversion."""
try:
@ -810,6 +866,8 @@ def run_pyqtgraph(args) -> None:
p_line = win.addPlot(row=0, col=0, title="Сырые данные")
p_line.showGrid(x=True, y=True, alpha=0.3)
curve = p_line.plot(pen=pg.mkPen((80, 120, 255), width=1))
curve_raw_low = p_line.plot(pen=pg.mkPen((255, 90, 90), width=1))
curve_raw_high = p_line.plot(pen=pg.mkPen((90, 220, 255), width=1))
p_line_aux_vb = None
if bin_iq_power_mode:
p_line_aux_vb = pg.ViewBox()
@ -823,15 +881,23 @@ def run_pyqtgraph(args) -> None:
p_line_aux_vb = None
curve_aux_1 = pg.PlotDataItem(pen=pg.mkPen((255, 170, 40), width=1))
curve_aux_2 = pg.PlotDataItem(pen=pg.mkPen((170, 70, 255), width=1))
curve_aux_3 = pg.PlotDataItem(pen=pg.mkPen((255, 120, 20), width=1))
curve_aux_4 = pg.PlotDataItem(pen=pg.mkPen((120, 60, 220), width=1))
if p_line_aux_vb is not None:
p_line_aux_vb.addItem(curve_aux_1)
p_line_aux_vb.addItem(curve_aux_2)
p_line_aux_vb.addItem(curve_aux_3)
p_line_aux_vb.addItem(curve_aux_4)
else:
p_line.addItem(curve_aux_1)
p_line.addItem(curve_aux_2)
p_line.addItem(curve_aux_3)
p_line.addItem(curve_aux_4)
else:
curve_aux_1 = p_line.plot(pen=pg.mkPen((255, 170, 40), width=1))
curve_aux_2 = p_line.plot(pen=pg.mkPen((170, 70, 255), width=1))
curve_aux_3 = p_line.plot(pen=pg.mkPen((255, 120, 20), width=1))
curve_aux_4 = p_line.plot(pen=pg.mkPen((120, 60, 220), width=1))
curve_calib = p_line.plot(pen=pg.mkPen((220, 60, 60), width=1))
curve_norm = p_line.plot(pen=pg.mkPen((60, 180, 90), width=1))
p_line.setLabel("bottom", "ГГц")
@ -864,6 +930,7 @@ def run_pyqtgraph(args) -> None:
p_line_phase = win.addPlot(row=2, col=0, title="Raw phase: atan(CH2/CH1)")
p_line_phase.showGrid(x=True, y=True, alpha=0.3)
curve_phase = p_line_phase.plot(pen=pg.mkPen((230, 180, 40), width=1))
curve_phase_high = p_line_phase.plot(pen=pg.mkPen((80, 220, 220), width=1))
p_line_phase.setLabel("bottom", "ГГц")
p_line_phase.setLabel("left", "рад")
try:
@ -1312,18 +1379,23 @@ def run_pyqtgraph(args) -> None:
if not isinstance(payload, dict):
return None
signal_kind = payload.get("signal_kind")
if signal_kind in {"bin_iq", "bin_logdet"}:
if signal_kind in {"bin_iq", "bin_logdet", "bin_iq_do1_tagged"}:
return str(signal_kind)
return None
def current_packet_is_do1_tagged(info: Optional[SweepInfo] = None) -> bool:
return get_signal_kind(info) == "bin_iq_do1_tagged"
def current_packet_is_complex() -> bool:
return bool(complex_sweep_mode) and get_signal_kind() != "bin_logdet"
signal_kind = get_signal_kind()
return bool(complex_sweep_mode) and signal_kind not in {"bin_logdet", "bin_iq_do1_tagged"}
def refresh_signal_mode_labels() -> None:
signal_kind = get_signal_kind()
active_complex = current_packet_is_complex()
is_logdet = signal_kind == "bin_logdet"
is_bin_iq = signal_kind == "bin_iq"
is_do1_tagged = signal_kind == "bin_iq_do1_tagged"
try:
if is_logdet:
@ -1331,6 +1403,11 @@ def run_pyqtgraph(args) -> None:
p_line.setLabel("left", "В")
p_fft.setTitle("FFT: exp(V)")
parsed_data_cb.setText("Сырые log-detector (В)")
elif is_do1_tagged:
p_line.setTitle("DO1 tagged raw: LOW/HIGH CH1^2 + CH2^2 (В^2)")
p_line.setLabel("left", "CH1^2 + CH2^2, В^2")
p_fft.setTitle("FFT")
parsed_data_cb.setText("DO1 tagged CH1/CH2 (В)")
elif is_bin_iq:
p_line.setTitle("Сырые CH1/CH2 (В) и CH1^2 + CH2^2 (В^2)")
p_line.setLabel("left", "CH1^2 + CH2^2, В^2")
@ -1347,7 +1424,10 @@ def run_pyqtgraph(args) -> None:
p_fft.setTitle("FFT")
parsed_data_cb.setText("данные после парсинга")
p_fft.setLabel("left", "Амплитуда" if active_complex else "дБ")
p_complex_calib.setVisible(bool(active_complex))
p_img.setVisible(not is_do1_tagged)
p_fft.setVisible(not is_do1_tagged)
p_spec.setVisible(not is_do1_tagged)
p_complex_calib.setVisible((not is_do1_tagged) and bool(active_complex))
except Exception:
pass
@ -1365,6 +1445,12 @@ def run_pyqtgraph(args) -> None:
return False
ch_1_v = convert_tty_i16_to_voltage(code_1_arr[:width], tty_range_v)
ch_2_v = convert_tty_i16_to_voltage(code_2_arr[:width], tty_range_v)
runtime.full_do1_tagged_raw_low = None
runtime.full_do1_tagged_raw_high = None
runtime.full_do1_tagged_aux_low = None
runtime.full_do1_tagged_aux_high = None
runtime.full_do1_tagged_aux_low_codes = None
runtime.full_do1_tagged_aux_high_codes = None
runtime.full_current_aux_curves = (ch_1_v, ch_2_v)
runtime.full_current_fft_source = ch_1_v.astype(np.complex64) + (1j * ch_2_v.astype(np.complex64))
ch_1_v_f64 = ch_1_v.astype(np.float64, copy=False)
@ -1373,6 +1459,44 @@ def run_pyqtgraph(args) -> None:
runtime.full_current_sweep_codes = None
return True
def rebuild_do1_tagged_voltage_curves_from_codes() -> bool:
if (not bin_iq_power_mode) or runtime.full_do1_tagged_aux_low_codes is None or runtime.full_do1_tagged_aux_high_codes is None:
return False
try:
low_code_1, low_code_2 = runtime.full_do1_tagged_aux_low_codes
high_code_1, high_code_2 = runtime.full_do1_tagged_aux_high_codes
except Exception:
return False
low_code_1_arr = np.asarray(low_code_1, dtype=np.float32).reshape(-1)
low_code_2_arr = np.asarray(low_code_2, dtype=np.float32).reshape(-1)
high_code_1_arr = np.asarray(high_code_1, dtype=np.float32).reshape(-1)
high_code_2_arr = np.asarray(high_code_2, dtype=np.float32).reshape(-1)
width = min(low_code_1_arr.size, low_code_2_arr.size, high_code_1_arr.size, high_code_2_arr.size)
if width <= 0:
return False
low_ch_1_v = convert_tty_i16_to_voltage(low_code_1_arr[:width], tty_range_v)
low_ch_2_v = convert_tty_i16_to_voltage(low_code_2_arr[:width], tty_range_v)
high_ch_1_v = convert_tty_i16_to_voltage(high_code_1_arr[:width], tty_range_v)
high_ch_2_v = convert_tty_i16_to_voltage(high_code_2_arr[:width], tty_range_v)
low_ch_1_v_f64 = low_ch_1_v.astype(np.float64, copy=False)
low_ch_2_v_f64 = low_ch_2_v.astype(np.float64, copy=False)
high_ch_1_v_f64 = high_ch_1_v.astype(np.float64, copy=False)
high_ch_2_v_f64 = high_ch_2_v.astype(np.float64, copy=False)
raw_low = np.asarray((low_ch_1_v_f64 * low_ch_1_v_f64) + (low_ch_2_v_f64 * low_ch_2_v_f64), dtype=np.float32)
raw_high = np.asarray((high_ch_1_v_f64 * high_ch_1_v_f64) + (high_ch_2_v_f64 * high_ch_2_v_f64), dtype=np.float32)
runtime.full_do1_tagged_raw_low = raw_low
runtime.full_do1_tagged_raw_high = raw_high
runtime.full_do1_tagged_aux_low = (low_ch_1_v, low_ch_2_v)
runtime.full_do1_tagged_aux_high = (high_ch_1_v, high_ch_2_v)
runtime.full_current_aux_curves = None
runtime.full_current_aux_curves_codes = None
runtime.full_current_sweep_codes = None
runtime.full_current_fft_source = None
runtime.full_current_sweep_raw = compute_do1_tagged_aggregate(raw_low, raw_high)
return runtime.full_current_sweep_raw is not None and runtime.full_current_sweep_raw.size > 0
def rebuild_logdet_voltage_curve_from_codes() -> bool:
if (not bin_iq_power_mode) or runtime.full_current_sweep_codes is None:
return False
@ -1380,6 +1504,12 @@ def run_pyqtgraph(args) -> None:
if code_arr.size <= 0:
return False
sweep_raw_v, fft_input = build_logdet_voltage_fft_input(code_arr, tty_range_v)
runtime.full_do1_tagged_raw_low = None
runtime.full_do1_tagged_raw_high = None
runtime.full_do1_tagged_aux_low = None
runtime.full_do1_tagged_aux_high = None
runtime.full_do1_tagged_aux_low_codes = None
runtime.full_do1_tagged_aux_high_codes = None
runtime.full_current_aux_curves = None
runtime.full_current_aux_curves_codes = None
runtime.full_current_sweep_raw = sweep_raw_v
@ -1390,6 +1520,8 @@ def run_pyqtgraph(args) -> None:
signal_kind = get_signal_kind()
if signal_kind == "bin_logdet":
return rebuild_logdet_voltage_curve_from_codes()
if signal_kind == "bin_iq_do1_tagged":
return rebuild_do1_tagged_voltage_curves_from_codes()
return rebuild_tty_voltage_curves_from_codes()
def reset_background_state(*, clear_profile: bool = True) -> None:
@ -1427,6 +1559,7 @@ def run_pyqtgraph(args) -> None:
if reset_ring:
reset_ring_buffers()
tagged_mode = current_packet_is_do1_tagged()
if runtime.full_current_freqs is None or runtime.full_current_sweep_raw is None:
runtime.current_freqs = None
runtime.current_sweep_raw = None
@ -1434,6 +1567,10 @@ def run_pyqtgraph(args) -> None:
runtime.current_fft_input = None
runtime.current_fft_complex = None
runtime.current_aux_curves = None
runtime.current_do1_tagged_raw_low = None
runtime.current_do1_tagged_raw_high = None
runtime.current_do1_tagged_aux_low = None
runtime.current_do1_tagged_aux_high = None
runtime.current_sweep_norm = None
runtime.current_fft_mag = None
runtime.current_fft_db = None
@ -1462,6 +1599,40 @@ def run_pyqtgraph(args) -> None:
runtime.range_min_ghz,
runtime.range_max_ghz,
)
if tagged_mode:
runtime.current_do1_tagged_raw_low = apply_working_range_to_signal(
runtime.full_current_freqs,
runtime.full_current_sweep_raw,
runtime.full_do1_tagged_raw_low,
runtime.range_min_ghz,
runtime.range_max_ghz,
)
runtime.current_do1_tagged_raw_high = apply_working_range_to_signal(
runtime.full_current_freqs,
runtime.full_current_sweep_raw,
runtime.full_do1_tagged_raw_high,
runtime.range_min_ghz,
runtime.range_max_ghz,
)
runtime.current_do1_tagged_aux_low = apply_working_range_to_aux_curves(
runtime.full_current_freqs,
runtime.full_current_sweep_raw,
runtime.full_do1_tagged_aux_low,
runtime.range_min_ghz,
runtime.range_max_ghz,
)
runtime.current_do1_tagged_aux_high = apply_working_range_to_aux_curves(
runtime.full_current_freqs,
runtime.full_current_sweep_raw,
runtime.full_do1_tagged_aux_high,
runtime.range_min_ghz,
runtime.range_max_ghz,
)
else:
runtime.current_do1_tagged_raw_low = None
runtime.current_do1_tagged_raw_high = None
runtime.current_do1_tagged_aux_low = None
runtime.current_do1_tagged_aux_high = None
if runtime.current_sweep_raw.size == 0:
if push_to_ring:
@ -1472,6 +1643,10 @@ def run_pyqtgraph(args) -> None:
runtime.current_fft_input = None
runtime.current_fft_complex = None
runtime.current_aux_curves = None
runtime.current_do1_tagged_raw_low = None
runtime.current_do1_tagged_raw_high = None
runtime.current_do1_tagged_aux_low = None
runtime.current_do1_tagged_aux_high = None
runtime.current_sweep_norm = None
runtime.current_fft_mag = None
runtime.current_fft_db = None
@ -1482,6 +1657,16 @@ def run_pyqtgraph(args) -> None:
recompute_current_processed_sweep(push_to_ring=push_to_ring)
def recompute_current_processed_sweep(push_to_ring: bool = False) -> None:
if current_packet_is_do1_tagged():
runtime.current_sweep_norm = None
runtime.current_fft_source = None
runtime.current_fft_input = None
runtime.current_fft_complex = None
runtime.current_fft_mag = None
runtime.current_fft_db = None
runtime.current_distances = None
return
fft_source = runtime.current_fft_source
if fft_source is None and runtime.current_sweep_raw is not None:
fft_source = np.asarray(runtime.current_sweep_raw, dtype=np.float32)
@ -2207,8 +2392,76 @@ def run_pyqtgraph(args) -> None:
runtime.full_current_aux_curves_codes = None
runtime.full_current_sweep_codes = None
runtime.full_current_fft_source = None
runtime.full_do1_tagged_raw_low = None
runtime.full_do1_tagged_raw_high = None
runtime.full_do1_tagged_aux_low = None
runtime.full_do1_tagged_aux_high = None
runtime.full_do1_tagged_aux_low_codes = None
runtime.full_do1_tagged_aux_high_codes = None
signal_kind = get_signal_kind(info)
if signal_kind == "bin_logdet":
if signal_kind == "bin_iq_do1_tagged":
calibrated = calibrate_freqs(
{
"F": base_freqs,
"I": sweep,
}
)
runtime.full_current_freqs = np.asarray(calibrated["F"], dtype=np.float64)
payload = info.get(DO1_TAGGED_INFO_KEY) if isinstance(info, dict) else None
if isinstance(payload, dict):
raw_low_payload = payload.get("raw_low")
raw_high_payload = payload.get("raw_high")
if raw_low_payload is not None:
runtime.full_do1_tagged_raw_low = np.asarray(
calibrate_freqs({"F": base_freqs, "I": raw_low_payload})["I"],
dtype=np.float32,
)
if raw_high_payload is not None:
runtime.full_do1_tagged_raw_high = np.asarray(
calibrate_freqs({"F": base_freqs, "I": raw_high_payload})["I"],
dtype=np.float32,
)
runtime.full_current_sweep_raw = compute_do1_tagged_aggregate(
runtime.full_do1_tagged_raw_low,
runtime.full_do1_tagged_raw_high,
)
aux_low_payload = payload.get("aux_low")
aux_high_payload = payload.get("aux_high")
if (
bin_iq_power_mode
and isinstance(aux_low_payload, (tuple, list))
and len(aux_low_payload) == 2
and isinstance(aux_high_payload, (tuple, list))
and len(aux_high_payload) == 2
):
try:
low_aux_1 = np.asarray(
calibrate_freqs({"F": base_freqs, "I": aux_low_payload[0]})["I"],
dtype=np.float32,
)
low_aux_2 = np.asarray(
calibrate_freqs({"F": base_freqs, "I": aux_low_payload[1]})["I"],
dtype=np.float32,
)
high_aux_1 = np.asarray(
calibrate_freqs({"F": base_freqs, "I": aux_high_payload[0]})["I"],
dtype=np.float32,
)
high_aux_2 = np.asarray(
calibrate_freqs({"F": base_freqs, "I": aux_high_payload[1]})["I"],
dtype=np.float32,
)
runtime.full_do1_tagged_aux_low_codes = (low_aux_1, low_aux_2)
runtime.full_do1_tagged_aux_high_codes = (high_aux_1, high_aux_2)
rebuild_do1_tagged_voltage_curves_from_codes()
except Exception:
runtime.full_do1_tagged_aux_low_codes = None
runtime.full_do1_tagged_aux_high_codes = None
if runtime.full_current_sweep_raw is None:
runtime.full_current_sweep_raw = np.asarray(calibrated["I"], dtype=np.float32)
runtime.full_current_fft_source = None
elif signal_kind == "bin_logdet":
calibrated = calibrate_freqs(
{
"F": base_freqs,
@ -2242,7 +2495,7 @@ def run_pyqtgraph(args) -> None:
runtime.full_current_aux_curves_codes = None
runtime.full_current_fft_source = None
if runtime.full_current_fft_source is None:
if (signal_kind != "bin_iq_do1_tagged") and runtime.full_current_fft_source is None:
calibrated = calibrate_freqs(
{
"F": base_freqs,
@ -2327,11 +2580,13 @@ def run_pyqtgraph(args) -> None:
or last_bscan_refresh_stride <= 1
or (update_ticks % last_bscan_refresh_stride) == 0
)
do1_tagged_now = current_packet_is_do1_tagged()
if redraw_needed:
refresh_signal_mode_labels()
active_signal_kind = get_signal_kind()
active_complex_mode = current_packet_is_complex()
active_do1_tagged = active_signal_kind == "bin_iq_do1_tagged"
xs = resolve_curve_xs(
runtime.current_sweep_raw.size
if runtime.current_sweep_raw is not None
@ -2339,20 +2594,78 @@ def run_pyqtgraph(args) -> None:
)
displayed_calib = None
displayed_aux = resolve_visible_aux_curves(runtime.current_aux_curves, parsed_data_enabled)
displayed_phase = compute_aux_phase_curve(runtime.current_aux_curves)
displayed_tagged_aux_low, displayed_tagged_aux_high = resolve_visible_do1_tagged_aux_curves(
runtime.current_do1_tagged_aux_low,
runtime.current_do1_tagged_aux_high,
parsed_data_enabled,
)
if active_do1_tagged:
displayed_phase, displayed_phase_high = compute_do1_tagged_phase_curves(
runtime.current_do1_tagged_aux_low,
runtime.current_do1_tagged_aux_high,
)
else:
displayed_phase = compute_aux_phase_curve(runtime.current_aux_curves)
displayed_phase_high = None
try:
p_line_phase.setVisible(displayed_phase is not None and displayed_phase.size > 0)
p_line_phase.setVisible(
(displayed_phase is not None and displayed_phase.size > 0)
or (displayed_phase_high is not None and displayed_phase_high.size > 0)
)
except Exception:
pass
if runtime.current_sweep_raw is not None:
if active_do1_tagged:
curve.setData([], [])
if runtime.current_do1_tagged_raw_low is not None:
raw_low_x, raw_low_y = decimate_curve_for_display(xs, runtime.current_do1_tagged_raw_low)
raw_low_x, raw_low_y = sanitize_curve_data_for_display(raw_low_x, raw_low_y)
curve_raw_low.setData(raw_low_x, raw_low_y, autoDownsample=False)
else:
curve_raw_low.setData([], [])
if runtime.current_do1_tagged_raw_high is not None:
raw_high_x, raw_high_y = decimate_curve_for_display(xs, runtime.current_do1_tagged_raw_high)
raw_high_x, raw_high_y = sanitize_curve_data_for_display(raw_high_x, raw_high_y)
curve_raw_high.setData(raw_high_x, raw_high_y, autoDownsample=False)
else:
curve_raw_high.setData([], [])
elif runtime.current_sweep_raw is not None:
raw_x, raw_y = decimate_curve_for_display(xs, runtime.current_sweep_raw)
raw_x, raw_y = sanitize_curve_data_for_display(raw_x, raw_y)
curve.setData(raw_x, raw_y, autoDownsample=False)
curve_raw_low.setData([], [])
curve_raw_high.setData([], [])
else:
curve.setData([], [])
curve_raw_low.setData([], [])
curve_raw_high.setData([], [])
if displayed_aux is not None:
if active_do1_tagged:
if displayed_tagged_aux_low is not None:
aux_low_1, aux_low_2 = displayed_tagged_aux_low
aux_low_width = min(xs.size, aux_low_1.size, aux_low_2.size)
low_x_1, low_y_1 = decimate_curve_for_display(xs[:aux_low_width], aux_low_1[:aux_low_width])
low_x_2, low_y_2 = decimate_curve_for_display(xs[:aux_low_width], aux_low_2[:aux_low_width])
low_x_1, low_y_1 = sanitize_curve_data_for_display(low_x_1, low_y_1)
low_x_2, low_y_2 = sanitize_curve_data_for_display(low_x_2, low_y_2)
curve_aux_1.setData(low_x_1, low_y_1, autoDownsample=False)
curve_aux_2.setData(low_x_2, low_y_2, autoDownsample=False)
else:
curve_aux_1.setData([], [])
curve_aux_2.setData([], [])
if displayed_tagged_aux_high is not None:
aux_high_1, aux_high_2 = displayed_tagged_aux_high
aux_high_width = min(xs.size, aux_high_1.size, aux_high_2.size)
high_x_1, high_y_1 = decimate_curve_for_display(xs[:aux_high_width], aux_high_1[:aux_high_width])
high_x_2, high_y_2 = decimate_curve_for_display(xs[:aux_high_width], aux_high_2[:aux_high_width])
high_x_1, high_y_1 = sanitize_curve_data_for_display(high_x_1, high_y_1)
high_x_2, high_y_2 = sanitize_curve_data_for_display(high_x_2, high_y_2)
curve_aux_3.setData(high_x_1, high_y_1, autoDownsample=False)
curve_aux_4.setData(high_x_2, high_y_2, autoDownsample=False)
else:
curve_aux_3.setData([], [])
curve_aux_4.setData([], [])
elif displayed_aux is not None:
aux_1, aux_2 = displayed_aux
aux_width = min(xs.size, aux_1.size, aux_2.size)
aux_x_1, aux_y_1 = decimate_curve_for_display(xs[:aux_width], aux_1[:aux_width])
@ -2361,9 +2674,13 @@ def run_pyqtgraph(args) -> None:
aux_x_2, aux_y_2 = sanitize_curve_data_for_display(aux_x_2, aux_y_2)
curve_aux_1.setData(aux_x_1, aux_y_1, autoDownsample=False)
curve_aux_2.setData(aux_x_2, aux_y_2, autoDownsample=False)
curve_aux_3.setData([], [])
curve_aux_4.setData([], [])
else:
curve_aux_1.setData([], [])
curve_aux_2.setData([], [])
curve_aux_3.setData([], [])
curve_aux_4.setData([], [])
if displayed_phase is not None:
phase_width = min(xs.size, displayed_phase.size)
@ -2372,8 +2689,18 @@ def run_pyqtgraph(args) -> None:
curve_phase.setData(phase_x, phase_y, autoDownsample=False)
else:
curve_phase.setData([], [])
if displayed_phase_high is not None:
phase_high_width = min(xs.size, displayed_phase_high.size)
phase_high_x, phase_high_y = decimate_curve_for_display(
xs[:phase_high_width],
displayed_phase_high[:phase_high_width],
)
phase_high_x, phase_high_y = sanitize_curve_data_for_display(phase_high_x, phase_high_y)
curve_phase_high.setData(phase_high_x, phase_high_y, autoDownsample=False)
else:
curve_phase_high.setData([], [])
if runtime.calib_envelope is not None:
if (not active_do1_tagged) and runtime.calib_envelope is not None:
if runtime.current_sweep_raw is not None:
displayed_calib = resample_envelope(runtime.calib_envelope, runtime.current_sweep_raw.size)
xs_calib = xs[: displayed_calib.size]
@ -2386,7 +2713,7 @@ def run_pyqtgraph(args) -> None:
else:
curve_calib.setData([], [])
if runtime.current_sweep_norm is not None:
if (not active_do1_tagged) and runtime.current_sweep_norm is not None:
norm_display = runtime.current_sweep_norm * norm_display_scale
norm_x, norm_y = decimate_curve_for_display(xs[: norm_display.size], norm_display)
norm_x, norm_y = sanitize_curve_data_for_display(norm_x, norm_y)
@ -2395,7 +2722,13 @@ def run_pyqtgraph(args) -> None:
curve_norm.setData([], [])
if fixed_ylim is None:
if active_signal_kind == "bin_iq":
if active_do1_tagged:
y_series = [
runtime.current_do1_tagged_raw_low,
runtime.current_do1_tagged_raw_high,
runtime.current_sweep_raw,
]
elif active_signal_kind == "bin_iq":
y_series = [
runtime.current_sweep_raw,
displayed_calib,
@ -2416,10 +2749,14 @@ def run_pyqtgraph(args) -> None:
aux_limits = compute_auto_ylim(
displayed_aux[0] if displayed_aux is not None else None,
displayed_aux[1] if displayed_aux is not None else None,
displayed_tagged_aux_low[0] if displayed_tagged_aux_low is not None else None,
displayed_tagged_aux_low[1] if displayed_tagged_aux_low is not None else None,
displayed_tagged_aux_high[0] if displayed_tagged_aux_high is not None else None,
displayed_tagged_aux_high[1] if displayed_tagged_aux_high is not None else None,
)
if aux_limits is not None:
p_line_aux_vb.setYRange(aux_limits[0], aux_limits[1], padding=0)
phase_limits = compute_auto_ylim(displayed_phase)
phase_limits = compute_auto_ylim(displayed_phase, displayed_phase_high)
if phase_limits is not None:
p_line_phase.setYRange(phase_limits[0], phase_limits[1], padding=0)
@ -2457,10 +2794,12 @@ def run_pyqtgraph(args) -> None:
curve_complex_calib_real.setData([], [])
curve_complex_calib_imag.setData([], [])
sweep_for_fft = runtime.current_fft_input
if sweep_for_fft is None:
sweep_for_fft = None if active_do1_tagged else runtime.current_fft_input
if (not active_do1_tagged) and sweep_for_fft is None:
sweep_for_fft = runtime.current_sweep_norm if runtime.current_sweep_norm is not None else runtime.current_sweep_raw
distance_axis = runtime.current_distances if runtime.current_distances is not None else runtime.ring.distance_axis
distance_axis = None if active_do1_tagged else (
runtime.current_distances if runtime.current_distances is not None else runtime.ring.distance_axis
)
if sweep_for_fft is not None and sweep_for_fft.size > 0 and distance_axis is not None:
if (
runtime.current_fft_mag is None
@ -2706,7 +3045,7 @@ def run_pyqtgraph(args) -> None:
refresh_peak_params_label([])
runtime.plot_dirty = False
if changed and runtime.ring.ring is not None:
if changed and runtime.ring.ring is not None and (not do1_tagged_now):
if refresh_heavy_views:
disp = sanitize_image_for_display(runtime.ring.get_display_raw_decimated(RAW_WATERFALL_MAX_POINTS))
if disp is not None:
@ -2727,6 +3066,8 @@ def run_pyqtgraph(args) -> None:
if redraw_needed or status_dirty:
try:
status_payload = dict(runtime.current_info) if runtime.current_info else {}
if status_payload:
status_payload = {k: v for k, v in status_payload.items() if not str(k).startswith("_")}
if peak_calibrate_mode and runtime.current_peak_width is not None:
status_payload["peak_w"] = runtime.current_peak_width
if peak_calibrate_mode and runtime.current_peak_amplitude is not None:
@ -2771,7 +3112,7 @@ def run_pyqtgraph(args) -> None:
except Exception:
pass
if redraw_needed and runtime.ring.ring_fft is not None:
if redraw_needed and runtime.ring.ring_fft is not None and (not do1_tagged_now):
if not refresh_bscan_views:
log_debug_event(
"suppressed_fft_image_refresh",