def make_interpolators(interp_cache, keys, bads, epochs): make = [k for k in keys if (bads, k) not in interp_cache] logger = logging.getLogger(__name__) logger.debug("Making %i of %i interpolators" % (len(make), len(keys))) for key in make: picks_good = pick_types(epochs.info, ref_meg=False, exclude=key) picks_bad = pick_channels(epochs.ch_names, key) interpolation = map_meg_channels(epochs, picks_good, picks_bad, 'accurate') interp_cache[bads, key] = picks_good, picks_bad, interpolation
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 apply(self, inst): """Apply the operator Parameters ---------- inst : instance of Raw The data on which to apply the operator. Returns ------- inst : instance of Raw The input instance with cleaned data (operates inplace). """ if isinstance(inst, BaseRaw): if not inst.preload: raise RuntimeError('raw data must be loaded, use ' 'raw.load_data() or preload=True') offsets = np.concatenate( [np.arange(0, len(inst.times), 10000), [len(inst.times)]]) info = inst.info picks = pick_channels(info['ch_names'], self._used_chs) data_chs = [ info['ch_names'][pick] for pick in _pick_data_channels(info, exclude=()) ] missing = set(data_chs) - set(self._used_chs) if len(missing) > 0: raise RuntimeError('Not all data channels of inst were used ' 'to construct the operator: %s' % sorted(missing)) missing = set(self._used_chs) - set(info['ch_names'][pick] for pick in picks) if len(missing) > 0: raise RuntimeError('Not all channels originally used to ' 'construct the operator are present: %s' % sorted(missing)) for start, stop in zip(offsets[:-1], offsets[1:]): time_sl = slice(start, stop) inst._data[picks, time_sl] = np.dot(self._operator, inst._data[picks, time_sl]) else: # XXX Eventually this could support Evoked and Epochs, too raise TypeError('Only Raw instances are currently supported, got ' '%s' % type(inst)) return inst
def pick_channels_connectivity(csd, include=[], exclude=[], ordered=False, copy=True): """Pick channels from connectivity matrix. Parameters ---------- csd : instance of ResultConnectivity The Result object to select the channels from. include : list of str List of channels to include (if empty, include all available). exclude : list of str Channels to exclude (if empty, do not exclude any). ordered : bool If True (default False), ensure that the order of the channels in the modified instance matches the order of ``include``. .. versionadded:: 0.20.0 copy : bool If True (the default), return a copy of the CSD matrix with the modified channels. If False, channels are modified in-place. .. versionadded:: 0.20.0 Returns ------- res : instance of CrossSpectralDensity Cross-spectral density restricted to selected channels. """ if copy: csd = csd.copy() sel = pick_channels(csd.ch_names, include=include, exclude=exclude, ordered=ordered) data = [] for vec in csd._data.T: mat = _vector_to_sym_mat(vec) mat = mat[sel, :][:, sel] data.append(_sym_mat_to_vector(mat)) ch_names = [csd.ch_names[i] for i in sel] csd._data = np.array(data).T csd.ch_names = ch_names return csd
def apply(self, inst): """Apply the operator Parameters ---------- inst : instance of Raw The data on which to apply the operator. Returns ------- inst : instance of Raw The input instance with cleaned data (operates inplace). """ if isinstance(inst, BaseRaw): if not inst.preload: raise RuntimeError('raw data must be loaded, use ' 'raw.load_data() or preload=True') offsets = np.concatenate([np.arange(0, len(inst.times), 10000), [len(inst.times)]]) info = inst.info picks = pick_channels(info['ch_names'], self._used_chs) data_chs = [info['ch_names'][pick] for pick in _pick_data_channels(info, exclude=())] missing = set(data_chs) - set(self._used_chs) if len(missing) > 0: raise RuntimeError('Not all data channels of inst were used ' 'to construct the operator: %s' % sorted(missing)) missing = set(self._used_chs) - set(info['ch_names'][pick] for pick in picks) if len(missing) > 0: raise RuntimeError('Not all channels originally used to ' 'construct the operator are present: %s' % sorted(missing)) for start, stop in zip(offsets[:-1], offsets[1:]): time_sl = slice(start, stop) inst._data[picks, time_sl] = np.dot(self._operator, inst._data[picks, time_sl]) else: # XXX Eventually this could support Evoked and Epochs, too raise TypeError('Only Raw instances are currently supported, got ' '%s' % type(inst)) return inst
def _interpolate_bads_meg(epochs, bad_channels_by_epoch, mode='fast'): """Interpolate bad MEG channels per epoch Parameters ---------- inst : mne.io.Raw, mne.Epochs or mne.Evoked The data to interpolate. Must be preloaded. bad_channels_by_epoch : list of list of str Bad channel names specified for each epoch. For example, for an Epochs instance containing 3 epochs: ``[['F1'], [], ['F3', 'FZ']]`` Notes ----- Based on mne 0.9.0 MEG channel interpolation. """ if len(bad_channels_by_epoch) != len(epochs): raise ValueError("Unequal length of epochs (%i) and " "bad_channels_by_epoch (%i)" % (len(epochs), len(bad_channels_by_epoch))) interp_cache = {} for i, bad_channels in enumerate(bad_channels_by_epoch): if not bad_channels: continue # find interpolation matrix key = tuple(sorted(bad_channels)) if key in interp_cache: picks_good, picks_bad, interpolation = interp_cache[key] else: picks_good = pick_types(epochs.info, ref_meg=False, exclude=key) picks_bad = pick_channels(epochs.ch_names, key) interpolation = _map_meg_channels(epochs, picks_good, picks_bad, mode) interp_cache[key] = picks_good, picks_bad, interpolation # apply interpolation logger.info('Interpolating sensors %s on epoch %s', picks_bad, i) epochs._data[i, picks_bad, :] = interpolation.dot(epochs._data[i, picks_good, :])
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)