示例#1
0
def test_double_export_edf(tmp_path):
    """Test exporting an EDF file multiple times."""
    rng = np.random.RandomState(123456)
    format = 'edf'
    ch_types = [
        'eeg', 'eeg', 'stim', 'ecog', 'ecog', 'seeg', 'eog', 'ecg', 'emg',
        'dbs', 'bio'
    ]
    ch_names = np.arange(len(ch_types)).astype(str).tolist()
    info = create_info(ch_names, sfreq=1000, ch_types=ch_types)
    data = rng.random(size=(len(ch_names), 1000)) * 1.e-5

    # include subject info and measurement date
    subject_info = dict(first_name='mne',
                        last_name='python',
                        birthday=(1992, 1, 20),
                        sex=1,
                        hand=3)
    info['subject_info'] = subject_info
    raw = RawArray(data, info)

    # export once
    temp_fname = op.join(str(tmp_path), f'test.{format}')
    raw.export(temp_fname, add_ch_type=True)
    raw_read = read_raw_edf(temp_fname, preload=True)

    # export again
    raw_read.load_data()
    raw_read.export(temp_fname, add_ch_type=True)
    raw_read = read_raw_edf(temp_fname, preload=True)

    # stim channel should be dropped
    raw.drop_channels('2')

    assert raw.ch_names == raw_read.ch_names
    # only compare the original length, since extra zeros are appended
    orig_raw_len = len(raw)
    assert_array_almost_equal(raw.get_data(),
                              raw_read.get_data()[:, :orig_raw_len],
                              decimal=4)
    assert_allclose(raw.times,
                    raw_read.times[:orig_raw_len],
                    rtol=0,
                    atol=1e-5)

    # check channel types except for 'bio', which loses its type
    orig_ch_types = raw.get_channel_types()
    read_ch_types = raw_read.get_channel_types()
    assert_array_equal(orig_ch_types, read_ch_types)
示例#2
0
def test_integer_sfreq_edf(tmp_path):
    """Test saving a Raw array with integer sfreq to EDF."""
    np.random.RandomState(12345)
    format = 'edf'
    info = create_info(['1', '2', '3'], sfreq=1000,
                       ch_types=['eeg', 'eeg', 'stim'])
    data = np.random.random(size=(3, 1000)) * 1e-6

    # include subject info and measurement date
    subject_info = dict(first_name='mne', last_name='python',
                        birthday=(1992, 1, 20), sex=1, hand=3)
    info['subject_info'] = subject_info
    raw = RawArray(data, info)
    raw.set_meas_date(datetime.now(tz=timezone.utc))

    temp_fname = op.join(str(tmp_path), f'test.{format}')

    raw.export(temp_fname)
    raw_read = read_raw_edf(temp_fname, preload=True)

    # stim channel should be dropped
    raw.drop_channels('3')

    assert raw.ch_names == raw_read.ch_names
    # only compare the original length, since extra zeros are appended
    orig_raw_len = len(raw)
    assert_array_almost_equal(
        raw.get_data(), raw_read.get_data()[:, :orig_raw_len], decimal=4)
    assert_allclose(
        raw.times, raw_read.times[:orig_raw_len], rtol=0, atol=1e-5)

    # export now by hard-coding physical range
    raw.export(temp_fname, physical_range=(-3200, 3200))

    # include bad birthday that is non-EDF compliant
    bad_info = info.copy()
    bad_info['subject_info']['birthday'] = (1700, 1, 20)
    raw = RawArray(data, bad_info)
    with pytest.raises(RuntimeError, match='Setting patient birth date'):
        raw.export(temp_fname)

    # include bad measurement date that is non-EDF compliant
    raw = RawArray(data, info)
    meas_date = datetime(year=1984, month=1, day=1, tzinfo=timezone.utc)
    raw.set_meas_date(meas_date)
    with pytest.raises(RuntimeError, match='Setting start date time'):
        raw.export(temp_fname)
示例#3
0
def test_rawarray_edf(tmp_path):
    """Test saving a Raw array with integer sfreq to EDF."""
    rng = np.random.RandomState(12345)
    format = 'edf'
    ch_types = [
        'eeg', 'eeg', 'stim', 'ecog', 'seeg', 'eog', 'ecg', 'emg', 'dbs', 'bio'
    ]
    ch_names = np.arange(len(ch_types)).astype(str).tolist()
    info = create_info(ch_names, sfreq=1000, ch_types=ch_types)
    data = rng.random(size=(len(ch_names), 1000)) * 1e-5

    # include subject info and measurement date
    subject_info = dict(first_name='mne',
                        last_name='python',
                        birthday=(1992, 1, 20),
                        sex=1,
                        hand=3)
    info['subject_info'] = subject_info
    raw = RawArray(data, info)
    time_now = datetime.now()
    meas_date = datetime(year=time_now.year,
                         month=time_now.month,
                         day=time_now.day,
                         hour=time_now.hour,
                         minute=time_now.minute,
                         second=time_now.second,
                         tzinfo=timezone.utc)
    raw.set_meas_date(meas_date)
    temp_fname = op.join(str(tmp_path), f'test.{format}')

    raw.export(temp_fname, add_ch_type=True)
    raw_read = read_raw_edf(temp_fname, preload=True)

    # stim channel should be dropped
    raw.drop_channels('2')

    assert raw.ch_names == raw_read.ch_names
    # only compare the original length, since extra zeros are appended
    orig_raw_len = len(raw)
    assert_array_almost_equal(raw.get_data(),
                              raw_read.get_data()[:, :orig_raw_len],
                              decimal=4)
    assert_allclose(raw.times,
                    raw_read.times[:orig_raw_len],
                    rtol=0,
                    atol=1e-5)

    # check channel types except for 'bio', which loses its type
    orig_ch_types = raw.get_channel_types()
    read_ch_types = raw_read.get_channel_types()
    assert_array_equal(orig_ch_types, read_ch_types)
    assert raw.info['meas_date'] == raw_read.info['meas_date']

    # channel name can't be longer than 16 characters with the type added
    raw_bad = raw.copy()
    raw_bad.rename_channels({'1': 'abcdefghijklmnopqrstuvwxyz'})
    with pytest.raises(RuntimeError, match='Signal label'), \
            pytest.warns(RuntimeWarning, match='Data has a non-integer'):
        raw_bad.export(temp_fname)

    # include bad birthday that is non-EDF compliant
    bad_info = info.copy()
    bad_info['subject_info']['birthday'] = (1700, 1, 20)
    raw = RawArray(data, bad_info)
    with pytest.raises(RuntimeError, match='Setting patient birth date'):
        raw.export(temp_fname)

    # include bad measurement date that is non-EDF compliant
    raw = RawArray(data, info)
    meas_date = datetime(year=1984, month=1, day=1, tzinfo=timezone.utc)
    raw.set_meas_date(meas_date)
    with pytest.raises(RuntimeError, match='Setting start date time'):
        raw.export(temp_fname)

    # test that warning is raised if there are non-voltage based channels
    raw = RawArray(data, info)
    with pytest.warns(RuntimeWarning, match='The unit'):
        raw.set_channel_types({'9': 'hbr'})
    with pytest.warns(RuntimeWarning, match='Non-voltage channels'):
        raw.export(temp_fname)

    # data should match up to the non-accepted channel
    raw_read = read_raw_edf(temp_fname, preload=True)
    orig_raw_len = len(raw)
    assert_array_almost_equal(raw.get_data()[:-1, :],
                              raw_read.get_data()[:, :orig_raw_len],
                              decimal=4)
    assert_allclose(raw.times,
                    raw_read.times[:orig_raw_len],
                    rtol=0,
                    atol=1e-5)

    # the data should still match though
    raw_read = read_raw_edf(temp_fname, preload=True)
    raw.drop_channels('2')
    assert raw.ch_names == raw_read.ch_names
    orig_raw_len = len(raw)
    assert_array_almost_equal(raw.get_data(),
                              raw_read.get_data()[:, :orig_raw_len],
                              decimal=4)
    assert_allclose(raw.times,
                    raw_read.times[:orig_raw_len],
                    rtol=0,
                    atol=1e-5)
示例#4
0
def bv2fif(dataf,
           corf,
           ch_order=None,
           eogs=('VEOG', 'HEOG'),
           ecg='ECG',
           emg='EMG',
           preload='default',
           ref_ch='Fp1',
           dbs=False,
           new_sfreq=1000.0):
    montage = read_dig_montage(bvct=corf)
    if preload == 'default':
        preload = os.path.dirname(dataf) + '/workfile'

    raw = read_raw_brainvision(dataf, preload=preload)

    if dbs:
        event_ch = get_events(raw)

    # save downsampled raw for multitaper spectrogram
    raw_data = np.zeros(
        (raw._data.shape[0],
         int(raw._data.shape[1] / raw.info['sfreq'] * new_sfreq)))
    raw_info = raw.info.copy()
    raw_info['sfreq'] = new_sfreq
    for i in tqdm(range(len(raw._data))):
        ch = raw._data[i, ::int(raw.info['sfreq'] / new_sfreq)]
        raw_data[i] = ch
        del ch

    raw_resampled = RawArray(raw_data, raw_info)
    raw_resampled.annotations = raw.annotations

    if dbs:
        old_event_ch = [ch for ch in raw.info['ch_names'] if 'STI' in ch]
        if old_event_ch:
            raw_resampled.drop_channels([old_event_ch[0]])
        event_ch._data = event_ch._data[:, ::int(raw.info['sfreq'] /
                                                 new_sfreq)]
        event_ch.info['sfreq'] = new_sfreq
        event_ch.__len__ = len(event_ch._data[0])
        event_ch.info['lowpass'] = raw_resampled.info['lowpass']
        raw_resampled.add_channels([event_ch])

    prepInst(raw_resampled, dataf, 'raw', montage, ref_ch, eogs, ecg, emg)

    events, event_ids = events_from_annotations(raw)
    if len(np.unique(events[:, 2])) > 1:
        events = events[np.where(events[:,
                                        2] == events[1,
                                                     2])[0]]  #skip new segment
    epochs = Epochs(raw,
                    events,
                    tmin=-2,
                    tmax=2,
                    proj=False,
                    preload=op.dirname(dataf) + '/workfile-epo',
                    baseline=(-0.5, -0.1),
                    verbose=False,
                    detrend=1)
    events = events[
        epochs.
        selection]  #in case any epochs don't have data and get thrown out (poorly placed at beginning or end)
    epo_data = np.zeros(
        (epochs._data.shape[0], epochs._data.shape[1],
         int(np.ceil(epochs._data.shape[2] / epochs.info['sfreq'] *
                     new_sfreq))))
    for i in tqdm(range(epochs._data.shape[0])):
        for j in range(epochs._data.shape[1]):
            epo_curr = epochs._data[i,
                                    j, ::int(epochs.info['sfreq'] / new_sfreq)]
            epo_data[i, j] = epo_curr
            del epo_curr
    events[:, 0] = np.array(events[:, 0] * new_sfreq / raw.info['sfreq'],
                            dtype=int)
    epo_resampled = EpochsArray(epo_data, epochs.info.copy(), events, tmin=-2)
    epo_resampled.info['sfreq'] = new_sfreq
    epo_resampled.events[:, 2] = np.arange(len(events))
    epo_resampled.event_id = {str(i): i for i in range(len(events))}

    prepInst(epo_resampled, dataf, 'epo', montage, ref_ch, eogs, ecg, emg)
示例#5
0
def test_plot_sensors(raw):
    """Test plotting of sensor array."""
    plt.close('all')
    fig = raw.plot_sensors('3d')
    _fake_click(fig, fig.gca(), (-0.08, 0.67))
    raw.plot_sensors('topomap', ch_type='mag',
                     show_names=['MEG 0111', 'MEG 0131'])
    plt.close('all')
    ax = plt.subplot(111)
    raw.plot_sensors(ch_groups='position', axes=ax)
    raw.plot_sensors(ch_groups='selection', to_sphere=False)
    raw.plot_sensors(ch_groups=[[0, 1, 2], [3, 4]])
    pytest.raises(ValueError, raw.plot_sensors, ch_groups='asd')
    pytest.raises(TypeError, plot_sensors, raw)  # needs to be info
    pytest.raises(ValueError, plot_sensors, raw.info, kind='sasaasd')
    plt.close('all')
    fig, sels = raw.plot_sensors('select', show_names=True)
    ax = fig.axes[0]

    # Click with no sensors
    _fake_click(fig, ax, (0., 0.), xform='data')
    _fake_click(fig, ax, (0, 0.), xform='data', kind='release')
    assert fig.lasso.selection == []

    # Lasso with 1 sensor (upper left)
    _fake_click(fig, ax, (0, 1), xform='ax')
    fig.canvas.draw()
    assert fig.lasso.selection == []
    _fake_click(fig, ax, (0.65, 1), xform='ax', kind='motion')
    _fake_click(fig, ax, (0.65, 0.7), xform='ax', kind='motion')
    fig.canvas.key_press_event('control')
    _fake_click(fig, ax, (0, 0.7), xform='ax', kind='release')
    assert fig.lasso.selection == ['MEG 0121']

    # check that point appearance changes
    fc = fig.lasso.collection.get_facecolors()
    ec = fig.lasso.collection.get_edgecolors()
    assert (fc[:, -1] == [0.5, 1., 0.5]).all()
    assert (ec[:, -1] == [0.25, 1., 0.25]).all()

    _fake_click(fig, ax, (0.7, 1), xform='ax', kind='motion')
    xy = ax.collections[0].get_offsets()
    _fake_click(fig, ax, xy[2], xform='data')  # single selection
    assert fig.lasso.selection == ['MEG 0121', 'MEG 0131']
    _fake_click(fig, ax, xy[2], xform='data')  # deselect
    assert fig.lasso.selection == ['MEG 0121']
    plt.close('all')

    raw.info['dev_head_t'] = None  # like empty room
    with pytest.warns(RuntimeWarning, match='identity'):
        raw.plot_sensors()

    # Test plotting with sphere='eeglab'
    info = create_info(
        ch_names=['Fpz', 'Oz', 'T7', 'T8'],
        sfreq=100,
        ch_types='eeg'
    )
    data = 1e-6 * np.random.rand(4, 100)
    raw_eeg = RawArray(data=data, info=info)
    raw_eeg.set_montage('biosemi64')
    raw_eeg.plot_sensors(sphere='eeglab')

    # Should work with "FPz" as well
    raw_eeg.rename_channels({'Fpz': 'FPz'})
    raw_eeg.plot_sensors(sphere='eeglab')

    # Should still work without Fpz/FPz, as long as we still have Oz
    raw_eeg.drop_channels('FPz')
    raw_eeg.plot_sensors(sphere='eeglab')

    # Should raise if Oz is missing too, as we cannot reconstruct Fpz anymore
    raw_eeg.drop_channels('Oz')
    with pytest.raises(ValueError, match='could not find: Fpz'):
        raw_eeg.plot_sensors(sphere='eeglab')

    # Should raise if we don't have a montage
    chs = deepcopy(raw_eeg.info['chs'])
    raw_eeg.set_montage(None)
    with raw_eeg.info._unlock():
        raw_eeg.info['chs'] = chs
    with pytest.raises(ValueError, match='No montage was set'):
        raw_eeg.plot_sensors(sphere='eeglab')