This commit is contained in:
awe
2026-02-03 15:33:09 +03:00
parent a32bef2250
commit 53ff80a522

View File

@ -2,9 +2,11 @@
Визуализация данных с использованием matplotlib. Визуализация данных с использованием matplotlib.
""" """
import csv
import sys import sys
import threading import threading
import time import time
from datetime import datetime
from queue import Empty, Queue from queue import Empty, Queue
from typing import Optional, Tuple from typing import Optional, Tuple
@ -57,6 +59,35 @@ def run_matplotlib(args):
ring = None # type: Optional[np.ndarray] ring = None # type: Optional[np.ndarray]
ring_time = None # type: Optional[np.ndarray] ring_time = None # type: Optional[np.ndarray]
head = 0 head = 0
# Медианные данные для вычитания
median_data: Optional[np.ndarray] = None
median_subtract_enabled = False
# CLI параметры для автоматического сохранения/загрузки
ref_out_file = getattr(args, 'ref_out', None)
ref_in_file = getattr(args, 'ref_in', None)
ref_out_saved = False # Флаг, что медиана уже сохранена
# Автоматическая загрузка медианы при старте
if ref_in_file:
try:
data = []
with open(ref_in_file, 'r') as f:
reader = csv.reader(f)
next(reader) # Пропускаем заголовок
for row in reader:
if len(row) >= 2:
try:
data.append(float(row[1]))
except ValueError:
continue
if data:
median_data = np.array(data, dtype=np.float32)
median_subtract_enabled = True
print(f"[ref-in] Загружена медиана из {ref_in_file} ({len(median_data)} точек), вычитание включено")
else:
print(f"[ref-in] Предупреждение: файл {ref_in_file} пустой или неверный формат")
except Exception as e:
print(f"[ref-in] Ошибка загрузки {ref_in_file}: {e}")
# Авто-уровни цветовой шкалы водопада сырых данных пересчитываются по видимой области. # Авто-уровни цветовой шкалы водопада сырых данных пересчитываются по видимой области.
# FFT состояние (полное FFT для отрицательных частот) # FFT состояние (полное FFT для отрицательных частот)
fft_bins = FFT_LEN fft_bins = FFT_LEN
@ -268,6 +299,14 @@ def run_matplotlib(args):
nonlocal ring_phase, prev_phase_per_bin, phase_offset_per_bin, y_min_phase, y_max_phase nonlocal ring_phase, prev_phase_per_bin, phase_offset_per_bin, y_min_phase, y_max_phase
if s is None or s.size == 0 or ring is None: if s is None or s.size == 0 or ring is None:
return return
# Применяем вычитание медианы если включено
if median_subtract_enabled and median_data is not None:
take_median = min(s.size, median_data.size)
s_corrected = s.copy()
s_corrected[:take_median] = s[:take_median] - median_data[:take_median]
s = s_corrected
# Нормализуем длину до фиксированной ширины # Нормализуем длину до фиксированной ширины
w = ring.shape[1] w = ring.shape[1]
row = np.full((w,), np.nan, dtype=np.float32) row = np.full((w,), np.nan, dtype=np.float32)
@ -551,6 +590,31 @@ def run_matplotlib(args):
if changed and current_info: if changed and current_info:
status_text.set_text(format_status_kv(current_info)) status_text.set_text(format_status_kv(current_info))
# Автоматическое сохранение медианы при накоплении 1000+ свипов
if ref_out_file and not ref_out_saved and ring is not None:
nonlocal ref_out_saved
filled_count = np.count_nonzero(~np.isnan(ring[:, 0]))
if filled_count >= 1000:
try:
# Получаем последние 1000 свипов
ordered = ring if head == 0 else np.roll(ring, -head, axis=0)
recent_sweeps = ordered[-1000:, :]
median_sweep = np.nanmedian(recent_sweeps, axis=0)
# Сохраняем в файл
with open(ref_out_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Index', 'Median_Value'])
for i, value in enumerate(median_sweep):
if np.isfinite(value):
writer.writerow([i, float(value)])
ref_out_saved = True
print(f"[ref-out] Сохранена медиана 1000 свипов в {ref_out_file}")
status_text.set_text(f"[ref-out] Сохранено в {ref_out_file}")
except Exception as e:
print(f"[ref-out] Ошибка сохранения: {e}")
# Возвращаем обновлённые артисты # Возвращаем обновлённые артисты
return (line_obj, img_obj, fft_line_obj, img_fft_obj, phase_line_obj, img_phase_obj, status_text) return (line_obj, img_obj, fft_line_obj, img_fft_obj, phase_line_obj, img_phase_obj, status_text)