Skip to content

Commit 14dfcf8

Browse files
committed
Updated ffteeg code(contains notch, high and low pass filters)
1 parent 9384bb7 commit 14dfcf8

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

applications/ffteeg.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import pyqtgraph as pg
77
import pylsl
88
import sys
9-
from scipy.signal import butter, filtfilt
9+
from scipy.signal import butter, filtfilt, iirnotch
1010
from scipy.fft import fft
1111

1212
class EEGMonitor(QMainWindow):
@@ -27,7 +27,7 @@ def __init__(self):
2727
self.eeg_plot_widget.setLabel('bottom', 'EEG Plot')
2828
self.eeg_plot_widget.setYRange(0, 15000, padding=0)
2929
self.eeg_plot_widget.setXRange(0, 10, padding=0)
30-
self.eeg_plot_widget.setMouseEnabled(x=False, y=False) # Disable zoom
30+
self.eeg_plot_widget.setMouseEnabled(x=False, y=True) # Disable zoom
3131
self.main_layout.addWidget(self.eeg_plot_widget)
3232

3333
# Second half for FFT and Brainwave Power, aligned horizontally
@@ -77,6 +77,10 @@ def __init__(self):
7777
self.time_data = np.linspace(0, 10, self.buffer_size) # Fixed time array for plotting
7878
self.current_index = 0 # Index for overwriting data
7979

80+
# Notch filter at 50 Hz
81+
self.b_notch, self.a_notch = iirnotch(50, 30, self.sampling_rate)
82+
# High-pass filter (cutoff at 0.5 Hz)
83+
self.b_highpass, self.a_highpass = butter(4, 0.5 / (0.5 * self.sampling_rate), btype='high')
8084
# Low-pass filter (4th order, cutoff at 45 Hz)
8185
self.b_lowpass, self.a_lowpass = butter(4, 45 / (0.5 * self.sampling_rate), btype='low')
8286

@@ -96,15 +100,27 @@ def update_plot(self):
96100
self.eeg_data[self.current_index] = sample[0]
97101
self.current_index = (self.current_index + 1) % self.buffer_size # Circular increment
98102

99-
# Apply low-pass filter
100-
filtered_eeg = filtfilt(self.b_lowpass, self.a_lowpass, self.eeg_data)
103+
if self.current_index >= self.buffer_size:
104+
plot_data = self.eeg_data
105+
else:
106+
plot_data = np.concatenate((self.eeg_data[self.current_index:], self.eeg_data[:self.current_index]))
107+
108+
# Apply filters to the full data for EEG plot
109+
filtered_eeg = filtfilt(self.b_notch, self.a_notch, plot_data)
110+
filtered_eeg = filtfilt(self.b_highpass, self.a_highpass, filtered_eeg)
111+
filtered_eeg = filtfilt(self.b_lowpass, self.a_lowpass, filtered_eeg)
101112

102113
# Update the EEG plot with the filtered data
103114
self.eeg_curve.setData(self.time_data, filtered_eeg)
104115

105-
# Perform FFT with windowing (Hamming window)
106-
window = hamming(len(filtered_eeg)) # Apply Hamming window to reduce spectral leakage
107-
filtered_eeg_windowed = filtered_eeg * window # Element-wise multiply
116+
# Perform FFT on the latest 1-second slice
117+
latest_data = plot_data[-self.sampling_rate:] # Most recent 1-second data
118+
window = hamming(len(latest_data))
119+
filtered_eeg_windowed = latest_data * window
120+
121+
# Apply zero-padding
122+
zero_padded_length = 2048
123+
filtered_eeg_windowed_padded = np.pad(filtered_eeg_windowed, (0, zero_padded_length - len(filtered_eeg_windowed)), 'constant')
108124

109125
eeg_fft = np.abs(fft(filtered_eeg_windowed))[:len(filtered_eeg_windowed) // 2] # Positive frequencies only
110126
freqs = np.fft.fftfreq(len(filtered_eeg_windowed), 1 / self.sampling_rate)[:len(filtered_eeg_windowed) // 2]

0 commit comments

Comments
 (0)