def test_io_inverse_operator(): """Test IO of inverse_operator.""" tempdir = _TempDir() inverse_operator = read_inverse_operator(fname_inv) x = repr(inverse_operator) assert (x) assert (isinstance(inverse_operator['noise_cov'], Covariance)) # just do one example for .gz, as it should generalize _compare_io(inverse_operator, '.gz') # test warnings on bad filenames inv_badname = op.join(tempdir, 'test-bad-name.fif.gz') with pytest.warns(RuntimeWarning, match='-inv.fif'): write_inverse_operator(inv_badname, inverse_operator) with pytest.warns(RuntimeWarning, match='-inv.fif'): read_inverse_operator(inv_badname) # make sure we can write and read inv_fname = op.join(tempdir, 'test-inv.fif') args = (10, 1. / 9., 'dSPM') inv_prep = prepare_inverse_operator(inverse_operator, *args) write_inverse_operator(inv_fname, inv_prep) inv_read = read_inverse_operator(inv_fname) _compare(inverse_operator, inv_read) inv_read_prep = prepare_inverse_operator(inv_read, *args) _compare(inv_prep, inv_read_prep) inv_prep_prep = prepare_inverse_operator(inv_prep, *args) _compare(inv_prep, inv_prep_prep)
def test_apply_mne_inverse_raw(): """Test MNE with precomputed inverse operator on Raw.""" start = 3 stop = 10 raw = read_raw_fif(fname_raw) label_lh = read_label(fname_label % 'Aud-lh') _, times = raw[0, start:stop] inverse_operator = read_inverse_operator(fname_full) with pytest.raises(ValueError, match='has not been prepared'): apply_inverse_raw(raw, inverse_operator, lambda2, prepared=True) inverse_operator = prepare_inverse_operator(inverse_operator, nave=1, lambda2=lambda2, method="dSPM") for pick_ori in [None, "normal", "vector"]: stc = apply_inverse_raw(raw, inverse_operator, lambda2, "dSPM", label=label_lh, start=start, stop=stop, nave=1, pick_ori=pick_ori, buffer_size=None, prepared=True) stc2 = apply_inverse_raw(raw, inverse_operator, lambda2, "dSPM", label=label_lh, start=start, stop=stop, nave=1, pick_ori=pick_ori, buffer_size=3, prepared=True) if pick_ori is None: assert (np.all(stc.data > 0)) assert (np.all(stc2.data > 0)) assert (stc.subject == 'sample') assert (stc2.subject == 'sample') assert_array_almost_equal(stc.times, times) assert_array_almost_equal(stc2.times, times) assert_array_almost_equal(stc.data, stc2.data)
def _update(self): mne_info = self.traverse_back_and_find('mne_info') bads = mne_info['bads'] if bads != self._bad_channels: self.logger.info('Found new bad channels {};'.format(bads) + 'updating inverse operator') # self.inverse_operator = make_inverse_operator(self.fwd, mne_info) self.inverse_operator = make_inverse_operator(self.fwd, mne_info, depth=self.depth, loose=self.loose, fixed=self.fixed) self.inverse_operator = prepare_inverse_operator( self.inverse_operator, nave=100, lambda2=self.lambda2, method=self.method) # self._inverse_model_matrix = matrix_from_inverse_operator( # inverse_operator=self.inverse_operator, mne_info=mne_info, # snr=self.snr, method=self.method) self._bad_channels = bads input_array = self.parent.output raw_array = mne.io.RawArray(input_array, mne_info, verbose='ERROR') raw_array.pick_types(eeg=True, meg=False, stim=False, exclude='bads') # data = raw_array.get_data() # self.output = self._apply_inverse_model_matrix(data) stc = apply_inverse_raw(raw_array, self.inverse_operator, lambda2=self.lambda2, method=self.method, prepared=True) self.output = stc.data
def test_tfr_with_inverse_operator(method): """Test time freq with MNE inverse computation.""" tmin, tmax, event_id = -0.2, 0.5, 1 # Setup for reading the raw data raw = read_raw_fif(fname_data) events = find_events(raw, stim_channel='STI 014') inv = read_inverse_operator(fname_inv) inv = prepare_inverse_operator(inv, nave=1, lambda2=1. / 9., method=method) raw.info['bads'] += ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg=True, eeg=False, eog=True, stim=False, exclude='bads') # Load condition 1 event_id = 1 events3 = events[:3] # take 3 events to keep the computation time low epochs = Epochs(raw, events3, event_id, tmin, tmax, picks=picks, baseline=(None, 0), reject=dict(grad=4000e-13, eog=150e-6), preload=True) # Compute a source estimate per frequency band bands = dict(alpha=[10, 10]) label = read_label(fname_label) # XXX someday we should refactor this so that you don't have to pass # method -- maybe `prepare_inverse_operator` should add a `method` # to it and when `prepared=True` the value passed in can be ignored # (or better, default method=None means "dSPM if unprepared" and if they # actually pass a value, we check against `inv['method']`) stcs = source_band_induced_power(epochs, inv, bands, method=method, n_cycles=2, use_fft=False, pca=True, label=label, prepared=True) stc = stcs['alpha'] assert len(stcs) == len(list(bands.keys())) assert np.all(stc.data > 0) assert_allclose(stc.times, epochs.times, atol=1e-6) stcs_no_pca = source_band_induced_power(epochs, inv, bands, method=method, n_cycles=2, use_fft=False, pca=False, label=label, prepared=True) assert_allclose(stcs['alpha'].data, stcs_no_pca['alpha'].data) # Compute a source estimate per frequency band epochs = Epochs(raw, events[:10], event_id, tmin, tmax, picks=picks, baseline=(None, 0), reject=dict(grad=4000e-13, eog=150e-6), preload=True) freqs = np.arange(7, 30, 2) # define frequencies of interest power, phase_lock = source_induced_power( epochs, inv, freqs, label, baseline=(-0.1, 0), baseline_mode='percent', n_cycles=2, n_jobs=None, method=method, prepared=True) assert np.all(phase_lock > 0) assert np.all(phase_lock <= 1) assert 5 < np.max(power) < 7
def calc_inv_kernel(fn_inv, method="dSPM", nave=1, snr=6., pick_ori="normal", verbose=None): """ Interface for preparing the kernel of the inverse estimation. Parameters ---------- fn_inv : String containing the filename of the inverse operator (must be a fif-file) method : string which source localization method should be used? MNE-based: "MNE" | "dSPM" | "sLORETA" default: method="dSPM" nave : number of averages used to regularize the solution default: nave=1 snr : signal-to-noise ratio default: snr = 3. verbose : bool, str, int, or None If not None, override default verbose level (see mne.verbose). default: verbose=None """ # ------------------------------------------- # import necessary modules # ------------------------------------------- import mne.minimum_norm as min_norm from mne.minimum_norm.inverse import _assemble_kernel import numpy as np # ------------------------------------------- # estimate inverse kernel # ------------------------------------------- # load inverse solution inv_operator = min_norm.read_inverse_operator(fn_inv, verbose=verbose) # set up the inverse according to the parameters lambda2 = 1. / snr ** 2. # the regularization parameter. inv_operator = min_norm.prepare_inverse_operator(inv_operator, nave, lambda2, method) # estimate inverse kernel and noise normalization coefficient kernel, noise_norm, vertno = _assemble_kernel(inv_operator, None, method, pick_ori) if method == "MNE": noise_norm = np.ones((kernel.shape[0]/3)) noise_norm = noise_norm[:, np.newaxis] # ------------------------------------------- # return results # ------------------------------------------- return kernel, noise_norm, vertno
def _initialize(self): mne_info = self.traverse_back_and_find('mne_info') self._bad_channels = mne_info['bads'] if self._user_provided_forward_model_file_path is None: self._default_forward_model_file_path =\ get_default_forward_file(mne_info) self.sender.montage_signal.connect(self._root.reciever.on_montage_error) is_ok = True try: self.fwd, missing_ch_names = get_clean_forward( self.mne_forward_model_file_path, mne_info) mne_info['bads'] = list(set(mne_info['bads'] + missing_ch_names)) except ValueError as ve: if len(ve.args) == 3: self.sender.montage_signal.emit(ve.args) is_ok = False else: raise Exception('BAD FORWARD + DATA COMBINATION!') if is_ok: self.inverse_operator = make_inverse_operator(self.fwd, mne_info, depth=self.depth, loose=self.loose, fixed=self.fixed) self.lambda2 = 1.0 / self.snr ** 2 self.inverse_operator = prepare_inverse_operator( self.inverse_operator, nave=100, lambda2=self.lambda2, method=self.method) # self._inverse_model_matrix = matrix_from_inverse_operator( # inverse_operator=self.inverse_operator, mne_info=mne_info, # snr=self.snr, method=self.method) frequency = mne_info['sfreq'] # channel_count = self._inverse_model_matrix.shape[0] channel_count = self.fwd['nsource'] channel_labels = ['vertex #{}'.format(i + 1) for i in range(channel_count)] self.mne_info = mne.create_info(channel_labels, frequency)
def test_apply_inverse_cov(method, pick_ori): """Test MNE with precomputed inverse operator on cov.""" raw = read_raw_fif(fname_raw, preload=True) # use 10 sec of data raw.crop(0, 10) raw.filter(1, None) label_lh = read_label(fname_label % 'Aud-lh') # test with a free ori inverse inverse_operator = read_inverse_operator(fname_inv) data_cov = compute_raw_covariance(raw, tstep=None) with pytest.raises(ValueError, match='has not been prepared'): apply_inverse_cov(data_cov, raw.info, inverse_operator, lambda2=lambda2, prepared=True) this_inv_op = prepare_inverse_operator(inverse_operator, nave=1, lambda2=lambda2, method=method) raw_ori = 'normal' if pick_ori == 'normal' else 'vector' stc_raw = apply_inverse_raw( raw, this_inv_op, lambda2, method, label=label_lh, nave=1, pick_ori=raw_ori, prepared=True) stc_cov = apply_inverse_cov( data_cov, raw.info, this_inv_op, method=method, pick_ori=pick_ori, label=label_lh, prepared=True, lambda2=lambda2) n_sources = np.prod(stc_cov.data.shape[:-1]) raw_data = stc_raw.data.reshape(n_sources, -1) exp_res = np.diag(np.cov(raw_data, ddof=1)).copy() exp_res *= 1 if raw_ori == pick_ori else 3. # There seems to be some precision penalty when combining orientations, # but it's probably acceptable rtol = 5e-4 if pick_ori is None else 1e-12 assert_allclose(exp_res, stc_cov.data.ravel(), rtol=rtol) with pytest.raises(ValueError, match='Invalid value'): apply_inverse_cov( data_cov, raw.info, this_inv_op, method=method, pick_ori='vector')
def test_apply_mne_inverse_fixed_raw(): """Test MNE with fixed-orientation inverse operator on Raw.""" raw = read_raw_fif(fname_raw) start = 3 stop = 10 _, times = raw[0, start:stop] label_lh = read_label(fname_label % 'Aud-lh') # create a fixed-orientation inverse operator fwd = read_forward_solution_meg(fname_fwd, force_fixed=False, surf_ori=True) noise_cov = read_cov(fname_cov) pytest.raises(ValueError, make_inverse_operator, raw.info, fwd, noise_cov, loose=1., fixed=True) inv_op = make_inverse_operator(raw.info, fwd, noise_cov, fixed=True, use_cps=True) inv_op2 = prepare_inverse_operator(inv_op, nave=1, lambda2=lambda2, method="dSPM") stc = apply_inverse_raw(raw, inv_op2, lambda2, "dSPM", label=label_lh, start=start, stop=stop, nave=1, pick_ori=None, buffer_size=None, prepared=True) stc2 = apply_inverse_raw(raw, inv_op2, lambda2, "dSPM", label=label_lh, start=start, stop=stop, nave=1, pick_ori=None, buffer_size=3, prepared=True) stc3 = apply_inverse_raw(raw, inv_op, lambda2, "dSPM", label=label_lh, start=start, stop=stop, nave=1, pick_ori=None, buffer_size=None) assert (stc.subject == 'sample') assert (stc2.subject == 'sample') assert_array_almost_equal(stc.times, times) assert_array_almost_equal(stc2.times, times) assert_array_almost_equal(stc3.times, times) assert_array_almost_equal(stc.data, stc2.data) assert_array_almost_equal(stc.data, stc3.data)
def test_source_psd_epochs(method): """Test multi-taper source PSD computation in label from epochs.""" raw = read_raw_fif(fname_data) inverse_operator = read_inverse_operator(fname_inv) label = read_label(fname_label) event_id, tmin, tmax = 1, -0.2, 0.5 lambda2 = 1. / 9. bandwidth = 8. fmin, fmax = 0, 100 picks = pick_types(raw.info, meg=True, eeg=False, stim=True, ecg=True, eog=True, include=['STI 014'], exclude='bads') reject = dict(grad=4000e-13, mag=4e-12, eog=150e-6) events = find_events(raw, stim_channel='STI 014') epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks, baseline=(None, 0), reject=reject) # only look at one epoch epochs.drop_bad() one_epochs = epochs[:1] inv = prepare_inverse_operator(inverse_operator, nave=1, lambda2=1. / 9., method="dSPM") # return list stc_psd = compute_source_psd_epochs(one_epochs, inv, lambda2=lambda2, method=method, pick_ori="normal", label=label, bandwidth=bandwidth, fmin=fmin, fmax=fmax, prepared=True)[0] # return generator stcs = compute_source_psd_epochs(one_epochs, inv, lambda2=lambda2, method=method, pick_ori="normal", label=label, bandwidth=bandwidth, fmin=fmin, fmax=fmax, return_generator=True, prepared=True) for stc in stcs: stc_psd_gen = stc assert_allclose(stc_psd.data, stc_psd_gen.data, atol=1e-7) # compare with direct computation stc = apply_inverse_epochs(one_epochs, inv, lambda2=lambda2, method=method, pick_ori="normal", label=label, prepared=True)[0] sfreq = epochs.info['sfreq'] psd, freqs = psd_array_multitaper(stc.data, sfreq=sfreq, bandwidth=bandwidth, fmin=fmin, fmax=fmax) assert_allclose(psd, stc_psd.data, atol=1e-7) assert_allclose(freqs, stc_psd.times) # Check corner cases caused by tiny bandwidth with pytest.raises(ValueError, match='use a value of at least'): compute_source_psd_epochs( one_epochs, inv, lambda2=lambda2, method=method, pick_ori="normal", label=label, bandwidth=0.01, low_bias=True, fmin=fmin, fmax=fmax, return_generator=False, prepared=True)
evoked_tmp = data_train[subject1][1]['normal'] fwd1 = fwd_list[subject1] fwd_fixed1 = mne.convert_forward_solution(fwd1, force_fixed=True) #Apply projector to forward models G1 = (np.eye(71) - (np.ones((71, 1)) @ np.ones((71, 1)).T) / (np.ones( (71, 1)).T @ np.ones((71, 1)))) @ fwd_fixed1['sol']['data'] noise_cov = data_train[subject1][1]['cov'] #Find linear inverse solution given by K multiplied by M, called T^MNE in the report inverse_operator = make_inverse_operator(evoked_tmp.info, fwd_fixed1, noise_cov, loose=loose, depth=depth) inverse_operator = prepare_inverse_operator(inverse_operator, 1, lambda2, method, None, False) K, noise_norm, vertno, source_nn = _assemble_kernel(inverse_operator, None, method, pick_ori=pick_ori, use_cps=True) #Find subjects to augment to for subject2 in np.random.choice(subjects_test, num_aug, replace=False): fwd2 = fwd_list[subject2] fwd_fixed2 = mne.convert_forward_solution(fwd2, force_fixed=True) G2 = (np.eye(71) - (np.ones((71, 1)) @ np.ones( (71, 1)).T) / (np.ones((71, 1)).T @ np.ones( (71, 1)))) @ fwd_fixed2['sol']['data'] src = mne.SourceEstimate(
subject = 'sample' parcellation = 'aparc' # Options: aparc.a2009s, aparc. Note that Destrieux parcellation seems to already be optimized/flipped, so weighting has only a minor effect. method = 'dSPM' # Options: MNE, dSPM, eLORETA. sLORETA is not well supported. fpath = sample.data_path() fpath_meg = os.path.join(fpath, 'MEG', 'sample') subjects_dir = os.path.join(fpath, 'subjects') """Read forward and inverse operators from disk.""" fname_forward = os.path.join(fpath_meg, 'sample_audvis-meg-oct-6-fwd.fif') fname_inverse = os.path.join(fpath_meg, 'sample_audvis-meg-oct-6-meg-inv.fif') fwd = read_forward_solution(fname_forward) inv = read_inverse_operator(fname_inverse) """Force fixed source orientation mode.""" fwd_fixed = convert_forward_solution(fwd, force_fixed=True, use_cps=True) """Prepare the inverse operator for use.""" # Inverse loads with free orientation inv = prepare_inverse_operator(inv, 1, 1. / 9, method) """Read labels from FreeSurfer annotation files.""" labels = read_labels_from_annot(subject, subjects_dir=subjects_dir, parc=parcellation) """ Create weighted inverse operator. """ weighted_inv = weight_inverse_operator(fwd_fixed, inv, labels, method=method) """ Analyze results """ """ Check if weighting worked. """ source_identities, fwd_mat, inv_mat = _extract_operator_data(fwd_fixed, inv, labels, method=method)
'data'] # counterpart to forwardOperator, [sensors x sources] # read data and create HF-filtered-covariance matrix data1 = mne.io.read_raw_fif(icaFile, preload=True) data2 = copy.deepcopy(data1) data2.filter(l_freq=151, h_freq=249) cov = mne.compute_raw_covariance(data2) # get and write inv. operator inv = minnorm.make_inverse_operator(data1.info, fwd, cov, loose=0., depth=None, fixed=True) inv1 = minnorm.prepare_inverse_operator(inv, 1, 1. / 9.) inv_sol = minnorm.inverse._assemble_kernel( inv1, None, 'MNE', None)[0] # counterpart to forwardOperator, [sources x sensors] # test on extract of time series source_ts = minnorm.apply_inverse_raw(data1, inv, method='MNE', lambda2=1. / 9., start=0, stop=6000) label_ts = mne.extract_label_time_course(source_ts, labels_parc, src, mode='mean_flip',
def raw_ndvar(raw, i_start=None, i_stop=None, decim=1, inv=None, lambda2=1, method='dSPM', pick_ori=None, src=None, subjects_dir=None, parc='aparc', label=None): """Raw dta as NDVar Parameters ---------- raw : Raw | str Raw instance, or path of a raw FIFF file.. i_start : int | sequence of int Start sample (see notes; default is the beginning of the ``raw``). i_stop : int | sequence of int Stop sample (see notes; default is end of the ``raw``). decim : int Downsample the data by this factor when importing. ``1`` (default) means no downsampling. Note that this function does not low-pass filter the data. The data is downsampled by picking out every n-th sample. inv : InverseOperator MNE inverse operator to transform data to source space (by default, data are loaded in sensor space). If ``inv`` is specified, subsequent parameters are required to construct the right soure space. lambda2 : scalar Inverse solution parameter: lambda squared parameter. method : str Inverse solution parameter: noise normalization method. pick_ori : bool Inverse solution parameter. src : str Source space descriptor (e.g. ``'ico-4'``). subjects_dir : str MRI subjects directory. parc : str Parcellation to load for the source space. label : Label Restrict source estimate to this label. Returns ------- data : NDVar | list of NDVar Data (sensor or source space). If ``i_start`` and ``i_stopr`` are scalar then a single NDVar is returned, if they are lists then a list of NDVars is returned. Notes ----- ``i_start`` and ``i_stop`` are interpreted as event indexes (from :func:`mne.find_events`), i.e. relative to ``raw.first_samp``. """ if not isinstance(raw, MNE_RAW): raw = mne_raw(raw) name = os.path.basename(_get_raw_filename(raw)) start_scalar = i_start is None or isinstance(i_start, int) stop_scalar = i_stop is None or isinstance(i_stop, int) if start_scalar or stop_scalar: if not start_scalar and stop_scalar: raise TypeError( "i_start and i_stop must either both be scalar or both " "iterable, got i_start=%r, i_stop=%s" % (i_start, i_stop)) i_start = (i_start, ) i_stop = (i_stop, ) scalar = True else: scalar = False # event index to raw index i_start = tuple(i if i is None else i - raw.first_samp for i in i_start) i_stop = tuple(i if i is None else i - raw.first_samp for i in i_stop) # target dimension if inv is None: picks = mne.pick_types(raw.info, ref_meg=False) dim = sensor_dim(raw, picks) else: dim = SourceSpace.from_mne_source_spaces(inv['src'], src, subjects_dir, parc, label) inv = prepare_inverse_operator(inv, 1, lambda2, method) out = [] for start, stop in izip(i_start, i_stop): if inv is None: x = raw[picks, start:stop][0] else: x = apply_inverse_raw(raw, inv, lambda2, method, label, start, stop, pick_ori=pick_ori, prepared=True).data if decim != 1: x = x[:, ::decim] time = UTS(0, float(decim) / raw.info['sfreq'], x.shape[1]) out.append(NDVar(x, (dim, time), _cs.meg_info(), name)) if scalar: return out[0] else: return out
def raw_ndvar( raw, i_start=None, i_stop=None, decim=1, inv=None, lambda2=1, method="dSPM", pick_ori=None, src=None, subjects_dir=None, parc="aparc", label=None, ): """Raw dta as NDVar Parameters ---------- raw : Raw Raw instance. i_start : int | sequence of int Start sample (see notes; default is the beginning of the ``raw``). i_stop : int | sequence of int Stop sample (see notes; default is end of the ``raw``). decim : int Downsample the data by this factor when importing. ``1`` (default) means no downsampling. Note that this function does not low-pass filter the data. The data is downsampled by picking out every n-th sample. inv : InverseOperator MNE inverse operator to transform data to source space (by default, data are loaded in sensor space). If ``inv`` is specified, subsequent parameters are required to construct the right soure space. lambda2 : scalar Inverse solution parameter: lambda squared parameter. method : str Inverse solution parameter: noise normalization method. pick_ori : bool Inverse solution parameter. src : str Source space descriptor (e.g. ``'ico-4'``). subjects_dir : str MRI subjects directory. parc : str Parcellation to load for the source space. label : Label Restrict source estimate to this label. Returns ------- data : NDVar | list of NDVar Data (sensor or source space). If ``i_start`` and ``i_stopr`` are scalar then a single NDVar is returned, if they are lists then a list of NDVars is returned. Notes ----- ``i_start`` and ``i_stop`` are interpreted as event indexes (from :func:`mne.find_events`), i.e. relative to ``raw.first_samp``. """ start_scalar = i_start is None or isinstance(i_start, int) stop_scalar = i_stop is None or isinstance(i_stop, int) if start_scalar or stop_scalar: if not start_scalar and stop_scalar: raise TypeError( "i_start and i_stop must either both be scalar or both " "iterable, got i_start=%r, i_stop=%s" % (i_start, i_stop) ) i_start = (i_start,) i_stop = (i_stop,) scalar = True else: scalar = False # event index to raw index i_start = tuple(i if i is None else i - raw.first_samp for i in i_start) i_stop = tuple(i if i is None else i - raw.first_samp for i in i_stop) # target dimension if inv is None: picks = mne.pick_types(raw.info, ref_meg=False) dim = sensor_dim(raw, picks) else: dim = SourceSpace.from_mne_source_spaces(inv["src"], src, subjects_dir, parc, label) inv = prepare_inverse_operator(inv, 1, lambda2, method) out = [] for start, stop in izip(i_start, i_stop): if inv is None: x = raw[picks, start:stop][0] else: x = apply_inverse_raw(raw, inv, lambda2, method, label, start, stop, pick_ori=pick_ori, prepared=True).data if decim != 1: x = x[:, ::decim] time = UTS(0, float(decim) / raw.info["sfreq"], x.shape[1]) out.append(NDVar(x, (dim, time), _cs.meg_info())) if scalar: return out[0] else: return out
def test_apply_mne_inverse_epochs(): """Test MNE with precomputed inverse operator on Epochs.""" inverse_operator = read_inverse_operator(fname_full) label_lh = read_label(fname_label % 'Aud-lh') label_rh = read_label(fname_label % 'Aud-rh') event_id, tmin, tmax = 1, -0.2, 0.5 raw = read_raw_fif(fname_raw) picks = pick_types(raw.info, meg=True, eeg=False, stim=True, ecg=True, eog=True, include=['STI 014'], exclude='bads') reject = dict(grad=4000e-13, mag=4e-12, eog=150e-6) flat = dict(grad=1e-15, mag=1e-15) events = read_events(fname_event)[:15] epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks, baseline=(None, 0), reject=reject, flat=flat) inverse_operator = prepare_inverse_operator(inverse_operator, nave=1, lambda2=lambda2, method="dSPM") for pick_ori in [None, "normal", "vector"]: stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM", label=label_lh, pick_ori=pick_ori) stcs2 = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM", label=label_lh, pick_ori=pick_ori, prepared=True) # test if using prepared and not prepared inverse operator give the # same result assert_array_almost_equal(stcs[0].data, stcs2[0].data) assert_array_almost_equal(stcs[0].times, stcs2[0].times) assert (len(stcs) == 2) assert (3 < stcs[0].data.max() < 10) assert (stcs[0].subject == 'sample') inverse_operator = read_inverse_operator(fname_full) stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM", label=label_lh, pick_ori='normal') data = sum(stc.data for stc in stcs) / len(stcs) flip = label_sign_flip(label_lh, inverse_operator['src']) label_mean = np.mean(data, axis=0) label_mean_flip = np.mean(flip[:, np.newaxis] * data, axis=0) assert (label_mean.max() < label_mean_flip.max()) # test extracting a BiHemiLabel inverse_operator = prepare_inverse_operator(inverse_operator, nave=1, lambda2=lambda2, method="dSPM") stcs_rh = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM", label=label_rh, pick_ori="normal", prepared=True) stcs_bh = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM", label=label_lh + label_rh, pick_ori="normal", prepared=True) n_lh = len(stcs[0].data) assert_array_almost_equal(stcs[0].data, stcs_bh[0].data[:n_lh]) assert_array_almost_equal(stcs_rh[0].data, stcs_bh[0].data[n_lh:]) # test without using a label (so delayed computation is used) stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM", pick_ori="normal", prepared=True) assert (stcs[0].subject == 'sample') label_stc = stcs[0].in_label(label_rh) assert (label_stc.subject == 'sample') assert_array_almost_equal(stcs_rh[0].data, label_stc.data)
def raw_ndvar(raw, i_start=None, i_stop=None, decim=1, data=None, exclude='bads', sysname=None, connectivity=None, inv=None, lambda2=1, method='dSPM', pick_ori=None, src=None, subjects_dir=None, parc='aparc', label=None): """Raw dta as NDVar Parameters ---------- raw : Raw | str Raw instance, or path of a raw FIFF file.. i_start : int | sequence of int Start sample (see notes; default is the beginning of the ``raw``). i_stop : int | sequence of int Stop sample (see notes; default is end of the ``raw``). decim : int Downsample the data by this factor when importing. ``1`` (default) means no downsampling. Note that this function does not low-pass filter the data. The data is downsampled by picking out every n-th sample. data : 'eeg' | 'mag' | 'grad' | None The kind of data to include (default based on data). exclude : list of string | str Channels to exclude (:func:`mne.pick_types` kwarg). If 'bads' (default), exclude channels in info['bads']. If empty do not exclude any. sysname : str Name of the sensor system to load sensor connectivity (e.g. 'neuromag', inferred automatically for KIT data converted with a recent version of MNE-Python). connectivity : str | list of (str, str) | array of int, (n_edges, 2) Connectivity between elements. Can be specified as: - ``"none"`` for no connections - list of connections (e.g., ``[('OZ', 'O1'), ('OZ', 'O2'), ...]``) - :class:`numpy.ndarray` of int, shape (n_edges, 2), to specify connections in terms of indices. Each row should specify one connection [i, j] with i < j. If the array's dtype is uint32, property checks are disabled to improve efficiency. - ``"grid"`` to use adjacency in the sensor names If unspecified, it is inferred from ``sysname`` if possible. inv : InverseOperator MNE inverse operator to transform data to source space (by default, data are loaded in sensor space). If ``inv`` is specified, subsequent parameters are required to construct the right source space. lambda2 : scalar Inverse solution parameter: lambda squared parameter. method : str Inverse solution parameter: noise normalization method. pick_ori : bool Inverse solution parameter. src : str Source space descriptor (e.g. ``'ico-4'``). subjects_dir : str MRI subjects directory. parc : str Parcellation to load for the source space. label : Label Restrict source estimate to this label. Returns ------- data : NDVar | list of NDVar Data (sensor or source space). If ``i_start`` and ``i_stopr`` are scalar then a single NDVar is returned, if they are lists then a list of NDVars is returned. Notes ----- ``i_start`` and ``i_stop`` are interpreted as event indexes (from :func:`mne.find_events`), i.e. relative to ``raw.first_samp``. """ if not isinstance(raw, MNE_RAW): raw = mne_raw(raw) name = os.path.basename(_get_raw_filename(raw)) start_scalar = i_start is None or isinstance(i_start, int) stop_scalar = i_stop is None or isinstance(i_stop, int) if start_scalar or stop_scalar: if not start_scalar and stop_scalar: raise TypeError( "i_start and i_stop must either both be scalar or both " "iterable, got i_start=%r, i_stop=%s" % (i_start, i_stop)) i_start = (i_start,) i_stop = (i_stop,) scalar = True else: scalar = False # event index to raw index i_start = tuple(i if i is None else i - raw.first_samp for i in i_start) i_stop = tuple(i if i is None else i - raw.first_samp for i in i_stop) # target dimension if inv is None: if data is None: data = _guess_ndvar_data_type(raw.info) picks = _picks(raw.info, data, exclude) dim = sensor_dim(raw, picks, sysname, connectivity) info = _sensor_info(data, None, raw.info) else: assert data is None dim = SourceSpace.from_mne_source_spaces(inv['src'], src, subjects_dir, parc, label) inv = prepare_inverse_operator(inv, 1, lambda2, method) info = {} # FIXME out = [] for start, stop in zip(i_start, i_stop): if inv is None: x = raw[picks, start:stop][0] else: x = apply_inverse_raw(raw, inv, lambda2, method, label, start, stop, pick_ori=pick_ori, prepared=True).data if decim != 1: x = x[:, ::decim] time = UTS(0, float(decim) / raw.info['sfreq'], x.shape[1]) out.append(NDVar(x, (dim, time), info, name)) if scalar: return out[0] else: return out
def raw_ndvar(raw, i_start=None, i_stop=None, decim=1, data=None, exclude='bads', sysname=None, connectivity=None, inv=None, lambda2=1, method='dSPM', pick_ori=None, src=None, subjects_dir=None, parc='aparc', label=None): """Raw dta as NDVar Parameters ---------- raw : Raw | str Raw instance, or path of a raw FIFF file.. i_start : int | sequence of int Start sample (see notes; default is the beginning of the ``raw``). i_stop : int | sequence of int Stop sample (see notes; default is end of the ``raw``). decim : int Downsample the data by this factor when importing. ``1`` (default) means no downsampling. Note that this function does not low-pass filter the data. The data is downsampled by picking out every n-th sample. data : 'eeg' | 'mag' | 'grad' | None The kind of data to include (default based on data). exclude : list of string | str Channels to exclude (:func:`mne.pick_types` kwarg). If 'bads' (default), exclude channels in info['bads']. If empty do not exclude any. sysname : str Name of the sensor system to load sensor connectivity (e.g. 'neuromag', inferred automatically for KIT data converted with a recent version of MNE-Python). connectivity : str | list of (str, str) | array of int, (n_edges, 2) Connectivity between elements. Can be specified as: - ``"none"`` for no connections - list of connections (e.g., ``[('OZ', 'O1'), ('OZ', 'O2'), ...]``) - :class:`numpy.ndarray` of int, shape (n_edges, 2), to specify connections in terms of indices. Each row should specify one connection [i, j] with i < j. If the array's dtype is uint32, property checks are disabled to improve efficiency. - ``"grid"`` to use adjacency in the sensor names If unspecified, it is inferred from ``sysname`` if possible. inv : InverseOperator MNE inverse operator to transform data to source space (by default, data are loaded in sensor space). If ``inv`` is specified, subsequent parameters are required to construct the right source space. lambda2 : scalar Inverse solution parameter: lambda squared parameter. method : str Inverse solution parameter: noise normalization method. pick_ori : bool Inverse solution parameter. src : str Source space descriptor (e.g. ``'ico-4'``). subjects_dir : str MRI subjects directory. parc : str Parcellation to load for the source space. label : Label Restrict source estimate to this label. Returns ------- data : NDVar | list of NDVar Data (sensor or source space). If ``i_start`` and ``i_stopr`` are scalar then a single NDVar is returned, if they are lists then a list of NDVars is returned. Notes ----- ``i_start`` and ``i_stop`` are interpreted as event indexes (from :func:`mne.find_events`), i.e. relative to ``raw.first_samp``. """ if not isinstance(raw, MNE_RAW): raw = mne_raw(raw) name = os.path.basename(raw.filenames[0]) start_scalar = i_start is None or isinstance(i_start, int) stop_scalar = i_stop is None or isinstance(i_stop, int) if start_scalar or stop_scalar: if not start_scalar and stop_scalar: raise TypeError( "i_start and i_stop must either both be scalar or both " "iterable, got i_start=%r, i_stop=%s" % (i_start, i_stop)) i_start = (i_start, ) i_stop = (i_stop, ) scalar = True else: scalar = False # event index to raw index i_start = tuple(i if i is None else i - raw.first_samp for i in i_start) i_stop = tuple(i if i is None else i - raw.first_samp for i in i_stop) # target dimension if inv is None: if data is None: data = _guess_ndvar_data_type(raw.info) picks = _picks(raw.info, data, exclude) dim = sensor_dim(raw, picks, sysname, connectivity) info = _sensor_info(data, None, raw.info) else: assert data is None dim = SourceSpace.from_mne_source_spaces(inv['src'], src, subjects_dir, parc, label) inv = prepare_inverse_operator(inv, 1, lambda2, method) info = {} # FIXME out = [] for start, stop in zip(i_start, i_stop): if inv is None: x = raw[picks, start:stop][0] else: x = apply_inverse_raw(raw, inv, lambda2, method, label, start, stop, pick_ori=pick_ori, prepared=True).data if decim != 1: x = x[:, ::decim] time = UTS(0, float(decim) / raw.info['sfreq'], x.shape[1]) out.append(NDVar(x, (dim, time), name, info)) if scalar: return out[0] else: return out
def test_apply_inverse_operator(evoked, inv, min_, max_): """Test MNE inverse application.""" # use fname_inv as it will be faster than fname_full (fewer verts and chs) inverse_operator = read_inverse_operator(inv) # Inverse has 306 channels - 4 proj = 302 assert (compute_rank_inverse(inverse_operator) == 302) # Inverse has 306 channels - 4 proj = 302 assert (compute_rank_inverse(inverse_operator) == 302) stc = apply_inverse(evoked, inverse_operator, lambda2, "MNE") assert stc.subject == 'sample' assert stc.data.min() > min_ assert stc.data.max() < max_ assert abs(stc).data.mean() > 1e-11 # test if using prepared and not prepared inverse operator give the same # result inv_op = prepare_inverse_operator(inverse_operator, nave=evoked.nave, lambda2=lambda2, method="MNE") stc2 = apply_inverse(evoked, inv_op, lambda2, "MNE") assert_array_almost_equal(stc.data, stc2.data) assert_array_almost_equal(stc.times, stc2.times) # This is little more than a smoke test... stc = apply_inverse(evoked, inverse_operator, lambda2, "sLORETA") assert stc.subject == 'sample' assert abs(stc).data.min() > 0 assert 2 < stc.data.max() < 7 assert abs(stc).data.mean() > 0.1 stc = apply_inverse(evoked, inverse_operator, lambda2, "eLORETA") assert stc.subject == 'sample' assert abs(stc).data.min() > min_ assert stc.data.max() < max_ * 2 assert abs(stc).data.mean() > 1e-11 stc = apply_inverse(evoked, inverse_operator, lambda2, "dSPM") assert stc.subject == 'sample' assert abs(stc).data.min() > 0 assert 7.5 < stc.data.max() < 15 assert abs(stc).data.mean() > 0.1 # test without using a label (so delayed computation is used) label = read_label(fname_label % 'Aud-lh') for method in INVERSE_METHODS: stc = apply_inverse(evoked, inv_op, lambda2, method) stc_label = apply_inverse(evoked, inv_op, lambda2, method, label=label) assert_equal(stc_label.subject, 'sample') label_stc = stc.in_label(label) assert label_stc.subject == 'sample' assert_allclose(stc_label.data, label_stc.data) # Test that no errors are raised with loose inverse ops and picking normals noise_cov = read_cov(fname_cov) fwd = read_forward_solution_meg(fname_fwd) inv_op_meg = make_inverse_operator( evoked.info, fwd, noise_cov, loose=1, fixed='auto', depth=None) apply_inverse(evoked, inv_op_meg, 1 / 9., method='MNE', pick_ori='normal') # Test we get errors when using custom ref or no average proj is present evoked.info['custom_ref_applied'] = True pytest.raises(ValueError, apply_inverse, evoked, inv_op, lambda2, "MNE") evoked.info['custom_ref_applied'] = False evoked.info['projs'] = [] # remove EEG proj pytest.raises(ValueError, apply_inverse, evoked, inv_op, lambda2, "MNE") # But test that we do not get EEG-related errors on MEG-only inv (gh-4650) apply_inverse(evoked, inv_op_meg, 1. / 9.)