Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update with latest changes from develop #246

Merged
merged 37 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6579d6c
example test commit (#182)
JohnGriffiths Jun 2, 2022
ae4a5db
ci: run test workflow on develop branch
ErikBjare Jun 10, 2022
5c83bbe
ci: add develop branch to job triggers
ErikBjare May 5, 2022
32515fa
ci: fix syntax issue in workflow
ErikBjare Jun 16, 2022
75e42ef
fix: fixed import (brainflow updated API)
ErikBjare Jun 16, 2022
f139ab5
build(deps): locked pylsl==1.10.5 (#187)
ErikBjare Jun 16, 2022
e4e7d8a
Experiment Class Refactor (update to #183), converting specific exper…
Parvfect Aug 10, 2022
05bdf62
Submodule added for gsoc
Parvfect Sep 5, 2022
368afa3
Merge branch 'develop' of https://github.com/NeuroTechX/eeg-notebooks…
Parvfect Sep 5, 2022
6714740
Adding pipelines for cli analysis (#202)
Parvfect Oct 16, 2022
3f3281c
added more options for site args; improved function names; removed so…
JohnGriffiths Oct 16, 2022
79652af
fix subject num parsing bug
JohnGriffiths Oct 16, 2022
a62280a
analysis report function improvements for openbci cyton and gtec unic…
JohnGriffiths Oct 17, 2022
e7bee1b
run exp fix
JohnGriffiths Oct 18, 2022
e6e92b9
Update requirements.txt
JohnGriffiths Oct 20, 2022
30fb77c
fixes to get docs building by github action (#210)
pellet Oct 27, 2022
6783463
Update README.rst
JohnGriffiths Dec 1, 2022
3b1585f
removing gsoc submodule
JohnGriffiths Jan 19, 2023
8f41ebe
Merge branch 'master' into develop
JohnGriffiths Jan 19, 2023
478fa49
ci: update python to 3.8, update wxPython, update setup-python action
ErikBjare Mar 3, 2023
3bd12a7
ci: pin ubuntu versions to 22.04, updated wxPython urls
ErikBjare Mar 3, 2023
a4fe823
ci: bumped psychopy to 2023.1.0
ErikBjare Mar 3, 2023
c2c5d57
build(deps): set upper supported numpy version to 1.23.x
ErikBjare Mar 3, 2023
adf5e28
chore: applied no_implicit_optional
ErikBjare Mar 3, 2023
584272e
update dependencies - for build (#220)
oreHGA Mar 4, 2023
d0715cf
Updated psychopy (#215)
pellet Mar 4, 2023
c9b6671
Merge branch 'develop' into dev/update-wxpython
oreHGA Mar 4, 2023
53154c2
Updated doc examples for N170, P300 and SSVEP after Experiment Class …
Parvfect Mar 10, 2023
70758b7
Merge pull request #222 from NeuroTechX/dev/update-wxpython
ErikBjare Mar 11, 2023
c24b7c7
fix error breaking n170 test (#223)
pellet Mar 11, 2023
81dd244
fixed requirements.txt so 'pip install -e .' would work on windows. (…
pellet Apr 27, 2023
7be54d6
Get CI test builds working again! (#170)
ErikBjare Apr 27, 2023
9d61617
Merge branch 'master' into develop
oreHGA Nov 16, 2023
a4bec9b
fix macos build (#245)
pellet Nov 16, 2023
d8b5976
Add devcontainer configuration for CPU environment
tmorshed Dec 6, 2023
7cf7774
Fixed the python version needed
tmorshed Dec 8, 2023
d00c2dd
Fix plot conditions (#257)
JohnGriffiths Mar 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .devcontainer/cpu/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "EEG-ExPy-CPU",
"image": "mcr.microsoft.com/devcontainers/python:3.8",

"customizations": {
"vscode": {
"extensions": [
"ms-python.python"
],
"settings": {
"python.pythonPath": "/usr/local/bin/python"
}
}
},

"forwardPorts": [
8000,
8888,
5000,
6000
],
// print the python version:
"postCreateCommand": "python --version && pip install -r requirements.txt && pip install -e . && echo 'Dependencies installed'",
"appPort": 8000

}
13 changes: 7 additions & 6 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Set up Python
Expand All @@ -17,17 +17,18 @@ jobs:
python-version: 3.8
- name: Install dependencies
run: |
make install-deps-apt
python -m pip install --upgrade pip wheel
python -m pip install attrdict

# Install wxPython wheels since they are distribution-specific and therefore not on PyPI
# See: https://wxpython.org/pages/downloads/index.html
pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxPython
make install-deps-wxpython
- name: Build project
run: |
make build

pip install .
- name: Build docs
run: |
cd doc && make html
make docs
- name: Deploy Docs
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/master' # TODO: Deploy seperate develop-version of docs?
Expand Down
72 changes: 28 additions & 44 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,53 @@ on:

jobs:
test:
name: ${{ matrix.os }}, py-${{ matrix.python_version }}
name: test (${{ matrix.os }}, py-${{ matrix.python_version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
python_version: [3.7]
os: ['ubuntu-22.04', windows-latest, macOS-latest]
python_version: ['3.8']
include:
- os: ubuntu-latest
python_version: 3.8
# Experimental: Python 3.9
# Works fine, commented out because mostly covered (at least installing/building deps) by the typecheck job
# See issue: https://github.com/NeuroTechX/eeg-notebooks/issues/50
#- os: ubuntu-latest
# python_version: 3.9

# Check 3.10 for future-proofing
- os: ubuntu-22.04
python_version: '3.10'

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python_version }}

# Not needed if pywinhook is installed from wheels
#- name: Install swig
# if: "startsWith(runner.os, 'windows')"
# run: |
# (New-Object System.Net.WebClient).DownloadFile("http://prdownloads.sourceforge.net/swig/swigwin-4.0.1.zip","swigwin-4.0.1.zip");
# Expand-Archive .\swigwin-4.0.1.zip .;
# echo "$((Get-Item .).FullName)/swigwin-4.0.1" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

- name: Install APT dependencies
if: "startsWith(runner.os, 'Linux')"
run: |
# update archive links
sudo apt-get update
# xvfb is a dependency to create a virtual display
# libgtk-3-dev is a requirement for wxPython
# freeglut3-dev is a requirement for a wxPython dependency
sudo apt-get -y install xvfb libgtk-3-dev freeglut3-dev
make install-deps-apt
- name: Upgrade pip
run: |
python -m pip install --upgrade pip wheel
- name: Install Linux dependencies
if: "startsWith(runner.os, 'Linux')"
run: |
python -m pip install --upgrade pip wheel

# Install wxPython wheels since they are distribution-specific and therefore not on PyPI
# See: https://wxpython.org/pages/downloads/index.html
pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 wxPython

pip install .
- name: Install MacOS/Windows dependencies
make install-deps-wxpython
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
pip install .
pip install -U psychtoolbox # JG_ADD
# EB: needed?
make build
- name: Run eegnb install test
shell: bash
run: |
Expand All @@ -78,14 +71,15 @@ jobs:
Xvfb :0 -screen 0 1024x768x24 -ac +extension GLX +render -noreset &> xvfb.log &
export DISPLAY=:0
fi
pytest
make test

typecheck:
name: typecheck (${{ matrix.os }}, py-${{ matrix.python_version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: ['ubuntu-22.04']
python_version: [3.9]

steps:
Expand All @@ -97,27 +91,17 @@ jobs:
- name: Install APT dependencies
if: "startsWith(runner.os, 'Linux')"
run: |
# update archive links
sudo apt-get update
# xvfb is a dependency to create a virtual display
# libgtk-3-dev is a requirement for wxPython
# freeglut3-dev is a requirement for a wxPython dependency
sudo apt-get -y install xvfb libgtk-3-dev freeglut3-dev
make install-deps-apt
- name: Upgrade pip
run: |
python -m pip install --upgrade pip wheel
- name: Install Linux dependencies
if: "startsWith(runner.os, 'Linux')"
run: |
python -m pip install --upgrade pip wheel

# Install wxPython wheels since they are distribution-specific and therefore not on PyPI
# See: https://wxpython.org/pages/downloads/index.html
pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 wxPython

pip install .
- name: Install MacOS/Windows dependencies
make install-deps-wxpython
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
pip install .
make build
- name: Typecheck
run: |
# Exclude visual_cueing due to errors
python -m mypy --exclude 'examples/visual_cueing'
make typecheck
40 changes: 40 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
build:
# Use pep517 to install pygatt==4.0.5(deprecated setuptools/egg installer) on macos
pip install --use-pep517 .

test:
pytest

typecheck:
# Exclude visual_cueing due to errors
python -m mypy --exclude 'examples/visual_cueing'

docs:
cd doc && make html

clean:
cd doc && make clean

install-deps-apt:
sudo apt-get update # update archive links

# xvfb is a dependency to create a virtual display
# libgtk-3-dev is a requirement for wxPython
# freeglut3-dev is a requirement for a wxPython dependency
# portaudio19-dev *might* be required to import psychopy on Ubuntu
# pulseaudio *might* be required to actually run the tests (on PsychoPy import)
# libpulse-dev required to build pocketsphinx (speech recognition dependency of psychopy)
# libsdl2-dev required by psychopy
# libnotify4 is so we can have the libnotify.so module used in wxPython working
sudo apt-get -y install xvfb libgtk-3-dev freeglut3-dev portaudio19-dev libpulse-dev pulseaudio libsdl2-dev libnotify4

# configure dynamic links
sudo ldconfig

UPDATED_LIBPATH=$(sudo find / -name libnotify.so)
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$UPDATED_LIBPATH

install-deps-wxpython:
# Install wxPython wheels since they are distribution-specific and therefore not on PyPI
# See: https://wxpython.org/pages/downloads/index.html
pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-22.04 wxPython
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def setup(app):
'backreferences_dir': 'generated', # Where to drop linking files between examples & API
'doc_module': ('eeg-notebooks',),
'reference_url': {'eeg-notebooksS': None},
'remove_conffig_comments': True,
'remove_config_comments': True,
}

"""
79 changes: 41 additions & 38 deletions eegnb/analysis/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
from copy import deepcopy
import math
import logging
import sys
from collections import OrderedDict
from glob import glob
from typing import Union, List, Dict
from collections import Iterable
from typing import Union, List
from time import sleep, time
from numpy.core.fromnumeric import std
import keyboard
import os

Expand All @@ -20,6 +19,8 @@
from mne.channels import make_standard_montage
from mne.filter import create_filter
from matplotlib import pyplot as plt
from matplotlib import lines as mlines
from scipy import stats
from scipy.signal import lfilter, lfilter_zi

from eegnb import _get_recording_dir
Expand Down Expand Up @@ -221,7 +222,8 @@ def plot_conditions(
ylim=(-6, 6),
diff_waveform=(1, 2),
channel_count=4,
channel_order=None):
channel_order=None,
):
"""Plot ERP conditions.
Args:
epochs (mne.epochs): EEG epochs
Expand All @@ -247,20 +249,19 @@ def plot_conditions(
"""

if channel_order:
channel_order = np.array(channel_order)
channel_order = np.array(channel_order)
else:
channel_order = np.array(range(channel_count))

channel_order = np.array(range(channel_count))
channel_names = np.array(epochs.ch_names)[channel_order]

if isinstance(conditions, dict):
conditions = OrderedDict(conditions)

if palette is None:
palette = sns.color_palette("hls", len(conditions) + 1)

X = epochs.get_data() * 1e6

X = X[:,channel_order]
dfX = epochs.to_data_frame()
dfX[channel_names] *= 1e6

times = epochs.times
y = pd.Series(epochs.events[:, -1])
Expand All @@ -275,43 +276,45 @@ def plot_conditions(
plot_axes.append(axes[axis_x, axis_y])
axes = plot_axes

for ch in range(channel_count):
for cond, color in zip(conditions.values(), palette):
sns.tsplot(
X[y.isin(cond), ch],
time=times,
for ch,ch_name in enumerate(channel_names):
for cond,cond_name, color in zip(conditions.values(),conditions.keys(), palette):
dfXc = dfX[dfX.condition.isin(conditions[cond_name])]
sns.lineplot(
data=dfXc,
x="time",
y=ch_name,
color=color,
n_boot=n_boot,
ci=ci,
ax=axes[ch],
errorbar=('ci',ci)
)
axes[ch].set(xlabel='Time (s)', ylabel='Amplitude (uV)', title=epochs.ch_names[channel_order[ch]])

if diff_waveform:
diff = np.nanmean(X[y == diff_waveform[1], ch], axis=0) - np.nanmean(
X[y == diff_waveform[0], ch], axis=0
)
dfXc1 = dfX[dfX.condition.isin(conditions[diff_waveform[1]])]
dfXc2 = dfX[dfX.condition.isin(conditions[diff_waveform[0]])]
dfXc1_mn = dfXc1.set_index(['time', 'epoch'])[ch_name].unstack('epoch').mean(axis=1)
dfXc2_mn = dfXc2.set_index(['time', 'epoch'])[ch_name].unstack('epoch').mean(axis=1)
diff = (dfXc1_mn - dfXc2_mn).values
axes[ch].plot(times, diff, color="k", lw=1)

axes[ch].set_title(epochs.ch_names[channel_order[ch]])
axes[ch].set_title(ch_name)
axes[ch].set_ylim(ylim)
axes[ch].axvline(
x=0, ymin=ylim[0], ymax=ylim[1], color="k", lw=1, label="_nolegend_"
)

axes[0].set_xlabel("Time (s)")
axes[0].set_ylabel("Amplitude (uV)")
axes[-1].set_xlabel("Time (s)")
axes[1].set_ylabel("Amplitude (uV)")

legs = []
for cond,cond_name,color in zip(conditions.values(),conditions.keys(), palette):
lh = mlines.Line2D([], [], color=color, marker='', ls='-', label=cond_name)
legs.append(lh)
if diff_waveform:
legend = ["{} - {}".format(diff_waveform[1], diff_waveform[0])] + list(
conditions.keys()
)
else:
legend = conditions.keys()
axes[-1].legend(
legend, bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0.0
)
lh = mlines.Line2D([], [], color="k", marker='', ls='-',
label = "{} - {}".format(diff_waveform[1], diff_waveform[0]))
legs.append(lh)

axes[-1].legend(handles=legs,
bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0.0)
sns.despine()
plt.tight_layout()

Expand All @@ -331,6 +334,9 @@ def plot_highlight_regions(
Args:
x (array_like): x coordinates
y (array_like): y values of same shape as `x`
Keyword Args:
hue (array_like): values to be plotted as hue based on `hue_thresh`.
Must be of the same shape as `x` and `y`.
Keyword Args:
hue (array_like): values to be plotted as hue based on `hue_thresh`.
Must be of the same shape as `x` and `y`.
Expand Down Expand Up @@ -456,12 +462,9 @@ def check_report(eeg: EEG, n_times: int=60, pause_time=5, thres_std_low=None, th
Usage:
------
from eegnb.devices.eeg import EEG
from eegnb.analysis.utils import check_report
eeg = EEG(device='museS')
check_report(eeg)
standard deviation for a quality recording.

The thres_std_low & thres_std_high values are the
lower and upper bound of accepted
thresholds = {
standard deviation for a quality recording.

thresholds = {
Expand Down
Loading
Loading