def test_crop_when_negative_orig_time(windows_like_datetime): """Test cropping with orig_time, tmin and tmax previous to 1970.""" # Regression test for gh-6621 orig_time_stamp = -908196945.011331 # 1941-03-22 11:04:14.988669 annot = Annotations(description='foo', onset=np.arange(0, 0.999, 0.1), duration=[0], orig_time=orig_time_stamp) stamp = _dt_to_stamp(annot.orig_time) assert_allclose(stamp[0] + stamp[1] * 1e-6, orig_time_stamp) t = stamp[0] + stamp[1] * 1e-6 assert t == orig_time_stamp assert len(annot) == 10 # do not raise annot.crop(verbose='debug') assert len(annot) == 10 # Crop with negative tmin, tmax tmin, tmax = [orig_time_stamp + t for t in (0.25, .75)] assert tmin < 0 and tmax < 0 crop_annot = annot.crop(tmin=tmin, tmax=tmax) assert_allclose(crop_annot.onset, [0.3, 0.4, 0.5, 0.6, 0.7]) orig_dt = _stamp_to_dt(stamp) assert crop_annot.orig_time == orig_dt # orig_time does not change
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 = raw.info['meas_date'] assert isinstance(dt, datetime) stamp = _dt_to_stamp(dt) # Test time shifts. for orig_time in [None, dt, stamp[0], stamp]: annot = Annotations(onset, duration, description, orig_time) if orig_time is None: assert annot.orig_time is None else: assert isinstance(annot.orig_time, datetime) assert annot.orig_time.tzinfo is timezone.utc 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 = (stamp[0] + stamp[1] * 1e-6 + raw2._first_time) offset = _dt_to_stamp(_handle_meas_date(raw2.info['meas_date'])) offset = offset[0] + offset[1] * 1e-6 offset = orig_time - offset assert_allclose(offset, raw._first_time) annot = Annotations(onset, duration, description, orig_time) assert annot.orig_time is not None assert ' segments' in repr(annot) raw2.set_annotations(annot) assert_allclose(raw2.annotations.onset, onset + offset) assert raw2.annotations is not annot assert raw2.annotations.orig_time is not None 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_plot_raw_meas_date(raw, browser_backend): """Test effect of mismatched meas_date in raw.plot().""" raw.set_meas_date(_dt_to_stamp(raw.info['meas_date'])[0]) annot = Annotations([1 + raw.first_samp / raw.info['sfreq']], [5], ['bad']) with pytest.warns(RuntimeWarning, match='outside data range'): raw.set_annotations(annot) with pytest.warns(None): # sometimes projection raw.plot(group_by='position', order=np.arange(8)) fig = raw.plot() for key in ['down', 'up', 'escape']: fig._fake_keypress(key, fig=fig.mne.fig_selection)
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) meas_date = _handle_meas_date(np.pi) info['meas_date'] = meas_date 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) assert_allclose(raws[0].annotations.onset, [124, 125]) raw = RawArray(data.copy(), info) assert not len(raw.annotations) raw.set_annotations(Annotations([1.], [.5], 'x', None)) assert_allclose(raw.annotations.onset, [1.]) raws.append(raw) raw = concatenate_raws(raws, verbose='debug') assert raw.info['meas_date'] == raw.annotations.orig_time == meas_date 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 stamp = _dt_to_stamp(raw.info['meas_date']) orig_time = _handle_meas_date(stamp) for empty_annot in ( Annotations([], [], [], stamp), Annotations([], [], [], 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 == orig_time
def test_plot_raw(): """Test plotting of raw data.""" raw = _get_raw() raw.info['lowpass'] = 10. # allow heavy decim during plotting events = _get_events() plt.close('all') # ensure all are closed assert len(plt.get_fignums()) == 0 fig = raw.plot(events=events, order=[1, 7, 3], group_by='original') assert len(plt.get_fignums()) == 1 # make sure fig._mne_params is present assert isinstance(fig._mne_params, dict) # test mouse clicks x = fig.get_axes()[0].lines[1].get_xdata().mean() y = fig.get_axes()[0].lines[1].get_ydata().mean() data_ax = fig.axes[0] _fake_click(fig, data_ax, [x, y], xform='data') # mark a bad channel _fake_click(fig, data_ax, [x, y], xform='data') # unmark a bad channel _fake_click(fig, data_ax, [0.5, 0.999]) # click elsewhere in 1st axes _fake_click(fig, data_ax, [-0.1, 0.9]) # click on y-label _fake_click(fig, fig.get_axes()[1], [0.5, 0.5]) # change time _fake_click(fig, fig.get_axes()[2], [0.5, 0.5]) # change channels assert len(plt.get_fignums()) == 1 # open SSP window _fake_click(fig, fig.get_axes()[-1], [0.5, 0.5]) _fake_click(fig, fig.get_axes()[-1], [0.5, 0.5], kind='release') assert len(plt.get_fignums()) == 2 ssp_fig = plt.figure(plt.get_fignums()[-1]) fig.canvas.button_press_event(1, 1, 1) # outside any axes fig.canvas.scroll_event(0.5, 0.5, -0.5) # scroll down fig.canvas.scroll_event(0.5, 0.5, 0.5) # scroll up ax = ssp_fig.get_axes()[0] # only one axis is used assert _proj_status(ax) == [True] * 3 t = [c for c in ax.get_children() if isinstance(c, matplotlib.text.Text)] pos = np.array(t[0].get_position()) + 0.01 _fake_click(ssp_fig, ssp_fig.get_axes()[0], pos, xform='data') # off assert _proj_status(ax) == [False, True, True] _fake_click(ssp_fig, ssp_fig.get_axes()[0], pos, xform='data') # on assert _proj_status(ax) == [True] * 3 _fake_click(ssp_fig, ssp_fig.get_axes()[1], [0.5, 0.5]) # all off _fake_click(ssp_fig, ssp_fig.get_axes()[1], [0.5, 0.5], kind='release') assert _proj_status(ax) == [False] * 3 assert fig._mne_params['projector'] is None # actually off _fake_click(ssp_fig, ssp_fig.get_axes()[1], [0.5, 0.5]) # all on _fake_click(ssp_fig, ssp_fig.get_axes()[1], [0.5, 0.5], kind='release') assert fig._mne_params['projector'] is not None # on assert _proj_status(ax) == [True] * 3 # test keypresses # test for group_by='original' for key in [ 'down', 'up', 'right', 'left', 'o', '-', '+', '=', 'd', 'd', 'pageup', 'pagedown', 'home', 'end', '?', 'f11', 'z', 'escape' ]: fig.canvas.key_press_event(key) # test for group_by='selection' fig = plot_raw(raw, events=events, group_by='selection') for key in [ 'b', 'down', 'up', 'right', 'left', 'o', '-', '+', '=', 'd', 'd', 'pageup', 'pagedown', 'home', 'end', '?', 'f11', 'b', 'z', 'escape' ]: fig.canvas.key_press_event(key) # test zen mode fig = plot_raw(raw, show_scrollbars=False) # Color setting pytest.raises(KeyError, raw.plot, event_color={0: 'r'}) pytest.raises(TypeError, raw.plot, event_color={'foo': 'r'}) annot = Annotations([10, 10 + raw.first_samp / raw.info['sfreq']], [10, 10], ['test', 'test'], raw.info['meas_date']) with pytest.warns(RuntimeWarning, match='outside data range'): raw.set_annotations(annot) fig = plot_raw(raw, events=events, event_color={-1: 'r', 998: 'b'}) plt.close('all') for group_by, order in zip( ['position', 'selection'], [np.arange(len(raw.ch_names))[::-3], [1, 2, 4, 6]]): with pytest.warns(None): # sometimes projection fig = raw.plot(group_by=group_by, order=order) x = fig.get_axes()[0].lines[1].get_xdata()[10] y = fig.get_axes()[0].lines[1].get_ydata()[10] with pytest.warns(None): # old mpl (at least 2.0) can warn _fake_click(fig, data_ax, [x, y], xform='data') # mark bad fig.canvas.key_press_event('down') # change selection _fake_click(fig, fig.get_axes()[2], [0.5, 0.5]) # change channels sel_fig = plt.figure(1) topo_ax = sel_fig.axes[1] _fake_click(sel_fig, topo_ax, [-0.425, 0.20223853], xform='data') fig.canvas.key_press_event('down') fig.canvas.key_press_event('up') fig.canvas.scroll_event(0.5, 0.5, -1) # scroll down fig.canvas.scroll_event(0.5, 0.5, 1) # scroll up _fake_click(sel_fig, topo_ax, [-0.5, 0.], xform='data') _fake_click(sel_fig, topo_ax, [0.5, 0.], xform='data', kind='motion') _fake_click(sel_fig, topo_ax, [0.5, 0.5], xform='data', kind='motion') _fake_click(sel_fig, topo_ax, [-0.5, 0.5], xform='data', kind='release') plt.close('all') # test if meas_date is off raw.set_meas_date(_dt_to_stamp(raw.info['meas_date'])[0]) annot = Annotations([1 + raw.first_samp / raw.info['sfreq']], [5], ['bad']) with pytest.warns(RuntimeWarning, match='outside data range'): raw.set_annotations(annot) with pytest.warns(None): # sometimes projection raw.plot(group_by='position', order=np.arange(8)) for fig_num in plt.get_fignums(): fig = plt.figure(fig_num) if hasattr(fig, 'radio'): # Get access to selection fig. break for key in ['down', 'up', 'escape']: fig.canvas.key_press_event(key) raw._data[:] = np.nan # this should (at least) not die, the output should pretty clearly show # that there is a problem so probably okay to just plot something blank with pytest.warns(None): raw.plot(scalings='auto') plt.close('all')
def test_plot_raw_traces(raw): """Test plotting of raw data.""" raw.info['lowpass'] = 10. # allow heavy decim during plotting events = _get_events() plt.close('all') # ensure all are closed fig = raw.plot(events=events, order=[1, 7, 5, 2, 3], n_channels=3, group_by='original') assert hasattr(fig, 'mne') # make sure fig.mne param object is present assert len(fig.axes) == 5 # setup x = fig.mne.traces[0].get_xdata()[5] y = fig.mne.traces[0].get_ydata()[5] data_ax = fig.mne.ax_main hscroll = fig.mne.ax_hscroll vscroll = fig.mne.ax_vscroll # test marking bad channels label = fig.mne.ax_main.get_yticklabels()[0].get_text() assert label not in fig.mne.info['bads'] _fake_click(fig, data_ax, [x, y], xform='data') # click data to mark bad assert label in fig.mne.info['bads'] _fake_click(fig, data_ax, [x, y], xform='data') # click data to unmark bad assert label not in fig.mne.info['bads'] _click_ch_name(fig, ch_index=0, button=1) # click name to mark bad assert label in fig.mne.info['bads'] # test other kinds of clicks _fake_click(fig, data_ax, [0.5, 0.999]) # click elsewhere (add vline) _fake_click(fig, data_ax, [0.5, 0.999], button=3) # remove vline _fake_click(fig, hscroll, [0.5, 0.5]) # change time _fake_click(fig, hscroll, [0.5, 0.5]) # shouldn't change time this time # test scrolling through channels labels = [label.get_text() for label in data_ax.get_yticklabels()] assert labels == [raw.ch_names[1], raw.ch_names[7], raw.ch_names[5]] _fake_click(fig, vscroll, [0.5, 0.01]) # change channels to end labels = [label.get_text() for label in data_ax.get_yticklabels()] assert labels == [raw.ch_names[5], raw.ch_names[2], raw.ch_names[3]] for _ in (0, 0): # first click changes channels to mid; second time shouldn't change _fake_click(fig, vscroll, [0.5, 0.5]) labels = [label.get_text() for label in data_ax.get_yticklabels()] assert labels == [raw.ch_names[7], raw.ch_names[5], raw.ch_names[2]] assert len(plt.get_fignums()) == 1 # test clicking a channel name in butterfly mode bads = fig.mne.info['bads'].copy() fig.canvas.key_press_event('b') _click_ch_name(fig, ch_index=0, button=1) # should be no-op assert fig.mne.info['bads'] == bads # unchanged fig.canvas.key_press_event('b') # test starting up in zen mode fig = plot_raw(raw, show_scrollbars=False) # test order, title, & show_options kwargs with pytest.raises(ValueError, match='order should be array-like; got'): raw.plot(order='foo') with pytest.raises(TypeError, match='title must be None or a string, got'): raw.plot(title=1) raw.plot(show_options=True) plt.close('all') # Color setting with pytest.raises(KeyError, match='must be strictly positive, or -1'): raw.plot(event_color={0: 'r'}) with pytest.raises(TypeError, match='event_color key must be an int, got'): raw.plot(event_color={'foo': 'r'}) annot = Annotations([10, 10 + raw.first_samp / raw.info['sfreq']], [10, 10], ['test', 'test'], raw.info['meas_date']) with pytest.warns(RuntimeWarning, match='outside data range'): raw.set_annotations(annot) fig = plot_raw(raw, events=events, event_color={-1: 'r', 998: 'b'}) plt.close('all') for group_by, order in zip(['position', 'selection'], [np.arange(len(raw.ch_names))[::-3], [1, 2, 4, 6]]): fig = raw.plot(group_by=group_by, order=order) x = fig.get_axes()[0].lines[1].get_xdata()[10] y = fig.get_axes()[0].lines[1].get_ydata()[10] _fake_click(fig, data_ax, [x, y], xform='data') # mark bad fig.canvas.key_press_event('down') # change selection _fake_click(fig, fig.get_axes()[2], [0.5, 0.5]) # change channels sel_fig = plt.figure(1) topo_ax = sel_fig.axes[1] _fake_click(sel_fig, topo_ax, [-0.425, 0.20223853], xform='data') fig.canvas.key_press_event('down') fig.canvas.key_press_event('up') fig.canvas.scroll_event(0.5, 0.5, -1) # scroll down fig.canvas.scroll_event(0.5, 0.5, 1) # scroll up _fake_click(sel_fig, topo_ax, [-0.5, 0.], xform='data') _fake_click(sel_fig, topo_ax, [0.5, 0.], xform='data', kind='motion') _fake_click(sel_fig, topo_ax, [0.5, 0.5], xform='data', kind='motion') _fake_click(sel_fig, topo_ax, [-0.5, 0.5], xform='data', kind='release') plt.close('all') # test if meas_date is off raw.set_meas_date(_dt_to_stamp(raw.info['meas_date'])[0]) annot = Annotations([1 + raw.first_samp / raw.info['sfreq']], [5], ['bad']) with pytest.warns(RuntimeWarning, match='outside data range'): raw.set_annotations(annot) with pytest.warns(None): # sometimes projection raw.plot(group_by='position', order=np.arange(8)) for fig_num in plt.get_fignums(): fig = plt.figure(fig_num) if hasattr(fig, 'radio'): # Get access to selection fig. break for key in ['down', 'up', 'escape']: fig.canvas.key_press_event(key) raw._data[:] = np.nan # this should (at least) not die, the output should pretty clearly show # that there is a problem so probably okay to just plot something blank with pytest.warns(None): raw.plot(scalings='auto') plt.close('all')