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) with catch_logging() as log_file: for fl in ['auto', '10s', 2048]: bp = band_pass_filter(a, sfreq, 4, 8, fl, 1.0, 1.0, n_jobs=1, phase='zero') bs = band_stop_filter(a, sfreq, 4 - 1.0, 8 + 1.0, fl, 1.0, 1.0, n_jobs=1, phase='zero') lp = low_pass_filter(a, sfreq, 8, fl, 1.0, n_jobs=1, phase='zero') hp = high_pass_filter(lp, sfreq, 4, fl, 1.0, n_jobs=1, phase='zero') bp_c = band_pass_filter(a, sfreq, 4, 8, fl, 1.0, 1.0, n_jobs='cuda', verbose='INFO', phase='zero') bs_c = band_stop_filter(a, sfreq, 4 - 1.0, 8 + 1.0, fl, 1.0, 1.0, n_jobs='cuda', verbose='INFO', phase='zero') lp_c = low_pass_filter(a, sfreq, 8, fl, 1.0, n_jobs='cuda', verbose='INFO', phase='zero') hp_c = high_pass_filter(lp, sfreq, 4, fl, 1.0, n_jobs='cuda', verbose='INFO', phase='zero') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) 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 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. tempdir = _TempDir() log_file = op.join(tempdir, 'temp_log.txt') sfreq = 500 sig_len_secs = 20 a = np.random.randn(sig_len_secs * sfreq) set_log_file(log_file, overwrite=True) for fl in ['10s', None, 2048]: bp = band_pass_filter(a, sfreq, 4, 8, n_jobs=1, filter_length=fl) bs = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs=1, filter_length=fl) lp = low_pass_filter(a, sfreq, 8, n_jobs=1, filter_length=fl) hp = high_pass_filter(lp, sfreq, 4, n_jobs=1, filter_length=fl) bp_c = band_pass_filter(a, sfreq, 4, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') bs_c = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs='cuda', filter_length=fl, verbose='INFO') lp_c = low_pass_filter(a, sfreq, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') hp_c = high_pass_filter(lp, sfreq, 4, n_jobs='cuda', filter_length=fl, verbose='INFO') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA set_log_file() with open(log_file) as fid: out = fid.readlines() # 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 a = np.random.RandomState(0).randn(3, sig_len_secs * sfreq) a1 = resample(a, 1, 2, n_jobs=2, npad=0) a2 = resample(a, 1, 2, n_jobs='cuda', npad=0) a3 = resample(a, 2, 1, n_jobs=2, npad=0) a4 = resample(a, 2, 1, n_jobs='cuda', npad=0) assert_array_almost_equal(a3, a4, 14) assert_array_almost_equal(a1, a2, 14)
def test_resample(): "Test resampling" x = np.random.normal(0, 1, (10, 10, 10)) x_rs = resample(x, 1, 2, 10) assert_equal(x.shape, (10, 10, 10)) assert_equal(x_rs.shape, (10, 10, 5)) x_2 = x.swapaxes(0, 1) x_2_rs = resample(x_2, 1, 2, 10) assert_array_equal(x_2_rs.swapaxes(0, 1), x_rs) x_3 = x.swapaxes(0, 2) x_3_rs = resample(x_3, 1, 2, 10, 0) assert_array_equal(x_3_rs.swapaxes(0, 2), x_rs)
def test_resample_scipy(): """Test resampling against SciPy.""" n_jobs_test = (1, 'cuda') for window in ('boxcar', 'hann'): for N in (100, 101, 102, 103): x = np.arange(N).astype(float) err_msg = '%s: %s' % (N, window) x_2_sp = sp_resample(x, 2 * N, window=window) for n_jobs in n_jobs_test: x_2 = resample(x, 2, 1, 0, window=window, n_jobs=n_jobs) assert_allclose(x_2, x_2_sp, atol=1e-12, err_msg=err_msg) new_len = int(round(len(x) * (1. / 2.))) x_p5_sp = sp_resample(x, new_len, window=window) for n_jobs in n_jobs_test: x_p5 = resample(x, 1, 2, 0, window=window, n_jobs=n_jobs) assert_allclose(x_p5, x_p5_sp, atol=1e-12, err_msg=err_msg)
def test_resample(): """Test resampling.""" x = rng.normal(0, 1, (10, 10, 10)) x_rs = resample(x, 1, 2, 10) assert x.shape == (10, 10, 10) assert x_rs.shape == (10, 10, 5) x_2 = x.swapaxes(0, 1) x_2_rs = resample(x_2, 1, 2, 10) assert_array_equal(x_2_rs.swapaxes(0, 1), x_rs) x_3 = x.swapaxes(0, 2) x_3_rs = resample(x_3, 1, 2, 10, 0) assert_array_equal(x_3_rs.swapaxes(0, 2), x_rs) # make sure we cast to array if necessary assert_array_equal(resample([0., 0.], 2, 1), [0., 0., 0., 0.])
def test_resample(): """Test resampling.""" x = rng.normal(0, 1, (10, 10, 10)) x_rs = resample(x, 1, 2, 10) assert_equal(x.shape, (10, 10, 10)) assert_equal(x_rs.shape, (10, 10, 5)) x_2 = x.swapaxes(0, 1) x_2_rs = resample(x_2, 1, 2, 10) assert_array_equal(x_2_rs.swapaxes(0, 1), x_rs) x_3 = x.swapaxes(0, 2) x_3_rs = resample(x_3, 1, 2, 10, 0) assert_array_equal(x_3_rs.swapaxes(0, 2), x_rs) # make sure we cast to array if necessary assert_array_equal(resample([0, 0], 2, 1), [0., 0., 0., 0.])
def test_cuda_resampling(): """Test CUDA resampling.""" rng = np.random.RandomState(0) 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(np.zeros(2), 2, 1, n_jobs='cuda'), np.zeros(4))
def test_sw_detect(self): """Test function slow-wave detect """ # Keep only Fz and during a N3 sleep period with (huge) slow-waves data_sw = data_full[1, 666000:672000].astype(np.float64) hypno_sw = hypno_full[666000:672000] # Parameters product testing freq_sw = [(0.3, 3.5), (0.5, 4)] dur_neg = [(0.3, 1.5), [0.1, 2]] dur_pos = [(0.3, 1.5), [0, 1]] amp_neg = [(40, 300), [40, None]] amp_pos = [(10, 150), (0, None)] amp_ptp = [(75, 400), [80, 300]] prod_args = product(freq_sw, dur_neg, dur_pos, amp_neg, amp_pos, amp_ptp) for i, (f, dn, dp, an, ap, aptp) in enumerate(prod_args): print((f, dn, dp, an, ap, aptp)) sw_detect(data_sw, sf_full, freq_sw=f, dur_neg=dn, dur_pos=dp, amp_neg=an, amp_pos=ap, amp_ptp=aptp) # With N3 hypnogram sw_detect(data_sw, sf_full, hypno=hypno_sw) # With N1 sw_detect(data_sw, sf_full, hypno=np.ones(data_sw.shape, dtype=int)) # With 2D data sw_detect(data_sw[np.newaxis, ...], sf_full) # Downsampling with hypnogram data_sw_200 = resample(data_sw, up=2) sw_detect(data_sw_200, 200, hypno=2 * np.ones(data_sw_200.shape, dtype=int), include=2) # Downsampling without hypnogram data_sw_200 = resample(data_sw, up=2) sw_detect(data_sw_200, 200) # Non-integer sampling frequency data_sw_250 = resample(data_sw, up=2.5) sw_detect(data_sw_250, 250)
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 Fs = 500 sig_len_secs = 20 a = np.random.randn(sig_len_secs * Fs) set_log_file(log_file, overwrite=True) for fl in ['10s', None, 2048]: bp = band_pass_filter(a, Fs, 4, 8, n_jobs=1, filter_length=fl) bs = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, n_jobs=1, filter_length=fl) lp = low_pass_filter(a, Fs, 8, n_jobs=1, filter_length=fl) hp = high_pass_filter(lp, Fs, 4, n_jobs=1, filter_length=fl) bp_c = band_pass_filter(a, Fs, 4, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') bs_c = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, n_jobs='cuda', filter_length=fl, verbose='INFO') lp_c = low_pass_filter(a, Fs, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') hp_c = high_pass_filter(lp, Fs, 4, n_jobs='cuda', filter_length=fl, verbose='INFO') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA set_log_file() with open(log_file) as fid: out = fid.readlines() assert_true(sum(['Using CUDA for FFT FIR filtering' in o for o in out]) == 12) # check resampling a = np.random.RandomState(0).randn(3, sig_len_secs * Fs) a1 = resample(a, 1, 2, n_jobs=2, npad=0) a2 = resample(a, 1, 2, n_jobs='cuda', npad=0) a3 = resample(a, 2, 1, n_jobs=2, npad=0) a4 = resample(a, 2, 1, n_jobs='cuda', npad=0) assert_array_almost_equal(a3, a4, 14) assert_array_almost_equal(a1, a2, 14)
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 Fs = 500 sig_len_secs = 20 a = np.random.randn(sig_len_secs * Fs) set_log_file(log_file, overwrite=True) for fl in ['10s', None, 2048]: bp = band_pass_filter(a, Fs, 4, 8, n_jobs=1, filter_length=fl) bs = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, n_jobs=1, filter_length=fl) lp = low_pass_filter(a, Fs, 8, n_jobs=1, filter_length=fl) hp = high_pass_filter(lp, Fs, 4, n_jobs=1, filter_length=fl) bp_c = band_pass_filter(a, Fs, 4, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') bs_c = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, n_jobs='cuda', filter_length=fl, verbose='INFO') lp_c = low_pass_filter(a, Fs, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') hp_c = high_pass_filter(lp, Fs, 4, n_jobs='cuda', filter_length=fl, verbose='INFO') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA set_log_file() out = open(log_file).readlines() assert_true(sum(['Using CUDA for FFT FIR filtering' in o for o in out]) == 12) # check resampling a = np.random.RandomState(0).randn(3, sig_len_secs * Fs) a1 = resample(a, 1, 2, n_jobs=2, npad=0) a2 = resample(a, 1, 2, n_jobs='cuda', npad=0) a3 = resample(a, 2, 1, n_jobs=2, npad=0) a4 = resample(a, 2, 1, n_jobs='cuda', npad=0) assert_array_almost_equal(a3, a4, 14) assert_array_almost_equal(a1, a2, 14)
def load_dataset(subject, fold): path = 'YOUR PATH' # Load data train_eeg = np.load(path + "/cv%01d_sbj%02d_train_eeg.npy" % (fold, subject)) train_label = np.load(path + "/cv%01d_sbj%02d_train_label.npy" % (fold, subject)) test_eeg = np.load(path + "/cv%01d_sbj%02d_test_eeg.npy" % (fold, subject)) test_label = np.load(path + "/cv%01d_sbj%02d_test_label.npy" % (fold, subject)) # Divide the training trials to training and validation trials for model selection. np.random.seed(seed=970304) rand_idx = np.random.permutation(train_eeg.shape[0]) train_eeg = train_eeg[rand_idx, :, :] train_label = train_label[rand_idx] tmp = 40 valid_eeg = train_eeg[:tmp, :, :] valid_label = train_label[:tmp] train_eeg = train_eeg[tmp:, :, :] train_label = train_label[tmp:] train_eeg, valid_eeg, test_eeg = np.expand_dims( train_eeg, -1), np.expand_dims(valid_eeg, -1), np.expand_dims(test_eeg, -1) # Downsampling train_eeg, valid_eeg, test_eeg = resample(train_eeg, up=1, down=10, axis=-2), resample( valid_eeg, up=1, down=10, axis=-2), resample(test_eeg, up=1, down=10, axis=-2) train_eeg, valid_eeg, test_eeg = train_eeg[:, : 2, :, :], valid_eeg[:, : 2, :, :], test_eeg[:, : 2, :, :] return train_eeg, train_label, valid_eeg, valid_label, test_eeg, test_label
def test_cuda_resampling(): """Test CUDA 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.]) from mne.cuda import _cuda_capable # allow above funs to set it if not _cuda_capable: pytest.skip('CUDA not enabled')
def _resample(X, source_sample_rate, resample_to): ''' Resample OVER 0-st axis :param X: eeg Time x Channels :param resample_to: :return: ''' downsample_factor = source_sample_rate / resample_to return resample(X, up=1., down=downsample_factor, npad='auto', axis=0)
def _resample(self, X, resample_to): ''' Resample OVER 1-st axis :param X: eeg trials x Time x Channels :param resample_to: :return: ''' downsample_factor = self.source_sample_rate / resample_to return resample(X, up=1., down=downsample_factor, npad='auto', axis=1)
def _resample(data, sourceSR, targetSR, axesFormat=Formats.tct): axis = axes[axesFormat].index(0) _factor = targetSR / sourceSR if _factor == 1: return data return resample(data, up=max(1., _factor), down=max(1., 1 / _factor), npad="auto", axis=axis)
def test_filters(): """Test low-, band-, and high-pass filters""" Fs = 500 sig_len_secs = 60 # Filtering of short signals (filter length = len(a)) a = np.random.randn(sig_len_secs * Fs) bp = band_pass_filter(a, Fs, 4, 8) lp = low_pass_filter(a, Fs, 8) hp = high_pass_filter(lp, Fs, 4) assert_array_almost_equal(hp, bp, 2) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, Fs, 4, 8, filter_length) lp_oa = low_pass_filter(a, Fs, 8, filter_length) hp_oa = high_pass_filter(lp_oa, Fs, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 1000 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1), 1, 2) assert_array_almost_equal(bp_oa[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(range(Fs * sig_len_secs)) / float(Fs) # make sinusoid close to the Nyquist frequency sig = np.sin(2 * np.pi * Fs / 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)
def test_filters(): """Test low-, band-, and high-pass filters""" Fs = 500 sig_len_secs = 60 # Filtering of short signals (filter length = len(a)) a = np.random.randn(sig_len_secs * Fs) bp = band_pass_filter(a, Fs, 4, 8) lp = low_pass_filter(a, Fs, 8) hp = high_pass_filter(lp, Fs, 4) assert_array_almost_equal(hp, bp, 2) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, Fs, 4, 8, filter_length) lp_oa = low_pass_filter(a, Fs, 8, filter_length) hp_oa = high_pass_filter(lp_oa, Fs, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 1000 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1), 1, 2) assert_array_almost_equal(bp_oa[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(range(Fs*sig_len_secs))/float(Fs) # make sinusoid close to the Nyquist frequency sig = np.sin(2*np.pi*Fs/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)
def _prepare_stim(zfn, path_out, sex, tal, cal, col, num, fs_out, dtype, ref_rms, n_jobs): """Read in a binary CRM file and write out a scaled resampled wav. """ from mne.filter import resample zip_file = ZipFile(zfn) x = _read_binary(zip_file, cal, col, num, 0) fn = '%i%i%i%i%i.wav' % (sex, tal, cal, col, num) if int(np.round(fs_out)) != int(np.round(_fs_binary)): x = resample(x, fs_out, _fs_binary, n_jobs=n_jobs, verbose=0) x *= ref_rms / _rms_binary write_wav(join(path_out, fn), x, fs_out, overwrite=True, dtype=dtype, verbose=False)
def reSample(signal, current, target): """ Input: signal = The signal to resample current = The current sample rate target = The target sample rate Output: signal_resampled target """ newRate = current / target signal_resampled = resample(signal, down=newRate, npad="auto") return signal_resampled, target
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 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) with catch_logging() as log_file: for fl in ['10s', None, 2048]: bp = band_pass_filter(a, sfreq, 4, 8, n_jobs=1, filter_length=fl) bs = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs=1, filter_length=fl) lp = low_pass_filter(a, sfreq, 8, n_jobs=1, filter_length=fl) hp = high_pass_filter(lp, sfreq, 4, n_jobs=1, filter_length=fl) bp_c = band_pass_filter(a, sfreq, 4, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') bs_c = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs='cuda', filter_length=fl, verbose='INFO') lp_c = low_pass_filter(a, sfreq, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') hp_c = high_pass_filter(lp, sfreq, 4, n_jobs='cuda', filter_length=fl, verbose='INFO') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) 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 a = rng.randn(3, sig_len_secs * sfreq) a1 = resample(a, 1, 2, n_jobs=2, npad=0) a2 = resample(a, 1, 2, n_jobs='cuda', npad=0) a3 = resample(a, 2, 1, n_jobs=2, npad=0) a4 = resample(a, 2, 1, n_jobs='cuda', npad=0) assert_array_almost_equal(a3, a4, 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 test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling""" sfreq = 500 sig_len_secs = 30 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, band_pass_filter, a, sfreq, 4, 8, fl, 1.0, 1.0, phase='zero') for nj in ['blah', 0.5]: assert_raises(ValueError, band_pass_filter, a, sfreq, 4, 8, 100, 1.0, 1.0, n_jobs=nj, phase='zero') # > Nyq/2 assert_raises(ValueError, band_pass_filter, a, sfreq, 4, sfreq / 2., 100, 1.0, 1.0, phase='zero') assert_raises(ValueError, low_pass_filter, a, sfreq, sfreq / 2., 100, 1.0, phase='zero') # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation band_pass_filter(a, sfreq, 1, 8, filter_length=1024, phase='zero') 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 band_pass_filter(a, sfreq, 1, 8, filter_length='0.5s', phase='zero') 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', 8192]: bp = band_pass_filter(a, sfreq, 4, 8, fl, 1.0, 1.0, phase='zero') bs = band_stop_filter(a, sfreq, 4 - 1.0, 8 + 1.0, fl, 1.0, 1.0, phase='zero') lp = low_pass_filter(a, sfreq, 8, fl, 1.0, n_jobs=2, phase='zero') hp = high_pass_filter(lp, sfreq, 4, fl, 1.0, phase='zero') assert_array_almost_equal(hp, bp, 5) assert_array_almost_equal(bp + bs, a, 5) # 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 = band_pass_filter(a, sfreq, 4, 8, 1000, 2.0, 2.0, phase='zero') b_filt = band_pass_filter(b, sfreq, 4, 8, 1000, 2.0, 2.0, picks=[0], phase='zero') 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, band_pass_filter, a, sfreq, 4, 8, 100, 1.0, 1.0, picks=np.array([0, 1]), phase='zero')
def test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling """ Fs = 500 sig_len_secs = 30 a = np.random.randn(2, sig_len_secs * Fs) # let's test our catchers for fl in ['blah', [0, 1], 1000.5, '10ss', '10']: assert_raises(ValueError, band_pass_filter, a, Fs, 4, 8, filter_length=fl) for nj in ['blah', 0.5, 0]: assert_raises(ValueError, band_pass_filter, a, Fs, 4, 8, n_jobs=nj) # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation band_pass_filter(a, Fs, 1, 8, filter_length=1024) # Warning for too short a filter band_pass_filter(a, Fs, 1, 8, filter_length='0.5s') assert_true(len(w) >= 2) # try new default and old default for fl in ['10s', '5000ms', None]: bp = band_pass_filter(a, Fs, 4, 8, filter_length=fl) bs = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, filter_length=fl) lp = low_pass_filter(a, Fs, 8, filter_length=fl, n_jobs=2) hp = high_pass_filter(lp, Fs, 4, filter_length=fl) assert_array_almost_equal(hp, bp, 2) assert_array_almost_equal(bp + bs, a, 1) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, Fs, 4, 8, filter_length) bs_oa = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, filter_length) lp_oa = low_pass_filter(a, Fs, 8, filter_length) hp_oa = high_pass_filter(lp_oa, Fs, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) assert_array_almost_equal(bp_oa + bs_oa, a, 2) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 0 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp_oa[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_oa, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp_oa[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_oa, 2 * len(bp_oa), window='boxcar'), len(bp_oa), window='boxcar') assert_array_almost_equal(bp_oa[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(range(Fs * sig_len_secs)) / float(Fs) # make sinusoid close to the Nyquist frequency sig = np.sin(2 * np.pi * Fs / 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) iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert_true(iir_params['a'].size - 1 == 3) assert_true(iir_params['b'].size - 1 == 3) iir_params = dict(ftype='butter', order=4) iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_true(iir_params['a'].size - 1 == 4) assert_true(iir_params['b'].size - 1 == 4)
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_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, fir_design='firwin') 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_design='firwin') assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 100, 1., 1., fir_window='foo') assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 10, 1., 1., fir_design='firwin') # too short # > Nyq/2 assert_raises(ValueError, filter_data, a, sfreq, 4, sfreq / 2., None, 100, 1.0, 1.0, fir_design='firwin') assert_raises(ValueError, filter_data, a, sfreq, -1, None, None, 100, 1.0, 1.0, fir_design='firwin') # these should work create_filter(a, sfreq, None, None, fir_design='firwin') 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, fir_design='firwin2') 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', fir_design='firwin2') assert_true(any('Increase filter_length' in str(ww.message) for ww in w)) # 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_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, 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 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)
def convolve_hrtf(data, fs, angle, source='cipic', interp=False): """Convolve a signal with a head-related transfer function Technically we will be convolving with binaural room impulse responses (BRIRs), but HRTFs (freq-domain equiv. representations) are the common terminology. Parameters ---------- data : 1-dimensional or 1xN array-like Data to operate on. fs : float The sample rate of the data. (HRTFs will be resampled if necessary.) angle : float The azimuthal angle of the HRTF. source : str Source to use for HRTFs. Currently `'barb'` and `'cipic'` are supported. The former is default for legacy purpose. `'cipic'` is recommended for new experiments. interp : bool Parameter to determine whether to restrict use to known HRTF values or to use an interpolated HRTF for angles not in the source; set to False by default Returns ------- data_hrtf : array A 2D array ``shape=(2, n_samples)`` containing the convolved data. Notes ----- CIPIC data downloaded from: http://earlab.bu.edu/databases/collections/cipic/Default.aspx. Additional documentation: http://earlab.bu.edu/databases/collections/cipic/documentation/hrir_data_documentation.pdf # noqa The data were modified to suit our experimental needs. Below is the licensing information for the CIPIC data: **Copyright** Copyright (c) 2001 The Regents of the University of California. All Rights Reserved. **Disclaimer** THE REGENTS OF THE UNIVERSITY OF CALIFORNIA MAKE NO REPRESENTATION OR WARRANTIES WITH RESPECT TO THE CONTENTS HEREOF AND SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OR MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Further, the Regents of the University of California reserve the right to revise this software and/or documentation and to make changes from time to time in the content hereof without obligation of the Regents of the University of California to notify any person of such revision or change. Use of Materials The Regents of the University of California hereby grant users permission to reproduce and/or use materials available therein for any purpose- educational, research or commercial. However, each reproduction of any part of the materials must include the copyright notice, if it is present. In addition, as a courtesy, if these materials are used in published research, this use should be acknowledged in the publication. If these materials are used in the development of commercial products, the Regents of the University of California request that written acknowledgment of such use be sent to: CIPIC- Center for Image Processing and Integrated Computing University of California 1 Shields Avenue Davis, CA 95616-8553 """ fs = float(fs) angle = float(angle) known_sources = ['barb', 'cipic'] known_fs = [24414, 44100] # must be sorted if source not in known_sources: raise ValueError('Source "{0}" unknown, must be one of {1}' ''.format(source, known_sources)) if not isinstance(interp, bool): raise ValueError('interp must be bool') data = np.array(data, np.float64) data = _fix_audio_dims(data, n_channels=1).ravel() # Find out which sampling rate to get--first that is >= fs # Use the last, highest one whether it is high enough or not ge = [int(np.round(fs)) <= k for k in known_fs[:-1]] + [True] brir_fs = known_fs[ge.index(True)] brir, brir_fs, leftward = _get_hrtf(angle, source, brir_fs, interp) order = [1, 0] if leftward else [0, 1] if not np.allclose(brir_fs, fs, rtol=0, atol=0.5): from mne.filter import resample brir = [resample(b, fs, brir_fs) for b in brir] out = np.array([np.convolve(data, brir[o]) for o in order]) return out
from mne.filter import filter_data, resample from yasa.main import (_corr, _covar, _rms, _slope_lstsq, _detrend, moving_transform, stft_power, get_sync_sw, _index_to_events, get_bool_vector, trimbothstd, _merge_close, spindles_detect, spindles_detect_multi, _zerocrossings, sw_detect, sw_detect_multi) # Load data data = np.loadtxt('notebooks/data_N2_spindles_15sec_200Hz.txt') sf = 200 data_sigma = filter_data(data, sf, 12, 15, method='fir', verbose=0) # Resample the data to 128 Hz fac = 128 / sf data_128 = resample(data, up=fac, down=1.0, npad='auto', axis=-1, window='boxcar', n_jobs=1, pad='reflect_limited', verbose=False) sf_128 = 128 # Resample the data to 150 Hz fac = 150 / sf data_150 = resample(data, up=fac, down=1.0, npad='auto', axis=-1, window='boxcar', n_jobs=1, pad='reflect_limited', verbose=False) sf_150 = 150 # Load an extract of N3 sleep without any spindle data_n3 = np.loadtxt('notebooks/data_N3_no-spindles_30sec_100Hz.txt') sf_n3 = 100 # Load a full recording and its hypnogram
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) with catch_logging() as log_file: for fl in ['10s', None, 2048]: bp = band_pass_filter(a, sfreq, 4, 8, n_jobs=1, filter_length=fl) bs = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs=1, filter_length=fl) lp = low_pass_filter(a, sfreq, 8, n_jobs=1, filter_length=fl) hp = high_pass_filter(lp, sfreq, 4, n_jobs=1, filter_length=fl) bp_c = band_pass_filter(a, sfreq, 4, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') bs_c = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs='cuda', filter_length=fl, verbose='INFO') lp_c = low_pass_filter(a, sfreq, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') hp_c = high_pass_filter(lp, sfreq, 4, n_jobs='cuda', filter_length=fl, verbose='INFO') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) 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 test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling """ sfreq = 500 sig_len_secs = 30 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, band_pass_filter, a, sfreq, 4, 8, filter_length=fl) for nj in ['blah', 0.5]: assert_raises(ValueError, band_pass_filter, a, sfreq, 4, 8, n_jobs=nj) # > Nyq/2 assert_raises(ValueError, band_pass_filter, a, sfreq, 4, sfreq / 2.) assert_raises(ValueError, low_pass_filter, a, sfreq, sfreq / 2.) # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation band_pass_filter(a, sfreq, 1, 8, filter_length=1024) # Warning for too short a filter band_pass_filter(a, sfreq, 1, 8, filter_length='0.5s') assert_true(len(w) >= 2) # try new default and old default for fl in ['10s', '5000ms', None]: bp = band_pass_filter(a, sfreq, 4, 8, filter_length=fl) bs = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, filter_length=fl) lp = low_pass_filter(a, sfreq, 8, filter_length=fl, n_jobs=2) hp = high_pass_filter(lp, sfreq, 4, filter_length=fl) assert_array_almost_equal(hp, bp, 2) assert_array_almost_equal(bp + bs, a, 1) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, sfreq, 4, 8, filter_length) bs_oa = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, filter_length) lp_oa = low_pass_filter(a, sfreq, 8, filter_length) hp_oa = high_pass_filter(lp_oa, sfreq, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) # Our filters are no longer quite complementary with linear rolloffs :( # this is the tradeoff for stability of the filtering # obtained by directly using the result of firwin2 instead of # modifying it... assert_array_almost_equal(bp_oa + bs_oa, a, 1) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 0 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp_oa[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_oa, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp_oa[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_oa, 2 * bp_oa.shape[-1], axis=-1, window='boxcar'), bp_oa.shape[-1], window='boxcar', axis=-1) assert_array_almost_equal(bp_oa[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) iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert_true(iir_params['a'].size - 1 == 3) assert_true(iir_params['b'].size - 1 == 3) iir_params = dict(ftype='butter', order=4) iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_true(iir_params['a'].size - 1 == 4) assert_true(iir_params['b'].size - 1 == 4) # check that picks work for 3d array with one channel and picks=[0] a = rng.randn(5 * sfreq, 5 * sfreq) b = a[:, None, :] with warnings.catch_warnings(record=True) as w: a_filt = band_pass_filter(a, sfreq, 4, 8) b_filt = band_pass_filter(b, sfreq, 4, 8, picks=[0]) assert_array_equal(a_filt[:, None, :], b_filt) # check for n-dimensional case a = rng.randn(2, 2, 2, 2) assert_raises(ValueError, band_pass_filter, a, sfreq, Fp1=4, Fp2=8, picks=np.array([0, 1])) # 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) x += np.sin(2 * np.pi * sine_freq * np.arange(N) / sfreq) with warnings.catch_warnings(record=True): # filter attenuation x_filt = low_pass_filter(x, sfreq, lp, '1s') # the firwin2 function gets us this close assert_allclose(x, x_filt, rtol=1e-3, atol=1e-3)
def convolve_hrtf(data, fs, angle, source='cipic', interp=False): """Convolve a signal with a head-related transfer function Technically we will be convolving with binaural room impulse responses (BRIRs), but HRTFs (freq-domain equiv. representations) are the common terminology. Parameters ---------- data : 1-dimensional or 1xN array-like Data to operate on. fs : float The sample rate of the data. (HRTFs will be resampled if necessary.) angle : float The azimuthal angle of the HRTF. source : str Source to use for HRTFs. Currently `'barb'` and `'cipic'` are supported. The former is default for legacy purpose. The latter is recommended for new experiments. interp : bool Parameter to determine whether to restrict use to known HRTF values or to use an interpolated HRTF for angles not in the source; set to False by default Returns ------- data_hrtf : array A 2D array ``shape=(2, n_samples)`` containing the convolved data. Notes ----- CIPIC data downloaded from: http://earlab.bu.edu/databases/collections/cipic/Default.aspx. Additional documentation: http://earlab.bu.edu/databases/collections/cipic/documentation/hrir_data_documentation.pdf # noqa The data were modified to suit our experimental needs. Below is the licensing information for the CIPIC data: **Copyright** Copyright (c) 2001 The Regents of the University of California. All Rights Reserved. **Disclaimer** THE REGENTS OF THE UNIVERSITY OF CALIFORNIA MAKE NO REPRESENTATION OR WARRANTIES WITH RESPECT TO THE CONTENTS HEREOF AND SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OR MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Further, the Regents of the University of California reserve the right to revise this software and/or documentation and to make changes from time to time in the content hereof without obligation of the Regents of the University of California to notify any person of such revision or change. Use of Materials The Regents of the University of California hereby grant users permission to reproduce and/or use materials available therein for any purpose- educational, research or commercial. However, each reproduction of any part of the materials must include the copyright notice, if it is present. In addition, as a courtesy, if these materials are used in published research, this use should be acknowledged in the publication. If these materials are used in the development of commercial products, the Regents of the University of California request that written acknowledgment of such use be sent to: CIPIC- Center for Image Processing and Integrated Computing University of California 1 Shields Avenue Davis, CA 95616-8553 """ fs = float(fs) angle = float(angle) known_sources = ['barb', 'cipic'] known_fs = [24414, 44100] # must be sorted if source not in known_sources: raise ValueError('Source "{0}" unknown, must be one of {1}' ''.format(source, known_sources)) if not isinstance(interp, bool): raise ValueError('interp must be bool') data = np.array(data, np.float64) data = _fix_audio_dims(data, n_channels=1).ravel() # Find out which sampling rate to get--first that is >= fs # Use the last, highest one whether it is high enough or not ge = [int(np.round(fs)) <= k for k in known_fs[:-1]] + [True] brir_fs = known_fs[ge.index(True)] brir, brir_fs, leftward = _get_hrtf(angle, source, brir_fs, interp) order = [1, 0] if leftward else [0, 1] if not np.allclose(brir_fs, fs, rtol=0, atol=0.5): from mne.filter import resample brir = [resample(b, fs, brir_fs) for b in brir] out = np.array([np.convolve(data, brir[o]) for o in order]) return out
def fourier_resample(psg, new_sample_rate, old_sample_rate): from mne.filter import resample return resample(psg, new_sample_rate, old_sample_rate, axis=0)
def _resample(self, X, y, resample_to): self.sample_rate = resample_to duration = self.end_epoch - self.start_epoch downsample_factor = X.shape[1]/(resample_to * duration) return resample(X,up=1., down=downsample_factor, npad='auto',axis=1), y
def test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling """ sfreq = 500 sig_len_secs = 30 a = np.random.randn(2, sig_len_secs * sfreq) # let's test our catchers for fl in ['blah', [0, 1], 1000.5, '10ss', '10']: assert_raises(ValueError, band_pass_filter, a, sfreq, 4, 8, filter_length=fl) for nj in ['blah', 0.5]: assert_raises(ValueError, band_pass_filter, a, sfreq, 4, 8, n_jobs=nj) # > Nyq/2 assert_raises(ValueError, band_pass_filter, a, sfreq, 4, sfreq / 2.) assert_raises(ValueError, low_pass_filter, a, sfreq, sfreq / 2.) # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation band_pass_filter(a, sfreq, 1, 8, filter_length=1024) # Warning for too short a filter band_pass_filter(a, sfreq, 1, 8, filter_length='0.5s') assert_true(len(w) >= 2) # try new default and old default for fl in ['10s', '5000ms', None]: bp = band_pass_filter(a, sfreq, 4, 8, filter_length=fl) bs = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, filter_length=fl) lp = low_pass_filter(a, sfreq, 8, filter_length=fl, n_jobs=2) hp = high_pass_filter(lp, sfreq, 4, filter_length=fl) assert_array_almost_equal(hp, bp, 2) assert_array_almost_equal(bp + bs, a, 1) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, sfreq, 4, 8, filter_length) bs_oa = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, filter_length) lp_oa = low_pass_filter(a, sfreq, 8, filter_length) hp_oa = high_pass_filter(lp_oa, sfreq, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) # Our filters are no longer quite complementary with linear rolloffs :( # this is the tradeoff for stability of the filtering # obtained by directly using the result of firwin2 instead of # modifying it... assert_array_almost_equal(bp_oa + bs_oa, a, 1) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 0 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp_oa[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_oa, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp_oa[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_oa, 2 * bp_oa.shape[-1], axis=-1, window='boxcar'), bp_oa.shape[-1], window='boxcar', axis=-1) assert_array_almost_equal(bp_oa[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) iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert_true(iir_params['a'].size - 1 == 3) assert_true(iir_params['b'].size - 1 == 3) iir_params = dict(ftype='butter', order=4) iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_true(iir_params['a'].size - 1 == 4) assert_true(iir_params['b'].size - 1 == 4) # check that picks work for 3d array with one channel and picks=[0] a = np.random.randn(5 * sfreq, 5 * sfreq) b = a[:, None, :] with warnings.catch_warnings(record=True) as w: a_filt = band_pass_filter(a, sfreq, 4, 8) b_filt = band_pass_filter(b, sfreq, 4, 8, picks=[0]) assert_array_equal(a_filt[:, None, :], b_filt) # check for n-dimensional case a = np.random.randn(2, 2, 2, 2) assert_raises(ValueError, band_pass_filter, a, sfreq, Fp1=4, Fp2=8, picks=np.array([0, 1])) # 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) x += np.sin(2 * np.pi * sine_freq * np.arange(N) / sfreq) with warnings.catch_warnings(record=True): # filter attenuation x_filt = low_pass_filter(x, sfreq, lp, '1s') # the firwin2 function gets us this close assert_allclose(x, x_filt, rtol=1e-3, atol=1e-3)
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, band_pass_filter, a, sfreq, 4, 8, fl, 1., 1.) for nj in ['blah', 0.5]: assert_raises(ValueError, band_pass_filter, a, sfreq, 4, 8, 100, 1., 1., n_jobs=nj) assert_raises(ValueError, band_pass_filter, a, sfreq, 4, 8, 100, 1., 1., fir_window='foo') # > Nyq/2 assert_raises(ValueError, band_pass_filter, a, sfreq, 4, sfreq / 2., 100, 1.0, 1.0) assert_raises(ValueError, low_pass_filter, a, sfreq, sfreq / 2., 100, 1.0) # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation band_pass_filter(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 band_pass_filter(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 = band_pass_filter(a, sfreq, 4, 8, fl, 1.0, 1.0) bs = band_stop_filter(a, sfreq, 4 - 1.0, 8 + 1.0, fl, 1.0, 1.0) lp = low_pass_filter(a, sfreq, 8, fl, 1.0, n_jobs=2) hp = high_pass_filter(lp, sfreq, 4, fl, 1.0) 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 = band_pass_filter(a, sfreq, 4, 8, 400, 2.0, 2.0) b_filt = band_pass_filter(b, sfreq, 4, 8, 400, 2.0, 2.0, picks=[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, band_pass_filter, a, sfreq, 4, 8, 100, 1.0, 1.0, picks=np.array([0, 1]))
def resample(self, sfreq, npad='auto', window='boxcar', n_jobs=1, pad='edge', verbose=None): """Resample data. This method is an adaptation of the mne-python one. Parameters ---------- sfreq : float New sample rate to use. npad : int | str Amount to pad the start and end of the data. Can also be “auto” to use a padding that will result in a power-of-two size (can be much faster). window : str | tuple Frequency-domain window to use in resampling. See scipy.signal.resample(). pad : str | 'edge' The type of padding to use. Supports all numpy.pad() mode options. Can also be “reflect_limited”, which pads with a reflected version of each vector mirrored on the first and last values of the vector, followed by zeros. Only used for method='fir'. The default is 'edge', which pads with the edge values of each vector. Returns ------- inst : instance of DatasetEphy The object with the filtering applied. Notes ----- For some data, it may be more accurate to use npad=0 to reduce artifacts. This is dataset dependent -- check your data! """ set_log_level(verbose) assert self._groupedby is "subject", ("Slicing only work when data is " "grouped by 'subjects'") from mne.filter import resample sfreq = float(sfreq) o_sfreq = self.sfreq logger.info(f" Resample to the frequency {sfreq}Hz") for k in range(len(self._x)): self._x[k] = resample(self._x[k], sfreq, o_sfreq, npad, window=window, n_jobs=n_jobs, pad=pad) self.sfreq = float(sfreq) self.times = (np.arange(self._x[0].shape[-1], dtype=np.float) / sfreq + self.times[0]) self.n_times = len(self.times) return self
def test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling """ Fs = 500 sig_len_secs = 30 a = np.random.randn(2, sig_len_secs * Fs) # let's test our catchers for fl in ['blah', [0, 1], 1000.5, '10ss', '10']: assert_raises(ValueError, band_pass_filter, a, Fs, 4, 8, filter_length=fl) for nj in ['blah', 0.5, 0]: assert_raises(ValueError, band_pass_filter, a, Fs, 4, 8, n_jobs=nj) assert_raises(ValueError, band_pass_filter, a, Fs, 4, Fs / 2.) # > Nyq/2 assert_raises(ValueError, low_pass_filter, a, Fs, Fs / 2.) # > Nyq/2 # check our short-filter warning: with warnings.catch_warnings(record=True) as w: # Warning for low attenuation band_pass_filter(a, Fs, 1, 8, filter_length=1024) # Warning for too short a filter band_pass_filter(a, Fs, 1, 8, filter_length='0.5s') assert_true(len(w) >= 2) # try new default and old default for fl in ['10s', '5000ms', None]: bp = band_pass_filter(a, Fs, 4, 8, filter_length=fl) bs = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, filter_length=fl) lp = low_pass_filter(a, Fs, 8, filter_length=fl, n_jobs=2) hp = high_pass_filter(lp, Fs, 4, filter_length=fl) assert_array_almost_equal(hp, bp, 2) assert_array_almost_equal(bp + bs, a, 1) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, Fs, 4, 8, filter_length) bs_oa = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, filter_length) lp_oa = low_pass_filter(a, Fs, 8, filter_length) hp_oa = high_pass_filter(lp_oa, Fs, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) assert_array_almost_equal(bp_oa + bs_oa, a, 2) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 0 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp_oa[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_oa, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp_oa[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_oa, 2 * bp_oa.shape[-1], axis=-1, window='boxcar'), bp_oa.shape[-1], window='boxcar', axis=-1) assert_array_almost_equal(bp_oa[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(Fs * sig_len_secs))) / float(Fs) # make sinusoid close to the Nyquist frequency sig = np.sin(2 * np.pi * Fs / 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) iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert_true(iir_params['a'].size - 1 == 3) assert_true(iir_params['b'].size - 1 == 3) iir_params = dict(ftype='butter', order=4) iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_true(iir_params['a'].size - 1 == 4) assert_true(iir_params['b'].size - 1 == 4)
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. tempdir = _TempDir() log_file = op.join(tempdir, 'temp_log.txt') sfreq = 500 sig_len_secs = 20 a = np.random.randn(sig_len_secs * sfreq) set_log_file(log_file, overwrite=True) for fl in ['10s', None, 2048]: bp = band_pass_filter(a, sfreq, 4, 8, n_jobs=1, filter_length=fl) bs = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs=1, filter_length=fl) lp = low_pass_filter(a, sfreq, 8, n_jobs=1, filter_length=fl) hp = high_pass_filter(lp, sfreq, 4, n_jobs=1, filter_length=fl) bp_c = band_pass_filter(a, sfreq, 4, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') bs_c = band_stop_filter(a, sfreq, 4 - 0.5, 8 + 0.5, n_jobs='cuda', filter_length=fl, verbose='INFO') lp_c = low_pass_filter(a, sfreq, 8, n_jobs='cuda', filter_length=fl, verbose='INFO') hp_c = high_pass_filter(lp, sfreq, 4, n_jobs='cuda', filter_length=fl, verbose='INFO') assert_array_almost_equal(bp, bp_c, 12) assert_array_almost_equal(bs, bs_c, 12) assert_array_almost_equal(lp, lp_c, 12) assert_array_almost_equal(hp, hp_c, 12) # check to make sure we actually used CUDA set_log_file() with open(log_file) as fid: out = fid.readlines() # 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 a = np.random.RandomState(0).randn(3, sig_len_secs * sfreq) a1 = resample(a, 1, 2, n_jobs=2, npad=0) a2 = resample(a, 1, 2, n_jobs='cuda', npad=0) a3 = resample(a, 2, 1, n_jobs=2, npad=0) a4 = resample(a, 2, 1, n_jobs='cuda', npad=0) assert_array_almost_equal(a3, a4, 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 test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling.""" rng = np.random.RandomState(0) 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, TypeError), filter_data, a, sfreq, 4, 8, None, fl, 1.0, 1.0, fir_design='firwin') with pytest.raises(TypeError, match='got <class'): filter_data(a, sfreq, 4, 8, None, 1000, 1.0, 1.0, n_jobs=0.5, phase='zero', fir_design='firwin') with pytest.raises(ValueError, match='Invalid value'): filter_data(a, sfreq, 4, 8, None, 1000, 1.0, 1.0, n_jobs='blah', 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=2e-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=None 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) want_length = int(round(_length_factors['hamming'] * 1000. / 0.5)) want_length += (want_length % 2 == 0) assert want_length == 6601 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 h = create_filter(np.empty(10000), 1000., l_freq=None, h_freq=55., h_trans_bandwidth=0.5, method='fir', phase='zero', fir_design='firwin', filter_length='7s', verbose=True) assert len(h) == 7001 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', filter_length='7s', verbose=True) assert len(h) == 8193 # next power of two
def test_filters(): """Test low-, band-, high-pass, and band-stop filters plus resampling """ Fs = 500 sig_len_secs = 30 # Filtering of short signals (filter length = len(a)) a = np.random.randn(2, sig_len_secs * Fs) bp = band_pass_filter(a, Fs, 4, 8) bs = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5) lp = low_pass_filter(a, Fs, 8) hp = high_pass_filter(lp, Fs, 4) assert_array_almost_equal(hp, bp, 2) assert_array_almost_equal(bp + bs, a, 1) # Overlap-add filtering with a fixed filter length filter_length = 8192 bp_oa = band_pass_filter(a, Fs, 4, 8, filter_length) bs_oa = band_stop_filter(a, Fs, 4 - 0.5, 8 + 0.5, filter_length) lp_oa = low_pass_filter(a, Fs, 8, filter_length) hp_oa = high_pass_filter(lp_oa, Fs, 4, filter_length) assert_array_almost_equal(hp_oa, bp_oa, 2) assert_array_almost_equal(bp_oa + bs_oa, a, 2) # The two methods should give the same result # As filtering for short signals uses a circular convolution (FFT) and # the overlap-add filter implements a linear convolution, the signal # boundary will be slightly different and we ignore it n_edge_ignore = 0 assert_array_almost_equal(hp[n_edge_ignore:-n_edge_ignore], hp_oa[n_edge_ignore:-n_edge_ignore], 2) # and since these are low-passed, downsampling/upsampling should be close n_resamp_ignore = 10 bp_up_dn = resample(resample(bp_oa, 2, 1, n_jobs=2), 1, 2, n_jobs=2) assert_array_almost_equal(bp_oa[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_oa, 2, 1, n_jobs='cuda'), 1, 2, n_jobs='cuda') assert_array_almost_equal(bp_oa[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_oa, 2 * len(bp_oa), window='boxcar'), len(bp_oa), window='boxcar') assert_array_almost_equal(bp_oa[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(range(Fs * sig_len_secs)) / float(Fs) # make sinusoid close to the Nyquist frequency sig = np.sin(2 * np.pi * Fs / 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) iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low') # this should be a third order filter assert_true(iir_params['a'].size - 1 == 3) assert_true(iir_params['b'].size - 1 == 3) iir_params = dict(ftype='butter', order=4) iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low') assert_true(iir_params['a'].size - 1 == 4) assert_true(iir_params['b'].size - 1 == 4)