def test_compute_whitener_rank(): """Test risky rank options.""" info = read_info(ave_fname) info = pick_info(info, pick_types(info, meg=True)) with info._unlock(): info['projs'] = [] # need a square version because the diag one takes shortcuts in # compute_whitener (users shouldn't even need this function so it's # private) cov = make_ad_hoc_cov(info)._as_square() assert len(cov['names']) == 306 _, _, rank = compute_whitener(cov, info, rank=None, return_rank=True) assert rank == 306 assert compute_rank(cov, info=info, verbose=True) == dict(meg=rank) cov['data'][-1] *= 1e-14 # trivially rank-deficient _, _, rank = compute_whitener(cov, info, rank=None, return_rank=True) assert rank == 305 assert compute_rank(cov, info=info, verbose=True) == dict(meg=rank) # this should emit a warning with pytest.warns(RuntimeWarning, match='exceeds the estimated'): _, _, rank = compute_whitener(cov, info, rank=dict(meg=306), return_rank=True) assert rank == 306
def test_compute_whitener(proj, pca): """Test properties of compute_whitener.""" raw = read_raw_fif(raw_fname).crop(0, 3).load_data() raw.pick_types(meg=True, eeg=True, exclude=()) if proj: raw.apply_proj() else: raw.del_proj() with pytest.warns(RuntimeWarning, match='Too few samples'): cov = compute_raw_covariance(raw) assert cov['names'] == raw.ch_names W, _, C = compute_whitener(cov, raw.info, pca=pca, return_colorer=True, verbose='error') n_channels = len(raw.ch_names) n_reduced = len(raw.ch_names) rank = n_channels - len(raw.info['projs']) n_reduced = rank if pca is True else n_channels assert W.shape == C.shape[::-1] == (n_reduced, n_channels) # round-trip mults round_trip = np.dot(W, C) if pca is True: assert_allclose(round_trip, np.eye(n_reduced), atol=1e-7) elif pca == 'white': # Our first few rows/cols are zeroed out in the white space assert_allclose(round_trip[-rank:, -rank:], np.eye(rank), atol=1e-7) else: assert pca is False assert_allclose(round_trip, np.eye(n_channels), atol=0.05) raw.info['bads'] = [raw.ch_names[0]] picks = pick_types(raw.info, meg=True, eeg=True, exclude=[]) with pytest.warns(RuntimeWarning, match='Too few samples'): cov2 = compute_raw_covariance(raw, picks=picks) cov3 = compute_raw_covariance(raw, picks=None) assert_allclose(cov2['data'][1:, 1:], cov3['data']) W2, _, C2 = compute_whitener(cov2, raw.info, pca=pca, return_colorer=True, picks=picks, verbose='error') W3, _, C3 = compute_whitener(cov3, raw.info, pca=pca, return_colorer=True, picks=None, verbose='error') # this tol is not great, but Windows needs it rtol = 3e-5 if sys.platform.startswith('win') else 1e-11 assert_allclose(W, W2, rtol=rtol) assert_allclose(C, C2, rtol=rtol) n_channels = len(raw.ch_names) - len(raw.info['bads']) n_reduced = len(raw.ch_names) - len(raw.info['bads']) rank = n_channels - len(raw.info['projs']) n_reduced = rank if pca is True else n_channels assert W3.shape == C3.shape[::-1] == (n_reduced, n_channels)
def test_cov_order(): """Test covariance ordering.""" raw = read_raw_fif(raw_fname) raw.set_eeg_reference(projection=True) info = raw.info # add MEG channel with low enough index number to affect EEG if # order is incorrect info['bads'] += ['MEG 0113'] ch_names = [info['ch_names'][pick] for pick in pick_types(info, meg=False, eeg=True)] cov = read_cov(cov_fname) # no avg ref present warning prepare_noise_cov(cov, info, ch_names, verbose='error') # big reordering cov_reorder = cov.copy() order = np.random.RandomState(0).permutation(np.arange(len(cov.ch_names))) cov_reorder['names'] = [cov['names'][ii] for ii in order] cov_reorder['data'] = cov['data'][order][:, order] # Make sure we did this properly _assert_reorder(cov_reorder, cov, order) # Now check some functions that should get the same result for both # regularize with pytest.raises(ValueError, match='rank, if str'): regularize(cov, info, rank='foo') with pytest.raises(TypeError, match='rank must be'): regularize(cov, info, rank=False) with pytest.raises(TypeError, match='rank must be'): regularize(cov, info, rank=1.) cov_reg = regularize(cov, info, rank='full') cov_reg_reorder = regularize(cov_reorder, info, rank='full') _assert_reorder(cov_reg_reorder, cov_reg, order) # prepare_noise_cov cov_prep = prepare_noise_cov(cov, info, ch_names) cov_prep_reorder = prepare_noise_cov(cov, info, ch_names) _assert_reorder(cov_prep, cov_prep_reorder, order=np.arange(len(cov_prep['names']))) # compute_whitener whitener, w_ch_names, n_nzero = compute_whitener( cov, info, return_rank=True) assert whitener.shape[0] == whitener.shape[1] whitener_2, w_ch_names_2, n_nzero_2 = compute_whitener( cov_reorder, info, return_rank=True) assert_array_equal(w_ch_names_2, w_ch_names) assert_allclose(whitener_2, whitener) assert n_nzero == n_nzero_2 # with pca assert n_nzero < whitener.shape[0] whitener_pca, w_ch_names_pca, n_nzero_pca = compute_whitener( cov, info, pca=True, return_rank=True) assert_array_equal(w_ch_names_pca, w_ch_names) assert n_nzero_pca == n_nzero assert whitener_pca.shape == (n_nzero_pca, len(w_ch_names)) # whiten_evoked evoked = read_evokeds(ave_fname)[0] evoked_white = whiten_evoked(evoked, cov) evoked_white_2 = whiten_evoked(evoked, cov_reorder) assert_allclose(evoked_white_2.data, evoked_white.data)
def test_cov_order(): """Test covariance ordering.""" raw = read_raw_fif(raw_fname) raw.set_eeg_reference(projection=True) info = raw.info # add MEG channel with low enough index number to affect EEG if # order is incorrect info['bads'] += ['MEG 0113'] ch_names = [info['ch_names'][pick] for pick in pick_types(info, meg=False, eeg=True)] cov = read_cov(cov_fname) # no avg ref present warning prepare_noise_cov(cov, info, ch_names, verbose='error') # big reordering cov_reorder = cov.copy() order = np.random.RandomState(0).permutation(np.arange(len(cov.ch_names))) cov_reorder['names'] = [cov['names'][ii] for ii in order] cov_reorder['data'] = cov['data'][order][:, order] # Make sure we did this properly _assert_reorder(cov_reorder, cov, order) # Now check some functions that should get the same result for both # regularize with pytest.raises(ValueError, match='rank, if str'): regularize(cov, info, rank='foo') with pytest.raises(TypeError, match='rank must be'): regularize(cov, info, rank=False) with pytest.raises(TypeError, match='rank must be'): regularize(cov, info, rank=1.) cov_reg = regularize(cov, info, rank='full') cov_reg_reorder = regularize(cov_reorder, info, rank='full') _assert_reorder(cov_reg_reorder, cov_reg, order) # prepare_noise_cov cov_prep = prepare_noise_cov(cov, info, ch_names) cov_prep_reorder = prepare_noise_cov(cov, info, ch_names) _assert_reorder(cov_prep, cov_prep_reorder, order=np.arange(len(cov_prep['names']))) # compute_whitener whitener, w_ch_names, n_nzero = compute_whitener( cov, info, return_rank=True) assert whitener.shape[0] == whitener.shape[1] whitener_2, w_ch_names_2, n_nzero_2 = compute_whitener( cov_reorder, info, return_rank=True) assert_array_equal(w_ch_names_2, w_ch_names) assert_allclose(whitener_2, whitener, rtol=1e-6) assert n_nzero == n_nzero_2 # with pca assert n_nzero < whitener.shape[0] whitener_pca, w_ch_names_pca, n_nzero_pca = compute_whitener( cov, info, pca=True, return_rank=True) assert_array_equal(w_ch_names_pca, w_ch_names) assert n_nzero_pca == n_nzero assert whitener_pca.shape == (n_nzero_pca, len(w_ch_names)) # whiten_evoked evoked = read_evokeds(ave_fname)[0] evoked_white = whiten_evoked(evoked, cov) evoked_white_2 = whiten_evoked(evoked, cov_reorder) assert_allclose(evoked_white_2.data, evoked_white.data, atol=1e-7)
def test_sss_proj(): """Test `meg` proj option.""" raw = read_raw_fif(raw_fname) raw.crop(0, 1.0).load_data().pick_types(meg=True, exclude=()) raw.pick_channels(raw.ch_names[:51]).del_proj() raw_sss = maxwell_filter(raw, int_order=5, ext_order=2) sss_rank = 21 # really low due to channel picking assert len(raw_sss.info['projs']) == 0 for meg, n_proj, want_rank in (('separate', 6, sss_rank), ('combined', 3, sss_rank - 3)): proj = compute_proj_raw(raw_sss, n_grad=3, n_mag=3, meg=meg, verbose='error') this_raw = raw_sss.copy().add_proj(proj).apply_proj() assert len(this_raw.info['projs']) == n_proj sss_proj_rank = _compute_rank_int(this_raw) cov = compute_raw_covariance(this_raw, verbose='error') W, ch_names, rank = compute_whitener(cov, this_raw.info, return_rank=True) assert ch_names == this_raw.ch_names assert want_rank == sss_proj_rank == rank # proper reduction if meg == 'combined': assert this_raw.info['projs'][0]['data']['col_names'] == ch_names else: mag_names = ch_names[2::3] assert this_raw.info['projs'][3]['data']['col_names'] == mag_names
def test_sss_proj(): """Test `meg` proj option.""" raw = read_raw_fif(raw_fname) raw.crop(0, 1.0).load_data().pick_types(exclude=()) raw.pick_channels(raw.ch_names[:51]).del_proj() with pytest.raises(ValueError, match='can only be used with Maxfiltered'): compute_proj_raw(raw, meg='combined') raw_sss = maxwell_filter(raw, int_order=5, ext_order=2) sss_rank = 21 # really low due to channel picking assert len(raw_sss.info['projs']) == 0 for meg, n_proj, want_rank in (('separate', 6, sss_rank), ('combined', 3, sss_rank - 3)): proj = compute_proj_raw(raw_sss, n_grad=3, n_mag=3, meg=meg, verbose='error') this_raw = raw_sss.copy().add_proj(proj).apply_proj() assert len(this_raw.info['projs']) == n_proj sss_proj_rank = _compute_rank_int(this_raw) cov = compute_raw_covariance(this_raw, verbose='error') W, ch_names, rank = compute_whitener(cov, this_raw.info, return_rank=True) assert ch_names == this_raw.ch_names assert want_rank == sss_proj_rank == rank # proper reduction if meg == 'combined': assert this_raw.info['projs'][0]['data']['col_names'] == ch_names else: mag_names = ch_names[2::3] assert this_raw.info['projs'][3]['data']['col_names'] == mag_names
def test_compute_whitener(proj, pca): """Test properties of compute_whitener.""" raw = read_raw_fif(raw_fname).crop(0, 3).load_data() raw.pick_types(eeg=True, exclude=()) if proj: raw.apply_proj() else: raw.del_proj() with pytest.warns(RuntimeWarning, match='Too few samples'): cov = compute_raw_covariance(raw) W, _, C = compute_whitener(cov, raw.info, pca=pca, return_colorer=True, verbose='error') n_channels = len(raw.ch_names) n_reduced = len(raw.ch_names) rank = n_channels - len(raw.info['projs']) n_reduced = rank if pca is True else n_channels assert W.shape == C.shape[::-1] == (n_reduced, n_channels) # round-trip mults round_trip = np.dot(W, C) if pca is True: assert_allclose(round_trip, np.eye(n_reduced), atol=1e-7) elif pca == 'white': # Our first few rows/cols are zeroed out in the white space assert_allclose(round_trip[-rank:, -rank:], np.eye(rank), atol=1e-7) else: assert pca is False assert_allclose(round_trip, np.eye(n_channels), atol=0.05)
def test_compute_whitener(proj, pca): """Test properties of compute_whitener.""" raw = read_raw_fif(raw_fname).crop(0, 3).load_data() raw.pick_types(meg=True, eeg=True, exclude=()) if proj: raw.apply_proj() else: raw.del_proj() with pytest.warns(RuntimeWarning, match='Too few samples'): cov = compute_raw_covariance(raw) W, _, C = compute_whitener(cov, raw.info, pca=pca, return_colorer=True, verbose='error') n_channels = len(raw.ch_names) n_reduced = len(raw.ch_names) rank = n_channels - len(raw.info['projs']) n_reduced = rank if pca is True else n_channels assert W.shape == C.shape[::-1] == (n_reduced, n_channels) # round-trip mults round_trip = np.dot(W, C) if pca is True: assert_allclose(round_trip, np.eye(n_reduced), atol=1e-7) elif pca == 'white': # Our first few rows/cols are zeroed out in the white space assert_allclose(round_trip[-rank:, -rank:], np.eye(rank), atol=1e-7) else: assert pca is False assert_allclose(round_trip, np.eye(n_channels), atol=0.05)
def test_cov_order(): """Test covariance ordering.""" info = read_info(raw_fname) # add MEG channel with low enough index number to affect EEG if # order is incorrect info['bads'] += ['MEG 0113'] ch_names = [ info['ch_names'][pick] for pick in pick_types(info, meg=False, eeg=True) ] cov = read_cov(cov_fname) # no avg ref present warning prepare_noise_cov(cov, info, ch_names, verbose='error') # big reordering cov_reorder = cov.copy() order = np.random.RandomState(0).permutation(np.arange(len(cov.ch_names))) cov_reorder['names'] = [cov['names'][ii] for ii in order] cov_reorder['data'] = cov['data'][order][:, order] # Make sure we did this properly _assert_reorder(cov_reorder, cov, order) # Now check some functions that should get the same result for both # regularize cov_reg = regularize(cov, info) cov_reg_reorder = regularize(cov_reorder, info) _assert_reorder(cov_reg_reorder, cov_reg, order) # prepare_noise_cov cov_prep = prepare_noise_cov(cov, info, ch_names) cov_prep_reorder = prepare_noise_cov(cov, info, ch_names) _assert_reorder(cov_prep, cov_prep_reorder, order=np.arange(len(cov_prep['names']))) # compute_whitener whitener, w_ch_names = compute_whitener(cov, info) whitener_2, w_ch_names_2 = compute_whitener(cov_reorder, info) assert_array_equal(w_ch_names_2, w_ch_names) assert_allclose(whitener_2, whitener) # whiten_evoked evoked = read_evokeds(ave_fname)[0] evoked_white = whiten_evoked(evoked, cov) evoked_white_2 = whiten_evoked(evoked, cov_reorder) assert_allclose(evoked_white_2.data, evoked_white.data)
def test_cov_order(): """Test covariance ordering.""" info = read_info(raw_fname) # add MEG channel with low enough index number to affect EEG if # order is incorrect info['bads'] += ['MEG 0113'] ch_names = [info['ch_names'][pick] for pick in pick_types(info, meg=False, eeg=True)] cov = read_cov(cov_fname) # no avg ref present warning prepare_noise_cov(cov, info, ch_names, verbose='error') # big reordering cov_reorder = cov.copy() order = np.random.RandomState(0).permutation(np.arange(len(cov.ch_names))) cov_reorder['names'] = [cov['names'][ii] for ii in order] cov_reorder['data'] = cov['data'][order][:, order] # Make sure we did this properly _assert_reorder(cov_reorder, cov, order) # Now check some functions that should get the same result for both # regularize cov_reg = regularize(cov, info) cov_reg_reorder = regularize(cov_reorder, info) _assert_reorder(cov_reg_reorder, cov_reg, order) # prepare_noise_cov cov_prep = prepare_noise_cov(cov, info, ch_names) cov_prep_reorder = prepare_noise_cov(cov, info, ch_names) _assert_reorder(cov_prep, cov_prep_reorder, order=np.arange(len(cov_prep['names']))) # compute_whitener whitener, w_ch_names = compute_whitener(cov, info) whitener_2, w_ch_names_2 = compute_whitener(cov_reorder, info) assert_array_equal(w_ch_names_2, w_ch_names) assert_allclose(whitener_2, whitener) # whiten_evoked evoked = read_evokeds(ave_fname)[0] evoked_white = whiten_evoked(evoked, cov) evoked_white_2 = whiten_evoked(evoked, cov_reorder) assert_allclose(evoked_white_2.data, evoked_white.data)
def _pre_whiten(self, data, info, picks): """Aux function.""" has_pre_whitener = hasattr(self, 'pre_whitener_') if not has_pre_whitener and self.noise_cov is None: # use standardization as whitener # Scale (z-score) the data by channel info = pick_info(info, picks) pre_whitener = np.empty([len(data), 1]) for ch_type in _DATA_CH_TYPES_SPLIT + ('eog', "ref_meg"): if _contains_ch_type(info, ch_type): if ch_type == 'seeg': this_picks = pick_types(info, meg=False, seeg=True) elif ch_type == 'ecog': this_picks = pick_types(info, meg=False, ecog=True) elif ch_type == 'eeg': this_picks = pick_types(info, meg=False, eeg=True) elif ch_type in ('mag', 'grad'): this_picks = pick_types(info, meg=ch_type) elif ch_type == 'eog': this_picks = pick_types(info, meg=False, eog=True) elif ch_type in ('hbo', 'hbr'): this_picks = pick_types(info, meg=False, fnirs=ch_type) elif ch_type == 'ref_meg': this_picks = pick_types(info, meg=False, ref_meg=True) else: raise RuntimeError( 'Should not be reached.' 'Unsupported channel {}'.format(ch_type)) pre_whitener[this_picks] = np.std(data[this_picks], axis=1)[:, None] data /= pre_whitener elif not has_pre_whitener and self.noise_cov is not None: from mne.cov import compute_whitener pre_whitener, _ = compute_whitener(self.noise_cov, info, picks) assert data.shape[0] == pre_whitener.shape[1] data = np.dot(pre_whitener, data) elif has_pre_whitener and self.noise_cov is None: data /= self.pre_whitener_ pre_whitener = self.pre_whitener_ else: data = np.dot(self.pre_whitener_, data) pre_whitener = self.pre_whitener_ return data, pre_whitener
def _multiv_normalize(epoch_train, epoch_test, cv_normalize_noise=None): if cv_normalize_noise not in ('epoch', 'baseline', None): raise ValueError("cv_normalize_noise must be one of {0}".format( ('epoch', 'baseline', None))) if cv_normalize_noise: log.info("Applying multivariate noise normalization " "with method '{0}'".format(cv_normalize_noise)) tmax = 0. if cv_normalize_noise == 'baseline' else None cov_train = mne.compute_covariance(epoch_train, tmax=tmax, method='shrunk') W_train, ch_names = compute_whitener(cov_train, epoch_train.info) # whiten both training and testing set epoch_train = np.array( [np.dot(W_train, e) for e in epoch_train.get_data()]) epoch_test = np.array( [np.dot(W_train, e) for e in epoch_test.get_data()]) else: epoch_train = epoch_train.get_data() epoch_test = epoch_test.get_data() return epoch_train, epoch_test
def _cov_rank(cov, info): # XXX : this should use the to appear compute_rank function return compute_whitener(cov, info, return_rank=True, verbose='error')[2]
def __init__(self, forward, data, noise_std=None, radius=None, neigh_std=None, n_parts=100, top_min=None, top_max=None, subsample=None, dip_mom_std=None, hyper_q=True, noise_cov=None, lam=0.25, max_n_dips=10, Fourier_transf=False, verbose=False): if not is_forward(forward): raise ValueError('Forward must be an instance of MNE' ' class Forward.') if not is_evoked(data): raise ValueError('Data must be an instance of MNE class ' 'Evoked or EvokedArray.') # 1) Choosen by the user self.fourier = Fourier_transf self.n_parts = n_parts self.lam = lam self.max_n_dips = max_n_dips self.subsample = subsample self.verbose = verbose self.hyper_q = hyper_q self.forward, _info_picked = _select_orient_forward( forward, data.info, noise_cov) self.source_space = forward['source_rr'] self.n_verts = self.source_space.shape[0] self.lead_field = forward['sol']['data'] self.distance_matrix = ssd.cdist(self.source_space, self.source_space) if radius is None: self.radius = initialize_radius(self.source_space) else: self.radius = radius print('Computing neighbours matrix...', end='') self.neigh = compute_neighbours_matrix(self.source_space, self.distance_matrix, self.radius) print('[done]') if neigh_std is None: self.neigh_std = self.radius / 2 else: self.neigh_std = neigh_std print('Computing neighbours probabilities...', end='') self.neigh_p = compute_neighbours_probability_matrix( self.neigh, self.source_space, self.distance_matrix, self.neigh_std) print('[done]') # Prepare data if is_evoked(data): _data = self._prepare_evoked_data(data, top_min, top_max) else: raise ValueError # Perform whitening if a noise covariance is provided if noise_cov is not None: if self.fourier: raise NotImplementedError( 'Still to implement whitening in the frequency domain') else: if is_evoked(data): _sf = np.sqrt(data.nave) elif is_epochs(data): _sf = 1.0 else: raise ValueError whitener, _ = compute_whitener(noise_cov, info=_info_picked, pca=True, picks=_info_picked['ch_names']) _data = _sf * np.dot(whitener, _data) self.lead_field = (_sf * np.dot(whitener, self.lead_field)) print('Data and leadfield have been prewhitened.') self.r_data = _data.real del _data if dip_mom_std is None: print('Estimating dipole moment std...', end='') self.dip_mom_std = estimate_dip_mom_std(self.r_data, self.lead_field) print('[done]') print(' Estimated dipole moment std: {:.4e}'.format( self.dip_mom_std)) elif isinstance(dip_mom_std, float): self.dip_mom_std = dip_mom_std print('User defined dipole moment std: {:.4e}'.format( self.dip_mom_std)) else: raise ValueError( 'Dipole moment std must be either None or a float.') if self.hyper_q: print('Sampling hyperprior for dipole moment std.') if noise_std is None: print('Estimating noise std...', end='') self.noise_std = estimate_noise_std(self.r_data) print('[done]') print(' Estimated noise std: {:.4e}'.format(self.noise_std)) else: self.noise_std = noise_std print('User defined noise std: {:.4e}'.format(self.noise_std)) self._resample_it = list() self.est_n_dips = list() self.est_locs = list() self.est_dip_moms = None self.est_dip_mom_std = None self.final_dip_mom_std = None self.model_sel = list() self.pmap = list() if self.hyper_q: self.est_dip_mom_std = list( np.array([]) for _ in range(self.n_parts)) self.posterior = EmpPdf(self.n_parts, self.n_verts, self.lam, dip_mom_std=self.dip_mom_std, hyper_q=self.hyper_q, verbose=self.verbose) for _part in self.posterior.particles: if self.hyper_q: _aux = 0 _pos_def = _part._check_sigma(self.r_data, self.lead_field, self.noise_std) while _pos_def is False: _part.dip_mom_std = 10**(3 * np.random.rand()) * ( self.dip_mom_std / 35) _pos_def = _part._check_sigma(self.r_data, self.lead_field, self.noise_std) _aux += 1 if _aux == 100: raise ValueError _part.compute_loglikelihood_unit(self.r_data, self.lead_field, noise_std=self.noise_std)
def _cov_rank(cov, info): return compute_whitener(cov, info, return_rank=True, verbose='error')[2]
def __init__(self, forward, evoked, s_noise, radius=None, sigma_neigh=None, n_parts=100, sample_min=None, sample_max=None, subsample=None, s_q=None, cov=None, lam=0.25, N_dip_max=10, verbose=False): # 1) Choosen by the user self.n_parts = n_parts self.lam = lam self.N_dip_max = N_dip_max self.verbose = verbose self.forward, _info_picked = _select_orient_forward( forward, evoked.info, cov) self.source_space = forward['source_rr'] self.n_verts = self.source_space.shape[0] self.lead_field = forward['sol']['data'] self.distance_matrix = ssd.cdist(self.source_space, self.source_space) if radius is None: self.radius = self.initialize_radius() else: self.radius = radius print('Computing neighbours matrix...') self.neigh = self.create_neigh(self.radius) print('[done]') if sigma_neigh is None: self.sigma_neigh = self.radius / 2 else: self.sigma_neigh = sigma_neigh print('Computing neighbours probabilities...') self.neigh_p = self.create_neigh_p(self.sigma_neigh) print('[done]') if sample_min is None: self.s_min = 0 else: if isinstance(sample_min, (int, np.integer)): self.s_min = sample_min else: raise ValueError('sample_min index should be an integer') # self.ist_in = np.argmin(np.abs(evoked.times-time_in * 0.001)) # TODO: pensare meglio alla definizione di distanza (istante piu' vicino? o istante prima/dopo?) if sample_max is None: self.s_max = evoked.data.shape[1] - 1 else: # self.ist_fin = np.argmin(np.abs(evoked.times - time_fin * 0.001)) if isinstance(sample_max, (int, np.integer)): self.s_max = sample_max else: raise ValueError('sample_max index should be an integer') print('Analyzing data from {0} ms to {1} ms'.format( round(evoked.times[self.s_min], 4), round(evoked.times[self.s_max], 4))) if subsample is not None: self.subsample = subsample if subsample is not None: print('Subsampling data with step {0}'.format(subsample)) data = evoked.data[:, self.s_min:self.s_max + 1:subsample] else: data = evoked.data[:, self.s_min:self.s_max + 1] # Perform whitening if a noise covariance is provided if cov is not None: whitener, _ = compute_whitener(cov, info=_info_picked, pca=True, picks=_info_picked['ch_names']) data = np.sqrt(evoked.nave) * np.dot(whitener, data) self.lead_field = np.sqrt(evoked.nave) * np.dot( whitener, self.lead_field) self.r_data = data.real self.i_data = data.imag del data if s_q is None: print('Estimating dipole strength variance...') self.s_q = self.estimate_s_q() print('[done]') print(' Estimated dipole strength variance: {:.4e}'.format( self.s_q)) else: self.s_q = s_q if s_noise is None: print('Estimating noise variance...') self.s_noise = self.estimate_s_noise() print('[done]') print(' Estimated noise variance: {:.4e}'.format(self.s_noise)) else: self.s_noise = s_noise self._resample_it = list() self.est_n_dips = list() self.est_locs = list() self.est_q = np.array([]) self.model_sel = list() self.blob = list() self.SW_pv = list() self.emp = EmpPdf(self.n_parts, self.n_verts, self.lam, verbose=self.verbose) for _part in self.emp.particles: _part.compute_loglikelihood_unit(self.r_data, self.lead_field, self.s_noise, self.s_q)
def make_lcmv(info, forward, data_cov, reg=0.05, noise_cov=None, label=None, pick_ori=None, rank=None, weight_norm='unit-noise-gain', reduce_rank=False, verbose=None): """Compute LCMV spatial filter. Parameters ---------- info : dict The measurement info to specify the channels to include. Bad channels in info['bads'] are not used. forward : dict Forward operator. data_cov : Covariance The data covariance. reg : float The regularization for the whitened data covariance. noise_cov : Covariance The noise covariance. If provided, whitening will be done. Providing a noise covariance is mandatory if you mix sensor types, e.g. gradiometers with magnetometers or EEG with MEG. label : Label Restricts the LCMV solution to a given label. pick_ori : None | 'normal' | 'max-power' If 'normal', rather than pooling the orientations by taking the norm, only the radial component is kept. If 'max-power', the source orientation that maximizes output source power is chosen. If None, the solution depends on the forward model: if the orientation is fixed, a scalar beamformer is computed. If the forward model has free orientation, a vector beamformer is computed, combining the output for all source orientations. rank : None | int | dict Specified rank of the noise covariance matrix. If None, the rank is detected automatically. If int, the rank is specified for the MEG channels. A dictionary with entries 'eeg' and/or 'meg' can be used to specify the rank for each modality. weight_norm : 'unit-noise-gain' | 'nai' | None If 'unit-noise-gain', the unit-noise gain minimum variance beamformer will be computed (Borgiotti-Kaplan beamformer) [2]_, if 'nai', the Neural Activity Index [1]_ will be computed, if None, the unit-gain LCMV beamformer [2]_ will be computed. reduce_rank : bool If True, the rank of the leadfield will be reduced by 1 for each spatial location. Setting reduce_rank to True is typically necessary if you use a single sphere model for MEG. 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). Returns ------- filters | dict Beamformer weights. Notes ----- The original reference is [1]_. References ---------- .. [1] Van Veen et al. Localization of brain electrical activity via linearly constrained minimum variance spatial filtering. Biomedical Engineering (1997) vol. 44 (9) pp. 867--880 .. [2] Sekihara & Nagarajan. Adaptive spatial filters for electromagnetic brain imaging (2008) Springer Science & Business Media """ picks = _setup_picks(info, forward, data_cov, noise_cov) is_free_ori, ch_names, proj, vertno, G = \ _prepare_beamformer_input(info, forward, label, picks, pick_ori) data_cov = pick_channels_cov(data_cov, include=ch_names) Cm = data_cov['data'] # check number of sensor types present in the data # This line takes ~23 ms on kernprof # _check_one_ch_type(info, picks, noise_cov) # apply SSPs is_ssp = False if info['projs']: Cm = np.dot(proj, np.dot(Cm, proj.T)) is_ssp = True if noise_cov is not None: # Handle whitening + data covariance whitener, _ = compute_whitener(noise_cov, info, picks, rank=rank) # whiten the leadfield G = np.dot(whitener, G) # whiten data covariance Cm = np.dot(whitener, np.dot(Cm, whitener.T)) else: whitener = None # Tikhonov regularization using reg parameter d to control for # trade-off between spatial resolution and noise sensitivity Cm_inv, d = _reg_pinv(Cm.copy(), reg) if weight_norm is not None: # estimate noise level based on covariance matrix, taking the # smallest eigenvalue that is not zero noise, _ = linalg.eigh(Cm) if rank is not None: rank_Cm = rank else: rank_Cm = estimate_rank(Cm, tol='auto', norm=False, return_singular=False) noise = noise[len(noise) - rank_Cm] # use either noise floor or regularization parameter d noise = max(noise, d) # Compute square of Cm_inv used for weight normalization Cm_inv_sq = np.dot(Cm_inv, Cm_inv) del Cm # leadfield rank and optional rank reduction if reduce_rank: if not pick_ori == 'max-power': raise NotImplementedError('The computation of spatial filters ' 'with rank reduction using reduce_rank ' 'parameter is only implemented with ' 'pick_ori=="max-power".') if not isinstance(reduce_rank, bool): raise ValueError('reduce_rank has to be True or False ' ' (got %s).' % reduce_rank) # Compute spatial filters W = np.dot(G.T, Cm_inv) n_orient = 3 if is_free_ori else 1 n_sources = G.shape[1] // n_orient TMP = np.dot(G.T, Cm_inv_sq) G = np.asfortranarray(G) max_ori = np.empty(n_orient * n_sources, order='F') pwr = np.empty(n_sources, order='F') tmp_prod = _beam_loop(n_sources, W, G, n_orient, TMP) max_ori = stacked_power_iteration(tmp_prod) W = multiply_by_orientations_rowwise(W, max_ori) G_or = multiply_by_orientations_columnwise(G, max_ori) TMP_or = multiply_by_orientations_rowwise(TMP, max_ori) pwr = np.array([TMP_or[k, :] @ G_or[:, k] for k in range(n_sources)]) denom = np.sqrt(pwr) W /= np.expand_dims(denom, axis=1) is_free_ori = False filters = dict(weights=W, data_cov=data_cov, noise_cov=noise_cov, whitener=whitener, weight_norm=weight_norm, pick_ori=pick_ori, ch_names=ch_names, proj=proj, is_ssp=is_ssp, vertices=vertno, is_free_ori=is_free_ori, nsource=forward['nsource'], src=deepcopy(forward['src'])) return filters
def gen_covariances(p, subjects, run_indices, decim): """Generate forward solutions Can only complete successfully once preprocessing is performed. Parameters ---------- p : instance of Parameters Analysis parameters. subjects : list of str Subject names to analyze (e.g., ['Eric_SoP_001', ...]). run_indices : array-like | None Run indices to include. decim : list of int The subject decimations. """ for si, subj in enumerate(subjects): print(' Subject %2d/%2d...' % (si + 1, len(subjects)), end='') cov_dir = op.join(p.work_dir, subj, p.cov_dir) if not op.isdir(cov_dir): os.mkdir(cov_dir) has_rank_arg = 'rank' in get_args(compute_covariance) kwargs = dict() kwargs_erm = dict() if p.cov_rank == 'full': # backward compat if has_rank_arg: kwargs['rank'] = 'full' else: if not has_rank_arg: raise RuntimeError( 'There is no "rank" argument of compute_covariance, ' 'you need to update MNE-Python') if p.cov_rank is None: assert p.compute_rank # otherwise this is weird kwargs['rank'] = _compute_rank(p, subj, run_indices[si]) else: kwargs['rank'] = p.cov_rank kwargs_erm['rank'] = kwargs['rank'] if p.force_erm_cov_rank_full and has_rank_arg: kwargs_erm['rank'] = 'full' # Use the same thresholds we used for primary Epochs if p.autoreject_thresholds: reject = get_epochs_evokeds_fnames(p, subj, [])[0][1] reject = reject.replace('-epo.fif', '-reject.h5') reject = read_hdf5(reject) else: reject = _handle_dict(p.reject, subj) flat = _handle_dict(p.flat, subj) # Make empty room cov if p.runs_empty: if len(p.runs_empty) > 1: raise ValueError('Too many empty rooms; undefined output!') new_run = safe_inserter(p.runs_empty[0], subj) empty_cov_name = op.join( cov_dir, new_run + p.pca_extra + p.inv_tag + '-cov.fif') empty_fif = get_raw_fnames(p, subj, 'pca', 'only', False)[0] raw = read_raw_fif(empty_fif, preload=True) raw.pick_types(meg=True, eog=True, exclude='bads') use_reject, use_flat = _restrict_reject_flat(reject, flat, raw) if 'eeg' in use_reject: del use_reject['eeg'] if 'eeg' in use_flat: del use_flat['eeg'] cov = compute_raw_covariance(raw, reject=use_reject, flat=use_flat, method=p.cov_method, **kwargs_erm) write_cov(empty_cov_name, cov) # Make evoked covariances for ii, (inv_name, inv_run) in enumerate(zip(p.inv_names, p.inv_runs)): cov_name = op.join( cov_dir, safe_inserter(inv_name, subj) + ('-%d' % p.lp_cut) + p.inv_tag + '-cov.fif') if run_indices[si] is None: ridx = inv_run else: ridx = np.intersect1d(run_indices[si], inv_run) # read in raw files raw_fnames = get_raw_fnames(p, subj, 'pca', False, False, ridx) raws = [] first_samps = [] last_samps = [] for raw_fname in raw_fnames: raws.append(read_raw_fif(raw_fname, preload=False)) first_samps.append(raws[-1]._first_samps[0]) last_samps.append(raws[-1]._last_samps[-1]) _fix_raw_eog_cals(raws) # safe b/c cov only needs MEEG raw = concatenate_raws(raws) # read in events events = _read_events(p, subj, ridx, raw) if p.pick_events_cov is not None: old_count = sum(len(e) for e in events) if callable(p.pick_events_cov): picker = p.pick_events_cov else: picker = p.pick_events_cov[ii] events = picker(events) new_count = len(events) print(' Using %s/%s events for %s' % (new_count, old_count, op.basename(cov_name))) # create epochs use_reject, use_flat = _restrict_reject_flat(reject, flat, raw) baseline = _get_baseline(p) epochs = Epochs( raw, events, event_id=None, tmin=baseline[0], tmax=baseline[1], baseline=(None, None), proj=False, reject=use_reject, flat=use_flat, preload=True, decim=decim[si], verbose='error', # ignore decim-related warnings on_missing=p.on_missing, reject_by_annotation=p.reject_epochs_by_annot) epochs.pick_types(meg=True, eeg=True, exclude=[]) cov = compute_covariance(epochs, method=p.cov_method, **kwargs) if kwargs.get('rank', None) not in (None, 'full'): want_rank = sum(kwargs['rank'].values()) out_rank = compute_whitener(cov, epochs.info, return_rank=True, verbose='error')[2] if want_rank != out_rank: # Hopefully we never hit this code path, but let's keep # some debugging stuff around just in case plot_cov(cov, epochs.info) epochs_fnames, _ = get_epochs_evokeds_fnames( p, subj, p.analyses) epochs2 = read_epochs(epochs_fnames[1], preload=True) idx = np.searchsorted(epochs.events[:, 0], epochs2.events[:, 0]) assert len(np.unique(idx)) == len(idx) epochs = epochs[idx] assert np.array_equal(epochs.events[:, 0], epochs2.events[:, 0]) epochs2.pick_types(meg=True, eeg=True, exclude=[]) import matplotlib.pyplot as plt plt.figure() for eps in (epochs, epochs2): eps = eps.get_data().transpose([1, 0, 2]) eps = eps.reshape(len(eps), -1) plt.plot( np.log10(np.maximum(linalg.svdvals(eps), 1e-50))) epochs.plot() baseline = _get_baseline(p) epochs2.copy().crop(*baseline).plot() raise RuntimeError('Error computing rank') write_cov(cov_name, cov) print()