diff --git a/src/ria_toolkit_oss/view/view_signal.py b/src/ria_toolkit_oss/view/view_signal.py index b045e0e..2d94efa 100644 --- a/src/ria_toolkit_oss/view/view_signal.py +++ b/src/ria_toolkit_oss/view/view_signal.py @@ -1,3 +1,4 @@ +import gc import os import textwrap from typing import Optional @@ -8,6 +9,7 @@ from matplotlib import gridspec from PIL import Image from scipy.fft import fft, fftshift from scipy.signal import spectrogram +from scipy.signal.windows import hann from ria_toolkit_oss.datatypes.recording import Recording from ria_toolkit_oss.view.tools import ( @@ -122,7 +124,7 @@ def view_sig( plot_y_indx = plot_y_indx + 2 fft_size = get_fft_size(plot_length=plot_length) - f, t_spec, Sxx = spectrogram( + _, t_spec, Sxx = spectrogram( complex_signal[:plot_length], fs=sample_rate, nperseg=fft_size, @@ -132,14 +134,16 @@ def view_sig( ) # shift frequencies so zero is centered + f_bins = np.fft.fftfreq(fft_size, d=1.0 / sample_rate) + f_bins = np.fft.fftshift(f_bins) + f_bins = f_bins + center_frequency Sxx = np.fft.fftshift(Sxx, axes=0) - f = np.fft.fftshift(f) - sample_rate / 2 + center_frequency spec_ax.imshow( 10 * np.log10(Sxx + 1e-12), aspect="auto", origin="lower", - extent=[t_spec[0], t_spec[-1], f[0], f[-1]], + extent=[t_spec[0], t_spec[-1], f_bins[0], f_bins[-1]], cmap="twilight", ) @@ -169,18 +173,17 @@ def view_sig( freq_ax = plt.subplot(gs[plot_y_indx : plot_y_indx + 2, :]) plot_y_indx = plot_y_indx + 2 - epsilon = 1e-10 - spectrum = np.abs(fftshift(fft(complex_signal[0:plot_length]))) - freqs = ( - np.linspace(-1 * (sample_rate / 2), (sample_rate / 2), len(complex_signal[0:plot_length])) - + center_frequency - ) + # Apply window to reduce spectral leakage + window = hann(len(complex_signal[:plot_length])) + spectrum = np.abs(fftshift(fft(complex_signal[:plot_length] * window))) - # Use semi-log for the y-axis - freq_ax.semilogy(freqs, spectrum + epsilon, color=COLORS["accent"], linewidth=0.8) - freq_ax.set_xlabel("Frequency") - freq_ax.set_ylabel("Magnitude") - freq_ax.set_title("Frequency Spectrum", fontsize=subtitle_fontsize) + # Convert to dB + spectrum_db = 20 * np.log10(spectrum + 1e-12) # 20*log for magnitude + + freqs = np.linspace(-sample_rate / 2, sample_rate / 2, len(complex_signal[:plot_length])) + center_frequency + freq_ax.plot(freqs, spectrum_db, color=COLORS["accent"], linewidth=0.8) + freq_ax.set_ylabel("Magnitude (dB)") + freq_ax.set_title("Frequency Spectrum (Windowed FFT)", fontsize=subtitle_fontsize) set_spines(freq_ax, spines) if constellation: @@ -255,3 +258,7 @@ def view_sig( output_path, _ = set_path(output_path=output_path) plt.savefig(output_path, dpi=dpi) print(f"Saved signal plot to {output_path}") + + # Garbage collection and clean up to prevent memory overloading + plt.close("all") + gc.collect() diff --git a/src/ria_toolkit_oss/view/view_signal_simple.py b/src/ria_toolkit_oss/view/view_signal_simple.py index ec5570e..cbca651 100644 --- a/src/ria_toolkit_oss/view/view_signal_simple.py +++ b/src/ria_toolkit_oss/view/view_signal_simple.py @@ -2,6 +2,7 @@ from __future__ import annotations +import gc from typing import Optional import matplotlib @@ -318,6 +319,10 @@ def view_simple_sig( return output_path plt.show() + + # Garbage collection and clean up to prevent memory overloading + plt.close("all") + gc.collect() return None