NeuroTechX / EEG-ExPy

EEG Experiments in Python
https://neurotechx.github.io/EEG-ExPy/
BSD 3-Clause "New" or "Revised" License
437 stars 124 forks source link

Add signal quality checks before recording starts #97

Closed oreHGA closed 3 years ago

oreHGA commented 3 years ago

📝 Provide a description of the new feature

What is the expected behavior of the proposed feature?

This will be based off @ErikBjare 's take on the problem - https://erik.bjareholt.com/thesis/Signal.html

Results will be placed on the command line prompt with a suggestion on changes to make to improve quality.

What is the scenario this would be used?

Before the recording gets started, the quality check happens to make the user aware of how valuable their recordings will be for analysis moving forward.

Initially targeting muse devices, but we aim to generalize to different device types.


If you'd like to see this feature implemented, add a 👍 reaction to this post.

JohnGriffiths commented 3 years ago

This function should go in the cli utils.py file:

https://github.com/JohnGriffiths/eeg-notebooks/blob/master/eegnb/cli/utils.py

Made a minimal start on this for muselsl. Pushing shortly.

JohnGriffiths commented 3 years ago

OR, maybe we should make use of our device abstraction and put some part of this as a method in the EEG class

https://github.com/NeuroTechX/eeg-notebooks/blob/master/eegnb/devices/eeg.py

I see two ways of doing this:

  1. Write short data snippets to file and read in and compute signal quality index as a separate step

  2. Read the data snippets in memory and compute sq

Consderations:

Option 1 is obviously less elegant because it involves i/o

However, our device abstraction is already currently based around i/o (i.e. you define an output file when you start a recording). So within our current device class it would (I think) be less additional code to do option 2 than option 1. Similarly, option 2 would necessarily involve at least two separate implementations (one for brainflow one for muselsl), whereas option 1 can just use our higher-level device wrapper.

The lines for pulling samples into memory are however pretty minimal so not a huge overhead all the same

JohnGriffiths commented 3 years ago

Make a 10s temp recording file for sigqual eval with EEG device and muse headset

import os
import time
from eegnb.devices.eeg import EEG
f = os.path.abspath('sigqual_tempfile.csv')
this_eeg = EEG(device='muse2016')
this_eeg.start(f, duration=10)
time.sleep(3) # get error if no markers?
this_eeg.push_sample([99], timestamp=time.time())
JohnGriffiths commented 3 years ago

Code for pulling samples used in the muselsl visualizer

https://github.com/alexandrebarachant/muse-lsl/blob/master/muselsl/viewer_v2.py

from pylsl import StreamInlet, resolve_byprop
from muselsl.constants  import LSL_EEG_CHUNK, LSL_SCAN_TIMEOUT

streams = resolve_byprop('type', 'EEG', timeout=LSL_SCAN_TIMEOUT)
inlet = StreamInlet(streams[0], max_chunklen=LSL_EEG_CHUNK)
samples, timestamps = inlet.pull_chunk(timeout=0.0, max_samples=100)

import numpy as np
arr = np.array(samples)
np.std(arr,axis=0)
ErikBjare commented 3 years ago

Brainflow filtering: https://brainflow.readthedocs.io/en/stable/Examples.html#python-signal-filtering

MNE filtering: https://mne.tools/stable/generated/mne.filter.filter_data.html

My filtering (inspired by the muse-lsl viewer): https://github.com/ErikBjare/thesis/blob/b25661aaffa5ab957b464fe8f46fdbfe81b51eb4/src/eegclassify/clean.py#L26-L45

JohnGriffiths commented 3 years ago

So following the discussion in developer's meeting today, the plan on this is to implement

i) A 'data buffer' or 'get recent data' functionality in the EEG device class

ii) Add Erik's signal quality check code as a function in analysis/utils.py

iii) Add something that initializes i), calls ii), and prints results to command line

PR for my first attempt at the data buffer component, for muse: https://github.com/NeuroTechX/eeg-notebooks/pull/103