{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Display sensitivity maps for EEG and MEG sensors\n\nSensitivity maps can be produced from forward operators that\nindicate how well different sensor types will be able to detect\nneural currents from different regions of the brain.\n\nTo get started with forward modeling see `tut-forward`.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Author: Eric Larson \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\nimport numpy as np\n\nimport mne\nfrom mne.datasets import sample\nfrom mne.source_estimate import SourceEstimate\nfrom mne.source_space import compute_distance_to_sensors\n\nprint(__doc__)\n\ndata_path = sample.data_path()\nmeg_path = data_path / \"MEG\" / \"sample\"\nfwd_fname = meg_path / \"sample_audvis-meg-eeg-oct-6-fwd.fif\"\nsubjects_dir = data_path / \"subjects\"\n\n# Read the forward solutions with surface orientation\nfwd = mne.read_forward_solution(fwd_fname)\nmne.convert_forward_solution(fwd, surf_ori=True, copy=False)\nleadfield = fwd[\"sol\"][\"data\"]\nprint(\"Leadfield shape : {leadfield.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compute sensitivity maps\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "grad_map = mne.sensitivity_map(fwd, ch_type=\"grad\", mode=\"fixed\")\nmag_map = mne.sensitivity_map(fwd, ch_type=\"mag\", mode=\"fixed\")\neeg_map = mne.sensitivity_map(fwd, ch_type=\"eeg\", mode=\"fixed\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show gain matrix a.k.a. leadfield matrix with sensitivity map\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "picks_meg = mne.pick_types(fwd[\"info\"], meg=True, eeg=False)\npicks_eeg = mne.pick_types(fwd[\"info\"], meg=False, eeg=True)\n\nfig, axes = plt.subplots(2, 1, figsize=(10, 8), sharex=True)\nfig.suptitle(\"Lead field matrix (500 dipoles only)\", fontsize=14)\nfor ax, picks, ch_type in zip(axes, [picks_meg, picks_eeg], [\"meg\", \"eeg\"]):\n im = ax.imshow(leadfield[picks, :500], origin=\"lower\", aspect=\"auto\", cmap=\"RdBu_r\")\n ax.set_title(ch_type.upper())\n ax.set_xlabel(\"sources\")\n ax.set_ylabel(\"sensors\")\n fig.colorbar(im, ax=ax)\n\nfig_2, ax = plt.subplots()\nax.hist(\n [grad_map.data.ravel(), mag_map.data.ravel(), eeg_map.data.ravel()],\n bins=20,\n label=[\"Gradiometers\", \"Magnetometers\", \"EEG\"],\n color=[\"c\", \"b\", \"k\"],\n)\nfig_2.legend()\nax.set(title=\"Normal orientation sensitivity\", xlabel=\"sensitivity\", ylabel=\"count\")\n\nbrain_sens = grad_map.plot(\n subjects_dir=subjects_dir, clim=dict(lims=[0, 50, 100]), figure=1\n)\nbrain_sens.add_text(0.1, 0.9, \"Gradiometer sensitivity\", \"title\", font_size=16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare sensitivity map with distribution of source depths\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# source space with vertices\nsrc = fwd[\"src\"]\n\n# Compute minimum Euclidean distances between vertices and MEG sensors\ndepths = compute_distance_to_sensors(src=src, info=fwd[\"info\"], picks=picks_meg).min(\n axis=1\n)\nmaxdep = depths.max() # for scaling\n\nvertices = [src[0][\"vertno\"], src[1][\"vertno\"]]\n\ndepths_map = SourceEstimate(data=depths, vertices=vertices, tmin=0.0, tstep=1.0)\n\nbrain_dep = depths_map.plot(\n subject=\"sample\",\n subjects_dir=subjects_dir,\n clim=dict(kind=\"value\", lims=[0, maxdep / 2.0, maxdep]),\n figure=2,\n)\nbrain_dep.add_text(0.1, 0.9, \"Source depth (m)\", \"title\", font_size=16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sensitivity is likely to co-vary with the distance between sources to\nsensors. To determine the strength of this relationship, we can compute the\ncorrelation between source depth and sensitivity values.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "corr = np.corrcoef(depths, grad_map.data[:, 0])[0, 1]\nprint(f\"Correlation between source depth and gradiomter sensitivity values: {corr:f}.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Gradiometer sensitiviy is highest close to the sensors, and decreases rapidly\nwith inreasing source depth. This is confirmed by the high negative\ncorrelation between the two.\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 }