def test_config(): """Test mne-python config file support""" key = '_MNE_PYTHON_CONFIG_TESTING' value = '123456' old_val = os.getenv(key, None) os.environ[key] = value assert_true(get_config(key) == value) del os.environ[key] # catch the warning about it being a non-standard config key with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') set_config(key, None, home_dir=tempdir) assert_true(len(w) == 1) assert_true(get_config(key, home_dir=tempdir) is None) assert_raises(KeyError, get_config, key, raise_error=True) with warnings.catch_warnings(record=True): warnings.simplefilter('always') set_config(key, value, home_dir=tempdir) assert_true(get_config(key, home_dir=tempdir) == value) set_config(key, None, home_dir=tempdir) if old_val is not None: os.environ[key] = old_val # Check if get_config with no input returns all config key = 'MNE_PYTHON_TESTING_KEY' config = {key: value} with warnings.catch_warnings(record=True): # non-standard key warnings.simplefilter('always') set_config(key, value, home_dir=tempdir) assert_equal(get_config(home_dir=tempdir), config)
def test_config(): """Test mne-python config file support""" tempdir = _TempDir() key = '_MNE_PYTHON_CONFIG_TESTING' value = '123456' old_val = os.getenv(key, None) os.environ[key] = value assert_true(get_config(key) == value) del os.environ[key] # catch the warning about it being a non-standard config key assert_true(len(set_config(None, None)) > 10) # tuple of valid keys with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') set_config(key, None, home_dir=tempdir) assert_true(len(w) == 1) assert_true(get_config(key, home_dir=tempdir) is None) assert_raises(KeyError, get_config, key, raise_error=True) with warnings.catch_warnings(record=True): warnings.simplefilter('always') set_config(key, value, home_dir=tempdir) assert_true(get_config(key, home_dir=tempdir) == value) set_config(key, None, home_dir=tempdir) if old_val is not None: os.environ[key] = old_val # Check if get_config with no input returns all config key = 'MNE_PYTHON_TESTING_KEY' config = {key: value} with warnings.catch_warnings(record=True): # non-standard key warnings.simplefilter('always') set_config(key, value, home_dir=tempdir) assert_equal(get_config(home_dir=tempdir), config)
def forward_pipeline(raw_fname, subject, fwd_fname=None, trans_fname=None, subjects_dir=None, overwrite=False): import os.path as op from mne.utils import get_config if subjects_dir is None: subjects_dir = get_config('SUBJECTS_DIR') # Setup paths save_dir = '/'.join(raw_fname.split('/')[:-1]) bem_dir = op.join(subjects_dir, subject, 'bem') bem_sol_fname = op.join(subjects_dir, subject, 'bem', subject + '-5120-bem-sol.fif') oct_fname = op.join(subjects_dir, subject, 'bem', subject + '-oct-6-src.fif') src_fname = op.join(bem_dir, subject + '-oct-6-src.fif') bem_sol_fname = op.join(bem_dir, subject + '-5120-bem-sol.fif') if trans_fname is None: trans_fname = op.join(save_dir, subject + '-trans.fif') if fwd_fname is None: fwd_fname = op.join(save_dir, subject + '-meg-fwd.fif') # 0. Checks Freesurfer segmentation and compute watershed bem miss_anatomy = not op.isfile(src_fname) or not op.exists(bem_sol_fname) for fname in [bem_sol_fname, oct_fname]: if not op.isfile(op.join(subjects_dir, subject, 'bem', fname)): miss_anatomy = True if miss_anatomy: raise RuntimeError('Could not find BEM (%s, %s), relaunch ' 'pipeline_anatomy()' % (bem_sol_fname, oct_fname)) # 1. Manual coregisteration head markers with coils if not op.isfile(trans_fname): raise RuntimeError('Could not find trans (%s), launch' 'coregistration.' % trans_fname) # 2. Forward solution if overwrite or not op.isfile(fwd_fname): from mne import (make_forward_solution, convert_forward_solution, write_forward_solution) fwd = make_forward_solution(info=raw_fname, trans=trans_fname, src=oct_fname, bem=bem_sol_fname, fname=None, meg=True, eeg=False, mindist=5.0, overwrite=True, ignore_ref=True) # Convert to surface orientation for better visualization fwd = convert_forward_solution(fwd, surf_ori=True) # save write_forward_solution(fwd_fname, fwd, overwrite=True) return
def test_min_window_size(raw, cfg_value): """Test minimum window plot size.""" old_cfg = get_config('MNE_BROWSE_RAW_SIZE') set_config('MNE_BROWSE_RAW_SIZE', cfg_value) fig = raw.plot() # 8 × 8 inches is default minimum size assert_array_equal(fig.get_size_inches(), (8, 8)) set_config('MNE_BROWSE_RAW_SIZE', old_cfg)
def test_config(): """Test mne-python config file support.""" tempdir = _TempDir() key = '_MNE_PYTHON_CONFIG_TESTING' value = '123456' old_val = os.getenv(key, None) os.environ[key] = value assert_true(get_config(key) == value) del os.environ[key] # catch the warning about it being a non-standard config key assert_true(len(set_config(None, None)) > 10) # tuple of valid keys with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') set_config(key, None, home_dir=tempdir, set_env=False) assert_true(len(w) == 1) assert_true(get_config(key, home_dir=tempdir) is None) assert_raises(KeyError, get_config, key, raise_error=True) with warnings.catch_warnings(record=True): warnings.simplefilter('always') assert_true(key not in os.environ) set_config(key, value, home_dir=tempdir, set_env=True) assert_true(key in os.environ) assert_true(get_config(key, home_dir=tempdir) == value) set_config(key, None, home_dir=tempdir, set_env=True) assert_true(key not in os.environ) set_config(key, None, home_dir=tempdir, set_env=True) assert_true(key not in os.environ) if old_val is not None: os.environ[key] = old_val # Check if get_config with no input returns all config key = 'MNE_PYTHON_TESTING_KEY' config = {key: value} with warnings.catch_warnings(record=True): # non-standard key warnings.simplefilter('always') set_config(key, value, home_dir=tempdir) assert_equal(get_config(home_dir=tempdir), config) # Check what happens when we use a corrupted file json_fname = get_config_path(home_dir=tempdir) with open(json_fname, 'w') as fid: fid.write('foo{}') with warnings.catch_warnings(record=True) as w: assert_equal(get_config(home_dir=tempdir), dict()) assert_true(any('not a valid JSON' in str(ww.message) for ww in w)) with warnings.catch_warnings(record=True) as w: # non-standard key assert_raises(RuntimeError, set_config, key, 'true', home_dir=tempdir)
def test_min_window_size(raw, cfg_value, browser_backend): """Test minimum window plot size.""" old_cfg = get_config('MNE_BROWSE_RAW_SIZE') set_config('MNE_BROWSE_RAW_SIZE', cfg_value) fig = raw.plot() # For an unknown reason, the Windows-CI is a bit off # (on local Windows 10 the size is exactly as expected). atol = 0 if not os.name == 'nt' else 0.2 # 8 × 8 inches is default minimum size. assert_allclose(fig._get_size(), (8, 8), atol=atol) set_config('MNE_BROWSE_RAW_SIZE', old_cfg)
def test_config(): """Test mne-python config file support.""" tempdir = _TempDir() key = '_MNE_PYTHON_CONFIG_TESTING' value = '123456' value2 = '123' old_val = os.getenv(key, None) os.environ[key] = value assert (get_config(key) == value) del os.environ[key] # catch the warning about it being a non-standard config key assert (len(set_config(None, None)) > 10) # tuple of valid keys with warnings.catch_warnings(record=True) as w: # non-standard key warnings.simplefilter('always') set_config(key, None, home_dir=tempdir, set_env=False) assert (len(w) == 1) assert (get_config(key, home_dir=tempdir) is None) pytest.raises(KeyError, get_config, key, raise_error=True) with warnings.catch_warnings(record=True): # non-standard key warnings.simplefilter('always') assert (key not in os.environ) set_config(key, value, home_dir=tempdir, set_env=True) assert (key in os.environ) assert (get_config(key, home_dir=tempdir) == value) set_config(key, None, home_dir=tempdir, set_env=True) assert (key not in os.environ) set_config(key, None, home_dir=tempdir, set_env=True) assert (key not in os.environ) if old_val is not None: os.environ[key] = old_val # Check if get_config with key=None returns all config key = 'MNE_PYTHON_TESTING_KEY' assert key not in get_config(home_dir=tempdir) with warnings.catch_warnings(record=True): # non-standard key warnings.simplefilter('always') set_config(key, value, home_dir=tempdir) assert_equal(get_config(home_dir=tempdir)[key], value) old_val = os.environ.get(key) try: # os.environ should take precedence over config file os.environ[key] = value2 assert_equal(get_config(home_dir=tempdir)[key], value2) finally: # reset os.environ if old_val is None: os.environ.pop(key, None) else: os.environ[key] = old_val # Check what happens when we use a corrupted file json_fname = get_config_path(home_dir=tempdir) with open(json_fname, 'w') as fid: fid.write('foo{}') with warnings.catch_warnings(record=True) as w: assert key not in get_config(home_dir=tempdir) assert (any('not a valid JSON' in str(ww.message) for ww in w)) with warnings.catch_warnings(record=True): # non-standard key pytest.raises(RuntimeError, set_config, key, 'true', home_dir=tempdir)
def forward_pipeline(raw_fname, subject, fwd_fname=None, trans_fname=None, subjects_dir=None, overwrite=False, ignore_ref=True): import os.path as op from mne.utils import get_config if subjects_dir is None: subjects_dir = get_config('SUBJECTS_DIR') # Setup paths save_dir = raw_fname.split('/') save_dir = ('/'.join(save_dir[:-1]) if isinstance(save_dir, list) else save_dir) bem_dir = op.join(subjects_dir, subject, 'bem') bem_sol_fname = op.join(subjects_dir, subject, 'bem', subject + '-5120-bem-sol.fif') oct_fname = op.join(subjects_dir, subject, 'bem', subject + '-oct-6-src.fif') src_fname = op.join(bem_dir, subject + '-oct-6-src.fif') bem_sol_fname = op.join(bem_dir, subject + '-5120-bem-sol.fif') if trans_fname is None: trans_fname = op.join(save_dir, subject + '-trans.fif') if fwd_fname is None: fwd_fname = op.join(save_dir, subject + '-meg-fwd.fif') # 0. Checks Freesurfer segmentation and compute watershed bem miss_anatomy = not op.isfile(src_fname) or not op.exists(bem_sol_fname) for fname in [bem_sol_fname, oct_fname]: if not op.isfile(op.join(subjects_dir, subject, 'bem', fname)): miss_anatomy = True if miss_anatomy: raise RuntimeError('Could not find BEM (%s, %s), relaunch ' 'pipeline_anatomy()' % (bem_sol_fname, oct_fname)) # 1. Manual coregisteration head markers with coils if not op.isfile(trans_fname): raise RuntimeError('Could not find trans (%s), launch' 'coregistration.' % trans_fname) # 2. Forward solution if overwrite or not op.isfile(fwd_fname): from mne import (make_forward_solution, convert_forward_solution, write_forward_solution) fwd = make_forward_solution( info=raw_fname, trans=trans_fname, src=oct_fname, bem=bem_sol_fname, fname=None, meg=True, eeg=False, mindist=5.0, overwrite=True, ignore_ref=ignore_ref) # Convert to surface orientation for better visualization fwd = convert_forward_solution(fwd, surf_ori=True) # save write_forward_solution(fwd_fname, fwd, overwrite=True) return
def test_config(): """Test mne-python config file support.""" tempdir = _TempDir() key = '_MNE_PYTHON_CONFIG_TESTING' value = '123456' value2 = '123' old_val = os.getenv(key, None) os.environ[key] = value assert (get_config(key) == value) del os.environ[key] # catch the warning about it being a non-standard config key assert (len(set_config(None, None)) > 10) # tuple of valid keys with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, None, home_dir=tempdir, set_env=False) assert (get_config(key, home_dir=tempdir) is None) pytest.raises(KeyError, get_config, key, raise_error=True) assert (key not in os.environ) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, value, home_dir=tempdir, set_env=True) assert (key in os.environ) assert (get_config(key, home_dir=tempdir) == value) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, None, home_dir=tempdir, set_env=True) assert (key not in os.environ) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, None, home_dir=tempdir, set_env=True) assert (key not in os.environ) if old_val is not None: os.environ[key] = old_val # Check if get_config with key=None returns all config key = 'MNE_PYTHON_TESTING_KEY' assert key not in get_config(home_dir=tempdir) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, value, home_dir=tempdir) assert_equal(get_config(home_dir=tempdir)[key], value) old_val = os.environ.get(key) try: # os.environ should take precedence over config file os.environ[key] = value2 assert_equal(get_config(home_dir=tempdir)[key], value2) finally: # reset os.environ if old_val is None: os.environ.pop(key, None) else: os.environ[key] = old_val # Check what happens when we use a corrupted file json_fname = get_config_path(home_dir=tempdir) with open(json_fname, 'w') as fid: fid.write('foo{}') with pytest.warns(RuntimeWarning, match='not a valid JSON'): assert key not in get_config(home_dir=tempdir) with pytest.warns(RuntimeWarning, match='non-standard'): pytest.raises(RuntimeError, set_config, key, 'true', home_dir=tempdir)
def anatomy_pipeline(subject, subjects_dir=None, overwrite=False): from mne.bem import make_watershed_bem from mne.commands.mne_make_scalp_surfaces import _run as make_scalp_surface from mne.utils import get_config if subjects_dir is None: subjects_dir = get_config('SUBJECTS_DIR') # Set file name ---------------------------------------------------------- bem_dir = op.join(subjects_dir, subject, 'bem') src_fname = op.join(bem_dir, subject + '-oct-6-src.fif') bem_fname = op.join(bem_dir, subject + '-5120-bem.fif') bem_sol_fname = op.join(bem_dir, subject + '-5120-bem-sol.fif') # 0. Create watershed BEM surfaces if overwrite or not op.isfile(op.join(bem_dir, subject + '-head.fif')): check_libraries() if not check_freesurfer(subjects_dir=subjects_dir, subject=subject): warnings.warn('%s is probably not segmented correctly, check ' 'log.' % subject) make_watershed_bem(subject=subject, subjects_dir=subjects_dir, overwrite=True, volume='T1', atlas=False, gcaatlas=False, preflood=None) # 1. Make scalp surfaces miss_surface = False # make_scalp is only for outer_skin for part in ['brain', 'inner_skull', 'outer_skin', 'outer_skull']: fname = op.join( bem_dir, 'watershed', '%s_%s_surface' % (subject, part)) if not op.isfile(fname): miss_surface = True if overwrite or miss_surface: make_scalp_surface(subjects_dir=subjects_dir, subject=subject, force=True, overwrite=True, verbose=None) # 2. Copy files outside watershed folder in case of bad manipulation miss_surface_copy = False for surface in ['inner_skull', 'outer_skull', 'outer_skin']: fname = op.join(bem_dir, '%s.surf' % surface) if not op.isfile(fname): miss_surface_copy = True if overwrite or miss_surface_copy: for surface in ['inner_skull', 'outer_skull', 'outer_skin']: from shutil import copyfile from_file = op.join(bem_dir, 'watershed/%s_%s_surface' % (subject, surface)) to_file = op.join(bem_dir, '%s.surf' % surface) if op.exists(to_file): os.remove(to_file) copyfile(from_file, to_file) # 3. Setup source space if overwrite or not op.isfile(src_fname): from mne import setup_source_space, write_source_spaces check_libraries() files = ['lh.white', 'rh.white', 'lh.sphere', 'rh.sphere'] for fname in files: if not op.exists(op.join(subjects_dir, subject, 'surf', fname)): raise RuntimeError('missing: %s' % fname) src = setup_source_space(subject=subject, subjects_dir=subjects_dir, spacing='oct6', surface='white', add_dist=True, n_jobs=-1, verbose=None) write_source_spaces(src_fname, src) # 4. Prepare BEM model if overwrite or not op.exists(bem_sol_fname): from mne.bem import (make_bem_model, write_bem_surfaces, make_bem_solution, write_bem_solution) check_libraries() surfs = make_bem_model(subject=subject, subjects_dir=subjects_dir) write_bem_surfaces(fname=bem_fname, surfs=surfs) bem = make_bem_solution(surfs) write_bem_solution(fname=bem_sol_fname, bem=bem)
def test_config(tmp_path): """Test mne-python config file support.""" tempdir = str(tmp_path) key = '_MNE_PYTHON_CONFIG_TESTING' value = '123456' value2 = '123' value3 = Path('/foo/bar') old_val = os.getenv(key, None) os.environ[key] = value assert (get_config(key) == value) del os.environ[key] # catch the warning about it being a non-standard config key assert (len(get_config('')) > 10) # tuple of valid keys with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, None, home_dir=tempdir, set_env=False) assert (get_config(key, home_dir=tempdir) is None) pytest.raises(KeyError, get_config, key, raise_error=True) assert (key not in os.environ) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, value, home_dir=tempdir, set_env=True) assert (key in os.environ) assert (get_config(key, home_dir=tempdir) == value) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, None, home_dir=tempdir, set_env=True) assert (key not in os.environ) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, None, home_dir=tempdir, set_env=True) assert (key not in os.environ) if old_val is not None: os.environ[key] = old_val # Check serialization from Path to string with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, value3, home_dir=tempdir) # Check if get_config with key=None returns all config key = 'MNE_PYTHON_TESTING_KEY' assert key not in get_config(home_dir=tempdir) with pytest.warns(RuntimeWarning, match='non-standard'): set_config(key, value, home_dir=tempdir) assert get_config(home_dir=tempdir)[key] == value old_val = os.environ.get(key) try: # os.environ should take precedence over config file os.environ[key] = value2 assert get_config(home_dir=tempdir)[key] == value2 finally: # reset os.environ if old_val is None: os.environ.pop(key, None) else: os.environ[key] = old_val # Check what happens when we use a corrupted file json_fname = get_config_path(home_dir=tempdir) with open(json_fname, 'w') as fid: fid.write('foo{}') with pytest.warns(RuntimeWarning, match='not a valid JSON'): assert key not in get_config(home_dir=tempdir) with pytest.warns(RuntimeWarning, match='non-standard'): pytest.raises(RuntimeError, set_config, key, 'true', home_dir=tempdir) # degenerate conditions pytest.raises(ValueError, set_memmap_min_size, 1) pytest.raises(ValueError, set_memmap_min_size, 'foo') pytest.raises(TypeError, get_config, 1) pytest.raises(TypeError, set_config, 1) pytest.raises(TypeError, set_config, 'foo', 1) pytest.raises(TypeError, _get_stim_channel, 1, None) pytest.raises(TypeError, _get_stim_channel, [1], None)
def test_coreg_gui_pyvista_basic(tmp_path, renderer_interactive_pyvistaqt, monkeypatch): """Test that using CoregistrationUI matches mne coreg.""" from mne.gui import coregistration config = get_config() # the sample subject in testing has MRI fids assert op.isfile( op.join(subjects_dir, 'sample', 'bem', 'sample-fiducials.fif')) coreg = coregistration(subject='sample', subjects_dir=subjects_dir, trans=fname_trans) assert coreg._lock_fids coreg._reset_fiducials() coreg.close() # make it always log the distances monkeypatch.setattr(_3d.logger, 'info', _3d.logger.warning) with catch_logging() as log: coreg = coregistration( inst=raw_path, subject='sample', head_high_res=False, # for speed subjects_dir=subjects_dir, verbose='debug') log = log.getvalue() assert 'Total 16/78 points inside the surface' in log coreg._set_fiducials_file(fid_fname) assert coreg._fiducials_file == fid_fname # fitting (with scaling) assert not coreg._mri_scale_modified coreg._reset() coreg._reset_fitting_parameters() coreg._set_scale_mode("uniform") coreg._fits_fiducials() assert_allclose(coreg.coreg._scale, np.array([97.46, 97.46, 97.46]) * 1e-2, atol=1e-3) shown_scale = [coreg._widgets[f's{x}'].get_value() for x in 'XYZ'] assert_allclose(shown_scale, coreg.coreg._scale * 100, atol=1e-2) coreg._set_icp_fid_match("nearest") coreg._set_scale_mode("3-axis") coreg._fits_icp() assert_allclose(coreg.coreg._scale, np.array([104.43, 101.47, 125.78]) * 1e-2, atol=1e-3) shown_scale = [coreg._widgets[f's{x}'].get_value() for x in 'XYZ'] assert_allclose(shown_scale, coreg.coreg._scale * 100, atol=1e-2) coreg._set_scale_mode("None") coreg._set_icp_fid_match("matched") assert coreg._mri_scale_modified # unlock fiducials assert coreg._lock_fids coreg._set_lock_fids(False) assert not coreg._lock_fids # picking assert not coreg._mri_fids_modified vtk_picker = TstVTKPicker(coreg._surfaces['head'], 0, (0, 0)) coreg._on_mouse_move(vtk_picker, None) coreg._on_button_press(vtk_picker, None) coreg._on_pick(vtk_picker, None) coreg._on_button_release(vtk_picker, None) coreg._on_pick(vtk_picker, None) # also pick when locked assert coreg._mri_fids_modified # lock fiducials coreg._set_lock_fids(True) assert coreg._lock_fids # fitting (no scaling) assert coreg._nasion_weight == 10. coreg._set_point_weight(11., 'nasion') assert coreg._nasion_weight == 11. coreg._fit_fiducials() with catch_logging() as log: coreg._redraw() # actually emit the log log = log.getvalue() assert 'Total 6/78 points inside the surface' in log with catch_logging() as log: coreg._fit_icp() coreg._redraw() log = log.getvalue() assert 'Total 38/78 points inside the surface' in log assert coreg.coreg._extra_points_filter is None coreg._omit_hsp() with catch_logging() as log: coreg._redraw() log = log.getvalue() assert 'Total 29/53 points inside the surface' in log assert coreg.coreg._extra_points_filter is not None coreg._reset_omit_hsp_filter() with catch_logging() as log: coreg._redraw() log = log.getvalue() assert 'Total 38/78 points inside the surface' in log assert coreg.coreg._extra_points_filter is None assert coreg._grow_hair == 0 coreg._fit_fiducials() # go back to few inside to start with catch_logging() as log: coreg._redraw() log = log.getvalue() assert 'Total 6/78 points inside the surface' in log norm = np.linalg.norm(coreg._head_geo['rr']) # what's used for inside assert_allclose(norm, 5.949288, atol=1e-3) coreg._set_grow_hair(20.0) with catch_logging() as log: coreg._redraw() assert coreg._grow_hair == 20.0 norm = np.linalg.norm(coreg._head_geo['rr']) assert_allclose(norm, 6.555220, atol=1e-3) # outward log = log.getvalue() assert 'Total 8/78 points inside the surface' in log # more outside now # visualization assert not coreg._helmet coreg._set_helmet(True) assert coreg._helmet assert coreg._orient_glyphs assert coreg._scale_by_distance assert coreg._mark_inside assert_allclose(coreg._head_opacity, float(config.get('MNE_COREG_HEAD_OPACITY', '0.8'))) assert coreg._hpi_coils assert coreg._eeg_channels assert coreg._head_shape_points assert coreg._scale_mode == 'None' assert coreg._icp_fid_match == 'matched' assert coreg._head_resolution is False assert coreg._trans_modified tmp_trans = tmp_path / 'tmp-trans.fif' coreg._save_trans(tmp_trans) assert not coreg._trans_modified assert op.isfile(tmp_trans) # first, disable auto cleanup coreg._renderer._window_close_disconnect(after=True) # test _close_callback() coreg.close() coreg._widgets['close_dialog'].trigger('Discard') # do not save coreg._clean() # finally, cleanup internal structures # Coregistration instance should survive assert isinstance(coreg.coreg, Coregistration) # Fullscreen mode coreg = coregistration(subject='sample', subjects_dir=subjects_dir, fullscreen=True)
def test_coreg_gui_pyvista(tmp_path, renderer_interactive_pyvistaqt): """Test that using CoregistrationUI matches mne coreg.""" from mne.gui import coregistration config = get_config(home_dir=os.environ.get('_MNE_FAKE_HOME_DIR')) tmp_trans = tmp_path / 'tmp-trans.fif' # the sample subject in testing has MRI fids assert op.isfile( op.join(subjects_dir, 'sample', 'bem', 'sample-fiducials.fif')) coreg = coregistration(subject='sample', subjects_dir=subjects_dir, trans=fname_trans) assert coreg._lock_fids coreg._reset_fiducials() coreg.close() coreg = coregistration(inst=raw_path, subject='sample', subjects_dir=subjects_dir) coreg._set_fiducials_file(fid_fname) assert coreg._fiducials_file == fid_fname # unlock fiducials assert coreg._lock_fids coreg._set_lock_fids(False) assert not coreg._lock_fids # picking vtk_picker = TstVTKPicker(coreg._surfaces['head'], 0, (0, 0)) coreg._on_mouse_move(vtk_picker, None) coreg._on_button_press(vtk_picker, None) coreg._on_pick(vtk_picker, None) coreg._on_button_release(vtk_picker, None) coreg._on_pick(vtk_picker, None) # also pick when locked # lock fiducials coreg._set_lock_fids(True) assert coreg._lock_fids # fitting assert coreg._nasion_weight == 10. coreg._set_point_weight(11., 'nasion') assert coreg._nasion_weight == 11. coreg._fit_fiducials() coreg._fit_icp() assert coreg._coreg._extra_points_filter is None coreg._omit_hsp() assert coreg._coreg._extra_points_filter is not None coreg._reset_omit_hsp_filter() assert coreg._coreg._extra_points_filter is None assert coreg._grow_hair == 0 coreg._set_grow_hair(0.1) assert coreg._grow_hair == 0.1 # visualization assert coreg._orient_glyphs == \ (config.get('MNE_COREG_ORIENT_TO_SURFACE', '') == 'true') assert coreg._hpi_coils assert coreg._eeg_channels assert coreg._head_shape_points assert coreg._scale_mode == 'None' assert coreg._icp_fid_match == 'nearest' assert coreg._head_resolution == \ (config.get('MNE_COREG_HEAD_HIGH_RES', 'true') == 'true') assert not coreg._head_transparency coreg._set_head_transparency(True) assert coreg._head_transparency coreg._save_trans(tmp_trans) assert op.isfile(tmp_trans) coreg.close()
def _prepare_mne_browse_epochs(params, projs, n_channels, n_epochs, scalings, title, picks, order=None): """Helper for setting up the mne_browse_epochs window.""" import matplotlib.pyplot as plt import matplotlib as mpl from matplotlib.collections import LineCollection from matplotlib.colors import colorConverter epochs = params['epochs'] if picks is None: picks = _handle_picks(epochs) if len(picks) < 1: raise RuntimeError('No appropriate channels found. Please' ' check your picks') picks = sorted(picks) # Reorganize channels inds = list() types = list() for t in ['grad', 'mag']: idxs = pick_types(params['info'], meg=t, ref_meg=False, exclude=[]) if len(idxs) < 1: continue mask = np.in1d(idxs, picks, assume_unique=True) inds.append(idxs[mask]) types += [t] * len(inds[-1]) pick_kwargs = dict(meg=False, ref_meg=False, exclude=[]) if order is None: order = ['eeg', 'seeg', 'ecog', 'eog', 'ecg', 'emg', 'ref_meg', 'stim', 'resp', 'misc', 'chpi', 'syst', 'ias', 'exci'] for ch_type in order: pick_kwargs[ch_type] = True idxs = pick_types(params['info'], **pick_kwargs) if len(idxs) < 1: continue mask = np.in1d(idxs, picks, assume_unique=True) inds.append(idxs[mask]) types += [ch_type] * len(inds[-1]) pick_kwargs[ch_type] = False inds = np.concatenate(inds).astype(int) if not len(inds) == len(picks): raise RuntimeError('Some channels not classified. Please' ' check your picks') ch_names = [params['info']['ch_names'][x] for x in inds] # set up plotting size = get_config('MNE_BROWSE_RAW_SIZE') n_epochs = min(n_epochs, len(epochs.events)) duration = len(epochs.times) * n_epochs n_channels = min(n_channels, len(picks)) if size is not None: size = size.split(',') size = tuple(float(s) for s in size) if title is None: title = epochs.name if epochs.name is None or len(title) == 0: title = '' fig = figure_nobar(facecolor='w', figsize=size, dpi=80) fig.canvas.set_window_title('mne_browse_epochs') ax = plt.subplot2grid((10, 15), (0, 1), colspan=13, rowspan=9) ax.annotate(title, xy=(0.5, 1), xytext=(0, ax.get_ylim()[1] + 15), ha='center', va='bottom', size=12, xycoords='axes fraction', textcoords='offset points') color = _handle_default('color', None) ax.axis([0, duration, 0, 200]) ax2 = ax.twiny() ax2.set_zorder(-1) ax2.axis([0, duration, 0, 200]) ax_hscroll = plt.subplot2grid((10, 15), (9, 1), colspan=13) ax_hscroll.get_yaxis().set_visible(False) ax_hscroll.set_xlabel('Epochs') ax_vscroll = plt.subplot2grid((10, 15), (0, 14), rowspan=9) ax_vscroll.set_axis_off() ax_vscroll.add_patch(mpl.patches.Rectangle((0, 0), 1, len(picks), facecolor='w', zorder=3)) ax_help_button = plt.subplot2grid((10, 15), (9, 0), colspan=1) help_button = mpl.widgets.Button(ax_help_button, 'Help') help_button.on_clicked(partial(_onclick_help, params=params)) # populate vertical and horizontal scrollbars for ci in range(len(picks)): if ch_names[ci] in params['info']['bads']: this_color = params['bad_color'] else: this_color = color[types[ci]] ax_vscroll.add_patch(mpl.patches.Rectangle((0, ci), 1, 1, facecolor=this_color, edgecolor=this_color, zorder=4)) vsel_patch = mpl.patches.Rectangle((0, 0), 1, n_channels, alpha=0.5, edgecolor='w', facecolor='w', zorder=5) ax_vscroll.add_patch(vsel_patch) ax_vscroll.set_ylim(len(types), 0) ax_vscroll.set_title('Ch.') # populate colors list type_colors = [colorConverter.to_rgba(color[c]) for c in types] colors = list() for color_idx in range(len(type_colors)): colors.append([type_colors[color_idx]] * len(epochs.events)) lines = list() n_times = len(epochs.times) for ch_idx in range(n_channels): if len(colors) - 1 < ch_idx: break lc = LineCollection(list(), antialiased=False, linewidths=0.5, zorder=3, picker=3.) ax.add_collection(lc) lines.append(lc) times = epochs.times data = np.zeros((params['info']['nchan'], len(times) * n_epochs)) ylim = (25., 0.) # Hardcoded 25 because butterfly has max 5 rows (5*5=25). # make shells for plotting traces offset = ylim[0] / n_channels offsets = np.arange(n_channels) * offset + (offset / 2.) times = np.arange(len(times) * len(epochs.events)) epoch_times = np.arange(0, len(times), n_times) ax.set_yticks(offsets) ax.set_ylim(ylim) ticks = epoch_times + 0.5 * n_times ax.set_xticks(ticks) ax2.set_xticks(ticks[:n_epochs]) labels = list(range(1, len(ticks) + 1)) # epoch numbers ax.set_xticklabels(labels) ax2.set_xticklabels(labels) xlim = epoch_times[-1] + len(epochs.times) ax_hscroll.set_xlim(0, xlim) vertline_t = ax_hscroll.text(0, 1, '', color='y', va='bottom', ha='right') # fit horizontal scroll bar ticks hscroll_ticks = np.arange(0, xlim, xlim / 7.0) hscroll_ticks = np.append(hscroll_ticks, epoch_times[-1]) hticks = list() for tick in hscroll_ticks: hticks.append(epoch_times.flat[np.abs(epoch_times - tick).argmin()]) hlabels = [x / n_times + 1 for x in hticks] ax_hscroll.set_xticks(hticks) ax_hscroll.set_xticklabels(hlabels) for epoch_idx in range(len(epoch_times)): ax_hscroll.add_patch(mpl.patches.Rectangle((epoch_idx * n_times, 0), n_times, 1, facecolor=(0.8, 0.8, 0.8), edgecolor=(0.8, 0.8, 0.8), alpha=0.5)) hsel_patch = mpl.patches.Rectangle((0, 0), duration, 1, edgecolor='k', facecolor=(0.5, 0.5, 0.5), alpha=0.25, linewidth=1, clip_on=False) ax_hscroll.add_patch(hsel_patch) text = ax.text(0, 0, 'blank', zorder=3, verticalalignment='baseline', ha='left', fontweight='bold') text.set_visible(False) params.update({'fig': fig, 'ax': ax, 'ax2': ax2, 'ax_hscroll': ax_hscroll, 'ax_vscroll': ax_vscroll, 'vsel_patch': vsel_patch, 'hsel_patch': hsel_patch, 'lines': lines, 'projs': projs, 'ch_names': ch_names, 'n_channels': n_channels, 'n_epochs': n_epochs, 'scalings': scalings, 'duration': duration, 'ch_start': 0, 'colors': colors, 'def_colors': type_colors, # don't change at runtime 'picks': picks, 'data': data, 'times': times, 'epoch_times': epoch_times, 'offsets': offsets, 'labels': labels, 'scale_factor': 1.0, 'butterfly_scale': 1.0, 'fig_proj': None, 'types': np.array(types), 'inds': inds, 'vert_lines': list(), 'vertline_t': vertline_t, 'butterfly': False, 'text': text, 'ax_help_button': ax_help_button, # needed for positioning 'help_button': help_button, # reference needed for clicks 'fig_options': None, 'settings': [True, True, True, True], 'image_plot': None}) params['plot_fun'] = partial(_plot_traces, params=params) # callbacks callback_scroll = partial(_plot_onscroll, params=params) fig.canvas.mpl_connect('scroll_event', callback_scroll) callback_click = partial(_mouse_click, params=params) fig.canvas.mpl_connect('button_press_event', callback_click) callback_key = partial(_plot_onkey, params=params) fig.canvas.mpl_connect('key_press_event', callback_key) callback_resize = partial(_resize_event, params=params) fig.canvas.mpl_connect('resize_event', callback_resize) fig.canvas.mpl_connect('pick_event', partial(_onpick, params=params)) params['callback_key'] = callback_key # Draw event lines for the first time. _plot_vert_lines(params) # Plot bad epochs for epoch_idx in params['bads']: params['ax_hscroll'].patches[epoch_idx].set_color((1., 0., 0., 1.)) params['ax_hscroll'].patches[epoch_idx].set_zorder(3) params['ax_hscroll'].patches[epoch_idx].set_edgecolor('w') for ch_idx in range(len(params['ch_names'])): params['colors'][ch_idx][epoch_idx] = (1., 0., 0., 1.) assert params['fix_log'].shape == (len(epochs.events), len(params['ch_names'])) # Plot bad segments if params['fix_log'] is not None: for ch_idx in range(len(params['ch_names'])): for epoch_idx in range(len(epochs.events)): this_log = params['fix_log'][epoch_idx, ch_idx] if epoch_idx in params['bads']: pass else: if this_log == 1: params['colors'][ch_idx][epoch_idx] = (1., 0., 0., 1.) elif this_log == 2: params['colors'][ch_idx][epoch_idx] = (0., 0., 1., 1.) params['plot_fun']()
def create_bem_surf(subject, subjects_dir=None, overwrite=False): # from jr.meg # noqa # from mne.bem import make_watershed_bem # from mne.commands.mne_make_scalp_surfaces import _run as make_scalp_surface from mne.utils import get_config if subjects_dir is None: subjects_dir = get_config('SUBJECTS_DIR') # Set file name ---------------------------------------------------------- bem_dir = op.join(subjects_dir, subject, 'bem') src_fname = op.join(bem_dir, subject + '-oct-6-src.fif') bem_fname = op.join(bem_dir, subject + '-5120-bem.fif') bem_sol_fname = op.join(bem_dir, subject + '-5120-bem-sol.fif') # Skip make_watershed_bem and make_scalp_surface because it is # already done from bash shell (freesurfer command) miss_surface_copy = False for surface in ['inner_skull', 'outer_skull', 'outer_skin']: fname = op.join(bem_dir, '%s.surf' % surface) if not op.isfile(fname): miss_surface_copy = True if overwrite or miss_surface_copy: for surface in ['inner_skull', 'outer_skull', 'outer_skin']: from shutil import copyfile from_file = op.join(bem_dir, 'watershed/%s_%s_surface' % (subject, surface)) to_file = op.join(bem_dir, '%s.surf' % surface) if op.exists(to_file): os.remove(to_file) copyfile(from_file, to_file) # 3. Setup source space if overwrite or not op.isfile(src_fname): from mne import setup_source_space check_libraries() files = ['lh.white', 'rh.white', 'lh.sphere', 'rh.sphere'] for fname in files: if not op.exists(op.join(subjects_dir, subject, 'surf', fname)): raise RuntimeError('missing: %s' % fname) setup_source_space(subject=subject, subjects_dir=subjects_dir, fname=src_fname, spacing='oct6', surface='white', overwrite=True, add_dist=True, n_jobs=-1, verbose=None) # 4. Prepare BEM model if overwrite or not op.exists(bem_sol_fname): from mne.bem import (make_bem_model, write_bem_surfaces, make_bem_solution, write_bem_solution) check_libraries() # run with a single layer model (enough for MEG data) surfs = make_bem_model(subject, conductivity=[0.3], subjects_dir=subjects_dir) # surfs = make_bem_model(subject=subject, subjects_dir=subjects_dir) write_bem_surfaces(fname=bem_fname, surfs=surfs) bem = make_bem_solution(surfs) write_bem_solution(fname=bem_sol_fname, bem=bem)
def test_coreg_gui_pyvista(tmp_path, renderer_interactive_pyvistaqt): """Test that using CoregistrationUI matches mne coreg.""" from mne.gui import coregistration from mne.gui._coreg import CoregistrationUI config = get_config(home_dir=os.environ.get('_MNE_FAKE_HOME_DIR')) # the sample subject in testing has MRI fids assert op.isfile( op.join(subjects_dir, 'sample', 'bem', 'sample-fiducials.fif')) deprecated_params = ['standalone', 'head_transparency', 'project_eeg'] for param in deprecated_params: kwargs = {p: None for p in deprecated_params} kwargs[param] = True with pytest.warns(DeprecationWarning, match=f'{param} is deprecated'): coreg = CoregistrationUI(info_file=None, subject='sample', subjects_dir=subjects_dir, **kwargs) coreg.close() del kwargs deprecated_params = ['project_eeg'] for param in deprecated_params: kwargs = {p: None for p in deprecated_params} kwargs[param] = True with pytest.warns(DeprecationWarning, match=f'{param} is deprecated'): coreg = coregistration(subject='sample', subjects_dir=subjects_dir, **kwargs) coreg.close() del kwargs coreg = coregistration(subject='sample', subjects_dir=subjects_dir, trans=fname_trans) assert coreg._lock_fids coreg._reset_fiducials() coreg.close() coreg = coregistration(inst=raw_path, subject='sample', subjects_dir=subjects_dir) coreg._set_fiducials_file(fid_fname) assert coreg._fiducials_file == fid_fname # fitting (with scaling) assert not coreg._mri_scale_modified coreg._reset() coreg._reset_fitting_parameters() coreg._set_scale_mode("uniform") coreg._fits_fiducials() assert_allclose(coreg.coreg._scale, np.array([97.46, 97.46, 97.46]) * 1e-2, atol=1e-3) coreg._set_icp_fid_match("nearest") coreg._set_scale_mode("3-axis") coreg._fits_icp() assert_allclose(coreg.coreg._scale, np.array([104.43, 101.47, 125.78]) * 1e-2, atol=1e-3) coreg._set_scale_mode("None") coreg._set_icp_fid_match("matched") assert coreg._mri_scale_modified # unlock fiducials assert coreg._lock_fids coreg._set_lock_fids(False) assert not coreg._lock_fids # picking assert not coreg._mri_fids_modified vtk_picker = TstVTKPicker(coreg._surfaces['head'], 0, (0, 0)) coreg._on_mouse_move(vtk_picker, None) coreg._on_button_press(vtk_picker, None) coreg._on_pick(vtk_picker, None) coreg._on_button_release(vtk_picker, None) coreg._on_pick(vtk_picker, None) # also pick when locked assert coreg._mri_fids_modified # lock fiducials coreg._set_lock_fids(True) assert coreg._lock_fids # fitting (no scaling) assert coreg._nasion_weight == 10. coreg._set_point_weight(11., 'nasion') assert coreg._nasion_weight == 11. coreg._fit_fiducials() coreg._fit_icp() assert coreg.coreg._extra_points_filter is None coreg._omit_hsp() assert coreg.coreg._extra_points_filter is not None coreg._reset_omit_hsp_filter() assert coreg.coreg._extra_points_filter is None assert coreg._grow_hair == 0 coreg._set_grow_hair(0.1) assert coreg._grow_hair == 0.1 # visualization assert not coreg._helmet coreg._set_helmet(True) assert coreg._helmet assert coreg._orient_glyphs assert coreg._scale_by_distance assert coreg._mark_inside assert_allclose(coreg._head_opacity, float(config.get('MNE_COREG_HEAD_OPACITY', '0.8'))) assert coreg._hpi_coils assert coreg._eeg_channels assert coreg._head_shape_points assert coreg._scale_mode == 'None' assert coreg._icp_fid_match == 'matched' assert coreg._head_resolution == \ (config.get('MNE_COREG_HEAD_HIGH_RES', 'true') == 'true') assert coreg._trans_modified tmp_trans = tmp_path / 'tmp-trans.fif' coreg._save_trans(tmp_trans) assert not coreg._trans_modified assert op.isfile(tmp_trans) # first, disable auto cleanup coreg._renderer._window_close_disconnect(after=True) # test _close_callback() coreg.close() coreg._widgets['close_dialog'].trigger('Discard') # do not save coreg._clean() # finally, cleanup internal structures # Coregistration instance should survive assert isinstance(coreg.coreg, Coregistration)
def anatomy_pipeline(subject, subjects_dir=None, overwrite=False): from mne.bem import make_watershed_bem from mne.commands.mne_make_scalp_surfaces import _run as make_scalp_surface from mne.utils import get_config if subjects_dir is None: subjects_dir = get_config('SUBJECTS_DIR') # Set file name ---------------------------------------------------------- bem_dir = op.join(subjects_dir, subject, 'bem') src_fname = op.join(bem_dir, subject + '-oct-6-src.fif') bem_fname = op.join(bem_dir, subject + '-5120-bem.fif') bem_sol_fname = op.join(bem_dir, subject + '-5120-bem-sol.fif') # 0. Create watershed BEM surfaces if overwrite or not op.isfile(op.join(bem_dir, subject + '-head.fif')): check_libraries() if not check_freesurfer(subjects_dir=subjects_dir, subject=subject): warnings.warn('%s is probably not segmented correctly, check ' 'log.' % subject) make_watershed_bem(subject=subject, subjects_dir=subjects_dir, overwrite=True, volume='T1', atlas=False, gcaatlas=False, preflood=None) # 1. Make scalp surfaces miss_surface = False # make_scalp is only for outer_skin for part in ['brain', 'inner_skull', 'outer_skin', 'outer_skull']: fname = op.join( bem_dir, 'watershed', '%s_%s_surface' % (subject, part)) if not op.isfile(fname): miss_surface = True if overwrite or miss_surface: make_scalp_surface(subjects_dir=subjects_dir, subject=subject, force=True, overwrite=True, verbose=None) # 2. Copy files outside watershed folder in case of bad manipulation miss_surface_copy = False for surface in ['inner_skull', 'outer_skull', 'outer_skin']: fname = op.join(bem_dir, '%s.surf' % surface) if not op.isfile(fname): miss_surface_copy = True if overwrite or miss_surface_copy: for surface in ['inner_skull', 'outer_skull', 'outer_skin']: from shutil import copyfile from_file = op.join(bem_dir, 'watershed/%s_%s_surface' % (subject, surface)) to_file = op.join(bem_dir, '%s.surf' % surface) if op.exists(to_file): os.remove(to_file) copyfile(from_file, to_file) # 3. Setup source space if overwrite or not op.isfile(src_fname): from mne import setup_source_space check_libraries() files = ['lh.white', 'rh.white', 'lh.sphere', 'rh.sphere'] for fname in files: if not op.exists(op.join(subjects_dir, subject, 'surf', fname)): raise RuntimeError('missing: %s' % fname) setup_source_space(subject=subject, subjects_dir=subjects_dir, fname=src_fname, spacing='oct6', surface='white', overwrite=True, add_dist=True, n_jobs=-1, verbose=None) # 4. Prepare BEM model if overwrite or not op.exists(bem_sol_fname): from mne.bem import (make_bem_model, write_bem_surfaces, make_bem_solution, write_bem_solution) check_libraries() surfs = make_bem_model(subject=subject, subjects_dir=subjects_dir) write_bem_surfaces(fname=bem_fname, surfs=surfs) bem = make_bem_solution(surfs) write_bem_solution(fname=bem_sol_fname, bem=bem)