Ejemplo n.º 1
0
def test_combine_channels_metadata():
    """Test if metadata is correctly retained in combined object."""
    import pandas as pd

    raw = read_raw_fif(raw_fname, preload=True)
    epochs = Epochs(raw, read_events(eve_fname), preload=True)

    metadata = pd.DataFrame({
        "A": np.arange(len(epochs)),
        "B": np.ones(len(epochs))
    })
    epochs.metadata = metadata

    good = dict(foo=[0, 1, 3, 4], bar=[5, 2])  # good grad and mag
    combined_epochs = combine_channels(epochs, good)
    pd.testing.assert_frame_equal(epochs.metadata, combined_epochs.metadata)
Ejemplo n.º 2
0
    evoked_file = f'{sub}_task-{task}_ref-avg_lpf-none_ave.fif.gz'
    scene_diff = read_evokeds(out_erps / evoked_file,
                              condition='scene-object',
                              verbose=False)
    face_diff = read_evokeds(out_erps / evoked_file,
                             condition='face-object',
                             verbose=False)

    # Make virtual electrodes
    new_chans = {
        'mean(P7/PO7)': pick_channels(scene_diff.info['ch_names'],
                                      ['PO7', 'P7']),
        'mean(P8/PO8)': pick_channels(scene_diff.info['ch_names'],
                                      ['PO8', 'P8'])
    }
    scene_diff = combine_channels(scene_diff, new_chans)
    face_diff = combine_channels(face_diff, new_chans)

    # Extract data
    scene_peaks = mean_amplitude(scene_diff, tmin=.15, tmax=.224)
    scene_peaks.insert(0, 'id', sub.replace('sub-', ''))
    scene_peaks.insert(1, 'age_group', age)
    scene_peaks.insert(2, 'condition', 'scene')
    scene_peaks.insert(3, 'hemisphere', ['left', 'right'])
    face_peaks = mean_amplitude(face_diff, tmin=.1, tmax=.17)
    face_peaks.insert(0, 'id', sub.replace('sub-', ''))
    face_peaks.insert(1, 'age_group', age)
    face_peaks.insert(2, 'condition', 'face')
    face_peaks.insert(3, 'hemisphere', ['left', 'right'])
    sub_df = pd.concat([scene_peaks, face_peaks])
Ejemplo n.º 3
0
def test_combine_channels():
    """Test channel combination on Raw, Epochs, and Evoked."""
    raw = read_raw_fif(raw_fname, preload=True)
    raw_ch_bad = read_raw_fif(raw_fname, preload=True)
    raw_ch_bad.info['bads'] = ['MEG 0113', 'MEG 0112']
    epochs = Epochs(raw, read_events(eve_fname))
    evoked = epochs.average()
    good = dict(foo=[0, 1, 3, 4], bar=[5, 2])  # good grad and mag

    # Test good cases
    combine_channels(raw, good)
    combine_channels(epochs, good)
    combine_channels(evoked, good)
    combine_channels(raw, good, drop_bad=True)
    combine_channels(raw_ch_bad, good, drop_bad=True)

    # Test with stimulus channels
    combine_stim = combine_channels(raw, good, keep_stim=True)
    target_nchan = len(good) + len(pick_types(raw.info, meg=False, stim=True))
    assert combine_stim.info['nchan'] == target_nchan

    # Test results with one ROI
    good_single = dict(foo=[0, 1, 3, 4])  # good grad
    combined_mean = combine_channels(raw, good_single, method='mean')
    combined_median = combine_channels(raw, good_single, method='median')
    combined_std = combine_channels(raw, good_single, method='std')
    foo_mean = np.mean(raw.get_data()[good_single['foo']], axis=0)
    foo_median = np.median(raw.get_data()[good_single['foo']], axis=0)
    foo_std = np.std(raw.get_data()[good_single['foo']], axis=0)
    assert np.array_equal(combined_mean.get_data(),
                          np.expand_dims(foo_mean, axis=0))
    assert np.array_equal(combined_median.get_data(),
                          np.expand_dims(foo_median, axis=0))
    assert np.array_equal(combined_std.get_data(),
                          np.expand_dims(foo_std, axis=0))

    # Test bad cases
    bad1 = dict(foo=[0, 376], bar=[5, 2])  # out of bounds
    bad2 = dict(foo=[0, 2], bar=[5, 2])  # type mix in same group
    with pytest.raises(ValueError, match='"method" must be a callable, or'):
        combine_channels(raw, good, method='bad_method')
    with pytest.raises(TypeError, match='"keep_stim" must be of type bool'):
        combine_channels(raw, good, keep_stim='bad_type')
    with pytest.raises(TypeError, match='"drop_bad" must be of type bool'):
        combine_channels(raw, good, drop_bad='bad_type')
    with pytest.raises(ValueError, match='Some channel indices are out of'):
        combine_channels(raw, bad1)
    with pytest.raises(ValueError, match='Cannot combine sensors of diff'):
        combine_channels(raw, bad2)

    # Test warnings
    raw_no_stim = read_raw_fif(raw_fname, preload=True)
    raw_no_stim.pick_types(meg=True, stim=False)
    warn1 = dict(foo=[375, 375], bar=[5, 2])  # same channel in same group
    warn2 = dict(foo=[375], bar=[5, 2])  # one channel (last channel)
    warn3 = dict(foo=[0, 4], bar=[5, 2])  # one good channel left
    with pytest.warns(RuntimeWarning, match='Could not find stimulus'):
        combine_channels(raw_no_stim, good, keep_stim=True)
    with pytest.warns(RuntimeWarning, match='Less than 2 channels') as record:
        combine_channels(raw, warn1)
        combine_channels(raw, warn2)
        combine_channels(raw_ch_bad, warn3, drop_bad=True)
    assert len(record) == 3
