From dddba0ec6010bd635e30067a664a3fd34d25fbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Sun, 27 Mar 2022 20:10:04 +0200 Subject: [PATCH 01/11] Revert "Revert PR #167: "ci: fix broken CI" (#169)" This reverts commit 2d748719b656160ea10fe94f29ff5c613e35f957. --- .github/workflows/docs.yml | 10 +- .github/workflows/test.yml | 62 ++---- Makefile | 32 +++ doc/conf.py | 4 +- eegnb/analysis/utils.py | 55 +++-- eegnb/analysis/utils_old.py | 294 -------------------------- eegnb/cli/__main__.py | 8 +- eegnb/datasets/datasets.py | 23 +- examples/visual_n170/01r__n170_viz.py | 2 +- requirements.txt | 34 ++- 10 files changed, 133 insertions(+), 391 deletions(-) create mode 100644 Makefile delete mode 100755 eegnb/analysis/utils_old.py diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d208acd8..e0bf5414 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python @@ -17,16 +17,14 @@ jobs: python-version: 3.8 - name: Install dependencies run: | + make install-deps-apt 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 - + make install-deps-wxpython 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' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 185caf2d..8f808173 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,16 +8,14 @@ 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] - include: - - os: ubuntu-latest - python_version: 3.8 + python_version: [3.8] + #include: # 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 @@ -40,33 +38,22 @@ 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: Run eegnb install test shell: bash - pip install -U psychtoolbox # JG_ADD run: | if [ "$RUNNER_OS" == "Linux" ]; then Xvfb :0 -screen 0 1024x768x24 -ac +extension GLX +render -noreset &> xvfb.log & - / export DISPLAY=:0 fi eegnb --help @@ -78,9 +65,10 @@ 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 @@ -97,27 +85,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 diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..4175cb02 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +build: + pip install . + +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 + sudo apt-get -y install xvfb libgtk-3-dev freeglut3-dev portaudio19-dev libpulse-dev pulseaudio libsdl2-dev + +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-18.04 wxPython diff --git a/doc/conf.py b/doc/conf.py index cae9a5dc..d4503b43 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -263,7 +263,7 @@ def setup(app): 'backreferences_dir': 'generated', # Where to drop linking files between examples & API 'doc_module': ('eeg-notebooks'), 'reference_url': {'eeg-notebooks': None}, - 'remove_conffig_comments': True} + 'remove_config_comments': True} """ sphinx_gallery_conf = { @@ -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, } """ diff --git a/eegnb/analysis/utils.py b/eegnb/analysis/utils.py index bd67baa9..603ed14c 100644 --- a/eegnb/analysis/utils.py +++ b/eegnb/analysis/utils.py @@ -2,11 +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 typing import Union, List from time import sleep, time -from numpy.core.fromnumeric import std import pandas as pd import numpy as np @@ -16,13 +16,13 @@ from mne.channels import make_standard_montage from mne.filter import create_filter from matplotlib import pyplot as plt +from scipy import stats from scipy.signal import lfilter, lfilter_zi from eegnb import _get_recording_dir from eegnb.devices.eeg import EEG from eegnb.devices.utils import EEG_INDICES, SAMPLE_FREQS - # this should probably not be done here sns.set_context("talk") @@ -32,6 +32,33 @@ logger = logging.getLogger(__name__) +def _bootstrap(data, n_boot: int, ci: float): + """From: https://stackoverflow.com/a/47582329/965332""" + boot_dist = [] + for i in range(int(n_boot)): + resampler = np.random.randint(0, data.shape[0], data.shape[0]) + sample = data.take(resampler, axis=0) + boot_dist.append(np.mean(sample, axis=0)) + b = np.array(boot_dist) + s1 = np.apply_along_axis(stats.scoreatpercentile, 0, b, 50 - ci / 2) + s2 = np.apply_along_axis(stats.scoreatpercentile, 0, b, 50 + ci / 2) + return (s1, s2) + + +def _tsplotboot(ax, data, time: list, n_boot: int, ci: float, color): + """From: https://stackoverflow.com/a/47582329/965332""" + # Time forms the xaxis of the plot + if time is None: + x = np.arange(data.shape[1]) + else: + x = np.asarray(time) + est = np.mean(data, axis=0) + cis = _bootstrap(data, n_boot, ci) + ax.fill_between(x, cis[0], cis[1], alpha=0.2, color=color) + ax.plot(x, est, color=color) + ax.margins(x=0) + + def load_csv_as_raw( fnames: List[str], sfreq: float, @@ -152,7 +179,9 @@ def load_data( site = "*" data_path = ( - _get_recording_dir(device_name, experiment, subject_str, session_str, site, data_dir) + _get_recording_dir( + device_name, experiment, subject_str, session_str, site, data_dir + ) / "*.csv" ) fnames = glob(str(data_path)) @@ -193,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 @@ -219,10 +249,9 @@ 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)) if isinstance(conditions, dict): conditions = OrderedDict(conditions) @@ -232,7 +261,7 @@ def plot_conditions( X = epochs.get_data() * 1e6 - X = X[:,channel_order] + X = X[:, channel_order] times = epochs.times y = pd.Series(epochs.events[:, -1]) @@ -249,13 +278,15 @@ def plot_conditions( for ch in range(channel_count): for cond, color in zip(conditions.values(), palette): - sns.tsplot( - X[y.isin(cond), ch], + y_cond = y.isin(cond) + X_cond = X[y_cond, ch] + _tsplotboot( + ax=axes[ch], + data=X_cond, time=times, color=color, n_boot=n_boot, ci=ci, - ax=axes[ch], ) if diff_waveform: diff --git a/eegnb/analysis/utils_old.py b/eegnb/analysis/utils_old.py deleted file mode 100755 index 16f01ffe..00000000 --- a/eegnb/analysis/utils_old.py +++ /dev/null @@ -1,294 +0,0 @@ -# -*- coding: utf-8 -*- - -from glob import glob -import os -from collections import OrderedDict - -from mne import create_info, concatenate_raws -from mne.io import RawArray -from mne.channels import make_standard_montage -import pandas as pd -import numpy as np -import seaborn as sns -from matplotlib import pyplot as plt - - -sns.set_context("talk") -sns.set_style("white") - - -def load_muse_csv_as_raw( - filename, - sfreq=256.0, - ch_ind=[0, 1, 2, 3], - stim_ind=5, - replace_ch_names=None, - verbose=1, -): - """Load CSV files into a Raw object. - - Args: - filename (str or list): path or paths to CSV files to load - - Keyword Args: - subject_nb (int or str): subject number. If 'all', load all - subjects. - session_nb (int or str): session number. If 'all', load all - sessions. - sfreq (float): EEG sampling frequency - ch_ind (list): indices of the EEG channels to keep - stim_ind (int): index of the stim channel - replace_ch_names (dict or None): dictionary containing a mapping to - rename channels. Useful when an external electrode was used. - - Returns: - (mne.io.array.array.RawArray): loaded EEG - """ - n_channel = len(ch_ind) - - raw = [] - print(filename) - for fname in filename: - print(fname) - # read the file - data = pd.read_csv(fname, index_col=0) - - # name of each channels - ch_names = list(data.columns)[0:n_channel] + ["Stim"] - - if replace_ch_names is not None: - ch_names = [ - c if c not in replace_ch_names.keys() else replace_ch_names[c] - for c in ch_names - ] - - # type of each channels - ch_types = ["eeg"] * n_channel + ["stim"] - montage = make_standard_montage("standard_1005") - - # get data and exclude Aux channel - data = data.values[:, ch_ind + [stim_ind]].T - - # convert in Volts (from uVolts) - data[:-1] *= 1e-6 - - # create MNE object - info = create_info( - ch_names=ch_names, - ch_types=ch_types, - sfreq=sfreq, - montage=montage, - verbose=verbose, - ) - raw.append(RawArray(data=data, info=info, verbose=verbose)) - - # concatenate all raw objects - print("raw is") - print(raw) - raws = concatenate_raws(raw, verbose=verbose) - - return raws - - -def load_data( - data_dir, - site="eegnb_examples", - experiment="visual_n170", - device="muse2016", - subject_nb=1, - session_nb=1, - sfreq=256.0, - ch_ind=[0, 1, 2, 3], - stim_ind=5, - replace_ch_names=None, - verbose=1, -): - - """Load CSV files from the /data directory into a Raw object. - - Args: - data_dir (str): directory inside /data that contains the - CSV files to load, e.g., 'auditory/P300' - - Keyword Args: - subject_nb (int or str): subject number. If 'all', load all - subjects. - session_nb (int or str): session number. If 'all', load all - sessions. - sfreq (float): EEG sampling frequency - ch_ind (list): indices of the EEG channels to keep - stim_ind (int): index of the stim channel - replace_ch_names (dict or None): dictionary containing a mapping to - rename channels. Useful when an external electrode was used. - - Returns: - (mne.io.array.array.RawArray): loaded EEG - """ - if subject_nb == "all": - subject_nb = "*" - if session_nb == "all": - session_nb = "*" - - subject_nb_str = "%04.f" % subject_nb - session_nb_str = "%03.f" % session_nb - subsess = "subject{}/session{}/*.csv".format(subject_nb_str, session_nb_str) - data_path = os.path.join(data_dir, experiment, site, device, subsess) - fnames = glob(data_path) - - return load_muse_csv_as_raw( - fnames, - sfreq=sfreq, - ch_ind=ch_ind, - stim_ind=stim_ind, - replace_ch_names=replace_ch_names, - verbose=verbose, - ) - - -def plot_conditions( - epochs, - conditions=OrderedDict(), - ci=97.5, - n_boot=1000, - title="", - palette=None, - ylim=(-6, 6), - diff_waveform=(1, 2), -): - """Plot ERP conditions. - - Args: - epochs (mne.epochs): EEG epochs - - Keyword Args: - conditions (OrderedDict): dictionary that contains the names of the - conditions to plot as keys, and the list of corresponding marker - numbers as value. E.g., - - conditions = {'Non-target': [0, 1], - 'Target': [2, 3, 4]} - - ci (float): confidence interval in range [0, 100] - n_boot (int): number of bootstrap samples - title (str): title of the figure - palette (list): color palette to use for conditions - ylim (tuple): (ymin, ymax) - diff_waveform (tuple or None): tuple of ints indicating which - conditions to subtract for producing the difference waveform. - If None, do not plot a difference waveform - - Returns: - (matplotlib.figure.Figure): figure object - (list of matplotlib.axes._subplots.AxesSubplot): list of axes - """ - if isinstance(conditions, dict): - conditions = OrderedDict(conditions) - - if palette is None: - palette = sns.color_palette("hls", len(conditions) + 1) - - X = epochs.get_data() * 1e6 - times = epochs.times - y = pd.Series(epochs.events[:, -1]) - - fig, axes = plt.subplots(2, 2, figsize=[12, 6], sharex=True, sharey=True) - axes = [axes[1, 0], axes[0, 0], axes[0, 1], axes[1, 1]] - - for ch in range(4): - for cond, color in zip(conditions.values(), palette): - sns.tsplot( - X[y.isin(cond), ch], - time=times, - color=color, - n_boot=n_boot, - ci=ci, - ax=axes[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 - ) - axes[ch].plot(times, diff, color="k", lw=1) - - axes[ch].set_title(epochs.ch_names[ch]) - 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)") - - if diff_waveform: - legend = ["{} - {}".format(diff_waveform[1], diff_waveform[0])] + list( - conditions.keys() - ) - else: - legend = conditions.keys() - axes[-1].legend(legend, loc="lower right") - sns.despine() - plt.tight_layout() - - if title: - fig.suptitle(title, fontsize=20) - - return fig, axes - - -def plot_highlight_regions( - x, y, hue, hue_thresh=0, xlabel="", ylabel="", legend_str=() -): - """Plot a line with highlighted regions based on additional value. - - Plot a line and highlight ranges of x for which an additional value - is lower than a threshold. For example, the additional value might be - pvalues, and the threshold might be 0.05. - - 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`. - hue_thresh (float): threshold to be applied to `hue`. Regions for which - `hue` is lower than `hue_thresh` will be highlighted. - xlabel (str): x-axis label - ylabel (str): y-axis label - legend_str (tuple): legend for the line and the highlighted regions - - Returns: - (matplotlib.figure.Figure): figure object - (list of matplotlib.axes._subplots.AxesSubplot): list of axes - """ - fig, axes = plt.subplots(1, 1, figsize=(10, 5), sharey=True) - - axes.plot(x, y, lw=2, c="k") - plt.xlabel(xlabel) - plt.ylabel(ylabel) - - kk = 0 - a = [] - while kk < len(hue): - if hue[kk] < hue_thresh: - b = kk - kk += 1 - while kk < len(hue): - if hue[kk] > hue_thresh: - break - else: - kk += 1 - a.append([b, kk - 1]) - else: - kk += 1 - - st = (x[1] - x[0]) / 2.0 - for p in a: - axes.axvspan(x[p[0]] - st, x[p[1]] + st, facecolor="g", alpha=0.5) - plt.legend(legend_str) - sns.despine() - - return fig, axes diff --git a/eegnb/cli/__main__.py b/eegnb/cli/__main__.py index 6e57fbce..e19aca4c 100644 --- a/eegnb/cli/__main__.py +++ b/eegnb/cli/__main__.py @@ -1,9 +1,7 @@ -from eegnb import DATA_DIR import click -from time import sleep -from os import path import os -import shutil + +from eegnb import DATA_DIR from eegnb.datasets.datasets import zip_data_folders from .introprompt import intro_prompt @@ -34,7 +32,7 @@ def runexp( recdur: float = None, outfname: str = None, prompt: bool = False, - dosigqualcheck = True, + dosigqualcheck=True, ): """ Run experiment. diff --git a/eegnb/datasets/datasets.py b/eegnb/datasets/datasets.py index 3fc7ae87..21add031 100644 --- a/eegnb/datasets/datasets.py +++ b/eegnb/datasets/datasets.py @@ -1,11 +1,17 @@ -import os,sys,glob,shutil,numpy as np, pandas as pd -import requests, zipfile,gdown +import os +import glob +import shutil +import zipfile + +import requests +import gdown + from datetime import datetime from eegnb import DATA_DIR # eegnb example data sites. do not select these when zipping recordings -eegnb_sites = ['eegnb_examples', 'grifflab_dev', 'jadinlab_home'] +eegnb_sites = ["eegnb_examples", "grifflab_dev", "jadinlab_home"] def fetch_dataset( @@ -64,7 +70,7 @@ def fetch_dataset( } # If no non-default top-level data path specified, use default - if data_dir == None: + if data_dir is None: data_dir = DATA_DIR # check parameter entries @@ -85,12 +91,9 @@ def fetch_dataset( destination = os.path.join(data_dir, "downloaded_data.zip") if download_method == "gdown": - URL = "https://drive.google.com/uc?id=" + gdrive_locs[experiment] gdown.download(URL, destination, quiet=False) - elif download_method == "requests": - URL = "https://docs.google.com/uc?export=download" session = requests.Session() @@ -114,6 +117,8 @@ def fetch_dataset( for chunk in response.iter_content(CHUNK_SIZE): if chunk: f.write(chunk) + else: + raise ValueError("download_method not supported") # unzip the file with zipfile.ZipFile(destination, "r") as zip_ref: @@ -160,9 +165,7 @@ def fetch_dataset( return fnames - -def zip_data_folders(experiment: str, - site: str="local"): +def zip_data_folders(experiment: str, site: str = "local"): """ Run data zipping diff --git a/examples/visual_n170/01r__n170_viz.py b/examples/visual_n170/01r__n170_viz.py index 9aa48f7d..53ba630e 100644 --- a/examples/visual_n170/01r__n170_viz.py +++ b/examples/visual_n170/01r__n170_viz.py @@ -59,7 +59,7 @@ subject = 1 session = 1 raw = load_data(subject,session, - experiment='visual-N170', site='eegnb_examples', device_name='muse2016_bfn', + experiment='visual-N170', site='eegnb_examples', device_name='muse2016', data_dir = eegnb_data_path) ################################################################################################### diff --git a/requirements.txt b/requirements.txt index ea8be01c..2436971c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,18 @@ # Main repo requirements -psychopy==2020.2.3 -psychtoolbox +psychopy==2022.1.1 scikit-learn>=0.23.2 pandas>=1.1.4 numpy>=1.19.4 mne>=0.20.8 -seaborn==0.9.0 +seaborn>=0.11.0 pyriemann>=0.2.7 jupyter muselsl>=2.0.2 brainflow>=4.8.2 gdown matplotlib>=3.3.3 -pysocks==1.7.1 -pyserial==3.5 +pysocks>=1.7.1 +pyserial>=3.5 h5py>=3.1.0 pytest-shutil pyo>=1.0.3; platform_system == "Linux" @@ -23,9 +22,6 @@ pyo>=1.0.3; platform_system == "Linux" wxPython>=4.0 ; platform_system == "Linux" click -# can be removed once minimum version is Python 3.7 -dataclasses; python_version == '3.6' - # pywinhook needs some special treatment since there are only wheels on PyPI for Python 3.7-3.8, and building requires special tools (swig, VS C++ tools) # See issue: https://github.com/NeuroTechX/eeg-notebooks/issues/29 pywinhook>=1.6.0 ; platform_system == "Windows" and (python_version == "3.7" or python_version == "3.8") @@ -45,14 +41,14 @@ nbval types-requests # Docs requirements -sphinx==3.1.1 -sphinx-gallery==0.8.1 -sphinx_rtd_theme==0.5.0 -sphinx-tabs==1.3.0 -sphinx-copybutton==0.3.1 -sphinxcontrib-httpdomain==1.7.0 -numpydoc==1.1.0 -recommonmark==0.6.0 -versioneer==0.19 -rst2pdf==0.98 -docutils==0.17 +sphinx +sphinx-gallery +sphinx_rtd_theme +sphinx-tabs +sphinx-copybutton +sphinxcontrib-httpdomain +numpydoc +recommonmark +versioneer +rst2pdf +docutils From db8caec09295f81e96ede079a27455d6526cde08 Mon Sep 17 00:00:00 2001 From: Ore O Date: Fri, 10 Mar 2023 04:47:23 -0800 Subject: [PATCH 02/11] Update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4175cb02..e2a1a5ac 100644 --- a/Makefile +++ b/Makefile @@ -29,4 +29,4 @@ install-deps-apt: 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-18.04 wxPython + pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxPython From 479acb6417a0001e4e3d8ecb9bac99e81aa20266 Mon Sep 17 00:00:00 2001 From: Ore O Date: Fri, 10 Mar 2023 05:15:09 -0800 Subject: [PATCH 03/11] fix: Update vep.py import --- eegnb/experiments/visual_vep/vep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eegnb/experiments/visual_vep/vep.py b/eegnb/experiments/visual_vep/vep.py index 1acd1b11..e162bc53 100644 --- a/eegnb/experiments/visual_vep/vep.py +++ b/eegnb/experiments/visual_vep/vep.py @@ -1,6 +1,6 @@ from time import time, strftime, gmtime from pylsl import StreamInfo, StreamOutlet -from eegnb.experiments.Experiment import Experiment +from eegnb.experiments import Experiment class VisualVEP(Experiment): From 3c997b9b19016013bdda1c294a91b5209fc86194 Mon Sep 17 00:00:00 2001 From: Ore O Date: Fri, 10 Mar 2023 05:28:05 -0800 Subject: [PATCH 04/11] Update Makefile --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index e2a1a5ac..f05f846e 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,12 @@ install-deps-apt: # libpulse-dev required to build pocketsphinx (speech recognition dependency of psychopy) # libsdl2-dev required by psychopy sudo apt-get -y install xvfb libgtk-3-dev freeglut3-dev portaudio19-dev libpulse-dev pulseaudio libsdl2-dev + + # 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 From 0340fe4f2b65f9d42811dddf943a22aafee7d97a Mon Sep 17 00:00:00 2001 From: Ore O Date: Fri, 10 Mar 2023 05:28:45 -0800 Subject: [PATCH 05/11] Update vep.py --- eegnb/experiments/visual_vep/vep.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eegnb/experiments/visual_vep/vep.py b/eegnb/experiments/visual_vep/vep.py index e162bc53..29972f47 100644 --- a/eegnb/experiments/visual_vep/vep.py +++ b/eegnb/experiments/visual_vep/vep.py @@ -1,6 +1,8 @@ from time import time, strftime, gmtime from pylsl import StreamInfo, StreamOutlet + from eegnb.experiments import Experiment +from eegnb.devices.eeg import EEG class VisualVEP(Experiment): From 53da35a9b4f71f2d7d82e66e7f46bd1a4ac130ef Mon Sep 17 00:00:00 2001 From: Ore O Date: Wed, 26 Apr 2023 23:52:28 -0700 Subject: [PATCH 06/11] fix: typo in makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f05f846e..b70b879b 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ install-deps-apt: # configure dynamic links sudo ldconfig - UPDATED_LIBPATH=(sudo find / -name libnotify.so) + UPDATED_LIBPATH=$(sudo find / -name libnotify.so) LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$UPDATED_LIBPATH install-deps-wxpython: From bb88718941bcc1516af75fa44e7cfb6d4edbc74d Mon Sep 17 00:00:00 2001 From: Ore O Date: Wed, 26 Apr 2023 23:56:15 -0700 Subject: [PATCH 07/11] fix: update BaseExperiment class reference --- eegnb/experiments/visual_vep/vep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eegnb/experiments/visual_vep/vep.py b/eegnb/experiments/visual_vep/vep.py index 29972f47..c4e02851 100644 --- a/eegnb/experiments/visual_vep/vep.py +++ b/eegnb/experiments/visual_vep/vep.py @@ -5,7 +5,7 @@ from eegnb.devices.eeg import EEG -class VisualVEP(Experiment): +class VisualVEP(Experiment.BaseExperiment): def __init__(self, duration=120, eeg: EEG=None, save_fn=None, n_trials = 2000, iti = 0.2, soa = 0.2, jitter = 0.1): From 997f64ab98b66642e4b2d142cd48b5a210220016 Mon Sep 17 00:00:00 2001 From: Ore O Date: Thu, 27 Apr 2023 00:12:51 -0700 Subject: [PATCH 08/11] Update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b70b879b..e00b3e35 100644 --- a/Makefile +++ b/Makefile @@ -35,4 +35,4 @@ install-deps-apt: 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-20.04 wxPython + pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-22.04 wxPython From a45770e5d5695d98de508a11f78309fba154f642 Mon Sep 17 00:00:00 2001 From: Ore O Date: Thu, 27 Apr 2023 00:19:56 -0700 Subject: [PATCH 09/11] Update vep.py --- eegnb/experiments/visual_vep/vep.py | 1 + 1 file changed, 1 insertion(+) diff --git a/eegnb/experiments/visual_vep/vep.py b/eegnb/experiments/visual_vep/vep.py index 6c77a303..9cfcef96 100644 --- a/eegnb/experiments/visual_vep/vep.py +++ b/eegnb/experiments/visual_vep/vep.py @@ -1,5 +1,6 @@ from time import time, strftime, gmtime from pylsl import StreamInfo, StreamOutlet +from typing import Optional from eegnb.experiments import Experiment from eegnb.devices.eeg import EEG From 06744771f5e41bbe5c96eb37a856f92e890e94ea Mon Sep 17 00:00:00 2001 From: Ore O Date: Thu, 27 Apr 2023 00:29:24 -0700 Subject: [PATCH 10/11] Update 01r__n170_viz.py --- examples/visual_n170/01r__n170_viz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/visual_n170/01r__n170_viz.py b/examples/visual_n170/01r__n170_viz.py index 53ba630e..9aa48f7d 100644 --- a/examples/visual_n170/01r__n170_viz.py +++ b/examples/visual_n170/01r__n170_viz.py @@ -59,7 +59,7 @@ subject = 1 session = 1 raw = load_data(subject,session, - experiment='visual-N170', site='eegnb_examples', device_name='muse2016', + experiment='visual-N170', site='eegnb_examples', device_name='muse2016_bfn', data_dir = eegnb_data_path) ################################################################################################### From b479f249a6d17681be87f3947d001199eb8ef43b Mon Sep 17 00:00:00 2001 From: Ore O Date: Thu, 27 Apr 2023 00:31:05 -0700 Subject: [PATCH 11/11] makefile: install libnotify4 --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e00b3e35..29e53347 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,8 @@ install-deps-apt: # 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 - sudo apt-get -y install xvfb libgtk-3-dev freeglut3-dev portaudio19-dev libpulse-dev pulseaudio libsdl2-dev + # 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