This commit is contained in:
awe
2026-04-30 18:02:28 +03:00
parent d0809e6710
commit 3b5af19c6f

View File

@ -1408,6 +1408,13 @@ def run_pyqtgraph(args) -> None:
text_value_cache[key] = text_value text_value_cache[key] = text_value
return True return True
def set_peak_marker_visibility(visible: bool) -> None:
set_item_visible_if_changed("fft_bg_line", fft_bg_line, visible)
set_item_visible_if_changed("fft_left_line", fft_left_line, visible)
set_item_visible_if_changed("fft_right_line", fft_right_line, visible)
set_item_visible_if_changed("spec_left_line", spec_left_line, visible)
set_item_visible_if_changed("spec_right_line", spec_right_line, visible)
fixed_ylim: Optional[Tuple[float, float]] = None fixed_ylim: Optional[Tuple[float, float]] = None
if args.ylim: if args.ylim:
try: try:
@ -2046,11 +2053,11 @@ def run_pyqtgraph(args) -> None:
try: try:
fft_real_enabled = bool(fft_real_cb.isChecked()) fft_real_enabled = bool(fft_real_cb.isChecked())
except Exception: except Exception:
fft_real_enabled = True fft_real_enabled = False
try: try:
fft_imag_enabled = bool(fft_imag_cb.isChecked()) fft_imag_enabled = bool(fft_imag_cb.isChecked())
except Exception: except Exception:
fft_imag_enabled = True fft_imag_enabled = False
runtime.mark_dirty() runtime.mark_dirty()
def restore_range_controls() -> None: def restore_range_controls() -> None:
@ -3100,7 +3107,7 @@ def run_pyqtgraph(args) -> None:
distance_axis = None if active_do1_tagged else ( distance_axis = None if active_do1_tagged else (
runtime.current_distances if runtime.current_distances is not None else runtime.ring.distance_axis 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 refresh_fft_views and sweep_for_fft is not None and sweep_for_fft.size > 0 and distance_axis is not None:
if ( if (
runtime.current_fft_mag is None runtime.current_fft_mag is None
or runtime.current_fft_mag.size != distance_axis.size or runtime.current_fft_mag.size != distance_axis.size
@ -3160,19 +3167,19 @@ def run_pyqtgraph(args) -> None:
) )
if visible_abs is not None: if visible_abs is not None:
abs_x, abs_y = sanitize_curve_data_for_display(xs_fft[: visible_abs.size], visible_abs) abs_x, abs_y = sanitize_curve_data_for_display(xs_fft[: visible_abs.size], visible_abs)
curve_fft.setData(abs_x, abs_y) set_curve_data("fft_abs", curve_fft, abs_x, abs_y)
else: else:
curve_fft.setData([], []) clear_curve_if_needed("fft_abs", curve_fft)
if visible_real is not None: if visible_real is not None:
real_x, real_y = sanitize_curve_data_for_display(xs_fft[: visible_real.size], visible_real) real_x, real_y = sanitize_curve_data_for_display(xs_fft[: visible_real.size], visible_real)
curve_fft_real.setData(real_x, real_y) set_curve_data("fft_real", curve_fft_real, real_x, real_y)
else: else:
curve_fft_real.setData([], []) clear_curve_if_needed("fft_real", curve_fft_real)
if visible_imag is not None: if visible_imag is not None:
imag_x, imag_y = sanitize_curve_data_for_display(xs_fft[: visible_imag.size], visible_imag) imag_x, imag_y = sanitize_curve_data_for_display(xs_fft[: visible_imag.size], visible_imag)
curve_fft_imag.setData(imag_x, imag_y) set_curve_data("fft_imag", curve_fft_imag, imag_x, imag_y)
else: else:
curve_fft_imag.setData([], []) clear_curve_if_needed("fft_imag", curve_fft_imag)
if peak_search_enabled and visible_abs is not None: if peak_search_enabled and visible_abs is not None:
fft_ref_db = rolling_median_ref(xs_fft, fft_vals_db, peak_ref_window) fft_ref_db = rolling_median_ref(xs_fft, fft_vals_db, peak_ref_window)
@ -3180,11 +3187,11 @@ def run_pyqtgraph(args) -> None:
if np.any(finite_ref): if np.any(finite_ref):
fft_ref_lin = _db_to_linear_amplitude(fft_ref_db[finite_ref]) fft_ref_lin = _db_to_linear_amplitude(fft_ref_db[finite_ref])
ref_x, ref_y = sanitize_curve_data_for_display(xs_fft[finite_ref], fft_ref_lin) ref_x, ref_y = sanitize_curve_data_for_display(xs_fft[finite_ref], fft_ref_lin)
curve_fft_ref.setData(ref_x, ref_y) set_curve_data("fft_ref", curve_fft_ref, ref_x, ref_y)
curve_fft_ref.setVisible(True) set_item_visible_if_changed("fft_ref", curve_fft_ref, True)
ref_curve_for_range = fft_ref_lin ref_curve_for_range = fft_ref_lin
else: else:
curve_fft_ref.setVisible(False) set_item_visible_if_changed("fft_ref", curve_fft_ref, False)
runtime.peak_candidates = find_top_peaks_over_ref(xs_fft, fft_vals_db, fft_ref_db, top_n=3) runtime.peak_candidates = find_top_peaks_over_ref(xs_fft, fft_vals_db, fft_ref_db, top_n=3)
refresh_peak_params_label(runtime.peak_candidates) refresh_peak_params_label(runtime.peak_candidates)
for idx, box in enumerate(fft_peak_boxes): for idx, box in enumerate(fft_peak_boxes):
@ -3196,19 +3203,21 @@ def run_pyqtgraph(args) -> None:
dtype=np.float32, dtype=np.float32,
) )
) )
box.setData( set_curve_data(
f"fft_peak_box_{idx}",
box,
[peak["left"], peak["left"], peak["right"], peak["right"], peak["left"]], [peak["left"], peak["left"], peak["right"], peak["right"], peak["left"]],
y_box, y_box,
) )
box.setVisible(True) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, True)
else: else:
box.setVisible(False) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, False)
else: else:
runtime.peak_candidates = [] runtime.peak_candidates = []
refresh_peak_params_label([]) refresh_peak_params_label([])
curve_fft_ref.setVisible(False) set_item_visible_if_changed("fft_ref", curve_fft_ref, False)
for box in fft_peak_boxes: for idx, box in enumerate(fft_peak_boxes):
box.setVisible(False) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, False)
y_limits = compute_auto_ylim(visible_abs, visible_real, visible_imag, ref_curve_for_range) y_limits = compute_auto_ylim(visible_abs, visible_real, visible_imag, ref_curve_for_range)
if refresh_auto_ranges and y_limits is not None: if refresh_auto_ranges and y_limits is not None:
@ -3222,37 +3231,25 @@ def run_pyqtgraph(args) -> None:
fft_right_line.setValue(markers["right"]) fft_right_line.setValue(markers["right"])
spec_left_line.setValue(markers["left"]) spec_left_line.setValue(markers["left"])
spec_right_line.setValue(markers["right"]) spec_right_line.setValue(markers["right"])
fft_bg_line.setVisible(True) set_peak_marker_visibility(True)
fft_left_line.setVisible(True)
fft_right_line.setVisible(True)
spec_left_line.setVisible(True)
spec_right_line.setVisible(True)
runtime.current_peak_width = markers["width"] runtime.current_peak_width = markers["width"]
runtime.current_peak_amplitude = markers["amplitude"] runtime.current_peak_amplitude = markers["amplitude"]
else: else:
fft_bg_line.setVisible(False) set_peak_marker_visibility(False)
fft_left_line.setVisible(False)
fft_right_line.setVisible(False)
spec_left_line.setVisible(False)
spec_right_line.setVisible(False)
runtime.current_peak_width = None runtime.current_peak_width = None
runtime.current_peak_amplitude = None runtime.current_peak_amplitude = None
else: else:
fft_bg_line.setVisible(False) set_peak_marker_visibility(False)
fft_left_line.setVisible(False)
fft_right_line.setVisible(False)
spec_left_line.setVisible(False)
spec_right_line.setVisible(False)
runtime.current_peak_width = None runtime.current_peak_width = None
runtime.current_peak_amplitude = None runtime.current_peak_amplitude = None
else: else:
curve_fft_real.setData([], []) clear_curve_if_needed("fft_real", curve_fft_real)
curve_fft_imag.setData([], []) clear_curve_if_needed("fft_imag", curve_fft_imag)
if fft_abs_enabled: if fft_abs_enabled:
fft_x, fft_y = sanitize_curve_data_for_display(xs_fft, fft_vals_db) fft_x, fft_y = sanitize_curve_data_for_display(xs_fft, fft_vals_db)
curve_fft.setData(fft_x, fft_y) set_curve_data("fft_abs", curve_fft, fft_x, fft_y)
else: else:
curve_fft.setData([], []) clear_curve_if_needed("fft_abs", curve_fft)
finite_fft = np.isfinite(xs_fft) & np.isfinite(fft_vals_db) finite_fft = np.isfinite(xs_fft) & np.isfinite(fft_vals_db)
y_for_range = fft_vals_db[finite_fft] if fft_abs_enabled else np.zeros((0,), dtype=np.float32) y_for_range = fft_vals_db[finite_fft] if fft_abs_enabled else np.zeros((0,), dtype=np.float32)
@ -3261,29 +3258,31 @@ def run_pyqtgraph(args) -> None:
finite_ref = np.isfinite(xs_fft) & np.isfinite(fft_ref) finite_ref = np.isfinite(xs_fft) & np.isfinite(fft_ref)
if np.any(finite_ref): if np.any(finite_ref):
ref_x, ref_y = sanitize_curve_data_for_display(xs_fft[finite_ref], fft_ref[finite_ref]) ref_x, ref_y = sanitize_curve_data_for_display(xs_fft[finite_ref], fft_ref[finite_ref])
curve_fft_ref.setData(ref_x, ref_y) set_curve_data("fft_ref", curve_fft_ref, ref_x, ref_y)
curve_fft_ref.setVisible(True) set_item_visible_if_changed("fft_ref", curve_fft_ref, True)
y_for_range = np.concatenate((y_for_range, fft_ref[finite_ref])) y_for_range = np.concatenate((y_for_range, fft_ref[finite_ref]))
else: else:
curve_fft_ref.setVisible(False) set_item_visible_if_changed("fft_ref", curve_fft_ref, False)
runtime.peak_candidates = find_top_peaks_over_ref(xs_fft, fft_vals_db, fft_ref, top_n=3) runtime.peak_candidates = find_top_peaks_over_ref(xs_fft, fft_vals_db, fft_ref, top_n=3)
refresh_peak_params_label(runtime.peak_candidates) refresh_peak_params_label(runtime.peak_candidates)
for idx, box in enumerate(fft_peak_boxes): for idx, box in enumerate(fft_peak_boxes):
if idx < len(runtime.peak_candidates): if idx < len(runtime.peak_candidates):
peak = runtime.peak_candidates[idx] peak = runtime.peak_candidates[idx]
box.setData( set_curve_data(
f"fft_peak_box_{idx}",
box,
[peak["left"], peak["left"], peak["right"], peak["right"], peak["left"]], [peak["left"], peak["left"], peak["right"], peak["right"], peak["left"]],
[peak["ref"], peak["peak_y"], peak["peak_y"], peak["ref"], peak["ref"]], [peak["ref"], peak["peak_y"], peak["peak_y"], peak["ref"], peak["ref"]],
) )
box.setVisible(True) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, True)
else: else:
box.setVisible(False) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, False)
else: else:
runtime.peak_candidates = [] runtime.peak_candidates = []
refresh_peak_params_label([]) refresh_peak_params_label([])
curve_fft_ref.setVisible(False) set_item_visible_if_changed("fft_ref", curve_fft_ref, False)
for box in fft_peak_boxes: for idx, box in enumerate(fft_peak_boxes):
box.setVisible(False) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, False)
if active_background is not None and fft_abs_enabled: if active_background is not None and fft_abs_enabled:
if refresh_auto_ranges: if refresh_auto_ranges:
@ -3306,41 +3305,25 @@ def run_pyqtgraph(args) -> None:
fft_right_line.setValue(markers["right"]) fft_right_line.setValue(markers["right"])
spec_left_line.setValue(markers["left"]) spec_left_line.setValue(markers["left"])
spec_right_line.setValue(markers["right"]) spec_right_line.setValue(markers["right"])
fft_bg_line.setVisible(True) set_peak_marker_visibility(True)
fft_left_line.setVisible(True)
fft_right_line.setVisible(True)
spec_left_line.setVisible(True)
spec_right_line.setVisible(True)
runtime.current_peak_width = markers["width"] runtime.current_peak_width = markers["width"]
runtime.current_peak_amplitude = markers["amplitude"] runtime.current_peak_amplitude = markers["amplitude"]
else: else:
fft_bg_line.setVisible(False) set_peak_marker_visibility(False)
fft_left_line.setVisible(False)
fft_right_line.setVisible(False)
spec_left_line.setVisible(False)
spec_right_line.setVisible(False)
runtime.current_peak_width = None runtime.current_peak_width = None
runtime.current_peak_amplitude = None runtime.current_peak_amplitude = None
else: else:
fft_bg_line.setVisible(False) set_peak_marker_visibility(False)
fft_left_line.setVisible(False)
fft_right_line.setVisible(False)
spec_left_line.setVisible(False)
spec_right_line.setVisible(False)
runtime.current_peak_width = None runtime.current_peak_width = None
runtime.current_peak_amplitude = None runtime.current_peak_amplitude = None
else: elif refresh_fft_views:
curve_fft_ref.setVisible(False) set_item_visible_if_changed("fft_ref", curve_fft_ref, False)
curve_fft.setData([], []) clear_curve_if_needed("fft_abs", curve_fft)
curve_fft_real.setData([], []) clear_curve_if_needed("fft_real", curve_fft_real)
curve_fft_imag.setData([], []) clear_curve_if_needed("fft_imag", curve_fft_imag)
for box in fft_peak_boxes: for idx, box in enumerate(fft_peak_boxes):
box.setVisible(False) set_item_visible_if_changed(f"fft_peak_box_{idx}", box, False)
fft_bg_line.setVisible(False) set_peak_marker_visibility(False)
fft_left_line.setVisible(False)
fft_right_line.setVisible(False)
spec_left_line.setVisible(False)
spec_right_line.setVisible(False)
runtime.current_peak_width = None runtime.current_peak_width = None
runtime.current_peak_amplitude = None runtime.current_peak_amplitude = None
runtime.peak_candidates = [] runtime.peak_candidates = []
@ -3386,9 +3369,9 @@ def run_pyqtgraph(args) -> None:
status_parts.append(f"ui wf/{last_heavy_refresh_stride}") status_parts.append(f"ui wf/{last_heavy_refresh_stride}")
status_suffix = " | ".join(status_parts) status_suffix = " | ".join(status_parts)
if status_suffix: if status_suffix:
status.setText(f"{base_status} | {status_suffix}" if base_status else status_suffix) set_text_if_changed("status", status, f"{base_status} | {status_suffix}" if base_status else status_suffix)
else: else:
status.setText(base_status) set_text_if_changed("status", status, base_status)
except Exception: except Exception:
pass pass
status_dirty = False status_dirty = False
@ -3399,14 +3382,15 @@ def run_pyqtgraph(args) -> None:
if chs is None: if chs is None:
chs = runtime.current_info.get("ch") if isinstance(runtime.current_info, dict) else None chs = runtime.current_info.get("ch") if isinstance(runtime.current_info, dict) else None
if chs is None: if chs is None:
ch_text.setText("") set_text_if_changed("channel_text", ch_text, "")
else: else:
if isinstance(chs, (list, tuple, set)): if isinstance(chs, (list, tuple, set)):
ch_list = sorted(int(v) for v in chs) ch_list = sorted(int(v) for v in chs)
ch_text_val = ", ".join(str(v) for v in ch_list) ch_text_val = ", ".join(str(v) for v in ch_list)
else: else:
ch_text_val = str(int(chs)) ch_text_val = str(int(chs))
ch_text.setText(f"chs {ch_text_val}") set_text_if_changed("channel_text", ch_text, f"chs {ch_text_val}")
if refresh_line_views or refresh_auto_ranges:
(x0, x1), (y0, y1) = p_line.viewRange() (x0, x1), (y0, y1) = p_line.viewRange()
dx = 0.01 * max(1.0, float(x1 - x0)) dx = 0.01 * max(1.0, float(x1 - x0))
dy = 0.01 * max(1.0, float(y1 - y0)) dy = 0.01 * max(1.0, float(y1 - y0))