Ejemplo n.º 4
0
def get_erp_measures_from_cross_condition_data(
    erp_arrays: List[EvokedArray],
    cross_condition_data: pd.DataFrame,
    interval_in_seconds: float,
):
    erp_measures = pd.DataFrame(columns=[
        "fid",
        "ch_name",
        "tmin",
        "tmax",
        "mode",
        "peak_latency",
        "peak_amplitude",
        "mean_amplitude",
    ])

    picks = cross_condition_data['ch_name'].values[0].split()
    mode = cross_condition_data['mode'].values[0]
    for erp in erp_arrays:
        picks_idx = pick_channels(erp.info['ch_names'], include=picks)

        if len(picks_idx) > 1:
            roi_erp = combine_channels(erp, dict(roi=picks_idx), method='mean')
            tmin = cross_condition_data['peak_latency'].values[
                0] - interval_in_seconds
            tmax = cross_condition_data['peak_latency'].values[
                0] + interval_in_seconds

            if tmax > erp.tmax:
                tmax = erp.tmax
            if tmin < erp.tmin:
                tmin = erp.tmin

            _, lat, amp = roi_erp.get_peak(ch_type='eeg',
                                           tmin=tmin,
                                           tmax=tmax,
                                           mode=mode,
                                           return_amplitude=True)

            mean_amp = get_mean_amplitude(erp=roi_erp,
                                          tmin=tmin,
                                          tmax=tmax,
                                          mode=mode)

            fid = Path(erp.comment.replace("\\", "/")).name
            ch_name = cross_condition_data['ch_name'].values[0]
            erp_measures = erp_measures.append(dict(fid=fid,
                                                    ch_name=ch_name,
                                                    tmin=tmin,
                                                    tmax=tmax,
                                                    mode=mode,
                                                    peak_latency=lat,
                                                    peak_amplitude=amp * 1e6,
                                                    mean_amplitude=mean_amp),
                                               ignore_index=True)

        else:
            for ch_name in cross_condition_data['ch_name']:
                tmin = cross_condition_data[
                    cross_condition_data['ch_name'] ==
                    ch_name]['peak_latency'] - interval_in_seconds
                tmax = cross_condition_data[
                    cross_condition_data['ch_name'] ==
                    ch_name]['peak_latency'] + interval_in_seconds

                tmin = tmin.values[0]
                tmax = tmax.values[0]

                if tmax > erp.tmax:
                    tmax = erp.tmax
                if tmin < erp.tmin:
                    tmin = erp.tmin

                _, lat, amp = erp.copy().pick(ch_name).get_peak(
                    ch_type='eeg',
                    tmin=tmin,
                    tmax=tmax,
                    mode=mode,
                    return_amplitude=True)

                mean_amp = get_mean_amplitude(erp=erp.copy().pick(ch_name),
                                              tmin=tmin,
                                              tmax=tmax,
                                              mode=mode)

                fid = Path(erp.comment.replace("\\", "/")).name
                erp_measures = erp_measures.append(dict(
                    fid=fid,
                    ch_name=ch_name,
                    tmin=tmin,
                    tmax=tmax,
                    mode=mode,
                    peak_latency=lat,
                    peak_amplitude=amp * 1e6,
                    mean_amplitude=mean_amp),
                                                   ignore_index=True)

    return erp_measures
