Spaces:
Running
Running
File size: 8,059 Bytes
3bb804c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
from ..utils import get_config, verbose
@verbose
def coregistration(
*,
width=None,
height=None,
inst=None,
subject=None,
subjects_dir=None,
head_opacity=None,
head_high_res=None,
trans=None,
orient_to_surface=None,
scale_by_distance=None,
mark_inside=None,
interaction=None,
fullscreen=None,
show=True,
block=False,
verbose=None,
):
"""Coregister an MRI with a subject's head shape.
The GUI can be launched through the command line interface:
.. code-block:: bash
$ mne coreg
or using a python interpreter as shown in :ref:`tut-source-alignment`.
Parameters
----------
width : int | None
Specify the width for window (in logical pixels).
Default is None, which uses ``MNE_COREG_WINDOW_WIDTH`` config value
(which defaults to ``800``).
height : int | None
Specify a height for window (in logical pixels).
Default is None, which uses ``MNE_COREG_WINDOW_WIDTH`` config value
(which defaults to ``400``).
inst : None | path-like
Path to an instance file containing the digitizer data. Compatible for
Raw, Epochs, and Evoked files.
subject : None | str
Name of the mri subject.
%(subjects_dir)s
head_opacity : float | None
The opacity of the head surface in the range ``[0., 1.]``.
Default is None, which uses ``MNE_COREG_HEAD_OPACITY`` config value
(which defaults to ``1.``).
head_high_res : bool | None
Use a high resolution head surface.
Default is None, which uses ``MNE_COREG_HEAD_HIGH_RES`` config value
(which defaults to True).
trans : path-like | Transform | None
The Head<->MRI transform or the path to its FIF file (``"-trans.fif"``).
orient_to_surface : bool | None
If True (default), orient EEG electrode and head shape points to the head
surface.
.. versionadded:: 0.16
scale_by_distance : bool | None
If True (default), scale the digitization points by their distance from the
scalp surface.
.. versionadded:: 0.16
mark_inside : bool | None
If True (default), mark points inside the head surface in a
different color.
.. versionadded:: 0.16
%(interaction_scene_none)s
Defaults to ``'terrain'``.
.. versionadded:: 0.16
.. versionchanged:: 1.0
Default interaction mode if ``None`` and no config setting found
changed from ``'trackball'`` to ``'terrain'``.
%(fullscreen)s
Default is ``None``, which uses ``MNE_COREG_FULLSCREEN`` config value
(which defaults to ``False``).
.. versionadded:: 1.1
show : bool
Show the GUI if True.
block : bool
Whether to halt program execution until the figure is closed.
%(verbose)s
Returns
-------
frame : instance of CoregistrationUI
The coregistration frame.
Notes
-----
Many parameters (e.g., ``head_opacity``) take None as a parameter,
which means that the default will be read from the MNE-Python
configuration file (which gets saved when exiting).
Step by step instructions for the coregistrations are shown below:
.. youtube:: ALV5qqMHLlQ
"""
config = get_config()
if head_high_res is None:
head_high_res = config.get("MNE_COREG_HEAD_HIGH_RES", "true") == "true"
if head_opacity is None:
head_opacity = config.get("MNE_COREG_HEAD_OPACITY", 0.8)
if width is None:
width = config.get("MNE_COREG_WINDOW_WIDTH", 800)
if height is None:
height = config.get("MNE_COREG_WINDOW_HEIGHT", 600)
if subjects_dir is None:
if "SUBJECTS_DIR" in config:
subjects_dir = config["SUBJECTS_DIR"]
elif "MNE_COREG_SUBJECTS_DIR" in config:
subjects_dir = config["MNE_COREG_SUBJECTS_DIR"]
false_like = ("false", "0")
if orient_to_surface is None:
orient_to_surface = config.get("MNE_COREG_ORIENT_TO_SURFACE", "true").lower()
orient_to_surface = orient_to_surface not in false_like
if scale_by_distance is None:
scale_by_distance = config.get("MNE_COREG_SCALE_BY_DISTANCE", "true").lower()
scale_by_distance = scale_by_distance not in false_like
if interaction is None:
interaction = config.get("MNE_COREG_INTERACTION", "terrain")
if mark_inside is None:
mark_inside = config.get("MNE_COREG_MARK_INSIDE", "true").lower()
mark_inside = mark_inside not in false_like
if fullscreen is None:
fullscreen = config.get("MNE_COREG_FULLSCREEN", "") == "true"
head_opacity = float(head_opacity)
width = int(width)
height = int(height)
from ..viz.backends.renderer import MNE_3D_BACKEND_TESTING
from ._coreg import CoregistrationUI
if MNE_3D_BACKEND_TESTING:
show = block = False
return CoregistrationUI(
info_file=inst,
subject=subject,
subjects_dir=subjects_dir,
head_resolution=head_high_res,
head_opacity=head_opacity,
orient_glyphs=orient_to_surface,
scale_by_distance=scale_by_distance,
mark_inside=mark_inside,
trans=trans,
size=(width, height),
show=show,
block=block,
interaction=interaction,
fullscreen=fullscreen,
verbose=verbose,
)
class _GUIScraper:
"""Scrape GUI outputs."""
def __repr__(self):
return "<GUIScraper>"
def __call__(self, block, block_vars, gallery_conf):
from ._coreg import CoregistrationUI
gui_classes = (CoregistrationUI,)
try:
from mne_gui_addons._ieeg_locate import IntracranialElectrodeLocator
except Exception:
pass
else:
gui_classes = gui_classes + (IntracranialElectrodeLocator,)
from qtpy import QtGui
from sphinx_gallery.scrapers import figure_rst
for gui in block_vars["example_globals"].values():
if (
isinstance(gui, gui_classes)
and not getattr(gui, "_scraped", False)
and gallery_conf["builder_name"] == "html"
):
gui._scraped = True # monkey-patch but it's easy enough
img_fname = next(block_vars["image_path_iterator"])
# TODO fix in window refactor
window = gui if hasattr(gui, "grab") else gui._renderer._window
# window is QWindow
# https://doc.qt.io/qt-5/qwidget.html#grab
pixmap = window.grab()
if hasattr(gui, "_renderer"): # if no renderer, no need
# Now the tricky part: we need to get the 3D renderer,
# extract the image from it, and put it in the correct
# place in the pixmap. The easiest way to do this is
# actually to save the 3D image first, then load it
# using QPixmap and Qt geometry.
plotter = gui._renderer.plotter
plotter.screenshot(img_fname)
sub_pixmap = QtGui.QPixmap(img_fname)
# https://doc.qt.io/qt-5/qwidget.html#mapTo
# https://doc.qt.io/qt-5/qpainter.html#drawPixmap-1
QtGui.QPainter(pixmap).drawPixmap(
plotter.mapTo(window, plotter.rect().topLeft()), sub_pixmap
)
# https://doc.qt.io/qt-5/qpixmap.html#save
pixmap.save(img_fname)
try: # for compatibility with both GUIs, will be refactored
gui._renderer.close() # TODO should be triggered by close
except Exception:
pass
gui.close()
return figure_rst([img_fname], gallery_conf["src_dir"], "GUI")
return ""
|