def _interpolate_bads_meg_fast(inst, picks, mode='accurate', dots=None, verbose=False): """Interpolate bad channels from data in good channels.""" # We can have pre-picked instances or not. # And we need to handle it. inst_picked = True if len(inst.ch_names) > len(picks): picked_info = pick_info(inst.info, picks) dots = _pick_dots(dots, picks, picks) inst_picked = False else: picked_info = inst.info.copy() def get_picks_bad_good(info, picks_meg): picks_good = [ p for p in picks_meg if info['ch_names'][p] not in info['bads'] ] # select the bad meg channel to be interpolated if len(info['bads']) == 0: picks_bad = [] else: picks_bad = [ p for p in picks_meg if info['ch_names'][p] in info['bads'] ] return picks_meg, picks_good, picks_bad picks_meg, picks_good, picks_bad = get_picks_bad_good( picked_info, range(picked_info['nchan'])) # return without doing anything if there are no meg channels if len(picks_meg) == 0 or len(picks_bad) == 0: return # we need to make sure that only meg channels are passed here # as the MNE interpolation code is not fogriving. # This is why we picked the info. mapping = _fast_map_meg_channels(picked_info, pick_from=picks_good, pick_to=picks_bad, dots=dots, mode=mode) # the downside is that the mapping matrix now does not match # the unpicked info of the data. # Since we may have picked the info, we need to double map # the indices. _, picks_good_, picks_bad_orig = get_picks_bad_good(inst.info, picks) ch_names_a = [picked_info['ch_names'][pp] for pp in picks_bad] ch_names_b = [inst.info['ch_names'][pp] for pp in picks_bad_orig] assert ch_names_a == ch_names_b if not inst_picked: picks_good_ = [pp for pp in picks if pp in picks_good_] assert len(picks_good_) == len(picks_good) ch_names_a = [picked_info['ch_names'][pp] for pp in picks_good] ch_names_b = [inst.info['ch_names'][pp] for pp in picks_good_] assert ch_names_a == ch_names_b _do_interp_dots(inst, mapping, picks_good_, picks_bad_orig)
def _interpolate_bads_eeg(inst, picks=None, verbose=None): """ Interpolate bad EEG channels. Operates in place. Parameters ---------- inst : mne.io.Raw, mne.Epochs or mne.Evoked The data to interpolate. Must be preloaded. picks: np.ndarray, shape(n_channels, ) | list | None The channel indices to be used for interpolation. """ from mne.bem import _fit_sphere from mne.utils import logger, warn from mne.channels.interpolation import _do_interp_dots from mne.channels.interpolation import _make_interpolation_matrix import numpy as np if picks is None: picks = pick_types(inst.info, meg=False, eeg=True, exclude=[]) bads_idx = np.zeros(len(inst.ch_names), dtype=np.bool) goods_idx = np.zeros(len(inst.ch_names), dtype=np.bool) inst.info._check_consistency() bads_idx[picks] = [inst.ch_names[ch] in inst.info['bads'] for ch in picks] if len(picks) == 0 or bads_idx.sum() == 0: return goods_idx[picks] = True goods_idx[bads_idx] = False pos = inst._get_channel_positions(picks) # Make sure only good EEG are used bads_idx_pos = bads_idx[picks] goods_idx_pos = goods_idx[picks] pos_good = pos[goods_idx_pos] pos_bad = pos[bads_idx_pos] # test spherical fit radius, center = _fit_sphere(pos_good) distance = np.sqrt(np.sum((pos_good - center)**2, 1)) distance = np.mean(distance / radius) if np.abs(1. - distance) > 0.1: warn('Your spherical fit is poor, interpolation results are ' 'likely to be inaccurate.') logger.info('Computing interpolation matrix from {0} sensor ' 'positions'.format(len(pos_good))) interpolation = _make_interpolation_matrix(pos_good, pos_bad) logger.info('Interpolating {0} sensors'.format(len(pos_bad))) _do_interp_dots(inst, interpolation, goods_idx, bads_idx)
def _interpolate_bads_eeg(inst, picks=None, verbose=None): """ Interpolate bad EEG channels. Operates in place. Parameters ---------- inst : mne.io.Raw, mne.Epochs or mne.Evoked The data to interpolate. Must be preloaded. picks: np.ndarray, shape(n_channels, ) | list | None The channel indices to be used for interpolation. """ from mne.bem import _fit_sphere from mne.utils import logger, warn from mne.channels.interpolation import _do_interp_dots from mne.channels.interpolation import _make_interpolation_matrix import numpy as np if picks is None: picks = pick_types(inst.info, meg=False, eeg=True, exclude=[]) bads_idx = np.zeros(len(inst.ch_names), dtype=np.bool) goods_idx = np.zeros(len(inst.ch_names), dtype=np.bool) inst.info._check_consistency() bads_idx[picks] = [inst.ch_names[ch] in inst.info['bads'] for ch in picks] if len(picks) == 0 or bads_idx.sum() == 0: return goods_idx[picks] = True goods_idx[bads_idx] = False pos = inst._get_channel_positions(picks) # Make sure only good EEG are used bads_idx_pos = bads_idx[picks] goods_idx_pos = goods_idx[picks] pos_good = pos[goods_idx_pos] pos_bad = pos[bads_idx_pos] # test spherical fit radius, center = _fit_sphere(pos_good) distance = np.sqrt(np.sum((pos_good - center) ** 2, 1)) distance = np.mean(distance / radius) if np.abs(1. - distance) > 0.1: warn('Your spherical fit is poor, interpolation results are ' 'likely to be inaccurate.') logger.info('Computing interpolation matrix from {0} sensor ' 'positions'.format(len(pos_good))) interpolation = _make_interpolation_matrix(pos_good, pos_bad) logger.info('Interpolating {0} sensors'.format(len(pos_bad))) _do_interp_dots(inst, interpolation, goods_idx, bads_idx)
def _interpolate_bads_meg_fast(inst, picks, mode='accurate', dots=None, verbose=None): """Interpolate bad channels from data in good channels.""" # We can have pre-picked instances or not. # And we need to handle it. inst_picked = True if len(inst.ch_names) > len(picks): picked_info = pick_info(inst.info, picks) dots = _pick_dots(dots, picks, picks) inst_picked = False else: picked_info = inst.info.copy() def get_picks_bad_good(info, picks_meg): picks_good = [p for p in picks_meg if info['ch_names'][p] not in info['bads']] # select the bad meg channel to be interpolated if len(info['bads']) == 0: picks_bad = [] else: picks_bad = [p for p in picks_meg if info['ch_names'][p] in info['bads']] return picks_meg, picks_good, picks_bad picks_meg, picks_good, picks_bad = get_picks_bad_good( picked_info, range(picked_info['nchan'])) # return without doing anything if there are no meg channels if len(picks_meg) == 0 or len(picks_bad) == 0: return # we need to make sure that only meg channels are passed here # as the MNE interpolation code is not fogriving. # This is why we picked the info. mapping = _fast_map_meg_channels( picked_info, pick_from=picks_good, pick_to=picks_bad, dots=dots, mode=mode) # the downside is that the mapping matrix now does not match # the unpicked info of the data. # Since we may have picked the info, we need to double map # the indices. _, picks_good_, picks_bad_orig = get_picks_bad_good( inst.info, picks) ch_names_a = [picked_info['ch_names'][pp] for pp in picks_bad] ch_names_b = [inst.info['ch_names'][pp] for pp in picks_bad_orig] assert ch_names_a == ch_names_b if not inst_picked: picks_good_ = [pp for pp in picks if pp in picks_good_] assert len(picks_good_) == len(picks_good) ch_names_a = [picked_info['ch_names'][pp] for pp in picks_good] ch_names_b = [inst.info['ch_names'][pp] for pp in picks_good_] assert ch_names_a == ch_names_b _do_interp_dots(inst, mapping, picks_good_, picks_bad_orig)
def _interpolate_bads_meg(inst, mode='accurate', origin=None, verbose=None): """Interpolate bad channels from data in good channels. Parameters ---------- inst : mne.io.Raw, mne.Epochs or mne.Evoked The data to interpolate. Must be preloaded. mode : str Either `'accurate'` or `'fast'`, determines the quality of the Legendre polynomial expansion used for interpolation. `'fast'` should be sufficient for most applications. origin : None | list If None, origin is set to sensor center of mass, otherwise use the coordinates provided as origin. The old standard value is (0., 0., 0.04) verbose : bool, str, int, or None If not None, override default verbose level (see :func:`mne.verbose` and :ref:`Logging documentation <tut_logging>` for more). """ from mne.channels.interpolation import _do_interp_dots picks_meg = pick_types(inst.info, meg=True, eeg=False, exclude=[]) picks_good = pick_types(inst.info, meg=True, eeg=False, exclude='bads') meg_ch_names = [inst.info['ch_names'][p] for p in picks_meg] bads_meg = [ch for ch in inst.info['bads'] if ch in meg_ch_names] # select the bad meg channel to be interpolated if len(bads_meg) == 0: picks_bad = [] else: picks_bad = pick_channels(inst.info['ch_names'], bads_meg, exclude=[]) # return without doing anything if there are no meg channels if len(picks_meg) == 0 or len(picks_bad) == 0: return info_from = pick_info(inst.info, picks_good) info_to = pick_info(inst.info, picks_bad) if check_version('mne', min_version='0.21'): from mne.forward import _map_meg_or_eeg_channels mapping = _map_meg_or_eeg_channels(info_from, info_to, mode=mode, origin=origin) else: from mne.forward import _map_meg_channels mapping = _map_meg_channels(info_from, info_to, mode=mode, origin=origin) _do_interp_dots(inst, mapping, picks_good, picks_bad)
def _interpolate_bads_meg_fast(inst, mode='accurate', verbose=None): """Interpolate bad channels from data in good channels. """ from mne.channels.interpolation import _do_interp_dots from mne import pick_types, pick_channels picks_meg = pick_types(inst.info, meg=True, eeg=False, exclude=[]) ch_names = [inst.info['ch_names'][p] for p in picks_meg] picks_good = pick_types(inst.info, meg=True, eeg=False, exclude='bads') # select the bad meg channel to be interpolated if len(inst.info['bads']) == 0: picks_bad = [] else: picks_bad = pick_channels(ch_names, inst.info['bads'], exclude=[]) # return without doing anything if there are no meg channels if len(picks_meg) == 0 or len(picks_bad) == 0: return mapping = _fast_map_meg_channels(inst, picks_good, picks_bad, mode=mode) _do_interp_dots(inst, mapping, picks_good, picks_bad)
def _interpolate_bads_eeg(inst, picks=None, verbose=False): """ Interpolate bad EEG channels. Operates in place. Parameters ---------- inst : mne.io.Raw, mne.Epochs or mne.Evoked The data to interpolate. Must be preloaded. picks : str | list | slice | None Channels to include for interpolation. Slices and lists of integers will be interpreted as channel indices. In lists, channel *name* strings (e.g., ``['EEG 01', 'EEG 02']``) will pick the given channels. None (default) will pick all EEG channels. Note that channels in ``info['bads']`` *will be included* if their names or indices are explicitly provided. """ from mne.bem import _fit_sphere from mne.utils import logger, warn from mne.channels.interpolation import _do_interp_dots from mne.channels.interpolation import _make_interpolation_matrix import numpy as np inst.info._check_consistency() if picks is None: picks = pick_types(inst.info, meg=False, eeg=True, exclude=[]) else: picks = _handle_picks(inst.info, picks) bads_idx = np.zeros(len(inst.ch_names), dtype=np.bool) goods_idx = np.zeros(len(inst.ch_names), dtype=np.bool) bads_idx[picks] = [inst.ch_names[ch] in inst.info['bads'] for ch in picks] if len(picks) == 0 or bads_idx.sum() == 0: return goods_idx[picks] = True goods_idx[bads_idx] = False pos = inst._get_channel_positions(picks) # Make sure only good EEG are used bads_idx_pos = bads_idx[picks] goods_idx_pos = goods_idx[picks] pos_good = pos[goods_idx_pos] pos_bad = pos[bads_idx_pos] # test spherical fit radius, center = _fit_sphere(pos_good) distance = np.sqrt(np.sum((pos_good - center)**2, 1)) distance = np.mean(distance / radius) if np.abs(1. - distance) > 0.1: warn('Your spherical fit is poor, interpolation results are ' 'likely to be inaccurate.') logger.info('Computing interpolation matrix from {0} sensor ' 'positions'.format(len(pos_good))) interpolation = _make_interpolation_matrix(pos_good, pos_bad) logger.info('Interpolating {0} sensors'.format(len(pos_bad))) _do_interp_dots(inst, interpolation, goods_idx, bads_idx)
def _interpolate_bads_meg(inst, mode='accurate', origin=None, verbose=None): """Interpolate bad channels from data in good channels. Parameters ---------- inst : mne.io.Raw, mne.Epochs or mne.Evoked The data to interpolate. Must be preloaded. mode : str Either `'accurate'` or `'fast'`, determines the quality of the Legendre polynomial expansion used for interpolation. `'fast'` should be sufficient for most applications. origin : None | list If None, origin is set to sensor center of mass, otherwise use the coordinates provided as origin. The old standard value is (0., 0., 0.04) verbose : bool, str, int, or None If not None, override default verbose level (see :func:`mne.verbose` and :ref:`Logging documentation <tut_logging>` for more). """ picks_meg = pick_types(inst.info, meg=True, eeg=False, exclude=[]) picks_good = pick_types(inst.info, meg=True, eeg=False, exclude='bads') meg_ch_names = [inst.info['ch_names'][p] for p in picks_meg] bads_meg = [ch for ch in inst.info['bads'] if ch in meg_ch_names] # select the bad meg channel to be interpolated if len(bads_meg) == 0: picks_bad = [] else: picks_bad = pick_channels(inst.info['ch_names'], bads_meg, exclude=[]) # return without doing anything if there are no meg channels if len(picks_meg) == 0 or len(picks_bad) == 0: return info_from = pick_info(inst.info, picks_good) info_to = pick_info(inst.info, picks_bad) if origin is None: posvec = np.array([inst.info['chs'][p]['loc'][0:3] for p in picks_meg]) norvec = np.array( [inst.info['chs'][p]['loc'][9:12] for p in picks_meg]) cogpos = np.mean(posvec, axis=0) norsum = np.mean(norvec, axis=0) anorm = np.sqrt(np.dot(norsum, norsum.T)) ndir = norsum / anorm # push the position slightly (4cm) away from the helmet: altpos = cogpos - 0.04 * ndir print(">_interpolate_bads_meg\\DBG> cog(sens) = [%8.5f %8.5f %8.5f]" % \ (cogpos[0], cogpos[1], cogpos[2])) print(">_interpolate_bads_meg\\DBG> alt(sens) = [%8.5f %8.5f %8.5f]" % \ (altpos[0], altpos[1], altpos[2])) cogposhd = apply_trans(inst.info['dev_head_t']['trans'], cogpos, move=True) altposhd = apply_trans(inst.info['dev_head_t']['trans'], altpos, move=True) print(">_interpolate_bads_meg\\DBG> cog(hdcs) = [%8.5f %8.5f %8.5f]" % \ (cogposhd[0], cogposhd[1], cogposhd[2])) print(">_interpolate_bads_meg\\DBG> alt(hdcs) = [%8.5f %8.5f %8.5f]" % \ (altposhd[0], altposhd[1], altposhd[2])) print(">_interpolate_bads_meg\\DBG> calling _map_meg_channels(..., origin=(%8.5f %8.5f %8.5f))" % \ (altposhd[0], altposhd[1], altposhd[2])) origin = (altposhd[0], altposhd[1], altposhd[2]) else: origin = origin mapping = _map_meg_channels(info_from, info_to, mode=mode, origin=origin) _do_interp_dots(inst, mapping, picks_good, picks_bad)