Ejemplo n.º 5
0
def get_erp_peak_measures(erp: EvokedArray,
                          tmin: float,
                          tmax: float,
                          mode: str,
                          picks=None,
                          combine='mean') -> pd.DataFrame:
    """
    Computes peak measures (peak latency, peak amplitude) from Evoked instance for a
    given time interval defined by tmin and tmax in seconds. Peak measures can be
    computed for ROIs (averages data over given list of channels) by defining the list
    of channel names (e.g. ['F2', 'F5', 'F7']) that will be aggregated first,
    and then the measures computed.
    If picks is not defined, peak measures are computed for each channel.
    Parameters
    ----------
    erp
    tmin
    tmax
    mode: 'pos': finds the peak with a positive voltage (ignores negative voltages)
    'neg': finds the peak with a negative voltage (ignores positive voltages)
    'abs': finds the peak with the largest absolute voltage regardless of sign (positive or negative)
    combine: whether to combine channels (defined by picks) using 'mean', 'median' or 'std'
    use None to not combine channels but get peak measures separately for each channel
    picks

    Returns
    -------
    DataFrame containing the peak measures for each channel or for a given ROI
    """
    if picks is None:
        picks = []

    erp_measures = pd.DataFrame(columns=[
        "fid",
        "ch_name",
        "tmin",
        "tmax",
        "mode",
        "peak_latency",
        "peak_amplitude",
    ])

    if combine:
        picks_idx = pick_channels(erp.info["ch_names"], include=picks)
        roi_erp = combine_channels(erp, dict(roi=picks_idx), method=combine)
        _, lat, amp = roi_erp.get_peak(ch_type='eeg',
                                       tmin=tmin,
                                       tmax=tmax,
                                       mode=mode,
                                       return_amplitude=True)

        ch_name = ' '.join(picks)
        erp_measures = erp_measures.append(dict(fid=erp.comment,
                                                ch_name=ch_name,
                                                tmin=tmin,
                                                tmax=tmax,
                                                mode=mode,
                                                peak_latency=lat,
                                                peak_amplitude=amp * 1e6),
                                           ignore_index=True)

    else:
        for ch_name in picks:
            _, lat, amp = erp.copy().pick(ch_name).get_peak(
                ch_type='eeg',
                tmin=tmin,
                tmax=tmax,
                mode=mode,
                return_amplitude=True)

            erp_measures = erp_measures.append(dict(fid=erp.comment,
                                                    ch_name=ch_name,
                                                    tmin=tmin,
                                                    tmax=tmax,
                                                    mode=mode,
                                                    peak_latency=lat,
                                                    peak_amplitude=amp * 1e6),
                                               ignore_index=True)

    return erp_measures
Ejemplo n.º 6
0
###############################################################################
# Evoked response averaged across channels by ROI
# -----------------------------------------------
#
# It is possible to average channels by region of interest (for example left
# and right) when studying the response to this left auditory stimulus. Here we
# use our Raw object on which the average reference projection has been added
# back.
evoked = mne.Epochs(raw, **epochs_params).average()

left_idx = mne.pick_channels(evoked.info['ch_names'],
                             ['EEG 017', 'EEG 018', 'EEG 025', 'EEG 026'])
right_idx = mne.pick_channels(evoked.info['ch_names'],
                              ['EEG 023', 'EEG 024', 'EEG 034', 'EEG 035'])
roi_dict = dict(Left=left_idx, Right=right_idx)
evoked_combined = combine_channels(evoked, roi_dict, method='mean')

title = 'Evoked response averaged by side'
evoked_combined.plot(titles=dict(eeg=title), time_unit='s')

###############################################################################
# Evoked arithmetic (e.g. differences)
# ------------------------------------
#
# Trial subsets from Epochs can be selected using 'tags' separated by '/'.
# Evoked objects support basic arithmetic.
# First, we create an Epochs object containing 4 conditions.

event_id = {'left/auditory': 1, 'right/auditory': 2,
            'left/visual': 3, 'right/visual': 4}
epochs_params = dict(events=events, event_id=event_id, tmin=tmin, tmax=tmax,