def test_filter_picks(): """Test filtering default channel picks""" ch_types = ['mag', 'grad', 'eeg', 'seeg', 'misc', 'stim', 'ecog'] info = create_info(ch_names=ch_types, ch_types=ch_types, sfreq=256) raw = RawArray(data=np.zeros((len(ch_types), 1000)), info=info) # -- Deal with meg mag grad exception ch_types = ('misc', 'stim', 'meg', 'eeg', 'seeg', 'ecog') # -- Filter data channels for ch_type in ('mag', 'grad', 'eeg', 'seeg', 'ecog'): picks = dict((ch, ch == ch_type) for ch in ch_types) picks['meg'] = ch_type if ch_type in ('mag', 'grad') else False raw_ = raw.copy().pick_types(**picks) # Avoid RuntimeWarning due to Attenuation with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') raw_.filter(10, 30) assert_true(any(['Attenuation' in str(ww.message) for ww in w])) # -- Error if no data channel for ch_type in ('misc', 'stim'): picks = dict((ch, ch == ch_type) for ch in ch_types) raw_ = raw.copy().pick_types(**picks) assert_raises(RuntimeError, raw_.filter, 10, 30)
def test_annotate_flat(first_samp): """Test marking flat segments.""" # Test if ECG analysis will work on data that is not preloaded n_ch, n_times = 11, 1000 data = np.random.RandomState(0).randn(n_ch, n_times) assert not (np.diff(data, axis=-1) == 0).any() # nothing flat at first info = create_info(n_ch, 1000., 'eeg') info['meas_date'] = (1, 2) # test first_samp != for gh-6295 raw = RawArray(data, info, first_samp=first_samp) raw.info['bads'] = [raw.ch_names[-1]] # # First make a channel flat the whole time # raw_0 = raw.copy() raw_0._data[0] = 0. for kwargs, bads, want_times in [ # Anything < 1 will mark spatially (dict(bad_percent=100.), [], 0), (dict(bad_percent=99.9), [raw.ch_names[0]], n_times), (dict(), [raw.ch_names[0]], n_times) ]: # default (1) raw_time = raw_0.copy() annot, got_bads = annotate_flat(raw_0, verbose='debug', **kwargs) assert got_bads == bads raw_time.set_annotations(raw_time.annotations + annot) raw_time.info['bads'] += got_bads n_good_times = raw_time.get_data(reject_by_annotation='omit').shape[1] assert n_good_times == want_times with pytest.deprecated_call(match='annotate_flat'): raw_time_2 = mark_flat(raw_0.copy(), verbose='debug', **kwargs) _assert_annotations_equal(raw_time_2.annotations, raw_time.annotations) assert raw_time_2.info['bads'] == raw_time.info['bads'] # # Now make a channel flat for 20% of the time points # raw_0 = raw.copy() n_good_times = int(round(0.8 * n_times)) raw_0._data[0, n_good_times:] = 0. threshold = 100 * (n_times - n_good_times) / n_times for kwargs, bads, want_times in [ # Should change behavior at bad_percent=20 (dict(bad_percent=100), [], n_good_times), (dict(bad_percent=threshold), [], n_good_times), (dict(bad_percent=threshold - 1e-5), [raw.ch_names[0]], n_times), (dict(), [raw.ch_names[0]], n_times) ]: annot, got_bads = annotate_flat(raw_0, verbose='debug', **kwargs) assert got_bads == bads raw_time = raw_0.copy() raw_time.set_annotations(raw_time.annotations + annot) raw_time.info['bads'] += got_bads n_good_times = raw_time.get_data(reject_by_annotation='omit').shape[1] assert n_good_times == want_times with pytest.raises(TypeError, match='must be an instance of BaseRaw'): annotate_flat(0.) with pytest.raises(ValueError, match='not convert string to float'): annotate_flat(raw, 'x')
def test_set_eeg_reference_ch_type(ch_type): """Test setting EEG reference for ECoG or DBS.""" # gh-6454 # gh-8739 added DBS ch_names = ['ECOG01', 'ECOG02', 'DBS01', 'DBS02', 'MISC'] rng = np.random.RandomState(0) data = rng.randn(5, 1000) raw = RawArray( data, create_info(ch_names, 1000., ['ecog'] * 2 + ['dbs'] * 2 + ['misc'])) if ch_type == 'auto': ref_ch = ch_names[:2] else: ref_ch = raw.copy().pick(picks=ch_type).ch_names with catch_logging() as log: reref, ref_data = set_eeg_reference(raw.copy(), ch_type=ch_type, verbose=True) if ch_type in ['auto', 'ecog']: assert 'Applying a custom ECoG' in log.getvalue() else: assert 'Applying a custom DBS' in log.getvalue() assert reref.info['custom_ref_applied'] # gh-7350 _test_reference(raw, reref, ref_data, ref_ch) with pytest.raises(ValueError, match='No channels supplied'): set_eeg_reference(raw, ch_type='eeg') # gh-8739 raw2 = RawArray(data, create_info(5, 1000., ['mag'] * 4 + ['misc'])) with pytest.raises(ValueError, match='No EEG, ECoG, sEEG or DBS channels ' 'found to rereference.'): set_eeg_reference(raw2, ch_type='auto')
def test_annotate_amplitude_multiple_ch_types(meas_date, first_samp): """Test cases with several channel types.""" n_ch, n_times = 11, 1000 data = np.random.RandomState(0).randn(n_ch, n_times) assert not (np.diff(data, axis=-1) == 0).any() # nothing flat at first info = create_info(n_ch, 1000., ['eeg'] * 3 + ['mag'] * 2 + ['grad'] * 4 + ['eeg'] * 2) # from annotate_flat: test first_samp != for gh-6295 raw = RawArray(data, info, first_samp=first_samp) raw.info['bads'] = [raw.ch_names[-1]] raw.set_meas_date(meas_date) # -- 2 channel types both to annotate -- raw_ = raw.copy() raw_._data[1, 800:] = 0. raw_._data[5, :200] = np.arange(0, 200 * 10, 10) raw_._data[5, 200:] += raw_._data[5, 199] # add offset for next samples annots, bads = annotate_amplitude(raw_, peak=5, flat=0, bad_percent=50) assert len(annots) == 2 assert len(bads) == 0 # check annotation instance assert all(annot['description'] in ('BAD_flat', 'BAD_peak') for annot in annots) for annot in annots: start_idx = 0 if annot['description'] == 'BAD_peak' else 800 stop_idx = 199 if annot['description'] == 'BAD_peak' else -1 _check_annotation(raw_, annot, meas_date, first_samp, start_idx, stop_idx) # -- 2 channel types, one flat picked, one not picked -- raw_ = raw.copy() raw_._data[1, 800:] = 0. raw_._data[5, :200] = np.arange(0, 200 * 10, 10) raw_._data[5, 200:] += raw_._data[5, 199] # add offset for next samples annots, bads = annotate_amplitude(raw_, peak=5, flat=0, bad_percent=50, picks='eeg') assert len(annots) == 1 assert len(bads) == 0 # check annotation instance _check_annotation(raw_, annots[0], meas_date, first_samp, 800, -1) assert annots[0]['description'] == 'BAD_flat' # -- 2 channel types, one flat, one not picked, reverse -- raw_ = raw.copy() raw_._data[1, 800:] = 0. raw_._data[5, :200] = np.arange(0, 200 * 10, 10) raw_._data[5, 200:] += raw_._data[5, 199] # add offset for next samples annots, bads = annotate_amplitude(raw_, peak=5, flat=0, bad_percent=50, picks='grad') assert len(annots) == 1 assert len(bads) == 0 # check annotation instance _check_annotation(raw_, annots[0], meas_date, first_samp, 0, 199) assert annots[0]['description'] == 'BAD_peak'
def test_flat_bad_acq_skip(): """Test that acquisition skips are handled properly.""" # -- file with a couple of skip and flat channels -- raw = read_raw_fif(skip_fname, preload=True) annots, bads = annotate_amplitude(raw, flat=0) assert len(annots) == 0 assert bads == [ # MaxFilter finds the same 21 channels 'MEG%04d' % (int(num),) for num in '141 331 421 431 611 641 1011 1021 1031 1241 1421 ' '1741 1841 2011 2131 2141 2241 2531 2541 2611 2621'.split()] # -- overlap of flat segment with bad_acq_skip -- n_ch, n_times = 11, 1000 data = np.random.RandomState(0).randn(n_ch, n_times) assert not (np.diff(data, axis=-1) == 0).any() # nothing flat at first info = create_info(n_ch, 1000., 'eeg') raw = RawArray(data, info, first_samp=0) raw.info['bads'] = [raw.ch_names[-1]] bad_acq_skip = Annotations([0.5], [0.2], ['bad_acq_skip'], orig_time=None) raw.set_annotations(bad_acq_skip) # add flat channel overlapping with the left edge of bad_acq_skip raw_ = raw.copy() raw_._data[0, 400:600] = 0. annots, bads = annotate_amplitude(raw_, peak=None, flat=0, bad_percent=25) assert len(annots) == 1 assert len(bads) == 0 # check annotation instance assert annots[0]['description'] == 'BAD_flat' _check_annotation(raw_, annots[0], None, 0, 400, 499) # add flat channel overlapping with the right edge of bad_acq_skip raw_ = raw.copy() raw_._data[0, 600:800] = 0. annots, bads = annotate_amplitude(raw_, peak=None, flat=0, bad_percent=25) assert len(annots) == 1 assert len(bads) == 0 # check annotation instance assert annots[0]['description'] == 'BAD_flat' _check_annotation(raw_, annots[0], None, 0, 700, 799) # add flat channel overlapping entirely with bad_acq_skip raw_ = raw.copy() raw_._data[0, 200:800] = 0. annots, bads = annotate_amplitude(raw_, peak=None, flat=0, bad_percent=41) assert len(annots) == 2 assert len(bads) == 0 # check annotation instance annots = sorted(annots, key=lambda x: x['onset']) assert all(annot['description'] == 'BAD_flat' for annot in annots) _check_annotation(raw_, annots[0], None, 0, 200, 500) _check_annotation(raw_, annots[1], None, 0, 700, 799)
def test_mark_flat(first_samp): """Test marking flat segments.""" # Test if ECG analysis will work on data that is not preloaded n_ch, n_times = 11, 1000 data = np.random.RandomState(0).randn(n_ch, n_times) assert not (np.diff(data, axis=-1) == 0).any() # nothing flat at first info = create_info(n_ch, 1000., 'eeg') info['meas_date'] = (1, 2) # test first_samp != for gh-6295 raw = RawArray(data, info, first_samp=first_samp) raw.info['bads'] = [raw.ch_names[-1]] # # First make a channel flat the whole time # raw_0 = raw.copy() raw_0._data[0] = 0. for kwargs, bads, want_times in [ # Anything < 1 will mark spatially (dict(bad_percent=100.), [], 0), (dict(bad_percent=99.9), [raw.ch_names[0]], n_times), (dict(), [raw.ch_names[0]], n_times)]: # default (1) raw_time = mark_flat(raw_0.copy(), verbose='debug', **kwargs) want_bads = raw.info['bads'] + bads assert raw_time.info['bads'] == want_bads n_good_times = raw_time.get_data(reject_by_annotation='omit').shape[1] assert n_good_times == want_times # # Now make a channel flat for 20% of the time points # raw_0 = raw.copy() n_good_times = int(round(0.8 * n_times)) raw_0._data[0, n_good_times:] = 0. threshold = 100 * (n_times - n_good_times) / n_times for kwargs, bads, want_times in [ # Should change behavior at bad_percent=20 (dict(bad_percent=100), [], n_good_times), (dict(bad_percent=threshold), [], n_good_times), (dict(bad_percent=threshold - 1e-5), [raw.ch_names[0]], n_times), (dict(), [raw.ch_names[0]], n_times)]: raw_time = mark_flat(raw_0.copy(), verbose='debug', **kwargs) want_bads = raw.info['bads'] + bads assert raw_time.info['bads'] == want_bads n_good_times = raw_time.get_data(reject_by_annotation='omit').shape[1] assert n_good_times == want_times with pytest.raises(TypeError, match='must be an instance of BaseRaw'): mark_flat(0.) with pytest.raises(ValueError, match='not convert string to float'): mark_flat(raw, 'x')
def test_annotate_amplitude_with_overlap(meas_date, first_samp): """Test cases with overlap between annotations.""" n_ch, n_times = 11, 1000 data = np.random.RandomState(0).randn(n_ch, n_times) assert not (np.diff(data, axis=-1) == 0).any() # nothing flat at first info = create_info(n_ch, 1000., 'eeg') # from annotate_flat: test first_samp != for gh-6295 raw = RawArray(data, info, first_samp=first_samp) raw.info['bads'] = [raw.ch_names[-1]] raw.set_meas_date(meas_date) # -- overlap between peak and flat -- raw_ = raw.copy() raw_._data[0, 800:] = 0. raw_._data[1, 700:900] = np.arange(0, 200 * 10, 10) raw_._data[1, 900:] += raw_._data[1, 899] # add offset for next samples annots, bads = annotate_amplitude(raw_, peak=5, flat=0, bad_percent=25) assert len(annots) == 2 assert len(bads) == 0 # check annotation instance assert all(annot['description'] in ('BAD_flat', 'BAD_peak') for annot in annots) for annot in annots: start_idx = 700 if annot['description'] == 'BAD_peak' else 800 stop_idx = 899 if annot['description'] == 'BAD_peak' else -1 _check_annotation(raw_, annot, meas_date, first_samp, start_idx, stop_idx) # -- overlap between peak and peak on same channel -- raw_ = raw.copy() raw_._data[0, 700:900] = np.arange(0, 200 * 10, 10) raw_._data[0, 800:] = np.arange(1000, 300 * 10, 10) annots, bads = annotate_amplitude(raw_, peak=5, flat=None, bad_percent=50) assert len(annots) == 1 assert len(bads) == 0 # check annotation instance assert annots[0]['description'] == 'BAD_peak' _check_annotation(raw_, annots[0], meas_date, first_samp, 700, -1) # -- overlap between flat and flat on different channel -- raw_ = raw.copy() raw_._data[0, 700:900] = 0. raw_._data[1, 800:] = 0. annots, bads = annotate_amplitude(raw_, peak=None, flat=0.01, bad_percent=50) assert len(annots) == 1 assert len(bads) == 0 # check annotation instance assert annots[0]['description'] == 'BAD_flat' _check_annotation(raw_, annots[0], meas_date, first_samp, 700, -1)
def test_picks_by_channels(): """Test creating pick_lists.""" rng = np.random.RandomState(909) test_data = rng.random_sample((4, 2000)) ch_names = ['MEG %03d' % i for i in [1, 2, 3, 4]] ch_types = ['grad', 'mag', 'mag', 'eeg'] sfreq = 250.0 info = create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) _assert_channel_types(info) raw = RawArray(test_data, info) pick_list = _picks_by_type(raw.info) assert_equal(len(pick_list), 3) assert_equal(pick_list[0][0], 'mag') pick_list2 = _picks_by_type(raw.info, meg_combined=False) assert_equal(len(pick_list), len(pick_list2)) assert_equal(pick_list2[0][0], 'mag') pick_list2 = _picks_by_type(raw.info, meg_combined=True) assert_equal(len(pick_list), len(pick_list2) + 1) assert_equal(pick_list2[0][0], 'meg') test_data = rng.random_sample((4, 2000)) ch_names = ['MEG %03d' % i for i in [1, 2, 3, 4]] ch_types = ['mag', 'mag', 'mag', 'mag'] sfreq = 250.0 info = create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) raw = RawArray(test_data, info) # This acts as a set, not an order assert_array_equal(pick_channels(info['ch_names'], ['MEG 002', 'MEG 001']), [0, 1]) # Make sure checks for list input work. pytest.raises(ValueError, pick_channels, ch_names, 'MEG 001') pytest.raises(ValueError, pick_channels, ch_names, ['MEG 001'], 'hi') pick_list = _picks_by_type(raw.info) assert_equal(len(pick_list), 1) assert_equal(pick_list[0][0], 'mag') pick_list2 = _picks_by_type(raw.info, meg_combined=True) assert_equal(len(pick_list), len(pick_list2)) assert_equal(pick_list2[0][0], 'mag') # pick_types type check with pytest.raises(ValueError, match='must be of type'): raw.pick_types(eeg='string') # duplicate check names = ['MEG 002', 'MEG 002'] assert len(pick_channels(raw.info['ch_names'], names)) == 1 assert len(raw.copy().pick_channels(names)[0][0]) == 1
def test_picks_by_channels(): """Test creating pick_lists.""" rng = np.random.RandomState(909) test_data = rng.random_sample((4, 2000)) ch_names = ['MEG %03d' % i for i in [1, 2, 3, 4]] ch_types = ['grad', 'mag', 'mag', 'eeg'] sfreq = 250.0 info = create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) _assert_channel_types(info) raw = RawArray(test_data, info) pick_list = _picks_by_type(raw.info) assert_equal(len(pick_list), 3) assert_equal(pick_list[0][0], 'mag') pick_list2 = _picks_by_type(raw.info, meg_combined=False) assert_equal(len(pick_list), len(pick_list2)) assert_equal(pick_list2[0][0], 'mag') pick_list2 = _picks_by_type(raw.info, meg_combined=True) assert_equal(len(pick_list), len(pick_list2) + 1) assert_equal(pick_list2[0][0], 'meg') test_data = rng.random_sample((4, 2000)) ch_names = ['MEG %03d' % i for i in [1, 2, 3, 4]] ch_types = ['mag', 'mag', 'mag', 'mag'] sfreq = 250.0 info = create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) raw = RawArray(test_data, info) # This acts as a set, not an order assert_array_equal(pick_channels(info['ch_names'], ['MEG 002', 'MEG 001']), [0, 1]) # Make sure checks for list input work. pytest.raises(ValueError, pick_channels, ch_names, 'MEG 001') pytest.raises(ValueError, pick_channels, ch_names, ['MEG 001'], 'hi') pick_list = _picks_by_type(raw.info) assert_equal(len(pick_list), 1) assert_equal(pick_list[0][0], 'mag') pick_list2 = _picks_by_type(raw.info, meg_combined=True) assert_equal(len(pick_list), len(pick_list2)) assert_equal(pick_list2[0][0], 'mag') # pick_types type check pytest.raises(ValueError, raw.pick_types, eeg='string') # duplicate check names = ['MEG 002', 'MEG 002'] assert len(pick_channels(raw.info['ch_names'], names)) == 1 assert len(raw.copy().pick_channels(names)[0][0]) == 1
def test_set_eeg_reference_ch_type(ch_type): """Test setting EEG reference for ECoG.""" # gh-6454 rng = np.random.RandomState(0) data = rng.randn(3, 1000) raw = RawArray(data, create_info(3, 1000., ['ecog'] * 2 + ['misc'])) with catch_logging() as log: reref, ref_data = set_eeg_reference(raw.copy(), ch_type=ch_type, verbose=True) assert 'Applying a custom ECoG' in log.getvalue() assert reref.info['custom_ref_applied'] # gh-7350 _test_reference(raw, reref, ref_data, ['0', '1']) with pytest.raises(ValueError, match='No channels supplied'): set_eeg_reference(raw, ch_type='eeg')
def test_crop(): """Test cropping raw files """ # split a concatenated file to test a difficult case raw = concatenate_raws([Raw(f) for f in [fif_fname, fif_fname]]) split_size = 10. # in seconds sfreq = raw.info['sfreq'] nsamp = (raw.last_samp - raw.first_samp + 1) # do an annoying case (off-by-one splitting) tmins = np.r_[1., np.round(np.arange(0., nsamp - 1, split_size * sfreq))] tmins = np.sort(tmins) tmaxs = np.concatenate((tmins[1:] - 1, [nsamp - 1])) tmaxs /= sfreq tmins /= sfreq raws = [None] * len(tmins) for ri, (tmin, tmax) in enumerate(zip(tmins, tmaxs)): raws[ri] = raw.copy().crop(tmin, tmax, copy=False) all_raw_2 = concatenate_raws(raws, preload=False) assert_equal(raw.first_samp, all_raw_2.first_samp) assert_equal(raw.last_samp, all_raw_2.last_samp) assert_array_equal(raw[:, :][0], all_raw_2[:, :][0]) tmins = np.round(np.arange(0., nsamp - 1, split_size * sfreq)) tmaxs = np.concatenate((tmins[1:] - 1, [nsamp - 1])) tmaxs /= sfreq tmins /= sfreq # going in revere order so the last fname is the first file (need it later) raws = [None] * len(tmins) for ri, (tmin, tmax) in enumerate(zip(tmins, tmaxs)): raws[ri] = raw.copy().crop(tmin, tmax, copy=False) # test concatenation of split file all_raw_1 = concatenate_raws(raws, preload=False) all_raw_2 = raw.copy().crop(0, None, copy=False) for ar in [all_raw_1, all_raw_2]: assert_equal(raw.first_samp, ar.first_samp) assert_equal(raw.last_samp, ar.last_samp) assert_array_equal(raw[:, :][0], ar[:, :][0]) # test shape consistency of cropped raw data = np.zeros((1, 1002001)) info = create_info(1, 1000) raw = RawArray(data, info) for tmin in range(0, 1001, 100): raw1 = raw.copy().crop(tmin=tmin, tmax=tmin + 2, copy=False) assert_equal(raw1[:][0].shape, (1, 2001))
def fc_aec(data, sfreq, freq_bands): """ data is ROI x TIME freq bands is a dict of (lower,upper) freq tuples using bits from https://martinos.org/mne/dev/auto_tutorials/plot_modifying_data_inplace.html """ # N rois nr = data.shape[0] # Convert time series data to MNE raw datatype so we can use filter and hilbert functions ch_names = [str(s) for s in range(0, nr)] ch_types = ['eeg' for _ in ch_names] info = create_info(ch_names, sfreq, ch_types=ch_types) raw = RawArray(data.copy(), info) aecs = {} for freq_band, (lfreq, hfreq) in freq_bands.items(): # Filter raw_band = raw.copy() raw_band.filter(lfreq, hfreq, l_trans_bandwidth=2., h_trans_bandwidth=2., fir_design='firwin') raw_hilb = raw_band.copy() # Compute hilbert transform hilb_picks = pick_types(raw_band.info, meg=False, eeg=True) raw_hilb.apply_hilbert(hilb_picks) # Take the amplitude and phase raw_amp = raw_hilb.copy() raw_amp.apply_function(np.abs, hilb_picks) raw_phase = raw_hilb.copy() raw_phase.apply_function(np.angle, hilb_picks) aecs[freq_band] = raw_amp.to_data_frame().corr().values return aecs
def test_rawarray_edf(tmp_path): """Test saving a Raw array with integer sfreq to EDF.""" rng = np.random.RandomState(12345) format = 'edf' ch_types = [ 'eeg', 'eeg', 'stim', 'ecog', 'seeg', 'eog', 'ecg', 'emg', 'dbs', 'bio' ] ch_names = np.arange(len(ch_types)).astype(str).tolist() info = create_info(ch_names, sfreq=1000, ch_types=ch_types) data = rng.random(size=(len(ch_names), 1000)) * 1e-5 # include subject info and measurement date subject_info = dict(first_name='mne', last_name='python', birthday=(1992, 1, 20), sex=1, hand=3) info['subject_info'] = subject_info raw = RawArray(data, info) time_now = datetime.now() meas_date = datetime(year=time_now.year, month=time_now.month, day=time_now.day, hour=time_now.hour, minute=time_now.minute, second=time_now.second, tzinfo=timezone.utc) raw.set_meas_date(meas_date) temp_fname = op.join(str(tmp_path), f'test.{format}') raw.export(temp_fname, add_ch_type=True) raw_read = read_raw_edf(temp_fname, preload=True) # stim channel should be dropped raw.drop_channels('2') assert raw.ch_names == raw_read.ch_names # only compare the original length, since extra zeros are appended orig_raw_len = len(raw) assert_array_almost_equal(raw.get_data(), raw_read.get_data()[:, :orig_raw_len], decimal=4) assert_allclose(raw.times, raw_read.times[:orig_raw_len], rtol=0, atol=1e-5) # check channel types except for 'bio', which loses its type orig_ch_types = raw.get_channel_types() read_ch_types = raw_read.get_channel_types() assert_array_equal(orig_ch_types, read_ch_types) assert raw.info['meas_date'] == raw_read.info['meas_date'] # channel name can't be longer than 16 characters with the type added raw_bad = raw.copy() raw_bad.rename_channels({'1': 'abcdefghijklmnopqrstuvwxyz'}) with pytest.raises(RuntimeError, match='Signal label'), \ pytest.warns(RuntimeWarning, match='Data has a non-integer'): raw_bad.export(temp_fname) # include bad birthday that is non-EDF compliant bad_info = info.copy() bad_info['subject_info']['birthday'] = (1700, 1, 20) raw = RawArray(data, bad_info) with pytest.raises(RuntimeError, match='Setting patient birth date'): raw.export(temp_fname) # include bad measurement date that is non-EDF compliant raw = RawArray(data, info) meas_date = datetime(year=1984, month=1, day=1, tzinfo=timezone.utc) raw.set_meas_date(meas_date) with pytest.raises(RuntimeError, match='Setting start date time'): raw.export(temp_fname) # test that warning is raised if there are non-voltage based channels raw = RawArray(data, info) with pytest.warns(RuntimeWarning, match='The unit'): raw.set_channel_types({'9': 'hbr'}) with pytest.warns(RuntimeWarning, match='Non-voltage channels'): raw.export(temp_fname) # data should match up to the non-accepted channel raw_read = read_raw_edf(temp_fname, preload=True) orig_raw_len = len(raw) assert_array_almost_equal(raw.get_data()[:-1, :], raw_read.get_data()[:, :orig_raw_len], decimal=4) assert_allclose(raw.times, raw_read.times[:orig_raw_len], rtol=0, atol=1e-5) # the data should still match though raw_read = read_raw_edf(temp_fname, preload=True) raw.drop_channels('2') assert raw.ch_names == raw_read.ch_names orig_raw_len = len(raw) assert_array_almost_equal(raw.get_data(), raw_read.get_data()[:, :orig_raw_len], decimal=4) assert_allclose(raw.times, raw_read.times[:orig_raw_len], rtol=0, atol=1e-5)
def test_set_eeg_reference(): """Test rereference eeg data.""" raw = read_raw_fif(fif_fname, preload=True) raw.info['projs'] = [] # Test setting an average reference projection assert (not _has_eeg_average_ref_proj(raw.info['projs'])) reref, ref_data = set_eeg_reference(raw, projection=True) assert (_has_eeg_average_ref_proj(reref.info['projs'])) assert (not reref.info['projs'][0]['active']) assert (ref_data is None) reref.apply_proj() eeg_chans = [raw.ch_names[ch] for ch in pick_types(raw.info, meg=False, eeg=True)] _test_reference(raw, reref, ref_data, [ch for ch in eeg_chans if ch not in raw.info['bads']]) # Test setting an average reference when one was already present with pytest.warns(RuntimeWarning, match='untouched'): reref, ref_data = set_eeg_reference(raw, copy=False, projection=True) assert ref_data is None # Test setting an average reference on non-preloaded data raw_nopreload = read_raw_fif(fif_fname, preload=False) raw_nopreload.info['projs'] = [] reref, ref_data = set_eeg_reference(raw_nopreload, projection=True) assert (_has_eeg_average_ref_proj(reref.info['projs'])) assert (not reref.info['projs'][0]['active']) # Rereference raw data by creating a copy of original data reref, ref_data = set_eeg_reference(raw, ['EEG 001', 'EEG 002'], copy=True) assert (reref.info['custom_ref_applied']) _test_reference(raw, reref, ref_data, ['EEG 001', 'EEG 002']) # Test that data is modified in place when copy=False reref, ref_data = set_eeg_reference(raw, ['EEG 001', 'EEG 002'], copy=False) assert (raw is reref) # Test moving from custom to average reference reref, ref_data = set_eeg_reference(raw, ['EEG 001', 'EEG 002']) reref, _ = set_eeg_reference(reref, projection=True) assert (_has_eeg_average_ref_proj(reref.info['projs'])) assert_equal(reref.info['custom_ref_applied'], False) # When creating an average reference fails, make sure the # custom_ref_applied flag remains untouched. reref = raw.copy() reref.info['custom_ref_applied'] = True reref.pick_types(eeg=False) # Cause making average ref fail pytest.raises(ValueError, set_eeg_reference, reref, projection=True) assert (reref.info['custom_ref_applied']) # Test moving from average to custom reference reref, ref_data = set_eeg_reference(raw, projection=True) reref, _ = set_eeg_reference(reref, ['EEG 001', 'EEG 002']) assert not _has_eeg_average_ref_proj(reref.info['projs']) assert len(reref.info['projs']) == 0 assert_equal(reref.info['custom_ref_applied'], True) # Test that disabling the reference does not change the data assert _has_eeg_average_ref_proj(raw.info['projs']) reref, _ = set_eeg_reference(raw, []) assert_array_equal(raw._data, reref._data) assert not _has_eeg_average_ref_proj(reref.info['projs']) # make sure ref_channels=[] removes average reference projectors assert _has_eeg_average_ref_proj(raw.info['projs']) reref, _ = set_eeg_reference(raw, []) assert (not _has_eeg_average_ref_proj(reref.info['projs'])) # Test that average reference gives identical results when calculated # via SSP projection (projection=True) or directly (projection=False) raw.info['projs'] = [] reref_1, _ = set_eeg_reference(raw.copy(), projection=True) reref_1.apply_proj() reref_2, _ = set_eeg_reference(raw.copy(), projection=False) assert_allclose(reref_1._data, reref_2._data, rtol=1e-6, atol=1e-15) # Test average reference without projection reref, ref_data = set_eeg_reference(raw.copy(), ref_channels="average", projection=False) _test_reference(raw, reref, ref_data, eeg_chans) with pytest.raises(ValueError, match='supported for ref_channels="averag'): set_eeg_reference(raw, [], True, True) with pytest.raises(ValueError, match='supported for ref_channels="averag'): set_eeg_reference(raw, ['EEG 001'], True, True) # gh-6454 rng = np.random.RandomState(0) data = rng.randn(3, 1000) raw = RawArray(data, create_info(3, 1000., ['ecog'] * 2 + ['misc'])) reref, ref_data = set_eeg_reference(raw.copy()) _test_reference(raw, reref, ref_data, ['0', '1'])
def test_annotations(): """Test annotation class.""" raw = read_raw_fif(fif_fname) onset = np.array(range(10)) duration = np.ones(10) description = np.repeat('test', 10) dt = datetime.utcnow() meas_date = raw.info['meas_date'] # Test time shifts. for orig_time in [None, dt, meas_date[0], meas_date]: annot = Annotations(onset, duration, description, orig_time) assert_raises(ValueError, Annotations, onset, duration, description[:9]) assert_raises(ValueError, Annotations, [onset, 1], duration, description) assert_raises(ValueError, Annotations, onset, [duration, 1], description) # Test combining annotations with concatenate_raws raw2 = raw.copy() orig_time = (meas_date[0] + meas_date[1] * 0.000001 + raw2.first_samp / raw2.info['sfreq']) annot = Annotations(onset, duration, description, orig_time) assert_true(' segments' in repr(annot)) raw2.annotations = annot assert_array_equal(raw2.annotations.onset, onset) concatenate_raws([raw, raw2]) raw.annotations.delete(-1) # remove boundary annotations raw.annotations.delete(-1) assert_array_almost_equal(onset + 20., raw.annotations.onset, decimal=2) assert_array_equal(annot.duration, raw.annotations.duration) assert_array_equal(raw.annotations.description, np.repeat('test', 10)) # Test combining with RawArray and orig_times data = np.random.randn(2, 1000) * 10e-12 sfreq = 100. info = create_info(ch_names=['MEG1', 'MEG2'], ch_types=['grad'] * 2, sfreq=sfreq) info['meas_date'] = 0 raws = [] for i, fs in enumerate([12300, 100, 12]): raw = RawArray(data.copy(), info, first_samp=fs) ants = Annotations([1., 2.], [.5, .5], 'x', fs / sfreq) raw.annotations = ants raws.append(raw) raw = RawArray(data.copy(), info) raw.annotations = Annotations([1.], [.5], 'x', None) raws.append(raw) raw = concatenate_raws(raws) boundary_idx = np.where(raw.annotations.description == 'BAD boundary')[0] assert_equal(len(boundary_idx), 3) raw.annotations.delete(boundary_idx) boundary_idx = np.where(raw.annotations.description == 'EDGE boundary')[0] assert_equal(len(boundary_idx), 3) raw.annotations.delete(boundary_idx) assert_array_equal(raw.annotations.onset, [1., 2., 11., 12., 21., 22., 31.]) raw.annotations.delete(2) assert_array_equal(raw.annotations.onset, [1., 2., 12., 21., 22., 31.]) raw.annotations.append(5, 1.5, 'y') assert_array_equal(raw.annotations.onset, [1., 2., 12., 21., 22., 31., 5]) assert_array_equal(raw.annotations.duration, [.5, .5, .5, .5, .5, .5, 1.5]) assert_array_equal(raw.annotations.description, ['x', 'x', 'x', 'x', 'x', 'x', 'y']) # Test concatenating annotations with and without orig_time. raw = read_raw_fif(fif_fname) last_time = raw.last_samp / raw.info['sfreq'] raw2 = raw.copy() raw.annotations = Annotations([45.], [3], 'test', raw.info['meas_date']) raw2.annotations = Annotations([2.], [3], 'BAD', None) raw = concatenate_raws([raw, raw2]) raw.annotations.delete(-1) # remove boundary annotations raw.annotations.delete(-1) assert_array_almost_equal(raw.annotations.onset, [45., 2. + last_time], decimal=2)
def test_realign(ratio_other, start_raw, start_other, stop_raw, stop_other): """Test realigning raw.""" # construct a true signal sfreq = 100. duration = 50 stop_raw = duration - stop_raw stop_other = duration - stop_other signal = np.zeros(int(round((duration + 1) * sfreq))) orig_events = np.round( np.arange( max(start_raw, start_other) + 2, min(stop_raw, stop_other) - 2) * sfreq).astype(int) signal[orig_events] = 1. n_events = len(orig_events) times = np.arange(len(signal)) / sfreq stim = np.convolve(signal, np.ones(int(round(0.02 * sfreq))))[:len(times)] signal = np.convolve(signal, np.hanning(int(round(0.2 * sfreq))))[:len(times)] # construct our sampled versions of these signals (linear interp is fine) sfreq_raw = sfreq sfreq_other = ratio_other * sfreq raw_times = np.arange(start_raw, stop_raw, 1. / sfreq_raw) other_times = np.arange(start_other, stop_other, 1. / sfreq_other) assert raw_times[0] >= times[0] assert raw_times[-1] <= times[-1] assert other_times[0] >= times[0] assert other_times[-1] <= times[-1] data_raw = np.array([ interp1d(times, d, kind)(raw_times) for d, kind in ((signal, 'linear'), (stim, 'nearest')) ]) data_other = np.array([ interp1d(times, d, kind)(other_times) for d, kind in ((signal, 'linear'), (stim, 'nearest')) ]) info_raw = create_info(['raw_data', 'raw_stim'], sfreq, ['eeg', 'stim']) info_other = create_info(['other_data', 'other_stim'], sfreq, ['eeg', 'stim']) raw = RawArray(data_raw, info_raw, first_samp=111) other = RawArray(data_other, info_other, first_samp=222) # naive processing evoked_raw, events_raw, _, events_other = _assert_similarity( raw, other, n_events) if start_raw == start_other: # can just naively crop a, b = data_raw[0], data_other[0] n = min(len(a), len(b)) corr = np.corrcoef(a[:n], b[:n])[0, 1] min_, max_ = (0.99999, 1.) if sfreq_raw == sfreq_other else (0.8, 0.9) assert min_ <= corr <= max_ # realign t_raw = (events_raw[:, 0] - raw.first_samp) / other.info['sfreq'] t_other = (events_other[:, 0] - other.first_samp) / other.info['sfreq'] assert duration - 10 <= len(events_raw) < duration raw_orig, other_orig = raw.copy(), other.copy() realign_raw(raw, other, t_raw, t_other) # old events should still work for raw and produce the same result evoked_raw_2, _, _, _ = _assert_similarity(raw, other, n_events, events_raw=events_raw) assert_allclose(evoked_raw.data, evoked_raw_2.data) assert_allclose(raw.times, other.times) # raw data now aligned corr = np.corrcoef(raw.get_data([0])[0], other.get_data([0])[0])[0, 1] assert 0.99 < corr <= 1. # Degenerate conditions -- only test in one run test_degenerate = (start_raw == start_other and stop_raw == stop_other and ratio_other == 1) if not test_degenerate: return # these alignments will not be correct but it shouldn't matter with pytest.warns(RuntimeWarning, match='^Fewer.*may be unreliable.*'): realign_raw(raw, other, raw_times[:5], other_times[:5]) with pytest.raises(ValueError, match='same shape'): realign_raw(raw_orig, other_orig, raw_times[:5], other_times) rand_times = np.random.RandomState(0).randn(len(other_times)) with pytest.raises(ValueError, match='cannot resample safely'): realign_raw(raw_orig, other_orig, rand_times, other_times) with pytest.warns(RuntimeWarning, match='.*computed as R=.*unreliable'): realign_raw(raw_orig, other_orig, raw_times + rand_times * 1000, other_times)
def test_annotate_amplitude(meas_date, first_samp): """Test automatic annotation for segments based on peak-to-peak value.""" n_ch, n_times = 11, 1000 data = np.random.RandomState(0).randn(n_ch, n_times) assert not (np.diff(data, axis=-1) == 0).any() # nothing flat at first info = create_info(n_ch, 1000., 'eeg') # from annotate_flat: test first_samp != for gh-6295 raw = RawArray(data, info, first_samp=first_samp) raw.info['bads'] = [raw.ch_names[-1]] raw.set_meas_date(meas_date) # -- test bad channels spatial marking -- for perc, dur in itertools.product((5, 99.9, 100.), (0.005, 0.95, 0.99)): kwargs = dict(bad_percent=perc, min_duration=dur) # test entire channel flat raw_ = raw.copy() raw_._data[0] = 0. annots, bads = annotate_amplitude(raw_, peak=None, flat=0., **kwargs) assert len(annots) == 0 assert bads == ['0'] # test multiple channels flat raw_ = raw.copy() raw_._data[0] = 0. raw_._data[2] = 0. annots, bads = annotate_amplitude(raw_, peak=None, flat=0., **kwargs) assert len(annots) == 0 assert bads == ['0', '2'] # test entire channel drifting raw_ = raw.copy() raw_._data[0] = np.arange(0, raw.times.size * 10, 10) annots, bads = annotate_amplitude(raw_, peak=5, flat=None, **kwargs) assert len(annots) == 0 assert bads == ['0'] # test multiple channels drifting raw_ = raw.copy() raw_._data[0] = np.arange(0, raw.times.size * 10, 10) raw_._data[2] = np.arange(0, raw.times.size * 10, 10) annots, bads = annotate_amplitude(raw_, peak=5, flat=None, **kwargs) assert len(annots) == 0 assert bads == ['0', '2'] # -- test bad channels temporal marking -- # flat channel for the 20% last points n_good_times = int(round(0.8 * n_times)) raw_ = raw.copy() raw_._data[0, n_good_times:] = 0. for perc in (5, 20): annots, bads = annotate_amplitude(raw_, peak=None, flat=0., bad_percent=perc) assert len(annots) == 0 assert bads == ['0'] annots, bads = annotate_amplitude(raw_, peak=None, flat=0., bad_percent=20.1) assert len(annots) == 1 assert len(bads) == 0 # check annotation instance assert annots[0]['description'] == 'BAD_flat' _check_annotation(raw_, annots[0], meas_date, first_samp, n_good_times, -1) # test multiple channels flat and multiple channels drift raw_ = raw.copy() raw_._data[0, 800:] = 0. raw_._data[1, 850:950] = 0. raw_._data[2, :200] = np.arange(0, 200 * 10, 10) raw_._data[2, 200:] += raw_._data[2, 199] # add offset for next samples raw_._data[3, 50:150] = np.arange(0, 100 * 10, 10) raw_._data[3, 150:] += raw_._data[3, 149] # add offset for next samples for perc in (5, 10): annots, bads = annotate_amplitude(raw_, peak=5, flat=0., bad_percent=perc) assert len(annots) == 0 assert bads == ['0', '1', '2', '3'] for perc in (10.1, 20): annots, bads = annotate_amplitude(raw_, peak=5, flat=0., bad_percent=perc) assert len(annots) == 2 assert bads == ['0', '2'] # check annotation instance assert all(annot['description'] in ('BAD_flat', 'BAD_peak') for annot in annots) for annot in annots: start_idx = 50 if annot['description'] == 'BAD_peak' else 850 stop_idx = 149 if annot['description'] == 'BAD_peak' else 949 _check_annotation(raw_, annot, meas_date, first_samp, start_idx, stop_idx) annots, bads = annotate_amplitude(raw_, peak=5, flat=0., bad_percent=20.1) assert len(annots) == 2 assert len(bads) == 0 # check annotation instance assert all(annot['description'] in ('BAD_flat', 'BAD_peak') for annot in annots) for annot in annots: start_idx = 0 if annot['description'] == 'BAD_peak' else 800 stop_idx = 199 if annot['description'] == 'BAD_peak' else -1 _check_annotation(raw_, annot, meas_date, first_samp, start_idx, stop_idx) # test flat on already marked bad channel raw_ = raw.copy() raw_._data[-1, :] = 0. # this channel is already in info['bads'] annots, bads = annotate_amplitude(raw_, peak=None, flat=0., bad_percent=5) assert len(annots) == 0 assert len(bads) == 0 # test drift on already marked bad channel raw_ = raw.copy() raw_._data[-1, :] = np.arange(0, raw.times.size * 10, 10) annots, bads = annotate_amplitude(raw_, peak=5, flat=None, bad_percent=5) assert len(annots) == 0 assert len(bads) == 0
def test_annotations(): """Test annotation class.""" raw = read_raw_fif(fif_fname) assert raw.annotations is None assert_raises(IOError, read_annotations, fif_fname) onset = np.array(range(10)) duration = np.ones(10) description = np.repeat('test', 10) dt = datetime.utcnow() meas_date = raw.info['meas_date'] # Test time shifts. for orig_time in [None, dt, meas_date[0], meas_date]: annot = Annotations(onset, duration, description, orig_time) assert_raises(ValueError, Annotations, onset, duration, description[:9]) assert_raises(ValueError, Annotations, [onset, 1], duration, description) assert_raises(ValueError, Annotations, onset, [duration, 1], description) # Test combining annotations with concatenate_raws raw2 = raw.copy() orig_time = (meas_date[0] + meas_date[1] * 0.000001 + raw2.first_samp / raw2.info['sfreq']) annot = Annotations(onset, duration, description, orig_time) assert_true(' segments' in repr(annot)) raw2.annotations = annot assert_array_equal(raw2.annotations.onset, onset) concatenate_raws([raw, raw2]) raw.annotations.delete(-1) # remove boundary annotations raw.annotations.delete(-1) assert_array_almost_equal(onset + 20., raw.annotations.onset, decimal=2) assert_array_equal(annot.duration, raw.annotations.duration) assert_array_equal(raw.annotations.description, np.repeat('test', 10)) # Test combining with RawArray and orig_times data = np.random.randn(2, 1000) * 10e-12 sfreq = 100. info = create_info(ch_names=['MEG1', 'MEG2'], ch_types=['grad'] * 2, sfreq=sfreq) info['meas_date'] = 0 raws = [] for i, fs in enumerate([12300, 100, 12]): raw = RawArray(data.copy(), info, first_samp=fs) ants = Annotations([1., 2.], [.5, .5], 'x', fs / sfreq) raw.annotations = ants raws.append(raw) raw = RawArray(data.copy(), info) raw.annotations = Annotations([1.], [.5], 'x', None) raws.append(raw) raw = concatenate_raws(raws) boundary_idx = np.where(raw.annotations.description == 'BAD boundary')[0] assert_equal(len(boundary_idx), 3) raw.annotations.delete(boundary_idx) boundary_idx = np.where(raw.annotations.description == 'EDGE boundary')[0] assert_equal(len(boundary_idx), 3) raw.annotations.delete(boundary_idx) assert_array_equal(raw.annotations.onset, [1., 2., 11., 12., 21., 22., 31.]) raw.annotations.delete(2) assert_array_equal(raw.annotations.onset, [1., 2., 12., 21., 22., 31.]) raw.annotations.append(5, 1.5, 'y') assert_array_equal(raw.annotations.onset, [1., 2., 12., 21., 22., 31., 5]) assert_array_equal(raw.annotations.duration, [.5, .5, .5, .5, .5, .5, 1.5]) assert_array_equal(raw.annotations.description, ['x', 'x', 'x', 'x', 'x', 'x', 'y']) # Test concatenating annotations with and without orig_time. raw = read_raw_fif(fif_fname) last_time = raw.last_samp / raw.info['sfreq'] raw2 = raw.copy() raw.annotations = Annotations([45.], [3], 'test', raw.info['meas_date']) raw2.annotations = Annotations([2.], [3], 'BAD', None) raw = concatenate_raws([raw, raw2]) raw.annotations.delete(-1) # remove boundary annotations raw.annotations.delete(-1) assert_array_almost_equal(raw.annotations.onset, [45., 2. + last_time], decimal=2) # Test IO tempdir = _TempDir() fname = op.join(tempdir, 'test-annot.fif') raw.annotations.save(fname) annot_read = read_annotations(fname) for attr in ('onset', 'duration', 'orig_time'): assert_allclose(getattr(annot_read, attr), getattr(raw.annotations, attr)) assert_array_equal(annot_read.description, raw.annotations.description) annot = Annotations((), (), ()) annot.save(fname) assert_raises(IOError, read_annotations, fif_fname) # none in old raw annot = read_annotations(fname) assert isinstance(annot, Annotations) assert len(annot) == 0 # Test that empty annotations can be saved with an object fname = op.join(tempdir, 'test_raw.fif') raw.annotations = annot raw.save(fname) raw_read = read_raw_fif(fname) assert isinstance(raw_read.annotations, Annotations) assert len(raw_read.annotations) == 0 raw.annotations = None raw.save(fname, overwrite=True) raw_read = read_raw_fif(fname) assert raw_read.annotations is None