From 3022ef04b5946a6fb53792e3b748b471ab86ff89 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sat, 18 May 2024 21:13:01 +0200 Subject: [PATCH 01/14] push Pedro's implementation --- moabb/datasets/alphawaves.py | 185 +++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 moabb/datasets/alphawaves.py diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py new file mode 100644 index 000000000..c2178d1d3 --- /dev/null +++ b/moabb/datasets/alphawaves.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +import mne +import numpy as np +from moabb.datasets import download as dl +from moabb.datasets.base import BaseDataset +from scipy.io import loadmat + +ALPHAWAVES_URL = 'https://zenodo.org/record/2348892/files/' + + +class AlphaWaves(BaseDataset): + '''Dataset containing EEG recordings of subjects in a simple + resting-state eyes open/closed experimental protocol. Data were recorded + during a pilot experiment taking place in the GIPSA-lab, Grenoble, + France, in 2017 [1]. + + **Dataset Description** + + This dataset concerns an experiment carried out at GIPSA-lab + (University of Grenoble Alpes, CNRS, Grenoble-INP) in 2017. + Principal Investigators : Eng. Grégoire Cattan, Eng. Pedro L. C. Rodrigues + Scientific Supervisor : Dr. Marco Congedo + + Introduction : + + The occipital dominant rhythm (commonly referred to as occipital ‘Alpha’) + is prominent in occipital and parietal regions when a subject is exempt of + visual stimulations, as in the case when keeping the eyes closed [2]. In + normal subjects its peak frequency is in the range 8-12Hz. The detection of + alpha waves on the ongoing electroencephalography (EEG) is a useful + indicator of the subject’s level of stress, concentration, relaxation or + mental load [3,4] and an easy marker to detect in the recorded signals + because of its high signal-to-noise-ratio. This experiment was conducted to + provide a simple yet reliable set of EEG signals carrying very distinct + signatures on each experimental condition. It can be useful for researchers + and students looking for an EEG dataset to perform tests with signal + processing and machine learning algorithms. An example of application of + this dataset can be seen in [5]. + + I. Participants + + A total of 20 volunteers participated in the experiment (7 females), with + mean (sd) age 25.8 (5.27) and median 25.5. 18 subjects were between 19 and + 28 years old. Two participants with age 33 and 44 were outside this range. + + II. Procedures + + EEG signals were acquired using a standard research grade amplifier + (g.USBamp, g.tec, Schiedlberg, Austria) and the EC20 cap equipped with 16 + wet electrodes (EasyCap, Herrsching am Ammersee, Germany), placed according + to the 10-20 international system. The locations of the electrodes were + FP1, FP2, FC5, FC6, FZ, T7, CZ, T8, P7, P3, PZ, P4, P8, O1, Oz, and O2. + The reference was placed on the right earlobe and the ground at the AFZ + scalp location. The amplifier was linked by USB connection to the PC where + the data were acquired by means of the software OpenVibe [6,7]. We acquired + the data with no digital filter and a sampling frequency of 512 samples per + second was used. For ensuing analyses, the experimenter was able to tag the + EEG signal using an in-house application based on a C/C++ library [8]. The + tag were sent by the application to the amplifier through the USB port of + the PC. It was then recorded along with the EEG signal as a supplementary + channel. + + For each recording we provide the age, genre and fatigue of each + participant. Fatigue was evaluated by the subjects thanks to a scale + ranging from 0 to 10, where 10 represents exhaustion. Each participant + underwent one session consisting of ten blocks of ten seconds of EEG data + recording. Five blocks were recorded while a subject was keeping his eyes + closed (condition 1) and the others while his eyes were open (condition 2). + The two conditions were alternated. Before the onset of each block, the + subject was asked to close or open his eyes according to the experimental + condition. The experimenter then tagged the EEG signal using the in-house + application and started a 10-second countdown of a block. + + III. Organization of the dataset + + For each subject we provide a single .mat file containing the complete + recording of the session. The file is a 2D-matrix where the rows contain + the observations at each time sample. Columns 2 to 17 contain the + recordings on each of the 16 EEG electrodes. The first column of the matrix + represents the timestamp of each observation and column 18 and 19 contain + the triggers for the experimental condition 1 and 2. The rows in column 18 + (resp. 19) are filled with zeros, except at the timestamp corresponding to + the beginning of the block for condition 1 (resp. 2), when the row gets a + value of one. + + We supply an online and open-source example working with Python [9]. + + References + ---------- + + .. [1] Cattan G, Andreev A, Mendoza C, Congedo M. The Impact of Passive + Head-Mounted Virtual Reality Devices on the Quality of EEG Signals. + In Delft: The Eurographics Association; 2018 [cited 2018 Apr 16]. + + .. [2] Pfurtscheller G, Stancák A, Neuper C. Event-related synchronization + (ERS) in the alpha band — an electrophysiological correlate of + cortical idling: A review. Int J Psychophysiol. 1996 Nov + 1;24(1):39–46. + + .. [3] Banquet JP. Spectral analysis of the EEG in meditation. + Electroencephalogr Clin Neurophysiol. 1973 Aug 1;35(2):143–51. + + .. [4] Antonenko P, Paas F, Grabner R, van Gog T. Using + Electroencephalography to Measure Cognitive Load. + Educ Psychol Rev. 2010 Dec 1;22(4):425–38. + + .. [5] Rodrigues PLC, Congedo M, Jutten C. Multivariate Time-Series + Analysis Via Manifold Learning. In: 2018 IEEE Statistical Signal + Processing Workshop (SSP). 2018. p. 573–7. + + .. [6] Renard Y, Lotte F, Gibert G, Congedo M, Maby E, Delannoy V, et al. + OpenViBE: An Open-Source Software Platform to Design, Test, and Use + Brain–Computer Interfaces in Real and Virtual Environments. + Presence Teleoperators Virtual Environ. 2010 Feb 1;19(1):35–53. + + .. [7] Arrouët C, Congedo M, Marvie J-E, Lamarche F, Lécuyer A, Arnaldi B. + Open-ViBE: A Three Dimensional Platform for Real-Time Neuroscience. + J Neurother. 2005 Jul 8;9(1):3–25. + + .. [8] Mandal MK. C++ Library for Serial Communication with Arduino + [Internet]. 2016 [cited 2018 Dec 15]. Available from: + https://github.com/manashmndl/SerialPort + + .. [9] Rodrigues PLC. Alpha-Waves-Dataset [Internet]. + Grenoble: GIPSA-lab; 2018. Available from: + https://github.com/plcrodrigues/Alpha-Waves-Dataset + + ''' + + def __init__(self): + + subject_list = list(range(1, 6+1)) + list(range(8, 20+1)) + self.subject_list = subject_list + + def _get_single_subject_data(self, subject): + """return data for a single subject""" + + filepath = self.data_path(subject)[0] + data = loadmat(filepath) + + S = data['SIGNAL'][:, 1:17] + stim_close = data['SIGNAL'][:, 17] + stim_open = data['SIGNAL'][:, 18] + stim = 1 * stim_close + 2 * stim_open + + chnames = [ + 'Fp1', + 'Fp2', + 'Fc5', + 'Fz', + 'Fc6', + 'T7', + 'Cz', + 'T8', + 'P7', + 'P3', + 'Pz', + 'P4', + 'P8', + 'O1', + 'Oz', + 'O2', + 'stim'] + chtypes = ['eeg'] * 16 + ['stim'] + X = np.concatenate([S, stim[:, None]], axis=1).T + + info = mne.create_info(ch_names=chnames, sfreq=512, + ch_types=chtypes, + verbose=False) + raw = mne.io.RawArray(data=X, info=info, verbose=False) + + return raw + + def data_path(self, subject, path=None, force_update=False, + update_path=None, verbose=None): + + if subject not in self.subject_list: + raise(ValueError("Invalid subject number")) + + url = '{:s}subject_{:02d}.mat'.format(ALPHAWAVES_URL, subject) + file_path = dl.data_path(url, 'ALPHAWAVES') + + return [file_path] \ No newline at end of file From dc7352f571b8a61aef53686fc2f12cf6d6f72b84 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sat, 18 May 2024 21:17:47 +0200 Subject: [PATCH 02/14] complete constructor --- moabb/datasets/alphawaves.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py index c2178d1d3..89cde8e04 100644 --- a/moabb/datasets/alphawaves.py +++ b/moabb/datasets/alphawaves.py @@ -130,9 +130,16 @@ class AlphaWaves(BaseDataset): ''' def __init__(self): - subject_list = list(range(1, 6+1)) + list(range(8, 20+1)) - self.subject_list = subject_list + super().__init__( + subjects=subject_list, + sessions_per_subject=1, + events=dict(on=1, off=2), + code="Alphawaves", + interval=[0, 10], + paradigm="rstate", + doi="https://doi.org/10.5281/zenodo.2348892", + ) def _get_single_subject_data(self, subject): """return data for a single subject""" From 6d27b36be3e6eb882455bb3d8e1c1e79fd06cf92 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sat, 18 May 2024 22:12:08 +0200 Subject: [PATCH 03/14] Complete doc --- docs/source/dataset_summary.rst | 1 + docs/source/datasets.rst | 1 + moabb/datasets/__init__.py | 1 + moabb/datasets/alphawaves.py | 120 ++++++++++---------------------- 4 files changed, 38 insertions(+), 85 deletions(-) diff --git a/docs/source/dataset_summary.rst b/docs/source/dataset_summary.rst index cd2087b7c..478c064d3 100644 --- a/docs/source/dataset_summary.rst +++ b/docs/source/dataset_summary.rst @@ -120,6 +120,7 @@ is a resting state experiment. :class:`Cattan2019_PHMD`,12,16,2,10,60s,512Hz,1 :class:`Hinss2021`,15,62,4,1,2s,250Hz,1 + :class:`Rodrigues2018`,20,16,2,5,10s,512Hz,1 Compound Datasets ====================== diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 213e2a8c7..ee4c60a38 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -101,6 +101,7 @@ Resting State Datasets Cattan2019_PHMD Hinss2021 + Rodrigues2018 ------------ diff --git a/moabb/datasets/__init__.py b/moabb/datasets/__init__.py index 99b6af498..7dc7e07d2 100644 --- a/moabb/datasets/__init__.py +++ b/moabb/datasets/__init__.py @@ -11,6 +11,7 @@ # flake8: noqa from .alex_mi import AlexMI +from .alphawaves import Rodrigues2018 from .bbci_eeg_fnirs import Shin2017A, Shin2017B # Depreciated datasets (will be removed in the future): diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py index 89cde8e04..6c349df64 100644 --- a/moabb/datasets/alphawaves.py +++ b/moabb/datasets/alphawaves.py @@ -10,34 +10,31 @@ ALPHAWAVES_URL = 'https://zenodo.org/record/2348892/files/' -class AlphaWaves(BaseDataset): - '''Dataset containing EEG recordings of subjects in a simple +class Rodrigues2018(BaseDataset): + '''Alphawaves dataset + + .. admonition:: Dataset summary + + + ============== ======= ======= ========== ================= ============ =============== =========== + Name #Subj #Chan #Classes #Blocks/class Trials len Sampling rate #Sessions + =============== ======= ======= ========== ================= ============ =============== =========== + Rodrigues2018 20 16 2 5 10s 512Hz 1 + =============== ======= ======= ========== ================= ============ =============== =========== + + + Dataset containing EEG recordings of subjects in a simple resting-state eyes open/closed experimental protocol. Data were recorded during a pilot experiment taking place in the GIPSA-lab, Grenoble, France, in 2017 [1]. **Dataset Description** - This dataset concerns an experiment carried out at GIPSA-lab - (University of Grenoble Alpes, CNRS, Grenoble-INP) in 2017. - Principal Investigators : Eng. Grégoire Cattan, Eng. Pedro L. C. Rodrigues - Scientific Supervisor : Dr. Marco Congedo - - Introduction : - - The occipital dominant rhythm (commonly referred to as occipital ‘Alpha’) - is prominent in occipital and parietal regions when a subject is exempt of - visual stimulations, as in the case when keeping the eyes closed [2]. In - normal subjects its peak frequency is in the range 8-12Hz. The detection of - alpha waves on the ongoing electroencephalography (EEG) is a useful - indicator of the subject’s level of stress, concentration, relaxation or - mental load [3,4] and an easy marker to detect in the recorded signals - because of its high signal-to-noise-ratio. This experiment was conducted to + This experiment was conducted to provide a simple yet reliable set of EEG signals carrying very distinct signatures on each experimental condition. It can be useful for researchers and students looking for an EEG dataset to perform tests with signal - processing and machine learning algorithms. An example of application of - this dataset can be seen in [5]. + processing and machine learning algorithms. I. Participants @@ -50,83 +47,36 @@ class AlphaWaves(BaseDataset): EEG signals were acquired using a standard research grade amplifier (g.USBamp, g.tec, Schiedlberg, Austria) and the EC20 cap equipped with 16 wet electrodes (EasyCap, Herrsching am Ammersee, Germany), placed according - to the 10-20 international system. The locations of the electrodes were - FP1, FP2, FC5, FC6, FZ, T7, CZ, T8, P7, P3, PZ, P4, P8, O1, Oz, and O2. - The reference was placed on the right earlobe and the ground at the AFZ - scalp location. The amplifier was linked by USB connection to the PC where - the data were acquired by means of the software OpenVibe [6,7]. We acquired - the data with no digital filter and a sampling frequency of 512 samples per - second was used. For ensuing analyses, the experimenter was able to tag the - EEG signal using an in-house application based on a C/C++ library [8]. The - tag were sent by the application to the amplifier through the USB port of - the PC. It was then recorded along with the EEG signal as a supplementary - channel. - - For each recording we provide the age, genre and fatigue of each - participant. Fatigue was evaluated by the subjects thanks to a scale - ranging from 0 to 10, where 10 represents exhaustion. Each participant - underwent one session consisting of ten blocks of ten seconds of EEG data - recording. Five blocks were recorded while a subject was keeping his eyes + to the 10-20 international system. + We acquired the data with no digital filter and a sampling frequency of 512Hz + was used. + + Each participant underwent one session consisting of + ten blocks of ten seconds of EEG data recording. + Five blocks were recorded while a subject was keeping his eyes closed (condition 1) and the others while his eyes were open (condition 2). The two conditions were alternated. Before the onset of each block, the subject was asked to close or open his eyes according to the experimental - condition. The experimenter then tagged the EEG signal using the in-house - application and started a 10-second countdown of a block. - - III. Organization of the dataset + condition. - For each subject we provide a single .mat file containing the complete - recording of the session. The file is a 2D-matrix where the rows contain - the observations at each time sample. Columns 2 to 17 contain the - recordings on each of the 16 EEG electrodes. The first column of the matrix - represents the timestamp of each observation and column 18 and 19 contain - the triggers for the experimental condition 1 and 2. The rows in column 18 - (resp. 19) are filled with zeros, except at the timestamp corresponding to - the beginning of the block for condition 1 (resp. 2), when the row gets a - value of one. - - We supply an online and open-source example working with Python [9]. + We supply an online and open-source example working with Python [2]. References ---------- - .. [1] Cattan G, Andreev A, Mendoza C, Congedo M. The Impact of Passive - Head-Mounted Virtual Reality Devices on the Quality of EEG Signals. - In Delft: The Eurographics Association; 2018 [cited 2018 Apr 16]. - - .. [2] Pfurtscheller G, Stancák A, Neuper C. Event-related synchronization - (ERS) in the alpha band — an electrophysiological correlate of - cortical idling: A review. Int J Psychophysiol. 1996 Nov - 1;24(1):39–46. + .. [1] G. Cattan, P. L. Coelho Rodrigues, and M. Congedo, + ‘EEG Alpha Waves Dataset’, 2018. + Available: https://hal.archives-ouvertes.fr/hal-02086581 - .. [3] Banquet JP. Spectral analysis of the EEG in meditation. - Electroencephalogr Clin Neurophysiol. 1973 Aug 1;35(2):143–51. - - .. [4] Antonenko P, Paas F, Grabner R, van Gog T. Using - Electroencephalography to Measure Cognitive Load. - Educ Psychol Rev. 2010 Dec 1;22(4):425–38. - - .. [5] Rodrigues PLC, Congedo M, Jutten C. Multivariate Time-Series - Analysis Via Manifold Learning. In: 2018 IEEE Statistical Signal - Processing Workshop (SSP). 2018. p. 573–7. - - .. [6] Renard Y, Lotte F, Gibert G, Congedo M, Maby E, Delannoy V, et al. - OpenViBE: An Open-Source Software Platform to Design, Test, and Use - Brain–Computer Interfaces in Real and Virtual Environments. - Presence Teleoperators Virtual Environ. 2010 Feb 1;19(1):35–53. - - .. [7] Arrouët C, Congedo M, Marvie J-E, Lamarche F, Lécuyer A, Arnaldi B. - Open-ViBE: A Three Dimensional Platform for Real-Time Neuroscience. - J Neurother. 2005 Jul 8;9(1):3–25. - - .. [8] Mandal MK. C++ Library for Serial Communication with Arduino - [Internet]. 2016 [cited 2018 Dec 15]. Available from: - https://github.com/manashmndl/SerialPort - - .. [9] Rodrigues PLC. Alpha-Waves-Dataset [Internet]. + .. [2] Rodrigues PLC. Alpha-Waves-Dataset [Internet]. Grenoble: GIPSA-lab; 2018. Available from: https://github.com/plcrodrigues/Alpha-Waves-Dataset + Notes + ----- + + .. versionadded:: 1.0.1 + ''' def __init__(self): @@ -135,7 +85,7 @@ def __init__(self): subjects=subject_list, sessions_per_subject=1, events=dict(on=1, off=2), - code="Alphawaves", + code="Rodrigues2018", interval=[0, 10], paradigm="rstate", doi="https://doi.org/10.5281/zenodo.2348892", From c53fa39803834ac710edb222dc7b3f1282d84081 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sat, 18 May 2024 22:28:05 +0200 Subject: [PATCH 04/14] fix bug with file location --- docs/source/dataset_summary.rst | 2 +- docs/source/datasets.rst | 2 +- examples/noplot_phmd_ml_spectrum.py | 4 ++-- moabb/datasets/__init__.py | 2 +- moabb/datasets/alphawaves.py | 15 +++++++++------ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/source/dataset_summary.rst b/docs/source/dataset_summary.rst index 478c064d3..a2dc1de51 100644 --- a/docs/source/dataset_summary.rst +++ b/docs/source/dataset_summary.rst @@ -120,7 +120,7 @@ is a resting state experiment. :class:`Cattan2019_PHMD`,12,16,2,10,60s,512Hz,1 :class:`Hinss2021`,15,62,4,1,2s,250Hz,1 - :class:`Rodrigues2018`,20,16,2,5,10s,512Hz,1 + :class:`Rodrigues2017`,20,16,2,5,10s,512Hz,1 Compound Datasets ====================== diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index ee4c60a38..e4e091a9f 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -101,7 +101,7 @@ Resting State Datasets Cattan2019_PHMD Hinss2021 - Rodrigues2018 + Rodrigues2017 ------------ diff --git a/examples/noplot_phmd_ml_spectrum.py b/examples/noplot_phmd_ml_spectrum.py index 746138702..b6b3b0af8 100644 --- a/examples/noplot_phmd_ml_spectrum.py +++ b/examples/noplot_phmd_ml_spectrum.py @@ -18,7 +18,7 @@ import matplotlib.pyplot as plt import numpy as np -from moabb.datasets import Cattan2019_PHMD +from moabb.datasets import Cattan2019_PHMD, Rodrigues2017 from moabb.paradigms import RestingStateToP300Adapter @@ -38,7 +38,7 @@ channel = "Cz" subject = 1 -dataset = Cattan2019_PHMD() +dataset = Rodrigues2017() events = ["on", "off"] paradigm = RestingStateToP300Adapter(events=events, channels=[channel]) diff --git a/moabb/datasets/__init__.py b/moabb/datasets/__init__.py index 7dc7e07d2..804be9d8a 100644 --- a/moabb/datasets/__init__.py +++ b/moabb/datasets/__init__.py @@ -11,7 +11,7 @@ # flake8: noqa from .alex_mi import AlexMI -from .alphawaves import Rodrigues2018 +from .alphawaves import Rodrigues2017 from .bbci_eeg_fnirs import Shin2017A, Shin2017B # Depreciated datasets (will be removed in the future): diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py index 6c349df64..b2614e2ea 100644 --- a/moabb/datasets/alphawaves.py +++ b/moabb/datasets/alphawaves.py @@ -2,6 +2,7 @@ # -*- coding: UTF-8 -*- import mne +import os import numpy as np from moabb.datasets import download as dl from moabb.datasets.base import BaseDataset @@ -10,7 +11,7 @@ ALPHAWAVES_URL = 'https://zenodo.org/record/2348892/files/' -class Rodrigues2018(BaseDataset): +class Rodrigues2017(BaseDataset): '''Alphawaves dataset .. admonition:: Dataset summary @@ -19,7 +20,7 @@ class Rodrigues2018(BaseDataset): ============== ======= ======= ========== ================= ============ =============== =========== Name #Subj #Chan #Classes #Blocks/class Trials len Sampling rate #Sessions =============== ======= ======= ========== ================= ============ =============== =========== - Rodrigues2018 20 16 2 5 10s 512Hz 1 + Rodrigues2017 20 16 2 5 10s 512Hz 1 =============== ======= ======= ========== ================= ============ =============== =========== @@ -85,7 +86,7 @@ def __init__(self): subjects=subject_list, sessions_per_subject=1, events=dict(on=1, off=2), - code="Rodrigues2018", + code="Rodrigues2017", interval=[0, 10], paradigm="rstate", doi="https://doi.org/10.5281/zenodo.2348892", @@ -94,8 +95,10 @@ def __init__(self): def _get_single_subject_data(self, subject): """return data for a single subject""" - filepath = self.data_path(subject)[0] - data = loadmat(filepath) + dirpath = self.data_path(subject)[0] + filepath = os.listdir(dirpath)[0] + + data = loadmat(os.path.join(dirpath, filepath)) S = data['SIGNAL'][:, 1:17] stim_close = data['SIGNAL'][:, 17] @@ -128,7 +131,7 @@ def _get_single_subject_data(self, subject): verbose=False) raw = mne.io.RawArray(data=X, info=info, verbose=False) - return raw + return {"0": {"0": raw}} def data_path(self, subject, path=None, force_update=False, update_path=None, verbose=None): From e08b698db016a070bc71ab8c70c8419e3ce4f0e6 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sat, 18 May 2024 22:42:58 +0200 Subject: [PATCH 05/14] rename on/off to closed/open --- moabb/datasets/alphawaves.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py index b2614e2ea..0ad52a2b2 100644 --- a/moabb/datasets/alphawaves.py +++ b/moabb/datasets/alphawaves.py @@ -85,7 +85,7 @@ def __init__(self): super().__init__( subjects=subject_list, sessions_per_subject=1, - events=dict(on=1, off=2), + events=dict(closed=1, open=2), code="Rodrigues2017", interval=[0, 10], paradigm="rstate", @@ -104,7 +104,6 @@ def _get_single_subject_data(self, subject): stim_close = data['SIGNAL'][:, 17] stim_open = data['SIGNAL'][:, 18] stim = 1 * stim_close + 2 * stim_open - chnames = [ 'Fp1', 'Fp2', From 296f9afcfccbcf20856f8f2c9281338ab3804ef7 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 19 May 2024 08:59:06 +0200 Subject: [PATCH 06/14] push example --- examples/plot_restingstate_classification.py | 157 +++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 examples/plot_restingstate_classification.py diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py new file mode 100644 index 000000000..af5f101cf --- /dev/null +++ b/examples/plot_restingstate_classification.py @@ -0,0 +1,157 @@ +""" +================================ +Resting state classification +================================ + +This example compares the performance of different +pipelines with resting state datasets. + +""" + +# License: BSD (3-clause) + +import warnings + +from moabb.evaluations.evaluations import WithinSessionEvaluation +import numpy as np +import seaborn as sns +import pandas as pd +from matplotlib import pyplot as plt +from pyriemann.channelselection import ElectrodeSelection +from pyriemann.estimation import Covariances +from pyriemann.spatialfilters import Xdawn +from pyriemann.tangentspace import TangentSpace +from pyriemann.classification import MDM +from sklearn.base import TransformerMixin +from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA +from sklearn.pipeline import make_pipeline + +from moabb import set_log_level +from moabb.datasets import Cattan2019_PHMD, Hinss2021, Rodrigues2017 +from moabb.evaluations import CrossSessionEvaluation +from moabb.paradigms import RestingStateToP300Adapter + + +# Suppressing future and runtime warnings for cleaner output +set_log_level("info") + + +############################################################################## +# Initialization Process +# ---------------------- +# +# 1) Load the datasets +# 2) Define the paradigms +# 3) Select a subset of subjects and specific events for analysis + +# We define a list with the dataset to use +datasets = [Cattan2019_PHMD(), Hinss2021(), Rodrigues2017()] + +# To reduce the computation time in the example, we will only use the +# first two subjects. +start_subject = 1 +stop_subject = 2 +title = "Datasets: " +for dataset in datasets: + title = title + " " + dataset.code + dataset.subject_list = dataset.subject_list[start_subject:stop_subject] + +# Here we define the mne events for the RestingState paradigm. +events_cattan = dict(on=1, off=2) +events_hinss = dict(easy=2, diff=3) +events_rodrigues = dict(closed=1, off=2) + +# Create a paradigm by dataset as the events and lenght of epochs are different. +paradigm_cattan = RestingStateToP300Adapter(events=events_cattan, tmin=10, tmax=50) +paradigm_hinss = RestingStateToP300Adapter(events=events_hinss, tmin=0, tmax=0.5) +paradigm_rodrigues = RestingStateToP300Adapter(events=events_rodrigues, tmin=0, tmax=10) +paradigms = [paradigm_cattan, paradigm_hinss, paradigm_rodrigues] + +############################################################################## +# Create Pipelines +# ---------------- +# +# Pipelines must be a dict of scikit-learning pipeline transformer. +# For the sake of the example, we will just limit ourselves to two pipelines +# but more can be added. + +pipelines = {} + +pipelines["Xdawn+Cov+TS+LDA"] = make_pipeline( + Xdawn(nfilter=4), Covariances(estimator="lwf"), TangentSpace(), LDA() +) + +pipelines["Cov+MDM"] = make_pipeline( + Covariances(estimator="lwf"), MDM() +) + +############################################################################## +# Run evaluation +# ---------------- +# +# Compare the pipeline using a cross session evaluation. + +evaluation_cattan = WithinSessionEvaluation( + paradigm=paradigm_cattan, + datasets=[datasets[0]], + overwrite=False, + ) +results_cattan = evaluation_cattan.process(pipelines) + +evaluation_hinss = CrossSessionEvaluation( + paradigm=paradigm_hinss, + datasets=[datasets[1]], + overwrite=False, + ) +results_hinss = evaluation_hinss.process(pipelines) + +evaluation_rodrigues = CrossSessionEvaluation( + paradigm=paradigm_rodrigues, + datasets=[datasets[2]], + overwrite=False, + ) +results_rodrigues= evaluation_rodrigues.process(pipelines) + +results = pd.concat([results_cattan, results_hinss, results_rodrigues], ignore_index=True) + +############################################################################### +# Here, with the ElSel+Cov+TS+LDA pipeline, we reduce the computation time +# in approximately 8 times to the Cov+ElSel+TS+LDA pipeline. + +print("Averaging the session performance:") +print(results.groupby("pipeline").mean("score")[["score", "time"]]) + +############################################################################### +# Plot Results +# ------------- +# +# Here, we plot the results to compare two pipelines + + +fig, ax = plt.subplots(facecolor="white", figsize=[8, 4]) + +sns.stripplot( + data=results, + y="score", + x="pipeline", + ax=ax, + jitter=True, + alpha=0.5, + zorder=1, + palette="Set1", +) +sns.pointplot(data=results, y="score", x="pipeline", ax=ax, palette="Set1").set( + title=title +) + +ax.set_ylabel("ROC AUC") +ax.set_ylim(0.3, 1) + +plt.show() + +############################################################################### +# Key Observations: +# ----------------- +# - `Xdawn` is not ideal for the resting state paradigm. This is due to its specific design for Event-Related Potential (ERP). +# - Electrode selection strategy based on covariance matrices demonstrates less variability and typically yields better performance. +# - However, this strategy is more time-consuming compared to the simpler electrode selection based on time epoch data. From 83afa4358f7980b776bc4a70bef5f0732b25f401 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 19 May 2024 09:06:30 +0200 Subject: [PATCH 07/14] fix example --- examples/plot_restingstate_classification.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py index af5f101cf..318372d4f 100644 --- a/examples/plot_restingstate_classification.py +++ b/examples/plot_restingstate_classification.py @@ -59,7 +59,7 @@ # Here we define the mne events for the RestingState paradigm. events_cattan = dict(on=1, off=2) events_hinss = dict(easy=2, diff=3) -events_rodrigues = dict(closed=1, off=2) +events_rodrigues = dict(closed=1, open=2) # Create a paradigm by dataset as the events and lenght of epochs are different. paradigm_cattan = RestingStateToP300Adapter(events=events_cattan, tmin=10, tmax=50) @@ -105,7 +105,7 @@ ) results_hinss = evaluation_hinss.process(pipelines) -evaluation_rodrigues = CrossSessionEvaluation( +evaluation_rodrigues = WithinSessionEvaluation( paradigm=paradigm_rodrigues, datasets=[datasets[2]], overwrite=False, From e9debc168df22d8c63b6e3f6a6a69c98ae7295a5 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 19 May 2024 18:47:05 +0200 Subject: [PATCH 08/14] minor refacto of the example --- examples/plot_restingstate_classification.py | 69 +++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py index 318372d4f..8c1707be5 100644 --- a/examples/plot_restingstate_classification.py +++ b/examples/plot_restingstate_classification.py @@ -6,6 +6,10 @@ This example compares the performance of different pipelines with resting state datasets. +Different evaluation methods are used for the different +datasets, then the results are aggregated and statistics +are plot by pipeline and dataset. + """ # License: BSD (3-clause) @@ -17,7 +21,6 @@ import seaborn as sns import pandas as pd from matplotlib import pyplot as plt -from pyriemann.channelselection import ElectrodeSelection from pyriemann.estimation import Covariances from pyriemann.spatialfilters import Xdawn from pyriemann.tangentspace import TangentSpace @@ -30,6 +33,11 @@ from moabb.datasets import Cattan2019_PHMD, Hinss2021, Rodrigues2017 from moabb.evaluations import CrossSessionEvaluation from moabb.paradigms import RestingStateToP300Adapter +from moabb.analysis.meta_analysis import ( # noqa: E501 + compute_dataset_statistics, + find_significant_differences, +) +import moabb.analysis.plotting as moabb_plt # Suppressing future and runtime warnings for cleaner output @@ -50,13 +58,13 @@ # To reduce the computation time in the example, we will only use the # first two subjects. start_subject = 1 -stop_subject = 2 +stop_subject = 4 title = "Datasets: " for dataset in datasets: title = title + " " + dataset.code dataset.subject_list = dataset.subject_list[start_subject:stop_subject] -# Here we define the mne events for the RestingState paradigm. +# Here we define the mne events for the RestingState paradigms. events_cattan = dict(on=1, off=2) events_hinss = dict(easy=2, diff=3) events_rodrigues = dict(closed=1, open=2) @@ -71,7 +79,7 @@ # Create Pipelines # ---------------- # -# Pipelines must be a dict of scikit-learning pipeline transformer. +# Pipelines must be a dict of scikit-learn pipeline transformer. # For the sake of the example, we will just limit ourselves to two pipelines # but more can be added. @@ -89,11 +97,13 @@ # Run evaluation # ---------------- # -# Compare the pipeline using a cross session evaluation. +# Compare pipelines using a within and cross-sessionevaluation. +# (the evaluation method is different depending on the dataset) evaluation_cattan = WithinSessionEvaluation( paradigm=paradigm_cattan, datasets=[datasets[0]], + n_jobs=-1, overwrite=False, ) results_cattan = evaluation_cattan.process(pipelines) @@ -101,6 +111,7 @@ evaluation_hinss = CrossSessionEvaluation( paradigm=paradigm_hinss, datasets=[datasets[1]], + n_jobs=-1, overwrite=False, ) results_hinss = evaluation_hinss.process(pipelines) @@ -108,50 +119,30 @@ evaluation_rodrigues = WithinSessionEvaluation( paradigm=paradigm_rodrigues, datasets=[datasets[2]], + n_jobs=-1, overwrite=False, ) results_rodrigues= evaluation_rodrigues.process(pipelines) +# Display results by pipeline and dataset results = pd.concat([results_cattan, results_hinss, results_rodrigues], ignore_index=True) -############################################################################### -# Here, with the ElSel+Cov+TS+LDA pipeline, we reduce the computation time -# in approximately 8 times to the Cov+ElSel+TS+LDA pipeline. - print("Averaging the session performance:") -print(results.groupby("pipeline").mean("score")[["score", "time"]]) +print(results) +print(results.groupby(["pipeline", "dataset"]).mean("score")[["score", "time"]]) + ############################################################################### # Plot Results # ------------- # -# Here, we plot the results to compare two pipelines - - -fig, ax = plt.subplots(facecolor="white", figsize=[8, 4]) - -sns.stripplot( - data=results, - y="score", - x="pipeline", - ax=ax, - jitter=True, - alpha=0.5, - zorder=1, - palette="Set1", -) -sns.pointplot(data=results, y="score", x="pipeline", ax=ax, palette="Set1").set( - title=title -) - -ax.set_ylabel("ROC AUC") -ax.set_ylim(0.3, 1) - +# Here, we plot the results to compare the performance of the two pipelines +# with the different datasets. + +stats = compute_dataset_statistics(results) +stats.fillna(0, inplace=True) +print(stats) +moabb_plt.meta_analysis_plot( + stats, "Xdawn+Cov+TS+LDA", "Cov+MDM" + ) plt.show() - -############################################################################### -# Key Observations: -# ----------------- -# - `Xdawn` is not ideal for the resting state paradigm. This is due to its specific design for Event-Related Potential (ERP). -# - Electrode selection strategy based on covariance matrices demonstrates less variability and typically yields better performance. -# - However, this strategy is more time-consuming compared to the simpler electrode selection based on time epoch data. From 98bbbf57c9b8b511a7a2d77c6f50704c80e15b0b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 16:50:29 +0000 Subject: [PATCH 09/14] [pre-commit.ci] auto fixes from pre-commit.com hooks --- examples/noplot_phmd_ml_spectrum.py | 2 +- examples/plot_restingstate_classification.py | 57 ++++++-------- moabb/datasets/alphawaves.py | 81 +++++++++++--------- 3 files changed, 68 insertions(+), 72 deletions(-) diff --git a/examples/noplot_phmd_ml_spectrum.py b/examples/noplot_phmd_ml_spectrum.py index b6b3b0af8..d3bb7ef1f 100644 --- a/examples/noplot_phmd_ml_spectrum.py +++ b/examples/noplot_phmd_ml_spectrum.py @@ -18,7 +18,7 @@ import matplotlib.pyplot as plt import numpy as np -from moabb.datasets import Cattan2019_PHMD, Rodrigues2017 +from moabb.datasets import Rodrigues2017 from moabb.paradigms import RestingStateToP300Adapter diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py index 8c1707be5..3f56e7052 100644 --- a/examples/plot_restingstate_classification.py +++ b/examples/plot_restingstate_classification.py @@ -14,30 +14,25 @@ # License: BSD (3-clause) -import warnings -from moabb.evaluations.evaluations import WithinSessionEvaluation -import numpy as np -import seaborn as sns import pandas as pd from matplotlib import pyplot as plt +from pyriemann.classification import MDM from pyriemann.estimation import Covariances from pyriemann.spatialfilters import Xdawn from pyriemann.tangentspace import TangentSpace -from pyriemann.classification import MDM -from sklearn.base import TransformerMixin from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA from sklearn.pipeline import make_pipeline +import moabb.analysis.plotting as moabb_plt from moabb import set_log_level -from moabb.datasets import Cattan2019_PHMD, Hinss2021, Rodrigues2017 -from moabb.evaluations import CrossSessionEvaluation -from moabb.paradigms import RestingStateToP300Adapter from moabb.analysis.meta_analysis import ( # noqa: E501 compute_dataset_statistics, - find_significant_differences, ) -import moabb.analysis.plotting as moabb_plt +from moabb.datasets import Cattan2019_PHMD, Hinss2021, Rodrigues2017 +from moabb.evaluations import CrossSessionEvaluation +from moabb.evaluations.evaluations import WithinSessionEvaluation +from moabb.paradigms import RestingStateToP300Adapter # Suppressing future and runtime warnings for cleaner output @@ -89,9 +84,7 @@ Xdawn(nfilter=4), Covariances(estimator="lwf"), TangentSpace(), LDA() ) -pipelines["Cov+MDM"] = make_pipeline( - Covariances(estimator="lwf"), MDM() -) +pipelines["Cov+MDM"] = make_pipeline(Covariances(estimator="lwf"), MDM()) ############################################################################## # Run evaluation @@ -101,28 +94,28 @@ # (the evaluation method is different depending on the dataset) evaluation_cattan = WithinSessionEvaluation( - paradigm=paradigm_cattan, - datasets=[datasets[0]], - n_jobs=-1, - overwrite=False, - ) + paradigm=paradigm_cattan, + datasets=[datasets[0]], + n_jobs=-1, + overwrite=False, +) results_cattan = evaluation_cattan.process(pipelines) evaluation_hinss = CrossSessionEvaluation( - paradigm=paradigm_hinss, - datasets=[datasets[1]], - n_jobs=-1, - overwrite=False, - ) + paradigm=paradigm_hinss, + datasets=[datasets[1]], + n_jobs=-1, + overwrite=False, +) results_hinss = evaluation_hinss.process(pipelines) evaluation_rodrigues = WithinSessionEvaluation( - paradigm=paradigm_rodrigues, - datasets=[datasets[2]], - n_jobs=-1, - overwrite=False, - ) -results_rodrigues= evaluation_rodrigues.process(pipelines) + paradigm=paradigm_rodrigues, + datasets=[datasets[2]], + n_jobs=-1, + overwrite=False, +) +results_rodrigues = evaluation_rodrigues.process(pipelines) # Display results by pipeline and dataset results = pd.concat([results_cattan, results_hinss, results_rodrigues], ignore_index=True) @@ -142,7 +135,5 @@ stats = compute_dataset_statistics(results) stats.fillna(0, inplace=True) print(stats) -moabb_plt.meta_analysis_plot( - stats, "Xdawn+Cov+TS+LDA", "Cov+MDM" - ) +moabb_plt.meta_analysis_plot(stats, "Xdawn+Cov+TS+LDA", "Cov+MDM") plt.show() diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py index 0ad52a2b2..30a763305 100644 --- a/moabb/datasets/alphawaves.py +++ b/moabb/datasets/alphawaves.py @@ -1,19 +1,22 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- -import mne import os + +import mne import numpy as np +from scipy.io import loadmat + from moabb.datasets import download as dl from moabb.datasets.base import BaseDataset -from scipy.io import loadmat -ALPHAWAVES_URL = 'https://zenodo.org/record/2348892/files/' + +ALPHAWAVES_URL = "https://zenodo.org/record/2348892/files/" class Rodrigues2017(BaseDataset): - '''Alphawaves dataset - + """Alphawaves dataset + .. admonition:: Dataset summary @@ -78,15 +81,15 @@ class Rodrigues2017(BaseDataset): .. versionadded:: 1.0.1 - ''' + """ def __init__(self): - subject_list = list(range(1, 6+1)) + list(range(8, 20+1)) + subject_list = list(range(1, 6 + 1)) + list(range(8, 20 + 1)) super().__init__( subjects=subject_list, sessions_per_subject=1, events=dict(closed=1, open=2), - code="Rodrigues2017", + code="Rodrigues2017", interval=[0, 10], paradigm="rstate", doi="https://doi.org/10.5281/zenodo.2348892", @@ -100,45 +103,47 @@ def _get_single_subject_data(self, subject): data = loadmat(os.path.join(dirpath, filepath)) - S = data['SIGNAL'][:, 1:17] - stim_close = data['SIGNAL'][:, 17] - stim_open = data['SIGNAL'][:, 18] + S = data["SIGNAL"][:, 1:17] + stim_close = data["SIGNAL"][:, 17] + stim_open = data["SIGNAL"][:, 18] stim = 1 * stim_close + 2 * stim_open chnames = [ - 'Fp1', - 'Fp2', - 'Fc5', - 'Fz', - 'Fc6', - 'T7', - 'Cz', - 'T8', - 'P7', - 'P3', - 'Pz', - 'P4', - 'P8', - 'O1', - 'Oz', - 'O2', - 'stim'] - chtypes = ['eeg'] * 16 + ['stim'] + "Fp1", + "Fp2", + "Fc5", + "Fz", + "Fc6", + "T7", + "Cz", + "T8", + "P7", + "P3", + "Pz", + "P4", + "P8", + "O1", + "Oz", + "O2", + "stim", + ] + chtypes = ["eeg"] * 16 + ["stim"] X = np.concatenate([S, stim[:, None]], axis=1).T - info = mne.create_info(ch_names=chnames, sfreq=512, - ch_types=chtypes, - verbose=False) + info = mne.create_info( + ch_names=chnames, sfreq=512, ch_types=chtypes, verbose=False + ) raw = mne.io.RawArray(data=X, info=info, verbose=False) return {"0": {"0": raw}} - def data_path(self, subject, path=None, force_update=False, - update_path=None, verbose=None): + def data_path( + self, subject, path=None, force_update=False, update_path=None, verbose=None + ): if subject not in self.subject_list: - raise(ValueError("Invalid subject number")) + raise (ValueError("Invalid subject number")) - url = '{:s}subject_{:02d}.mat'.format(ALPHAWAVES_URL, subject) - file_path = dl.data_path(url, 'ALPHAWAVES') + url = "{:s}subject_{:02d}.mat".format(ALPHAWAVES_URL, subject) + file_path = dl.data_path(url, "ALPHAWAVES") - return [file_path] \ No newline at end of file + return [file_path] From 140c69ed3c872bf5d12968870f38f119d2d52266 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 19 May 2024 18:53:03 +0200 Subject: [PATCH 10/14] what's new --- docs/source/whats_new.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/whats_new.rst b/docs/source/whats_new.rst index 934165505..94a8f8ce0 100644 --- a/docs/source/whats_new.rst +++ b/docs/source/whats_new.rst @@ -34,6 +34,7 @@ Enhancements - Add SSVEP and ERP paradigms to DL pipelines (:gh:`590` by `Pierre Guetschel`_) - Allow to pass a single pipeline file to ``benchmark`` (:gh:`591` by `Pierre Guetschel`_) - Exposing the `drop_rate` for all the deep learning parameters (:gh:`592` by `Bruno Aristimunha`_) +- Add Alphawes dataset (:gh:`602` by `Gregoire Cattan`_ and `Pedro L. C. Rodrigues`_) Bugs ~~~~ From 735baa772fd36a34686e7cce2edc58e3d284521c Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 19 May 2024 18:55:27 +0200 Subject: [PATCH 11/14] typo --- examples/plot_restingstate_classification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py index 3f56e7052..56db33c77 100644 --- a/examples/plot_restingstate_classification.py +++ b/examples/plot_restingstate_classification.py @@ -64,7 +64,7 @@ events_hinss = dict(easy=2, diff=3) events_rodrigues = dict(closed=1, open=2) -# Create a paradigm by dataset as the events and lenght of epochs are different. +# Create a paradigm by dataset as the events and length of epochs are different. paradigm_cattan = RestingStateToP300Adapter(events=events_cattan, tmin=10, tmax=50) paradigm_hinss = RestingStateToP300Adapter(events=events_hinss, tmin=0, tmax=0.5) paradigm_rodrigues = RestingStateToP300Adapter(events=events_rodrigues, tmin=0, tmax=10) From a8290b2c60ab59382565672da355a3c78f2c9173 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 16:55:58 +0000 Subject: [PATCH 12/14] [pre-commit.ci] auto fixes from pre-commit.com hooks --- examples/plot_restingstate_classification.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py index 56db33c77..12f81b596 100644 --- a/examples/plot_restingstate_classification.py +++ b/examples/plot_restingstate_classification.py @@ -26,9 +26,7 @@ import moabb.analysis.plotting as moabb_plt from moabb import set_log_level -from moabb.analysis.meta_analysis import ( # noqa: E501 - compute_dataset_statistics, -) +from moabb.analysis.meta_analysis import compute_dataset_statistics # noqa: E501 from moabb.datasets import Cattan2019_PHMD, Hinss2021, Rodrigues2017 from moabb.evaluations import CrossSessionEvaluation from moabb.evaluations.evaluations import WithinSessionEvaluation From 5f975d7d7470f6f97ca67a7233a5ac7e03d58131 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 21 May 2024 14:57:24 +0200 Subject: [PATCH 13/14] remove examples --- examples/noplot_phmd_ml_spectrum.py | 4 +- examples/plot_restingstate_classification.py | 139 ------------------- 2 files changed, 2 insertions(+), 141 deletions(-) delete mode 100644 examples/plot_restingstate_classification.py diff --git a/examples/noplot_phmd_ml_spectrum.py b/examples/noplot_phmd_ml_spectrum.py index d3bb7ef1f..746138702 100644 --- a/examples/noplot_phmd_ml_spectrum.py +++ b/examples/noplot_phmd_ml_spectrum.py @@ -18,7 +18,7 @@ import matplotlib.pyplot as plt import numpy as np -from moabb.datasets import Rodrigues2017 +from moabb.datasets import Cattan2019_PHMD from moabb.paradigms import RestingStateToP300Adapter @@ -38,7 +38,7 @@ channel = "Cz" subject = 1 -dataset = Rodrigues2017() +dataset = Cattan2019_PHMD() events = ["on", "off"] paradigm = RestingStateToP300Adapter(events=events, channels=[channel]) diff --git a/examples/plot_restingstate_classification.py b/examples/plot_restingstate_classification.py deleted file mode 100644 index 56db33c77..000000000 --- a/examples/plot_restingstate_classification.py +++ /dev/null @@ -1,139 +0,0 @@ -""" -================================ -Resting state classification -================================ - -This example compares the performance of different -pipelines with resting state datasets. - -Different evaluation methods are used for the different -datasets, then the results are aggregated and statistics -are plot by pipeline and dataset. - -""" - -# License: BSD (3-clause) - - -import pandas as pd -from matplotlib import pyplot as plt -from pyriemann.classification import MDM -from pyriemann.estimation import Covariances -from pyriemann.spatialfilters import Xdawn -from pyriemann.tangentspace import TangentSpace -from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA -from sklearn.pipeline import make_pipeline - -import moabb.analysis.plotting as moabb_plt -from moabb import set_log_level -from moabb.analysis.meta_analysis import ( # noqa: E501 - compute_dataset_statistics, -) -from moabb.datasets import Cattan2019_PHMD, Hinss2021, Rodrigues2017 -from moabb.evaluations import CrossSessionEvaluation -from moabb.evaluations.evaluations import WithinSessionEvaluation -from moabb.paradigms import RestingStateToP300Adapter - - -# Suppressing future and runtime warnings for cleaner output -set_log_level("info") - - -############################################################################## -# Initialization Process -# ---------------------- -# -# 1) Load the datasets -# 2) Define the paradigms -# 3) Select a subset of subjects and specific events for analysis - -# We define a list with the dataset to use -datasets = [Cattan2019_PHMD(), Hinss2021(), Rodrigues2017()] - -# To reduce the computation time in the example, we will only use the -# first two subjects. -start_subject = 1 -stop_subject = 4 -title = "Datasets: " -for dataset in datasets: - title = title + " " + dataset.code - dataset.subject_list = dataset.subject_list[start_subject:stop_subject] - -# Here we define the mne events for the RestingState paradigms. -events_cattan = dict(on=1, off=2) -events_hinss = dict(easy=2, diff=3) -events_rodrigues = dict(closed=1, open=2) - -# Create a paradigm by dataset as the events and length of epochs are different. -paradigm_cattan = RestingStateToP300Adapter(events=events_cattan, tmin=10, tmax=50) -paradigm_hinss = RestingStateToP300Adapter(events=events_hinss, tmin=0, tmax=0.5) -paradigm_rodrigues = RestingStateToP300Adapter(events=events_rodrigues, tmin=0, tmax=10) -paradigms = [paradigm_cattan, paradigm_hinss, paradigm_rodrigues] - -############################################################################## -# Create Pipelines -# ---------------- -# -# Pipelines must be a dict of scikit-learn pipeline transformer. -# For the sake of the example, we will just limit ourselves to two pipelines -# but more can be added. - -pipelines = {} - -pipelines["Xdawn+Cov+TS+LDA"] = make_pipeline( - Xdawn(nfilter=4), Covariances(estimator="lwf"), TangentSpace(), LDA() -) - -pipelines["Cov+MDM"] = make_pipeline(Covariances(estimator="lwf"), MDM()) - -############################################################################## -# Run evaluation -# ---------------- -# -# Compare pipelines using a within and cross-sessionevaluation. -# (the evaluation method is different depending on the dataset) - -evaluation_cattan = WithinSessionEvaluation( - paradigm=paradigm_cattan, - datasets=[datasets[0]], - n_jobs=-1, - overwrite=False, -) -results_cattan = evaluation_cattan.process(pipelines) - -evaluation_hinss = CrossSessionEvaluation( - paradigm=paradigm_hinss, - datasets=[datasets[1]], - n_jobs=-1, - overwrite=False, -) -results_hinss = evaluation_hinss.process(pipelines) - -evaluation_rodrigues = WithinSessionEvaluation( - paradigm=paradigm_rodrigues, - datasets=[datasets[2]], - n_jobs=-1, - overwrite=False, -) -results_rodrigues = evaluation_rodrigues.process(pipelines) - -# Display results by pipeline and dataset -results = pd.concat([results_cattan, results_hinss, results_rodrigues], ignore_index=True) - -print("Averaging the session performance:") -print(results) -print(results.groupby(["pipeline", "dataset"]).mean("score")[["score", "time"]]) - - -############################################################################### -# Plot Results -# ------------- -# -# Here, we plot the results to compare the performance of the two pipelines -# with the different datasets. - -stats = compute_dataset_statistics(results) -stats.fillna(0, inplace=True) -print(stats) -moabb_plt.meta_analysis_plot(stats, "Xdawn+Cov+TS+LDA", "Cov+MDM") -plt.show() From 2fbc044af02cdb68eb0d9f0a4deae9602ed3268a Mon Sep 17 00:00:00 2001 From: bruAristimunha Date: Tue, 21 May 2024 15:10:50 +0200 Subject: [PATCH 14/14] Fixing citation and table --- moabb/datasets/alphawaves.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/moabb/datasets/alphawaves.py b/moabb/datasets/alphawaves.py index 30a763305..cc29a6886 100644 --- a/moabb/datasets/alphawaves.py +++ b/moabb/datasets/alphawaves.py @@ -20,17 +20,17 @@ class Rodrigues2017(BaseDataset): .. admonition:: Dataset summary - ============== ======= ======= ========== ================= ============ =============== =========== - Name #Subj #Chan #Classes #Blocks/class Trials len Sampling rate #Sessions - =============== ======= ======= ========== ================= ============ =============== =========== - Rodrigues2017 20 16 2 5 10s 512Hz 1 - =============== ======= ======= ========== ================= ============ =============== =========== + =============== ======= ======= ========== =============== ============ =============== =========== + Name #Subj #Chan #Classes #Blocks/class Trials len Sampling rate #Sessions + =============== ======= ======= ========== =============== ============ =============== =========== + Rodrigues2017 20 16 2 5 10s 512Hz 1 + =============== ======= ======= ========== =============== ============ =============== =========== Dataset containing EEG recordings of subjects in a simple resting-state eyes open/closed experimental protocol. Data were recorded during a pilot experiment taking place in the GIPSA-lab, Grenoble, - France, in 2017 [1]. + France, in 2017 [1]_. **Dataset Description** @@ -63,7 +63,7 @@ class Rodrigues2017(BaseDataset): subject was asked to close or open his eyes according to the experimental condition. - We supply an online and open-source example working with Python [2]. + We supply an online and open-source example working with Python [2]_. References ----------