def test_basics(): """Test annotation class.""" raw = read_raw_fif(fif_fname) assert raw.annotations is not None # XXX to be fixed in #5416 assert len(raw.annotations.onset) == 0 # XXX to be fixed in #5416 pytest.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) pytest.raises(ValueError, Annotations, onset, duration, description[:9]) pytest.raises(ValueError, Annotations, [onset, 1], duration, description) pytest.raises(ValueError, Annotations, onset, [duration, 1], description) # Test combining annotations with concatenate_raws raw2 = raw.copy() delta = raw.times[-1] + 1. / raw.info['sfreq'] orig_time = (meas_date[0] + meas_date[1] * 1e-6 + raw2._first_time) offset = orig_time - _handle_meas_date(raw2.info['meas_date']) annot = Annotations(onset, duration, description, orig_time) assert ' segments' in repr(annot) raw2.set_annotations(annot) assert_array_equal(raw2.annotations.onset, onset + offset) assert id(raw2.annotations) != id(annot) concatenate_raws([raw, raw2]) assert_and_remove_boundary_annot(raw) assert_allclose(onset + offset + delta, raw.annotations.onset, rtol=1e-5) assert_array_equal(annot.duration, raw.annotations.duration) assert_array_equal(raw.annotations.description, np.repeat('test', 10))
def test_annotations(): """Test annotation class.""" raw = Raw(fif_fname) onset = np.array(range(10)) duration = np.ones(10) + raw.first_samp 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 annot = Annotations(onset, duration, description, dt) sfreq = raw.info['sfreq'] raw2 = raw.copy() raw2.annotations = annot concatenate_raws([raw, raw2]) assert_array_equal(annot.onset, raw.annotations.onset) assert_array_equal(annot.duration, raw.annotations.duration) raw2.annotations = Annotations(onset, duration * 2, description, None) last_samp = raw.last_samp - 1 concatenate_raws([raw, raw2]) onsets = np.concatenate([onset, onset + (last_samp - raw.first_samp) / sfreq]) assert_array_equal(raw.annotations.onset, onsets) assert_array_equal(raw.annotations.onset[:10], onset) assert_array_equal(raw.annotations.duration[:10], duration) assert_array_equal(raw.annotations.duration[10:], duration * 2) assert_array_equal(raw.annotations.description, np.repeat('test', 20))
def test_resample(): """Test resample (with I/O and multiple files) """ tempdir = _TempDir() raw = Raw(fif_fname).crop(0, 3, False) raw.preload_data() raw_resamp = raw.copy() sfreq = raw.info['sfreq'] # test parallel on upsample raw_resamp.resample(sfreq * 2, n_jobs=2) assert_equal(raw_resamp.n_times, len(raw_resamp.times)) raw_resamp.save(op.join(tempdir, 'raw_resamp-raw.fif')) raw_resamp = Raw(op.join(tempdir, 'raw_resamp-raw.fif'), preload=True) assert_equal(sfreq, raw_resamp.info['sfreq'] / 2) assert_equal(raw.n_times, raw_resamp.n_times / 2) assert_equal(raw_resamp._data.shape[1], raw_resamp.n_times) assert_equal(raw._data.shape[0], raw_resamp._data.shape[0]) # test non-parallel on downsample raw_resamp.resample(sfreq, n_jobs=1) assert_equal(raw_resamp.info['sfreq'], sfreq) assert_equal(raw._data.shape, raw_resamp._data.shape) assert_equal(raw.first_samp, raw_resamp.first_samp) assert_equal(raw.last_samp, raw.last_samp) # upsampling then downsampling doubles resampling error, but this still # works (hooray). Note that the stim channels had to be sub-sampled # without filtering to be accurately preserved # note we have to treat MEG and EEG+STIM channels differently (tols) assert_allclose(raw._data[:306, 200:-200], raw_resamp._data[:306, 200:-200], rtol=1e-2, atol=1e-12) assert_allclose(raw._data[306:, 200:-200], raw_resamp._data[306:, 200:-200], rtol=1e-2, atol=1e-7) # now check multiple file support w/resampling, as order of operations # (concat, resample) should not affect our data raw1 = raw.copy() raw2 = raw.copy() raw3 = raw.copy() raw4 = raw.copy() raw1 = concatenate_raws([raw1, raw2]) raw1.resample(10) raw3.resample(10) raw4.resample(10) raw3 = concatenate_raws([raw3, raw4]) assert_array_equal(raw1._data, raw3._data) assert_array_equal(raw1._first_samps, raw3._first_samps) assert_array_equal(raw1._last_samps, raw3._last_samps) assert_array_equal(raw1._raw_lengths, raw3._raw_lengths) assert_equal(raw1.first_samp, raw3.first_samp) assert_equal(raw1.last_samp, raw3.last_samp) assert_equal(raw1.info['sfreq'], raw3.info['sfreq'])
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) raw2.annotations = annot assert_array_equal(raw2.annotations.onset, onset) concatenate_raws([raw, raw2]) 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([1000, 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 = concatenate_raws(raws) assert_array_equal(raw.annotations.onset, [1., 2., 11., 12., 21., 22.]) raw.annotations.delete(2) assert_array_equal(raw.annotations.onset, [1., 2., 12., 21., 22.]) raw.annotations.append(5, 1.5, 'y') assert_array_equal(raw.annotations.onset, [1., 2., 12., 21., 22., 5]) assert_array_equal(raw.annotations.duration, [.5, .5, .5, .5, .5, 1.5]) assert_array_equal(raw.annotations.description, ['x', 'x', 'x', 'x', 'x', 'y'])
def test_crop(): """Test cropping raw files """ # split a concatenated file to test a difficult case raw = Raw([fif_fname, fif_fname], preload=False) 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.crop(tmin, tmax, True) 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() raws[ri].crop(tmin, tmax, False) # test concatenation of split file all_raw_1 = concatenate_raws(raws, preload=False) all_raw_2 = raw.crop(0, None, True) 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.crop(tmin=tmin, tmax=tmin + 2, copy=True) assert_equal(raw1[:][0].shape, (1, 2001))
def test_crop(): """Test cropping raw files """ # split a concatenated file to test a difficult case raw = Raw([fif_fname, fif_fname], preload=False) split_size = 10.0 # 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.0, np.round(np.arange(0.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.crop(tmin, tmax, True) 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.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() raws[ri].crop(tmin, tmax, False) # test concatenation of split file all_raw_1 = concatenate_raws(raws, preload=False) all_raw_2 = raw.crop(0, None, True) 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])
def test_annotation_epoching(): """Test that annotations work properly with concatenated edges.""" # Create data with just a DC component data = np.ones((1, 1000)) info = create_info(1, 1000., 'eeg') raw = concatenate_raws([RawArray(data, info) for ii in range(3)]) events = np.array([[a, 0, 1] for a in [0, 500, 1000, 1500, 2000]]) epochs = Epochs(raw, events, tmin=0, tmax=0.999, baseline=None, preload=True) # 1000 samples long assert_equal(len(epochs.drop_log), len(events)) assert_equal(len(epochs), 3) assert_equal([0, 2, 4], epochs.selection)
def test_annotation_filtering(): """Test that annotations work properly with filtering.""" # Create data with just a DC component data = np.ones((1, 1000)) info = create_info(1, 1000., 'eeg') raws = [RawArray(data * (ii + 1), info) for ii in range(4)] kwargs_pass = dict(l_freq=None, h_freq=50., fir_design='firwin') kwargs_stop = dict(l_freq=50., h_freq=None, fir_design='firwin') # lowpass filter, which should not modify the data raws_pass = [raw.copy().filter(**kwargs_pass) for raw in raws] # highpass filter, which should zero it out raws_stop = [raw.copy().filter(**kwargs_stop) for raw in raws] # concat the original and the filtered segments raws_concat = concatenate_raws([raw.copy() for raw in raws]) raws_zero = raws_concat.copy().apply_function(lambda x: x * 0) raws_pass_concat = concatenate_raws(raws_pass) raws_stop_concat = concatenate_raws(raws_stop) # make sure we did something reasonable with our individual-file filtering assert_allclose(raws_concat[0][0], raws_pass_concat[0][0], atol=1e-14) assert_allclose(raws_zero[0][0], raws_stop_concat[0][0], atol=1e-14) # ensure that our Annotations cut up the filtering properly raws_concat_pass = raws_concat.copy().filter(skip_by_annotation='edge', **kwargs_pass) assert_allclose(raws_concat[0][0], raws_concat_pass[0][0], atol=1e-14) raws_concat_stop = raws_concat.copy().filter(skip_by_annotation='edge', **kwargs_stop) assert_allclose(raws_zero[0][0], raws_concat_stop[0][0], atol=1e-14) # one last test: let's cut out a section entirely: # here the 1-3 second window should be skipped raw = raws_concat.copy() raw.annotations.append(1., 2., 'foo') raw.filter(l_freq=50., h_freq=None, fir_design='firwin', skip_by_annotation='foo') # our filter will zero out anything not skipped: mask = np.concatenate((np.zeros(1000), np.ones(2000), np.zeros(1000))) expected_data = raws_concat[0][0][0] * mask assert_allclose(raw[0][0][0], expected_data, atol=1e-14)
def test_raw_array_orig_times(): """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'] = (np.pi, 0) raws = [] for first_samp in [12300, 100, 12]: raw = RawArray(data.copy(), info, first_samp=first_samp) ants = Annotations([1., 2.], [.5, .5], 'x', np.pi + first_samp / sfreq) raw.set_annotations(ants) raws.append(raw) raw = RawArray(data.copy(), info) raw.set_annotations(Annotations([1.], [.5], 'x', None)) raws.append(raw) raw = concatenate_raws(raws, verbose='debug') assert_and_remove_boundary_annot(raw, 3) assert_array_equal(raw.annotations.onset, [124., 125., 134., 135., 144., 145., 154.]) raw.annotations.delete(2) assert_array_equal(raw.annotations.onset, [124., 125., 135., 144., 145., 154.]) raw.annotations.append(5, 1.5, 'y') assert_array_equal(raw.annotations.onset, [5., 124., 125., 135., 144., 145., 154.]) assert_array_equal(raw.annotations.duration, [1.5, .5, .5, .5, .5, .5, .5]) assert_array_equal(raw.annotations.description, ['y', 'x', 'x', 'x', 'x', 'x', 'x']) # These three things should be equivalent expected_orig_time = (raw.info['meas_date'][0] + raw.info['meas_date'][1] / 1000000) for empty_annot in ( Annotations([], [], [], expected_orig_time), Annotations([], [], [], None), None): raw.set_annotations(empty_annot) assert isinstance(raw.annotations, Annotations) assert len(raw.annotations) == 0 assert raw.annotations.orig_time == expected_orig_time
def test_events_from_annot_in_raw_objects(): """Test basic functionality of events_fron_annot for raw objects.""" raw = read_raw_fif(fif_fname) events = mne.find_events(raw) event_id = { 'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3, 'Visual/Right': 4, 'Visual/Smiley': 32, 'Motor/Button': 5 } event_map = {v: k for k, v in event_id.items()} annot = Annotations(onset=raw.times[events[:, 0] - raw.first_samp], duration=np.zeros(len(events)), description=[event_map[vv] for vv in events[:, 2]], orig_time=None) raw.set_annotations(annot) events2, event_id2 = \ events_from_annotations(raw, event_id=event_id, regexp=None) assert_array_equal(events, events2) assert_equal(event_id, event_id2) events3, event_id3 = \ events_from_annotations(raw, event_id=None, regexp=None) assert_array_equal(events[:, 0], events3[:, 0]) assert set(event_id.keys()) == set(event_id3.keys()) # ensure that these actually got sorted properly expected_event_id = { desc: idx + 1 for idx, desc in enumerate(sorted(event_id.keys())) } assert event_id3 == expected_event_id first = np.unique(events3[:, 2]) second = np.arange(1, len(event_id) + 1, 1).astype(first.dtype) assert_array_equal(first, second) first = np.unique(list(event_id3.values())) second = np.arange(1, len(event_id) + 1, 1).astype(first.dtype) assert_array_equal(first, second) events4, event_id4 =\ events_from_annotations(raw, event_id=None, regexp='.*Left') expected_event_id4 = {k: v for k, v in event_id.items() if 'Left' in k} assert_equal(event_id4.keys(), expected_event_id4.keys()) expected_events4 = events[(events[:, 2] == 1) | (events[:, 2] == 3)] assert_array_equal(expected_events4[:, 0], events4[:, 0]) events5, event_id5 = \ events_from_annotations(raw, event_id=event_id, regexp='.*Left') expected_event_id5 = {k: v for k, v in event_id.items() if 'Left' in k} assert_equal(event_id5, expected_event_id5) expected_events5 = events[(events[:, 2] == 1) | (events[:, 2] == 3)] assert_array_equal(expected_events5, events5) with pytest.raises(ValueError, match='not find any of the events'): events_from_annotations(raw, regexp='not_there') with pytest.raises(ValueError, match='Invalid input event_id'): events_from_annotations(raw, event_id='wrong') # concat does not introduce BAD or EDGE raw_concat = concatenate_raws([raw.copy(), raw.copy()]) _, event_id = events_from_annotations(raw_concat) assert isinstance(event_id, dict) assert len(event_id) > 0 for kind in ('BAD', 'EDGE'): assert '%s boundary' % kind in raw_concat.annotations.description for key in event_id.keys(): assert kind not in key # remove all events raw.set_annotations(None) events7, _ = events_from_annotations(raw) assert_array_equal(events7, np.empty((0, 3), dtype=int))
def test_eeg_classifier(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes, update_path=False) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel="auto", verbose="WARNING") for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads") # Extract trials, only using EEG channels epoched = mne.Epochs( raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True, ) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_window_samples = 450 n_classes = 2 in_chans = X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_window_samples=input_window_samples, final_conv_length=12, ) to_dense_prediction_model(model) if cuda: model.cuda() # determine output size test_input = np_to_th( np.ones((2, in_chans, input_window_samples, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] train_set = create_from_X_y(X[:48], y[:48], drop_last_window=False, window_size_samples=input_window_samples, window_stride_samples=n_preds_per_input) valid_set = create_from_X_y(X[48:60], y[48:60], drop_last_window=False, window_size_samples=input_window_samples, window_stride_samples=n_preds_per_input) cropped_cb_train = CroppedTrialEpochScoring( "accuracy", name="train_trial_accuracy", lower_is_better=False, on_train=True, ) cropped_cb_valid = CroppedTrialEpochScoring( "accuracy", on_train=False, name="valid_trial_accuracy", lower_is_better=False, ) clf = EEGClassifier( model, cropped=True, criterion=CroppedLoss, criterion__loss_function=nll_loss, optimizer=optim.Adam, train_split=predefined_split(valid_set), batch_size=32, callbacks=[ ("train_trial_accuracy", cropped_cb_train), ("valid_trial_accuracy", cropped_cb_valid), ], ) clf.fit(train_set, y=None, epochs=4) expected = [{ 'batches': [{ 'train_batch_size': 32, 'train_loss': 1.6639312505722046 }, { 'train_batch_size': 32, 'train_loss': 2.6161606311798096 }, { 'train_batch_size': 32, 'train_loss': 1.627132773399353 }, { 'valid_batch_size': 24, 'valid_loss': 0.9677614569664001 }], 'epoch': 1, 'train_batch_count': 3, 'train_loss': 1.9690748850504558, 'train_loss_best': True, 'train_trial_accuracy': 0.4791666666666667, 'train_trial_accuracy_best': True, 'valid_batch_count': 1, 'valid_loss': 0.9677614569664001, 'valid_loss_best': True, 'valid_trial_accuracy': 0.5, 'valid_trial_accuracy_best': True }, { 'batches': [{ 'train_batch_size': 32, 'train_loss': 1.3829222917556763 }, { 'train_batch_size': 32, 'train_loss': 1.3123714923858643 }, { 'train_batch_size': 32, 'train_loss': 1.0109959840774536 }, { 'valid_batch_size': 24, 'valid_loss': 1.9435862302780151 }], 'epoch': 2, 'train_batch_count': 3, 'train_loss': 1.2354299227396648, 'train_loss_best': True, 'train_trial_accuracy': 0.5, 'train_trial_accuracy_best': True, 'valid_batch_count': 1, 'valid_loss': 1.9435862302780151, 'valid_loss_best': False, 'valid_trial_accuracy': 0.5, 'valid_trial_accuracy_best': False }, { 'batches': [{ 'train_batch_size': 32, 'train_loss': 1.172208547592163 }, { 'train_batch_size': 32, 'train_loss': 0.8899562954902649 }, { 'train_batch_size': 32, 'train_loss': 1.0232216119766235 }, { 'valid_batch_size': 24, 'valid_loss': 0.9585554599761963 }], 'epoch': 3, 'train_batch_count': 3, 'train_loss': 1.0284621516863506, 'train_loss_best': True, 'train_trial_accuracy': 0.5, 'train_trial_accuracy_best': False, 'valid_batch_count': 1, 'valid_loss': 0.9585554599761963, 'valid_loss_best': True, 'valid_trial_accuracy': 0.5, 'valid_trial_accuracy_best': False }, { 'batches': [{ 'train_batch_size': 32, 'train_loss': 0.9693693518638611 }, { 'train_batch_size': 32, 'train_loss': 0.900641918182373 }, { 'train_batch_size': 32, 'train_loss': 0.8839665651321411 }, { 'valid_batch_size': 24, 'valid_loss': 0.873468816280365 }], 'epoch': 4, 'train_batch_count': 3, 'train_loss': 0.9179926117261251, 'train_loss_best': True, 'train_trial_accuracy': 0.625, 'train_trial_accuracy_best': True, 'valid_batch_count': 1, 'valid_loss': 0.873468816280365, 'valid_loss_best': True, 'valid_trial_accuracy': 0.4166666666666667, 'valid_trial_accuracy_best': False }] history_without_dur = [{k: v for k, v in h.items() if k != "dur"} for h in clf.history] assert_deep_allclose(expected, history_without_dur, atol=1e-3, rtol=1e-3)
def test_cropped_decoding(): import mne from mne.io import concatenate_raws # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes, update_path=True) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True) import numpy as np from braindecode.datautil.signal_target import SignalAndTarget # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 train_set = SignalAndTarget(X[:60], y=y[:60]) test_set = SignalAndTarget(X[60:], y=y[60:]) from braindecode.models.shallow_fbcsp import ShallowFBCSPNet from torch import nn from braindecode.torch_ext.util import set_random_seeds from braindecode.models.util import to_dense_prediction_model # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_time_length = 450 n_classes = 2 in_chans = train_set.X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=12).create_network() to_dense_prediction_model(model) if cuda: model.cuda() from torch import optim optimizer = optim.Adam(model.parameters()) from braindecode.torch_ext.util import np_to_var # determine output size test_input = np_to_var( np.ones((2, in_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] print("{:d} predictions per input/trial".format(n_preds_per_input)) from braindecode.datautil.iterators import CropsFromTrialsIterator iterator = CropsFromTrialsIterator(batch_size=32, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input) from braindecode.torch_ext.util import np_to_var, var_to_np import torch.nn.functional as F from numpy.random import RandomState import torch as th from braindecode.experiments.monitors import compute_preds_per_trial_from_crops rng = RandomState((2017, 6, 30)) losses = [] accuracies = [] for i_epoch in range(4): # Set model to training mode model.train() for batch_X, batch_y in iterator.get_batches(train_set, shuffle=False): net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() # Remove gradients of last backward pass from all parameters optimizer.zero_grad() outputs = model(net_in) # Mean predictions across trial # Note that this will give identical gradients to computing # a per-prediction loss (at least for the combination of log softmax activation # and negative log likelihood loss which we are using here) outputs = th.mean(outputs, dim=2, keepdim=False) loss = F.nll_loss(outputs, net_target) loss.backward() optimizer.step() # Print some statistics each epoch model.eval() print("Epoch {:d}".format(i_epoch)) for setname, dataset in (('Train', train_set), ('Test', test_set)): # Collect all predictions and losses all_preds = [] all_losses = [] batch_sizes = [] for batch_X, batch_y in iterator.get_batches(dataset, shuffle=False): net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() outputs = model(net_in) all_preds.append(var_to_np(outputs)) outputs = th.mean(outputs, dim=2, keepdim=False) loss = F.nll_loss(outputs, net_target) loss = float(var_to_np(loss)) all_losses.append(loss) batch_sizes.append(len(batch_X)) # Compute mean per-input loss loss = np.mean( np.array(all_losses) * np.array(batch_sizes) / np.mean(batch_sizes)) print("{:6s} Loss: {:.5f}".format(setname, loss)) losses.append(loss) # Assign the predictions to the trials preds_per_trial = compute_preds_per_trial_from_crops( all_preds, input_time_length, dataset.X) # preds per trial are now trials x classes x timesteps/predictions # Now mean across timesteps for each trial to get per-trial predictions meaned_preds_per_trial = np.array( [np.mean(p, axis=1) for p in preds_per_trial]) predicted_labels = np.argmax(meaned_preds_per_trial, axis=1) accuracy = np.mean(predicted_labels == dataset.y) accuracies.append(accuracy * 100) print("{:6s} Accuracy: {:.1f}%".format(setname, accuracy * 100)) np.testing.assert_allclose(np.array(losses), np.array([ 1.31657708, 1.73548156, 1.02950428, 1.43932164, 0.78677772, 1.12382019, 0.55920881, 0.87277424 ]), rtol=1e-4, atol=1e-5) np.testing.assert_allclose(np.array(accuracies), np.array([ 50., 46.66666667, 50., 46.66666667, 50., 46.66666667, 66.66666667, 50. ]), rtol=1e-4, atol=1e-5)
def test_crop(): """Test cropping with annotations.""" raw = read_raw_fif(fif_fname) events = mne.find_events(raw) onset = events[events[:, 2] == 1, 0] / raw.info['sfreq'] duration = np.full_like(onset, 0.5) description = ['bad %d' % k for k in range(len(onset))] annot = mne.Annotations(onset, duration, description, orig_time=raw.info['meas_date']) raw.set_annotations(annot) split_time = raw.times[-1] / 2. + 2. split_idx = len(onset) // 2 + 1 raw_cropped_left = raw.copy().crop(0., split_time - 1. / raw.info['sfreq']) assert_array_equal(raw_cropped_left.annotations.description, raw.annotations.description[:split_idx]) assert_allclose(raw_cropped_left.annotations.duration, raw.annotations.duration[:split_idx]) assert_allclose(raw_cropped_left.annotations.onset, raw.annotations.onset[:split_idx]) raw_cropped_right = raw.copy().crop(split_time, None) assert_array_equal(raw_cropped_right.annotations.description, raw.annotations.description[split_idx:]) assert_allclose(raw_cropped_right.annotations.duration, raw.annotations.duration[split_idx:]) assert_allclose(raw_cropped_right.annotations.onset, raw.annotations.onset[split_idx:]) raw_concat = mne.concatenate_raws([raw_cropped_left, raw_cropped_right], verbose='debug') assert_allclose(raw_concat.times, raw.times) assert_allclose(raw_concat[:][0], raw[:][0], atol=1e-20) assert_and_remove_boundary_annot(raw_concat) # Ensure we annotations survive round-trip crop->concat assert_array_equal(raw_concat.annotations.description, raw.annotations.description) for attr in ('onset', 'duration'): assert_allclose(getattr(raw_concat.annotations, attr), getattr(raw.annotations, attr), err_msg='Failed for %s:' % (attr, )) raw.set_annotations(None) # undo # Test concatenating annotations with and without orig_time. raw2 = raw.copy() raw.set_annotations(Annotations([45.], [3], 'test', raw.info['meas_date'])) raw2.set_annotations(Annotations([2.], [3], 'BAD', None)) expected_onset = [45., 2. + raw._last_time] raw = concatenate_raws([raw, raw2]) assert_and_remove_boundary_annot(raw) assert_array_almost_equal(raw.annotations.onset, expected_onset, 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) pytest.raises(IOError, read_annotations, fif_fname) # none in old raw annot = read_annotations(fname) assert isinstance(annot, Annotations) assert len(annot) == 0 annot.crop() # test if cropping empty annotations doesn't raise an error # Test that empty annotations can be saved with an object fname = op.join(tempdir, 'test_raw.fif') raw.set_annotations(annot) raw.save(fname) raw_read = read_raw_fif(fname) assert isinstance(raw_read.annotations, Annotations) assert len(raw_read.annotations) == 0 raw.set_annotations(None) raw.save(fname, overwrite=True) raw_read = read_raw_fif(fname) assert raw_read.annotations is not None # XXX to be fixed in #5416 assert len(raw_read.annotations.onset) == 0 # XXX to be fixed in #5416
def test_resample(): """Test resample (with I/O and multiple files) """ tempdir = _TempDir() raw = Raw(fif_fname).crop(0, 3, copy=False) raw.load_data() raw_resamp = raw.copy() sfreq = raw.info['sfreq'] # test parallel on upsample raw_resamp.resample(sfreq * 2, n_jobs=2, npad='auto') assert_equal(raw_resamp.n_times, len(raw_resamp.times)) raw_resamp.save(op.join(tempdir, 'raw_resamp-raw.fif')) raw_resamp = Raw(op.join(tempdir, 'raw_resamp-raw.fif'), preload=True) assert_equal(sfreq, raw_resamp.info['sfreq'] / 2) assert_equal(raw.n_times, raw_resamp.n_times / 2) assert_equal(raw_resamp._data.shape[1], raw_resamp.n_times) assert_equal(raw._data.shape[0], raw_resamp._data.shape[0]) # test non-parallel on downsample raw_resamp.resample(sfreq, n_jobs=1, npad='auto') assert_equal(raw_resamp.info['sfreq'], sfreq) assert_equal(raw._data.shape, raw_resamp._data.shape) assert_equal(raw.first_samp, raw_resamp.first_samp) assert_equal(raw.last_samp, raw.last_samp) # upsampling then downsampling doubles resampling error, but this still # works (hooray). Note that the stim channels had to be sub-sampled # without filtering to be accurately preserved # note we have to treat MEG and EEG+STIM channels differently (tols) assert_allclose(raw._data[:306, 200:-200], raw_resamp._data[:306, 200:-200], rtol=1e-2, atol=1e-12) assert_allclose(raw._data[306:, 200:-200], raw_resamp._data[306:, 200:-200], rtol=1e-2, atol=1e-7) # now check multiple file support w/resampling, as order of operations # (concat, resample) should not affect our data raw1 = raw.copy() raw2 = raw.copy() raw3 = raw.copy() raw4 = raw.copy() raw1 = concatenate_raws([raw1, raw2]) raw1.resample(10., npad='auto') raw3.resample(10., npad='auto') raw4.resample(10., npad='auto') raw3 = concatenate_raws([raw3, raw4]) assert_array_equal(raw1._data, raw3._data) assert_array_equal(raw1._first_samps, raw3._first_samps) assert_array_equal(raw1._last_samps, raw3._last_samps) assert_array_equal(raw1._raw_lengths, raw3._raw_lengths) assert_equal(raw1.first_samp, raw3.first_samp) assert_equal(raw1.last_samp, raw3.last_samp) assert_equal(raw1.info['sfreq'], raw3.info['sfreq']) # test resampling of stim channel # basic decimation stim = [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) assert_allclose(raw.resample(8., npad='auto')._data, [[1, 1, 0, 0, 1, 1, 0, 0]]) # decimation of multiple stim channels raw = RawArray(2 * [stim], create_info(2, len(stim), 2 * ['stim'])) assert_allclose(raw.resample(8., npad='auto')._data, [[1, 1, 0, 0, 1, 1, 0, 0], [1, 1, 0, 0, 1, 1, 0, 0]]) # decimation that could potentially drop events if the decimation is # done naively stim = [0, 0, 0, 1, 1, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) assert_allclose(raw.resample(4., npad='auto')._data, [[0, 1, 1, 0]]) # two events are merged in this case (warning) stim = [0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') raw.resample(8., npad='auto') assert_true(len(w) == 1) # events are dropped in this case (warning) stim = [0, 1, 1, 0, 0, 1, 1, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') raw.resample(4., npad='auto') assert_true(len(w) == 1) # test resampling events: this should no longer give a warning stim = [0, 1, 1, 0, 0, 1, 1, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) events = find_events(raw) raw, events = raw.resample(4., events=events, npad='auto') assert_equal(events, np.array([[0, 0, 1], [2, 0, 1]])) # test copy flag stim = [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) raw_resampled = raw.copy().resample(4., npad='auto') assert_true(raw_resampled is not raw) raw_resampled = raw.resample(4., npad='auto') assert_true(raw_resampled is raw) # resample should still work even when no stim channel is present raw = RawArray(np.random.randn(1, 100), create_info(1, 100, ['eeg'])) raw.info['lowpass'] = 50. raw.resample(10, npad='auto') assert_equal(raw.info['lowpass'], 5.) assert_equal(len(raw), 10)
r, g, b, a = cmap(old) cdict["red"].append((new, r, r)) cdict["green"].append((new, g, g)) cdict["blue"].append((new, b, b)) cdict["alpha"].append((new, a, a)) return LinearSegmentedColormap("erds", cdict) # load and preprocess data #################################################### subject = 20 # use data from subject 1 runs = [3, 7, 11] # use only hand and feet motor imagery runs fnames = mne.datasets.eegbci.load_data(subject, runs) raws = [mne.io.read_raw_edf(f, preload=True, stim_channel='auto') for f in fnames] raw = concatenate_raws(raws) raw.rename_channels(lambda x: x.strip('.')) # remove dots from channel names events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') picks = mne.pick_channels(raw.info["ch_names"], ["C3", "Cz", "C4"]) # epoch data ################################################################## tmin, tmax = -1, 4 # define epochs around events (in s) event_ids = dict(hands=2, feet=3) # map event IDs to tasks epochs = mne.Epochs(raw, events, event_ids, tmin - 0.5, tmax + 0.5, picks=picks, baseline=None, preload=True) # compute ERDS maps ###########################################################
def save_epochs(p, subjects, in_names, in_numbers, analyses, out_names, out_numbers, must_match, decim, run_indices): """Generate epochs from raw data based on events Can only complete after preprocessing is complete. Parameters ---------- p : instance of Parameters Analysis parameters. subjects : list of str Subject names to analyze (e.g., ['Eric_SoP_001', ...]). in_names : list of str Names of input events. in_numbers : list of list of int Event numbers (in scored event files) associated with each name. analyses : list of str Lists of analyses of interest. out_names : list of list of str Event types to make out of old ones. out_numbers : list of list of int Event numbers to convert to (e.g., [[1, 1, 2, 3, 3], ...] would create three event types, where the first two and last two event types from the original list get collapsed over). must_match : list of int Indices from the original in_names that must match in event counts before collapsing. Should eventually be expanded to allow for ratio-based collapsing. decim : int | list of int Amount to decimate. run_indices : array-like | None Run indices to include. """ in_names = np.asanyarray(in_names) old_dict = dict() for n, e in zip(in_names, in_numbers): old_dict[n] = e # let's do some sanity checks if len(in_names) != len(in_numbers): raise RuntimeError('in_names (%d) must have same length as ' 'in_numbers (%d)' % (len(in_names), len(in_numbers))) if np.any(np.array(in_numbers) <= 0): raise ValueError('in_numbers must all be > 0') if len(out_names) != len(out_numbers): raise RuntimeError('out_names must have same length as out_numbers') for name, num in zip(out_names, out_numbers): num = np.array(num) if len(name) != len(np.unique(num[num > 0])): raise RuntimeError('each entry in out_names must have length ' 'equal to the number of unique elements in the ' 'corresponding entry in out_numbers:\n%s\n%s' % (name, np.unique(num[num > 0]))) if len(num) != len(in_names): raise RuntimeError('each entry in out_numbers must have the same ' 'length as in_names') if (np.array(num) == 0).any(): raise ValueError('no element of out_numbers can be zero') ch_namess = list() drop_logs = list() sfreqs = set() for si, subj in enumerate(subjects): if p.disp_files: print(' Loading raw files for subject %s.' % subj) epochs_dir = op.join(p.work_dir, subj, p.epochs_dir) if not op.isdir(epochs_dir): os.mkdir(epochs_dir) evoked_dir = op.join(p.work_dir, subj, p.inverse_dir) if not op.isdir(evoked_dir): os.mkdir(evoked_dir) # read in raw files raw_names = get_raw_fnames(p, subj, 'pca', False, False, run_indices[si]) first_samps = [] last_samps = [] for raw_fname in raw_names: raw = read_raw_fif(raw_fname, preload=False) first_samps.append(raw._first_samps[0]) last_samps.append(raw._last_samps[-1]) raw = [read_raw_fif(fname, preload=False) for fname in raw_names] _fix_raw_eog_cals(raw) # EOG epoch scales might be bad! raw = concatenate_raws(raw) # optionally calculate autoreject thresholds this_decim = _handle_decim(decim[si], raw.info['sfreq']) new_sfreq = raw.info['sfreq'] / this_decim if p.disp_files: print(' Epoching data (decim=%s -> sfreq=%0.1f Hz).' % (this_decim, new_sfreq)) if new_sfreq not in sfreqs: if len(sfreqs) > 0: warnings.warn('resulting new sampling frequency %s not equal ' 'to previous values %s' % (new_sfreq, sfreqs)) sfreqs.add(new_sfreq) epochs_fnames, evoked_fnames = get_epochs_evokeds_fnames( p, subj, analyses) mat_file, fif_file = epochs_fnames if p.autoreject_thresholds: assert len(p.autoreject_types) > 0 assert all(a in ('mag', 'grad', 'eeg', 'ecg', 'eog') for a in p.autoreject_types) from autoreject import get_rejection_threshold picker = p.pick_events_autoreject if type(picker) is str: assert picker == 'restrict', \ 'Only "restrict" is valid str for p.pick_events_autoreject' events = _read_events(p, subj, run_indices[si], raw, picker=picker) print(' Computing autoreject thresholds', end='') rtmin = p.reject_tmin if p.reject_tmin is not None else p.tmin rtmax = p.reject_tmax if p.reject_tmax is not None else p.tmax temp_epochs = Epochs(raw, events, event_id=None, tmin=rtmin, tmax=rtmax, baseline=_get_baseline(p), proj=True, reject=None, flat=None, preload=True, decim=this_decim, reject_by_annotation=p.reject_epochs_by_annot) kwargs = dict() if 'verbose' in get_args(get_rejection_threshold): kwargs['verbose'] = False new_dict = get_rejection_threshold(temp_epochs, **kwargs) use_reject = dict() msgs = list() for k in p.autoreject_types: msgs.append('%s=%d %s' % (k, DEFAULTS['scalings'][k] * new_dict[k], DEFAULTS['units'][k])) use_reject[k] = new_dict[k] print(': ' + ', '.join(msgs)) hdf5_file = fif_file.replace('-epo.fif', '-reject.h5') assert hdf5_file.endswith('.h5') write_hdf5(hdf5_file, use_reject, overwrite=True) else: use_reject = _handle_dict(p.reject, subj) # read in events and create epochs events = _read_events(p, subj, run_indices[si], raw, picker='restrict') flat = _handle_dict(p.flat, subj) use_reject, use_flat = _restrict_reject_flat(use_reject, flat, raw) epochs = Epochs(raw, events, event_id=old_dict, tmin=p.tmin, tmax=p.tmax, baseline=_get_baseline(p), reject=use_reject, flat=use_flat, proj=p.epochs_proj, preload=True, decim=this_decim, on_missing=p.on_missing, reject_tmin=p.reject_tmin, reject_tmax=p.reject_tmax, reject_by_annotation=p.reject_epochs_by_annot) del raw if epochs.events.shape[0] < 1: epochs.plot_drop_log() raise ValueError('No valid epochs') drop_logs.append(epochs.drop_log) ch_namess.append(epochs.ch_names) # only kept trials that were not dropped sfreq = epochs.info['sfreq'] # now deal with conditions to save evoked if p.disp_files: print(' Matching trial counts and saving data to disk.') for var, name in ((out_names, 'out_names'), (out_numbers, 'out_numbers'), (must_match, 'must_match'), (evoked_fnames, 'evoked_fnames')): if len(var) != len(analyses): raise ValueError('len(%s) (%s) != len(analyses) (%s)' % (name, len(var), len(analyses))) for analysis, names, numbers, match, fn in zip(analyses, out_names, out_numbers, must_match, evoked_fnames): # do matching numbers = np.asanyarray(numbers) nn = numbers[numbers >= 0] new_numbers = [] for num in numbers: if num > 0 and num not in new_numbers: # Eventually we could relax this requirement, but not # having it in place is likely to cause people pain... if any(num < n for n in new_numbers): raise RuntimeError('each list of new_numbers must be ' ' monotonically increasing') new_numbers.append(num) new_numbers = np.array(new_numbers) in_names_match = in_names[match] # use some variables to allow safe name re-use offset = max(epochs.events[:, 2].max(), new_numbers.max()) + 1 safety_str = '__mnefun_copy__' assert len(new_numbers) == len(names) # checked above if p.match_fun is None: # first, equalize trial counts (this will make a copy) e = epochs[list(in_names[numbers > 0])] if len(in_names_match) > 1: e.equalize_event_counts(in_names_match) # second, collapse relevant types for num, name in zip(new_numbers, names): collapse = [ x for x in in_names[num == numbers] if x in e.event_id ] combine_event_ids(e, collapse, {name + safety_str: num + offset}, copy=False) for num, name in zip(new_numbers, names): e.events[e.events[:, 2] == num + offset, 2] -= offset e.event_id[name] = num del e.event_id[name + safety_str] else: # custom matching e = p.match_fun(epochs.copy(), analysis, nn, in_names_match, names) # now make evoked for each out type evokeds = list() n_standard = 0 kinds = ['standard'] if p.every_other: kinds += ['even', 'odd'] for kind in kinds: for name in names: this_e = e[name] if kind == 'even': this_e = this_e[::2] elif kind == 'odd': this_e = this_e[1::2] else: assert kind == 'standard' if len(this_e) > 0: ave = this_e.average(picks='all') stde = this_e.standard_error(picks='all') if kind != 'standard': ave.comment += ' %s' % (kind, ) stde.comment += ' %s' % (kind, ) evokeds.append(ave) evokeds.append(stde) if kind == 'standard': n_standard += 2 write_evokeds(fn, evokeds) naves = [ str(n) for n in sorted( set([evoked.nave for evoked in evokeds[:n_standard]])) ] naves = ', '.join(naves) if p.disp_files: print(' Analysis "%s": %s epochs / condition' % (analysis, naves)) if p.disp_files: print(' Saving epochs to disk.') if 'mat' in p.epochs_type: spio.savemat(mat_file, dict(epochs=epochs.get_data(), events=epochs.events, sfreq=sfreq, drop_log=epochs.drop_log), do_compression=True, oned_as='column') if 'fif' in p.epochs_type: epochs.save(fif_file, **_get_epo_kwargs()) if p.plot_drop_logs: for subj, drop_log in zip(subjects, drop_logs): plot_drop_log(drop_log, threshold=p.drop_thresh, subject=subj)
cond_tags += [('not-' if i == 0 else '') + conds.columns[k] for k, i in enumerate(c[2:], 2)] conditions.append('/'.join(map(str, cond_tags))) print(conditions[:10]) ############################################################################## # Let's make the event_id dictionary event_id = dict(zip(conditions, conds.trigger + 1)) event_id['0/human bodypart/human/not-face/animal/natural'] ############################################################################## # Read MEG data n_runs = 4 # 4 for full data (use less to speed up computations) fname = op.join(data_path, 'sample_subject_%i_tsss_mc.fif') raws = [read_raw_fif(fname % block) for block in range(n_runs)] raw = concatenate_raws(raws) events = mne.find_events(raw, min_duration=.002) events = events[events[:, 2] <= max_trigger] mne.viz.plot_events(events, sfreq=raw.info['sfreq']) ############################################################################## # Epoch data picks = mne.pick_types(raw.info, meg=True) epochs = mne.Epochs(raw, events=events, event_id=event_id, baseline=None, picks=picks, tmin=-.1, tmax=.500, preload=True) ############################################################################## # Let's plot some conditions epochs['face'].average().plot()
def test_eeg_classifier(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes, update_path=False) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel="auto", verbose="WARNING") for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads") # Extract trials, only using EEG channels epoched = mne.Epochs( raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True, ) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_window_samples = 450 n_classes = 2 in_chans = X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_window_samples=input_window_samples, final_conv_length=12, ) to_dense_prediction_model(model) if cuda: model.cuda() # determine output size test_input = np_to_var( np.ones((2, in_chans, input_window_samples, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] train_set = create_from_X_y(X[:48], y[:48], drop_last_window=False, window_size_samples=input_window_samples, window_stride_samples=n_preds_per_input) valid_set = create_from_X_y(X[48:60], y[48:60], drop_last_window=False, window_size_samples=input_window_samples, window_stride_samples=n_preds_per_input) cropped_cb_train = CroppedTrialEpochScoring( "accuracy", name="train_trial_accuracy", lower_is_better=False, on_train=True, ) cropped_cb_valid = CroppedTrialEpochScoring( "accuracy", on_train=False, name="valid_trial_accuracy", lower_is_better=False, ) clf = EEGClassifier( model, criterion=CroppedLoss, criterion__loss_function=nll_loss, optimizer=optim.Adam, train_split=predefined_split(valid_set), batch_size=32, callbacks=[ ("train_trial_accuracy", cropped_cb_train), ("valid_trial_accuracy", cropped_cb_valid), ], ) clf.fit(train_set, y=None, epochs=4) expected = [{ 'batches': [{ 'train_batch_size': 32, 'train_loss': 1.9391239881515503 }, { 'train_batch_size': 32, 'train_loss': 2.895704507827759 }, { 'train_batch_size': 32, 'train_loss': 1.0713887214660645 }, { 'valid_batch_size': 24, 'valid_loss': 1.18110191822052 }], 'epoch': 1, 'train_batch_count': 3, 'train_loss': 1.9687390724817913, 'train_loss_best': True, 'train_trial_accuracy': 0.4791666666666667, 'train_trial_accuracy_best': True, 'valid_batch_count': 1, 'valid_loss': 1.18110191822052, 'valid_loss_best': True, 'valid_trial_accuracy': 0.5, 'valid_trial_accuracy_best': True }, { 'batches': [{ 'train_batch_size': 32, 'train_loss': 1.6741573810577393 }, { 'train_batch_size': 32, 'train_loss': 0.9984264373779297 }, { 'train_batch_size': 32, 'train_loss': 1.1340471506118774 }, { 'valid_batch_size': 24, 'valid_loss': 2.5375664234161377 }], 'epoch': 2, 'train_batch_count': 3, 'train_loss': 1.2688769896825154, 'train_loss_best': True, 'train_trial_accuracy': 0.5, 'train_trial_accuracy_best': True, 'valid_batch_count': 1, 'valid_loss': 2.5375664234161377, 'valid_loss_best': False, 'valid_trial_accuracy': 0.5, 'valid_trial_accuracy_best': False }, { 'batches': [{ 'train_batch_size': 32, 'train_loss': 0.8795645833015442 }, { 'train_batch_size': 32, 'train_loss': 1.0339491367340088 }, { 'train_batch_size': 32, 'train_loss': 1.19275963306427 }, { 'valid_batch_size': 24, 'valid_loss': 1.655737042427063 }], 'epoch': 3, 'train_batch_count': 3, 'train_loss': 1.0354244510332744, 'train_loss_best': True, 'train_trial_accuracy': 0.5, 'train_trial_accuracy_best': False, 'valid_batch_count': 1, 'valid_loss': 1.655737042427063, 'valid_loss_best': False, 'valid_trial_accuracy': 0.5, 'valid_trial_accuracy_best': False }, { 'batches': [{ 'train_batch_size': 32, 'train_loss': 1.1963350772857666 }, { 'train_batch_size': 32, 'train_loss': 0.8621770143508911 }, { 'train_batch_size': 32, 'train_loss': 1.099318265914917 }, { 'valid_batch_size': 24, 'valid_loss': 1.0293445587158203 }], 'epoch': 4, 'train_batch_count': 3, 'train_loss': 1.0526101191838582, 'train_loss_best': False, 'train_trial_accuracy': 0.625, 'train_trial_accuracy_best': True, 'valid_batch_count': 1, 'valid_loss': 1.0293445587158203, 'valid_loss_best': True, 'valid_trial_accuracy': 0.25, 'valid_trial_accuracy_best': False }] history_without_dur = [{k: v for k, v in h.items() if k != "dur"} for h in clf.history] assert_deep_allclose(expected, history_without_dur, atol=1e-3, rtol=1e-3)
#Lista delle runs runs = [3, 7, 11] ica_true = True for subj in subjects: ls_run = [] #Lista dove inseriamo le run for run in runs: fname = eegbci.load_data(subj, runs=run)[0] #Prendo le run raw_run = read_raw_edf(fname, preload=True) #Le carico len_run = np.sum((raw_run._annotations).duration) #Controllo la durata if len_run > 123: raw_run.crop(tmax=124.4) #Taglio la parte finale ls_run.append(raw_run) #Aggiungo la run alla lista delle run raw = concatenate_raws(ls_run) eegbci.standardize(raw) #Cambio i nomi dei canali montage = make_standard_montage('standard_1005') #Caricare il montaggio raw.set_montage(montage) #Setto il montaggio raw.filter(1.0, 79.0, fir_design='firwin', skip_by_annotation='edge') #Filtro raw_notch = raw.notch_filter(freqs=60) #Faccio un filtro passa banda #todo: azzerare variabile plot_pre_psd = raw.plot_psd(area_mode=None, show=True, average=False, fmin=1.0, fmax=80.0, dB=False, n_fft=160) psd_name = os.path.join(dir_pre_psd, 'S' + str(subj) + '_real_pre.png')
def ica(data, sfreq, new_sfreq, save_name=None, threshold=2): if save_name is not None: for directory in [ 'ica', 'eog_score', 'eog_avg', 'raw_EEG', 'corrected_EEG', 'montage', 'new_raw' ]: if not os.path.exists(directory): os.makedirs(directory) # Create a dummy mne.io.RawArray object ch_types = CH_TYPES ch_names = CH_NAMES # Create an info object. info = mne.create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) long = 18000 # 15 s raws = [mne.io.RawArray(data[i][:, :long], info) for i in range(len(data))] raw = concatenate_raws(raws) raw.set_montage("standard_1020") if new_sfreq is not None and new_sfreq != sfreq: raw_resampled = raw.copy().resample(new_sfreq, npad='auto') raw_tmp = raw_resampled.copy() else: raw_tmp = raw.copy() ica_obj = ICA(random_state=None) ica_obj.fit(raw_tmp) n_max_eog = 3 # use max 3 components eog_epochs = create_eog_epochs(raw_tmp) eog_epochs.decimate(5).apply_baseline((None, None)) try: eog_inds, scores_eog = ica_obj.find_bads_eog(eog_epochs, threshold=threshold) print('Found %d EOG component(s)' % (len(eog_inds), )) #remove EOG from EEG ica_obj.exclude += eog_inds except: pass raw_corrected = raw_resampled.copy() ica_obj.apply(raw_corrected) print(ica_obj) # save fig and data if save_name is not None: ica_obj.plot_sources(raw_tmp, show=False).savefig('ica/' + save_name + '_ica.png') try: ica_obj.plot_scores(scores_eog, exclude=eog_inds, title='EOG scores', show=False).savefig('eog_score/' + save_name + '_eog_score.png') except: pass ica_obj.plot_sources(eog_epochs.average(), title='EOG average', show=False).savefig('eog_avg/' + save_name + '_eog_avg.png') raw.plot(show=False, scalings=dict( eeg=50, eog=150)).savefig('raw_EEG/' + save_name + '_raw_EEG.png') raw_corrected.plot(show=False, scalings=dict( eeg=50, eog=150)).savefig('corrected_EEG/' + save_name + '_corrected_EEG.png') ica_obj.plot_components(inst=raw_tmp, show=False)[0].savefig('montage/' + save_name + '_montage.png') print('======================================') print(raw_corrected.get_data().shape) raw_corrected.save('new_raw/' + save_name + '_raw.fif', overwrite=True) return reshape2Dto3D(raw_corrected.get_data(), trials=5)
def get_crops_multi(sub_id_range=[1, 50], event_code=[5, 6, 9, 10, 13, 14], t=[0, 4.0], filter=[0.5, 36], time_window=1.0, time_step=0.5): physionet_paths = [ mne.datasets.eegbci.load_data(sub_id, event_code) for sub_id in range(sub_id_range[0], sub_id_range[1]) ] physionet_paths = np.concatenate(physionet_paths) parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto') for path in physionet_paths ] raw = concatenate_raws(parts) if filter != None: raw.filter(filter[0], filter[1], fir_design='firwin', skip_by_annotation='edge') else: pass picks = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') # Read epochs (train will be done only between 1 and 2s) # Testing will be done with a running classifier epochs = mne.Epochs(raw, events, dict(hands=2, feet=3), tmin=t[0], tmax=t[1], proj=False, picks=picks, baseline=None, preload=True) ### startからendまでcrop,初期配列 start = t[0] end = start + time_window this_epoch = epochs.copy().crop(tmin=start, tmax=end) x = (this_epoch.get_data() * 1e6).astype(np.float32) y = (this_epoch.events[:, 2] - 2).astype(np.int64) print('get_time {} to {}'.format(start, end)) ### 繰り返しcropデータを連結 while True: start += time_step end = start + time_window if end > t[1]: break this_epoch = epochs.copy().crop(tmin=start, tmax=end) x = np.vstack((x, (this_epoch.get_data() * 1e6).astype(np.float32))) y = np.hstack((y, (this_epoch.events[:, 2] - 2).astype(np.int64))) print('get_time {} to {}'.format(start, end)) # epochs_list = [] # start = t[0] # while True: # end = start + time_window # if end > t[1]: # break # epochs_list.append(epochs.copy().crop(tmin=start, tmax=end)) # # print('get_time {} to {}'.format(start, end)) # start += time_step # # epochs_list = [] # # for i in range(int(160 * (t[1]-t[0]-time_window) / (160*time_step))): # # epochs_train = epochs.copy().crop(tmin=i * time_window/160 * (160*time_step), tmax=i * time_window/160 * (160*time_step) + time_window) # # epochs_list.append(epochs_train) # data_list = [] # label_list = [] # for epoch in epochs_list: # X = (epoch.get_data() * 1e6).astype(np.float32) # y = (epoch.events[:,2] - 2).astype(np.int64) # data_list.append(X) # label_list.append(y) # data_array = np.array(data_list) # label_array = np.array(label_list) # data_array2 = data_array.reshape(-1, data_array.shape[-2], data_array.shape[-1]) # label_array2 = label_array.reshape(-1) return x, y, raw, epochs
def get_data_one_class(id=1, event_code=[5, 6, 9, 10, 13, 14], filter=[0.5, 36], t=[1, 4.1], classid=2): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = id event_codes = event_code # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # bandpass filter if filter != None: raw.filter(filter[0], filter[1], fir_design='firwin', skip_by_annotation='edge') else: pass # Find the events in this dataset events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, classid, tmin=t[0], tmax=t[1], proj=False, picks=eeg_channel_inds, baseline=None, preload=True) # change time length # epochs_train = epochs.copy().crop(tmin=1., tmax=2.) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) #2,3 -> 0,1 return X, y
from mne.decoding import CSP print(__doc__) # ############################################################################# # # Set parameters and read data # avoid classification of evoked responses by using epochs that start 1s after # cue onset. tmin, tmax = -1., 4. event_id = dict(hands=2, feet=3) subject = 1 runs = [6, 10, 14] # motor imagery: hands vs feet raw_fnames = eegbci.load_data(subject, runs) raw = concatenate_raws([read_raw_edf(f, preload=True) for f in raw_fnames]) # strip channel names of "." characters raw.rename_channels(lambda x: x.strip('.')) # Apply band-pass filter raw.filter(7., 30., fir_design='firwin', skip_by_annotation='edge') events, _ = events_from_annotations(raw, event_id=dict(T1=2, T2=3)) picks = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Read epochs (train will be done only between 1 and 2s) # Testing will be done with a running classifier epochs = Epochs(raw, events, event_id, tmin, tmax, proj=True, picks=picks,
def test_eeg_classifier(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes, update_path=False) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel="auto", verbose="WARNING") for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads") # Extract trials, only using EEG channels epoched = mne.Epochs( raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True, ) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_time_length = 450 n_classes = 2 in_chans = X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=12, ) to_dense_prediction_model(model) if cuda: model.cuda() # determine output size test_input = np_to_var( np.ones((2, in_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] train_set = CroppedXyDataset(X[:60], y=y[:60], input_time_length=input_time_length, n_preds_per_input=n_preds_per_input) cropped_cb_train = CroppedTrialEpochScoring( "accuracy", name="train_trial_accuracy", lower_is_better=False, on_train=True, ) cropped_cb_valid = CroppedTrialEpochScoring( "accuracy", on_train=False, name="valid_trial_accuracy", lower_is_better=False, ) clf = EEGClassifier( model, criterion=CroppedLoss, criterion__loss_function=nll_loss, optimizer=optim.Adam, train_split=TrainTestSplit( train_size=0.8, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input, ), batch_size=32, callbacks=[ ("train_trial_accuracy", cropped_cb_train), ("valid_trial_accuracy", cropped_cb_valid), ], ) clf.fit(train_set.X, train_set.y, epochs=4) expected = [ { "batches": [ { "train_loss": 1.9391239881515503, "train_batch_size": 32 }, { "train_loss": 2.895704507827759, "train_batch_size": 32 }, { "train_loss": 1.0713893175125122, "train_batch_size": 32 }, { "valid_loss": 1.1811838150024414, "valid_batch_size": 24 }, ], "epoch": 1, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 1.9687392711639404, "train_loss_best": True, "valid_loss": 1.1811838150024414, "valid_loss_best": True, "train_trial_accuracy": 0.4791666666666667, "train_trial_accuracy_best": True, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": True, }, { "batches": [ { "train_loss": 1.5488793849945068, "train_batch_size": 32 }, { "train_loss": 1.1174801588058472, "train_batch_size": 32 }, { "train_loss": 1.1525697708129883, "train_batch_size": 32 }, { "valid_loss": 2.202029228210449, "valid_batch_size": 24 }, ], "epoch": 2, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 1.2729764382044475, "train_loss_best": True, "valid_loss": 2.202029228210449, "valid_loss_best": False, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": True, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": False, }, { "batches": [ { "train_loss": 1.0049529075622559, "train_batch_size": 32 }, { "train_loss": 1.0266971588134766, "train_batch_size": 32 }, { "train_loss": 1.0799436569213867, "train_batch_size": 32 }, { "valid_loss": 1.0638500452041626, "valid_batch_size": 24 }, ], "epoch": 3, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 1.0371979077657063, "train_loss_best": True, "valid_loss": 1.0638500452041626, "valid_loss_best": True, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": False, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": False, }, { "batches": [ { "train_loss": 1.0052555799484253, "train_batch_size": 32 }, { "train_loss": 0.8479514718055725, "train_batch_size": 32 }, { "train_loss": 0.9589881300926208, "train_batch_size": 32 }, { "valid_loss": 0.8794112801551819, "valid_batch_size": 24 }, ], "epoch": 4, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 0.9373983939488729, "train_loss_best": True, "valid_loss": 0.8794112801551819, "valid_loss_best": True, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": False, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": False, }, ] history_without_dur = [{k: v for k, v in h.items() if k != "dur"} for h in clf.history] assert_deep_allclose(expected, history_without_dur, atol=1e-3, rtol=1e-3)
def test_events_from_annot_in_raw_objects(): """Test basic functionality of events_fron_annot for raw objects.""" raw = read_raw_fif(fif_fname) events = mne.find_events(raw) event_id = { 'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3, 'Visual/Right': 4, 'Visual/Smiley': 32, 'Motor/Button': 5 } event_map = {v: k for k, v in event_id.items()} annot = Annotations(onset=raw.times[events[:, 0] - raw.first_samp], duration=np.zeros(len(events)), description=[event_map[vv] for vv in events[:, 2]], orig_time=None) raw.set_annotations(annot) events2, event_id2 = \ events_from_annotations(raw, event_id=event_id, regexp=None) assert_array_equal(events, events2) assert_equal(event_id, event_id2) events3, event_id3 = \ events_from_annotations(raw, event_id=None, regexp=None) assert_array_equal(events[:, 0], events3[:, 0]) assert set(event_id.keys()) == set(event_id3.keys()) # ensure that these actually got sorted properly expected_event_id = { desc: idx + 1 for idx, desc in enumerate(sorted(event_id.keys()))} assert event_id3 == expected_event_id first = np.unique(events3[:, 2]) second = np.arange(1, len(event_id) + 1, 1).astype(first.dtype) assert_array_equal(first, second) first = np.unique(list(event_id3.values())) second = np.arange(1, len(event_id) + 1, 1).astype(first.dtype) assert_array_equal(first, second) events4, event_id4 =\ events_from_annotations(raw, event_id=None, regexp='.*Left') expected_event_id4 = {k: v for k, v in event_id.items() if 'Left' in k} assert_equal(event_id4.keys(), expected_event_id4.keys()) expected_events4 = events[(events[:, 2] == 1) | (events[:, 2] == 3)] assert_array_equal(expected_events4[:, 0], events4[:, 0]) events5, event_id5 = \ events_from_annotations(raw, event_id=event_id, regexp='.*Left') expected_event_id5 = {k: v for k, v in event_id.items() if 'Left' in k} assert_equal(event_id5, expected_event_id5) expected_events5 = events[(events[:, 2] == 1) | (events[:, 2] == 3)] assert_array_equal(expected_events5, events5) with pytest.raises(ValueError, match='not find any of the events'): events_from_annotations(raw, regexp='not_there') with pytest.raises(ValueError, match='Invalid input event_id'): events_from_annotations(raw, event_id='wrong') # concat does not introduce BAD or EDGE raw_concat = concatenate_raws([raw.copy(), raw.copy()]) _, event_id = events_from_annotations(raw_concat) assert isinstance(event_id, dict) assert len(event_id) > 0 for kind in ('BAD', 'EDGE'): assert '%s boundary' % kind in raw_concat.annotations.description for key in event_id.keys(): assert kind not in key # remove all events raw.set_annotations(None) events7, _ = events_from_annotations(raw) assert_array_equal(events7, np.empty((0, 3), dtype=int))
def test_basics(): """Test annotation class.""" raw = read_raw_fif(fif_fname) assert raw.annotations is not None # XXX to be fixed in #5416 assert len(raw.annotations.onset) == 0 # XXX to be fixed in #5416 pytest.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) pytest.raises(ValueError, Annotations, onset, duration, description[:9]) pytest.raises(ValueError, Annotations, [onset, 1], duration, description) pytest.raises(ValueError, Annotations, onset, [duration, 1], description) # Test combining annotations with concatenate_raws raw2 = raw.copy() delta = raw.times[-1] + 1. / raw.info['sfreq'] orig_time = (meas_date[0] + meas_date[1] * 1e-6 + raw2._first_time) offset = orig_time - _handle_meas_date(raw2.info['meas_date']) annot = Annotations(onset, duration, description, orig_time) assert ' segments' in repr(annot) raw2.set_annotations(annot) assert_array_equal(raw2.annotations.onset, onset + offset) assert id(raw2.annotations) != id(annot) concatenate_raws([raw, raw2]) assert_and_remove_boundary_annot(raw) assert_allclose(onset + offset + delta, raw.annotations.onset, rtol=1e-5) 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'] = (np.pi, 0) raws = [] for first_samp in [12300, 100, 12]: raw = RawArray(data.copy(), info, first_samp=first_samp) ants = Annotations([1., 2.], [.5, .5], 'x', np.pi + first_samp / sfreq) raw.set_annotations(ants) raws.append(raw) raw = RawArray(data.copy(), info) raw.set_annotations(Annotations([1.], [.5], 'x', None)) raws.append(raw) raw = concatenate_raws(raws, verbose='debug') assert_and_remove_boundary_annot(raw, 3) assert_array_equal(raw.annotations.onset, [124., 125., 134., 135., 144., 145., 154.]) raw.annotations.delete(2) assert_array_equal(raw.annotations.onset, [124., 125., 135., 144., 145., 154.]) raw.annotations.append(5, 1.5, 'y') assert_array_equal(raw.annotations.onset, [5., 124., 125., 135., 144., 145., 154.]) assert_array_equal(raw.annotations.duration, [1.5, .5, .5, .5, .5, .5, .5]) assert_array_equal(raw.annotations.description, ['y', 'x', 'x', 'x', 'x', 'x', 'x']) # These three things should be equivalent expected_orig_time = (raw.info['meas_date'][0] + raw.info['meas_date'][1] / 1000000) for empty_annot in (Annotations([], [], [], expected_orig_time), Annotations([], [], [], None), None): raw.set_annotations(empty_annot) assert isinstance(raw.annotations, Annotations) assert len(raw.annotations) == 0 assert raw.annotations.orig_time == expected_orig_time
def load_data(self, subject): """ Load data from a subject designated by his identifier. Input: subject: int between 1 and 109 Output: raw: mne.Raw, structure containing EEG data events: numpy array (n_events, 3) first column: date of event in sample second column: duration of event thrid column: event code """ assert 1 <= subject <= 109 # dictionnary to specify the label and code of each event of interest event_id = dict(left=0, right=1, hands=2, feet=3) # list of dictionnaries to specify the different tasks of interest task = [ dict(T1=event_id['left'], T2=event_id['right']), dict(T1=event_id['hands'], T2=event_id['feet']) ] # list of dictionnaries to specify the different runs to load for one subject runs = [ dict(id=4, task=task[0]), dict(id=6, task=task[1]), dict(id=8, task=task[0]), dict(id=10, task=task[1]), dict(id=12, task=task[0]), dict(id=14, task=task[1]) ] # load and concatenate the different files from the specified subject # download the files if necessary raws = list() events_list = list() for run in runs: # localize the file, download it if necessary filename = eegbci.load_data(subject, run['id']) # load its contain raw = read_raw_edf(filename[0], preload=True) events, _ = events_from_annotations(raw, event_id=run['task']) # accumulate the data raws.append(raw) events_list.append(events) # concatenate all data in two structures : one for EEG, one for the events raw, events = concatenate_raws(raws, events_list=events_list) # strip channel names of "." characters raw.rename_channels(lambda x: x.strip('.')) # delete annotations indices = [x for x in range(len(raw.annotations))] indices.reverse() for i in indices: raw.annotations.delete(i) return raw, events
def get_crops_multi_one_class(sub_id_range=[1, 50], event_code=[5, 6, 9, 10, 13, 14], t=[0, 4.0], filter=[0.5, 36], time_window=1.0, time_step=0.5, classid=2): physionet_paths = [ mne.datasets.eegbci.load_data(sub_id, event_code) for sub_id in range(sub_id_range[0], sub_id_range[1]) ] physionet_paths = np.concatenate(physionet_paths) parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto') for path in physionet_paths ] raw = concatenate_raws(parts) if filter != None: raw.filter(filter[0], filter[1], fir_design='firwin', skip_by_annotation='edge') else: pass picks = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Read epochs (train will be done only between 1 and 2s) # Testing will be done with a running classifier epochs = mne.Epochs(raw, events, classid, tmin=t[0], tmax=t[1], proj=False, picks=eeg_channel_inds, baseline=None, preload=True) ### startからendまでcrop,初期配列 start = t[0] end = start + time_window this_epoch = epochs.copy().crop(tmin=start, tmax=end) x = (this_epoch.get_data() * 1e6).astype(np.float32) y = (this_epoch.events[:, 2] - 2).astype(np.int64) print('get_time {} to {}'.format(start, end)) ### 繰り返しcropデータを連結 while True: start += time_step end = start + time_window if end > t[1]: break this_epoch = epochs.copy().crop(tmin=start, tmax=end) x = np.vstack((x, (this_epoch.get_data() * 1e6).astype(np.float32))) y = np.hstack((y, (this_epoch.events[:, 2] - 2).astype(np.int64))) print('get_time {} to {}'.format(start, end)) return x, y
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) raw2.annotations = annot assert_array_equal(raw2.annotations.onset, onset) concatenate_raws([raw, raw2]) 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) 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]) assert_array_almost_equal(raw.annotations.onset, [45., 2. + last_time], decimal=2)
def test_trialwise_decoding(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes, update_path=False) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel="auto", verbose="WARNING") for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) raw.apply_function(lambda x: x * 1000000) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads") # Extract trials, only using EEG channels epoched = mne.Epochs( raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True, ) ds = EpochsDataset(epoched) train_set = Subset(ds, np.arange(60)) valid_set = Subset(ds, np.arange(60, len(ds))) train_valid_split = predefined_split(valid_set) cuda = False if cuda: device = 'cuda' else: device = 'cpu' set_random_seeds(seed=20170629, cuda=cuda) n_classes = 2 in_chans = train_set[0][0].shape[0] input_window_samples = train_set[0][0].shape[1] model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_window_samples=input_window_samples, final_conv_length="auto", ) if cuda: model.cuda() clf = EEGClassifier( model, cropped=False, criterion=torch.nn.NLLLoss, optimizer=torch.optim.Adam, train_split=train_valid_split, optimizer__lr=0.001, batch_size=30, callbacks=["accuracy"], device=device, ) clf.fit(train_set, y=None, epochs=6) np.testing.assert_allclose( clf.history[:, 'train_loss'], np.array([ 1.1114974617958069, 1.0976492166519165, 0.668171226978302, 0.5880511999130249, 0.7054798305034637, 0.5272344648838043 ]), rtol=1e-4, atol=1e-5, ) np.testing.assert_allclose( clf.history[:, 'valid_loss'], np.array([ 0.8467752933502197, 0.9804958701133728, 0.9134824872016907, 0.8305345773696899, 0.8263336420059204, 0.8535978198051453 ]), rtol=1e-4, atol=1e-5, ) np.testing.assert_allclose( clf.history[:, 'train_accuracy'], np.array([ 0.7166666666666667, 0.6666666666666666, 0.85, 0.9333333333333333, 0.9166666666666666, 0.9 ]), rtol=1e-4, atol=1e-5, ) np.testing.assert_allclose( clf.history[:, 'valid_accuracy'], np.array([ 0.6, 0.5666666666666667, 0.5333333333333333, 0.5333333333333333, 0.6, 0.6666666666666666 ]), rtol=1e-4, atol=1e-5, )
def test_cropped_decoding(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data( subject_id, event_codes, update_path=False ) # Load each of the files parts = [ mne.io.read_raw_edf( path, preload=True, stim_channel="auto", verbose="WARNING" ) for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types( raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads" ) # Extract trials, only using EEG channels epoched = mne.Epochs( raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True, ) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_window_samples = 450 n_classes = 2 in_chans = X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_window_samples=input_window_samples, final_conv_length=12, ) to_dense_prediction_model(model) if cuda: model.cuda() # Perform forward pass to determine how many outputs per input n_preds_per_input = get_output_shape(model, in_chans, input_window_samples)[2] train_set = create_from_X_y(X[:60], y[:60], drop_last_window=False, window_size_samples=input_window_samples, window_stride_samples=n_preds_per_input) valid_set = create_from_X_y(X[60:], y[60:], drop_last_window=False, window_size_samples=input_window_samples, window_stride_samples=n_preds_per_input) train_split = predefined_split(valid_set) clf = EEGClassifier( model, cropped=True, criterion=CroppedLoss, criterion__loss_function=torch.nn.functional.nll_loss, optimizer=optim.Adam, train_split=train_split, batch_size=32, callbacks=['accuracy'], ) clf.fit(train_set, y=None, epochs=4) np.testing.assert_allclose( clf.history[:, 'train_loss'], np.array( [ 1.455306, 1.455934, 1.210563, 1.065806 ] ), rtol=1e-3, atol=1e-4, ) np.testing.assert_allclose( clf.history[:, 'valid_loss'], np.array( [ 2.547288, 1.51785, 1.394036, 1.064355 ] ), rtol=1e-3, atol=1e-3, ) np.testing.assert_allclose( clf.history[:, 'train_accuracy'], np.array( [ 0.5, 0.5, 0.5, 0.533333 ] ), rtol=1e-3, atol=1e-4, ) np.testing.assert_allclose( clf.history[:, 'valid_accuracy'], np.array( [ 0.533333, 0.466667, 0.533333, 0.5 ] ), rtol=1e-3, atol=1e-4, )
def test_basics(): """Test annotation class.""" raw = read_raw_fif(fif_fname) assert raw.annotations is None pytest.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) pytest.raises(ValueError, Annotations, onset, duration, description[:9]) pytest.raises(ValueError, Annotations, [onset, 1], duration, description) pytest.raises(ValueError, Annotations, onset, [duration, 1], description) # Test combining annotations with concatenate_raws raw2 = raw.copy() delta = raw.times[-1] + 1. / raw.info['sfreq'] orig_time = (meas_date[0] + meas_date[1] * 1e-6 + raw2.first_samp / raw2.info['sfreq']) annot = Annotations(onset, duration, description, orig_time) assert ' 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_allclose(onset + delta, raw.annotations.onset, rtol=1e-5) 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'] = np.pi raws = [] for first_samp in [12300, 100, 12]: raw = RawArray(data.copy(), info, first_samp=first_samp) ants = Annotations([1., 2.], [.5, .5], 'x', np.pi + first_samp / 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, verbose='debug') boundary_idx = np.where(raw.annotations.description == 'BAD boundary')[0] assert len(boundary_idx) == 3 raw.annotations.delete(boundary_idx) boundary_idx = np.where(raw.annotations.description == 'EDGE boundary')[0] assert 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'])
sns.set_style('whitegrid') ############################################################################### # Set parameters and read data # avoid classification of evoked responses by using epochs that start 1s after # cue onset. tmin, tmax = 1., 3. event_id = dict(hands=2, feet=3) subject = 1 runs = [6, 10, 14] # motor imagery: hands vs feet raw_files = [ read_raw_edf(f, preload=True, verbose=False) for f in eegbci.load_data(subject, runs) ] raw = concatenate_raws(raw_files) # Apply band-pass filter raw.filter(7., 35., method='iir') events, _ = events_from_annotations(raw, event_id=dict(T1=2, T2=3)) picks = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') picks = picks[::4] # Read epochs (train will be done only between 1 and 2s)
def load_subject_session(sub=2, session_type='task'): subject = sub tmin, tmax = -1., 4. if session_type == 'task': event_id_annot = dict(T1=2, T2=3) event_id_epochs = dict(hands=2, feet=3) runs = [6, 10, 14] # motor imagery: hands vs feet elif session_type == 'baseline1': event_id_annot = dict(T0=0) event_id_epochs = dict(close=0) runs = 1 elif session_type == 'baseline2': event_id_annot = dict(T0=0) event_id_epochs = dict(open_=0) runs = 2 raw_fnames = eegbci.load_data(subject, runs, verbose=False) raws = [read_raw_edf(f, preload=True, verbose=False) for f in raw_fnames] raw = concatenate_raws(raws) # strip channel names of "." characters raw.rename_channels(lambda x: x.strip('.')) # Apply band-pass filter raw.filter(0.5, 40., fir_design='firwin', skip_by_annotation='edge', verbose=False) events, _ = events_from_annotations(raw, event_id=event_id_annot, chunk_duration=1., verbose=False) #print(np.round((events[:, 0] - raw.first_samp) / raw.info['sfreq'], 3)) picks = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') #picks = mne.pick_channels(raw.info['ch_names'], ['C5', 'C3', 'Cz', 'C4', 'C6', 'T9', 'T10', 'Af7', 'Fpz', 'Af8', 'F5', 'F3', 'Fz', 'F4', 'F6']) # Read epochs (train will be done only between 1 and 2s) # Testing will be done with a running classifier epochs = Epochs(raw, events, event_id_epochs, tmin, tmax, proj=True, picks=picks, baseline=None, preload=True, verbose=False) #epochs_train = epochs.copy().crop(tmin=1., tmax=2.) labels = epochs.events[:, -1] - 2 #epochs_data = epochs_train.get_data() psds, freqs = mne.time_frequency.psd_welch(epochs, fmin=0.5, fmax=30., verbose=False) # Normalize the PSDs psds /= np.sum(psds, axis=-1, keepdims=True) # specific frequency bands FREQ_BANDS = { "delta": [0.5, 4.5], "theta": [4.5, 8.5], "alpha": [8.5, 11.5], "sigma": [11.5, 15.5], "beta": [15.5, 30] } X = [] for fmin, fmax in FREQ_BANDS.values(): psds_band = psds[:, :, (freqs >= fmin) & (freqs < fmax)].mean(axis=-1) X.append(np.expand_dims(psds_band.reshape(len(psds), -1), axis=-1)) X = np.concatenate(X, axis=-1) X = X.reshape(X.shape[0], X.shape[1] * X.shape[-1]) return X, labels
def test_annotation_filtering(first_samp): """Test that annotations work properly with filtering.""" # Create data with just a DC component data = np.ones((1, 1000)) info = create_info(1, 1000., 'eeg') raws = [ RawArray(data * (ii + 1), info, first_samp=first_samp) for ii in range(4) ] kwargs_pass = dict(l_freq=None, h_freq=50., fir_design='firwin') kwargs_stop = dict(l_freq=50., h_freq=None, fir_design='firwin') # lowpass filter, which should not modify the data raws_pass = [raw.copy().filter(**kwargs_pass) for raw in raws] # highpass filter, which should zero it out raws_stop = [raw.copy().filter(**kwargs_stop) for raw in raws] # concat the original and the filtered segments raws_concat = concatenate_raws([raw.copy() for raw in raws]) raws_zero = raws_concat.copy().apply_function(lambda x: x * 0) raws_pass_concat = concatenate_raws(raws_pass) raws_stop_concat = concatenate_raws(raws_stop) # make sure we did something reasonable with our individual-file filtering assert_allclose(raws_concat[0][0], raws_pass_concat[0][0], atol=1e-14) assert_allclose(raws_zero[0][0], raws_stop_concat[0][0], atol=1e-14) # ensure that our Annotations cut up the filtering properly raws_concat_pass = raws_concat.copy().filter(skip_by_annotation='edge', **kwargs_pass) assert_allclose(raws_concat[0][0], raws_concat_pass[0][0], atol=1e-14) raws_concat_stop = raws_concat.copy().filter(skip_by_annotation='edge', **kwargs_stop) assert_allclose(raws_zero[0][0], raws_concat_stop[0][0], atol=1e-14) # one last test: let's cut out a section entirely: # here the 1-3 second window should be skipped raw = raws_concat.copy() raw.annotations.append(1., 2., 'foo') with catch_logging() as log: raw.filter(l_freq=50., h_freq=None, fir_design='firwin', skip_by_annotation='foo', verbose='info') log = log.getvalue() assert '2 contiguous segments' in log raw.annotations.append(2., 1., 'foo') # shouldn't change anything with catch_logging() as log: raw.filter(l_freq=50., h_freq=None, fir_design='firwin', skip_by_annotation='foo', verbose='info') log = log.getvalue() assert '2 contiguous segments' in log # our filter will zero out anything not skipped: mask = np.concatenate((np.zeros(1000), np.ones(2000), np.zeros(1000))) expected_data = raws_concat[0][0][0] * mask assert_allclose(raw[0][0][0], expected_data, atol=1e-14) # Let's try another one raw = raws[0].copy() raw.set_annotations(Annotations([0.], [0.5], ['BAD_ACQ_SKIP'])) my_data, times = raw.get_data(reject_by_annotation='omit', return_times=True) assert_allclose(times, raw.times[500:]) assert my_data.shape == (1, 500) raw_filt = raw.copy().filter(skip_by_annotation='bad_acq_skip', **kwargs_stop) expected = data.copy() expected[:, 500:] = 0 assert_allclose(raw_filt[:][0], expected, atol=1e-14) raw = raws[0].copy() raw.set_annotations(Annotations([0.5], [0.5], ['BAD_ACQ_SKIP'])) my_data, times = raw.get_data(reject_by_annotation='omit', return_times=True) assert_allclose(times, raw.times[:500]) assert my_data.shape == (1, 500) raw_filt = raw.copy().filter(skip_by_annotation='bad_acq_skip', **kwargs_stop) expected = data.copy() expected[:, :500] = 0 assert_allclose(raw_filt[:][0], expected, atol=1e-14)
def test_annotation_filtering(): """Test that annotations work properly with filtering.""" # Create data with just a DC component data = np.ones((1, 1000)) info = create_info(1, 1000., 'eeg') raws = [RawArray(data * (ii + 1), info) for ii in range(4)] kwargs_pass = dict(l_freq=None, h_freq=50., fir_design='firwin') kwargs_stop = dict(l_freq=50., h_freq=None, fir_design='firwin') # lowpass filter, which should not modify the data raws_pass = [raw.copy().filter(**kwargs_pass) for raw in raws] # highpass filter, which should zero it out raws_stop = [raw.copy().filter(**kwargs_stop) for raw in raws] # concat the original and the filtered segments raws_concat = concatenate_raws([raw.copy() for raw in raws]) raws_zero = raws_concat.copy().apply_function(lambda x: x * 0) raws_pass_concat = concatenate_raws(raws_pass) raws_stop_concat = concatenate_raws(raws_stop) # make sure we did something reasonable with our individual-file filtering assert_allclose(raws_concat[0][0], raws_pass_concat[0][0], atol=1e-14) assert_allclose(raws_zero[0][0], raws_stop_concat[0][0], atol=1e-14) # ensure that our Annotations cut up the filtering properly raws_concat_pass = raws_concat.copy().filter(skip_by_annotation='edge', **kwargs_pass) assert_allclose(raws_concat[0][0], raws_concat_pass[0][0], atol=1e-14) raws_concat_stop = raws_concat.copy().filter(skip_by_annotation='edge', **kwargs_stop) assert_allclose(raws_zero[0][0], raws_concat_stop[0][0], atol=1e-14) # one last test: let's cut out a section entirely: # here the 1-3 second window should be skipped raw = raws_concat.copy() raw.annotations.append(1., 2., 'foo') with catch_logging() as log: raw.filter(l_freq=50., h_freq=None, fir_design='firwin', skip_by_annotation='foo', verbose='info') log = log.getvalue() assert '2 contiguous segments' in log raw.annotations.append(2., 1., 'foo') # shouldn't change anything with catch_logging() as log: raw.filter(l_freq=50., h_freq=None, fir_design='firwin', skip_by_annotation='foo', verbose='info') log = log.getvalue() assert '2 contiguous segments' in log # our filter will zero out anything not skipped: mask = np.concatenate((np.zeros(1000), np.ones(2000), np.zeros(1000))) expected_data = raws_concat[0][0][0] * mask assert_allclose(raw[0][0][0], expected_data, atol=1e-14) # Let's try another one raw = raws[0].copy() raw.set_annotations(Annotations([0.], [0.5], ['BAD_ACQ_SKIP'])) my_data, times = raw.get_data(reject_by_annotation='omit', return_times=True) assert_allclose(times, raw.times[500:]) assert my_data.shape == (1, 500) raw_filt = raw.copy().filter(skip_by_annotation='bad_acq_skip', **kwargs_stop) expected = data.copy() expected[:, 500:] = 0 assert_allclose(raw_filt[:][0], expected, atol=1e-14) raw = raws[0].copy() raw.set_annotations(Annotations([0.5], [0.5], ['BAD_ACQ_SKIP'])) my_data, times = raw.get_data(reject_by_annotation='omit', return_times=True) assert_allclose(times, raw.times[:500]) assert my_data.shape == (1, 500) raw_filt = raw.copy().filter(skip_by_annotation='bad_acq_skip', **kwargs_stop) expected = data.copy() expected[:, :500] = 0 assert_allclose(raw_filt[:][0], expected, atol=1e-14)
# event_codes = [3,4,5,6,7,8,9,10,11,12,13,14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = \ mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, dict(hands_or_left=2, feet_or_right=3), tmin=1, tmax=4.1,
def test_eeg_classifier(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes, update_path=False) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel="auto", verbose="WARNING") for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events, _ = mne.events_from_annotations(raw) # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads") # Extract trials, only using EEG channels epoched = mne.Epochs( raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True, ) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_time_length = 450 n_classes = 2 in_chans = X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=12, ) to_dense_prediction_model(model) if cuda: model.cuda() # determine output size test_input = np_to_var( np.ones((2, in_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] train_set = CroppedXyDataset(X[:60], y=y[:60], input_time_length=input_time_length, n_preds_per_input=n_preds_per_input) cropped_cb_train = CroppedTrialEpochScoring( "accuracy", name="train_trial_accuracy", lower_is_better=False, on_train=True, ) cropped_cb_valid = CroppedTrialEpochScoring( "accuracy", on_train=False, name="valid_trial_accuracy", lower_is_better=False, ) clf = EEGClassifier( model, criterion=CroppedNLLLoss, optimizer=optim.Adam, train_split=TrainTestSplit( train_size=0.8, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input, ), batch_size=32, callbacks=[ ("train_trial_accuracy", cropped_cb_train), ("valid_trial_accuracy", cropped_cb_valid), ], ) clf.fit(train_set.X, train_set.y, epochs=4) expected = [ { "batches": [ { "train_loss": 2.0750882625579834, "train_batch_size": 32 }, { "train_loss": 3.09424090385437, "train_batch_size": 32 }, { "train_loss": 1.079931378364563, "train_batch_size": 32 }, { "valid_loss": 2.3208131790161133, "valid_batch_size": 24 }, ], "epoch": 1, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 2.083086848258972, "train_loss_best": True, "valid_loss": 2.3208131790161133, "valid_loss_best": True, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": True, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": True, }, { "batches": [ { "train_loss": 1.827332615852356, "train_batch_size": 32 }, { "train_loss": 1.4135494232177734, "train_batch_size": 32 }, { "train_loss": 1.1295170783996582, "train_batch_size": 32 }, { "valid_loss": 1.4291356801986694, "valid_batch_size": 24 }, ], "epoch": 2, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 1.4567997058232625, "train_loss_best": True, "valid_loss": 1.4291356801986694, "valid_loss_best": True, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": False, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": False, }, { "batches": [ { "train_loss": 1.1495535373687744, "train_batch_size": 32 }, { "train_loss": 2.356320381164551, "train_batch_size": 32 }, { "train_loss": 0.9548418521881104, "train_batch_size": 32 }, { "valid_loss": 2.248246908187866, "valid_batch_size": 24 }, ], "epoch": 3, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 1.4869052569071453, "train_loss_best": False, "valid_loss": 2.248246908187866, "valid_loss_best": False, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": False, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": False, }, { "batches": [ { "train_loss": 1.2157528400421143, "train_batch_size": 32 }, { "train_loss": 1.1182057857513428, "train_batch_size": 32 }, { "train_loss": 0.9163083434104919, "train_batch_size": 32 }, { "valid_loss": 0.9732739925384521, "valid_batch_size": 24 }, ], "epoch": 4, "train_batch_count": 3, "valid_batch_count": 1, "train_loss": 1.083422323067983, "train_loss_best": True, "valid_loss": 0.9732739925384521, "valid_loss_best": True, "train_trial_accuracy": 0.5, "train_trial_accuracy_best": False, "valid_trial_accuracy": 0.5, "valid_trial_accuracy_best": False, }, ] history_without_dur = [{k: v for k, v in h.items() if k != "dur"} for h in clf.history] assert_deep_allclose(history_without_dur, expected, atol=1e-3, rtol=1e-3)
def test_crop(): """Test cropping with annotations.""" raw = read_raw_fif(fif_fname) events = mne.find_events(raw) onset = events[events[:, 2] == 1, 0] / raw.info['sfreq'] duration = np.full_like(onset, 0.5) description = ['bad %d' % k for k in range(len(onset))] annot = mne.Annotations(onset, duration, description, orig_time=raw.info['meas_date']) raw.set_annotations(annot) split_time = raw.times[-1] / 2. + 2. split_idx = len(onset) // 2 + 1 raw_cropped_left = raw.copy().crop(0., split_time - 1. / raw.info['sfreq']) assert_array_equal(raw_cropped_left.annotations.description, raw.annotations.description[:split_idx]) assert_allclose(raw_cropped_left.annotations.duration, raw.annotations.duration[:split_idx]) assert_allclose(raw_cropped_left.annotations.onset, raw.annotations.onset[:split_idx]) raw_cropped_right = raw.copy().crop(split_time, None) assert_array_equal(raw_cropped_right.annotations.description, raw.annotations.description[split_idx:]) assert_allclose(raw_cropped_right.annotations.duration, raw.annotations.duration[split_idx:]) assert_allclose(raw_cropped_right.annotations.onset, raw.annotations.onset[split_idx:]) raw_concat = mne.concatenate_raws([raw_cropped_left, raw_cropped_right], verbose='debug') assert_allclose(raw_concat.times, raw.times) assert_allclose(raw_concat[:][0], raw[:][0], atol=1e-20) # Get rid of the boundary events raw_concat.annotations.delete(-1) raw_concat.annotations.delete(-1) # Ensure we annotations survive round-trip crop->concat assert_array_equal(raw_concat.annotations.description, raw.annotations.description) for attr in ('onset', 'duration'): assert_allclose(getattr(raw_concat.annotations, attr), getattr(raw.annotations, attr), err_msg='Failed for %s:' % (attr,)) raw.set_annotations(None) # undo # Test concatenating annotations with and without orig_time. raw2 = raw.copy() raw.set_annotations(Annotations([45.], [3], 'test', raw.info['meas_date'])) raw2.set_annotations(Annotations([2.], [3], 'BAD', None)) expected_onset = [45., 2. + raw._last_time] raw = concatenate_raws([raw, raw2]) raw.annotations.delete(-1) # remove boundary annotations raw.annotations.delete(-1) assert_array_almost_equal(raw.annotations.onset, expected_onset, 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) pytest.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.set_annotations(annot) raw.save(fname) raw_read = read_raw_fif(fname) assert isinstance(raw_read.annotations, Annotations) assert len(raw_read.annotations) == 0 raw.set_annotations(None) raw.save(fname, overwrite=True) raw_read = read_raw_fif(fname) assert raw_read.annotations is not None # XXX to be fixed in #5416 assert len(raw_read.annotations.onset) == 0 # XXX to be fixed in #5416
from mne.datasets import eegbci from mne.decoding import CSP from mne.time_frequency import AverageTFR from sklearn.discriminant_analysis import LinearDiscriminantAnalysis from sklearn.model_selection import StratifiedKFold, cross_val_score from sklearn.pipeline import make_pipeline from sklearn.preprocessing import LabelEncoder # %% # Set parameters and read data event_id = dict(hands=2, feet=3) # motor imagery: hands vs feet subject = 1 runs = [6, 10, 14] raw_fnames = eegbci.load_data(subject, runs) raw = concatenate_raws([read_raw_edf(f) for f in raw_fnames]) # Extract information from the raw file sfreq = raw.info['sfreq'] events, _ = events_from_annotations(raw, event_id=dict(T1=2, T2=3)) raw.pick_types(meg=False, eeg=True, stim=False, eog=False, exclude='bads') raw.load_data() # Assemble the classifier using scikit-learn pipeline clf = make_pipeline(CSP(n_components=4, reg=None, log=True, norm_trace=False), LinearDiscriminantAnalysis()) n_splits = 3 # for cross-validation, 5 is better, here we use 3 for speed cv = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42) # Classification & time-frequency parameters tmin, tmax = -.200, 2.000
def test_basics(): """Test annotation class.""" raw = read_raw_fif(fif_fname) assert raw.annotations is not None # XXX to be fixed in #5416 assert len(raw.annotations.onset) == 0 # XXX to be fixed in #5416 pytest.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) pytest.raises(ValueError, Annotations, onset, duration, description[:9]) pytest.raises(ValueError, Annotations, [onset, 1], duration, description) pytest.raises(ValueError, Annotations, onset, [duration, 1], description) # Test combining annotations with concatenate_raws raw2 = raw.copy() delta = raw.times[-1] + 1. / raw.info['sfreq'] orig_time = (meas_date[0] + meas_date[1] * 1e-6 + raw2._first_time) offset = orig_time - _handle_meas_date(raw2.info['meas_date']) annot = Annotations(onset, duration, description, orig_time) assert ' segments' in repr(annot) raw2.set_annotations(annot) assert_array_equal(raw2.annotations.onset, onset + offset) assert id(raw2.annotations) != id(annot) concatenate_raws([raw, raw2]) raw.annotations.delete(-1) # remove boundary annotations raw.annotations.delete(-1) assert_allclose(onset + offset + delta, raw.annotations.onset, rtol=1e-5) 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'] = (np.pi, 0) raws = [] for first_samp in [12300, 100, 12]: raw = RawArray(data.copy(), info, first_samp=first_samp) ants = Annotations([1., 2.], [.5, .5], 'x', np.pi + first_samp / sfreq) raw.set_annotations(ants) raws.append(raw) raw = RawArray(data.copy(), info) raw.set_annotations(Annotations([1.], [.5], 'x', None)) raws.append(raw) raw = concatenate_raws(raws, verbose='debug') boundary_idx = np.where(raw.annotations.description == 'BAD boundary')[0] assert len(boundary_idx) == 3 raw.annotations.delete(boundary_idx) boundary_idx = np.where(raw.annotations.description == 'EDGE boundary')[0] assert len(boundary_idx) == 3 raw.annotations.delete(boundary_idx) assert_array_equal(raw.annotations.onset, [124., 125., 134., 135., 144., 145., 154.]) raw.annotations.delete(2) assert_array_equal(raw.annotations.onset, [124., 125., 135., 144., 145., 154.]) raw.annotations.append(5, 1.5, 'y') assert_array_equal(raw.annotations.onset, [124., 125., 135., 144., 145., 154., 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'])
from mne.datasets import eegbci from mne import Epochs, pick_types, events_from_annotations, pick_channels from mne.io import concatenate_raws, read_raw_edf from mne.channels import make_standard_montage from mne.preprocessing import ICA from mne.time_frequency import tfr_multitaper from mne.stats import permutation_cluster_1samp_test as pcluster_test from mne.viz.utils import center_cmap #%% CARICO IL DATABASE subject = 1 runs = [4] #Scarico i dati e mi ritorna il path locale raw_fnames = eegbci.load_data(subject, runs) #Concateno le path e le metto in un unico oggetto raw = concatenate_raws([read_raw_edf(f, preload=True) for f in raw_fnames]) #Standardizzo la posizione degli elettrodi eegbci.standardize(raw) #Seleziono il montaggio montage = make_standard_montage('standard_1005') #Lo setto all'interno di raw raw.set_montage(montage) #Tolgo il punto alla fine raw.rename_channels(lambda x: x.strip('.')) raw.crop(tmax = 60).load_data() #%% VISUALIZZO I DATI RAW raw.plot() #%% FILTRAGGIO #Applico un filtro passa banda raw.filter(1.0, 79.0, fir_design='firwin', skip_by_annotation='edge') #Applico un NotchFilter
def test_multiple_files(): """Test loading multiple files simultaneously """ # split file tempdir = _TempDir() raw = Raw(fif_fname).crop(0, 10, False) raw.load_data() raw.load_data() # test no operation split_size = 3. # in seconds sfreq = raw.info['sfreq'] nsamp = (raw.last_samp - raw.first_samp) tmins = np.round(np.arange(0., nsamp, split_size * sfreq)) tmaxs = np.concatenate((tmins[1:] - 1, [nsamp])) tmaxs /= sfreq tmins /= sfreq assert_equal(raw.n_times, len(raw.times)) # going in reverse order so the last fname is the first file (need later) raws = [None] * len(tmins) for ri in range(len(tmins) - 1, -1, -1): fname = op.join(tempdir, 'test_raw_split-%d_raw.fif' % ri) raw.save(fname, tmin=tmins[ri], tmax=tmaxs[ri]) raws[ri] = Raw(fname) events = [find_events(r, stim_channel='STI 014') for r in raws] last_samps = [r.last_samp for r in raws] first_samps = [r.first_samp for r in raws] # test concatenation of split file assert_raises(ValueError, concatenate_raws, raws, True, events[1:]) all_raw_1, events1 = concatenate_raws(raws, preload=False, events_list=events) assert_equal(raw.first_samp, all_raw_1.first_samp) assert_equal(raw.last_samp, all_raw_1.last_samp) assert_allclose(raw[:, :][0], all_raw_1[:, :][0]) raws[0] = Raw(fname) all_raw_2 = concatenate_raws(raws, preload=True) assert_allclose(raw[:, :][0], all_raw_2[:, :][0]) # test proper event treatment for split files events2 = concatenate_events(events, first_samps, last_samps) events3 = find_events(all_raw_2, stim_channel='STI 014') assert_array_equal(events1, events2) assert_array_equal(events1, events3) # test various methods of combining files raw = Raw(fif_fname, preload=True) n_times = raw.n_times # make sure that all our data match times = list(range(0, 2 * n_times, 999)) # add potentially problematic points times.extend([n_times - 1, n_times, 2 * n_times - 1]) raw_combo0 = Raw([fif_fname, fif_fname], preload=True) _compare_combo(raw, raw_combo0, times, n_times) raw_combo = Raw([fif_fname, fif_fname], preload=False) _compare_combo(raw, raw_combo, times, n_times) raw_combo = Raw([fif_fname, fif_fname], preload='memmap8.dat') _compare_combo(raw, raw_combo, times, n_times) assert_raises(ValueError, Raw, [fif_fname, ctf_fname]) assert_raises(ValueError, Raw, [fif_fname, fif_bad_marked_fname]) assert_equal(raw[:, :][0].shape[1] * 2, raw_combo0[:, :][0].shape[1]) assert_equal(raw_combo0[:, :][0].shape[1], raw_combo0.n_times) # with all data preloaded, result should be preloaded raw_combo = Raw(fif_fname, preload=True) raw_combo.append(Raw(fif_fname, preload=True)) assert_true(raw_combo.preload is True) assert_equal(raw_combo.n_times, raw_combo._data.shape[1]) _compare_combo(raw, raw_combo, times, n_times) # with any data not preloaded, don't set result as preloaded raw_combo = concatenate_raws([Raw(fif_fname, preload=True), Raw(fif_fname, preload=False)]) assert_true(raw_combo.preload is False) assert_array_equal(find_events(raw_combo, stim_channel='STI 014'), find_events(raw_combo0, stim_channel='STI 014')) _compare_combo(raw, raw_combo, times, n_times) # user should be able to force data to be preloaded upon concat raw_combo = concatenate_raws([Raw(fif_fname, preload=False), Raw(fif_fname, preload=True)], preload=True) assert_true(raw_combo.preload is True) _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(fif_fname, preload=False), Raw(fif_fname, preload=True)], preload='memmap3.dat') _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(fif_fname, preload=True), Raw(fif_fname, preload=True)], preload='memmap4.dat') _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(fif_fname, preload=False), Raw(fif_fname, preload=False)], preload='memmap5.dat') _compare_combo(raw, raw_combo, times, n_times) # verify that combining raws with different projectors throws an exception raw.add_proj([], remove_existing=True) assert_raises(ValueError, raw.append, Raw(fif_fname, preload=True)) # now test event treatment for concatenated raw files events = [find_events(raw, stim_channel='STI 014'), find_events(raw, stim_channel='STI 014')] last_samps = [raw.last_samp, raw.last_samp] first_samps = [raw.first_samp, raw.first_samp] events = concatenate_events(events, first_samps, last_samps) events2 = find_events(raw_combo0, stim_channel='STI 014') assert_array_equal(events, events2) # check out the len method assert_equal(len(raw), raw.n_times) assert_equal(len(raw), raw.last_samp - raw.first_samp + 1)
def test_trialwise_decoding(): import mne from mne.io import concatenate_raws # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True) import numpy as np # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 from braindecode.datautil.signal_target import SignalAndTarget train_set = SignalAndTarget(X[:60], y=y[:60]) test_set = SignalAndTarget(X[60:], y=y[60:]) from braindecode.models.shallow_fbcsp import ShallowFBCSPNet from torch import nn from braindecode.torch_ext.util import set_random_seeds # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) n_classes = 2 in_chans = train_set.X.shape[1] # final_conv_length = auto ensures we only get a single output in the time dimension model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], final_conv_length='auto').create_network() if cuda: model.cuda() from torch import optim optimizer = optim.Adam(model.parameters()) from braindecode.torch_ext.util import np_to_var, var_to_np from braindecode.datautil.iterators import get_balanced_batches import torch.nn.functional as F from numpy.random import RandomState rng = RandomState((2017, 6, 30)) losses = [] accuracies = [] for i_epoch in range(6): i_trials_in_batch = get_balanced_batches(len(train_set.X), rng, shuffle=True, batch_size=30) # Set model to training mode model.train() for i_trials in i_trials_in_batch: # Have to add empty fourth dimension to X batch_X = train_set.X[i_trials][:, :, :, None] batch_y = train_set.y[i_trials] net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() # Remove gradients of last backward pass from all parameters optimizer.zero_grad() # Compute outputs of the network outputs = model(net_in) # Compute the loss loss = F.nll_loss(outputs, net_target) # Do the backpropagation loss.backward() # Update parameters with the optimizer optimizer.step() # Print some statistics each epoch model.eval() print("Epoch {:d}".format(i_epoch)) for setname, dataset in (('Train', train_set), ('Test', test_set)): # Here, we will use the entire dataset at once, which is still possible # for such smaller datasets. Otherwise we would have to use batches. net_in = np_to_var(dataset.X[:, :, :, None]) if cuda: net_in = net_in.cuda() net_target = np_to_var(dataset.y) if cuda: net_target = net_target.cuda() outputs = model(net_in) loss = F.nll_loss(outputs, net_target) losses.append(float(var_to_np(loss))) print("{:6s} Loss: {:.5f}".format(setname, float(var_to_np(loss)))) predicted_labels = np.argmax(var_to_np(outputs), axis=1) accuracy = np.mean(dataset.y == predicted_labels) accuracies.append(accuracy * 100) print("{:6s} Accuracy: {:.1f}%".format(setname, accuracy * 100)) np.testing.assert_allclose(np.array(losses), np.array([ 1.1775966882705688, 1.2602351903915405, 0.7068756818771362, 0.9367912411689758, 0.394258975982666, 0.6598362326622009, 0.3359280526638031, 0.656258761882782, 0.2790488004684448, 0.6104397177696228, 0.27319177985191345, 0.5949864983558655 ]), rtol=1e-4, atol=1e-5) np.testing.assert_allclose(np.array(accuracies), np.array([ 51.666666666666671, 53.333333333333336, 63.333333333333329, 56.666666666666664, 86.666666666666671, 66.666666666666657, 90.0, 63.333333333333329, 96.666666666666671, 56.666666666666664, 96.666666666666671, 66.666666666666657 ]), rtol=1e-4, atol=1e-5)
def test_resample(): """Test resample (with I/O and multiple files) """ tempdir = _TempDir() raw = Raw(fif_fname).crop(0, 3, False) raw.load_data() raw_resamp = raw.copy() sfreq = raw.info['sfreq'] # test parallel on upsample raw_resamp.resample(sfreq * 2, n_jobs=2, npad='auto') assert_equal(raw_resamp.n_times, len(raw_resamp.times)) raw_resamp.save(op.join(tempdir, 'raw_resamp-raw.fif')) raw_resamp = Raw(op.join(tempdir, 'raw_resamp-raw.fif'), preload=True) assert_equal(sfreq, raw_resamp.info['sfreq'] / 2) assert_equal(raw.n_times, raw_resamp.n_times / 2) assert_equal(raw_resamp._data.shape[1], raw_resamp.n_times) assert_equal(raw._data.shape[0], raw_resamp._data.shape[0]) # test non-parallel on downsample raw_resamp.resample(sfreq, n_jobs=1, npad='auto') assert_equal(raw_resamp.info['sfreq'], sfreq) assert_equal(raw._data.shape, raw_resamp._data.shape) assert_equal(raw.first_samp, raw_resamp.first_samp) assert_equal(raw.last_samp, raw.last_samp) # upsampling then downsampling doubles resampling error, but this still # works (hooray). Note that the stim channels had to be sub-sampled # without filtering to be accurately preserved # note we have to treat MEG and EEG+STIM channels differently (tols) assert_allclose(raw._data[:306, 200:-200], raw_resamp._data[:306, 200:-200], rtol=1e-2, atol=1e-12) assert_allclose(raw._data[306:, 200:-200], raw_resamp._data[306:, 200:-200], rtol=1e-2, atol=1e-7) # now check multiple file support w/resampling, as order of operations # (concat, resample) should not affect our data raw1 = raw.copy() raw2 = raw.copy() raw3 = raw.copy() raw4 = raw.copy() raw1 = concatenate_raws([raw1, raw2]) raw1.resample(10., npad='auto') raw3.resample(10., npad='auto') raw4.resample(10., npad='auto') raw3 = concatenate_raws([raw3, raw4]) assert_array_equal(raw1._data, raw3._data) assert_array_equal(raw1._first_samps, raw3._first_samps) assert_array_equal(raw1._last_samps, raw3._last_samps) assert_array_equal(raw1._raw_lengths, raw3._raw_lengths) assert_equal(raw1.first_samp, raw3.first_samp) assert_equal(raw1.last_samp, raw3.last_samp) assert_equal(raw1.info['sfreq'], raw3.info['sfreq']) # test resampling of stim channel # basic decimation stim = [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) assert_allclose(raw.resample(8., npad='auto')._data, [[1, 1, 0, 0, 1, 1, 0, 0]]) # decimation of multiple stim channels raw = RawArray(2 * [stim], create_info(2, len(stim), 2 * ['stim'])) assert_allclose(raw.resample(8., npad='auto')._data, [[1, 1, 0, 0, 1, 1, 0, 0], [1, 1, 0, 0, 1, 1, 0, 0]]) # decimation that could potentially drop events if the decimation is # done naively stim = [0, 0, 0, 1, 1, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) assert_allclose(raw.resample(4., npad='auto')._data, [[0, 1, 1, 0]]) # two events are merged in this case (warning) stim = [0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') raw.resample(8., npad='auto') assert_true(len(w) == 1) # events are dropped in this case (warning) stim = [0, 1, 1, 0, 0, 1, 1, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') raw.resample(4., npad='auto') assert_true(len(w) == 1) # test resampling events: this should no longer give a warning stim = [0, 1, 1, 0, 0, 1, 1, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) events = find_events(raw) raw, events = raw.resample(4., events=events, npad='auto') assert_equal(events, np.array([[0, 0, 1], [2, 0, 1]])) # test copy flag stim = [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0] raw = RawArray([stim], create_info(1, len(stim), ['stim'])) raw_resampled = raw.resample(4., npad='auto', copy=True) assert_true(raw_resampled is not raw) raw_resampled = raw.resample(4., npad='auto', copy=False) assert_true(raw_resampled is raw) # resample should still work even when no stim channel is present raw = RawArray(np.random.randn(1, 100), create_info(1, 100, ['eeg'])) raw.info['lowpass'] = 50. raw.resample(10, npad='auto') assert_equal(raw.info['lowpass'], 5.) assert_equal(len(raw), 10)
def test_multiple_files(): """Test loading multiple files simultaneously """ # split file tempdir = _TempDir() raw = Raw(fif_fname).crop(0, 10, copy=False) raw.load_data() raw.load_data() # test no operation split_size = 3. # in seconds sfreq = raw.info['sfreq'] nsamp = (raw.last_samp - raw.first_samp) tmins = np.round(np.arange(0., nsamp, split_size * sfreq)) tmaxs = np.concatenate((tmins[1:] - 1, [nsamp])) tmaxs /= sfreq tmins /= sfreq assert_equal(raw.n_times, len(raw.times)) # going in reverse order so the last fname is the first file (need later) raws = [None] * len(tmins) for ri in range(len(tmins) - 1, -1, -1): fname = op.join(tempdir, 'test_raw_split-%d_raw.fif' % ri) raw.save(fname, tmin=tmins[ri], tmax=tmaxs[ri]) raws[ri] = Raw(fname) assert_equal(len(raws[ri].times), int(round((tmaxs[ri] - tmins[ri]) * raw.info['sfreq'])) + 1) # + 1 b/c inclusive events = [find_events(r, stim_channel='STI 014') for r in raws] last_samps = [r.last_samp for r in raws] first_samps = [r.first_samp for r in raws] # test concatenation of split file assert_raises(ValueError, concatenate_raws, raws, True, events[1:]) all_raw_1, events1 = concatenate_raws(raws, preload=False, events_list=events) assert_allclose(all_raw_1.times, raw.times) assert_equal(raw.first_samp, all_raw_1.first_samp) assert_equal(raw.last_samp, all_raw_1.last_samp) assert_allclose(raw[:, :][0], all_raw_1[:, :][0]) raws[0] = Raw(fname) all_raw_2 = concatenate_raws(raws, preload=True) assert_allclose(raw[:, :][0], all_raw_2[:, :][0]) # test proper event treatment for split files events2 = concatenate_events(events, first_samps, last_samps) events3 = find_events(all_raw_2, stim_channel='STI 014') assert_array_equal(events1, events2) assert_array_equal(events1, events3) # test various methods of combining files raw = Raw(fif_fname, preload=True) n_times = raw.n_times # make sure that all our data match times = list(range(0, 2 * n_times, 999)) # add potentially problematic points times.extend([n_times - 1, n_times, 2 * n_times - 1]) raw_combo0 = concatenate_raws([Raw(f) for f in [fif_fname, fif_fname]], preload=True) _compare_combo(raw, raw_combo0, times, n_times) raw_combo = concatenate_raws([Raw(f) for f in [fif_fname, fif_fname]], preload=False) _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(f) for f in [fif_fname, fif_fname]], preload='memmap8.dat') _compare_combo(raw, raw_combo, times, n_times) with warnings.catch_warnings(record=True): # deprecated assert_raises(ValueError, Raw, [fif_fname, ctf_fname]) assert_raises(ValueError, Raw, [fif_fname, fif_bad_marked_fname]) assert_equal(raw[:, :][0].shape[1] * 2, raw_combo0[:, :][0].shape[1]) assert_equal(raw_combo0[:, :][0].shape[1], raw_combo0.n_times) # with all data preloaded, result should be preloaded raw_combo = Raw(fif_fname, preload=True) raw_combo.append(Raw(fif_fname, preload=True)) assert_true(raw_combo.preload is True) assert_equal(raw_combo.n_times, raw_combo._data.shape[1]) _compare_combo(raw, raw_combo, times, n_times) # with any data not preloaded, don't set result as preloaded raw_combo = concatenate_raws([Raw(fif_fname, preload=True), Raw(fif_fname, preload=False)]) assert_true(raw_combo.preload is False) assert_array_equal(find_events(raw_combo, stim_channel='STI 014'), find_events(raw_combo0, stim_channel='STI 014')) _compare_combo(raw, raw_combo, times, n_times) # user should be able to force data to be preloaded upon concat raw_combo = concatenate_raws([Raw(fif_fname, preload=False), Raw(fif_fname, preload=True)], preload=True) assert_true(raw_combo.preload is True) _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(fif_fname, preload=False), Raw(fif_fname, preload=True)], preload='memmap3.dat') _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(fif_fname, preload=True), Raw(fif_fname, preload=True)], preload='memmap4.dat') _compare_combo(raw, raw_combo, times, n_times) raw_combo = concatenate_raws([Raw(fif_fname, preload=False), Raw(fif_fname, preload=False)], preload='memmap5.dat') _compare_combo(raw, raw_combo, times, n_times) # verify that combining raws with different projectors throws an exception raw.add_proj([], remove_existing=True) assert_raises(ValueError, raw.append, Raw(fif_fname, preload=True)) # now test event treatment for concatenated raw files events = [find_events(raw, stim_channel='STI 014'), find_events(raw, stim_channel='STI 014')] last_samps = [raw.last_samp, raw.last_samp] first_samps = [raw.first_samp, raw.first_samp] events = concatenate_events(events, first_samps, last_samps) events2 = find_events(raw_combo0, stim_channel='STI 014') assert_array_equal(events, events2) # check out the len method assert_equal(len(raw), raw.n_times) assert_equal(len(raw), raw.last_samp - raw.first_samp + 1)
from pyriemann.stats import PermutationTest from pyriemann.estimation import Covariances ############################################################################### ## Set parameters and read data # avoid classification of evoked responses by using epochs that start 1s after # cue onset. tmin, tmax = 1., 3. event_id = dict(hands=2, feet=3) subject = 1 runs = [6, 10, 14] # motor imagery: hands vs feet raw_files = [read_raw_edf(f, preload=True,verbose=False) for f in eegbci.load_data(subject, runs) ] raw = concatenate_raws(raw_files) # strip channel names raw.info['ch_names'] = [chn.strip('.') for chn in raw.info['ch_names']] # Apply band-pass filter raw.filter(7., 35., method='iir') events = find_events(raw, shortest_event=0, stim_channel='STI 014') picks = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Read epochs (train will be done only between 1 and 2s) # Testing will be done with a running classifier epochs = Epochs(raw, events, event_id, tmin, tmax, proj=True, picks=picks, baseline=None, preload=True, add_eeg_ref=False,verbose=False)
def culc_by_csp_and_lda(subject, runs=[6, 10, 14], event_id=dict(hands=2, feet=3)): tmin, tmax = -1., 4. raw_fnames = eegbci.load_data(subject, runs) raw_files = [ read_raw_edf(f, preload=True, stim_channel='auto') for f in raw_fnames ] raw = concatenate_raws(raw_files) # strip channel names of "." characters raw.rename_channels(lambda x: x.strip('.')) # Apply band-pass filter raw.filter(7., 30., fir_design='firwin', skip_by_annotation='edge') events = find_events(raw, shortest_event=0, stim_channel='STI 014') picks = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Read epochs (train will be done only between 1 and 2s) # Testing will be done with a running classifier epochs = Epochs(raw, events, event_id, tmin, tmax, proj=True, picks=picks, baseline=None, preload=True) epochs_train = epochs.copy().crop(tmin=1., tmax=2.) labels = epochs.events[:, -1] - 2 # -----------------------LDAによる分類---------------------------- # モンテカルロ相互検証ジェネレータを定義する(分散を減らす): scores = [] epochs_data = epochs.get_data() epochs_data_train = epochs_train.get_data() cv = KFold(n_splits=5) # cv = ShuffleSplit(10, test_size=0.2, random_state=42) lda = sklearn.discriminant_analysis.LinearDiscriminantAnalysis() # lda = svm.SVC() csp = mne.decoding.CSP(n_components=4, reg=None, log=True, norm_trace=False) clf = sklearn.pipeline.Pipeline([('CSP', csp), ('SVM', lda)]) scores = cross_val_score(clf, epochs_data_train, labels, cv=cv, n_jobs=1) class_balance = np.mean(labels == labels[0]) # 0と1のラベルの数の比率 class_balance = max(class_balance, 1. - class_balance) print("Classification accuracy: %f / Chance level: %f" % (np.mean(scores), class_balance)) # # 視覚化のための完全なデータで推定されたCSPパターンのプロット csp.fit_transform(epochs_data, labels) layout = read_layout('EEG1005') csp.plot_patterns(epochs.info, layout=layout, ch_type='eeg', units='Patterns (AU)', size=1.5) # ---------------------------時間の経過とともにパフォーマンスを調べる------------------------------ sfreq = raw.info['sfreq'] # サンプルレート w_length = int(sfreq * 0.5) # running classifier: window length w_step = int(sfreq * 0.1) # running classifier: window step size w_start = np.arange(0, epochs_data.shape[2] - w_length, w_step) scores_windows = [] for train_idx, test_idx in cv.split(epochs_data_train): y_train, y_test = labels[train_idx], labels[test_idx] # ----------- train--------------- X_train = csp.fit_transform(epochs_data_train[train_idx], y_train) lda.fit(X_train, y_train) # ------------test--------------- # running classifier: test classifier on sliding window score_this_window = [] for n in w_start: data = epochs_data[test_idx][:, :, n:(n + w_length)] X_test = csp.transform(data) score_this_window.append(lda.score(X_test, y_test)) scores_windows.append(score_this_window) # Plot scores over time w_times = (w_start + w_length / 2.) / sfreq + epochs.tmin plt.figure() plt.plot(w_times, np.mean(scores_windows, 0), label='Score') plt.axvline(0, linestyle='--', color='k', label='Onset') plt.axhline(0.5, linestyle='-', color='k', label='Chance') plt.xlabel('time (s)') plt.ylabel('classification accuracy') plt.title('Classification score over time') plt.legend(loc='lower right') # plt.savefig(str(path) + "_svm.png") plt.show()