def test_plotting(): """Test that the plots show properly.""" out_dir = _TempDir() fname, behf, corrupted = make_raw(out_dir) raw = _read_raw(fname, preload=True) pd = raw._data[0] candidates = _find_pd_candidates(pd, max_len=max_len, baseline=baseline, zscore=zscore, max_flip_i=max_flip_i, sfreq=raw.info['sfreq'])[0] beh = _read_tsv(behf) beh_events = np.array(beh['fix_onset_time']) * raw.info['sfreq'] beh_events_adjusted, alignment, events = _find_best_alignment( beh_events, candidates, exclude_shift, resync, raw.info['sfreq'], verbose=False) errors = beh_events_adjusted - events + alignment _plot_trial_errors(beh_events_adjusted, alignment, events, errors, exclude_shift, raw.info['sfreq']) errors[abs(errors) / raw.info['sfreq'] > 2 * exclude_shift] = np.nan np.testing.assert_array_almost_equal(plt.gca().lines[0].get_ydata(), errors) section_data = [(0, 'test', np.random.random(10))] _plot_excluded_events(section_data, 2) assert plt.gca().title.get_text() == 'test' np.testing.assert_array_equal(plt.gca().lines[0].get_ydata(), section_data[0][2])
def test_two_pd_alignment(): """Test spliting photodiode events into two and adding.""" out_dir = _TempDir() raw, _, events, _ = pd_parser.simulate_pd_data(prop_corrupted=0.) fname = op.join(out_dir, 'test-raw.fif') raw.save(fname) events2 = events[::2] events3 = events[1:][::2] # make behavior data np.random.seed(12) beh_events2 = events2[:, 0].astype(float) / raw.info['sfreq'] offsets2 = np.random.random(len(beh_events2)) * 0.05 - 0.025 beh_events2 += offsets2 # make next one beh_events3 = events3[:, 0].astype(float) / raw.info['sfreq'] offsets3 = np.random.random(len(beh_events3)) * 0.05 - 0.025 beh_events3 += offsets3 n_na = abs(len(beh_events2) - len(beh_events3)) if len(beh_events2) > len(beh_events3): beh_events3 = list(beh_events3) + ['n/a'] * n_na elif len(beh_events3) > len(beh_events2): beh_events2 = list(beh_events2) + ['n/a'] * n_na beh = dict(trial=np.arange(len(beh_events2)), fix_onset_time=beh_events2, response_onset_time=beh_events3) behf = op.join(out_dir, 'behf-test.tsv') _to_tsv(behf, beh) pd_parser.parse_pd(fname, pd_event_name='Fixation', beh=beh, pd_ch_names=['pd'], beh_key='fix_onset_time', zscore=20, exclude_shift=0.05) pd_parser.parse_pd(fname, pd_event_name='Response', beh=beh, pd_ch_names=['pd'], beh_key='response_onset_time', zscore=20, add_events=True, exclude_shift=0.05) raw = _read_raw(fname) annot, pd_ch_names, beh2 = _load_data(raw) raw.set_annotations(annot) events4, event_id = mne.events_from_annotations(raw) np.testing.assert_array_equal(events4[events4[:, 2] == 1, 0], events2[:, 0]) np.testing.assert_array_equal(events4[events4[:, 2] == 2, 0], events3[:, 0]) assert pd_ch_names == ['pd'] np.testing.assert_array_equal(beh2['pd_parser_sample'], events2[:, 0])
def test_parse_audio(): out_dir = _TempDir() max_len = 0.25 zscore = 10 audio_fname = op.join(basepath, 'test_video.wav') fs, data = wavfile.read(audio_fname) data = data.mean(axis=1) # stereo audio but only need one source info = mne.create_info(['audio'], fs, ['stim']) raw = mne.io.RawArray(data[np.newaxis], info) fname = op.join(out_dir, 'test_video-raw.fif') raw.save(fname, overwrite=True) raw = _read_raw(fname, preload=True) audio = raw._data[0] candidates = _find_audio_candidates(audio=audio, sfreq=raw.info['sfreq'], max_len=max_len, zscore=zscore, verbose=verbose) np.testing.assert_array_equal( candidates, np.array([ 914454, 1915824, 2210042, 2970516, 4010037, 5011899, 6051706, 7082591, 7651608, 8093410, 9099765, 10145123, 12010012, 13040741, 14022720, 15038656, 16021487 ])) behf = op.join(basepath, 'test_video_beh.tsv') pd_parser.parse_audio(raw, beh=behf, audio_ch_names=['audio'], zscore=10) annot, audio_ch_names, beh = _load_data(raw) np.testing.assert_array_almost_equal( annot.onset, np.array([ 19.05112457, 39.9129982, 61.88574982, 83.54243469, 104.41456604, 126.07720947, 147.5539856, 168.61270142, 189.57843018, 211.35673523, 250.20858765, 271.68209839, 292.14001465, 313.30532837, 333.78097534 ])) assert audio_ch_names == ['audio'] assert beh['pd_parser_sample'] == \ [914454, 1915824, 2970516, 4010037, 5011899, 6051706, 7082591, 8093410, 9099765, 10145123, 12010012, 13040741, 14022720, 15038656, 16021487] # test cli if platform.system() != 'Windows': assert call([ f'parse_audio {fname} --beh {behf} ' '--audio_ch_names audio --zscore 10 -o' ], shell=True, env=os.environ) == 0
# make fake electrophysiology data info = mne.create_info(['ch1', 'ch2', 'ch3'], raw.info['sfreq'], ['seeg'] * 3) raw2 = mne.io.RawArray(np.random.random((3, raw.times.size)) * 1e-6, info) raw2.info['lowpass'] = raw.info['lowpass'] # these must match to combine raw.add_channels([raw2]) # bids needs these data fields raw.info['dig'] = None raw.info['line_freq'] = 60 fname = op.join(out_dir, 'sub-1_task-mytask_raw.fif') raw.save(fname) # roundtrip so that raw is properly loaded from disk and has a filename raw = _read_raw(fname) ############################################################################### # Make behavior data # # We'll make a dictionary with lists for the events that are time-stamped when # the photodiode was turned on and other events relative to those events. # We'll add some noise to the time-stamps so that we can see how behavior # might look in an experimental setting. # Let's make a task where there is a fixation stimulus, then a go cue, # and a then response as an example. np.random.seed(12) # add some noise to make it harder to align, use just over # the exclusion of 0.03 to make some events excluded offsets = np.random.random(n_events) * 0.035 - 0.0125
def test_inputs(): """Test that inputs for functions raise necessary errors.""" out_dir = _TempDir() # test tsv beh = dict(test=[1, 2], test2=[2, 1]) _to_tsv(op.join(out_dir, 'test.tsv'), beh) assert beh == _read_tsv(op.join(out_dir, 'test.tsv')) with pytest.raises(ValueError, match='Unable to read'): _read_tsv('test.foo') with pytest.raises(ValueError, match='Error in reading tsv'): with open(op.join(out_dir, 'test.tsv'), 'w') as _: pass _read_tsv(op.join(out_dir, 'test.tsv')) with pytest.raises(ValueError, match='contains no data'): with open(op.join(out_dir, 'test.tsv'), 'w') as f: f.write('test') _read_tsv(op.join(out_dir, 'test.tsv')) with pytest.raises(ValueError, match='different lengths'): with open(op.join(out_dir, 'test.tsv'), 'w') as f: f.write('test\ttest2\n1\t1\n1') _read_tsv(op.join(out_dir, 'test.tsv')) with pytest.raises(ValueError, match='Empty data file, no keys'): _to_tsv(op.join(out_dir, 'test.tsv'), dict()) with pytest.raises(ValueError, match='Unable to write'): _to_tsv('foo.bar', dict(test=1)) # test read raw, beh, events, corrupted_indices = pd_parser.simulate_pd_data() with pytest.raises(ValueError, match='must be loaded from disk'): _read_raw(raw, preload=True) raw.save(op.join(out_dir, 'test-raw.fif'), overwrite=True) with pytest.raises(ValueError, match='not recognized'): _read_raw('foo.bar') raw2 = _read_raw(op.join(out_dir, 'test-raw.fif'), preload=True) np.testing.assert_array_almost_equal(raw._data, raw2._data, decimal=3) # test load beh with pytest.raises(ValueError, match='not in the columns'): _load_beh(op.join(basepath, 'pd_events.tsv'), 'foo') # test get pd data with pytest.raises(ValueError, match='in raw channel names'): _get_data(raw, ['foo']) with pytest.raises(ValueError, match='in raw channel names'): _get_channel_data(raw, ['foo']) with pytest.raises(ValueError, match='baseline must be between 0 and 1'): pd_parser.parse_pd(raw, beh=beh, baseline=2) with pytest.raises(FileNotFoundError, match='fname does not exist'): _load_data('bar/foo.fif') with pytest.raises(ValueError, match='pd-parser data not found'): raw.save(op.join(out_dir, 'foo.fif')) _load_data(op.join(out_dir, 'foo.fif')) # test i/o raw3 = _read_raw(op.join(out_dir, 'test-raw.fif')) _save_data(raw3, events=np.arange(10), event_id='Fixation', ch_names=['pd'], beh=beh, add_events=False) with pytest.raises(ValueError, match='`pd_parser_sample` is not allowed'): _save_data(raw3, events=events, event_id='Fixation', ch_names=['pd'], beh=beh, add_events=False) annot, pd_ch_names, beh2 = _load_data(raw3) raw.set_annotations(annot) events2, event_id = mne.events_from_annotations(raw) np.testing.assert_array_equal(events2[:, 0], np.arange(10)) assert event_id == {'Fixation': 1} assert pd_ch_names == ['pd'] np.testing.assert_array_equal(beh2['time'], beh['time']) np.testing.assert_array_equal(beh2['pd_parser_sample'], np.arange(10)) # check overwrite behf = op.join(out_dir, 'behf-test.tsv') _to_tsv(behf, beh) with pytest.raises(ValueError, match='directory already exists'): pd_parser.parse_pd(raw3, beh=behf) pd_parser.parse_pd(raw3, beh=None, pd_ch_names=['pd'], overwrite=True) annot, pd_ch_names, beh = _load_data(raw3) raw3.set_annotations(annot) events2, _ = mne.events_from_annotations(raw3) assert all([event in events2[:, 0] for event in events[:, 0]]) assert pd_ch_names == ['pd'] assert beh is None # test overwrite raw = _read_raw(op.join(out_dir, 'test-raw.fif')) with pytest.raises(ValueError, match='data directory already exists'): _check_overwrite(raw, add_events=False, overwrite=False)