Compare commits

..

3 Commits

Author SHA1 Message Date
71f23e3a96 Merge pull request 'recording performance improvements' (#16) from sred-recording-fix into main
Some checks failed
Build Sphinx Docs Set / Build Docs (push) Successful in 8s
Build Project / Build Project (3.10) (push) Successful in 34s
Build Project / Build Project (3.11) (push) Successful in 31s
Build Project / Build Project (3.12) (push) Successful in 30s
Test with tox / Test with tox (3.10) (push) Failing after 29s
Test with tox / Test with tox (3.11) (push) Successful in 22s
Test with tox / Test with tox (3.12) (push) Successful in 22s
Reviewed-on: #16
2026-01-27 12:56:38 -05:00
ben
0178adcdb5 lint fix
Some checks failed
Build Sphinx Docs Set / Build Docs (pull_request) Successful in 7s
Build Project / Build Project (3.10) (pull_request) Successful in 33s
Build Project / Build Project (3.11) (pull_request) Successful in 30s
Build Project / Build Project (3.12) (pull_request) Successful in 32s
Test with tox / Test with tox (3.11) (pull_request) Successful in 23s
Test with tox / Test with tox (3.12) (pull_request) Successful in 22s
Test with tox / Test with tox (3.10) (pull_request) Failing after 27s
2026-01-27 12:49:09 -05:00
ben
0ee6f5e63f recording performance improvements
Some checks failed
Build Sphinx Docs Set / Build Docs (pull_request) Successful in 8s
Build Project / Build Project (3.10) (pull_request) Successful in 34s
Build Project / Build Project (3.11) (pull_request) Successful in 31s
Test with tox / Test with tox (3.10) (pull_request) Failing after 26s
Build Project / Build Project (3.12) (pull_request) Successful in 30s
Test with tox / Test with tox (3.11) (pull_request) Successful in 23s
Test with tox / Test with tox (3.12) (pull_request) Successful in 22s
2026-01-27 12:44:27 -05:00

View File

@ -54,6 +54,18 @@ def spectrogram(rec: Recording, thumbnail: bool = False) -> Figure:
frequencies_shifted = np.fft.fftshift(frequencies) frequencies_shifted = np.fft.fftshift(frequencies)
Sxx_shifted = np.fft.fftshift(Sxx_log_norm, axes=0) Sxx_shifted = np.fft.fftshift(Sxx_log_norm, axes=0)
# Downsample heatmap for performance (max 500x500 = 250,000 points)
max_freq_bins = 500
max_time_bins = 500
freq_step = max(1, len(frequencies_shifted) // max_freq_bins)
time_step = max(1, len(times) // max_time_bins)
if freq_step > 1 or time_step > 1:
Sxx_shifted = Sxx_shifted[::freq_step, ::time_step]
frequencies_shifted = frequencies_shifted[::freq_step]
times = times[::time_step]
fig = go.Figure( fig = go.Figure(
data=go.Heatmap( data=go.Heatmap(
z=Sxx_shifted, z=Sxx_shifted,
@ -102,11 +114,19 @@ def iq_time_series(rec: Recording) -> Figure:
complex_signal = rec.data[0] complex_signal = rec.data[0]
sample_rate = int(rec.metadata.get("sample_rate", 1)) sample_rate = int(rec.metadata.get("sample_rate", 1))
plot_length = len(complex_signal) plot_length = len(complex_signal)
t = np.arange(0, plot_length, 1) / sample_rate # Downsample for performance (max 10,000 points)
max_points = 10000
step = max(1, plot_length // max_points)
if step > 1:
complex_signal = complex_signal[::step]
plot_length = len(complex_signal)
t = np.arange(0, plot_length, 1) * step / sample_rate
fig = go.Figure() fig = go.Figure()
fig.add_trace(go.Scatter(x=t, y=complex_signal.real, mode="lines", name="I (In-phase)", line=dict(width=0.6))) # Use Scattergl for WebGL-accelerated rendering
fig.add_trace(go.Scatter(x=t, y=complex_signal.imag, mode="lines", name="Q (Quadrature)", line=dict(width=0.6))) fig.add_trace(go.Scattergl(x=t, y=complex_signal.real, mode="lines", name="I (In-phase)", line=dict(width=0.6)))
fig.add_trace(go.Scattergl(x=t, y=complex_signal.imag, mode="lines", name="Q (Quadrature)", line=dict(width=0.6)))
fig.update_layout( fig.update_layout(
title="IQ Time Series", title="IQ Time Series",
@ -139,8 +159,15 @@ def frequency_spectrum(rec: Recording) -> Figure:
log_spectrum = np.log10(spectrum + epsilon) log_spectrum = np.log10(spectrum + epsilon)
scaled_log_spectrum = (log_spectrum - log_spectrum.min()) / (log_spectrum.max() - log_spectrum.min()) scaled_log_spectrum = (log_spectrum - log_spectrum.min()) / (log_spectrum.max() - log_spectrum.min())
# Downsample for performance (max 10,000 points)
max_points = 10000
if len(freqs) > max_points:
step = len(freqs) // max_points
freqs = freqs[::step]
scaled_log_spectrum = scaled_log_spectrum[::step]
fig = go.Figure() fig = go.Figure()
fig.add_trace(go.Scatter(x=freqs, y=scaled_log_spectrum, mode="lines", name="Spectrum", line=dict(width=0.4))) fig.add_trace(go.Scattergl(x=freqs, y=scaled_log_spectrum, mode="lines", name="Spectrum", line=dict(width=0.4)))
fig.update_layout( fig.update_layout(
title="Frequency Spectrum", title="Frequency Spectrum",
@ -174,7 +201,7 @@ def constellation(rec: Recording) -> Figure:
q_ds = complex_signal.imag[::step] q_ds = complex_signal.imag[::step]
fig = go.Figure() fig = go.Figure()
fig.add_trace(go.Scatter(x=i_ds, y=q_ds, mode="lines", name="Constellation", line=dict(width=0.2))) fig.add_trace(go.Scattergl(x=i_ds, y=q_ds, mode="lines", name="Constellation", line=dict(width=0.2)))
fig.update_layout( fig.update_layout(
title="Constellation", title="Constellation",
@ -221,7 +248,7 @@ def power_spectral_density(rec: Recording) -> Figure:
fig = go.Figure() fig = go.Figure()
fig.add_trace( fig.add_trace(
go.Scatter(x=frequencies_shifted, y=psd_db, mode="lines", name="PSD", line=dict(width=0.8, color="#00D9FF")) go.Scattergl(x=frequencies_shifted, y=psd_db, mode="lines", name="PSD", line=dict(width=0.8, color="#00D9FF"))
) )
fig.update_layout( fig.update_layout(
@ -257,8 +284,16 @@ def fft_plot(rec: Recording) -> Figure:
magnitude = np.abs(fft_result) magnitude = np.abs(fft_result)
magnitude_db = 20 * np.log10(magnitude + 1e-10) magnitude_db = 20 * np.log10(magnitude + 1e-10)
max_points = 10000
if len(freqs) > max_points:
step = len(freqs) // max_points
freqs = freqs[::step]
magnitude_db = magnitude_db[::step]
fig = go.Figure() fig = go.Figure()
fig.add_trace(go.Scatter(x=freqs, y=magnitude_db, mode="lines", name="FFT", line=dict(width=0.6, color="#FF6B9D"))) fig.add_trace(
go.Scattergl(x=freqs, y=magnitude_db, mode="lines", name="FFT", line=dict(width=0.6, color="#FF6B9D"))
)
fig.update_layout( fig.update_layout(
title="FFT Magnitude", title="FFT Magnitude",
@ -314,6 +349,18 @@ def spectrogram_3d(rec: Recording) -> Figure:
frequencies_shifted = np.fft.fftshift(frequencies) frequencies_shifted = np.fft.fftshift(frequencies)
Sxx_shifted = np.fft.fftshift(Sxx_log, axes=0) Sxx_shifted = np.fft.fftshift(Sxx_log, axes=0)
# Downsample to prevent browser memory issues (max ~40,000 total points)
max_freq_bins = 200
max_time_bins = 200
freq_step = max(1, len(frequencies_shifted) // max_freq_bins)
time_step = max(1, len(times) // max_time_bins)
if freq_step > 1 or time_step > 1:
Sxx_shifted = Sxx_shifted[::freq_step, ::time_step]
frequencies_shifted = frequencies_shifted[::freq_step]
times = times[::time_step]
fig = go.Figure( fig = go.Figure(
data=[ data=[
go.Surface( go.Surface(