fix
This commit is contained in:
@ -74,6 +74,32 @@ 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"
|
||||
DISPLAY_DISTANCE_ZERO_M = 9.0
|
||||
|
||||
|
||||
def display_distance_value(distance_m: float, *, zero_at_m: float = DISPLAY_DISTANCE_ZERO_M) -> float:
|
||||
"""Map physical distance to the displayed reversed distance axis."""
|
||||
try:
|
||||
distance_val = float(distance_m)
|
||||
except Exception:
|
||||
return float("nan")
|
||||
if not np.isfinite(distance_val):
|
||||
return float("nan")
|
||||
return float(float(zero_at_m) - distance_val)
|
||||
|
||||
|
||||
def display_distance_axis(
|
||||
distance_axis: Optional[np.ndarray],
|
||||
*,
|
||||
zero_at_m: float = DISPLAY_DISTANCE_ZERO_M,
|
||||
) -> np.ndarray:
|
||||
"""Return display coordinates where physical ``zero_at_m`` is shown as 0 m."""
|
||||
if distance_axis is None:
|
||||
return np.zeros((0,), dtype=np.float64)
|
||||
axis_arr = np.asarray(distance_axis, dtype=np.float64).reshape(-1)
|
||||
if axis_arr.size <= 0:
|
||||
return np.zeros((0,), dtype=np.float64)
|
||||
return (float(zero_at_m) - axis_arr).astype(np.float64, copy=False)
|
||||
|
||||
|
||||
def sanitize_curve_data_for_display(
|
||||
@ -996,7 +1022,7 @@ def run_pyqtgraph(args) -> None:
|
||||
fft_bg_line.setVisible(False)
|
||||
fft_left_line.setVisible(False)
|
||||
fft_right_line.setVisible(False)
|
||||
p_fft.setLabel("bottom", "Расстояние, м")
|
||||
p_fft.setLabel("bottom", "Расстояние, м (0 = 9 м)")
|
||||
p_fft.setLabel("left", "Амплитуда" if complex_sweep_mode else "дБ")
|
||||
if complex_sweep_mode:
|
||||
try:
|
||||
@ -1017,7 +1043,7 @@ def run_pyqtgraph(args) -> None:
|
||||
p_spec.getAxis("bottom").setStyle(showValues=False)
|
||||
except Exception:
|
||||
pass
|
||||
p_spec.setLabel("left", "Расстояние, м")
|
||||
p_spec.setLabel("left", "Расстояние, м (0 = 9 м)")
|
||||
img_fft = pg.ImageItem()
|
||||
p_spec.addItem(img_fft)
|
||||
spec_left_line = pg.InfiniteLine(angle=0, movable=False, pen=peak_pen)
|
||||
@ -1472,7 +1498,7 @@ def run_pyqtgraph(args) -> None:
|
||||
text = f"{fft_low_cut_percent:.1f}%"
|
||||
cut_start = _active_distance_cut_start()
|
||||
if cut_start is not None and np.isfinite(cut_start):
|
||||
text = f"{text} (~{cut_start:.4g} м)"
|
||||
text = f"{text} (~{display_distance_value(cut_start):.4g} м)"
|
||||
if text == last_fft_low_cut_label_text:
|
||||
return
|
||||
try:
|
||||
@ -1501,22 +1527,31 @@ def run_pyqtgraph(args) -> None:
|
||||
|
||||
distance_bounds = resolve_axis_bounds(runtime.ring.distance_axis)
|
||||
if distance_bounds is not None:
|
||||
d_min_full, d_max = distance_bounds
|
||||
span = max(1e-9, float(d_max - d_min_full))
|
||||
set_image_rect_if_changed("fft_waterfall_rect", img_fft, 0.0, d_min_full, float(max_sweeps), span)
|
||||
display_axis_full = display_distance_axis(runtime.ring.distance_axis)
|
||||
display_bounds = resolve_axis_bounds(display_axis_full)
|
||||
if display_bounds is not None:
|
||||
d_min_display, d_max_display = display_bounds
|
||||
set_image_rect_if_changed(
|
||||
"fft_waterfall_rect",
|
||||
img_fft,
|
||||
0.0,
|
||||
d_min_display,
|
||||
float(max_sweeps),
|
||||
max(1e-9, float(d_max_display - d_min_display)),
|
||||
)
|
||||
set_xy_range_if_changed(
|
||||
"fft_waterfall_range",
|
||||
p_spec,
|
||||
x_bounds=(0, max_sweeps - 1),
|
||||
y_bounds=(d_min_full, d_max),
|
||||
y_bounds=(d_min_display, d_max_display),
|
||||
padding=0,
|
||||
)
|
||||
|
||||
d_min_fft = d_min_full
|
||||
d_cut = _active_distance_cut_start()
|
||||
if d_cut is not None and np.isfinite(d_cut):
|
||||
d_min_fft = max(float(d_min_fft), float(d_cut))
|
||||
set_x_range_if_changed("fft_x", p_fft, d_min_fft, d_max, padding=0)
|
||||
fft_axis_physical, _fft_keep = apply_distance_cut_to_axis(runtime.ring.distance_axis, d_cut)
|
||||
fft_display_bounds = resolve_axis_bounds(display_distance_axis(fft_axis_physical))
|
||||
if fft_display_bounds is not None:
|
||||
set_x_range_if_changed("fft_x", p_fft, fft_display_bounds[0], fft_display_bounds[1], padding=0)
|
||||
refresh_fft_low_cut_label()
|
||||
|
||||
def resolve_curve_xs(size: int) -> np.ndarray:
|
||||
@ -2422,7 +2457,7 @@ def run_pyqtgraph(args) -> None:
|
||||
if idx < len(peaks):
|
||||
peak = peaks[idx]
|
||||
lines.append(f"peak {idx + 1}:")
|
||||
lines.append(f" X: {peak['x']:.4g} m")
|
||||
lines.append(f" X: {display_distance_value(peak['x']):.4g} m")
|
||||
lines.append(f" H: {peak['height']:.4g} dB")
|
||||
lines.append(f" W: {peak['width']:.4g} m")
|
||||
else:
|
||||
@ -3151,7 +3186,8 @@ def run_pyqtgraph(args) -> None:
|
||||
fft_complex_plot = fft_complex_plot[fft_keep_mask]
|
||||
elif fft_complex_plot is not None:
|
||||
fft_complex_plot = None
|
||||
fft_x_bounds = resolve_axis_bounds(xs_fft)
|
||||
xs_fft_display = display_distance_axis(xs_fft)
|
||||
fft_x_bounds = resolve_axis_bounds(xs_fft_display)
|
||||
if fft_x_bounds is not None:
|
||||
set_x_range_if_changed("fft_x", p_fft, fft_x_bounds[0], fft_x_bounds[1], padding=0)
|
||||
|
||||
@ -3168,17 +3204,17 @@ def run_pyqtgraph(args) -> None:
|
||||
show_imag=fft_imag_enabled,
|
||||
)
|
||||
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_display[: visible_abs.size], visible_abs)
|
||||
set_curve_data("fft_abs", curve_fft, abs_x, abs_y)
|
||||
else:
|
||||
clear_curve_if_needed("fft_abs", curve_fft)
|
||||
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_display[: visible_real.size], visible_real)
|
||||
set_curve_data("fft_real", curve_fft_real, real_x, real_y)
|
||||
else:
|
||||
clear_curve_if_needed("fft_real", curve_fft_real)
|
||||
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_display[: visible_imag.size], visible_imag)
|
||||
set_curve_data("fft_imag", curve_fft_imag, imag_x, imag_y)
|
||||
else:
|
||||
clear_curve_if_needed("fft_imag", curve_fft_imag)
|
||||
@ -3188,7 +3224,7 @@ def run_pyqtgraph(args) -> None:
|
||||
finite_ref = np.isfinite(xs_fft) & np.isfinite(fft_ref_db)
|
||||
if np.any(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_display[finite_ref], fft_ref_lin)
|
||||
set_curve_data("fft_ref", curve_fft_ref, ref_x, ref_y)
|
||||
set_item_visible_if_changed("fft_ref", curve_fft_ref, True)
|
||||
ref_curve_for_range = fft_ref_lin
|
||||
@ -3208,7 +3244,12 @@ def run_pyqtgraph(args) -> None:
|
||||
set_curve_data(
|
||||
f"fft_peak_box_{idx}",
|
||||
box,
|
||||
display_distance_axis(
|
||||
np.asarray(
|
||||
[peak["left"], peak["left"], peak["right"], peak["right"], peak["left"]],
|
||||
dtype=np.float64,
|
||||
)
|
||||
),
|
||||
y_box,
|
||||
)
|
||||
set_item_visible_if_changed(f"fft_peak_box_{idx}", box, True)
|
||||
@ -3229,10 +3270,10 @@ def run_pyqtgraph(args) -> None:
|
||||
markers = find_peak_width_markers(xs_fft, fft_vals_db)
|
||||
if markers is not None:
|
||||
fft_bg_line.setValue(float(_db_to_linear_amplitude(np.asarray([markers["background"]]))[0]))
|
||||
fft_left_line.setValue(markers["left"])
|
||||
fft_right_line.setValue(markers["right"])
|
||||
spec_left_line.setValue(markers["left"])
|
||||
spec_right_line.setValue(markers["right"])
|
||||
fft_left_line.setValue(display_distance_value(markers["left"]))
|
||||
fft_right_line.setValue(display_distance_value(markers["right"]))
|
||||
spec_left_line.setValue(display_distance_value(markers["left"]))
|
||||
spec_right_line.setValue(display_distance_value(markers["right"]))
|
||||
set_peak_marker_visibility(True)
|
||||
runtime.current_peak_width = markers["width"]
|
||||
runtime.current_peak_amplitude = markers["amplitude"]
|
||||
@ -3248,7 +3289,7 @@ def run_pyqtgraph(args) -> None:
|
||||
clear_curve_if_needed("fft_real", curve_fft_real)
|
||||
clear_curve_if_needed("fft_imag", curve_fft_imag)
|
||||
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_display, fft_vals_db)
|
||||
set_curve_data("fft_abs", curve_fft, fft_x, fft_y)
|
||||
else:
|
||||
clear_curve_if_needed("fft_abs", curve_fft)
|
||||
@ -3259,7 +3300,7 @@ def run_pyqtgraph(args) -> None:
|
||||
fft_ref = rolling_median_ref(xs_fft, fft_vals_db, peak_ref_window)
|
||||
finite_ref = np.isfinite(xs_fft) & np.isfinite(fft_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_display[finite_ref], fft_ref[finite_ref])
|
||||
set_curve_data("fft_ref", curve_fft_ref, ref_x, ref_y)
|
||||
set_item_visible_if_changed("fft_ref", curve_fft_ref, True)
|
||||
y_for_range = np.concatenate((y_for_range, fft_ref[finite_ref]))
|
||||
@ -3273,7 +3314,12 @@ def run_pyqtgraph(args) -> None:
|
||||
set_curve_data(
|
||||
f"fft_peak_box_{idx}",
|
||||
box,
|
||||
display_distance_axis(
|
||||
np.asarray(
|
||||
[peak["left"], peak["left"], peak["right"], peak["right"], peak["left"]],
|
||||
dtype=np.float64,
|
||||
)
|
||||
),
|
||||
[peak["ref"], peak["peak_y"], peak["peak_y"], peak["ref"], peak["ref"]],
|
||||
)
|
||||
set_item_visible_if_changed(f"fft_peak_box_{idx}", box, True)
|
||||
@ -3303,10 +3349,10 @@ def run_pyqtgraph(args) -> None:
|
||||
markers = find_peak_width_markers(xs_fft, fft_vals_db)
|
||||
if markers is not None:
|
||||
fft_bg_line.setValue(markers["background"])
|
||||
fft_left_line.setValue(markers["left"])
|
||||
fft_right_line.setValue(markers["right"])
|
||||
spec_left_line.setValue(markers["left"])
|
||||
spec_right_line.setValue(markers["right"])
|
||||
fft_left_line.setValue(display_distance_value(markers["left"]))
|
||||
fft_right_line.setValue(display_distance_value(markers["right"]))
|
||||
spec_left_line.setValue(display_distance_value(markers["left"]))
|
||||
spec_right_line.setValue(display_distance_value(markers["right"]))
|
||||
set_peak_marker_visibility(True)
|
||||
runtime.current_peak_width = markers["width"]
|
||||
runtime.current_peak_amplitude = markers["amplitude"]
|
||||
@ -3494,7 +3540,11 @@ def run_pyqtgraph(args) -> None:
|
||||
and runtime.ring.y_min_fft != runtime.ring.y_max_fft
|
||||
):
|
||||
levels = (runtime.ring.y_min_fft, runtime.ring.y_max_fft)
|
||||
distance_bounds = resolve_axis_bounds(disp_fft_axis)
|
||||
disp_fft_display_axis = display_distance_axis(disp_fft_axis)
|
||||
if disp_fft_display_axis.size == disp_fft.shape[0]:
|
||||
disp_fft = disp_fft[::-1, :]
|
||||
disp_fft_display_axis = disp_fft_display_axis[::-1]
|
||||
distance_bounds = resolve_axis_bounds(disp_fft_display_axis)
|
||||
if distance_bounds is not None:
|
||||
d_min, d_max = distance_bounds
|
||||
set_image_rect_if_changed("fft_waterfall_rect", img_fft, 0.0, d_min, float(max_sweeps), max(1e-9, d_max - d_min))
|
||||
|
||||
@ -20,6 +20,8 @@ from rfg_adc_plotter.gui.pyqtgraph_backend import (
|
||||
convert_tty_i16_to_voltage,
|
||||
decimate_bscan_rows_for_display,
|
||||
decimate_curve_for_display,
|
||||
display_distance_axis,
|
||||
display_distance_value,
|
||||
fft_bscan_image_to_db,
|
||||
is_short_sweep,
|
||||
resolve_axis_bounds,
|
||||
@ -546,6 +548,13 @@ class ProcessingTests(unittest.TestCase):
|
||||
self.assertTrue(bool(keep_mask[-1]))
|
||||
self.assertAlmostEqual(float(cut_axis[0]), 3.0, places=6)
|
||||
|
||||
def test_display_distance_axis_zero_is_at_nine_meters(self):
|
||||
axis = np.asarray([0.0, 4.5, 9.0], dtype=np.float64)
|
||||
display_axis = display_distance_axis(axis)
|
||||
|
||||
np.testing.assert_allclose(display_axis, np.asarray([9.0, 4.5, 0.0], dtype=np.float64))
|
||||
self.assertAlmostEqual(display_distance_value(9.0), 0.0, places=12)
|
||||
|
||||
def test_resolve_initial_window_size_stays_within_small_screen(self):
|
||||
width, height = resolve_initial_window_size(800, 480)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user