{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Continuous Target Decoding with SPoC\n\nSource Power Comodulation (SPoC) :footcite:`DahneEtAl2014` allows to identify\nthe composition of\northogonal spatial filters that maximally correlate with a continuous target.\n\nSPoC can be seen as an extension of the CSP for continuous variables.\n\nHere, SPoC is applied to decode the (continuous) fluctuation of an\nelectromyogram from MEG beta activity using data from\n[Cortico-Muscular Coherence example of FieldTrip](http://www.fieldtriptoolbox.org/tutorial/coherence)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Author: Alexandre Barachant \n# Jean-R\u00e9mi King \n#\n# License: BSD-3-Clause\n# Copyright the MNE-Python contributors." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\nfrom sklearn.linear_model import Ridge\nfrom sklearn.model_selection import KFold, cross_val_predict\nfrom sklearn.pipeline import make_pipeline\n\nimport mne\nfrom mne import Epochs\nfrom mne.datasets.fieldtrip_cmc import data_path\nfrom mne.decoding import SPoC\n\n# Define parameters\nfname = data_path() / \"SubjectCMC.ds\"\nraw = mne.io.read_raw_ctf(fname)\nraw.crop(50.0, 200.0) # crop for memory purposes\n\n# Filter muscular activity to only keep high frequencies\nemg = raw.copy().pick([\"EMGlft\"]).load_data()\nemg.filter(20.0, None)\n\n# Filter MEG data to focus on beta band\nraw.pick(picks=[\"meg\", \"ref_meg\"]).load_data()\nraw.filter(15.0, 30.0)\n\n# Build epochs as sliding windows over the continuous raw file\nevents = mne.make_fixed_length_events(raw, id=1, duration=0.75)\n\n# Epoch length is 1.5 second\nmeg_epochs = Epochs(raw, events, tmin=0.0, tmax=1.5, baseline=None, detrend=1, decim=12)\nemg_epochs = Epochs(emg, events, tmin=0.0, tmax=1.5, baseline=None)\n\n# Prepare classification\nX = meg_epochs.get_data()\ny = emg_epochs.get_data().var(axis=2)[:, 0] # target is EMG power\n\n# Classification pipeline with SPoC spatial filtering and Ridge Regression\nspoc = SPoC(n_components=2, log=True, reg=\"oas\", rank=\"full\")\nclf = make_pipeline(spoc, Ridge())\n# Define a two fold cross-validation\ncv = KFold(n_splits=2, shuffle=False)\n\n# Run cross validation\ny_preds = cross_val_predict(clf, X, y, cv=cv)\n\n# Plot the True EMG power and the EMG power predicted from MEG data\nfig, ax = plt.subplots(1, 1, figsize=[10, 4], layout=\"constrained\")\ntimes = raw.times[meg_epochs.events[:, 0] - raw.first_samp]\nax.plot(times, y_preds, color=\"b\", label=\"Predicted EMG\")\nax.plot(times, y, color=\"r\", label=\"True EMG\")\nax.set_xlabel(\"Time (s)\")\nax.set_ylabel(\"EMG Power\")\nax.set_title(\"SPoC MEG Predictions\")\nplt.legend()\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the contributions to the detected components (i.e., the forward model)\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "spoc.fit(X, y)\nspoc.plot_patterns(meg_epochs.info)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n.. footbibliography::\n\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 0 }