def test_filter_auto(): """Test filter auto parameters""" # test that our overlap-add filtering doesn't introduce strange # artifacts (from mne_analyze mailing list 2015/06/25) N = 300 sfreq = 100. lp = 10. sine_freq = 1. x = np.ones(N) t = np.arange(N) / sfreq x += np.sin(2 * np.pi * sine_freq * t) x_orig = x.copy() x_filt = filter_data(x, sfreq, None, lp) assert_array_equal(x, x_orig) # the firwin2 function gets us this close assert_allclose(x, x_filt, rtol=1e-4, atol=1e-4) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, None)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, copy=False)) assert_array_equal(x, x_filt) # degenerate conditions assert_raises(ValueError, filter_data, x, -sfreq, 1, 10) assert_raises(ValueError, filter_data, x, sfreq, 1, sfreq * 0.75) assert_raises(TypeError, filter_data, x.astype(np.float32), sfreq, None, 10, filter_length='auto', h_trans_bandwidth='auto')
def _instant_phase(data, freqs, sfreq, n_cycles=None, method="wavelet", freq_band=2, cuda=False, n_jobs=1): if method == "wavelet": phases = tfr_array_morlet(data, sfreq, freqs, n_cycles=n_cycles, output="phase", n_jobs=n_jobs) if method == "hilbert": phases = np.empty( (data.shape[0], data.shape[1], len(freqs), data.shape[2])) for freq_idx, freq in enumerate(list(freqs)): if cuda: temp_data = filter_data(data, sfreq, l_freq=freq - freq_band / 2, h_freq=freq + freq_band / 2, n_jobs="cuda") else: temp_data = filter_data(data, sfreq, l_freq=freq - freq_band / 2, h_freq=freq + freq_band / 2, n_jobs=n_jobs) analytic_signal = hilbert(temp_data) phases[:, :, freq_idx, :] = np.angle(analytic_signal) return phases
def test_filter_auto(): """Test filter auto parameters""" # test that our overlap-add filtering doesn't introduce strange # artifacts (from mne_analyze mailing list 2015/06/25) N = 300 sfreq = 100. lp = 10. sine_freq = 1. x = np.ones(N) t = np.arange(N) / sfreq x += np.sin(2 * np.pi * sine_freq * t) x_orig = x.copy() x_filt = low_pass_filter(x, sfreq, lp) assert_array_equal(x, x_orig) # the firwin2 function gets us this close assert_allclose(x, x_filt, rtol=1e-4, atol=1e-4) assert_array_equal(x_filt, low_pass_filter(x, sfreq, lp)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, copy=False)) assert_array_equal(x, x_filt) # degenerate conditions assert_raises(ValueError, filter_data, x, -sfreq, 1, 10) assert_raises(ValueError, filter_data, x, sfreq, 1, sfreq * 0.75) assert_raises(TypeError, filter_data, x.astype(np.float32), sfreq, None, 10, filter_length='auto', h_trans_bandwidth='auto')
def getOrthEnvelope(self, Index, ReferenceIndex, FreqBand, pad=100, LowPass=False): """ Function to compute the Orthogonalized Envelope of the indexed signal with respect to a reference signal. Is used create a plot the orthogonalized Envelope. """ Limits = FreqBand # Filter signal FilteredSignal = self.getFrequencyBand(Limits) # Get complex signal n_fft = next_fast_len(self.TimePoints) ComplexSignal = hilbert(FilteredSignal, N=n_fft, axis=-1)[:, :self.TimePoints] ComplexSignal = ComplexSignal[:,pad:-pad] # Get signal envelope and conjugate SignalEnv = np.abs(ComplexSignal) SignalConj = ComplexSignal.conj() OrthSignal = (ComplexSignal[Index] * (SignalConj[ReferenceIndex] / SignalEnv[ReferenceIndex])).imag OrthEnv = np.abs(OrthSignal) if LowPass: OrthEnv = filter_data(OrthEnv, self.fsample, 0, self.lowpass, fir_window='hamming', verbose=False) ReferenceEnv = filter_data(SignalEnv[ReferenceIndex], self.fsample, 0, self.lowpass, fir_window='hamming', verbose=False) else: ReferenceEnv = SignalEnv return OrthEnv, ReferenceEnv
def filter_and_make_analytic_signal(data, sfreq, l_phase_freq, h_phase_freq, l_amp_freq, h_amp_freq, method='fft', n_jobs=1): """ Filter data to required range and compute analytic signal from it. Parameters ---------- data : ndarray The signal to be analysed. l_phase_freq, h_phase_freq : float Low and high phase modulating frequencies. l_amp_freq, h_amp_freq : float Low and high amplitude modulated frequencies. method : 'fft' or 'iir' Filter method to be used. (mne.filter.filter_data) n_jobs : int Number of parallel jobs to run. Returns ------- theta : ndarray Low frequency filtered signal (modulating) gamma : ndarray High frequency filtered signal (modulated) phase : ndarray Phase of low frequency signal above. amp : ndarray Amplitude envelope of the high freq. signal above. """ # filter theta and gamma signals n_jobs = 4 method = 'fft' l_phase_freq, h_phase_freq, l_amp_freq, h_amp_freq = 6, 10, 60, 150 theta = filter_data(data, sfreq, l_phase_freq, h_phase_freq, n_jobs=njobs, method=method) gamma = filter_data(data, sfreq, l_amp_freq, h_amp_freq, n_jobs=njobs, method=method) # phase of the low freq modulating signal phase = np.angle(hilbert(theta)) # amplitude envelope of the high freq modulated signal amp = np.abs(hilbert(gamma)) return theta, gamma, phase, amp
def get_baseline_alpha(streamer, EEGdevice=7, oz_channel=4, seconds=20, fs=300, verbose=True): '''Calculating alpha baseline with eyes open args: - streamer: DSI/Enobio Streamer object - buffer_length: the number of data points used for hilbert power - seconds: base ''' if EEGdevice == 7: num_channels = 7 # clear buffer streamer.clear_out_buffer() # save the power powers = [] # start collecting for eyes open if verbose: print('Keep your eyes open!') print("Start calculating baseline...") data = np.zeros((seconds // 2 * fs, num_channels)) for i in range(seconds // 2 * fs): data[i] = streamer.out_buffer_queue.get()[:-1] # get Oz print(np.shape(data)) Oz = data[:, oz_channel] Oz_filter = filter_data(Oz, fs, 8, 12, verbose='ERROR') power_open = (np.abs(scisig.hilbert(Oz_filter))**2).mean() if verbose: print("Baseline calculation finished!") print('Baseline (eyes open): ' + str(power_open)) # start collecting for eyes closed if verbose: print('Keep your eyes closed!') print("Start calculating baseline...") data = np.zeros((seconds // 2 * fs, num_channels)) for i in range(seconds // 2 * fs): data[i] = streamer.out_buffer_queue.get()[:-1] # get Oz Oz = data[:, oz_channel] Oz_filter = filter_data(Oz, fs, 8, 12, verbose='ERROR') power_closed = (np.abs(scisig.hilbert(Oz_filter))**2).mean() if verbose: print("Baseline calculation finished!") print('Baseline (eyes closed): ' + str(power_closed)) return power_open, power_closed elif EEGdevice == 8: num_channels = 8 # TO DO, MAKE THIS WORK print('Just temporarily setting threshold values now') power_open = 10 power_closed = 100 return power_open, power_closed
def test_filter_array(): """Test filtering an array.""" for data in (np.zeros((11, 1, 10)), np.zeros((9, 1, 10))): filter_data(data, 512., 8, 12, method='iir', iir_params=dict(ftype='butterworth', order=2))
def test_n_jobs(n_jobs): """Test resampling against SciPy.""" x = np.random.RandomState(0).randn(4, 100) y1 = resample(x, 2, 1, n_jobs=None) y2 = resample(x, 2, 1, n_jobs=n_jobs) assert_allclose(y1, y2) y1 = filter_data(x, 100., 0, 40, n_jobs=None) y2 = filter_data(x, 100., 0, 40, n_jobs=n_jobs) assert_allclose(y1, y2)
def test_iir_stability(): """Test IIR filter stability check.""" sig = np.empty(1000) sfreq = 1000 # This will make an unstable filter, should throw RuntimeError assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(ftype='butter', order=8, output='ba')) # This one should work just fine filter_data(sig, sfreq, 0.6, None, method='iir', iir_params=dict(ftype='butter', order=8, output='sos')) # bad system type assert_raises(ValueError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(ftype='butter', order=8, output='foo')) # missing ftype assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(order=8, output='sos')) # bad ftype assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(order=8, ftype='foo', output='sos')) # missing gstop assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(gpass=0.5, output='sos')) # can't pass iir_params if method='fft' assert_raises(ValueError, filter_data, sig, sfreq, 0.1, None, method='fft', iir_params=dict(ftype='butter', order=2, output='sos')) # method must be string assert_raises(TypeError, filter_data, sig, sfreq, 0.1, None, method=1) # unknown method assert_raises(ValueError, filter_data, sig, sfreq, 0.1, None, method='blah') # bad iir_params assert_raises(TypeError, filter_data, sig, sfreq, 0.1, None, method='iir', iir_params='blah') assert_raises(ValueError, filter_data, sig, sfreq, 0.1, None, method='fft', iir_params=dict()) # should pass because dafault trans_bandwidth is not relevant iir_params = dict(ftype='butter', order=2, output='sos') x_sos = filter_data(sig, 250, 0.5, None, method='iir', iir_params=iir_params) iir_params_sos = construct_iir_filter(iir_params, f_pass=0.5, sfreq=250, btype='highpass') x_sos_2 = filter_data(sig, 250, 0.5, None, method='iir', iir_params=iir_params_sos) assert_allclose(x_sos[100:-100], x_sos_2[100:-100]) x_ba = filter_data(sig, 250, 0.5, None, method='iir', iir_params=dict(ftype='butter', order=2, output='ba')) # Note that this will fail for higher orders (e.g., 6) showing the # hopefully decreased numerical error of SOS assert_allclose(x_sos[100:-100], x_ba[100:-100])
def test_iir_stability(): """Test IIR filter stability check.""" sig = np.random.RandomState(0).rand(1000) sfreq = 1000 # This will make an unstable filter, should throw RuntimeError pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(ftype='butter', order=8, output='ba')) # This one should work just fine filter_data(sig, sfreq, 0.6, None, method='iir', iir_params=dict(ftype='butter', order=8, output='sos')) # bad system type pytest.raises(ValueError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(ftype='butter', order=8, output='foo')) # missing ftype pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(order=8, output='sos')) # bad ftype pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(order=8, ftype='foo', output='sos')) # missing gstop pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None, method='iir', iir_params=dict(gpass=0.5, output='sos')) # can't pass iir_params if method='fft' pytest.raises(ValueError, filter_data, sig, sfreq, 0.1, None, method='fft', iir_params=dict(ftype='butter', order=2, output='sos')) # method must be string pytest.raises(TypeError, filter_data, sig, sfreq, 0.1, None, method=1) # unknown method pytest.raises(ValueError, filter_data, sig, sfreq, 0.1, None, method='blah') # bad iir_params pytest.raises(TypeError, filter_data, sig, sfreq, 0.1, None, method='iir', iir_params='blah') pytest.raises(ValueError, filter_data, sig, sfreq, 0.1, None, method='fir', iir_params=dict()) # should pass because default trans_bandwidth is not relevant iir_params = dict(ftype='butter', order=2, output='sos') x_sos = filter_data(sig, 250, 0.5, None, method='iir', iir_params=iir_params) iir_params_sos = construct_iir_filter(iir_params, f_pass=0.5, sfreq=250, btype='highpass') x_sos_2 = filter_data(sig, 250, 0.5, None, method='iir', iir_params=iir_params_sos) assert_allclose(x_sos[100:-100], x_sos_2[100:-100]) x_ba = filter_data(sig, 250, 0.5, None, method='iir', iir_params=dict(ftype='butter', order=2, output='ba')) # Note that this will fail for higher orders (e.g., 6) showing the # hopefully decreased numerical error of SOS assert_allclose(x_sos[100:-100], x_ba[100:-100])
def modulation_index2d(data, sfreq): """ Compute the two dimensional modulation index. Parameters ---------- data : ndarray The signal data sfreq: float Sampling frequency Returns ------- mod2d : ndarray 2 dimensional modulation index """ from mne.filter import filter_data from scipy.signal import hilbert flow = np.arange(2, 40, 1) flow_step = 1.0 fhigh = np.arange(5, 205, 5) fhigh_step = 5.0 mod2d = np.zeros((flow.size, fhigh.size)) method = 'fft' n_jobs = 2 for i in range(0, flow.size): theta = filter_data(data, sfreq, flow[i], flow[i] + flow_step, method=method, n_jobs=n_jobs) theta = theta[sfreq:data.size - sfreq] phase = np.angle(hilbert(theta)) for j in range(0, fhigh.size): gamma = filter_data(data, sfreq, fhigh[j], fhigh[j] + fhigh_step, method=method, n_jobs=n_jobs) gamma = gamma[sfreq:data.size - sfreq] amp = np.abs(hilbert(gamma)) # compute the modulation index m_norm_length = modulation_index1d(amp, phase, sfreq) mod2d[i, j] = m_norm_length return mod2d
def EpochBCIData(EEGdata, fs, move_starts, rest_starts, rest_ends): """ This function epochs the data """ if EEGdevice == 7: channels = EEGdata.columns[1:8] elif EEGdevice == 8: channels = EEGdata.columns[0:8] epochs = [] epochs_norm = [] for movement in range(0, len(move_starts)): # Data for this movement t_start = move_starts[movement] - np.round(2.00 * fs) t_end = move_starts[movement] - np.round(0.250 * fs) # Baseline restOfInt = np.max(np.where(rest_starts < move_starts[movement])) tb_start = rest_starts[restOfInt] tb_end = rest_ends[restOfInt] # Note, baseline is filtered before it is used in the live script baseline_pre_filt = np.asarray( EEGdata.loc[tb_start:tb_end][channels]) * 1.0 baseline_filt = filter_data(baseline_pre_filt.T, sfreq=fs, l_freq=7, h_freq=31, verbose='ERROR') baseline = baseline_filt.T # Filter per epoch, like you would in real-time pre_filt = np.asarray(EEGdata.loc[t_start:t_end][channels]) * 1.0 filtered = filter_data(pre_filt.T, sfreq=fs, l_freq=7, h_freq=31, verbose='ERROR') epoch = pd.DataFrame(filtered.T) epoch.columns = EEGdata.columns[0:8] # Store epoch tmp = (epoch - np.mean(baseline, 0)) / np.std(baseline, 0) tmp = pd.DataFrame(tmp) tmp.columns = EEGdata.columns[0:8] epochs_norm.append(tmp) epochs.append(epoch) return epochs, epochs_norm
def test_cuda(): """Test CUDA-based filtering""" # NOTE: don't make test_cuda() the last test, or pycuda might spew # some warnings about clean-up failing # Also, using `n_jobs='cuda'` on a non-CUDA system should be fine, # as it should fall back to using n_jobs=1. sfreq = 500 sig_len_secs = 20 a = rng.randn(sig_len_secs * sfreq) kwargs = dict(fir_design='firwin') with catch_logging() as log_file: for fl in ['auto', '10s', 2048]: args = [a, sfreq, 4, 8, None, fl, 1.0, 1.0] bp = filter_data(*args, **kwargs) bp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(bp, bp_c, 12) args = [a, sfreq, 8 + 1.0, 4 - 1.0, None, fl, 1.0, 1.0] bs = filter_data(*args, **kwargs) bs_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(bs, bs_c, 12) args = [a, sfreq, None, 8, None, fl, 1.0] lp = filter_data(*args, **kwargs) lp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(lp, lp_c, 12) args = [lp, sfreq, 4, None, None, fl, 1.0] hp = filter_data(*args, **kwargs) hp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA out = log_file.getvalue().split('\n')[:-1] # triage based on whether or not we actually expected to use CUDA from mne.cuda import _cuda_capable # allow above funs to set it tot = 12 if _cuda_capable else 0 assert_true( sum(['Using CUDA for FFT FIR filtering' in o for o in out]) == tot) # check resampling for window in ('boxcar', 'triang'): for N in (997, 1000): # one prime, one even a = rng.randn(2, N) for fro, to in ((1, 2), (2, 1), (1, 3), (3, 1)): a1 = resample(a, fro, to, n_jobs=1, npad='auto', window=window) a2 = resample(a, fro, to, n_jobs='cuda', npad='auto', window=window) assert_allclose(a1, a2, rtol=1e-7, atol=1e-14) assert_array_almost_equal(a1, a2, 14) assert_array_equal(resample([0, 0], 2, 1, n_jobs='cuda'), [0., 0., 0., 0.]) assert_array_equal(resample(np.zeros(2, np.float32), 2, 1, n_jobs='cuda'), [0., 0., 0., 0.])
def getDataAtIndex(self,i): returnData = self.lslrec.data[i:i+self.samples][:] if self.do_channel_mask is True: mask = [2, 3, 4, 5, 6, 7, 14, 15, 16] returnData = filter.filter_data(returnData[:, mask].T, self.srate, l_freq=0.1, h_freq=None, method='iir', n_jobs=6) returnData = returnData.T return returnData
def simulate_data(freqs_sig=[9, 12], n_trials=100, n_channels=20, n_samples=500, samples_per_second=250, n_components=5, SNR=0.05, random_state=42): """Simulate data according to an instantaneous mixin model. Data are simulated in the statistical source space, where n=n_components sources contain the peak of interest. """ rng = np.random.RandomState(random_state) filt_params_signal = dict(l_freq=freqs_sig[0], h_freq=freqs_sig[1], l_trans_bandwidth=1, h_trans_bandwidth=1, fir_design='firwin') # generate an orthogonal mixin matrix mixing_mat = np.linalg.svd(rng.randn(n_channels, n_channels))[0] # define sources S_s = rng.randn(n_trials * n_samples, n_components) # filter source in the specific freq. band of interest S_s = filter_data(S_s.T, samples_per_second, **filt_params_signal).T S_n = rng.randn(n_trials * n_samples, n_channels - n_components) S = np.hstack((S_s, S_n)) # mix data X_s = np.dot(mixing_mat[:, :n_components], S_s.T).T X_n = np.dot(mixing_mat[:, n_components:], S_n.T).T # add noise X_s = X_s / np.linalg.norm(X_s, 'fro') X_n = X_n / np.linalg.norm(X_n, 'fro') X = SNR * X_s + (1 - SNR) * X_n X = X.T S = S.T return X, mixing_mat, S
def extract_band(data, fs, band='alpha'): """ Extract frequency band from eeg data Parameters ---------- data: ndarray Signal data to filter fs: int Sampling frequency band: str Frequency band to extract (delta, theta, alpha, beta, gamma) Returns ---------- filtered_data: ndarray Signal data constrained to given band """ bands = { 'delta': (None, 4), 'theta': (4, 8), 'alpha': (8, 12), 'beta': (12, 30), 'gamma': (30, None) } low_freq = bands[band][0] high_freq = bands[band][1] filtered_data = filter_data(data, fs, low_freq, high_freq) return (filtered_data)
def annotate_muscle_artifacts(raw, art_thresh=0.075, t_min=2, desc='Bad-muscle', n_jobs=1, return_stat_raw=False): """Find and annotation mucsle artifacts.""" raw = raw.copy() # pick meg_chans raw.info['comps'] = [] raw.pick_types(meg=True, ref_meg=False) raw.filter(110, 140, n_jobs=n_jobs, fir_design='firwin') raw.apply_hilbert(n_jobs=n_jobs, envelope=True) sfreq = raw.info['sfreq'] art_scores = stats.zscore(raw._data, axis=1) stat_raw = None art_scores_filt = filter_data(art_scores.mean(axis=0), sfreq, None, 5) art_mask = art_scores_filt > art_thresh if return_stat_raw: tmp_info = create_info(['mucsl_score'], raw.info['sfreq'], ['misc']) stat_raw = RawArray(art_scores_filt.reshape(1, -1), tmp_info) # remove artifact free periods under limit idx_min = t_min * sfreq comps, num_comps = label(art_mask == 0) for l in range(1, num_comps + 1): l_idx = np.nonzero(comps == l)[0] if len(l_idx) < idx_min: art_mask[l_idx] = True return _annotations_from_mask(raw.times, art_mask, desc), stat_raw
def test_filter_picks(): """Test filter picking.""" data = np.random.RandomState(0).randn(3, 1000) fs = 1000. kwargs = dict(l_freq=None, h_freq=40.) filt = filter_data(data, fs, **kwargs) # don't include seeg, dbs or stim in this list because they are in the one # below to ensure default cases are treated properly for kind in ('eeg', 'grad', 'emg', 'misc', 'dbs'): for picks in (None, [-2], kind, 'k'): # With always at least one data channel info = create_info(['s', 'k', 't'], fs, ['seeg', kind, 'stim']) raw = RawArray(data.copy(), info) raw.filter(picks=picks, **kwargs) if picks is None: if kind in _DATA_CH_TYPES_SPLIT: # should be included want = np.concatenate((filt[:2], data[2:])) else: # shouldn't want = np.concatenate((filt[:1], data[1:])) else: # just the kind of interest ([-2], kind, 'j' should be eq.) want = np.concatenate((data[:1], filt[1:2], data[2:])) assert_allclose(raw.get_data(), want) # Now with sometimes no data channels info = create_info(['k', 't'], fs, [kind, 'stim']) raw = RawArray(data[1:].copy(), info.copy()) if picks is None and kind not in _DATA_CH_TYPES_SPLIT: with pytest.raises(ValueError, match='yielded no channels'): raw.filter(picks=picks, **kwargs) else: raw.filter(picks=picks, **kwargs) want = want[1:] assert_allclose(raw.get_data(), want)
def load_file(filename, ch_names=None, skiprows=0, max_rows=0): """ Load data from file into mne RawArray for later use :param filename: filename for reading in form of relative path from working directory :param ch_names: dictionary having all or some channels like this: ch_names = {"af7":1, "af8":2, "tp9":3, "tp10":4} Key specifies position on head using 10-20 standard and Value referring to channel number on Cyton BCI board :return: RawArray class of mne.io library """ if ch_names is None: ch_names = {"af7":1, "af8":2, "tp9":3, "tp10":4} # Converter of BCI file to valuable data converter = {i: (microvolts_to_volts if i < 12 else lambda x: str(x).split(".")[1][:-1]) for i in range(0, 13)} info = mne.create_info( ch_names=list(ch_names.keys()), ch_types=['eeg' for i in range(0, len(ch_names))], sfreq=250, montage='standard_1020' ) data = np.loadtxt(filename, comments="%", delimiter=",", converters=converter, skiprows=skiprows, max_rows=max_rows).T data = data[list(ch_names.values())] data = filter_data(data, 250, l_freq=2, h_freq=50) # print ('data type', type(data), ' shape ' , data.shape) return mne.io.RawArray(data, info)
def _parallel_orth_corr(self, ComplexSignal, SignalEnv, ConjdivEnv): """ Computes orthogonalized correlation of the envelope of the complex signal (nx1 dim array) and the signal envelope (nxm dim array). This function is called by signal.getOrthFC() :param ComplexSignal Complex """ # Orthogonalize signal OrthSignal = (ComplexSignal * ConjdivEnv).imag OrthEnv = np.abs(OrthSignal) # Envelope Correlation if 'lowpass' in conn_mode: # Low-Pass filter OrthEnv = filter_data(OrthEnv, self.fsample, 0, self.lowpass, fir_window='hamming', verbose=False) SignalEnv = filter_data(SignalEnv, self.fsample, 0, self.lowpass, fir_window='hamming', verbose=False) corr_mat = pearson(OrthEnv, SignalEnv) corr = np.diag(corr_mat) return corr
def filter_to_frequency_band(signals: np.ndarray, sfreq: int, lower: int, upper: int) -> np.ndarray: """ filter signals to frequency range defined by upper and lower """ return filter_data(data=signals, sfreq=sfreq, l_freq=lower, h_freq=upper, verbose='error')
def test_cuda(): """Test CUDA-based filtering""" # NOTE: don't make test_cuda() the last test, or pycuda might spew # some warnings about clean-up failing # Also, using `n_jobs='cuda'` on a non-CUDA system should be fine, # as it should fall back to using n_jobs=1. sfreq = 500 sig_len_secs = 20 a = rng.randn(sig_len_secs * sfreq) kwargs = dict(fir_design='firwin') with catch_logging() as log_file: for fl in ['auto', '10s', 2048]: args = [a, sfreq, 4, 8, None, fl, 1.0, 1.0] bp = filter_data(*args, **kwargs) bp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(bp, bp_c, 12) args = [a, sfreq, 8 + 1.0, 4 - 1.0, None, fl, 1.0, 1.0] bs = filter_data(*args, **kwargs) bs_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(bs, bs_c, 12) args = [a, sfreq, None, 8, None, fl, 1.0] lp = filter_data(*args, **kwargs) lp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(lp, lp_c, 12) args = [lp, sfreq, 4, None, None, fl, 1.0] hp = filter_data(*args, **kwargs) hp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA out = log_file.getvalue().split('\n')[:-1] # triage based on whether or not we actually expected to use CUDA from mne.cuda import _cuda_capable # allow above funs to set it tot = 12 if _cuda_capable else 0 assert_true(sum(['Using CUDA for FFT FIR filtering' in o for o in out]) == tot) # check resampling for window in ('boxcar', 'triang'): for N in (997, 1000): # one prime, one even a = rng.randn(2, N) for fro, to in ((1, 2), (2, 1), (1, 3), (3, 1)): a1 = resample(a, fro, to, n_jobs=1, npad='auto', window=window) a2 = resample(a, fro, to, n_jobs='cuda', npad='auto', window=window) assert_allclose(a1, a2, rtol=1e-7, atol=1e-14) assert_array_almost_equal(a1, a2, 14) assert_array_equal(resample([0, 0], 2, 1, n_jobs='cuda'), [0., 0., 0., 0.]) assert_array_equal(resample(np.zeros(2, np.float32), 2, 1, n_jobs='cuda'), [0., 0., 0., 0.])
def load_raw_data(df, sampling_rate, path): data_list = [] for f in tqdm(df.filename_hr, desc='Reading signal...'): data = wfdb.rdsamp(path + f) # bandpass filter data = filter_data(data[0].T, 500, 0.5, 50, verbose='ERROR') data_list.append(data) data_list = np.array(data_list) return data_list
def test_filter_auto(): """Test filter auto parameters""" # test that our overlap-add filtering doesn't introduce strange # artifacts (from mne_analyze mailing list 2015/06/25) N = 300 sfreq = 100. lp = 10. sine_freq = 1. x = np.ones(N) t = np.arange(N) / sfreq x += np.sin(2 * np.pi * sine_freq * t) x_orig = x.copy() for pad in ('reflect_limited', 'reflect', 'edge'): for fir_design in ('firwin2', 'firwin'): kwargs = dict(fir_design=fir_design, pad=pad) x = x_orig.copy() x_filt = filter_data(x, sfreq, None, lp, **kwargs) assert_array_equal(x, x_orig) n_edge = 10 assert_allclose(x[n_edge:-n_edge], x_filt[n_edge:-n_edge], atol=1e-2) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, None, **kwargs)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, **kwargs)) assert_array_equal(x, x_orig) assert_array_equal( x_filt, filter_data(x, sfreq, None, lp, copy=False, **kwargs)) assert_array_equal(x, x_filt) # degenerate conditions assert_raises(ValueError, filter_data, x, -sfreq, 1, 10) assert_raises(ValueError, filter_data, x, sfreq, 1, sfreq * 0.75) assert_raises(TypeError, filter_data, x.astype(np.float32), sfreq, None, 10, filter_length='auto', h_trans_bandwidth='auto', **kwargs)
def low_pass(data, sfreq, hfreq): channels = data.columns[:16].values for i in channels: print("Low-pass filtering channel %i / %i: %s" % (np.where(channels == i)[0] + 1, len(channels), i)) data[i] = filter_data(data[i], sfreq=sfreq, l_freq=None, h_freq=hfreq, verbose=False) return data
def getFrequencyBand(self, Limits): """ Band pass filters signal from each region :param Limits: int, specifies limits of the frequency band :return: filter Signal """ lowerfreq = Limits[0] upperfreq = Limits[1] filteredSignal = filter_data(self.Signal, self.fsample, l_freq=lowerfreq, h_freq=upperfreq, fir_window='hamming', verbose=False) return filteredSignal
def filter_data_ecog(training_data_ecog): """Filters data using mne.filter Cutoff frequencies set to 8/30 Hz Args: training_data_ecog (np.ndarray): contains the loaded data from .mat-files Returns: np.ndarray: filtered data """ filtered_data_ecog = filter.filter_data(data=training_data_ecog , sfreq=1000, l_freq=10, h_freq=25, method="iir", n_jobs=6) return filtered_data_ecog
def make_cube_on_spike_triggers(filename, spike_times, high_pass_freq=500, num_of_points_in_spike_triggered_cube=100): filtered_data_type = np.float64 num_of_spikes = len(spike_times) num_of_points_for_padding = 50 shape_of_filt_spike_triggered_cube = ( (len(ec_channels), num_of_points_in_spike_triggered_cube, num_of_spikes)) spike_triggered_cube_hp = np.memmap( filename, dtype=np.int16, mode='w+', shape=shape_of_filt_spike_triggered_cube) for spike in np.arange(0, num_of_spikes): trigger_point = negative_extra_spike_times[spike] start_point = int(trigger_point - (num_of_points_in_spike_triggered_cube + num_of_points_for_padding) / 2) if start_point < 0: break end_point = int(trigger_point + (num_of_points_in_spike_triggered_cube + num_of_points_for_padding) / 2) if end_point > extra_data.shape[1]: break temp_unfiltered = extra_data[:, start_point:end_point] temp_unfiltered = temp_unfiltered.astype(filtered_data_type) iir_params = {'order': 4, 'ftype': 'butter', 'padlen': 0} temp_filtered = filters.filter_data( temp_unfiltered, sampling_freq, l_freq=high_pass_freq, h_freq=None, method='iir', iir_params=iir_params) # 4th order Butter with no padding temp_filtered = temp_filtered[:, int(num_of_points_for_padding / 2):-int(num_of_points_for_padding / 2)] spike_triggered_cube_hp[:, :, spike] = temp_filtered if spike % 100 == 0: print('Done ' + str(spike) + 'spikes') return spike_triggered_cube_hp
def filter_data(self): """Filter data. """ dialog = FilterDialog(self) if dialog.exec_(): low, high = dialog.low, dialog.high tmp = filter_data(self.all.current.raw._data, self.all.current.raw.info["sfreq"], l_freq=low, h_freq=high) name = self.all.current.name + " ({}-{} Hz)".format(low, high) new = DataSet(raw=mne.io.RawArray(tmp, self.all.current.raw.info), name=name, events=self.all.current.events) self.history.append("raw.filter({}, {})".format(low, high)) self._update_datasets(new)
def test_filter_auto(): """Test filter auto parameters.""" # test that our overlap-add filtering doesn't introduce strange # artifacts (from mne_analyze mailing list 2015/06/25) N = 300 sfreq = 100. lp = 10. sine_freq = 1. x = np.ones(N) t = np.arange(N) / sfreq x += np.sin(2 * np.pi * sine_freq * t) x_orig = x.copy() for pad in ('reflect_limited', 'reflect', 'edge'): for fir_design in ('firwin2', 'firwin'): kwargs = dict(fir_design=fir_design, pad=pad) x = x_orig.copy() x_filt = filter_data(x, sfreq, None, lp, **kwargs) assert_array_equal(x, x_orig) n_edge = 10 assert_allclose(x[n_edge:-n_edge], x_filt[n_edge:-n_edge], atol=1e-2) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, None, **kwargs)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, **kwargs)) assert_array_equal(x, x_orig) assert_array_equal(x_filt, filter_data(x, sfreq, None, lp, copy=False, **kwargs)) assert_array_equal(x, x_filt) # degenerate conditions pytest.raises(ValueError, filter_data, x, -sfreq, 1, 10) pytest.raises(ValueError, filter_data, x, sfreq, 1, sfreq * 0.75) pytest.raises(TypeError, filter_data, x.astype(np.float32), sfreq, None, 10, filter_length='auto', h_trans_bandwidth='auto', **kwargs)
def __call__(self, tensor): """ Args: tensor (Tensor): Tensor of size (..., T) to be filtered and downsampled. Returns: Tensor: Filtered and downsampled channels """ tensor = filter_data(tensor.astype(np.float64), self.sfreq, l_freq=self.low, h_freq=self.high, n_jobs=self.njobs, verbose=False) return resample(tensor, down=self.downsample, verbose=False).astype(np.float32)
def find_oscillation_events(arr, direction, sfreq, h_freq=5, thresh=None): ''' Idiosyncratic function designed to detect motion/null events in botfly oscillation-motion recordings. Roughly, works by: 1. Filter: lowpass filters stimulus (drum) recording to smooth input signal. 2. Peak finding: identify minima and maxima of drum signal. 3. Events: Reorganize info as an [Nx3] array of [start, stop, condition], where {CCW = 1, CW = 2} INPUTS -- arr: stimulus (drum) signal -- direction: CCW or CW -- sfreq: sampling frequency -- h_freq: lowpass frequency. If set to False, no lowpass applied. ''' assert direction == 'CCW' or direction == 'CW' ## Filter data. if h_freq: arr = filter_data(arr, sfreq, l_freq=None, h_freq=h_freq, phase='zero', verbose=False) ## Identify extrema. maxima, _ = peak_finder(arr, thresh=thresh, extrema=1) minima, _ = peak_finder(arr, thresh=thresh, extrema=-1) ## Re-organize into events. events = np.sort(np.concatenate([maxima, minima])) events = np.array([events[i:i + 2] for i in range(events.size - 1)]) if not events.size: raise ValueError('No events detected. Check paramaters.') ## Demarcate null/motion events. events = np.concatenate( [events, np.zeros(events.shape[0], dtype=int).reshape(-1, 1)], axis=-1) if direction == 'CCW': events[np.in1d(events[:, 0], maxima), -1] = 1 events[np.in1d(events[:, 0], minima), -1] = 2 else: events[np.in1d(events[:, 0], maxima), -1] = 2 events[np.in1d(events[:, 0], minima), -1] = 1 return events
def extract(input_): ix, path_to_a_file = input_ data = np.load(path_to_a_file).item() data = np.array([data[key].reshape(-1) for key in label_list]) data = filter_data( data, sfreq=250, l_freq=None, h_freq=30, method="fir", phase="minimum", n_jobs=1 ) # # baseline data = rescale(data, times, (-0.1, 0.0), mode="mean") data = rescale(data, times, (1.6, 2.6), mode="mean") data_dict[ix] = data
def _filt(sfreq, data, filter_freqs, verbose=False): """Filter data. Utility function to filter data which acts as a wrapper for ``mne.filter.filter_data`` ([Mne]_). Parameters ---------- sfreq : float Sampling rate of the data. data : ndarray, shape (n_channels, n_times) filter_freqs : array-like, shape (2,) Array of cutoff frequencies. If ``filter_freqs[0]`` is None, a low-pass filter is used. If ``filter_freqs[1]`` is None, a high-pass filter is used. If both ``filter_freqs[0]``, ``filter_freqs[1]`` are not None and ``filter_freqs[0] < filter_freqs[1]``, a band-pass filter is used. Eventually, if both ``filter_freqs[0]``, ``filter_freqs[1]`` are not None and ``filter_freqs[0] > filter_freqs[1]``, a band-stop filter is used. verbose : bool (default: False) Verbosity parameter. If True, info and warnings related to ``mne.filter.filter_data`` are printed. Returns ------- output : ndarray, shape (n_channels, n_times) References ---------- .. [Mne] https://mne-tools.github.io/stable/ """ if filter_freqs[0] is None and filter_freqs[1] is None: raise ValueError('The values of `filter_freqs` cannot all be None.') else: _verbose = 40 * (1 - int(verbose)) return filter_data(data, sfreq=sfreq, l_freq=filter_freqs[0], h_freq=filter_freqs[1], picks=None, fir_design='firwin', verbose=_verbose)
def test_cuda_fir(): """Test CUDA-based filtering.""" # Using `n_jobs='cuda'` on a non-CUDA system should be fine, # as it should fall back to using n_jobs=1. sfreq = 500 sig_len_secs = 20 a = rng.randn(sig_len_secs * sfreq) kwargs = dict(fir_design='firwin') with catch_logging() as log_file: for fl in ['auto', '10s', 2048]: args = [a, sfreq, 4, 8, None, fl, 1.0, 1.0] bp = filter_data(*args, **kwargs) bp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(bp, bp_c, 12) args = [a, sfreq, 8 + 1.0, 4 - 1.0, None, fl, 1.0, 1.0] bs = filter_data(*args, **kwargs) bs_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(bs, bs_c, 12) args = [a, sfreq, None, 8, None, fl, 1.0] lp = filter_data(*args, **kwargs) lp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(lp, lp_c, 12) args = [lp, sfreq, 4, None, None, fl, 1.0] hp = filter_data(*args, **kwargs) hp_c = filter_data(*args, n_jobs='cuda', verbose='info', **kwargs) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA out = log_file.getvalue().split('\n')[:-1] # triage based on whether or not we actually expected to use CUDA from mne.cuda import _cuda_capable # allow above funs to set it tot = 12 if _cuda_capable else 0 assert sum(['Using CUDA for FFT FIR filtering' in o for o in out]) == tot if not _cuda_capable: pytest.skip('CUDA not enabled')
evoked_std = epochs_standard.average() evoked_dev = epochs_deviant.average() del epochs_standard, epochs_deviant ############################################################################### # Typical preprocessing step is the removal of power line artifact (50 Hz or # 60 Hz). Here we notch filter the data at 60, 120 and 180 to remove the # original 60 Hz artifact and the harmonics. Normally this would be done to # raw data (with :func:`mne.io.Raw.filter`), but to reduce memory consumption # of this tutorial, we do it at evoked stage. if use_precomputed: sfreq = evoked_std.info['sfreq'] notches = [60, 120, 180] for evoked in (evoked_std, evoked_dev): evoked.data[:] = notch_filter(evoked.data, sfreq, notches) evoked.data[:] = filter_data(evoked.data, sfreq, l_freq=None, h_freq=100.) ############################################################################### # Here we plot the ERF of standard and deviant conditions. In both conditions # we can see the P50 and N100 responses. The mismatch negativity is visible # only in the deviant condition around 100-200 ms. P200 is also visible around # 170 ms in both conditions but much stronger in the standard condition. P300 # is visible in deviant condition only (decision making in preparation of the # button press). You can view the topographies from a certain time span by # painting an area with clicking and holding the left mouse button. evoked_std.plot(window_title='Standard', gfp=True) evoked_dev.plot(window_title='Deviant', gfp=True) ############################################################################### # Show activations as topography figures.
evoked_std = epochs_standard.average() evoked_dev = epochs_deviant.average() del epochs_standard, epochs_deviant ############################################################################### # Typical preprocessing step is the removal of power line artifact (50 Hz or # 60 Hz). Here we notch filter the data at 60, 120 and 180 to remove the # original 60 Hz artifact and the harmonics. Normally this would be done to # raw data (with :func:`mne.io.Raw.filter`), but to reduce memory consumption # of this tutorial, we do it at evoked stage. if use_precomputed: sfreq = evoked_std.info['sfreq'] notches = [60, 120, 180] for evoked in (evoked_std, evoked_dev): evoked.data[:] = notch_filter(evoked.data, sfreq, notches) evoked.data[:] = filter_data(evoked_std.data, sfreq, None, 100) ############################################################################### # Here we plot the ERF of standard and deviant conditions. In both conditions # we can see the P50 and N100 responses. The mismatch negativity is visible # only in the deviant condition around 100-200 ms. P200 is also visible around # 170 ms in both conditions but much stronger in the standard condition. P300 # is visible in deviant condition only (decision making in preparation of the # button press). You can view the topographies from a certain time span by # painting an area with clicking and holding the left mouse button. evoked_std.plot(window_title='Standard', gfp=True) evoked_dev.plot(window_title='Deviant', gfp=True) ############################################################################### # Show activations as topography figures. times = np.arange(0.05, 0.301, 0.025)
def test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling.""" sfreq = 100 sig_len_secs = 15 a = rng.randn(2, sig_len_secs * sfreq) # let's test our catchers for fl in ['blah', [0, 1], 1000.5, '10ss', '10']: pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, fl, 1.0, 1.0, fir_design='firwin') for nj in ['blah', 0.5]: pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, 1000, 1.0, 1.0, n_jobs=nj, phase='zero', fir_design='firwin') pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, 100, 1., 1., fir_window='foo') pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, 10, 1., 1., fir_design='firwin') # too short # > Nyq/2 pytest.raises(ValueError, filter_data, a, sfreq, 4, sfreq / 2., None, 100, 1.0, 1.0, fir_design='firwin') pytest.raises(ValueError, filter_data, a, sfreq, -1, None, None, 100, 1.0, 1.0, fir_design='firwin') # these should work create_filter(None, sfreq, None, None) create_filter(a, sfreq, None, None, fir_design='firwin') create_filter(a, sfreq, None, None, method='iir') # check our short-filter warning: with pytest.warns(RuntimeWarning, match='attenuation'): # Warning for low attenuation filter_data(a, sfreq, 1, 8, filter_length=256, fir_design='firwin2') with pytest.warns(RuntimeWarning, match='Increase filter_length'): # Warning for too short a filter filter_data(a, sfreq, 1, 8, filter_length='0.5s', fir_design='firwin2') # try new default and old default freqs = fftfreq(a.shape[-1], 1. / sfreq) A = np.abs(fft(a)) kwargs = dict(fir_design='firwin') for fl in ['auto', '10s', '5000ms', 1024, 1023]: bp = filter_data(a, sfreq, 4, 8, None, fl, 1.0, 1.0, **kwargs) bs = filter_data(a, sfreq, 8 + 1.0, 4 - 1.0, None, fl, 1.0, 1.0, **kwargs) lp = filter_data(a, sfreq, None, 8, None, fl, 10, 1.0, n_jobs=2, **kwargs) hp = filter_data(lp, sfreq, 4, None, None, fl, 1.0, 10, **kwargs) assert_allclose(hp, bp, rtol=1e-3, atol=1e-3) assert_allclose(bp + bs, a, rtol=1e-3, atol=1e-3) # Sanity check ttenuation mask = (freqs > 5.5) & (freqs < 6.5) assert_allclose(np.mean(np.abs(fft(bp)[:, mask]) / A[:, mask]), 1., atol=0.02) assert_allclose(np.mean(np.abs(fft(bs)[:, mask]) / A[:, mask]), 0., atol=0.2) # now the minimum-phase versions bp = filter_data(a, sfreq, 4, 8, None, fl, 1.0, 1.0, phase='minimum', **kwargs) bs = filter_data(a, sfreq, 8 + 1.0, 4 - 1.0, None, fl, 1.0, 1.0, phase='minimum', **kwargs) assert_allclose(np.mean(np.abs(fft(bp)[:, mask]) / A[:, mask]), 1., atol=0.11) assert_allclose(np.mean(np.abs(fft(bs)[:, mask]) / A[:, mask]), 0., atol=0.3) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp[n_resamp_ignore:-n_resamp_ignore], bp_up_dn[n_resamp_ignore:-n_resamp_ignore], 2) # note that on systems without CUDA, this line serves as a test for a # graceful fallback to n_jobs=1 bp_up_dn = resample(resample(bp, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp[n_resamp_ignore:-n_resamp_ignore], bp_up_dn[n_resamp_ignore:-n_resamp_ignore], 2) # test to make sure our resamling matches scipy's bp_up_dn = sp_resample(sp_resample(bp, 2 * bp.shape[-1], axis=-1, window='boxcar'), bp.shape[-1], window='boxcar', axis=-1) assert_array_almost_equal(bp[n_resamp_ignore:-n_resamp_ignore], bp_up_dn[n_resamp_ignore:-n_resamp_ignore], 2) # make sure we don't alias t = np.array(list(range(sfreq * sig_len_secs))) / float(sfreq) # make sinusoid close to the Nyquist frequency sig = np.sin(2 * np.pi * sfreq / 2.2 * t) # signal should disappear with 2x downsampling sig_gone = resample(sig, 1, 2)[n_resamp_ignore:-n_resamp_ignore] assert_array_almost_equal(np.zeros_like(sig_gone), sig_gone, 2) # let's construct some filters iir_params = dict(ftype='cheby1', gpass=1, gstop=20, output='ba') iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert iir_params['a'].size - 1 == 3 assert iir_params['b'].size - 1 == 3 iir_params = dict(ftype='butter', order=4, output='ba') iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert iir_params['a'].size - 1 == 4 assert iir_params['b'].size - 1 == 4 iir_params = dict(ftype='cheby1', gpass=1, gstop=20) iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter, which requires 2 SOS ((2, 6)) assert iir_params['sos'].shape == (2, 6) iir_params = dict(ftype='butter', order=4, output='sos') iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert iir_params['sos'].shape == (2, 6) # check that picks work for 3d array with one channel and picks=[0] a = rng.randn(5 * sfreq, 5 * sfreq) b = a[:, None, :] a_filt = filter_data(a, sfreq, 4, 8, None, 400, 2.0, 2.0, fir_design='firwin') b_filt = filter_data(b, sfreq, 4, 8, [0], 400, 2.0, 2.0, fir_design='firwin') assert_array_equal(a_filt[:, None, :], b_filt) # check for n-dimensional case a = rng.randn(2, 2, 2, 2) with pytest.warns(RuntimeWarning, match='longer'): pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, np.array([0, 1]), 100, 1.0, 1.0) # check corner case (#4693) h = create_filter( np.empty(10000), 1000., l_freq=None, h_freq=55., h_trans_bandwidth=0.5, method='fir', phase='zero-double', fir_design='firwin', verbose=True) assert len(h) == 6601
def test_spectral_connectivity(): """Test frequency-domain connectivity methods""" # Use a case known to have no spurious correlations (it would bad if # nosetests could randomly fail): rng = np.random.RandomState(0) trans_bandwidth = 2. sfreq = 50. n_signals = 3 n_epochs = 8 n_times = 256 tmin = 0. tmax = (n_times - 1) / sfreq data = rng.randn(n_signals, n_epochs * n_times) times_data = np.linspace(tmin, tmax, n_times) # simulate connectivity from 5Hz..15Hz fstart, fend = 5.0, 15.0 data[1, :] = filter_data(data[0, :], sfreq, fstart, fend, filter_length='auto', fir_design='firwin2', l_trans_bandwidth=trans_bandwidth, h_trans_bandwidth=trans_bandwidth) # add some noise, so the spectrum is not exactly zero data[1, :] += 1e-2 * rng.randn(n_times * n_epochs) data = data.reshape(n_signals, n_epochs, n_times) data = np.transpose(data, [1, 0, 2]) # First we test some invalid parameters: assert_raises(ValueError, spectral_connectivity, data, method='notamethod') assert_raises(ValueError, spectral_connectivity, data, mode='notamode') # test invalid fmin fmax settings assert_raises(ValueError, spectral_connectivity, data, fmin=10, fmax=10 + 0.5 * (sfreq / float(n_times))) assert_raises(ValueError, spectral_connectivity, data, fmin=10, fmax=5) assert_raises(ValueError, spectral_connectivity, data, fmin=(0, 11), fmax=(5, 10)) assert_raises(ValueError, spectral_connectivity, data, fmin=(11,), fmax=(12, 15)) methods = ['coh', 'cohy', 'imcoh', ['plv', 'ppc', 'pli', 'pli2_unbiased', 'wpli', 'wpli2_debiased', 'coh']] modes = ['multitaper', 'fourier', 'cwt_morlet'] # define some frequencies for cwt cwt_frequencies = np.arange(3, 24.5, 1) for mode in modes: for method in methods: if method == 'coh' and mode == 'multitaper': # only check adaptive estimation for coh to reduce test time check_adaptive = [False, True] else: check_adaptive = [False] if method == 'coh' and mode == 'cwt_morlet': # so we also test using an array for num cycles cwt_n_cycles = 7. * np.ones(len(cwt_frequencies)) else: cwt_n_cycles = 7. for adaptive in check_adaptive: if adaptive: mt_bandwidth = 1. else: mt_bandwidth = None con, freqs, times, n, _ = spectral_connectivity( data, method=method, mode=mode, indices=None, sfreq=sfreq, mt_adaptive=adaptive, mt_low_bias=True, mt_bandwidth=mt_bandwidth, cwt_frequencies=cwt_frequencies, cwt_n_cycles=cwt_n_cycles) assert_true(n == n_epochs) assert_array_almost_equal(times_data, times) if mode == 'multitaper': upper_t = 0.95 lower_t = 0.5 else: # mode == 'fourier' or mode == 'cwt_morlet' # other estimates have higher variance upper_t = 0.8 lower_t = 0.75 # test the simulated signal gidx = np.searchsorted(freqs, (fstart, fend)) bidx = np.searchsorted(freqs, (fstart - trans_bandwidth * 2, fend + trans_bandwidth * 2)) if method == 'coh': assert_true(np.all(con[1, 0, gidx[0]:gidx[1]] > upper_t), con[1, 0, gidx[0]:gidx[1]].min()) # we see something for zero-lag assert_true(np.all(con[1, 0, :bidx[0]] < lower_t)) assert_true(np.all(con[1, 0, bidx[1]:] < lower_t), con[1, 0, bidx[1:]].max()) elif method == 'cohy': # imaginary coh will be zero check = np.imag(con[1, 0, gidx[0]:gidx[1]]) assert_true(np.all(check < lower_t), check.max()) # we see something for zero-lag assert_true(np.all(np.abs(con[1, 0, gidx[0]:gidx[1]]) > upper_t)) assert_true(np.all(np.abs(con[1, 0, :bidx[0]]) < lower_t)) assert_true(np.all(np.abs(con[1, 0, bidx[1]:]) < lower_t)) elif method == 'imcoh': # imaginary coh will be zero assert_true(np.all(con[1, 0, gidx[0]:gidx[1]] < lower_t)) assert_true(np.all(con[1, 0, :bidx[0]] < lower_t)) assert_true(np.all(con[1, 0, bidx[1]:] < lower_t), con[1, 0, bidx[1]:].max()) # compute same connections using indices and 2 jobs indices = np.tril_indices(n_signals, -1) if not isinstance(method, list): test_methods = (method, _CohEst) else: test_methods = method stc_data = _stc_gen(data, sfreq, tmin) con2, freqs2, times2, n2, _ = spectral_connectivity( stc_data, method=test_methods, mode=mode, indices=indices, sfreq=sfreq, mt_adaptive=adaptive, mt_low_bias=True, mt_bandwidth=mt_bandwidth, tmin=tmin, tmax=tmax, cwt_frequencies=cwt_frequencies, cwt_n_cycles=cwt_n_cycles, n_jobs=2) assert_true(isinstance(con2, list)) assert_true(len(con2) == len(test_methods)) if method == 'coh': assert_array_almost_equal(con2[0], con2[1]) if not isinstance(method, list): con2 = con2[0] # only keep the first method # we get the same result for the probed connections assert_array_almost_equal(freqs, freqs2) assert_array_almost_equal(con[indices], con2) assert_true(n == n2) assert_array_almost_equal(times_data, times2) else: # we get the same result for the probed connections assert_true(len(con) == len(con2)) for c, c2 in zip(con, con2): assert_array_almost_equal(freqs, freqs2) assert_array_almost_equal(c[indices], c2) assert_true(n == n2) assert_array_almost_equal(times_data, times2) # compute same connections for two bands, fskip=1, and f. avg. fmin = (5., 15.) fmax = (15., 30.) con3, freqs3, times3, n3, _ = spectral_connectivity( data, method=method, mode=mode, indices=indices, sfreq=sfreq, fmin=fmin, fmax=fmax, fskip=1, faverage=True, mt_adaptive=adaptive, mt_low_bias=True, mt_bandwidth=mt_bandwidth, cwt_frequencies=cwt_frequencies, cwt_n_cycles=cwt_n_cycles) assert_true(isinstance(freqs3, list)) assert_true(len(freqs3) == len(fmin)) for i in range(len(freqs3)): assert_true(np.all((freqs3[i] >= fmin[i]) & (freqs3[i] <= fmax[i]))) # average con2 "manually" and we get the same result if not isinstance(method, list): for i in range(len(freqs3)): freq_idx = np.searchsorted(freqs2, freqs3[i]) con2_avg = np.mean(con2[:, freq_idx], axis=1) assert_array_almost_equal(con2_avg, con3[:, i]) else: for j in range(len(con2)): for i in range(len(freqs3)): freq_idx = np.searchsorted(freqs2, freqs3[i]) con2_avg = np.mean(con2[j][:, freq_idx], axis=1) assert_array_almost_equal(con2_avg, con3[j][:, i])
def test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling.""" sfreq = 100 sig_len_secs = 15 a = rng.randn(2, sig_len_secs * sfreq) # let's test our catchers for fl in ['blah', [0, 1], 1000.5, '10ss', '10']: assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, fl, 1.0, 1.0) for nj in ['blah', 0.5]: assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 1000, 1.0, 1.0, n_jobs=nj, phase='zero', fir_window='hann') assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 100, 1., 1., fir_window='foo') # > Nyq/2 assert_raises(ValueError, filter_data, a, sfreq, 4, sfreq / 2., None, 100, 1.0, 1.0) assert_raises(ValueError, filter_data, a, sfreq, -1, None, None, 100, 1.0, 1.0) # these should work create_filter(a, sfreq, None, None) create_filter(a, sfreq, None, None, method='iir') # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation filter_data(a, sfreq, 1, 8, filter_length=256) assert_true(any('attenuation' in str(ww.message) for ww in w)) with warnings.catch_warnings(record=True) as w: # Warning for too short a filter filter_data(a, sfreq, 1, 8, filter_length='0.5s') assert_true(any('Increase filter_length' in str(ww.message) for ww in w)) # try new default and old default for fl in ['auto', '10s', '5000ms', 1024]: bp = filter_data(a, sfreq, 4, 8, None, fl, 1.0, 1.0) bs = filter_data(a, sfreq, 8 + 1.0, 4 - 1.0, None, fl, 1.0, 1.0, phase='zero', fir_window='hamming') lp = filter_data(a, sfreq, None, 8, None, fl, 10, 1.0, n_jobs=2, phase='zero', fir_window='hamming') hp = filter_data(lp, sfreq, 4, None, None, fl, 1.0, 10, phase='zero', fir_window='hamming') assert_array_almost_equal(hp, bp, 4) assert_array_almost_equal(bp + bs, a, 4) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp[n_resamp_ignore:-n_resamp_ignore], bp_up_dn[n_resamp_ignore:-n_resamp_ignore], 2) # note that on systems without CUDA, this line serves as a test for a # graceful fallback to n_jobs=1 bp_up_dn = resample(resample(bp, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp[n_resamp_ignore:-n_resamp_ignore], bp_up_dn[n_resamp_ignore:-n_resamp_ignore], 2) # test to make sure our resamling matches scipy's bp_up_dn = sp_resample(sp_resample(bp, 2 * bp.shape[-1], axis=-1, window='boxcar'), bp.shape[-1], window='boxcar', axis=-1) assert_array_almost_equal(bp[n_resamp_ignore:-n_resamp_ignore], bp_up_dn[n_resamp_ignore:-n_resamp_ignore], 2) # make sure we don't alias t = np.array(list(range(sfreq * sig_len_secs))) / float(sfreq) # make sinusoid close to the Nyquist frequency sig = np.sin(2 * np.pi * sfreq / 2.2 * t) # signal should disappear with 2x downsampling sig_gone = resample(sig, 1, 2)[n_resamp_ignore:-n_resamp_ignore] assert_array_almost_equal(np.zeros_like(sig_gone), sig_gone, 2) # let's construct some filters iir_params = dict(ftype='cheby1', gpass=1, gstop=20, output='ba') iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert_equal(iir_params['a'].size - 1, 3) assert_equal(iir_params['b'].size - 1, 3) iir_params = dict(ftype='butter', order=4, output='ba') iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_equal(iir_params['a'].size - 1, 4) assert_equal(iir_params['b'].size - 1, 4) iir_params = dict(ftype='cheby1', gpass=1, gstop=20, output='sos') iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter, which requires 2 SOS ((2, 6)) assert_equal(iir_params['sos'].shape, (2, 6)) iir_params = dict(ftype='butter', order=4, output='sos') iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_equal(iir_params['sos'].shape, (2, 6)) # check that picks work for 3d array with one channel and picks=[0] a = rng.randn(5 * sfreq, 5 * sfreq) b = a[:, None, :] a_filt = filter_data(a, sfreq, 4, 8, None, 400, 2.0, 2.0) b_filt = filter_data(b, sfreq, 4, 8, [0], 400, 2.0, 2.0) assert_array_equal(a_filt[:, None, :], b_filt) # check for n-dimensional case a = rng.randn(2, 2, 2, 2) with warnings.catch_warnings(record=True): # filter too long assert_raises(ValueError, filter_data, a, sfreq, 4, 8, np.array([0, 1]), 100, 1.0, 1.0)