Skip to content

Commit 69ce5cc

Browse files
authored
Merge pull request #429 from Mentalab-hub/asr-testing
Asr testing
2 parents 01783a7 + 6fd9257 commit 69ce5cc

3 files changed

Lines changed: 19 additions & 14 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ dependencies = [
4242
'pyyaml',
4343
'bleak==0.22.3',
4444
'pylsl',
45-
'numba']
45+
'numba',
46+
'eegprep']
4647

4748
[tool.setuptools]
4849
package-dir = {"" = "src"}

src/explorepy/asr_processor.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
asr_process
1818
)
1919

20-
from explorepy.filters import ExGFilter
21-
20+
from explorepy.filters import bp_filter
2221

2322
logger = logging.getLogger(__name__)
2423

@@ -137,7 +136,6 @@ def __init__(self, stream_proc, in_topic):
137136
self.instantiate_buffers()
138137
self.is_initialized = True
139138
self.lifecycle_state = State.STABLE
140-
self.filter = None
141139

142140
@property
143141
def cutoff(self):
@@ -186,12 +184,11 @@ def on_calib_data_received(self, packet):
186184
"Error writing calibration packet, timer has not been set correctly or calibration length is invalid!"
187185
)
188186
if (time.time() - self.calib_started_at) > self.calibration_length:
189-
self.calibration_data_available = True
190187
self.stop_calibration()
191188
return
192189
self.calibration_data_input = np.append(
193190
self.calibration_data_input,
194-
self.filter.apply(packet, in_place=False).get_data()[1],
191+
packet.get_data()[1],
195192
axis=1,
196193
)
197194

@@ -222,8 +219,10 @@ def clean_data(self):
222219
return
223220
if self.to_clean_ts[0][0] <= 1.0:
224221
return
222+
filt_sig = bp_filter(self.to_clean.copy(), 45, 55, btype='bandstop', fs=self.sr)
223+
filtered_data = bp_filter(filt_sig, .1, 40, fs=self.sr)
225224
try:
226-
ret = asr_pipeline(self.to_clean, self.sr, self.ch_count, self._state)
225+
ret = asr_pipeline(filtered_data, self.sr, self.ch_count, self._state)
227226
self.cleaned_data_available = True
228227
idx = np.searchsorted(self.to_clean_ts[0], self.last_cleaned_timestamp)
229228
self.cleaned_data = ret[:, idx:]
@@ -259,12 +258,6 @@ def start_calibration(self, calib_length: float = -1.0):
259258
f"[{self._min_calibration_length},{self._max_calibration_length}]")
260259
logger.info(f"Starting ASR calibration for {self.calibration_length}s...")
261260
self.calib_started_at = time.time()
262-
self.filter = ExGFilter(
263-
cutoff_freq=(1, 45),
264-
filter_type='bandpass',
265-
s_rate=self.sr,
266-
n_chan=self.ch_count,
267-
)
268261
self.stream_processor.subscribe(self.on_calib_data_received, topic=self.in_topic)
269262

270263
def stop_calibration(self):
@@ -277,13 +270,16 @@ def stop_calibration(self):
277270

278271
def set_state_from_calibration_data(self, calib_data):
279272
self.lifecycle_state = State.CLEANING
280-
cleaned, state = clean_calib_data(calib_data, self.sr)
273+
filt_sig = bp_filter(calib_data, 45, 55, btype='bandstop', fs=self.sr)
274+
filtered_data = bp_filter(filt_sig, .1, 40, self.sr)
275+
cleaned, state = clean_calib_data(filtered_data, self.sr)
281276
if cleaned is None:
282277
self.calibration_data_available = False
283278
self.lifecycle_state = state
284279
return
285280
try:
286281
self._state = asr_calibrate(cleaned, self.sr, cutoff=self._cutoff)
282+
self.calibration_data_available = True
287283
self.lifecycle_state = state
288284
except np.linalg.LinAlgError as e:
289285
self.calibration_data_available = False

src/explorepy/filters.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55

66
import numpy as np
7+
from scipy import signal
78
from scipy.signal import (
89
butter,
910
iirfilter,
@@ -17,6 +18,13 @@
1718
logger = logging.getLogger(__name__)
1819

1920

21+
@staticmethod
22+
def bp_filter(exg, lf, hf, fs, btype='bandpass'):
23+
N = 5
24+
b, a = signal.butter(N, [lf, hf], btype=btype, fs=fs)
25+
return signal.filtfilt(b, a, exg, axis=1)
26+
27+
2028
class ExGFilter:
2129
"""Filter class for ExG signals"""
2230
def __init__(self, cutoff_freq, filter_type, s_rate, n_chan, order=5):

0 commit comments

Comments
 (0)