def test_bad_by_dropout(raw_tmp): """Test detection of channels with excessive portions of flat signal.""" # Add large dropout portions to the signal of a random channel n_chans, n_samples = raw_tmp._data.shape dropout_idx = int(RNG.randint(0, n_chans, 1)) x1, x2 = (int(n_samples / 10), int(2 * n_samples / 10)) raw_tmp._data[dropout_idx, x1:x2] = 0 # flatten 10% of signal # Test detection of channels that have excessive dropout regions nd = NoisyChannels(raw_tmp, do_detrend=False) nd.find_bad_by_correlation() assert nd.bad_by_dropout == [raw_tmp.ch_names[dropout_idx]]
def test_bad_by_correlation(raw_tmp): """Test detection of channels that correlate poorly with others.""" # Replace a random channel's signal with uncorrelated values n_chans, n_samples = raw_tmp._data.shape low_corr_idx = int(RNG.randint(0, n_chans, 1)) raw_tmp._data[low_corr_idx, :] = _generate_signal(10, 30, raw_tmp.times, 5) # Test detection of channels that correlate poorly with others nd = NoisyChannels(raw_tmp, do_detrend=False) nd.find_bad_by_correlation() assert nd.bad_by_correlation == [raw_tmp.ch_names[low_corr_idx]] # Add a channel with dropouts to see if correlation detection still works dropout_idx = (low_corr_idx - 1) if low_corr_idx > 0 else 1 x1, x2 = (int(n_samples / 10), int(2 * n_samples / 10)) raw_tmp._data[dropout_idx, x1:x2] = 0 # flatten 10% of signal # Re-test detection of channels that correlate poorly with others # (only new bad-by-correlation channel should be dropout) nd = NoisyChannels(raw_tmp, do_detrend=False) nd.find_bad_by_correlation() assert raw_tmp.ch_names[low_corr_idx] in nd.bad_by_correlation assert len(nd.bad_by_correlation) <= 2
def test_findnoisychannels(raw, montage): raw.set_montage(montage) nd = NoisyChannels(raw) nd.find_all_bads(ransac=True) bads = nd.get_bads() iterations = ( 10 # remove any noisy channels by interpolating the bads for 10 iterations ) for iter in range(0, iterations): raw.info["bads"] = bads raw.interpolate_bads() nd = NoisyChannels(raw) nd.find_all_bads(ransac=True) bads = nd.get_bads() # make sure no bad channels exist in the data raw.drop_channels(ch_names=bads) # Test for NaN and flat channels raw_tmp = raw.copy() m, n = raw_tmp._data.shape # Insert a nan value for a random channel rand_chn_idx1 = int(np.random.randint(0, m, 1)) rand_chn_idx2 = int(np.random.randint(0, m, 1)) rand_chn_lab1 = raw_tmp.ch_names[rand_chn_idx1] rand_chn_lab2 = raw_tmp.ch_names[rand_chn_idx2] raw_tmp._data[rand_chn_idx1, n - 1] = np.nan raw_tmp._data[rand_chn_idx2, :] = np.ones(n) nd = NoisyChannels(raw_tmp) nd.find_bad_by_nan_flat() assert nd.bad_by_nan == [rand_chn_lab1] assert nd.bad_by_flat == [rand_chn_lab2] # Test for high and low deviations in EEG data raw_tmp = raw.copy() m, n = raw_tmp._data.shape # Now insert one random channel with very low deviations rand_chn_idx = int(np.random.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] raw_tmp._data[rand_chn_idx, :] = raw_tmp._data[rand_chn_idx, :] / 10 nd = NoisyChannels(raw_tmp) nd.find_bad_by_deviation() assert rand_chn_lab in nd.bad_by_deviation # Inserting one random channel with a high deviation raw_tmp = raw.copy() rand_chn_idx = int(np.random.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] arbitrary_scaling = 5 raw_tmp._data[rand_chn_idx, :] *= arbitrary_scaling nd = NoisyChannels(raw_tmp) nd.find_bad_by_deviation() assert rand_chn_lab in nd.bad_by_deviation # Test for correlation between EEG channels raw_tmp = raw.copy() m, n = raw_tmp._data.shape rand_chn_idx = int(np.random.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] # Use cosine instead of sine to create a signal low = 10 high = 30 n_freq = 5 signal = np.zeros((1, n)) for freq_i in range(n_freq): freq = np.random.randint(low, high, n) signal[0, :] += np.cos(2 * np.pi * raw.times * freq) raw_tmp._data[rand_chn_idx, :] = signal * 1e-6 nd = NoisyChannels(raw_tmp) nd.find_bad_by_correlation() assert rand_chn_lab in nd.bad_by_correlation # Test for high freq noise detection raw_tmp = raw.copy() m, n = raw_tmp._data.shape rand_chn_idx = int(np.random.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] # Use freqs between 90 and 100 Hz to insert hf noise signal = np.zeros((1, n)) for freq_i in range(n_freq): freq = np.random.randint(90, 100, n) signal[0, :] += np.sin(2 * np.pi * raw.times * freq) raw_tmp._data[rand_chn_idx, :] = signal * 1e-6 nd = NoisyChannels(raw_tmp) nd.find_bad_by_hfnoise() assert rand_chn_lab in nd.bad_by_hf_noise # Test for signal to noise ratio in EEG data raw_tmp = raw.copy() m, n = raw_tmp._data.shape rand_chn_idx = int(np.random.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] # inserting an uncorrelated high frequency (90 Hz) signal in one channel raw_tmp[rand_chn_idx, :] = np.sin(2 * np.pi * raw.times * 90) * 1e-6 nd = NoisyChannels(raw_tmp) nd.find_bad_by_SNR() assert rand_chn_lab in nd.bad_by_SNR # Test for finding bad channels by RANSAC raw_tmp = raw.copy() # Ransac identifies channels that go bad together and are highly correlated. # Inserting highly correlated signal in channels 0 through 3 at 30 Hz raw_tmp._data[0:6, :] = np.cos(2 * np.pi * raw.times * 30) * 1e-6 nd = NoisyChannels(raw_tmp) np.random.seed(30) nd.find_bad_by_ransac() bads = nd.bad_by_ransac assert bads == raw_tmp.ch_names[0:6]
def test_findnoisychannels(raw, montage): """Test find noisy channels.""" # Set a random state for the test rng = np.random.RandomState(30) raw.set_montage(montage) nd = NoisyChannels(raw, random_state=rng) nd.find_all_bads(ransac=True) bads = nd.get_bads() iterations = ( 10 # remove any noisy channels by interpolating the bads for 10 iterations ) for iter in range(0, iterations): if len(bads) == 0: continue raw.info["bads"] = bads raw.interpolate_bads() nd = NoisyChannels(raw, random_state=rng) nd.find_all_bads(ransac=True) bads = nd.get_bads() # make sure no bad channels exist in the data raw.drop_channels(ch_names=bads) # Test for NaN and flat channels raw_tmp = raw.copy() m, n = raw_tmp._data.shape # Insert a nan value for a random channel and make another random channel # completely flat (ones) idxs = rng.choice(np.arange(m), size=2, replace=False) rand_chn_idx1 = idxs[0] rand_chn_idx2 = idxs[1] rand_chn_lab1 = raw_tmp.ch_names[rand_chn_idx1] rand_chn_lab2 = raw_tmp.ch_names[rand_chn_idx2] raw_tmp._data[rand_chn_idx1, n - 1] = np.nan raw_tmp._data[rand_chn_idx2, :] = np.ones(n) nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_nan_flat() assert nd.bad_by_nan == [rand_chn_lab1] assert nd.bad_by_flat == [rand_chn_lab2] # Test for high and low deviations in EEG data raw_tmp = raw.copy() m, n = raw_tmp._data.shape # Now insert one random channel with very low deviations rand_chn_idx = int(rng.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] raw_tmp._data[rand_chn_idx, :] = raw_tmp._data[rand_chn_idx, :] / 10 nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_deviation() assert rand_chn_lab in nd.bad_by_deviation # Inserting one random channel with a high deviation raw_tmp = raw.copy() rand_chn_idx = int(rng.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] arbitrary_scaling = 5 raw_tmp._data[rand_chn_idx, :] *= arbitrary_scaling nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_deviation() assert rand_chn_lab in nd.bad_by_deviation # Test for correlation between EEG channels raw_tmp = raw.copy() m, n = raw_tmp._data.shape rand_chn_idx = int(rng.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] # Use cosine instead of sine to create a signal low = 10 high = 30 n_freq = 5 signal = np.zeros((1, n)) for freq_i in range(n_freq): freq = rng.randint(low, high, n) signal[0, :] += np.cos(2 * np.pi * raw.times * freq) raw_tmp._data[rand_chn_idx, :] = signal * 1e-6 nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_correlation() assert rand_chn_lab in nd.bad_by_correlation # Test for high freq noise detection raw_tmp = raw.copy() m, n = raw_tmp._data.shape rand_chn_idx = int(rng.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] # Use freqs between 90 and 100 Hz to insert hf noise signal = np.zeros((1, n)) for freq_i in range(n_freq): freq = rng.randint(90, 100, n) signal[0, :] += np.sin(2 * np.pi * raw.times * freq) raw_tmp._data[rand_chn_idx, :] = signal * 1e-6 nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_hfnoise() assert rand_chn_lab in nd.bad_by_hf_noise # Test for signal to noise ratio in EEG data raw_tmp = raw.copy() m, n = raw_tmp._data.shape rand_chn_idx = int(rng.randint(0, m, 1)) rand_chn_lab = raw_tmp.ch_names[rand_chn_idx] # inserting an uncorrelated high frequency (90 Hz) signal in one channel raw_tmp[rand_chn_idx, :] = np.sin(2 * np.pi * raw.times * 90) * 1e-6 nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_SNR() assert rand_chn_lab in nd.bad_by_SNR # Test for finding bad channels by RANSAC raw_tmp = raw.copy() # Ransac identifies channels that go bad together and are highly correlated. # Inserting highly correlated signal in channels 0 through 3 at 30 Hz raw_tmp._data[0:6, :] = np.cos(2 * np.pi * raw.times * 30) * 1e-6 nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_ransac() bads = nd.bad_by_ransac assert bads == raw_tmp.ch_names[0:6] # Test for finding bad channels by channel-wise RANSAC raw_tmp = raw.copy() # Ransac identifies channels that go bad together and are highly correlated. # Inserting highly correlated signal in channels 0 through 3 at 30 Hz raw_tmp._data[0:6, :] = np.cos(2 * np.pi * raw.times * 30) * 1e-6 nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_bad_by_ransac(channel_wise=True) bads = nd.bad_by_ransac assert bads == raw_tmp.ch_names[0:6] # Test not-enough-memory and n_samples type exceptions raw_tmp = raw.copy() raw_tmp._data[0:6, :] = np.cos(2 * np.pi * raw.times * 30) * 1e-6 nd = NoisyChannels(raw_tmp, random_state=rng) # Set n_samples very very high to trigger a memory error n_samples = int(1e100) with pytest.raises(MemoryError): nd.find_bad_by_ransac(n_samples=n_samples) # Set n_samples to a float to trigger a type error n_samples = 35.5 with pytest.raises(TypeError): nd.find_bad_by_ransac(n_samples=n_samples) # Test IOError when not enough channels for ransac predictions raw_tmp = raw.copy() # Make flat all channels except 2 num_bad_channels = raw._data.shape[0] - 2 raw_tmp._data[0:num_bad_channels, :] = np.zeros_like( raw_tmp._data[0:num_bad_channels, :] ) nd = NoisyChannels(raw_tmp, random_state=rng) nd.find_all_bads(ransac=False) with pytest.raises(IOError): nd.find_bad_by_ransac()