{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Visualise NIRS artifact correction methods\n\nHere we artificially introduce several fNIRS artifacts and observe\nhow artifact correction techniques attempt to correct the data.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Authors: Robert Luke \n#\n# License: BSD-3-Clause\n# Copyright the MNE-Python contributors." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import os\n\nimport mne\nfrom mne.preprocessing.nirs import (\n optical_density,\n temporal_derivative_distribution_repair,\n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import data\n\nHere we will work with the `fNIRS motor data `.\nWe resample the data to make indexing exact times more convenient.\nWe then convert the data to optical density to perform corrections on\nand plot these signals.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fnirs_data_folder = mne.datasets.fnirs_motor.data_path()\nfnirs_cw_amplitude_dir = os.path.join(fnirs_data_folder, \"Participant-1\")\nraw_intensity = mne.io.read_raw_nirx(fnirs_cw_amplitude_dir, verbose=True)\nraw_intensity.load_data().resample(3, npad=\"auto\")\nraw_od = optical_density(raw_intensity)\nnew_annotations = mne.Annotations(\n [31, 187, 317], [8, 8, 8], [\"Movement\", \"Movement\", \"Movement\"]\n)\nraw_od.set_annotations(new_annotations)\nraw_od.plot(n_channels=15, duration=400, show_scrollbars=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see some small artifacts in the above data from movement around 40,\n190 and 240 seconds. However, this data is relatively clean so we will\nadd some additional artifacts below.\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Add artificial artifacts to data\n\nTwo common types of artifacts in NIRS data are spikes and baseline shifts.\nSpikes often occur when a person moves and the optode moves relative to the\nscalp and then returns to its original position.\nBaseline shifts occur if the optode moves relative to the scalp and does not\nreturn to its original position.\nWe add a spike type artifact at 100 seconds and a baseline shift at 200\nseconds to the data.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "corrupted_data = raw_od.get_data()\ncorrupted_data[:, 298:302] = corrupted_data[:, 298:302] - 0.06\ncorrupted_data[:, 450:750] = corrupted_data[:, 450:750] + 0.03\ncorrupted_od = mne.io.RawArray(\n corrupted_data, raw_od.info, first_samp=raw_od.first_samp\n)\nnew_annotations.append([95, 145, 245], [10, 10, 10], [\"Spike\", \"Baseline\", \"Baseline\"])\ncorrupted_od.set_annotations(new_annotations)\n\ncorrupted_od.plot(n_channels=15, duration=400, show_scrollbars=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Apply temporal derivative distribution repair\n\nThis approach corrects baseline shift and spike artifacts without the need\nfor any user-supplied parameters :footcite:`FishburnEtAl2019`.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "corrected_tddr = temporal_derivative_distribution_repair(corrupted_od)\ncorrected_tddr.plot(n_channels=15, duration=400, show_scrollbars=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see in the data above that the introduced spikes and shifts are\nlargely removed, but some residual smaller artifact remains.\nThe same can be said for the artifacts in the original data.\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n\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 }