Skip to content

Commit

Permalink
major update: merging develop to master (#217)
Browse files Browse the repository at this point in the history
* example test commit (#182)

* example test commit

* example edit

* ci: run test workflow on develop branch

* ci: add develop branch to job triggers

* ci: fix syntax issue in workflow

* fix: fixed import (brainflow updated API)

* build(deps): locked pylsl==1.10.5 (#187)

* Experiment Class Refactor (update to #183), converting specific experiments to subclasses (#184)

* First commit

* Second commit

* Modifications

* Lol

* Lol

* Incorporated N170 and p300, looking good for a PR

* ssvep update

* Implementing subclasses instead of loose functions

* fix: fixed import (brainflow updated API)

* Playing around still

* Fixing import errors

* Adding abstractmethod decorators

* Still working on the import error

* Guess what's finally working

* Comments and naming ticks

* More comments

* Live coding demonstration

* ssvep adapted

* Adapting Auditory Oddball

* changing save_fn to self.save_fun

* This maybe the last big change

* utils file changed, changes work through cli

Co-authored-by: Erik Bjäreholt <erik@bjareho.lt>

* Submodule added for gsoc

* Adding pipelines for cli analysis (#202)

* started pipelines function

* almost working simple function equivalents of nb scripts

* fix: fixed import (brainflow updated API)

* sqc fixes for unicorn (#176)

* Ignore pushes

* Trying to create a cli

* Stepping through the problem

* First commit

* Fixing pause in signal quality check

* Fixing Signal quality check problem

* fix the technical debt

* Save path done for automated saving pdf

* I feel amazing

* Almost through

* Update eegnb/cli/__main__.py

Co-authored-by: Erik Bjäreholt <erik@bjareho.lt>

* Trying to create cli but it's being really painful

* Extra word cli error

* Changed example handling

* Pain

* Adding whole datapath

* Finally fixed cli

* hmm

* Looking good

* added hyperlink

* Having some issues with detecting css and image deltetion

* Just the css now

* Fixed the css linking problem though it's a weird soln

* Automated running, still fnames problem

* Hahahah embedded images in html

* Improving code

* Okay now

* Look at that

* Almost there just the two figures now

* Now

* Added attrdict to do with cli error

Co-authored-by: John Griffiths <j.davidgriffiths@gmail.com>
Co-authored-by: Erik Bjäreholt <erik@bjareho.lt>
Co-authored-by: John Griffiths <JohnGriffiths@users.noreply.github.com>

* added more options for site args; improved function names; removed some redundant lines (#209)

* fix subject num parsing bug

* analysis report function improvements for openbci cyton and gtec unicorn devices

* run exp fix

* Update requirements.txt

* fixes to get docs building by github action (#210)

* fixes to get docs building by github action

* reverted some changes

* Update 01r__ssvep_viz.py

Co-authored-by: John Griffiths <JohnGriffiths@users.noreply.github.com>

* Update README.rst

small commit to test doc build workflow on this branch

* removing gsoc submodule

Co-authored-by: Erik Bjäreholt <erik@bjareho.lt>
Co-authored-by: Parv Agarwal <65726543+Parvfect@users.noreply.github.com>
Co-authored-by: Parvfect <parvagrw02@gmail.com>
Co-authored-by: Ben Pettit <pelleter@gmail.com>
  • Loading branch information
5 people authored Jan 19, 2023
1 parent a225012 commit ac1f5fb
Show file tree
Hide file tree
Showing 36 changed files with 1,155 additions and 599 deletions.
19 changes: 10 additions & 9 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,36 @@ name: Docs

on:
push:
branches: [ master, 'dev/*' ]
branches: [ master, develop, 'dev/*' ]
pull_request:
branches: [ master ]
branches: [ master, develop ]

jobs:
build:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.8
- name: Install dependencies
run: |
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-18.04 wxPython
pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxPython
pip install .
- name: Build docs
run: |
cd doc && make html
- name: Deploy Docs
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' # TODO: Deploy seperate develop-version of docs?
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: doc/_build/html

10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Test

on:
push:
branches: [ master ]
branches: [ master, develop ]
pull_request:
branches: [ master ]
branches: [ master, develop ]

jobs:
test:
Expand Down Expand Up @@ -60,13 +60,13 @@ jobs:
run: |
python -m pip install --upgrade pip wheel
pip install .
pip install -U psychtoolbox # JG_ADD
# EB: needed?
- name: Run eegnb install test
shell: bash
pip install -U psychtoolbox # JG_ADD
shell: bash
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
Xvfb :0 -screen 0 1024x768x24 -ac +extension GLX +render -noreset &> xvfb.log &
/
export DISPLAY=:0
fi
eegnb --help
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ examples/visual_cueing/*.csv
.coverage
coverage.xml
htmlcov

# PyCharm
.idea/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "GSOC-eeg-notebooks"]
path = GSOC-eeg-notebooks
url = https://github.com/Parvfect/GSOC-eeg-notebooks
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ EEG-Notebooks

EEG-Notebooks is a collection of classic EEG experiments, implemented in Python 3 and Jupyter notebooks. The experimental protocols and analyses are quite generic, but are primarily taylored for low-budget / consumer EEG hardware such as the InteraXon MUSE and OpenBCI Cyton. The goal is to make cognitive neuroscience and neurotechnology more accessible, affordable, and scalable.

- **For an intro talk on the eeg-notebooks project see:** `JG's Brainhack Ontario 2020 presentation <https://www.crowdcast.io/e/brainhack-ontario/7>`_.
- **For an intro talk on the eeg-notebooks project see:** `JG's Brainhack Ontario presentation <https://www.crowdcast.io/e/brainhack-ontario/7>`_.
- **For documentation see:** `documentation site <https://neurotechx.github.io/eeg-notebooks/index.html>`_.
- **For code see:** `github site <https://github.com/neurotechx/eeg-notebooks>`_.
- **For instructions on running experiments see:** `running experiments <https://neurotechx.github.io/eeg-notebooks/getting_started/running_experiments.html>`_.
Expand Down
39 changes: 39 additions & 0 deletions eegnb/analysis/analysis_report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<link href="styling.css" rel="stylesheet" />
<title>Analysis Report</title>
</head>
<body>
<div class="topnav">
<a href="#Description">Description</a>
<a href="#Raw Epoch">Raw Epoch</a>
<a href="#Stimulus Response">Stimulus Response</a>
</div>
<div id="Description">
<h1>Analysis Report</h1>
<p>
<b></b>Experiment Name: {} <br>
Subject Id: {} <br>
Session Id: {} <br>
EEG Device: {} <br>
Drop Percentage: {} <br> <br>
This is an analysis report for the experiment. <br> For more information about the experiment, please visit the <a href="https://neurotechx.github.io/eeg-notebooks/">documentation</a>
</p>
</div>
<div id="Raw Epoch">
<h2>Raw Epoch</h2>
<p>
The raw epoch is shown below. The raw epoch is the data that is recorded from the EEG headset. The raw epoch is then processed to remove noise and artifacts.
</p>
<img src="power_spectrum.png" alt="Raw Epoch" />
</div>
<div id="Stimulus Response">
<h2>Stimulus Response</h2>
<p>
The stimulus response is shown below. The stimulus response is the data that is recorded from the EEG headset after removing noise and artifacts.
</p>
<img src="erp_plot.png" alt="Stimulus Response" />
</div>
</body>
</html>
95 changes: 95 additions & 0 deletions eegnb/analysis/analysis_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@

# Generating html using Python

from airium import Airium
from typing import Dict
import os
import eegnb
import base64

a = Airium()

def get_experiment_information(experiment:str):
analysis_save_path = os.path.join(os.path.dirname(eegnb.__file__), "analysis")
file_path = os.path.join(analysis_save_path, "experiment_descriptions")

with open(os.path.join(file_path, experiment + ".txt"), 'r') as f:
experiment_text = f.readlines()

return experiment_text

def get_img_string(image_save_path):
""" Returns image as string to embed into the html report """
return base64.b64encode(open(image_save_path, "rb").read()).decode()

def get_html(experimental_parameters: Dict):

# add variable to store the link
analysis_save_path = os.path.join(os.path.dirname(eegnb.__file__), "analysis")
css_path = os.path.join(analysis_save_path, "styling.css")
eeg_device, experiment, subject, session, example, drop_percentage, epochs_chosen = experimental_parameters.values()

erp_image_path = os.path.join(os.getcwd(), "erp_plot.png")
pos_image_path = os.path.join(os.getcwd(), "power_spectrum.png")

experiment_text = get_experiment_information(experiment)


""" Possibility of unique experiment text - decision to be made """
#experiment_text = ""
#with open('experiment_descriptions/{}.txt'.format(experiment), 'r') as f:
# experiment_text = f.readlines()

a('<!DOCTYPE html>')
with a.html():
with a.head():
a.link(href=css_path, rel='stylesheet', type="text/css")
a.title(_t="Analysis Report")

with a.body():

# Navigation bar
with a.div(klass="topnav"):
a.a(_t="Description", href="#Description")
a.a(_t="Raw Epoch", href="#Raw Epoch")
a.a(_t="Stimulus Response", href="#Stimulus Response")

# Description
with a.div(id="Description"):
a.h1(_t="Analysis Report")
with a.p():
a("Experiment Name: {} <br>".format(experiment))

if example:
a("Example File <br>")
else:
a("Subject Id: {} <br>".format(subject))
a("Session Id: {} <br>".format(session))

a("EEG Device: {} <br>".format(eeg_device))
a('This is an analysis report for the experiment. <br> For more information about the experiment, please visit the <a href="https://neurotechx.github.io/eeg-notebooks/">documentation</a><br><br>')
a("{}<br>".format(experiment_text[0]))
a("{}<br>".format(experiment_text[1]))

# Raw Epoch
with a.div(id="Raw Epoch"):
a.h2(_t="Raw Epoch")
with a.p():
a("The power spectrum of the raw epoch is displayed below. The raw epoch is then processed to remove noise and artifacts.")
a.img(src="data:image/png;base64, {}".format(get_img_string(pos_image_path)), alt="Raw Epoch")

# Stimulus Response
with a.div(id="Stimulus Response"):
a.h2(_t="Stimulus Response")
with a.p():
a("The stimulus response is shown below. The stimulus response is the amplitude response at the specific timescales where the response to the stimulus can be detected. <br>")
a("Epochs chosen: {} <br>".format(epochs_chosen))
a("Drop Percentage: {} %<br> <br>".format(round(drop_percentage,2)))
a.img(src="data:image/png;base64, {}".format(get_img_string(erp_image_path)), alt="Stimulus Response")

# Delete the images
os.remove(erp_image_path)
os.remove(pos_image_path)

# Return the html
return str(a)
2 changes: 2 additions & 0 deletions eegnb/analysis/experiment_descriptions/visual-N170.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The N170 is a large negative event-related potential (ERP) component that occurs after the detection of faces, but not objects, scrambled faces, or other body parts such as hands.
In the experiment we aim to detect the N170 using faces and houses as our stimuli.
2 changes: 2 additions & 0 deletions eegnb/analysis/experiment_descriptions/visual-P300.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The P300 is a positive event-related potential (ERP) that occurs around 300ms after perceiving a novel or unexpected stimulus. It is most commonly elicited through ‘oddball’ experimental paradigms, where a certain subtype of stimulus is presented rarely amidst a background of another more common type of stimulus.
In the experiment, we aimed to elicit P300 response using a visual oddball stimulation.
Loading

0 comments on commit ac1f5fb

Please sign in to comment.