{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Annotate muscle artifacts\n\nMuscle contractions produce high frequency activity that can mask brain signal\nof interest. Muscle artifacts can be produced when clenching the jaw,\nswallowing, or twitching a cranial muscle. Muscle artifacts are most\nnoticeable in the range of 110-140 Hz.\n\nThis example uses :func:`~mne.preprocessing.annotate_muscle_zscore` to annotate\nsegments where muscle activity is likely present. This is done by band-pass\nfiltering the data in the 110-140 Hz range. Then, the envelope is taken using\nthe hilbert analytical signal to only consider the absolute amplitude and not\nthe phase of the high frequency signal. The envelope is z-scored and summed\nacross channels and divided by the square root of the number of channels.\nBecause muscle artifacts last several hundred milliseconds, a low-pass filter\nis applied on the averaged z-scores at 4 Hz, to remove transient peaks.\nSegments above a set threshold are annotated as ``BAD_muscle``. In addition,\nthe ``min_length_good`` parameter determines the cutoff for whether short\nspans of \"good data\" in between muscle artifacts are included in the\nsurrounding \"BAD\" annotation.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Authors: Adonay Nunes \n# Luke Bloy \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\nimport numpy as np\n\nfrom mne.datasets.brainstorm import bst_auditory\nfrom mne.io import read_raw_ctf\nfrom mne.preprocessing import annotate_muscle_zscore\n\n# Load data\ndata_path = bst_auditory.data_path()\nraw_fname = data_path / \"MEG\" / \"bst_auditory\" / \"S01_AEF_20131218_01.ds\"\n\nraw = read_raw_ctf(raw_fname, preload=False)\n\nraw.crop(130, 160).load_data() # just use a fraction of data for speed here\nraw.resample(300, npad=\"auto\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notch filter the data:\n\n

Note

If line noise is present, you should perform notch-filtering *before*\n detecting muscle artifacts. See `tut-section-line-noise` for an\n example.

\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "raw.notch_filter([60, 120])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# The threshold is data dependent, check the optimal threshold by plotting\n# ``scores_muscle``.\nthreshold_muscle = 5 # z-score\n# Choose one channel type, if there are axial gradiometers and magnetometers,\n# select magnetometers as they are more sensitive to muscle activity.\nannot_muscle, scores_muscle = annotate_muscle_zscore(\n raw,\n ch_type=\"mag\",\n threshold=threshold_muscle,\n min_length_good=0.2,\n filter_freq=[110, 140],\n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot muscle z-scores across recording\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, ax = plt.subplots()\nax.plot(raw.times, scores_muscle)\nax.axhline(y=threshold_muscle, color=\"r\")\nax.set(xlabel=\"time, (s)\", ylabel=\"zscore\", title=\"Muscle activity\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## View the annotations\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "order = np.arange(144, 164)\nraw.set_annotations(annot_muscle)\nraw.plot(start=5, duration=20, order=order)" ] } ], "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 }