├── __init__.py ├── stim ├── cats_dogs │ ├── LICENSE.txt │ ├── target-76116_640.jpg │ ├── target-2083492_640.jpg │ ├── target-360807_640.jpg │ ├── target-468232_640.jpg │ ├── nontarget-234836_640.jpg │ ├── nontarget-274183_640.jpg │ ├── nontarget-280332_640.jpg │ └── nontarget-734689_640.jpg └── face_house │ ├── faces │ ├── Annie_1.jpg │ ├── Annie_2.jpg │ ├── Annie_3.jpg │ ├── Annie_4.jpg │ ├── Blake_1.jpg │ ├── Blake_2.jpg │ ├── Blake_3.jpg │ ├── Blake_4.jpg │ ├── Don_1.jpg │ ├── Don_2.jpg │ ├── Don_3.jpg │ ├── Don_4.jpg │ ├── Frank_1.jpg │ ├── Frank_2.jpg │ ├── Frank_3.jpg │ ├── Frank_4.jpg │ ├── Janie_1.jpg │ ├── Janie_2.jpg │ ├── Janie_3.jpg │ ├── Janie_4.jpg │ ├── Joan_1.jpg │ ├── Joan_2.jpg │ ├── Joan_3.jpg │ ├── Joan_4.jpg │ ├── Jodi_1.jpg │ ├── Jodi_2.jpg │ ├── Jodi_3.jpg │ ├── Jodi_4.jpg │ ├── Joe_1.jpg │ ├── Joe_2.jpg │ ├── Joe_3.jpg │ ├── Joe_4.jpg │ ├── Tim_1.jpg │ ├── Tim_2.jpg │ ├── Tim_3.jpg │ ├── Tim_4.jpg │ ├── Tom_1.jpg │ ├── Tom_2.jpg │ ├── Tom_3.jpg │ ├── Tom_4.jpg │ ├── Estelle_1.jpg │ ├── Estelle_2.jpg │ ├── Estelle_3.jpg │ ├── Estelle_4.jpg │ ├── Wallace_1.jpg │ ├── Wallace_2.jpg │ ├── Wallace_3.jpg │ └── Wallace_4.jpg │ ├── houses │ ├── house1.1.jpg │ ├── house1.2.jpg │ ├── house1.3.jpg │ ├── house1.4.jpg │ ├── house2.1.jpg │ ├── house2.2.jpg │ ├── house2.3.jpg │ ├── house2.4.jpg │ ├── house3.1.jpg │ ├── house3.2.jpg │ ├── house3.3.jpg │ ├── house3.4.jpg │ ├── house4.1.jpg │ ├── house4.2.jpg │ ├── house4.3.jpg │ ├── house4.4.jpg │ ├── house5.1.jpg │ ├── house5.2.jpg │ ├── house5.3.jpg │ ├── house5.4.jpg │ ├── house6.1.jpg │ ├── house6.2.jpg │ ├── house6.3.jpg │ ├── house6.4.jpg │ ├── house7.1.jpg │ ├── house7.2.jpg │ ├── house7.3.jpg │ ├── house7.4.jpg │ ├── house8.1.jpg │ ├── house8.2.jpg │ ├── house8.3.jpg │ ├── house8.4.jpg │ ├── house9.1.jpg │ ├── house9.2.jpg │ ├── house9.3.jpg │ ├── house9.4.jpg │ ├── house10.1.jpg │ ├── house10.2.jpg │ ├── house10.3.jpg │ ├── house10.4.jpg │ ├── house11.1.jpg │ ├── house11.2.jpg │ ├── house11.3.jpg │ ├── house11.4.jpg │ ├── house12.1.jpg │ ├── house12.2.jpg │ ├── house12.3.jpg │ └── house12.4.jpg │ └── LICENSE.txt ├── doc_images ├── OpenBCI_Available.png ├── OpenBCI_standard16.png └── OpenBCI_standard8.png ├── utils.py ├── dataset.py ├── README.md ├── P300.ipynb ├── experiments.py └── N170.ipynb /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stim/cats_dogs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | All the files in this directory were downloaded from pixabay, and are Public Domain (CC0). 2 | -------------------------------------------------------------------------------- /doc_images/OpenBCI_Available.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/doc_images/OpenBCI_Available.png -------------------------------------------------------------------------------- /doc_images/OpenBCI_standard16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/doc_images/OpenBCI_standard16.png -------------------------------------------------------------------------------- /doc_images/OpenBCI_standard8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/doc_images/OpenBCI_standard8.png -------------------------------------------------------------------------------- /stim/face_house/faces/Annie_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Annie_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Annie_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Annie_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Annie_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Annie_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Annie_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Annie_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Blake_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Blake_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Blake_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Blake_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Blake_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Blake_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Blake_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Blake_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Don_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Don_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Don_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Don_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Don_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Don_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Don_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Don_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Frank_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Frank_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Frank_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Frank_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Frank_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Frank_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Frank_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Frank_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Janie_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Janie_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Janie_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Janie_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Janie_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Janie_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Janie_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Janie_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joan_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joan_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joan_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joan_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joan_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joan_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joan_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joan_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Jodi_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Jodi_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Jodi_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Jodi_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Jodi_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Jodi_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Jodi_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Jodi_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joe_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joe_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joe_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joe_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joe_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joe_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Joe_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Joe_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tim_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tim_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tim_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tim_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tim_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tim_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tim_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tim_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tom_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tom_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tom_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tom_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tom_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tom_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Tom_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Tom_4.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/target-76116_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/target-76116_640.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Estelle_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Estelle_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Estelle_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Estelle_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Estelle_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Estelle_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Estelle_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Estelle_4.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Wallace_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Wallace_1.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Wallace_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Wallace_2.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Wallace_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Wallace_3.jpg -------------------------------------------------------------------------------- /stim/face_house/faces/Wallace_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/faces/Wallace_4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house1.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house1.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house1.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house1.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house1.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house1.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house1.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house1.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house2.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house2.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house2.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house2.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house2.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house2.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house2.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house2.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house3.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house3.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house3.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house3.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house3.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house3.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house3.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house3.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house4.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house4.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house4.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house4.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house4.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house4.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house4.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house4.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house5.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house5.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house5.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house5.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house5.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house5.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house5.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house5.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house6.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house6.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house6.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house6.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house6.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house6.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house6.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house6.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house7.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house7.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house7.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house7.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house7.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house7.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house7.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house7.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house8.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house8.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house8.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house8.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house8.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house8.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house8.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house8.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house9.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house9.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house9.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house9.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house9.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house9.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house9.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house9.4.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/target-2083492_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/target-2083492_640.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/target-360807_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/target-360807_640.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/target-468232_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/target-468232_640.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house10.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house10.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house10.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house10.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house10.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house10.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house10.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house10.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house11.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house11.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house11.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house11.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house11.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house11.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house11.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house11.4.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house12.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house12.1.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house12.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house12.2.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house12.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house12.3.jpg -------------------------------------------------------------------------------- /stim/face_house/houses/house12.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/face_house/houses/house12.4.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/nontarget-234836_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/nontarget-234836_640.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/nontarget-274183_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/nontarget-274183_640.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/nontarget-280332_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/nontarget-280332_640.jpg -------------------------------------------------------------------------------- /stim/cats_dogs/nontarget-734689_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JadinTredup/brainflow-notebooks/HEAD/stim/cats_dogs/nontarget-734689_640.jpg -------------------------------------------------------------------------------- /stim/face_house/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Stimuli used in: 2 | 3 | Haxby, J., Gobbini, M., Furey, M., Ishai, A., Schouten, J., and Pietrini, P. (2001). 4 | Distributed and overlapping representations of faces and objects in ventral temporal 5 | cortex. Science 293, 2425–2430. 6 | 7 | See: http://www.pymvpa.org/datadb/haxby2001.html 8 | 9 | The original authors of Haxby et al. (2001) hold the copyright of this dataset and 10 | made it available under the terms of the Creative Commons Attribution-Share Alike 3.0 license. 11 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import socket 3 | import platform 4 | from collections import OrderedDict 5 | import seaborn as sns 6 | import pandas as pd 7 | from matplotlib import pyplot as plt 8 | 9 | 10 | SYNTHETIC_CHANNELS = ['T7', 'CP5', 'FC5', 'C3', 'C4', 'FC6', 'CP6', 'T8'] 11 | 12 | 13 | OPENBCI_STANDARD_8 = ['Fp1', 'Fp2', 'C3', 'C4', 'P7', 'P8', 'O1', 'O2', 14 | 'F7' , 'F8' , 'F3', 'F4', 'T7', 'T8', 'P3', 'P4'] 15 | 16 | 17 | OPENBCI_STANDARD_16 = ['Fp1', 'Fp2', 'C3', 'C4', 'P7', 'P8', 'O1', 'O2', 18 | 'F7' , 'F8' , 'F3', 'F4', 'T7', 'T8', 'P3', 'P4'] 19 | 20 | 21 | BRAINBIT_CHANNELS = ['T3', 'T4', 'O1', 'O2'] 22 | 23 | 24 | UNICORN_CHANNELS = ['Fz', 'C3', 'Cz', 'C4', 'Pz', 'PO7', 'Oz', 'PO8'] 25 | 26 | 27 | SDESIGN = ['O1', 'PO3', 'P7' , 'CP5', 'CP2', 'P8' , 'PO4', 'O2', 28 | 'P3', 'FC5', 'C3', 'CP1', 'P4', 'C4', 'FC6', 'CP6'] 29 | 30 | 31 | 32 | USB_LINUX = '/dev/ttyUSB0' 33 | 34 | USB_WINDOWS = 'COM3' 35 | 36 | 37 | def get_fns(subject, run, paradigm): 38 | 39 | data_fn = os.path.join('data', f'{subject}_{paradigm}_{run}.csv') 40 | event_fn = os.path.join('data', f'{subject}_{paradigm}_{run}_EVENTS.csv') 41 | 42 | return data_fn, event_fn 43 | 44 | 45 | def get_openbci_usb(usb_port): 46 | """Gets the standard USB port for the OpenBCI USB dongle 47 | """ 48 | if usb_port is None: 49 | if platform.system() == 'Linux': 50 | usb_port = USB_LINUX 51 | elif platform.system() == 'Windows': 52 | usb_port = USB_WINDOWS 53 | elif platform.system() == 'Darwin': 54 | print('Please provide name of usb port for Mac OS') 55 | return None 56 | 57 | return usb_port 58 | 59 | 60 | def get_openbci_ip(address, port): 61 | if address == None: 62 | address = '192.168.4.1' 63 | 64 | if port == None: 65 | s = socket.socket() 66 | s.bind(('', 0)) 67 | port = s.getsockname()[1] 68 | 69 | return address, port 70 | 71 | 72 | def plot_conditions(epochs, conditions=OrderedDict(), ci=97.5, n_boot=1000, 73 | title='', palette=None, ylim=(-6, 6), 74 | diff_waveform=(1, 2)): 75 | """Plot ERP conditions. 76 | Args: 77 | epochs (mne.epochs): EEG epochs 78 | Keyword Args: 79 | conditions (OrderedDict): dictionary that contains the names of the 80 | conditions to plot as keys, and the list of corresponding marker 81 | numbers as value. E.g., 82 | conditions = {'Non-target': [0, 1], 83 | 'Target': [2, 3, 4]} 84 | ci (float): confidence interval in range [0, 100] 85 | n_boot (int): number of bootstrap samples 86 | title (str): title of the figure 87 | palette (list): color palette to use for conditions 88 | ylim (tuple): (ymin, ymax) 89 | diff_waveform (tuple or None): tuple of ints indicating which 90 | conditions to subtract for producing the difference waveform. 91 | If None, do not plot a difference waveform 92 | Returns: 93 | (matplotlib.figure.Figure): figure object 94 | (list of matplotlib.axes._subplots.AxesSubplot): list of axes 95 | """ 96 | if isinstance(conditions, dict): 97 | conditions = OrderedDict(conditions) 98 | 99 | if palette is None: 100 | palette = sns.color_palette("hls", len(conditions) + 1) 101 | 102 | X = epochs.get_data() * 1e6 103 | times = epochs.times 104 | y = pd.Series(epochs.events[:, -1]) 105 | 106 | fig, axes = plt.subplots(2, 2, figsize=[12, 6], 107 | sharex=True, sharey=True) 108 | axes = [axes[1, 0], axes[0, 0], axes[0, 1], axes[1, 1]] 109 | 110 | for ch in range(4): 111 | for cond, color in zip(conditions.values(), palette): 112 | sns.tsplot(X[y.isin(cond), ch], time=times, color=color, 113 | n_boot=n_boot, ci=ci, ax=axes[ch]) 114 | 115 | if diff_waveform: 116 | diff = (np.nanmean(X[y == diff_waveform[1], ch], axis=0) - 117 | np.nanmean(X[y == diff_waveform[0], ch], axis=0)) 118 | axes[ch].plot(times, diff, color='k', lw=1) 119 | 120 | axes[ch].set_title(epochs.ch_names[ch]) 121 | axes[ch].set_ylim(ylim) 122 | axes[ch].axvline(x=0, ymin=ylim[0], ymax=ylim[1], color='k', 123 | lw=1, label='_nolegend_') 124 | 125 | axes[0].set_xlabel('Time (s)') 126 | axes[0].set_ylabel('Amplitude (uV)') 127 | axes[-1].set_xlabel('Time (s)') 128 | axes[1].set_ylabel('Amplitude (uV)') 129 | 130 | if diff_waveform: 131 | legend = (['{} - {}'.format(diff_waveform[1], diff_waveform[0])] + 132 | list(conditions.keys())) 133 | else: 134 | legend = conditions.keys() 135 | axes[-1].legend(legend) 136 | sns.despine() 137 | plt.tight_layout() 138 | 139 | if title: 140 | fig.suptitle(title, fontsize=20) 141 | 142 | return fig, axes -------------------------------------------------------------------------------- /dataset.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import pandas as pd 4 | 5 | from mne import create_info, concatenate_raws, pick_types, Epochs 6 | from mne.io import RawArray 7 | from mne.io.edf import read_raw_edf 8 | from mne.datasets import eegbci 9 | from mne.event import find_events 10 | from mne.channels import make_standard_montage 11 | 12 | from brainflow.board_shim import BoardShim, BoardIds 13 | from brainflow.data_filter import DataFilter, FilterTypes, AggOperations 14 | 15 | import utils 16 | 17 | class brainflowDataset: 18 | def __init__(self, paradigm, subject, board_type, layout=None): 19 | # Initialize class variables 20 | self.paradigm = paradigm 21 | self.board_type = board_type 22 | self.eeg_info = self._get_source_info(layout) 23 | self.subject = subject 24 | 25 | def _get_source_info(self, layout=None): 26 | """ Gets board-specific information from the Brainflow library 27 | 28 | Returns: 29 | eeg_channels 30 | sfreq 31 | channel_names 32 | """ 33 | if self.board_type == 'synthetic': 34 | board_id = BoardIds.SYNTHETIC_BOARD.value 35 | eeg_channels, sfreq= self._get_board_info(board_id) 36 | channel_names = utils.SYNTHETIC_CHANNELS 37 | 38 | elif self.board_type == 'ganglion': 39 | board_id = BoardIds.GANGLION_BOARD.value 40 | eeg_channels, sfreq = self._get_board_info(board_id) 41 | 42 | elif self.board_type == 'cyton': 43 | board_id = BoardIds.CYTON_BOARD.value 44 | eeg_channels, sfreq = self._get_board_info(board_id) 45 | channel_names = utils.OPENBCI_STANDARD_8 46 | 47 | elif self.board_type == 'cyton_daisy': 48 | board_id = BoardIds.CYTON_DAISY_BOARD.value 49 | eeg_channels, sfreq = self._get_board_info(board_id) 50 | channel_names = utils.OPENBCI_STANDARD_16 51 | 52 | elif self.board_type == 'ganglion_wifi': 53 | board_id = BoardIds.GANGLION_WIFI_BOARD.value 54 | eeg_channels, sfreq = self._get_board_info(board_id) 55 | 56 | elif self.board_type == 'cyton_wifi': 57 | board_id = BoardIds.CYTON_WIFI_BOARD.value 58 | eeg_channels, sfreq = self._get_board_info(board_id) 59 | channel_names = utils.OPENBCI_STANDARD_8 60 | 61 | elif self.board_type == 'cyton_daisy_wifi': 62 | board_id = BoardIds.CYTON_DAISY_WIFI_BOARD.value 63 | eeg_channels, sfreq = self._get_board_info(board_id) 64 | channel_names = utils.OPENBCI_STANDARD_16 65 | 66 | elif self.board_type == 'brainbit': 67 | board_id = BoardIds.BRAINBIT_BOARD.value 68 | eeg_channels, sfreq = self._get_board_info(board_id) 69 | channel_names = utils.BRAINBIT_CHANNELS 70 | 71 | elif self.board_type == 'unicorn': 72 | board_id = BoardIds.UNICORN_BOARD.value 73 | eeg_channels, sfreq, channel_names = self._get_board_info(board_id) 74 | channel_names = utils.UNICORN_CHANNELS 75 | 76 | 77 | if layout: 78 | channel_names = layout 79 | 80 | return [eeg_channels, sfreq, channel_names] 81 | 82 | def _get_board_info(self, id): 83 | channels = BoardShim.get_eeg_channels(id) 84 | sfreq = BoardShim.get_sampling_rate(id) 85 | return channels, sfreq 86 | 87 | def _load_session_data(self, subject_name, run): 88 | """Loads the session data and event files for a single session for a single subject. The first 5 seconds 89 | of every session is a baseline that was used to wait for the signal to settle, so the first 5 seconds 90 | of every trial is also removed. 91 | 92 | Parameters: 93 | subject_name 94 | run 95 | path 96 | 97 | Returns: 98 | data 99 | events 100 | """ 101 | data_fn = subject_name + '_' + self.paradigm + '_' + str(run) + '.csv' 102 | event_fn = subject_name + '_' + self.paradigm + '_' + str(run) + '_EVENTS.csv' 103 | data_path = os.path.join('data', data_fn) 104 | event_path = os.path.join('data', event_fn) 105 | print(data_path) 106 | data = DataFilter.read_file(data_path) 107 | 108 | # remove beginning 5 seconds where signal settles 109 | idx = 5 * self.eeg_info[1] 110 | data = data[:, idx:] 111 | 112 | events = pd.read_csv(event_path) 113 | return data, events 114 | 115 | def _create_stim_array(self, data, events): 116 | data_time = data[-1] 117 | events = events.values 118 | events[:, 1] += 1 119 | stim_array = np.zeros((1, len(data_time))) 120 | for event in events: 121 | insert_idx = np.where(data_time == event[-1]) 122 | stim_array[0][insert_idx] = event[1] 123 | 124 | return stim_array 125 | 126 | def _add_stim_to_raw(self, raw, stim_data, ch_name): 127 | info = create_info([ch_name], raw.info['sfreq'], ['stim']) 128 | stim_raw = RawArray(stim_data, info) 129 | raw.add_channels([stim_raw], force_update_info=True) 130 | return raw 131 | 132 | def _scale_eeg_data(self, data): 133 | data[self.eeg_info[0]] *= 1e-6 134 | return data 135 | 136 | def filter_data_pre_raw(self, data, fcenter, bandwidth, order, filter_type): 137 | """Filters the OpenBCI data using the BrainFlow functions before creating an MNE Raw object. 138 | 139 | Parameters: 140 | data 141 | fcenter 142 | bandwidth 143 | order 144 | filter_type 145 | 146 | Returns: 147 | data 148 | """ 149 | for channel in self.eeg_info[0]: 150 | if filter_type == 'bandpass': 151 | DataFilter.perform_bandpass(data[channel], self.eeg_info[1], fcenter, bandwidth, order, FilterTypes.BESSEL.value, 152 | 0) 153 | elif filter_type == 'notch': 154 | DataFilter.perform_bandstop(data[channel], self.eeg_info[1], fcenter, bandwidth, order, 155 | FilterTypes.BUTTERWORTH.value, 0) 156 | elif filter_type == 'highpass': 157 | DataFilter.perform_highpass(data[channel], self.eeg_info[1], fcenter, order, FilterTypes.BUTTERWORTH.value, 0) 158 | return data 159 | 160 | def denoise_data_pre_raw(self, data, denoise_method): 161 | for channel in self.eeg_info[0]: 162 | if denoise_method == 'mean': 163 | DataFilter.perform_rolling_filter(data[channel], 3, AggOperations.MEAN.value) 164 | elif denoise_method == 'median': 165 | DataFilter.perform_rolling_filter(data[channel], 3, AggOperations.MEDIAN.value) 166 | else: 167 | DataFilter.perform_wavelet_denoising(data[channel], denoise_method, 3) 168 | return data 169 | 170 | def preprocess_eeg(self, data, notch=True, bandpass=True, denoise=True, denoise_method='coif3'): 171 | """Preprocessing pipeline for EEG data 172 | 173 | Parameters: 174 | data 175 | notch 176 | bandpass 177 | denoise 178 | denoise_method 179 | 180 | Returns: 181 | data 182 | """ 183 | # Notch filter to remove line-frequency 184 | if notch: 185 | print("Notch filter") 186 | data = self.filter_data_pre_raw(data, 60, 2, 4, 'notch') 187 | # Bandpass filter 188 | if bandpass: 189 | print("Bandpass filter") 190 | data = self.filter_data_pre_raw(data, 26, 50, 3, 'bandpass') 191 | # Denoising 192 | if denoise: 193 | print("Denoise") 194 | data = self.denoise_data_pre_raw(data, denoise_method) 195 | 196 | return data 197 | 198 | def bci_to_raw(self, data): 199 | eeg_data = data[self.eeg_info[0], :] 200 | ch_types = ['eeg'] * len(self.eeg_info[0]) 201 | #montage = make_standard_montage('standard_1005') 202 | montage = make_standard_montage('standard_1020') 203 | info = create_info(ch_names=self.eeg_info[2], sfreq=self.eeg_info[1], ch_types=ch_types) 204 | raw = RawArray(eeg_data, info) 205 | raw.set_montage(montage) 206 | return raw 207 | 208 | def load_session_to_raw(self, subject_name, run, preprocess=False): 209 | # Load data 210 | data, events = self._load_session_data(subject_name, run) 211 | # Scale data 212 | data = self._scale_eeg_data(data) 213 | # Create stim array 214 | stims = self._create_stim_array(data, events) 215 | if preprocess: 216 | # Preprocess data 217 | data = self.preprocess_eeg(data) 218 | raw = self.bci_to_raw(data) 219 | raw = self._add_stim_to_raw(raw, stims, 'STI') 220 | return raw 221 | 222 | def load_subject_to_raw(self, subject_name, runs, preprocess=True): 223 | raws = [] 224 | for run in runs: 225 | raws.append(self.load_session_to_raw(subject_name, run, preprocess)) 226 | raw = concatenate_raws(raws) 227 | return raw 228 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Brainflow Notebooks 2 | 3 | ***NOTE :* This repository has been deprecated. Brainflow notebooks has been integrated into the original EEG notebooks where other developers and myself are consistently updating: ([Github Repo](https://github.com/neurotechx/eeg-notebooks)) ([Documentation](https://neurotechx.github.io/eeg-notebooks/))** 4 | 5 | This repository is a collection of EEG experiments which were originally developed by the [NeurotechX](https://neurotechx.com/) 6 | organization. The difference between this repository and the [original repository](https://github.com/neurotechx/eeg-notebooks) 7 | is that the notebooks have been edited to be compatible with the OpenBCI headset (specifically via the [brainflow API](https://brainflow.readthedocs.io/en/stable/#)). 8 | 9 | ## Getting Started 10 | 11 | ### Dependencies: 12 | * Numpy, Matplotlib, Pandas, Seaborn 13 | * Psychopy 14 | * MNE 15 | * Brainflow 16 | * PyRiemann 17 | 18 | #### Note for using Virtual Environments: 19 | If you are attempting to run these inside of a virtual environment, there can be some issues when attempting to install 20 | Psychopy. This is because PyQt5 takes some configuring to run inside of a venv. Instead of dealing with this headache, 21 | you can install PyQt5 on the system installation of Python3 then within in your virtual environment you can install 22 | PyQt5 via the "vext" package by running: `pip install vext.pyqt5`. Because of this, you also need to install PsychoPy 23 | and without dependencies and its other dependencies separately. In total you should run these three commands from within 24 | your virtual environment: 25 | ``` 26 | pip install vext.pyqt5 27 | 28 | pip install arabic_reshaper astunparse distro esprima freetype-py future gevent \ 29 | gitpython glfw imageio imageio-ffmpeg javascripthon json_tricks moviepy msgpack \ 30 | msgpack-numpy opencv-python openpyxl pillow psutil pyglet pyopengl pyosf pyparallel \ 31 | pyserial python-bidi python-gitlab pyyaml questplus requests[security] sounddevice \ 32 | soundfile tables xlrd 33 | 34 | pip install psychopy --no-deps 35 | ``` 36 | 37 | ## Using the Notebooks 38 | The notebooks rely on backend classes that are contained in the `experiments.py` and the `dataset.py` files. To describe 39 | how the API works, we will break the notebooks into two parts: data collection and data analysis. 40 | 41 | ### Data Collection 42 | Running the data collection has 3 steps: 43 | 1. Setting up the correct stimulus presentation for the desired paradigm. 44 | 2. Initialize the EEG device. 45 | 3. Run the trial(s). 46 | 47 | #### 1. Setting up the experiment 48 | The different types of experiments can all be imported in from the `experiments.py` file. At the moment there are only two paradigms 49 | available: ERPs and SSVEP. Different experiments can be loaded with the following commands: 50 | ```python 51 | from experiments import eventRelatedPotential, steadyStateEvokedPotentials 52 | 53 | # SSVEP experiment: 54 | ssvep_exp = steadyStateEvokedPotentials() 55 | 56 | # ERP, using the N170 stimuli: 57 | n170_exp = eventRelatedPotential(erp='n170') 58 | 59 | # ERP, using the P300 stimuli: 60 | p300_exp = eventRelatedPotential(erp='p300') 61 | ``` 62 | 63 | #### 2. Initialize the EEG device 64 | As of right now, brainflow supports both the OpenBCI and BrainBit headsets, and there is also a synthetic data source within 65 | the API itself. The notebooks at the moment only support the OpenBCI and synthetic headsets, but adding the additional setups as they 66 | come will be easy enough by adding a few lines of code. To initialize the devices: 67 | ```python 68 | # For the synthetic board 69 | exp.initialize_eeg(board_type='synthetic') 70 | 71 | # For the Ganglion board: 72 | exp.initialize_eeg(board_type='ganglion') # Using USB 73 | exp.initialize_eeg(board_type='ganglion_wifi') # Using Wifi 74 | 75 | # For using the 8-channel Cyton board 76 | exp.initialize_eeg(board_type='cyton') # Using USB 77 | exp.initialize_eeg(board_type='cyton_wifi') # Using Wifi 78 | 79 | # For using the 16-channel Cyton+Daisy combo 80 | exp.initialize_eeg(board_type='cyton_daisy') # Using USB 81 | exp.initialize_eeg(board_type='cyton_daisy_wifi') # Using Wifi 82 | 83 | # For using the BrainBit headband: 84 | exp.initialize_eeg(board_type='brainbit') 85 | 86 | # For using the Unicorn device 87 | exp.initialize_eeg(board_type='unicorn') 88 | ``` 89 | 90 | #### 3. Run data collection 91 | Now to run the experiment, you must define a subject name, trial duration, and trial number. The subject name and trial 92 | number will be used in the save file name for easy access later. **Note:** This portion of the code should always be run 93 | in a separate notebook cell. It is set up so that the cell can be repeated over and over again without needing to repeat 94 | the previous two steps. It is just recommended to increment the trial number with each pass, and change the subject name 95 | accordingly. 96 | ```python 97 | subject_name = 'test_subject' 98 | duration = 60 99 | trial_num = 3 100 | exp.run_trial(duration=duration, 101 | subject=subject_name, 102 | run=trial_num) 103 | ``` 104 | 105 | #### Full example 106 | Now putting it all together, if we wanted to run the N170 experiment for a 16-channel configuration, we would need in two 107 | separate notebook cells: 108 | ```python 109 | from experiments import eventRelatedPotential, steadyStateEvokedPotentials 110 | 111 | n170_exp = eventRelatedPotential(erp='n170') 112 | n170_exp.initialize_eeg(board_type='daisy') 113 | ``` 114 | In a separate cell: 115 | ```python 116 | subject_name = 'test_subject' 117 | duration = 60 118 | trial_num = 3 119 | n170_exp.run_trial(duration=duration, 120 | subject=subject_name, 121 | run=trial_num) 122 | ``` 123 | 124 | ### Data Analysis 125 | As EEG data analysis differs from paradigm to paradigm, this portion will really only cover the `dataset.py` module. This 126 | module loads the data and event files saved by the experiment and combines them into a single object. Brainflow offers some 127 | filtering and pre-processing functions which will be detailed/utilized in later notebooks, but right now the best practice is 128 | to use this module to output the unfiltered data as an MNE Raw object and perform filtering within MNE. To do this, you must 129 | define the subject and run numbers for which you want to load the data, the paradigm recorded, and the board type. There is an optional 130 | `layout` parameter which can be used for passing nonstandard arrangements of channel names for the OpenBCI headsets. After 131 | loading the dataset, you can convert it to a raw type, only selecting the runs you wish to keep. 132 | 133 | ```python 134 | subject_name = 'synthetic_test' 135 | runs = [0, 1, 2] 136 | dataset_n170 = branflowDatasety(paradigm='n170', 137 | subject=subject_name, 138 | board_type='synthetic') 139 | raw = dataset_n170.load_subject_to_raw(subject_name, runs) 140 | ``` 141 | 142 | 143 | ## Available Notebooks 144 | * **Free Record**: This notebook is to allow you to freely record your own data for any duration for any desired task 145 | not included in the notebooks. 146 | * **N170**: 147 | * **P300**: 148 | * **SSVEP**: 149 | 150 | ## Initializing the Boards 151 | Each board has optional parameters that can be passed to the `exp.initialize_eeg()` method. 152 | 153 | **OpenBCI:** 154 | For the OpenBCI boards, there is an option to pass the USB port needed for the dongle, but there is a default port for 155 | both Linux and Windows so it is optional on those two operating systems. The Ganglion however, also needs a layout of EEG 156 | electrode locations passed to it, as there is not a standardized 4-channel configuration. Additionally, if using the Wifi 157 | shield in *DIRECT* mode, the API uses a default IP address and finds an open port. If ot using in direct mode, you must pass 158 | the ip address of the board to the `ip_addr` parameter. 159 | 160 | **BrainBit and Unicorn:** BrainBit and Unicorn both have the option of passing their serial numbers to the `serial_num` 161 | parameter. This makes it possible to connect multiple headsets at the same time. 162 | 163 | 164 | 165 | # Repository Status 166 | The integration of the stimulus presentations with OpenBCI/Brainflow is work I have already completed and tested. This is 167 | just a porting and reformatting of that code to fit the NeurotechX EEG-Notebooks style. As such, I have yet to verify that 168 | the experiments run 100% smoothly within the notebooks. I will work on verifying that within the coming days and will update 169 | this section accordingly. 170 | 171 | ## Supported Board Status 172 | Here is a list of all of the boards brainFlow supports and their status of being integrated into the notebooks: 173 | 174 | **OpenBCI Ganglion:** 175 | - [X] Added 176 | - [ ] Connection tested 177 | - [ ] Recording tested 178 | - [ ] Data loading tested 179 | 180 | **OpenBCI Cyton:** 181 | - [X] Added 182 | - [X] Connection tested 183 | - [X] Recording tested 184 | - [X] Data loading tested 185 | 186 | **OpenBCI Cyton and Daisy:** 187 | - [X] Added 188 | - [X] Connection tested 189 | - [X] Recording tested 190 | - [X] Data loading tested 191 | 192 | **OpenBCI Wifi:** 193 | - [X] Added 194 | - [ ] Connection tested 195 | - [ ] Recording tested 196 | - [ ] Data loading tested 197 | 198 | **NeuroMD BrainBit:** 199 | - [X] Added 200 | - [ ] Connection tested 201 | - [ ] Recording tested 202 | - [ ] Data loading tested 203 | 204 | **G.TEC Unicorn:** 205 | - [X] Added 206 | - [ ] Connection tested 207 | - [ ] Recording tested 208 | - [ ] Data loading tested 209 | 210 | ## General TO-DO: 211 | 212 | - [ ] **Combine data and events during stream:** as of right now the data and events are saved in separate files during recording and then segmented and lined up 213 | when loading the entire dataset. This can not be done in the same way as for the Muse because LSL is not beting used here. 214 | - [X] **Add support for BrainBit:** Add the necessary lines to functions in both `experiments.py` and `dataset.py` to 215 | accommodate the BrainBit headset. 216 | 217 | ## Notebook Statuses 218 | * **N170**: 219 | - [X] *Stimulus Presentation*: **WORKING - 4/10/2020** 220 | - [X] *Data Recording*: **WORKING - 4/10/2020** 221 | - [ ] *Visualization*: 222 | - [X] *Classification Accuracy*: **WORKING - 4/10/2020** 223 | * **P300**: 224 | - [X] *Stimulus Presentation*: **WORKING - 4/10/2020** 225 | - [X] *Data Recording*: **WORKING - 4/10/2020** 226 | - [ ] *Visualization*: 227 | - [ ] *Classification Accuracy*: 228 | * **SSVEP**: 229 | - [X] *Stimulus Presentation*: **WORKING - 4/10/2020** 230 | - [X] *Data Recording*: **WORKING - 4/16/2020** 231 | - [X] *Visualization*: **WORKING - 4/24/2020** 232 | - [ ] *Classification Accuracy*: 233 | -------------------------------------------------------------------------------- /P300.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true, 8 | "pycharm": { 9 | "is_executing": false 10 | } 11 | }, 12 | "outputs": [], 13 | "source": [ 14 | "from collections import OrderedDict\n", 15 | "\n", 16 | "import numpy as np\n", 17 | "import pandas as pd\n", 18 | "import matplotlib.pyplot as plt\n", 19 | "import seaborn as sns\n", 20 | "\n", 21 | "from mne import Epochs, find_events\n", 22 | "from mne.decoding import Vectorizer\n", 23 | "\n", 24 | "from sklearn.pipeline import make_pipeline\n", 25 | "from sklearn.linear_model import LogisticRegression\n", 26 | "from sklearn.preprocessing import StandardScaler\n", 27 | "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA\n", 28 | "from sklearn.model_selection import cross_val_score, StratifiedShuffleSplit\n", 29 | "\n", 30 | "from pyriemann.estimation import ERPCovariances\n", 31 | "from pyriemann.tangentspace import TangentSpace\n", 32 | "from pyriemann.classification import MDM\n", 33 | "from pyriemann.spatialfilters import Xdawn\n", 34 | "\n", 35 | "from experiments import eventRelatedPotential\n", 36 | "from dataset import brainflowDataset\n", 37 | "from utils import plot_conditions" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "source": [ 43 | "# P300\n", 44 | "\n", 45 | "The P300 is a positive event-related potential (ERP) that occurs around 300ms after perceiving a novel or unexpected \n", 46 | "stimulus. It is most commonly elicited through 'oddball' experimental paradigms, where a certain subtype of stimulus is \n", 47 | "presented rarely amidst a background of another more common type of stimulus. Interestingly, the P300 is able to be \n", 48 | "elicited by multiple sensory modalities (e.g. visual, odditory, somatosensory). Thus, it is believed that the P300 may \n", 49 | "be a signature of higher level cognitive processing such as conscious attention." 50 | ], 51 | "metadata": { 52 | "collapsed": false 53 | } 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "source": [ 58 | "## Set up the experiment" 59 | ], 60 | "metadata": { 61 | "collapsed": false 62 | } 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 2, 67 | "outputs": [], 68 | "source": [ 69 | "p300_exp = eventRelatedPotential(erp='p300')" 70 | ], 71 | "metadata": { 72 | "collapsed": false, 73 | "pycharm": { 74 | "name": "#%%\n", 75 | "is_executing": false 76 | } 77 | } 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "source": [ 82 | "## Initialize the EEG signal" 83 | ], 84 | "metadata": { 85 | "collapsed": false 86 | } 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 3, 91 | "outputs": [], 92 | "source": [ 93 | "# For testing without connection\n", 94 | "#p300_exp.initialize_eeg(board_type='synthetic')\n", 95 | "\n", 96 | "# For using the 4-channel Ganglion board\n", 97 | "# Over USB:\n", 98 | "#p300_exp.initialize_eeg(board_type='ganglion')\n", 99 | "# Over Wifi:\n", 100 | "#p300_exp.initialize_eeg(board_type='ganglion_wifi)\n", 101 | "\n", 102 | "\n", 103 | "# For using the 8-channel Cyton board\n", 104 | "# Over USB:\n", 105 | "#p300_exp.initialize_eeg(board_type='cyton')\n", 106 | "# Over Wifi:\n", 107 | "#p300_exp.initialize_eeg(board_type='cyton_wifi')\n", 108 | "\n", 109 | "\n", 110 | "# For using the 16-channel Cyton+Daisy combo\n", 111 | "# Over USB:\n", 112 | "p300_exp.initialize_eeg(board_type='cyton_daisy')\n", 113 | "# Over Wifi:\n", 114 | "#p300_exp.initialize_eeg(board_type='cyton_daisy_wifi')\n", 115 | "\n", 116 | "# For using the BrainBit headband:\n", 117 | "#p300_exp.initialize_eeg(board_type='brainbit')\n", 118 | "\n", 119 | "# For using the Unicorn device\n", 120 | "#p300_exp.initialize_eeg(board_type='unicorn')" 121 | ], 122 | "metadata": { 123 | "collapsed": false, 124 | "pycharm": { 125 | "name": "#%%\n", 126 | "is_executing": false 127 | } 128 | } 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "source": [ 133 | "## Run Experiment" 134 | ], 135 | "metadata": { 136 | "collapsed": false 137 | } 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 5, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "text": [ 146 | "Beginning EEG Stream; Wait 5 seconds for signal to settle... \n", 147 | "\n" 148 | ], 149 | "output_type": "stream" 150 | } 151 | ], 152 | "source": [ 153 | "subject_name = 'test_subject'\n", 154 | "duration = 10\n", 155 | "trial_num = 0\n", 156 | "p300_exp.run_trial(duration=duration,\n", 157 | " subject=subject_name,\n", 158 | " run=trial_num)" 159 | ], 160 | "metadata": { 161 | "collapsed": false, 162 | "pycharm": { 163 | "name": "#%%\n", 164 | "is_executing": false 165 | } 166 | } 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "source": [ 171 | "## Load the Dataset" 172 | ], 173 | "metadata": { 174 | "collapsed": false 175 | } 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "outputs": [], 181 | "source": [ 182 | "runs = [0, 1, 2]\n", 183 | "dataset_p300 = brainflowDataset(paradigm='p300',\n", 184 | " subject=subject_name,\n", 185 | " board_type='cyton_daisy')\n", 186 | "raw = dataset_p300.load_subject_to_raw(subject_name, runs, preprocess=False)" 187 | ], 188 | "metadata": { 189 | "collapsed": false, 190 | "pycharm": { 191 | "name": "#%%\n" 192 | } 193 | } 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "source": [ 198 | "## Filter the data\n", 199 | "The justification for filtering 1-16 Hz is taken from... [**Find reference from Riemannian Geometric Classifier paper**]" 200 | ], 201 | "metadata": { 202 | "collapsed": false 203 | } 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "outputs": [], 209 | "source": [ 210 | "raw.filter(1, 16, method='iir')" 211 | ], 212 | "metadata": { 213 | "collapsed": false, 214 | "pycharm": { 215 | "name": "#%%\n" 216 | } 217 | } 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "source": [ 222 | "## Epoch the data" 223 | ], 224 | "metadata": { 225 | "collapsed": false 226 | } 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "outputs": [], 232 | "source": [ 233 | "events = find_events(raw)\n", 234 | "event_id = {'Non-Target': 1, 'Target': 2}\n", 235 | "epochs = Epochs(raw, events=events, event_id=event_id, \n", 236 | " tmin=-0.1, tmax=0.8, baseline=None,\n", 237 | " reject={'eeg': 100e-6}, preload=True, \n", 238 | " verbose=False)\n", 239 | "print('sample drop %: ', (1 - len(epochs.events)/len(events)) * 100)" 240 | ], 241 | "metadata": { 242 | "collapsed": false, 243 | "pycharm": { 244 | "name": "#%%\n" 245 | } 246 | } 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "source": [ 251 | "## Analyze data\n", 252 | "\n", 253 | "#### Epoch Averages" 254 | ], 255 | "metadata": { 256 | "collapsed": false 257 | } 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "outputs": [], 263 | "source": [ 264 | "%matplotlib inline\n", 265 | "conditions = OrderedDict()\n", 266 | "conditions['Non-target'] = [1]\n", 267 | "conditions['Target'] = [2]\n", 268 | "\n", 269 | "fig, ax = plot_conditions(epochs, conditions=conditions, \n", 270 | " ci=97.5, n_boot=1000, title='',\n", 271 | " diff_waveform=(1, 2))" 272 | ], 273 | "metadata": { 274 | "collapsed": false, 275 | "pycharm": { 276 | "name": "#%%\n" 277 | } 278 | } 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "source": [ 283 | "### Classify" 284 | ], 285 | "metadata": { 286 | "collapsed": false 287 | } 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "outputs": [], 293 | "source": [ 294 | "clfs = OrderedDict()\n", 295 | "\n", 296 | "clfs['Vect + LR'] = make_pipeline(Vectorizer(), StandardScaler(), LogisticRegression())\n", 297 | "clfs['Vect + RegLDA'] = make_pipeline(Vectorizer(), LDA(shrinkage='auto', solver='eigen'))\n", 298 | "clfs['Xdawn + RegLDA'] = make_pipeline(Xdawn(2, classes=[1]), Vectorizer(), LDA(shrinkage='auto', solver='eigen'))\n", 299 | "clfs['ERPCov + TS'] = make_pipeline(ERPCovariances(), TangentSpace(), LogisticRegression())\n", 300 | "clfs['ERPCov + MDM'] = make_pipeline(ERPCovariances(), MDM())\n", 301 | "\n", 302 | "# format data\n", 303 | "epochs.pick_types(eeg=True)\n", 304 | "X = epochs.get_data() * 1e6\n", 305 | "times = epochs.times\n", 306 | "y = epochs.events[:, -1]\n", 307 | "\n", 308 | "# define cross validation \n", 309 | "cv = StratifiedShuffleSplit(n_splits=10, test_size=0.25, random_state=42)\n", 310 | "\n", 311 | "# run cross validation for each pipeline\n", 312 | "auc = []\n", 313 | "methods = []\n", 314 | "for m in clfs:\n", 315 | " res = cross_val_score(clfs[m], X, y==2, scoring='roc_auc', cv=cv, n_jobs=-1)\n", 316 | " auc.extend(res)\n", 317 | " methods.extend([m]*len(res))\n", 318 | " \n", 319 | "results = pd.DataFrame(data=auc, columns=['AUC'])\n", 320 | "results['Method'] = methods\n", 321 | "\n", 322 | "plt.figure(figsize=[8,4])\n", 323 | "sns.barplot(data=results, x='AUC', y='Method')\n", 324 | "plt.xlim(0.2, 0.85)\n", 325 | "sns.despine()" 326 | ], 327 | "metadata": { 328 | "collapsed": false, 329 | "pycharm": { 330 | "name": "#%%\n" 331 | } 332 | } 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": null, 337 | "outputs": [], 338 | "source": [], 339 | "metadata": { 340 | "collapsed": false, 341 | "pycharm": { 342 | "name": "#%%\n" 343 | } 344 | } 345 | } 346 | ], 347 | "metadata": { 348 | "kernelspec": { 349 | "display_name": "Python 3", 350 | "language": "python", 351 | "name": "python3" 352 | }, 353 | "language_info": { 354 | "codemirror_mode": { 355 | "name": "ipython", 356 | "version": 2 357 | }, 358 | "file_extension": ".py", 359 | "mimetype": "text/x-python", 360 | "name": "python", 361 | "nbconvert_exporter": "python", 362 | "pygments_lexer": "ipython2", 363 | "version": "2.7.6" 364 | } 365 | }, 366 | "nbformat": 4, 367 | "nbformat_minor": 0 368 | } -------------------------------------------------------------------------------- /experiments.py: -------------------------------------------------------------------------------- 1 | import os 2 | import platform 3 | from glob import glob 4 | from time import time, sleep 5 | from random import choice 6 | 7 | import numpy as np 8 | from pandas import DataFrame 9 | from psychopy import visual, core, event 10 | 11 | from brainflow import DataFilter, BoardShim, BoardIds, BrainFlowInputParams 12 | 13 | from utils import get_fns, get_openbci_usb, get_openbci_ip 14 | 15 | 16 | def get_board_info(board_type, usb_port=None, ip_addr=None, ip_port=None, serial_num=None): 17 | 18 | params = BrainFlowInputParams() 19 | 20 | if board_type == 'synthetic': 21 | board_id = BoardIds.SYNTHETIC_BOARD.value 22 | 23 | elif board_type == 'ganglion': 24 | board_id = BoardIds.GANGLION_BOARD.value 25 | params.serial_port = get_openbci_usb(usb_port) 26 | 27 | elif board_type == 'cyton': 28 | board_id = BoardIds.CYTON_BOARD.value 29 | params.serial_port = get_openbci_usb(usb_port) 30 | 31 | elif board_type == 'cyton_daisy': 32 | board_id = BoardIds.CYTON_DAISY_BOARD.value 33 | params.serial_port = get_openbci_usb(usb_port) 34 | 35 | elif board_type == 'ganglion_wifi': 36 | board_id = BoardIds.GANGLION_WIFI_BOARD.value 37 | params.ip_address, params.ip_port = get_openbci_ip(ip_addr, ip_port) 38 | 39 | elif board_type == 'cyton_wifi': 40 | board_id = BoardIds.CYTON_WIFI_BOARD.value 41 | params.ip_address, params.ip_port = get_openbci_ip(ip_addr, ip_port) 42 | 43 | elif board_type == 'cyton_daisy_wifi': 44 | board_id = BoardIds.CYTON_DAISY_WIFI_BOARD.value 45 | params.ip_address, params.ip_port = get_openbci_ip(ip_addr, ip_port) 46 | 47 | elif board_type == 'brainbit': 48 | board_id = BoardIds.BRAINBIT_BOARD.value 49 | if serial_num: 50 | params.other_info = serial_num 51 | 52 | elif board_type == 'unicorn': 53 | board_id = BoardIds.UNICORN_BOARD.value 54 | if serial_num: 55 | params.other_info = serial_num 56 | 57 | return board_id, params 58 | 59 | 60 | def get_possible_ssvep_freqs(frame_rate, stim_type='single'): 61 | """ This function takes the frame rate of the monitor in use and returns the possible SSVEP 62 | stimulus frequencies based on the desired stimulus type. 63 | Credit: NeurotechX 64 | 65 | Parameters: 66 | frame_rate (int): 67 | stim_type (str): 68 | 69 | Returns: 70 | freqs 71 | """ 72 | max_period_nb = int(frame_rate / 6) 73 | periods = np.arange(max_period_nb) + 1 74 | 75 | if stim_type == 'single': 76 | freqs = dict() 77 | for p1 in periods: 78 | for p2 in periods: 79 | f = frame_rate / (p1 + p2) 80 | try: 81 | freqs[f].append((p1, p2)) 82 | except: 83 | freqs[f] = [(p1, p2)] 84 | elif stim_type == 'reversal': 85 | freqs = {frame_rate / p: [(p, p)] for p in periods[::-1]} 86 | 87 | return freqs 88 | 89 | def init_flicker_stim(frame_rate, cycle, soa): 90 | """ 91 | From NeurotechX EEG-Notebooks 92 | """ 93 | if isinstance(cycle, tuple): 94 | stim_freq = frame_rate / sum(cycle) 95 | n_cycles = int(soa * stim_freq) 96 | else: 97 | stim_freq = frame_rate / cycle 98 | cycle = (cycle, cycle) 99 | n_cycles = int(soa * stim_freq) / 2 100 | 101 | return {'cycle': cycle, 102 | 'freq' : stim_freq, 103 | 'n_cycles' : n_cycles} 104 | 105 | 106 | class freeRecording: 107 | 108 | def __init__(self, activity=None): 109 | self.board_prepared = False 110 | self.board_id = None 111 | self.params = None 112 | self.board = None 113 | self._setup_session(activity) 114 | 115 | def initialize_eeg(self, board_type='synthetic', usb_port=None, ip_addr=None, ip_port=None, serial_num=None): 116 | self.board_id, self.params = get_board_info(board_type, usb_port, ip_addr, ip_port, serial_num) 117 | self.board = BoardShim(self.board_id, self.params) 118 | self.board.prepare_session() 119 | self.board_prepared = True 120 | 121 | def _setup_session(self, activity): 122 | if activity == None: 123 | activity = 'UNLABELLED' 124 | 125 | self.session_name = activity 126 | 127 | def record(self, duration, subject, run): 128 | if self.board_prepared == False: 129 | self.board.prepare_session() 130 | self.board_prepared = True 131 | 132 | print("Beginning EEG Stream; Wait 5 seconds for signal to settle... \n") 133 | self.board.start_stream() 134 | sleep(5) 135 | 136 | print(f"Starting recording for {duration} seconds... \n") 137 | sleep(duration) 138 | 139 | # cleanup the session 140 | self.board.stop_stream() 141 | # self.board_prepared = False 142 | data = self.board.get_board_data() 143 | data_fn, event_fn = get_fns(subject, run, self.session_name) 144 | DataFilter.write_file(data, data_fn, 'w') 145 | 146 | 147 | class eventRelatedPotential: 148 | 149 | def __init__(self, erp='n170'): 150 | self.erp = erp 151 | self.board_prepared = False 152 | self.board_id = None 153 | self.params = None 154 | self.board = None 155 | self.max_trials = 500 156 | self._setup_trial() 157 | 158 | def initialize_eeg(self, board_type='synthetic', usb_port=None, ip_addr=None, ip_port=None, serial_num=None): 159 | self.board_id, self.params = get_board_info(board_type, usb_port, ip_addr, ip_port, serial_num) 160 | self.board = BoardShim(self.board_id, self.params) 161 | self.board.prepare_session() 162 | self.board_prepared = True 163 | 164 | def _setup_trial(self): 165 | if self.erp == 'n170': 166 | self.image_type = np.random.binomial(1, 0.5, self.max_trials) 167 | if self.erp == 'p300': 168 | self.image_type = np.random.binomial(1, 0.5, self.max_trials) 169 | 170 | self.trials = DataFrame(dict(image_type=self.image_type, 171 | timestamp=np.zeros(self.max_trials))) 172 | 173 | def _setup_task(self): 174 | if self.erp == 'n170': 175 | self.markernames = ['houses', 'faces'] 176 | self.markers = [1, 2] 177 | if self.erp == 'p300': 178 | self.markernames = ['nontargets', 'targets'] 179 | self.markers = [1, 2] 180 | 181 | def _setup_graphics(self): 182 | self.mywin = visual.Window([3440, 1440], monitor='testMonitor', units="deg") 183 | if self.erp == 'n170': 184 | faces = list(map(self._load_image, glob('stim/face_house/faces/*_3.jpg'))) 185 | houses = list(map(self._load_image, glob('stim/face_house/houses/*.3.jpg'))) 186 | self.stim = [houses, faces] 187 | if self.erp == 'p300': 188 | targets = list(map(self._load_image, glob('stim/cats_dogs/target-*.jpg'))) 189 | nontargets = list(map(self._load_image, glob('stim/cats_dogs/nontarget-*.jpg'))) 190 | self.stim = [nontargets, targets] 191 | 192 | def _load_image(self, fn): 193 | return visual.ImageStim(win=self.mywin, image=fn) 194 | 195 | def run_trial(self, duration, subject, run): 196 | if self.board_prepared == False: 197 | self.board.prepare_session() 198 | self.board_prepared = True 199 | # session information 200 | iti = 0.4 201 | soa = 0.3 202 | jitter = 0.2 203 | record_duration = np.float32(duration) 204 | print("Beginning EEG Stream; Wait 5 seconds for signal to settle... \n") 205 | self.board.start_stream() 206 | sleep(5) 207 | 208 | # Get starting time-stamp by pulling the last sample from the board and using its time stamp 209 | last_sample = self.board.get_current_board_data(1) 210 | start = last_sample[-1][0] 211 | 212 | # setup graphics 213 | self._setup_graphics() 214 | 215 | # iterate through events 216 | for ii, trial in self.trials.iterrows(): 217 | # inter trial interval 218 | core.wait(iti + np.random.rand() * jitter) 219 | label = self.trials['image_type'].iloc[ii] 220 | image = choice(self.stim[label]) 221 | image.draw() 222 | 223 | last_sample = self.board.get_current_board_data(1) 224 | timestamp = last_sample[-1][0] 225 | self.trials.loc[ii, 'timestamp'] = timestamp 226 | self.mywin.flip() 227 | 228 | # offset (Off-SET!) 229 | core.wait(soa) 230 | self.mywin.flip() 231 | if len(event.getKeys()) > 0 or (time() - start) > record_duration: 232 | break 233 | 234 | event.clearEvents() 235 | 236 | # cleanup the session 237 | self.board.stop_stream() 238 | #self.board_prepared = False 239 | data = self.board.get_board_data() 240 | data_fn, event_fn = get_fns(subject, run, self.erp) 241 | DataFilter.write_file(data, data_fn, 'w') 242 | self.mywin.close() 243 | self.trials.to_csv(event_fn) 244 | 245 | 246 | class steadyStateEvokedPotentials: 247 | 248 | def __init__(self, paradigm='ssvep'): 249 | self.paradigm = paradigm 250 | self.board_id = None 251 | self.params = None 252 | self.board = None 253 | self.max_trials = 500 254 | self._setup_trials() 255 | 256 | def initialize_eeg(self, board_type='synthetic', usb_port=None, ip_addr=None, ip_port=None, serial_num=None): 257 | BoardShim.enable_dev_board_logger() 258 | self.board_id, self.params = get_board_info(board_type, usb_port, ip_addr, ip_port, serial_num) 259 | self.board = BoardShim(self.board_id, self.params) 260 | self.board.prepare_session() 261 | 262 | def _setup_trials(self): 263 | self.stim_freq = np.random.binomial(1, 0.5, self.max_trials) 264 | self.trials = DataFrame(dict(stim_freq=self.stim_freq, 265 | timestamp=np.zeros(self.max_trials))) 266 | 267 | def _setup_graphics(self): 268 | soa = 3.0 269 | self.mywin = visual.Window([3440, 1440], monitor='testMonitor', units="deg", wintype='pygame') 270 | if self.paradigm == 'ssvep': 271 | grating = visual.GratingStim(win=self.mywin, mask='circle', size=80, sf=0.2) 272 | grating_neg = visual.GratingStim(win=self.mywin, mask='circle', size=80, sf=0.2, phase=0.5) 273 | frame_rate = np.round(self.mywin.getActualFrameRate()) 274 | stim_patterns = [init_flicker_stim(frame_rate, 2, soa), 275 | init_flicker_stim(frame_rate, 3, soa)] 276 | print(stim_patterns) 277 | 278 | return grating, grating_neg, stim_patterns 279 | 280 | def _load_image(self, fn): 281 | return visual.ImageStim(win=self.mywin, image=fn) 282 | 283 | def run_trial(self, duration, subject, run): 284 | # session information 285 | iti = 0.5 286 | soa = 3.0 287 | jitter = 0.2 288 | record_duration = np.float32(duration) 289 | print("Beginning EEG Stream; Wait 5 seconds for signal to settle... \n") 290 | self.board.start_stream() 291 | sleep(5) 292 | 293 | # Get starting time-stamp by pulling the last sample from the board and using its time stamp 294 | last_sample = self.board.get_current_board_data(1) 295 | start = last_sample[-1][0] 296 | 297 | # setup graphics 298 | grating, grating_neg, stim_patterns = self._setup_graphics() 299 | 300 | # iterate through events 301 | for ii, trial in self.trials.iterrows(): 302 | # inter trial interval 303 | core.wait(iti + np.random.rand() * jitter) 304 | label = self.trials['stim_freq'].iloc[ii] 305 | last_sample = self.board.get_current_board_data(1) 306 | timestamp = last_sample[-1][0] 307 | self.trials.loc[ii, 'timestamp'] = timestamp 308 | 309 | for _ in range(int(stim_patterns[label]['n_cycles'])): 310 | grating.setAutoDraw(True) 311 | for _ in range(int(stim_patterns[label]['cycle'][0])): 312 | self.mywin.flip() 313 | grating.setAutoDraw(False) 314 | grating_neg.setAutoDraw(True) 315 | for _ in range(stim_patterns[label]['cycle'][1]): 316 | self.mywin.flip() 317 | grating_neg.setAutoDraw(False) 318 | 319 | # Offset 320 | self.mywin.flip() 321 | if len(event.getKeys()) > 0 or (time() - start) > record_duration: 322 | break 323 | 324 | event.clearEvents() 325 | 326 | # cleanup the session 327 | self.board.stop_stream() 328 | data = self.board.get_board_data() 329 | data_fn, event_fn = get_fns(subject, run, self.paradigm) 330 | print(event_fn) 331 | DataFilter.write_file(data, data_fn, 'w') 332 | self.mywin.close() 333 | self.trials.to_csv(event_fn) 334 | -------------------------------------------------------------------------------- /N170.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [ 10 | { 11 | "name": "stdout", 12 | "output_type": "stream", 13 | "text": [ 14 | "pygame 1.9.6\n", 15 | "Hello from the pygame community. https://www.pygame.org/contribute.html\n" 16 | ] 17 | } 18 | ], 19 | "source": [ 20 | "from collections import OrderedDict\n", 21 | "\n", 22 | "import numpy as np\n", 23 | "import pandas as pd\n", 24 | "import matplotlib.pyplot as plt\n", 25 | "import seaborn as sns\n", 26 | "\n", 27 | "from mne import Epochs, find_events\n", 28 | "from mne.decoding import Vectorizer\n", 29 | "\n", 30 | "from sklearn.pipeline import make_pipeline\n", 31 | "from sklearn.linear_model import LogisticRegression\n", 32 | "from sklearn.preprocessing import StandardScaler\n", 33 | "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA\n", 34 | "from sklearn.model_selection import cross_val_score, StratifiedShuffleSplit\n", 35 | "\n", 36 | "from pyriemann.estimation import ERPCovariances\n", 37 | "from pyriemann.tangentspace import TangentSpace\n", 38 | "from pyriemann.classification import MDM\n", 39 | "from pyriemann.spatialfilters import Xdawn\n", 40 | "\n", 41 | "from experiments import eventRelatedPotential\n", 42 | "from dataset import brainflowDataset\n", 43 | "from utils import plot_conditions" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "source": [ 49 | "# N170\n", 50 | "\n", 51 | "\n", 52 | "\n", 53 | "The N170 is a large negative event-related potential (ERP) component that occurs after the detection of faces, but not \n", 54 | "objects, scrambled faces, or other body parts such as hands. The N170 occurs around 170ms after face perception and is \n", 55 | "most easily detected at lateral posterior electrodes such as T5 and T6 [1](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.601.6917&rep=rep1&type=pdf). \n", 56 | "Frontal or profile views of human (and animal [2](https://www.ncbi.nlm.nih.gov/pubmed/14995895)) faces elicit the strongest \n", 57 | "N170 and the strength of the N170 does not seem to be influenced by how familiar a face is. Thus, although there is no \n", 58 | "consensus on the specific source of the N170, researchers believe it is related to activity in the fusiform face area, \n", 59 | "an area of the brain that shows a similar response pattern and is involved in encoding the holistic representation of a face \n", 60 | "(i.e eyes, nose mouth all arranged in the appropriate way).\n", 61 | "\n", 62 | "In this notebook, we will attempt to detect the N170 with the OpenBCI Headset using faces and houses as our stimuli. \n", 63 | "The OpenBCI's temporal electrodes are well positioned to detect the N170 and we expect we'll be able to \n", 64 | "see an N170 emerge from just a few dozen trials. We will then run several different classification algorithms on our \n", 65 | "data in order to evaluate the performance of a potential brain-computer interface using the N170." 66 | ], 67 | "metadata": { 68 | "collapsed": false 69 | } 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "source": [ 74 | "## Set up the experiment" 75 | ], 76 | "metadata": { 77 | "collapsed": false 78 | } 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 2, 83 | "outputs": [], 84 | "source": [ 85 | "n170_exp = eventRelatedPotential(erp='n170')" 86 | ], 87 | "metadata": { 88 | "collapsed": false, 89 | "pycharm": { 90 | "name": "#%%\n" 91 | } 92 | } 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "source": [ 97 | "## Initialize the EEG signal" 98 | ], 99 | "metadata": { 100 | "collapsed": false, 101 | "pycharm": { 102 | "name": "#%% md\n" 103 | } 104 | } 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 3, 109 | "outputs": [ 110 | { 111 | "name": "stdout", 112 | "output_type": "stream", 113 | "text": [ 114 | "cyton_daisy\n", 115 | "/dev/ttyUSB0\n" 116 | ] 117 | } 118 | ], 119 | "source": [ 120 | "# For testing without connection\n", 121 | "#n170_exp.initialize_eeg(board_type='synthetic')\n", 122 | "\n", 123 | "# For using the 4-channel Ganglion board\n", 124 | "# Over USB:\n", 125 | "#n170_exp.initialize_eeg(board_type='ganglion')\n", 126 | "# Over Wifi:\n", 127 | "#n170_exp.initialize_eeg(board_type='ganglion_wifi)\n", 128 | "\n", 129 | "\n", 130 | "# For using the 8-channel Cyton board\n", 131 | "# Over USB:\n", 132 | "#n170_exp.initialize_eeg(board_type='cyton')\n", 133 | "# Over Wifi:\n", 134 | "#n170_exp.initialize_eeg(board_type='cyton_wifi')\n", 135 | "\n", 136 | "\n", 137 | "# For using the 16-channel Cyton+Daisy combo\n", 138 | "# Over USB:\n", 139 | "n170_exp.initialize_eeg(board_type='cyton_daisy')\n", 140 | "# Over Wifi:\n", 141 | "#n170_exp.initialize_eeg(board_type='cyton_daisy_wifi')\n", 142 | "\n", 143 | "# For using the BrainBit headband:\n", 144 | "#n170_exp.initialize_eeg(board_type='brainbit')\n", 145 | "\n", 146 | "# For using the Unicorn device\n", 147 | "#n170_exp.initialize_eeg(board_type='unicorn')" 148 | ], 149 | "metadata": { 150 | "collapsed": false, 151 | "pycharm": { 152 | "name": "#%%\n" 153 | } 154 | } 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "source": [ 159 | "## Run Experiment" 160 | ], 161 | "metadata": { 162 | "collapsed": false, 163 | "pycharm": { 164 | "name": "#%% md\n" 165 | } 166 | } 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 4, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "Beginning EEG Stream; Wait 5 seconds for signal to settle... \n", 177 | "\n" 178 | ] 179 | } 180 | ], 181 | "source": [ 182 | "subject_name = 'jadin_test'\n", 183 | "duration = 10\n", 184 | "trial_num = 3\n", 185 | "n170_exp.run_trial(duration=duration,\n", 186 | " subject=subject_name,\n", 187 | " run=trial_num)" 188 | ], 189 | "metadata": { 190 | "collapsed": false, 191 | "pycharm": { 192 | "name": "#%%\n" 193 | } 194 | } 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "source": [ 199 | "## Load the Dataset" 200 | ], 201 | "metadata": { 202 | "collapsed": false, 203 | "pycharm": { 204 | "name": "#%% md\n" 205 | } 206 | } 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 2, 211 | "outputs": [ 212 | { 213 | "name": "stdout", 214 | "output_type": "stream", 215 | "text": [ 216 | "data/jadin_test_n170_3.csv\n", 217 | "Notch filter\n", 218 | "Bandpass filter\n", 219 | "Denoise\n", 220 | "Creating RawArray with float64 data, n_channels=16, n_times=504\n", 221 | " Range : 0 ... 503 = 0.000 ... 4.024 secs\n", 222 | "Ready.\n", 223 | "Creating RawArray with float64 data, n_channels=1, n_times=504\n", 224 | " Range : 0 ... 503 = 0.000 ... 4.024 secs\n", 225 | "Ready.\n" 226 | ] 227 | } 228 | ], 229 | "source": [ 230 | "subject_name = 'jadin_test'\n", 231 | "runs = [3]\n", 232 | "dataset_n170 = brainflowDataset(paradigm='n170', \n", 233 | " subject=subject_name,\n", 234 | " board_type='cyton_daisy')\n", 235 | "raw = dataset_n170.load_subject_to_raw(subject_name, runs)" 236 | ], 237 | "metadata": { 238 | "collapsed": false, 239 | "pycharm": { 240 | "name": "#%%\n" 241 | } 242 | } 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "source": [ 247 | "## Filter the data\n", 248 | "The justification for filtering 1-16 Hz is taken from... [**Find reference from Riemannian Geometric Classifier paper**]" 249 | ], 250 | "metadata": { 251 | "collapsed": false, 252 | "pycharm": { 253 | "name": "#%% md\n" 254 | } 255 | } 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": 7, 260 | "outputs": [ 261 | { 262 | "name": "stdout", 263 | "output_type": "stream", 264 | "text": [ 265 | "Filtering raw data in 6 contiguous segments\n", 266 | "Setting up band-pass filter from 1 - 16 Hz\n", 267 | "\n", 268 | "IIR filter parameters\n", 269 | "---------------------\n", 270 | "Butterworth bandpass zero-phase (two-pass forward and reverse) non-causal filter:\n", 271 | "- Filter order 16 (effective, after forward-backward)\n", 272 | "- Cutoffs at 1.00, 16.00 Hz: -6.02, -6.02 dB\n", 273 | "\n" 274 | ] 275 | }, 276 | { 277 | "data": { 278 | "text/plain": "" 279 | }, 280 | "execution_count": 7, 281 | "metadata": {}, 282 | "output_type": "execute_result" 283 | } 284 | ], 285 | "source": [ 286 | "raw.filter(1, 16, method='iir')" 287 | ], 288 | "metadata": { 289 | "collapsed": false, 290 | "pycharm": { 291 | "name": "#%%\n" 292 | } 293 | } 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "source": [ 298 | "## Epoch the data" 299 | ], 300 | "metadata": { 301 | "collapsed": false 302 | } 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 8, 307 | "outputs": [ 308 | { 309 | "name": "stdout", 310 | "output_type": "stream", 311 | "text": [ 312 | "360 events found\n", 313 | "Event IDs: [1 2]\n", 314 | "sample drop %: 6.944444444444442\n" 315 | ] 316 | } 317 | ], 318 | "source": [ 319 | "events = find_events(raw)\n", 320 | "event_id = {'Non-Target': 1, 'Target': 2}\n", 321 | "epochs = Epochs(raw, events=events, event_id=event_id, \n", 322 | " tmin=-0.1, tmax=0.8, baseline=None,\n", 323 | " reject={'eeg': 100e-6}, preload=True, \n", 324 | " verbose=False)\n", 325 | "print('sample drop %: ', (1 - len(epochs.events)/len(events)) * 100)" 326 | ], 327 | "metadata": { 328 | "collapsed": false, 329 | "pycharm": { 330 | "name": "#%%\n" 331 | } 332 | } 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "source": [ 337 | "## Analyze data\n", 338 | "\n", 339 | "#### Epoch Averages" 340 | ], 341 | "metadata": { 342 | "collapsed": false 343 | } 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 9, 348 | "outputs": [ 349 | { 350 | "ename": "AttributeError", 351 | "evalue": "module 'seaborn' has no attribute 'tsplot'", 352 | "output_type": "error", 353 | "traceback": [ 354 | "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", 355 | "\u001B[0;31mAttributeError\u001B[0m Traceback (most recent call last)", 356 | "\u001B[0;32m\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 6\u001B[0m fig, ax = plot_conditions(epochs, conditions=conditions, \n\u001B[1;32m 7\u001B[0m \u001B[0mci\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;36m97.5\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mn_boot\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;36m1000\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mtitle\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m''\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m----> 8\u001B[0;31m diff_waveform=(1, 2))\n\u001B[0m\u001B[1;32m 9\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", 357 | "\u001B[0;32m~/Documents/Programming/brainflow-notebooks/utils.py\u001B[0m in \u001B[0;36mplot_conditions\u001B[0;34m(epochs, conditions, ci, n_boot, title, palette, ylim, diff_waveform)\u001B[0m\n\u001B[1;32m 57\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mch\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mrange\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;36m4\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 58\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mcond\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcolor\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mzip\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mconditions\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mvalues\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mpalette\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 59\u001B[0;31m sns.tsplot(X[y.isin(cond), ch], time=times, color=color,\n\u001B[0m\u001B[1;32m 60\u001B[0m n_boot=n_boot, ci=ci, ax=axes[ch])\n\u001B[1;32m 61\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", 358 | "\u001B[0;31mAttributeError\u001B[0m: module 'seaborn' has no attribute 'tsplot'" 359 | ] 360 | }, 361 | { 362 | "data": { 363 | "text/plain": "
", 364 | "image/png": "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\n" 365 | }, 366 | "metadata": { 367 | "needs_background": "light" 368 | }, 369 | "output_type": "display_data" 370 | } 371 | ], 372 | "source": [ 373 | "%matplotlib inline\n", 374 | "conditions = OrderedDict()\n", 375 | "conditions['Non-target'] = [1]\n", 376 | "conditions['Target'] = [2]\n", 377 | "\n", 378 | "fig, ax = plot_conditions(epochs, conditions=conditions, \n", 379 | " ci=97.5, n_boot=1000, title='',\n", 380 | " diff_waveform=(1, 2))" 381 | ], 382 | "metadata": { 383 | "collapsed": false, 384 | "pycharm": { 385 | "name": "#%%\n" 386 | } 387 | } 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "source": [ 392 | "### Classify" 393 | ], 394 | "metadata": { 395 | "collapsed": false 396 | } 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 10, 401 | "outputs": [ 402 | { 403 | "data": { 404 | "text/plain": "
", 405 | "image/png": "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\n" 406 | }, 407 | "metadata": { 408 | "needs_background": "light" 409 | }, 410 | "output_type": "display_data" 411 | } 412 | ], 413 | "source": [ 414 | "clfs = OrderedDict()\n", 415 | "\n", 416 | "clfs['Vect + LR'] = make_pipeline(Vectorizer(), StandardScaler(), LogisticRegression())\n", 417 | "clfs['Vect + RegLDA'] = make_pipeline(Vectorizer(), LDA(shrinkage='auto', solver='eigen'))\n", 418 | "clfs['Xdawn + RegLDA'] = make_pipeline(Xdawn(2, classes=[1]), Vectorizer(), LDA(shrinkage='auto', solver='eigen'))\n", 419 | "clfs['ERPCov + TS'] = make_pipeline(ERPCovariances(), TangentSpace(), LogisticRegression())\n", 420 | "clfs['ERPCov + MDM'] = make_pipeline(ERPCovariances(), MDM())\n", 421 | "\n", 422 | "# format data\n", 423 | "epochs.pick_types(eeg=True)\n", 424 | "X = epochs.get_data() * 1e6\n", 425 | "times = epochs.times\n", 426 | "y = epochs.events[:, -1]\n", 427 | "\n", 428 | "# define cross validation \n", 429 | "cv = StratifiedShuffleSplit(n_splits=10, test_size=0.25, random_state=42)\n", 430 | "\n", 431 | "# run cross validation for each pipeline\n", 432 | "auc = []\n", 433 | "methods = []\n", 434 | "for m in clfs:\n", 435 | " res = cross_val_score(clfs[m], X, y==2, scoring='roc_auc', cv=cv, n_jobs=-1)\n", 436 | " auc.extend(res)\n", 437 | " methods.extend([m]*len(res))\n", 438 | " \n", 439 | "results = pd.DataFrame(data=auc, columns=['AUC'])\n", 440 | "results['Method'] = methods\n", 441 | "\n", 442 | "plt.figure(figsize=[8,4])\n", 443 | "sns.barplot(data=results, x='AUC', y='Method')\n", 444 | "plt.xlim(0.2, 0.85)\n", 445 | "sns.despine()" 446 | ], 447 | "metadata": { 448 | "collapsed": false, 449 | "pycharm": { 450 | "name": "#%%\n" 451 | } 452 | } 453 | }, 454 | { 455 | "cell_type": "code", 456 | "execution_count": null, 457 | "outputs": [], 458 | "source": [], 459 | "metadata": { 460 | "collapsed": false, 461 | "pycharm": { 462 | "name": "#%%\n", 463 | "is_executing": false 464 | } 465 | } 466 | } 467 | ], 468 | "metadata": { 469 | "kernelspec": { 470 | "display_name": "Python 3", 471 | "language": "python", 472 | "name": "python3" 473 | }, 474 | "language_info": { 475 | "codemirror_mode": { 476 | "name": "ipython", 477 | "version": 2 478 | }, 479 | "file_extension": ".py", 480 | "mimetype": "text/x-python", 481 | "name": "python", 482 | "nbconvert_exporter": "python", 483 | "pygments_lexer": "ipython2", 484 | "version": "2.7.6" 485 | } 486 | }, 487 | "nbformat": 4, 488 | "nbformat_minor": 0 489 | } --------------------------------------------------------------------------------