3 freq diversion

This commit is contained in:
awe
2026-03-02 15:43:41 +03:00
parent 8cc21316e7
commit 1e05b1f3fd
7 changed files with 193 additions and 27 deletions

View File

@ -10,7 +10,12 @@ from rfg_adc_plotter.constants import (
FREQ_MIN_GHZ,
WF_WIDTH,
)
from rfg_adc_plotter.processing.fourier import compute_ifft_profile_from_sweep
from rfg_adc_plotter.processing.fourier import (
build_frequency_axis_hz,
compute_ifft_profile_from_sweep,
perform_ifft_depth_response,
reconstruct_complex_spectrum_from_real_trace,
)
class RingBuffer:
@ -38,6 +43,17 @@ class RingBuffer:
self.y_max_fft: Optional[float] = None
# FFT последнего свипа (для отображения без повторного вычисления)
self.last_fft_vals: Optional[np.ndarray] = None
# FFT-профили по третям входного частотного диапазона (для line-plot).
self.last_fft_third_axes_m: tuple[Optional[np.ndarray], Optional[np.ndarray], Optional[np.ndarray]] = (
None,
None,
None,
)
self.last_fft_third_vals: tuple[Optional[np.ndarray], Optional[np.ndarray], Optional[np.ndarray]] = (
None,
None,
None,
)
@property
def is_ready(self) -> bool:
@ -64,6 +80,8 @@ class RingBuffer:
self.fft_depth_axis_m = None
self.fft_bins = 0
self.last_fft_vals = None
self.last_fft_third_axes_m = (None, None, None)
self.last_fft_third_vals = (None, None, None)
self.y_min_fft = None
self.y_max_fft = None
return True
@ -94,6 +112,11 @@ class RingBuffer:
self._push_fft(s)
def _push_fft(self, s: np.ndarray):
empty_thirds = (
np.zeros((0,), dtype=np.float32),
np.zeros((0,), dtype=np.float32),
np.zeros((0,), dtype=np.float32),
)
depth_axis_m, fft_row = compute_ifft_profile_from_sweep(
s,
complex_mode=self.fft_complex_mode,
@ -103,6 +126,8 @@ class RingBuffer:
n = min(int(fft_row.size), int(depth_axis_m.size))
if n <= 0:
self.last_fft_third_axes_m = empty_thirds
self.last_fft_third_vals = empty_thirds
return
if n != fft_row.size:
fft_row = fft_row[:n]
@ -144,6 +169,7 @@ class RingBuffer:
prev_head = (self.head - 1) % self.ring_fft.shape[0]
self.ring_fft[prev_head, :] = fft_row
self.last_fft_vals = fft_row
self.last_fft_third_axes_m, self.last_fft_third_vals = self._compute_fft_thirds(s)
fr_min = np.nanmin(fft_row)
fr_max = float(np.nanpercentile(fft_row, 90))
@ -152,6 +178,65 @@ class RingBuffer:
if self.y_max_fft is None or (not np.isnan(fr_max) and fr_max > self.y_max_fft):
self.y_max_fft = float(fr_max)
def _compute_fft_thirds(
self, s: np.ndarray
) -> tuple[tuple[np.ndarray, np.ndarray, np.ndarray], tuple[np.ndarray, np.ndarray, np.ndarray]]:
sweep = np.asarray(s, dtype=np.float64).ravel()
total = int(sweep.size)
def _empty() -> np.ndarray:
return np.zeros((0,), dtype=np.float32)
if total <= 0:
return (_empty(), _empty(), _empty()), (_empty(), _empty(), _empty())
freq_hz = build_frequency_axis_hz(total)
edges = np.linspace(0, total, 4, dtype=np.int64)
axes: list[np.ndarray] = []
vals: list[np.ndarray] = []
for idx in range(3):
i0 = int(edges[idx])
i1 = int(edges[idx + 1])
if i1 - i0 < 2:
axes.append(_empty())
vals.append(_empty())
continue
seg = sweep[i0:i1]
seg_freq = freq_hz[i0:i1]
seg_complex = reconstruct_complex_spectrum_from_real_trace(
seg,
complex_mode=self.fft_complex_mode,
)
depth_m, seg_fft = perform_ifft_depth_response(seg_complex, seg_freq, axis="abs")
depth_m = np.asarray(depth_m, dtype=np.float32).ravel()
seg_fft = np.asarray(seg_fft, dtype=np.float32).ravel()
n = min(int(depth_m.size), int(seg_fft.size))
if n <= 0:
axes.append(_empty())
vals.append(_empty())
continue
depth_m = depth_m[:n]
seg_fft = seg_fft[:n]
n_keep = max(1, (n + 1) // 2)
axes.append(depth_m[:n_keep])
vals.append(seg_fft[:n_keep])
return (
axes[0],
axes[1],
axes[2],
), (
vals[0],
vals[1],
vals[2],
)
def get_display_ring(self) -> np.ndarray:
"""Кольцо в порядке от старого к новому, ось времени по X. Форма: (width, time)."""
if self.ring is None: