예제 #1
0
    def make_raw(self, data_duration=None, apply_ica=True, first_samp=0,
                 verbose=None):
        """Create instance of mne.io.RawArray.

        Parameters
        ----------
        data_duration : int, float
            Duration of previous data to use. If data=10, returns instance of
            mne.io.RawArray of the previous 10 seconds of data.
        apply_ica : bool (defaults to True)
            If True and self.ica has been fitted, will apply the ICA to the
            requested data. If False, will not fit ICA to the data.
        first_samp : int (defaults to 0)
            Sample offset.

        Returns
        -------
        raw : mne.io.RawArray
            The EEG data.
        """
        raw_data = self.get_data(data_duration=data_duration)
        raw_data[-1, :] = 0  # Make row of timestamps a row of events 0.

        if not apply_ica:
            return io.RawArray(raw_data, self.info, first_samp=first_samp,
                               verbose=verbose)
        elif apply_ica and self.ica.current_fit == 'unfitted':
            return io.RawArray(raw_data, self.info, first_samp=first_samp,
                               verbose=verbose)
        elif apply_ica and self.ica.current_fit != 'unfitted':
            raw = io.RawArray(raw_data, self.info, first_samp=first_samp,
                              verbose=verbose)
            return self.ica.apply(raw)
예제 #2
0
def test_interpolation_meg():
    """Test interpolation of MEG channels."""
    # speed accuracy tradeoff: channel subselection is faster but the
    # correlation drops
    thresh = 0.68

    raw, epochs_meg = _load_data('meg')

    # check that interpolation works when non M/EEG channels are present
    # before MEG channels
    raw.crop(0, 0.1).load_data().pick_channels(epochs_meg.ch_names)
    raw.info.normalize_proj()
    with pytest.warns(RuntimeWarning, match='unit .* changed from .* to .*'):
        raw.set_channel_types({raw.ch_names[0]: 'stim'})
    raw.info['bads'] = [raw.ch_names[1]]
    raw.load_data()
    raw.interpolate_bads(mode='fast')
    del raw

    # check that interpolation works for MEG
    epochs_meg.info['bads'] = ['MEG 0141']
    evoked = epochs_meg.average()
    pick = pick_channels(epochs_meg.info['ch_names'], epochs_meg.info['bads'])

    # MEG -- raw
    raw_meg = io.RawArray(data=epochs_meg._data[0], info=epochs_meg.info)
    raw_meg.info['bads'] = ['MEG 0141']
    data1 = raw_meg[pick, :][0][0]

    raw_meg.info.normalize_proj()
    data2 = raw_meg.interpolate_bads(reset_bads=False,
                                     mode='fast')[pick, :][0][0]
    assert np.corrcoef(data1, data2)[0, 1] > thresh
    # the same number of bads as before
    assert len(raw_meg.info['bads']) == len(raw_meg.info['bads'])

    # MEG -- epochs
    data1 = epochs_meg.get_data()[:, pick, :].ravel()
    epochs_meg.info.normalize_proj()
    epochs_meg.interpolate_bads(mode='fast')
    data2 = epochs_meg.get_data()[:, pick, :].ravel()
    assert np.corrcoef(data1, data2)[0, 1] > thresh
    assert len(epochs_meg.info['bads']) == 0

    # MEG -- evoked (plus auto origin)
    data1 = evoked.data[pick]
    evoked.info.normalize_proj()
    data2 = evoked.interpolate_bads(origin='auto').data[pick]
    assert np.corrcoef(data1, data2)[0, 1] > thresh

    # MEG -- with exclude
    evoked.info['bads'] = ['MEG 0141', 'MEG 0121']
    pick = pick_channels(evoked.ch_names, evoked.info['bads'], ordered=True)
    evoked.data[pick[-1]] = 1e10
    data1 = evoked.data[pick]
    evoked.info.normalize_proj()
    data2 = evoked.interpolate_bads(origin='auto',
                                    exclude=['MEG 0121']).data[pick]
    assert np.corrcoef(data1[0], data2[0])[0, 1] > thresh
    assert np.all(data2[1] == 1e10)
예제 #3
0
    def make_epochs(self,
                    marker_stream,
                    end_index,
                    marker_end,
                    trial_num,
                    data_duration=None,
                    events=None,
                    filter_range: tuple=(0.5, 15),
                    event_duration=0, event_id=None, tmin=-0.2, tmax=1.0, baseline=(None, 0), picks=None, preload=False,
                    reject=None, flat=None, proj=True, decim=1, reject_tmin=None, reject_tmax=None, detrend=None,
                    on_missing='error', reject_by_annotation=False, verbose=None):
        """Create instance of mne.Epochs. If events are not supplied, this script must be connected to a Markers stream.
        Args:
            marker_stream: stream_rt.MarkerStream; stream of marker data.
            end_index: Last index in data that is included.
            marker_end: index of the last marker in a set of trials
            trial_num: number of trials in a set
            data_duration: int, float; duration of previous data to use. If data=10, returns instance of mne.Epochs of
                the previous 10 seconds of data.
            events: ndarray; array of events of the shape (n_events, 3).
            filter_range: tuple containing bandpass filter range in Hz
            everything else: Copy parameters from mne.Epochs.
        Returns:
            epochs: mne.Epochs; contains time segments of data_duration after stimuli for training and prediciton.
            identities: list containing the row/column that was flashed in order.
            targets: list containing target values for training; i.e. 0 or 1.
        """
        targets = []
        raw_data = self.get_data(end_index, data_duration=data_duration)
        if events is None:
            events, targets = make_events(raw_data, marker_stream, marker_end, trial_num, event_duration)

        # Replace timestamps with zeros.
        raw_data[-1, :] = 0

        # Create raw array
        raw = io.RawArray(raw_data, self.info)

        # Populate events in event channel
        raw.add_events(events, self.event_channel_name)
        if targets[0][0] == 0:
            event_id = {'Non-Target': 0}
        else:
            event_id = {'Target': 1}

        # bandpass filter the data between two ends of the filter_range
        raw_filter(raw, filter_range[0], filter_range[1], picks=[0, 1, 2, 3])

        return Epochs(raw, events, event_id=event_id, tmin=tmin, tmax=tmax,
                      baseline=baseline, picks=picks,
                      preload=preload, reject=reject, flat=flat, proj=proj, decim=decim,
                      reject_tmin=reject_tmin,
                      reject_tmax=reject_tmax, detrend=detrend, on_missing=on_missing,
                      reject_by_annotation=reject_by_annotation,
                      verbose=verbose), targets
예제 #4
0
def test_interplation():
    """Test interpolation"""
    epochs.info['bads'] = []
    goods_idx = np.ones(len(epochs.ch_names), dtype=bool)
    goods_idx[epochs.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx

    evoked = epochs.average()
    ave_before = evoked.data[bads_idx]

    pos = epochs.get_channel_positions()
    pos_good = pos[goods_idx]
    pos_bad = pos[bads_idx]
    interpolation = _make_interpolation_matrix(pos_good, pos_bad)
    assert_equal(interpolation.shape, (1, len(epochs.ch_names) - 1))

    ave_after = np.dot(interpolation, evoked.data[goods_idx])

    assert_allclose(ave_before, ave_after, atol=2e-6)

    epochs.info['bads'] = []
    assert_raises(ValueError, epochs.interpolate_bads_eeg)

    epochs.info['bads'] = ['EEG 012']
    epochs.preload = False
    assert_raises(ValueError,  epochs.interpolate_bads_eeg)
    epochs.preload = True

    epochs2.info['bads'] = ['EEG 012', 'MEG 1711']

    epochs2.interpolate_bads_eeg()
    ave_after2 = epochs2.average().data[n_meg + np.where(bads_idx)[0]]

    assert_array_almost_equal(ave_after, ave_after2, decimal=16)

    raw = io.RawArray(data=epochs._data[0], info=epochs.info)
    raw_before = raw._data[bads_idx]
    raw.interpolate_bads_eeg()
    raw_after = raw._data[bads_idx]
    assert_equal(np.all(raw_before == raw_after), False)

    evoked = epochs.average()
    evoked.interpolate_bads_eeg()
    assert_array_equal(ave_after, evoked.data[bads_idx])

    for inst in [raw, epochs]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        assert_raises(ValueError, inst.interpolate_bads_eeg)
예제 #5
0
    def make_epochs(self, marker_stream, data_duration=None, events=None,
                    event_duration=0, event_id=None, apply_ica=True, tmin=-0.2,
                    tmax=1.0, baseline=(None, 0), picks=None, name='Unknown',
                    preload=False, reject=None, flat=None, proj=True, decim=1,
                    reject_tmin=None, reject_tmax=None, detrend=None,
                    add_eeg_ref=None, on_missing='error',
                    reject_by_annotation=True, verbose=None):
        """Create instance of mne.Epochs. If events are not supplied, this
        script must be connected to a Markers stream.

        Parameters
        ----------
        marker_stream : rteeg.MarkerStream
            Stream of marker data.
        data_duration : int, float
            Duration of previous data to use. If data=10, returns instance of
            mne.Epochs of the previous 10 seconds of data.
        events : ndarray
            Array of events of the shape (n_events, 3)
        Copy parameters from mne.Epochs

        apply_ica : bool (defaults to True)
            If True and if self.ica has been fitted, will apply the ICA to the
            requested data. If False, will not fit ICA to the data.

        Returns
        -------
        epochs : mne.Epochs
        """
        raw_data = self.get_data(data_duration=data_duration)
        if events is None:
            events = make_events(raw_data, marker_stream, event_duration)
        raw_data[-1, :] = 0  # Replace timestamps with zeros.
        raw = io.RawArray(raw_data, self.info)
        # If user wants to apply ICA and if ICA has been fitted ...
        if apply_ica and self.ica.current_fit != 'unfitted':
            raw = self.ica.apply(raw)
            # Should this be changed? ICA.apply() works in-place on raw.
        return Epochs(raw, events, event_id=event_id, tmin=tmin, tmax=tmax,
                      baseline=baseline, picks=picks, name=name,
                      preload=preload, reject=reject, flat=flat, proj=proj,
                      decim=decim, reject_tmin=reject_tmin,
                      reject_tmax=reject_tmax, detrend=detrend,
                      add_eeg_ref=add_eeg_ref, on_missing=on_missing,
                      reject_by_annotation=reject_by_annotation,
                      verbose=verbose)
예제 #6
0
def test_interpolation_eeg(offset, avg_proj, ctol, atol, method):
    """Test interpolation of EEG channels."""
    raw, epochs_eeg = _load_data('eeg')
    epochs_eeg = epochs_eeg.copy()
    assert not _has_eeg_average_ref_proj(epochs_eeg.info['projs'])
    # Offsetting the coordinate frame should have no effect on the output
    for inst in (raw, epochs_eeg):
        for ch in inst.info['chs']:
            if ch['kind'] == io.constants.FIFF.FIFFV_EEG_CH:
                ch['loc'][:3] += offset
                ch['loc'][3:6] += offset
        for d in inst.info['dig']:
            d['r'] += offset

    # check that interpolation does nothing if no bads are marked
    epochs_eeg.info['bads'] = []
    evoked_eeg = epochs_eeg.average()
    kw = dict(method=method)
    with pytest.warns(RuntimeWarning, match='Doing nothing'):
        evoked_eeg.interpolate_bads(**kw)

    # create good and bad channels for EEG
    epochs_eeg.info['bads'] = []
    goods_idx = np.ones(len(epochs_eeg.ch_names), dtype=bool)
    goods_idx[epochs_eeg.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx
    pos = epochs_eeg._get_channel_positions()

    evoked_eeg = epochs_eeg.average()
    if avg_proj:
        evoked_eeg.set_eeg_reference(projection=True).apply_proj()
        assert_allclose(evoked_eeg.data.mean(0), 0., atol=1e-20)
    ave_before = evoked_eeg.data[bads_idx]

    # interpolate bad channels for EEG
    epochs_eeg.info['bads'] = ['EEG 012']
    evoked_eeg = epochs_eeg.average()
    if avg_proj:
        evoked_eeg.set_eeg_reference(projection=True).apply_proj()
        good_picks = pick_types(evoked_eeg.info, meg=False, eeg=True)
        assert_allclose(evoked_eeg.data[good_picks].mean(0), 0., atol=1e-20)
    evoked_eeg_bad = evoked_eeg.copy()
    bads_picks = pick_channels(epochs_eeg.ch_names,
                               include=epochs_eeg.info['bads'],
                               ordered=True)
    evoked_eeg_bad.data[bads_picks, :] = 1e10

    # Test first the exclude parameter
    evoked_eeg_2_bads = evoked_eeg_bad.copy()
    evoked_eeg_2_bads.info['bads'] = ['EEG 004', 'EEG 012']
    evoked_eeg_2_bads.data[pick_channels(evoked_eeg_bad.ch_names,
                                         ['EEG 004', 'EEG 012'])] = 1e10
    evoked_eeg_interp = evoked_eeg_2_bads.interpolate_bads(origin=(0., 0., 0.),
                                                           exclude=['EEG 004'],
                                                           **kw)
    assert evoked_eeg_interp.info['bads'] == ['EEG 004']
    assert np.all(evoked_eeg_interp.get_data('EEG 004') == 1e10)
    assert np.all(evoked_eeg_interp.get_data('EEG 012') != 1e10)

    # Now test without exclude parameter
    evoked_eeg_bad.info['bads'] = ['EEG 012']
    evoked_eeg_interp = evoked_eeg_bad.copy().interpolate_bads(origin=(0., 0.,
                                                                       0.),
                                                               **kw)
    if avg_proj:
        assert_allclose(evoked_eeg_interp.data.mean(0), 0., atol=1e-6)
    interp_zero = evoked_eeg_interp.data[bads_idx]
    if method is None:  # using
        pos_good = pos[goods_idx]
        pos_bad = pos[bads_idx]
        interpolation = _make_interpolation_matrix(pos_good, pos_bad)
        assert interpolation.shape == (1, len(epochs_eeg.ch_names) - 1)
        interp_manual = np.dot(interpolation, evoked_eeg_bad.data[goods_idx])
        assert_array_equal(interp_manual, interp_zero)
        del interp_manual, interpolation, pos, pos_good, pos_bad
    assert_allclose(ave_before, interp_zero, atol=atol)
    assert ctol[0] < np.corrcoef(ave_before, interp_zero)[0, 1] < ctol[1]
    interp_fit = evoked_eeg_bad.copy().interpolate_bads(**kw).data[bads_idx]
    assert_allclose(ave_before, interp_fit, atol=2.5e-6)
    assert ctol[1] < np.corrcoef(ave_before, interp_fit)[0, 1]  # better

    # check that interpolation fails when preload is False
    epochs_eeg.preload = False
    with pytest.raises(RuntimeError, match='requires epochs data to be loade'):
        epochs_eeg.interpolate_bads(**kw)
    epochs_eeg.preload = True

    # check that interpolation changes the data in raw
    raw_eeg = io.RawArray(data=epochs_eeg._data[0], info=epochs_eeg.info)
    raw_before = raw_eeg._data[bads_idx]
    raw_after = raw_eeg.interpolate_bads(**kw)._data[bads_idx]
    assert not np.all(raw_before == raw_after)

    # check that interpolation fails when preload is False
    for inst in [raw, epochs_eeg]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        with pytest.raises(RuntimeError, match='requires.*data to be loaded'):
            inst.interpolate_bads(**kw)

    # check that interpolation works with few channels
    raw_few = raw.copy().crop(0, 0.1).load_data()
    raw_few.pick_channels(raw_few.ch_names[:1] + raw_few.ch_names[3:4])
    assert len(raw_few.ch_names) == 2
    raw_few.del_proj()
    raw_few.info['bads'] = [raw_few.ch_names[-1]]
    orig_data = raw_few[1][0]
    with _record_warnings() as w:
        raw_few.interpolate_bads(reset_bads=False, **kw)
    assert len([ww for ww in w if 'more than' not in str(ww.message)]) == 0
    new_data = raw_few[1][0]
    assert (new_data == 0).mean() < 0.5
    assert np.corrcoef(new_data, orig_data)[0, 1] > 0.2
예제 #7
0
def test_interpolation():
    """Test interpolation"""
    raw, epochs, epochs_eeg, epochs_meg = _load_data()

    # It's a trade of between speed and accuracy. If every second channel is
    # selected the tests are more than 3x faster but the correlation
    # drops to 0.8
    thresh = 0.80

    # create good and bad channels for EEG
    epochs_eeg.info['bads'] = []
    goods_idx = np.ones(len(epochs_eeg.ch_names), dtype=bool)
    goods_idx[epochs_eeg.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx

    evoked_eeg = epochs_eeg.average()
    ave_before = evoked_eeg.data[bads_idx]

    # interpolate bad channels for EEG
    pos = epochs_eeg._get_channel_positions()
    pos_good = pos[goods_idx]
    pos_bad = pos[bads_idx]
    interpolation = _make_interpolation_matrix(pos_good, pos_bad)
    assert_equal(interpolation.shape, (1, len(epochs_eeg.ch_names) - 1))
    ave_after = np.dot(interpolation, evoked_eeg.data[goods_idx])

    epochs_eeg.info['bads'] = ['EEG 012']
    evoked_eeg = epochs_eeg.average()
    assert_array_equal(ave_after, evoked_eeg.interpolate_bads().data[bads_idx])

    assert_allclose(ave_before, ave_after, atol=2e-6)

    # check that interpolation fails when preload is False
    epochs_eeg.preload = False
    assert_raises(ValueError, epochs_eeg.interpolate_bads)
    epochs_eeg.preload = True

    # check that interpolation changes the data in raw
    raw_eeg = io.RawArray(data=epochs_eeg._data[0], info=epochs_eeg.info)
    raw_before = raw_eeg._data[bads_idx]
    raw_after = raw_eeg.interpolate_bads()._data[bads_idx]
    assert_equal(np.all(raw_before == raw_after), False)

    # check that interpolation fails when preload is False
    for inst in [raw, epochs]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        assert_raises(ValueError, inst.interpolate_bads)

    # check that interpolation works for MEG
    epochs_meg.info['bads'] = ['MEG 0141']
    evoked = epochs_meg.average()
    pick = pick_channels(epochs_meg.info['ch_names'], epochs_meg.info['bads'])

    # MEG -- raw
    raw_meg = io.RawArray(data=epochs_meg._data[0], info=epochs_meg.info)
    raw_meg.info['bads'] = ['MEG 0141']
    data1 = raw_meg[pick, :][0][0]
    # reset_bads=False here because epochs_meg appears to share the same info
    # dict with raw and we want to test the epochs functionality too
    raw_meg.info.normalize_proj()
    data2 = raw_meg.interpolate_bads(reset_bads=False)[pick, :][0][0]
    assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
    # the same number of bads as before
    assert_true(len(raw_meg.info['bads']) == len(raw_meg.info['bads']))

    # MEG -- epochs
    data1 = epochs_meg.get_data()[:, pick, :].ravel()
    epochs_meg.info.normalize_proj()
    epochs_meg.interpolate_bads()
    data2 = epochs_meg.get_data()[:, pick, :].ravel()
    assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
    assert_true(len(raw_meg.info['bads']) == 0)

    # MEG -- evoked
    data1 = evoked.data[pick]
    evoked.info.normalize_proj()
    data2 = evoked.interpolate_bads().data[pick]
    assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
def test_interpolation_eeg():
    """Test interpolation of EEG channels."""
    raw, epochs_eeg = _load_data('eeg')

    # check that interpolation does nothing if no bads are marked
    epochs_eeg.info['bads'] = []
    evoked_eeg = epochs_eeg.average()
    with pytest.warns(RuntimeWarning, match='Doing nothing'):
        evoked_eeg.interpolate_bads()

    # create good and bad channels for EEG
    epochs_eeg.info['bads'] = []
    goods_idx = np.ones(len(epochs_eeg.ch_names), dtype=bool)
    goods_idx[epochs_eeg.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx

    evoked_eeg = epochs_eeg.average()
    ave_before = evoked_eeg.data[bads_idx]

    # interpolate bad channels for EEG
    pos = epochs_eeg._get_channel_positions()
    pos_good = pos[goods_idx]
    pos_bad = pos[bads_idx]
    interpolation = _make_interpolation_matrix(pos_good, pos_bad)
    assert interpolation.shape == (1, len(epochs_eeg.ch_names) - 1)
    ave_after = np.dot(interpolation, evoked_eeg.data[goods_idx])

    epochs_eeg.info['bads'] = ['EEG 012']
    evoked_eeg = epochs_eeg.average()
    assert_array_equal(ave_after, evoked_eeg.interpolate_bads().data[bads_idx])

    assert_allclose(ave_before, ave_after, atol=2e-6)

    # check that interpolation fails when preload is False
    epochs_eeg.preload = False
    pytest.raises(RuntimeError, epochs_eeg.interpolate_bads)
    epochs_eeg.preload = True

    # check that interpolation changes the data in raw
    raw_eeg = io.RawArray(data=epochs_eeg._data[0], info=epochs_eeg.info)
    raw_before = raw_eeg._data[bads_idx]
    raw_after = raw_eeg.interpolate_bads()._data[bads_idx]
    assert not np.all(raw_before == raw_after)

    # check that interpolation fails when preload is False
    for inst in [raw, epochs_eeg]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        pytest.raises(RuntimeError, inst.interpolate_bads)

    # check that interpolation works with few channels
    raw_few = raw.copy().crop(0, 0.1).load_data()
    raw_few.pick_channels(raw_few.ch_names[:1] + raw_few.ch_names[3:4])
    assert len(raw_few.ch_names) == 2
    raw_few.del_proj()
    raw_few.info['bads'] = [raw_few.ch_names[-1]]
    orig_data = raw_few[1][0]
    with pytest.warns(None) as w:
        raw_few.interpolate_bads(reset_bads=False)
    assert len(w) == 0
    new_data = raw_few[1][0]
    assert (new_data == 0).mean() < 0.5
    assert np.corrcoef(new_data, orig_data)[0, 1] > 0.1
예제 #9
0
def test_interpolation_eeg(offset):
    """Test interpolation of EEG channels."""
    raw, epochs_eeg = _load_data('eeg')
    epochs_eeg = epochs_eeg.copy()
    # Offsetting the coordinate frame should have no effect on the output
    for inst in (raw, epochs_eeg):
        for ch in inst.info['chs']:
            if ch['kind'] == io.constants.FIFF.FIFFV_EEG_CH:
                ch['loc'][:3] += offset
                ch['loc'][3:6] += offset
        for d in inst.info['dig']:
            d['r'] += offset

    # check that interpolation does nothing if no bads are marked
    epochs_eeg.info['bads'] = []
    evoked_eeg = epochs_eeg.average()
    with pytest.warns(RuntimeWarning, match='Doing nothing'):
        evoked_eeg.interpolate_bads()

    # create good and bad channels for EEG
    epochs_eeg.info['bads'] = []
    goods_idx = np.ones(len(epochs_eeg.ch_names), dtype=bool)
    goods_idx[epochs_eeg.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx

    evoked_eeg = epochs_eeg.average()
    ave_before = evoked_eeg.data[bads_idx]

    # interpolate bad channels for EEG
    pos = epochs_eeg._get_channel_positions()
    pos_good = pos[goods_idx]
    pos_bad = pos[bads_idx]
    interpolation = _make_interpolation_matrix(pos_good, pos_bad)
    assert interpolation.shape == (1, len(epochs_eeg.ch_names) - 1)
    interp_manual = np.dot(interpolation, evoked_eeg.data[goods_idx])

    epochs_eeg.info['bads'] = ['EEG 012']
    evoked_eeg = epochs_eeg.average()
    interp_zero = evoked_eeg.interpolate_bads(
        origin=(0., 0., 0.)).data[bads_idx]
    assert_array_equal(interp_manual, interp_zero)
    assert_allclose(ave_before, interp_zero, atol=3e-6)
    assert 0.985 < np.corrcoef(ave_before, interp_zero)[0, 1] < 0.99
    evoked_eeg.info['bads'] = ['EEG 012']
    interp_fit = evoked_eeg.interpolate_bads().data[bads_idx]
    assert_allclose(ave_before, interp_fit, atol=2e-6)
    assert 0.99 < np.corrcoef(ave_before, interp_fit)[0, 1]  # better

    # check that interpolation fails when preload is False
    epochs_eeg.preload = False
    pytest.raises(RuntimeError, epochs_eeg.interpolate_bads)
    epochs_eeg.preload = True

    # check that interpolation changes the data in raw
    raw_eeg = io.RawArray(data=epochs_eeg._data[0], info=epochs_eeg.info)
    raw_before = raw_eeg._data[bads_idx]
    raw_after = raw_eeg.interpolate_bads()._data[bads_idx]
    assert not np.all(raw_before == raw_after)

    # check that interpolation fails when preload is False
    for inst in [raw, epochs_eeg]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        pytest.raises(RuntimeError, inst.interpolate_bads)

    # check that interpolation works with few channels
    raw_few = raw.copy().crop(0, 0.1).load_data()
    raw_few.pick_channels(raw_few.ch_names[:1] + raw_few.ch_names[3:4])
    assert len(raw_few.ch_names) == 2
    raw_few.del_proj()
    raw_few.info['bads'] = [raw_few.ch_names[-1]]
    orig_data = raw_few[1][0]
    with pytest.warns(None) as w:
        raw_few.interpolate_bads(reset_bads=False)
    assert len([ww for ww in w if 'more than' not in str(ww.message)]) == 0
    new_data = raw_few[1][0]
    assert (new_data == 0).mean() < 0.5
    assert np.corrcoef(new_data, orig_data)[0, 1] > 0.2
예제 #10
0
def test_sns():
    """Test sensor noise suppression"""
    # artificial (IID) data
    data = np.random.RandomState(0).randn(102, 5000)
    info = create_info(len(data), 1000., 'mag')
    raw = io.RawArray(data, info)
    assert_raises(ValueError, SensorNoiseSuppression, 'foo')
    assert_raises(TypeError, SensorNoiseSuppression(10).fit, 'foo')
    assert_raises(ValueError, SensorNoiseSuppression, -1)
    raw.info['bads'] = [raw.ch_names[1]]
    assert_raises(ValueError, SensorNoiseSuppression(101).fit, raw)
    for n_neighbors, bounds in ((2, (17, 20)),
                                (5, (11, 15),),
                                (10, (9, 12)),
                                (20, (7, 10)),
                                (50, (5, 9)),
                                (100, (5, 8)),
                                ):
        sns = SensorNoiseSuppression(n_neighbors)
        sns.fit(raw)
        raw_sns = sns.apply(raw.copy())
        operator = sns.operator
        # bad channels are modified but not used
        assert_allclose(operator[:, 1], 0.)
        assert_true(np.sum(np.abs(operator)) > 0)
        assert_equal(operator[0].astype(bool).sum(), n_neighbors)
        assert_allclose(np.diag(operator), 0.)
        picks = pick_types(raw.info)
        orig_power = np.linalg.norm(raw[picks][0])
        # Test the suppression factor
        factor = orig_power / np.linalg.norm(raw_sns[picks][0])
        assert_true(bounds[0] < factor < bounds[1],
                    msg='%s: %s < %s < %s'
                    % (n_neighbors, bounds[0], factor, bounds[1]))
    # degenerate conditions
    assert_raises(TypeError, sns.apply, 'foo')
    sub_raw = raw.copy().pick_channels(raw.ch_names[:-1])
    assert_raises(RuntimeError, sns.apply, sub_raw)  # not all orig chs
    sub_sns = SensorNoiseSuppression(8)
    sub_sns.fit(sub_raw)
    assert_raises(RuntimeError, sub_sns.apply, raw)  # not all new chs
    # sample data
    raw = io.read_raw_fif(raw_fname)
    n_neighbors = 8
    sns = SensorNoiseSuppression(n_neighbors=n_neighbors)
    sns.fit(raw)
    raw_sns = sns.apply(raw.copy().load_data())
    operator = sns.operator
    # bad channels are modified
    assert_equal(len(raw.info['bads']), 2)
    for pick in pick_channels(raw.ch_names, raw.info['bads']):
        expected = np.zeros(operator.shape[0])
        sub_pick = sns._used_chs.index(raw.ch_names[pick])
        expected[sub_pick] = 1.
        assert_raises(AssertionError, assert_allclose, operator[sub_pick],
                      expected)
        assert_raises(AssertionError, assert_allclose, raw[pick][0],
                      raw_sns[pick][0])
    assert_equal(operator[0].astype(bool).sum(), n_neighbors)
    assert_equal(operator[0, 0], 0.)
    picks = pick_types(raw.info)
    orig_power = np.linalg.norm(raw[picks][0])
    # Test the suppression factor
    factor = orig_power / np.linalg.norm(raw_sns[picks][0])
    bounds = (1.3, 1.7)
    assert_true(bounds[0] < factor < bounds[1],
                msg='%s: %s < %s < %s'
                % (n_neighbors, bounds[0], factor, bounds[1]))
    # degenerate conditions
    assert_raises(RuntimeError, sns.apply, raw)  # not preloaded

    # Test against NoiseTools
    rng = np.random.RandomState(0)
    n_channels = 9
    x = rng.randn(n_channels, 10000)
    # make some correlations
    x = np.dot(rng.randn(n_channels, n_channels), x)
    x -= x.mean(axis=-1, keepdims=True)
    # savemat('test.mat', dict(x=x))  # --> run through nt_sns in MATLAB
    nt_op = np.array([  # Obtained from NoiseTools 18-Nov-2016
        [0, 0, -0.3528, 0, 0.6152, 0, 0, -0.3299, 0.1914],
        [0, 0, 0, 0.0336, 0, 0, -0.4284, 0, 0],
        [-0.2928, 0.2463, 0, 0, -0.0891, 0, 0, 0.2200, 0],
        [0, 0.0191, 0, 0, -0.3756, -0.3253, 0.4047, -0.4608, 0],
        [0.3184, 0, -0.0878, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0.5865, 0, -0.2137],
        [0, -0.5190, 0, 0.5059, 0, 0.8271, 0, 0, -0.0771],
        [-0.3953, 0, 0.3092, -0.5018, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, -0.2050, 0, 0, 0]]).T

    raw = RawArray(x, create_info(n_channels, 1000.,
                                  ['grad', 'grad', 'mag'] * 3))
    sns = SensorNoiseSuppression(3)
    sns.fit(raw)
    # this isn't perfect, but it's close
    np.testing.assert_allclose(sns.operator, nt_op, rtol=5e-2, atol=1e-3)
예제 #11
0
def to_mne_eeg(eegstream=None,
               line_freq=None,
               filenames=None,
               nasion=None,
               lpa=None,
               rpa=None):
    '''Convert recordings to MNE format.

    Args:
        eegstream : array
            EEG streams previously imported.
        line_freq : int
            Powerline frequency (50 or 60).
        filenames : array
            Full path of XDF files. Used for recording identification.
        nasion : array, shape(3,)
            Position of the nasion fiducial point.
            If specified, the array must have the same lenght of eegstream.
            Format for every recording (X, Y, Z) in meters: [0,0,0]
        lpa : array, shape(3,)
            Position of the left periauricular fiducial point.
            If specified, the array must have the same lenght of eegstream.
            Format for every recording (X, Y, Z) in meters: [0,0,0]
        rpa : array, shape(3,)
            Position of the right periauricular fiducial point.
            If specified, the array must have the same lenght of eegstream.
            Format for every recording (X, Y, Z) in meters: [0,0,0]
    Returns:
        Array of MNE RawArray instances with the recordings specified in eegstream.
    Raises:
        ValueError: if no stream is specified in eegstream or powerline frequency is not 50 or 60.
    See also:
        read_raw_xdf
        read_raw_xdf_dir
    '''
    if eegstream is None:
        raise (ValueError('Enter parameter array of EEG recordings.'))

    if line_freq is None or line_freq not in [50, 60]:
        raise (ValueError(
            'Enter the powerline frequency of your region (50 Hz or 60 Hz).'))

    eegstream = [eegstream] if not isinstance(eegstream, list) else eegstream

    raweeg = []

    # Get the names of the channels
    ch_names = [
        eegstream[0]['info']['desc'][0]['channels'][0]['channel'][i]['label']
        [0] for i in range(len(eegstream[0]['time_series'][0]))
    ]

    # Define sensor coordinates
    sensor_coord = [[-0.0856192, -0.0465147, -0.0457070],
                    [-0.0548397, 0.0685722, -0.0105900],
                    [0.0557433, 0.0696568, -0.0107550],
                    [0.0861618, -0.0470353, -0.0458690]]

    for index, stream in enumerate(eegstream):
        # Get channels position
        dig_montage = channels.make_dig_montage(
            ch_pos=dict(zip(ch_names, sensor_coord)),
            nasion=nasion[index] if nasion is not None else None,
            lpa=lpa[index] if lpa is not None else None,
            rpa=rpa[index] if rpa is not None else None,
            coord_frame='head')
        # Create raw info for processing
        info = create_info(ch_names=dig_montage.ch_names,
                           sfreq=float(stream['info']['nominal_srate'][0]),
                           ch_types='eeg')
        # Add channels position to info
        info.set_montage(dig_montage)
        # Convert data from microvolts to volts
        conv_data = stream["time_series"] * 1e-6
        # Reorder channels
        ord_data = [[sublist[1][item] for item in [1, 2, 3, 0]]
                    for sublist in enumerate(conv_data)]
        # Create raw data for mne
        raw = io.RawArray(np.array(ord_data).T, info)
        # Get the information of each stream
        stream_info = stream['info']['name'][0][:9] + ' ' + (
            filenames[index] if filenames is not None else '')
        # Print the information of each stream
        print('\nInfo: ' + str(index) + ' ' + stream_info + '\n')
        # Add the powerline frequency of each stream
        raw.info['line_freq'] = line_freq
        # Create annotation to store the name of the device and the filenames
        annotations = Annotations(0, 0, stream_info)
        # Add the annotations to raw data
        raw.set_annotations(annotations)
        # Add the RawArray object to list of eeg recordings
        raweeg.append(raw)

    return raweeg
예제 #12
0
파일: main.py 프로젝트: ArnoBen/EEG_PainERP
#%%
# for i, ch in enumerate(raw_edf.ch_names):
#     if i == 10:
#         print(ch)
#         plt.plot(raw_edf[ch][0][0])
#         continue
# plt.show()

# ch_names = raw_edf.ch_names
# ch_types = ['eeg'] * len(ch_names)
# info = mne.create_info(ch_names=ch_names, sfreq=fs, ch_types=ch_types)

#raw_edf.plot(scalings="auto", alpha=0.7)

#%% Using the .easy

raw_easy = pd.read_csv(data_path + ".easy", sep='\t', names=raw_edf.ch_names)
data = raw_easy.values.T

filtered_data = bandpass(data=data, f1=1, f2=40, fs=fs, axis=1)

# for i, row in enumerate(filtered_data):
#     plt.plot(row, alpha=0.7, label=i)
ch_names = raw_edf.ch_names

ch_types = ['eeg'] * len(ch_names)
info = mne.create_info(ch_names=ch_names, sfreq=fs, ch_types=ch_types)

raw_mne = io.RawArray(raw_easy.values.T, info)

raw_edf.plot(scalings="auto") 
예제 #13
0
def test_ssd():
    """Test Common Spatial Patterns algorithm on raw data."""
    X, A, S = simulate_data()
    sf = 250
    n_channels = X.shape[0]
    info = create_info(ch_names=n_channels, sfreq=sf, ch_types='eeg')
    n_components_true = 5

    # Init
    filt_params_signal = dict(l_freq=freqs_sig[0],
                              h_freq=freqs_sig[1],
                              l_trans_bandwidth=1,
                              h_trans_bandwidth=1)
    filt_params_noise = dict(l_freq=freqs_noise[0],
                             h_freq=freqs_noise[1],
                             l_trans_bandwidth=1,
                             h_trans_bandwidth=1)
    ssd = SSD(info, filt_params_signal, filt_params_noise)
    # freq no int
    freq = 'foo'
    filt_params_signal = dict(l_freq=freq,
                              h_freq=freqs_sig[1],
                              l_trans_bandwidth=1,
                              h_trans_bandwidth=1)
    filt_params_noise = dict(l_freq=freqs_noise[0],
                             h_freq=freqs_noise[1],
                             l_trans_bandwidth=1,
                             h_trans_bandwidth=1)
    with pytest.raises(TypeError, match='must be an instance '):
        ssd = SSD(info, filt_params_signal, filt_params_noise)

    # Wrongly specified noise band
    freq = 2
    filt_params_signal = dict(l_freq=freq,
                              h_freq=freqs_sig[1],
                              l_trans_bandwidth=1,
                              h_trans_bandwidth=1)
    filt_params_noise = dict(l_freq=freqs_noise[0],
                             h_freq=freqs_noise[1],
                             l_trans_bandwidth=1,
                             h_trans_bandwidth=1)
    with pytest.raises(ValueError, match='Wrongly specified '):
        ssd = SSD(info, filt_params_signal, filt_params_noise)

    # filt param no dict
    filt_params_signal = freqs_sig
    filt_params_noise = freqs_noise
    with pytest.raises(ValueError, match='must be defined'):
        ssd = SSD(info, filt_params_signal, filt_params_noise)

    # Data type
    filt_params_signal = dict(l_freq=freqs_sig[0],
                              h_freq=freqs_sig[1],
                              l_trans_bandwidth=1,
                              h_trans_bandwidth=1)
    filt_params_noise = dict(l_freq=freqs_noise[0],
                             h_freq=freqs_noise[1],
                             l_trans_bandwidth=1,
                             h_trans_bandwidth=1)
    ssd = SSD(info, filt_params_signal, filt_params_noise)
    raw = io.RawArray(X, info)

    pytest.raises(TypeError, ssd.fit, raw)

    # More than 1 channel type
    ch_types = np.reshape([['mag'] * 10, ['eeg'] * 10], n_channels)
    info_2 = create_info(ch_names=n_channels, sfreq=sf, ch_types=ch_types)

    with pytest.raises(ValueError, match='At this point SSD'):
        ssd = SSD(info_2, filt_params_signal, filt_params_noise)

    # Number of channels
    info_3 = create_info(ch_names=n_channels + 1, sfreq=sf, ch_types='eeg')
    ssd = SSD(info_3, filt_params_signal, filt_params_noise)
    pytest.raises(ValueError, ssd.fit, X)

    # Fit
    n_components = 10
    ssd = SSD(info,
              filt_params_signal,
              filt_params_noise,
              n_components=n_components)

    # Call transform before fit
    pytest.raises(AttributeError, ssd.transform, X)

    # Check outputs
    ssd.fit(X)

    assert (ssd.filters_.shape == (n_channels, n_channels))
    assert (ssd.patterns_.shape == (n_channels, n_channels))

    # Transform
    X_ssd = ssd.fit_transform(X)
    assert (X_ssd.shape[0] == n_components)
    # back and forward
    ssd = SSD(info,
              filt_params_signal,
              filt_params_noise,
              n_components=None,
              sort_by_spectral_ratio=False)
    ssd.fit(X)
    X_denoised = ssd.inverse_transform(X)
    assert_array_almost_equal(X_denoised, X)

    # Power ratio ordering
    spec_ratio, _ = ssd.get_spectral_ratio(ssd.transform(X))
    # since we now that the number of true components is 5, the relative
    # difference should be low for the first 5 components and then increases
    index_diff = np.argmax(-np.diff(spec_ratio))
    assert index_diff == n_components_true - 1

    # Check detected peaks
    # fit ssd
    n_components = n_components_true
    filt_params_signal = dict(l_freq=freqs_sig[0],
                              h_freq=freqs_sig[1],
                              l_trans_bandwidth=1,
                              h_trans_bandwidth=1)
    filt_params_noise = dict(l_freq=freqs_noise[0],
                             h_freq=freqs_noise[1],
                             l_trans_bandwidth=1,
                             h_trans_bandwidth=1)
    ssd = SSD(info,
              filt_params_signal,
              filt_params_noise,
              n_components=n_components,
              sort_by_spectral_ratio=False)
    ssd.fit(X)

    out = ssd.transform(X)
    psd_out, _ = psd_array_welch(out[0], sfreq=250, n_fft=250)
    psd_S, _ = psd_array_welch(S[0], sfreq=250, n_fft=250)
    corr = np.abs(np.corrcoef((psd_out, psd_S))[0, 1])
    assert np.abs(corr) > 0.95

    # Check pattern estimation
    # Since there is no exact ordering of the recovered patterns
    # a pair-wise greedy search will be done
    error = list()
    for ii in range(n_channels):
        corr = np.abs(np.corrcoef(ssd.patterns_[ii, :].T, A[:, 0])[0, 1])
        error.append(1 - corr)
        min_err = np.min(error)
    assert min_err < 0.3  # threshold taken from SSD original paper
예제 #14
0
    def make_epochs(self,
                    marker_stream,
                    end_index,
                    data_duration=None,
                    events=None,
                    event_duration=0,
                    event_id=None,
                    tmin=-0.2,
                    tmax=1.0,
                    baseline=(None, 0),
                    picks=None,
                    preload=False,
                    reject=None,
                    flat=None,
                    proj=True,
                    decim=1,
                    reject_tmin=None,
                    reject_tmax=None,
                    detrend=None,
                    on_missing='error',
                    reject_by_annotation=False,
                    verbose=None):
        """Create instance of mne.Epochs. If events are not supplied, this script must be connected to a Markers stream.

        Args:
            marker_stream: stream_rt.MarkerStream; stream of marker data.
            data_duration: int, float; duration of previous data to use. If data=10, returns instance of mne.Epochs of the
                previous 10 seconds of data.
            end_index: Last index in data that is included.
            events: ndarray; array of events of the shape (n_events, 3).
            everything else: Copy parameters from mne.Epochs.

        Returns:
            epochs: mne.Epochs; contains time segments of data_duration after stimuli for training and prediciton.
            identities: list containing the row/column that was flashed in order.
            targets: list containing target values for training; i.e. 0 or 1.
        """
        identities = []
        targets = []
        raw_data = self.get_data(end_index, data_duration=data_duration)
        if events is None:
            events, identities, targets = make_events(raw_data, marker_stream,
                                                      event_duration)

        # Replace timestamps with zeros.
        raw_data[-1, :] = 0

        # Create raw array
        raw = io.RawArray(raw_data, self.info)

        # Populate events in event channel
        raw.add_events(events, 'P300')
        event_id = {'Non-Target': 0, 'Target': 1}

        # Plot power spectral density
        # plot_psd(raw, 'std', picks=[0, 1, 2, 3])

        # Notch filter
        # notch_filter(raw, np.arange(50, 101, 50), picks=[0, 1, 2, 3])

        # filter the data between 0.5 and 15 Hz
        raw_filter(raw, 0.5, 15, picks=[0, 1, 2, 3])

        # plot raw data for visualization/validation
        plot(raw,
             events,
             duration=data_duration,
             n_channels=5,
             scalings='auto')

        return Epochs(raw,
                      events,
                      event_id=event_id,
                      tmin=tmin,
                      tmax=tmax,
                      baseline=baseline,
                      picks=picks,
                      preload=preload,
                      reject=reject,
                      flat=flat,
                      proj=proj,
                      decim=decim,
                      reject_tmin=reject_tmin,
                      reject_tmax=reject_tmax,
                      detrend=detrend,
                      on_missing=on_missing,
                      reject_by_annotation=reject_by_annotation,
                      verbose=verbose), identities, targets
예제 #15
0
def test_interpolation():
    """Test interpolation"""
    raw, epochs, epochs_eeg, epochs_meg = _load_data()

    # It's a trade of between speed and accuracy. If every second channel is
    # selected the tests are more than 3x faster but the correlation
    # drops to 0.8
    thresh = 0.80

    # check that interpolation does nothing if no bads are marked
    epochs_eeg.info['bads'] = []
    evoked_eeg = epochs_eeg.average()
    with warnings.catch_warnings(record=True) as w:
        evoked_eeg.interpolate_bads()
    assert_true(any('Doing nothing' in str(ww.message) for ww in w))

    # create good and bad channels for EEG
    epochs_eeg.info['bads'] = []
    goods_idx = np.ones(len(epochs_eeg.ch_names), dtype=bool)
    goods_idx[epochs_eeg.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx

    evoked_eeg = epochs_eeg.average()
    ave_before = evoked_eeg.data[bads_idx]

    # interpolate bad channels for EEG
    pos = epochs_eeg._get_channel_positions()
    pos_good = pos[goods_idx]
    pos_bad = pos[bads_idx]
    interpolation = _make_interpolation_matrix(pos_good, pos_bad)
    assert_equal(interpolation.shape, (1, len(epochs_eeg.ch_names) - 1))
    ave_after = np.dot(interpolation, evoked_eeg.data[goods_idx])

    epochs_eeg.info['bads'] = ['EEG 012']
    evoked_eeg = epochs_eeg.average()
    assert_array_equal(ave_after, evoked_eeg.interpolate_bads().data[bads_idx])

    assert_allclose(ave_before, ave_after, atol=2e-6)

    # check that interpolation fails when preload is False
    epochs_eeg.preload = False
    assert_raises(RuntimeError, epochs_eeg.interpolate_bads)
    epochs_eeg.preload = True

    # check that interpolation changes the data in raw
    raw_eeg = io.RawArray(data=epochs_eeg._data[0], info=epochs_eeg.info)
    raw_before = raw_eeg._data[bads_idx]
    raw_after = raw_eeg.interpolate_bads()._data[bads_idx]
    assert_equal(np.all(raw_before == raw_after), False)

    # check that interpolation fails when preload is False
    for inst in [raw, epochs]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        assert_raises(RuntimeError, inst.interpolate_bads)

    # check that interpolation works with few channels
    raw_few = raw.copy().crop(0, 0.1).load_data()
    raw_few.pick_channels(raw_few.ch_names[:1] + raw_few.ch_names[3:4])
    assert_equal(len(raw_few.ch_names), 2)
    raw_few.del_proj()
    raw_few.info['bads'] = [raw_few.ch_names[-1]]
    orig_data = raw_few[1][0]
    with warnings.catch_warnings(record=True) as w:
        raw_few.interpolate_bads(reset_bads=False)
    assert len(w) == 0
    new_data = raw_few[1][0]
    assert_true((new_data == 0).mean() < 0.5)
    assert_true(np.corrcoef(new_data, orig_data)[0, 1] > 0.1)

    # check that interpolation works when non M/EEG channels are present
    # before MEG channels
    with warnings.catch_warnings(record=True):  # change of units
        raw.rename_channels({'MEG 0113': 'TRIGGER'})
        raw.set_channel_types({'TRIGGER': 'stim'})
        raw.info['bads'] = [raw.info['ch_names'][1]]
        raw.load_data()
        raw.interpolate_bads()

    # check that interpolation works for MEG
    epochs_meg.info['bads'] = ['MEG 0141']
    evoked = epochs_meg.average()
    pick = pick_channels(epochs_meg.info['ch_names'], epochs_meg.info['bads'])

    # MEG -- raw
    raw_meg = io.RawArray(data=epochs_meg._data[0], info=epochs_meg.info)
    raw_meg.info['bads'] = ['MEG 0141']
    data1 = raw_meg[pick, :][0][0]

    raw_meg.info.normalize_proj()
    data2 = raw_meg.interpolate_bads(reset_bads=False)[pick, :][0][0]
    assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
    # the same number of bads as before
    assert_true(len(raw_meg.info['bads']) == len(raw_meg.info['bads']))

    # MEG -- epochs
    data1 = epochs_meg.get_data()[:, pick, :].ravel()
    epochs_meg.info.normalize_proj()
    epochs_meg.interpolate_bads()
    data2 = epochs_meg.get_data()[:, pick, :].ravel()
    assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
    assert_true(len(epochs_meg.info['bads']) == 0)

    # MEG -- evoked
    data1 = evoked.data[pick]
    evoked.info.normalize_proj()
    data2 = evoked.interpolate_bads().data[pick]
    assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
예제 #16
0
    def fit_ica(self, data, when='next', warm_start=False):
        """Conduct Independent Components Analysis (ICA) on a segment of data.

        The fitted ICA object is stored in the variable ica. Noisy components
        can be selected in the ICA, and then the ICA can be applied to incoming
        data to remove noise. Once fitted, ICA is applied by default to data
        when using the methods make_raw() or make_epochs().

        Components marked for removal can be accessed with self.ica.exclude.

        data : int, float, mne.RawArray
            The duration of previous or incoming data to use to fit the ICA, or
            an mne.RawArray object of data.
        when : {'previous', 'next'} (defaults to 'next')
            Whether to compute ICA on the previous or next X seconds of data.
            Can be 'next' or 'previous'. If data is type mne.RawArray, this
            parameter is ignored.
        warm_start : bool (defaults to False)
            If True, will include the EEG data from the previous fit. If False,
            will only use the data specified in the parameter data.
        """
        # Re-define ICA variable to start ICA from scratch if the ICA was
        # already fitted and user wants to fit again.
        if self.ica.current_fit != 'unfitted':
            self.ica = ICA(method='extended-infomax')

        if isinstance(data, io.RawArray):
            self.raw_for_ica = data

        elif isinstance(data, numbers.Number):
            user_index = int(data * self.info['sfreq'])
            if when.lower() not in ['previous', 'next']:
                raise ValueError("when must be 'previous' or 'next'. {} was "
                                 "passed.".format(when))
            elif when == 'previous':
                end_index = len(self.data)
                start_index = end_index - user_index
                # TODO: Check if out of bounds.

            elif when == 'next':
                start_index = len(self.data)
                end_index = start_index + user_index
                # Wait until the data is available.
                pbar = ProgressBar(end_index - start_index,
                                   mesg="Collecting data")
                while len(self.data) <= end_index:
                    # Sometimes sys.stdout.flush() raises ValueError. Is it
                    # because the while loop iterates too quickly for I/O?
                    try:
                        pbar.update(len(self.data) - start_index)
                    except ValueError:
                        pass
                print("")  # Get onto new line after progress bar finishes.

            _data = np.array([r[:] for r in
                              self.data[start_index:end_index]]).T

            # Now we have the data array in _data. Use it to make instance of
            # mne.RawArray, and then we can compute the ICA on that instance.
            _data[-1, :] = 0

            # Use previous data in addition to the specified data when fitting
            # the ICA, if the user requested this.
            if warm_start and self.raw_for_ica is not None:
                self.raw_for_ica = concatenate_raws(
                    [self.raw_for_ica, io.RawArray(_data, self.info)])
            else:
                self.raw_for_ica = io.RawArray(_data, self.info)

        logger.info("Computing ICA solution ...")
        t_0 = local_clock()
        self.ica.fit(self.raw_for_ica.copy())  # Fits in-place.
        logger.info("Finished in {:.2f} s".format(local_clock() - t_0))
예제 #17
0
def test_interpolation():
    """Test interpolation."""
    raw, epochs, epochs_eeg, epochs_meg = _load_data()

    # speed accuracy tradeoff: channel subselection is faster but the
    # correlation drops
    thresh = 0.7

    # check that interpolation does nothing if no bads are marked
    epochs_eeg.info['bads'] = []
    evoked_eeg = epochs_eeg.average()
    with pytest.warns(RuntimeWarning, match='Doing nothing'):
        evoked_eeg.interpolate_bads()

    # create good and bad channels for EEG
    epochs_eeg.info['bads'] = []
    goods_idx = np.ones(len(epochs_eeg.ch_names), dtype=bool)
    goods_idx[epochs_eeg.ch_names.index('EEG 012')] = False
    bads_idx = ~goods_idx

    evoked_eeg = epochs_eeg.average()
    ave_before = evoked_eeg.data[bads_idx]

    # interpolate bad channels for EEG
    pos = epochs_eeg._get_channel_positions()
    pos_good = pos[goods_idx]
    pos_bad = pos[bads_idx]
    interpolation = _make_interpolation_matrix(pos_good, pos_bad)
    assert interpolation.shape == (1, len(epochs_eeg.ch_names) - 1)
    ave_after = np.dot(interpolation, evoked_eeg.data[goods_idx])

    epochs_eeg.info['bads'] = ['EEG 012']
    evoked_eeg = epochs_eeg.average()
    assert_array_equal(ave_after, evoked_eeg.interpolate_bads().data[bads_idx])

    assert_allclose(ave_before, ave_after, atol=2e-6)

    # check that interpolation fails when preload is False
    epochs_eeg.preload = False
    pytest.raises(RuntimeError, epochs_eeg.interpolate_bads)
    epochs_eeg.preload = True

    # check that interpolation changes the data in raw
    raw_eeg = io.RawArray(data=epochs_eeg._data[0], info=epochs_eeg.info)
    raw_before = raw_eeg._data[bads_idx]
    raw_after = raw_eeg.interpolate_bads()._data[bads_idx]
    assert not np.all(raw_before == raw_after)

    # check that interpolation fails when preload is False
    for inst in [raw, epochs]:
        assert hasattr(inst, 'preload')
        inst.preload = False
        inst.info['bads'] = [inst.ch_names[1]]
        pytest.raises(RuntimeError, inst.interpolate_bads)

    # check that interpolation works with few channels
    raw_few = raw.copy().crop(0, 0.1).load_data()
    raw_few.pick_channels(raw_few.ch_names[:1] + raw_few.ch_names[3:4])
    assert len(raw_few.ch_names) == 2
    raw_few.del_proj()
    raw_few.info['bads'] = [raw_few.ch_names[-1]]
    orig_data = raw_few[1][0]
    with pytest.warns(None) as w:
        raw_few.interpolate_bads(reset_bads=False)
    assert len(w) == 0
    new_data = raw_few[1][0]
    assert (new_data == 0).mean() < 0.5
    assert np.corrcoef(new_data, orig_data)[0, 1] > 0.1

    # check that interpolation works when non M/EEG channels are present
    # before MEG channels
    raw.rename_channels({'MEG 0113': 'TRIGGER'})
    with pytest.warns(RuntimeWarning, match='unit .* changed from .* to .*'):
        raw.set_channel_types({'TRIGGER': 'stim'})
    raw.info['bads'] = [raw.info['ch_names'][1]]
    raw.load_data()
    raw.interpolate_bads(mode='fast')

    # check that interpolation works for MEG
    epochs_meg.info['bads'] = ['MEG 0141']
    evoked = epochs_meg.average()
    pick = pick_channels(epochs_meg.info['ch_names'], epochs_meg.info['bads'])

    # MEG -- raw
    raw_meg = io.RawArray(data=epochs_meg._data[0], info=epochs_meg.info)
    raw_meg.info['bads'] = ['MEG 0141']
    data1 = raw_meg[pick, :][0][0]

    raw_meg.info.normalize_proj()
    data2 = raw_meg.interpolate_bads(reset_bads=False,
                                     mode='fast')[pick, :][0][0]
    assert np.corrcoef(data1, data2)[0, 1] > thresh
    # the same number of bads as before
    assert len(raw_meg.info['bads']) == len(raw_meg.info['bads'])

    # MEG -- epochs
    data1 = epochs_meg.get_data()[:, pick, :].ravel()
    epochs_meg.info.normalize_proj()
    epochs_meg.interpolate_bads(mode='fast')
    data2 = epochs_meg.get_data()[:, pick, :].ravel()
    assert np.corrcoef(data1, data2)[0, 1] > thresh
    assert len(epochs_meg.info['bads']) == 0

    # MEG -- evoked (plus auto origin)
    data1 = evoked.data[pick]
    evoked.info.normalize_proj()
    data2 = evoked.interpolate_bads(origin='auto').data[pick]
    assert np.corrcoef(data1, data2)[0, 1] > thresh