{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Plot point-spread functions (PSFs) for a volume\n\nVisualise PSF at one volume vertex for sLORETA.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Authors: Olaf Hauk \n# Alexandre Gramfort \n# 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 numpy as np\n\nimport mne\nfrom mne.datasets import sample\nfrom mne.minimum_norm import get_point_spread, make_inverse_resolution_matrix\n\nprint(__doc__)\n\ndata_path = sample.data_path()\nsubjects_dir = data_path / \"subjects\"\nmeg_path = data_path / \"MEG\" / \"sample\"\nfname_cov = meg_path / \"sample_audvis-cov.fif\"\nfname_evo = meg_path / \"sample_audvis-ave.fif\"\nfname_trans = meg_path / \"sample_audvis_raw-trans.fif\"\nfname_bem = subjects_dir / \"sample\" / \"bem\" / \"sample-5120-bem-sol.fif\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the volume, create a coarse source space for speed (don't do this in\nreal code!), then compute the forward using this source space.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# read noise cov and and evoked\nnoise_cov = mne.read_cov(fname_cov)\nevoked = mne.read_evokeds(fname_evo, 0)\n\n# create a coarse source space\nsrc_vol = mne.setup_volume_source_space( # this is a very course resolution!\n \"sample\", pos=15.0, subjects_dir=subjects_dir, add_interpolator=False\n) # usually you want True, this is just for speed\n\n# compute the forward\nforward_vol = mne.make_forward_solution( # MEG-only for speed\n evoked.info, fname_trans, src_vol, fname_bem, eeg=False\n)\ndel src_vol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now make an inverse operator and compute the PSF at a source.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "inverse_operator_vol = mne.minimum_norm.make_inverse_operator(\n info=evoked.info, forward=forward_vol, noise_cov=noise_cov\n)\n\n# compute resolution matrix for sLORETA\nrm_lor_vol = make_inverse_resolution_matrix(\n forward_vol, inverse_operator_vol, method=\"sLORETA\", lambda2=1.0 / 9.0\n)\n\n# get PSF and CTF for sLORETA at one vertex\nsources_vol = [100]\nstc_psf_vol = get_point_spread(rm_lor_vol, forward_vol[\"src\"], sources_vol, norm=True)\ndel rm_lor_vol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualize\nPSF:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Which vertex corresponds to selected source\nsrc_vol = forward_vol[\"src\"]\nverttrue_vol = src_vol[0][\"vertno\"][sources_vol]\n\n# find vertex with maximum in PSF\nmax_vert_idx, _ = np.unravel_index(stc_psf_vol.data.argmax(), stc_psf_vol.data.shape)\nvert_max_ctf_vol = src_vol[0][\"vertno\"][[max_vert_idx]]\n\n# plot them\nbrain_psf_vol = stc_psf_vol.plot_3d(\n \"sample\",\n src=forward_vol[\"src\"],\n views=\"ven\",\n subjects_dir=subjects_dir,\n volume_options=dict(alpha=0.5),\n)\nbrain_psf_vol.add_text(0.1, 0.9, \"Volumetric sLORETA PSF\", \"title\", font_size=16)\nbrain_psf_vol.add_foci(\n verttrue_vol, coords_as_verts=True, scale_factor=1, hemi=\"vol\", color=\"green\"\n)\nbrain_psf_vol.add_foci(\n vert_max_ctf_vol,\n coords_as_verts=True,\n scale_factor=1.25,\n hemi=\"vol\",\n color=\"black\",\n alpha=0.3,\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 }