예제 #1
0
def test_ica_labels():
    """Test ICA labels."""
    # The CTF data are uniquely well suited to testing the ICA.find_bads_
    # methods
    raw = read_raw_ctf(ctf_fname, preload=True)

    # set the appropriate EEG channels to EOG and ECG
    raw.set_channel_types({'EEG057': 'eog', 'EEG058': 'eog', 'EEG059': 'ecg'})
    ica = ICA(n_components=4, random_state=0, max_iter=2, method='fastica',
              allow_ref_meg=True)
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(raw)
    _assert_ica_attributes(ica)

    ica.find_bads_eog(raw, l_freq=None, h_freq=None)
    picks = list(pick_types(raw.info, meg=False, eog=True))
    for idx, ch in enumerate(picks):
        assert '{}/{}/{}'.format('eog', idx, raw.ch_names[ch]) in ica.labels_
    assert 'eog' in ica.labels_
    for key in ('ecg', 'ref_meg', 'ecg/ECG-MAG'):
        assert key not in ica.labels_

    ica.find_bads_ecg(raw, l_freq=None, h_freq=None, method='correlation',
                      threshold='auto')
    picks = list(pick_types(raw.info, meg=False, ecg=True))
    for idx, ch in enumerate(picks):
        assert '{}/{}/{}'.format('ecg', idx, raw.ch_names[ch]) in ica.labels_
    for key in ('ecg', 'eog'):
        assert key in ica.labels_
    for key in ('ref_meg', 'ecg/ECG-MAG'):
        assert key not in ica.labels_

    # derive reference ICA components and append them to raw
    ica_rf = ICA(n_components=2, random_state=0, max_iter=2,
                 allow_ref_meg=True)
    with pytest.warns(UserWarning, match='did not converge'):
        ica_rf.fit(raw.copy().pick_types(meg=False, ref_meg=True))
    icacomps = ica_rf.get_sources(raw)
    # rename components so they are auto-detected by find_bads_ref
    icacomps.rename_channels({c: 'REF_' + c for c in icacomps.ch_names})
    # and add them to raw
    raw.add_channels([icacomps])
    ica.find_bads_ref(raw, l_freq=None, h_freq=None, method="separate")
    picks = pick_channels_regexp(raw.ch_names, 'REF_ICA*')
    for idx, ch in enumerate(picks):
        assert '{}/{}/{}'.format('ref_meg', idx,
                                 raw.ch_names[ch]) in ica.labels_
    ica.find_bads_ref(raw, l_freq=None, h_freq=None, method="together")
    assert 'ref_meg' in ica.labels_

    for key in ('ecg', 'eog', 'ref_meg'):
        assert key in ica.labels_
    assert 'ecg/ECG-MAG' not in ica.labels_

    ica.find_bads_ecg(raw, l_freq=None, h_freq=None, threshold='auto')
    for key in ('ecg', 'eog', 'ref_meg', 'ecg/ECG-MAG'):
        assert key in ica.labels_
예제 #2
0
def test_ica_labels():
    """Test ICA labels."""
    # The CTF data are uniquely well suited to testing the ICA.find_bads_
    # methods
    raw = read_raw_ctf(ctf_fname, preload=True)
    # derive reference ICA components and append them to raw
    icarf = ICA(n_components=2, random_state=0, max_iter=2, allow_ref_meg=True)
    with pytest.warns(UserWarning, match='did not converge'):
        icarf.fit(raw.copy().pick_types(meg=False, ref_meg=True))
    icacomps = icarf.get_sources(raw)
    # rename components so they are auto-detected by find_bads_ref
    icacomps.rename_channels({c: 'REF_' + c for c in icacomps.ch_names})
    # and add them to raw
    raw.add_channels([icacomps])
    # set the appropriate EEG channels to EOG and ECG
    raw.set_channel_types({'EEG057': 'eog', 'EEG058': 'eog', 'EEG059': 'ecg'})
    ica = ICA(n_components=4, random_state=0, max_iter=2, method='fastica')
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(raw)

    ica.find_bads_eog(raw, l_freq=None, h_freq=None)
    picks = list(pick_types(raw.info, meg=False, eog=True))
    for idx, ch in enumerate(picks):
        assert '{}/{}/{}'.format('eog', idx, raw.ch_names[ch]) in ica.labels_
    assert 'eog' in ica.labels_
    for key in ('ecg', 'ref_meg', 'ecg/ECG-MAG'):
        assert key not in ica.labels_

    ica.find_bads_ecg(raw, l_freq=None, h_freq=None, method='correlation')
    picks = list(pick_types(raw.info, meg=False, ecg=True))
    for idx, ch in enumerate(picks):
        assert '{}/{}/{}'.format('ecg', idx, raw.ch_names[ch]) in ica.labels_
    for key in ('ecg', 'eog'):
        assert key in ica.labels_
    for key in ('ref_meg', 'ecg/ECG-MAG'):
        assert key not in ica.labels_

    ica.find_bads_ref(raw, l_freq=None, h_freq=None)
    picks = pick_channels_regexp(raw.ch_names, 'REF_ICA*')
    for idx, ch in enumerate(picks):
        assert '{}/{}/{}'.format('ref_meg', idx,
                                 raw.ch_names[ch]) in ica.labels_
    for key in ('ecg', 'eog', 'ref_meg'):
        assert key in ica.labels_
    assert 'ecg/ECG-MAG' not in ica.labels_

    ica.find_bads_ecg(raw, l_freq=None, h_freq=None)
    for key in ('ecg', 'eog', 'ref_meg', 'ecg/ECG-MAG'):
        assert key in ica.labels_
예제 #3
0
def run_ica(raw, ica_fname=None, picks=None, n_max_ecg=3, n_max_eog=1):
    raw_f = raw.copy().filter(1,
                              45,
                              n_jobs=1,
                              l_trans_bandwidth=0.5,
                              h_trans_bandwidth=0.5,
                              filter_length='10s',
                              phase='zero-double')

    ica = ICA(method='fastica', random_state=42, n_components=0.98)
    if picks is None:
        picks = mne.pick_types(raw_f.info,
                               meg=True,
                               eeg=False,
                               eog=False,
                               stim=False,
                               exclude='bads')
    ica.fit(raw_f, picks=picks, reject=dict(grad=4000e-13, mag=4e-12), decim=3)
    ecg_epochs = create_ecg_epochs(raw_f, tmin=-.5, tmax=.5, picks=picks)
    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    ecg_inds = ecg_inds[:n_max_ecg]
    ica.exclude += ecg_inds
    eog_inds, scores = ica.find_bads_eog(raw_f)
    eog_inds = eog_inds[:n_max_eog]
    ica.exclude += eog_inds
    if ica_fname is None:
        ica_fname = raw_f._filenames[0][:-4] + '-pyimpress-ica.fif'
    ica.save(ica_fname)
    return ica, ica_fname
예제 #4
0
파일: meg_utils.py 프로젝트: hyruuk/hytools
def inscapesMEG_PP(fname, DATA_FOLDER, SAVE_FOLDER):
    fpath = DATA_FOLDER + fname
    raw = read_raw_ctf(fpath, preload=True)
    picks = mne.pick_types(raw.info, meg=True, eog=True, exclude='bads')
    raw.plot()
    raw.plot_psd(average=False, picks=picks)

    ## Filtering
    high_cutoff = 200
    low_cutoff = 0.5
    raw.filter(low_cutoff, high_cutoff, fir_design="firwin")
    raw.notch_filter(np.arange(60, high_cutoff + 1, 60),
                     picks=picks,
                     filter_length='auto',
                     phase='zero',
                     fir_design="firwin")
    raw.plot_psd(average=False, picks=picks)

    ## ICA
    ica = ICA(n_components=20, random_state=0).fit(raw, decim=3)
    ica.plot_sources(raw)
    fmax = 40.  ## correlation threshold for ICA components (maybe increase to 40. ?)

    ## FIND ECG COMPONENTS
    ecg_epochs = create_ecg_epochs(raw, ch_name='EEG059')
    ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs, ch_name='EEG059')
    ica.plot_scores(ecg_scores, ecg_inds)
    ica.plot_properties(ecg_epochs,
                        picks=ecg_inds,
                        psd_args={'fmax': fmax},
                        image_args={'sigma': 1.})

    ## FIND EOG COMPONENTS
    eog_epochs = create_eog_epochs(raw, ch_name='EEG057')
    eog_inds, eog_scores = ica.find_bads_eog(eog_epochs, ch_name='EEG057')
    ica.plot_scores(eog_scores, eog_inds)
    ica.plot_properties(eog_epochs,
                        picks=eog_inds,
                        psd_args={'fmax': fmax},
                        image_args={'sigma': 1.})

    ## EXCLUDE COMPONENTS
    ica.exclude = ecg_inds
    ica.apply(raw)
    ica.exclude = eog_inds
    ica.apply(raw)
    raw.plot()
    # Plot the clean signal.

    ## SAVE PREPROCESSED FILE
    time.sleep(60)
    raw.save(SAVE_FOLDER + fname + '_preprocessed.fif.gz', overwrite=True)
    time.sleep(30)
    filename = SAVE_FOLDER + fname + '_log.html'
    #!jupyter nbconvert inscapesMEG_preproc.ipynb --output $filename
    clear_output()
예제 #5
0
def fit_ica_and_plot_scores(method, random_state, tol=1e-4):
    ica = ICA(n_components=0.95, method=method, random_state=random_state,
              fit_params={'tol': tol}, max_iter=400)
    t0 = time()
    ica.fit(raw.copy(), picks=picks, decim=3,
            reject=dict(mag=4e-12, grad=4000e-13), verbose='warning')
    fit_time = time() - t0
    title = ('Method : %s, init %d. Took %.2g sec.'
             % (method, random_state + 1, fit_time))
    ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=picks)

    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    ica.plot_scores(scores, exclude=ecg_inds, title=title)
    ica.plot_components(ecg_inds, colorbar=True)
예제 #6
0
def preprocess_ICA_fif_to_ts(fif_file, ECG_ch_name, EoG_ch_name, l_freq, h_freq):
    # ------------------------ Import stuff ------------------------ #
    import os
    import mne
    import sys
    from mne.io import Raw
    from mne.preprocessing import ICA
    from mne.preprocessing import create_ecg_epochs, create_eog_epochs
    from nipype.utils.filemanip import split_filename as split_f
    from reportGen import generateReport
    import pickle

    subj_path, basename, ext = split_f(fif_file)
    # -------------------- Delete later ------------------- #
    subj_name = subj_path[-5:]
    results_dir = subj_path[:-6]
    # results_dir += '2016'
    subj_path = results_dir + '/' + subj_name
    if not os.path.exists(subj_path):
        try:
            os.makedirs(subj_path)
        except OSError:
            sys.stderr.write('ica_preproc: problem creating directory: ' + subj_path)
    ########################################################
    # Read raw
    #   If None the compensation in the data is not modified. If set to n, e.g. 3, apply
    #   gradient compensation of grade n as for CTF systems (compensation=3)
    print(fif_file)
    print(EoG_ch_name)
    #  ----------------------------- end Import stuff ----------------- #
    # EoG_ch_name = "EOG061, EOG062"

    # ------------- Load raw ------------- #
    raw = Raw(fif_file, preload=True)
    # select sensors
    select_sensors = mne.pick_types(raw.info, meg=True, ref_meg=False, exclude='bads')
    picks_meeg = mne.pick_types(raw.info, meg=True, eeg=True, exclude='bads')

    # filtering
    raw.filter(l_freq=l_freq, h_freq=h_freq, picks=picks_meeg, method='iir', n_jobs=1)

    # if ECG_ch_name == 'EMG063':
    if ECG_ch_name in raw.info['ch_names']:
        raw.set_channel_types({ECG_ch_name: 'ecg'})  # Without this files with ECG_ch_name = 'EMG063' fail
        # ECG_ch_name = 'ECG063'
    if EoG_ch_name == 'EMG065,EMG066,EMG067,EMG068':   # Because ica.find_bads_eog... can process max 2 EoG channels
        EoG_ch_name = 'EMG065,EMG067'                 # it won't fail if I specify 4 channels, but it'll use only first
                                                      # EMG065 and EMG066 are for vertical eye movements and
                                                      # EMG067 and EMG068 are for horizontal

    # print rnk
    rnk = 'N/A'
    # 1) Fit ICA model using the FastICA algorithm
    # Other available choices are `infomax` or `extended-infomax`
    # We pass a float value between 0 and 1 to select n_components based on the
    # percentage of variance explained by the PCA components.
    reject = dict(mag=10e-12, grad=10000e-13)
    flat = dict(mag=0.1e-12, grad=1e-13)
    # check if we have an ICA, if yes, we load it
    ica_filename = os.path.join(subj_path, basename + "-ica.fif")
    raw_ica_filename = os.path.join(subj_path, basename + "_ica_raw.fif")
    info_filename = os.path.join(subj_path, basename + "_info.pickle")
    # if os.path.exists(ica_filename) == False:
    ica = ICA(n_components=0.99, method='fastica')  # , max_iter=500
    ica.fit(raw, picks=select_sensors, reject=reject, flat=flat)  # decim = 3,
    # has_ICA = False
    # else:
    #     has_ICA = True
    #     ica = read_ica(ica_filename)
    #     ica.exclude = []
    # ica.labels_ = dict() # to avoid bug; Otherwise it'll throw an exception

    ica_sources_filename = subj_path + '/' + basename + '_ica_timecourse.fif'

    # if not os.path.isfile(ica_sources_filename):
    icaSrc = ica.get_sources(raw, add_channels=None, start=None, stop=None)
    icaSrc.save(ica_sources_filename, picks=None, tmin=0, tmax=None, buffer_size_sec=10,
                drop_small_buffer=False, proj=False, fmt='single', overwrite=True, split_size='2GB', verbose=None)
    icaSrc = None
    # if has_ICA == False:
    # ica.save(ica_filename)
    # return
    # 2) identify bad components by analyzing latent sources.
    # generate ECG epochs use detection via phase statistics

    # check if ECG_ch_name is in the raw channels
    # import ipdb; ipdb.set_trace()
    if ECG_ch_name in raw.info['ch_names']:
        ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=select_sensors, ch_name=ECG_ch_name)
    # if not  a synthetic ECG channel is created from cross channel average
    else:
        ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=select_sensors)
    # ICA for ECG artifact
    # threshold=0.25 come defualt
    ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs, method='ctps', threshold=0.25)
    # if len(ecg_inds) > 0:
    ecg_evoked = ecg_epochs.average()
    ecg_epochs = None    # ecg_epochs use too much memory
    n_max_ecg = 3
    ecg_inds = ecg_inds[:n_max_ecg]
    ica.exclude += ecg_inds
    n_max_eog = 4
    # import pdb; pdb.set_trace()
    if set(EoG_ch_name.split(',')).issubset(set(raw.info['ch_names'])):
        eog_inds, eog_scores = ica.find_bads_eog(raw, ch_name=EoG_ch_name)
        eog_inds = eog_inds[:n_max_eog]
        eog_evoked = create_eog_epochs(raw, tmin=-.5, tmax=.5, picks=select_sensors, ch_name=EoG_ch_name).average()
    else:
        eog_inds = eog_scores = eog_evoked = []
    # ------------------------------------------------------ #
    # This is necessary. Otherwise line
    # will through an exception
    if not eog_inds:
        eog_inds = None
    # ------------------------------------------------------ #
    generateReport(raw=raw, ica=ica, subj_name=subj_name, subj_path=subj_path, basename=basename,
                   ecg_evoked=ecg_evoked, ecg_scores=ecg_scores, ecg_inds=ecg_inds, ECG_ch_name=ECG_ch_name,
                   eog_evoked=eog_evoked, eog_scores=eog_scores, eog_inds=eog_inds, EoG_ch_name=EoG_ch_name)

    sfreq = raw.info['sfreq']
    raw = None  # To save memory
            
    # save ICA solution
    print ica_filename

    # ------------------------- Generate log ------------------------ #
    f = open(subj_path + '/' + basename + '_ica.log', 'w')
    f.write('Data rank after SSS: ' + str(rnk) + '\n')
    f.write('Sampling freq: ' + str(sfreq) + '\n')
    f.write('ECG exclude suggested: ' + str(ecg_inds) + '\n')
    f.write('EOG exclude suggested: ' + str(eog_inds) + '\n')
    f.write('\n')
    f.write('ECG exclude final: ' + str(ecg_inds) + '\n')
    f.write('EOG exclude final: ' + str(eog_inds) + '\n')
    f.write('Muscles exclude: []' + '\n')
    f.close()
    # ------------------------ end generate log ---------------------- #
    with open(info_filename, 'wb') as f:
        pickle.dump(ecg_inds, f)
        pickle.dump(ecg_scores, f)
        pickle.dump(eog_inds, f)
        pickle.dump(eog_scores, f)
    # -------------------- Save ICA solution ------------------------- #
    ica.save(ica_filename)

    return raw_ica_filename, sfreq
예제 #7
0
def test_ica_additional(method):
    """Test additional ICA functionality."""
    _skip_check_picard(method)

    tempdir = _TempDir()
    stop2 = 500
    raw = read_raw_fif(raw_fname).crop(1.5, stop).load_data()
    raw.del_proj()  # avoid warnings
    raw.set_annotations(Annotations([0.5], [0.5], ['BAD']))
    # XXX This breaks the tests :(
    # raw.info['bads'] = [raw.ch_names[1]]
    test_cov = read_cov(test_cov_name)
    events = read_events(event_name)
    picks = pick_types(raw.info, meg=True, stim=False, ecg=False,
                       eog=False, exclude='bads')[1::2]
    epochs = Epochs(raw, events, None, tmin, tmax, picks=picks,
                    baseline=(None, 0), preload=True, proj=False)
    epochs.decimate(3, verbose='error')
    assert len(epochs) == 4

    # test if n_components=None works
    ica = ICA(n_components=None, max_pca_components=None,
              n_pca_components=None, random_state=0, method=method, max_iter=1)
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(epochs)
    # for testing eog functionality
    picks2 = np.concatenate([picks, pick_types(raw.info, False, eog=True)])
    epochs_eog = Epochs(raw, events[:4], event_id, tmin, tmax, picks=picks2,
                        baseline=(None, 0), preload=True)
    del picks2

    test_cov2 = test_cov.copy()
    ica = ICA(noise_cov=test_cov2, n_components=3, max_pca_components=4,
              n_pca_components=4, method=method)
    assert (ica.info is None)
    with pytest.warns(RuntimeWarning, match='normalize_proj'):
        ica.fit(raw, picks[:5])
    assert (isinstance(ica.info, Info))
    assert (ica.n_components_ < 5)

    ica = ICA(n_components=3, max_pca_components=4, method=method,
              n_pca_components=4, random_state=0)
    pytest.raises(RuntimeError, ica.save, '')

    ica.fit(raw, picks=[1, 2, 3, 4, 5], start=start, stop=stop2)

    # check passing a ch_name to find_bads_ecg
    with pytest.warns(RuntimeWarning, match='longer'):
        _, scores_1 = ica.find_bads_ecg(raw)
        _, scores_2 = ica.find_bads_ecg(raw, raw.ch_names[1])
    assert scores_1[0] != scores_2[0]

    # test corrmap
    ica2 = ica.copy()
    ica3 = ica.copy()
    corrmap([ica, ica2], (0, 0), threshold='auto', label='blinks', plot=True,
            ch_type="mag")
    corrmap([ica, ica2], (0, 0), threshold=2, plot=False, show=False)
    assert (ica.labels_["blinks"] == ica2.labels_["blinks"])
    assert (0 in ica.labels_["blinks"])
    # test retrieval of component maps as arrays
    components = ica.get_components()
    template = components[:, 0]
    EvokedArray(components, ica.info, tmin=0.).plot_topomap([0], time_unit='s')

    corrmap([ica, ica3], template, threshold='auto', label='blinks', plot=True,
            ch_type="mag")
    assert (ica2.labels_["blinks"] == ica3.labels_["blinks"])

    plt.close('all')

    ica_different_channels = ICA(n_components=2, random_state=0).fit(
        raw, picks=[2, 3, 4, 5])
    pytest.raises(ValueError, corrmap, [ica_different_channels, ica], (0, 0))

    # test warnings on bad filenames
    ica_badname = op.join(op.dirname(tempdir), 'test-bad-name.fif.gz')
    with pytest.warns(RuntimeWarning, match='-ica.fif'):
        ica.save(ica_badname)
    with pytest.warns(RuntimeWarning, match='-ica.fif'):
        read_ica(ica_badname)

    # test decim
    ica = ICA(n_components=3, max_pca_components=4,
              n_pca_components=4, method=method, max_iter=1)
    raw_ = raw.copy()
    for _ in range(3):
        raw_.append(raw_)
    n_samples = raw_._data.shape[1]
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(raw, picks=picks[:5], decim=3)
    assert raw_._data.shape[1] == n_samples

    # test expl var
    ica = ICA(n_components=1.0, max_pca_components=4,
              n_pca_components=4, method=method, max_iter=1)
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(raw, picks=None, decim=3)
    assert (ica.n_components_ == 4)
    ica_var = _ica_explained_variance(ica, raw, normalize=True)
    assert (np.all(ica_var[:-1] >= ica_var[1:]))

    # test ica sorting
    ica.exclude = [0]
    ica.labels_ = dict(blink=[0], think=[1])
    ica_sorted = _sort_components(ica, [3, 2, 1, 0], copy=True)
    assert_equal(ica_sorted.exclude, [3])
    assert_equal(ica_sorted.labels_, dict(blink=[3], think=[2]))

    # epochs extraction from raw fit
    pytest.raises(RuntimeError, ica.get_sources, epochs)
    # test reading and writing
    test_ica_fname = op.join(op.dirname(tempdir), 'test-ica.fif')
    for cov in (None, test_cov):
        ica = ICA(noise_cov=cov, n_components=2, max_pca_components=4,
                  n_pca_components=4, method=method, max_iter=1)
        with pytest.warns(None):  # ICA does not converge
            ica.fit(raw, picks=picks[:10], start=start, stop=stop2)
        sources = ica.get_sources(epochs).get_data()
        assert (ica.mixing_matrix_.shape == (2, 2))
        assert (ica.unmixing_matrix_.shape == (2, 2))
        assert (ica.pca_components_.shape == (4, 10))
        assert (sources.shape[1] == ica.n_components_)

        for exclude in [[], [0], np.array([1, 2, 3])]:
            ica.exclude = exclude
            ica.labels_ = {'foo': [0]}
            ica.save(test_ica_fname)
            ica_read = read_ica(test_ica_fname)
            assert (list(ica.exclude) == ica_read.exclude)
            assert_equal(ica.labels_, ica_read.labels_)
            ica.apply(raw)
            ica.exclude = []
            ica.apply(raw, exclude=[1])
            assert (ica.exclude == [])

            ica.exclude = [0, 1]
            ica.apply(raw, exclude=[1])
            assert (ica.exclude == [0, 1])

            ica_raw = ica.get_sources(raw)
            assert (ica.exclude == [ica_raw.ch_names.index(e) for e in
                                    ica_raw.info['bads']])

        # test filtering
        d1 = ica_raw._data[0].copy()
        ica_raw.filter(4, 20, fir_design='firwin2')
        assert_equal(ica_raw.info['lowpass'], 20.)
        assert_equal(ica_raw.info['highpass'], 4.)
        assert ((d1 != ica_raw._data[0]).any())
        d1 = ica_raw._data[0].copy()
        ica_raw.notch_filter([10], trans_bandwidth=10, fir_design='firwin')
        assert ((d1 != ica_raw._data[0]).any())

        ica.n_pca_components = 2
        ica.method = 'fake'
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        assert (ica.n_pca_components == ica_read.n_pca_components)
        assert_equal(ica.method, ica_read.method)
        assert_equal(ica.labels_, ica_read.labels_)

        # check type consistency
        attrs = ('mixing_matrix_ unmixing_matrix_ pca_components_ '
                 'pca_explained_variance_ pre_whitener_')

        def f(x, y):
            return getattr(x, y).dtype

        for attr in attrs.split():
            assert_equal(f(ica_read, attr), f(ica, attr))

        ica.n_pca_components = 4
        ica_read.n_pca_components = 4

        ica.exclude = []
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        for attr in ['mixing_matrix_', 'unmixing_matrix_', 'pca_components_',
                     'pca_mean_', 'pca_explained_variance_',
                     'pre_whitener_']:
            assert_array_almost_equal(getattr(ica, attr),
                                      getattr(ica_read, attr))

        assert (ica.ch_names == ica_read.ch_names)
        assert (isinstance(ica_read.info, Info))

        sources = ica.get_sources(raw)[:, :][0]
        sources2 = ica_read.get_sources(raw)[:, :][0]
        assert_array_almost_equal(sources, sources2)

        _raw1 = ica.apply(raw, exclude=[1])
        _raw2 = ica_read.apply(raw, exclude=[1])
        assert_array_almost_equal(_raw1[:, :][0], _raw2[:, :][0])

    os.remove(test_ica_fname)
    # check score funcs
    for name, func in get_score_funcs().items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(raw, target='EOG 061', score_func=func,
                                   start=0, stop=10)
        assert (ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(raw, start=0, stop=50, score_func=stats.skew)
    # check exception handling
    pytest.raises(ValueError, ica.score_sources, raw,
                  target=np.arange(1))

    params = []
    params += [(None, -1, slice(2), [0, 1])]  # variance, kurtosis params
    params += [(None, 'MEG 1531')]  # ECG / EOG channel params
    for idx, ch_name in product(*params):
        ica.detect_artifacts(raw, start_find=0, stop_find=50, ecg_ch=ch_name,
                             eog_ch=ch_name, skew_criterion=idx,
                             var_criterion=idx, kurt_criterion=idx)

    # Make sure detect_artifacts marks the right components.
    # For int criterion, the doc says "E.g. range(2) would return the two
    # sources with the highest score". Assert that's what it does.
    # Only test for skew, since it's always the same code.
    ica.exclude = []
    ica.detect_artifacts(raw, start_find=0, stop_find=50, ecg_ch=None,
                         eog_ch=None, skew_criterion=0,
                         var_criterion=None, kurt_criterion=None)
    assert np.abs(scores[ica.exclude]) == np.max(np.abs(scores))

    evoked = epochs.average()
    evoked_data = evoked.data.copy()
    raw_data = raw[:][0].copy()
    epochs_data = epochs.get_data().copy()

    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_ecg(raw, method='ctps')
    assert_equal(len(scores), ica.n_components_)
    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_ecg(raw, method='correlation')
    assert_equal(len(scores), ica.n_components_)

    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_eog(raw)
    assert_equal(len(scores), ica.n_components_)

    idx, scores = ica.find_bads_ecg(epochs, method='ctps')

    assert_equal(len(scores), ica.n_components_)
    pytest.raises(ValueError, ica.find_bads_ecg, epochs.average(),
                  method='ctps')
    pytest.raises(ValueError, ica.find_bads_ecg, raw,
                  method='crazy-coupling')

    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_eog(raw)
    assert_equal(len(scores), ica.n_components_)

    raw.info['chs'][raw.ch_names.index('EOG 061') - 1]['kind'] = 202
    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_eog(raw)
    assert (isinstance(scores, list))
    assert_equal(len(scores[0]), ica.n_components_)

    idx, scores = ica.find_bads_eog(evoked, ch_name='MEG 1441')
    assert_equal(len(scores), ica.n_components_)

    idx, scores = ica.find_bads_ecg(evoked, method='correlation')
    assert_equal(len(scores), ica.n_components_)

    assert_array_equal(raw_data, raw[:][0])
    assert_array_equal(epochs_data, epochs.get_data())
    assert_array_equal(evoked_data, evoked.data)

    # check score funcs
    for name, func in get_score_funcs().items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(epochs_eog, target='EOG 061',
                                   score_func=func)
        assert (ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(epochs, score_func=stats.skew)

    # check exception handling
    pytest.raises(ValueError, ica.score_sources, epochs,
                  target=np.arange(1))

    # ecg functionality
    ecg_scores = ica.score_sources(raw, target='MEG 1531',
                                   score_func='pearsonr')

    with pytest.warns(RuntimeWarning, match='longer'):
        ecg_events = ica_find_ecg_events(
            raw, sources[np.abs(ecg_scores).argmax()])
    assert (ecg_events.ndim == 2)

    # eog functionality
    eog_scores = ica.score_sources(raw, target='EOG 061',
                                   score_func='pearsonr')
    with pytest.warns(RuntimeWarning, match='longer'):
        eog_events = ica_find_eog_events(
            raw, sources[np.abs(eog_scores).argmax()])
    assert (eog_events.ndim == 2)

    # Test ica fiff export
    ica_raw = ica.get_sources(raw, start=0, stop=100)
    assert (ica_raw.last_samp - ica_raw.first_samp == 100)
    assert_equal(len(ica_raw._filenames), 1)  # API consistency
    ica_chans = [ch for ch in ica_raw.ch_names if 'ICA' in ch]
    assert (ica.n_components_ == len(ica_chans))
    test_ica_fname = op.join(op.abspath(op.curdir), 'test-ica_raw.fif')
    ica.n_components = np.int32(ica.n_components)
    ica_raw.save(test_ica_fname, overwrite=True)
    ica_raw2 = read_raw_fif(test_ica_fname, preload=True)
    assert_allclose(ica_raw._data, ica_raw2._data, rtol=1e-5, atol=1e-4)
    ica_raw2.close()
    os.remove(test_ica_fname)

    # Test ica epochs export
    ica_epochs = ica.get_sources(epochs)
    assert (ica_epochs.events.shape == epochs.events.shape)
    ica_chans = [ch for ch in ica_epochs.ch_names if 'ICA' in ch]
    assert (ica.n_components_ == len(ica_chans))
    assert (ica.n_components_ == ica_epochs.get_data().shape[1])
    assert (ica_epochs._raw is None)
    assert (ica_epochs.preload is True)

    # test float n pca components
    ica.pca_explained_variance_ = np.array([0.2] * 5)
    ica.n_components_ = 0
    for ncomps, expected in [[0.3, 1], [0.9, 4], [1, 1]]:
        ncomps_ = ica._check_n_pca_components(ncomps)
        assert (ncomps_ == expected)

    ica = ICA(method=method)
    with pytest.warns(None):  # sometimes does not converge
        ica.fit(raw, picks=picks[:5])
    with pytest.warns(RuntimeWarning, match='longer'):
        ica.find_bads_ecg(raw)
    ica.find_bads_eog(epochs, ch_name='MEG 0121')
    assert_array_equal(raw_data, raw[:][0])

    raw.drop_channels(['MEG 0122'])
    pytest.raises(RuntimeError, ica.find_bads_eog, raw)
    with pytest.warns(RuntimeWarning, match='longer'):
        pytest.raises(RuntimeError, ica.find_bads_ecg, raw)
def runICA(raw,saveRoot,name):

    saveRoot = saveRoot    
    icaList = [] 
    ica = []
    n_max_ecg = 3   # max number of ecg components 
#    n_max_eog_1 = 2 # max number of vert eog comps
#    n_max_eog_2 = 2 # max number of horiz eog comps          
    ecg_source_idx, ecg_scores, ecg_exclude = [], [], []
    eog_source_idx, eog_scores, eog_exclude = [], [], []
    #horiz = 1       # will later be modified to horiz = 0 if no horizontal EOG components are identified                   
    ica = ICA(n_components=0.90,n_pca_components=64,max_pca_components=100,noise_cov=None)
    
    fit_picks = mne.pick_types(raw.info, meg=True, eeg=True, eog=False, ecg=False,
                   stim=False, exclude='bads')    
    ica.fit(raw, picks=fit_picks)
    #ica.fit(raw)
    #*************
    eog_picks = mne.pick_types(raw.info, meg=False, eeg=False, stim=False, eog=True, ecg=False, emg=False)[0]
    ecg_picks = mne.pick_types(raw.info, meg=False, eeg=False, stim=False, ecg=True, eog=False, emg=False)[0]
    ica_picks = mne.pick_types(raw.info, meg=True, eeg=True, eog=False, ecg=False,
                   stim=False, exclude='bads')
    ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=ica_picks)
    ecg_evoked = ecg_epochs.average()
    eog_evoked = create_eog_epochs(raw, tmin=-.5, tmax=.5, picks=ica_picks).average()

    ecg_source_idx, ecg_scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    eog_source_idx, eog_scores = ica.find_bads_eog(raw,ch_name=raw.ch_names[eog_picks].encode('ascii', 'ignore'))
    #eog_source_idx_2, eog_scores_2 = ica.find_bads_eog(raw,ch_name='EOG002')
    #if not eog_source_idx_2:
    #    horiz = 0
    
    #show_picks = np.abs(scores).argsort()[::-1][:5]
    #ica.plot_sources(raw, show_picks, exclude=ecg_inds, title=title % 'ecg')
    
        
    # defining a title-frame for later use
    title = 'Sources related to %s artifacts (red)'
  

    # extracting number of ica-components and plotting their topographies
    source_idx = range(0, ica.n_components_)
    #ica_plot = ica.plot_components(source_idx, ch_type="mag")
    ica_plot = ica.plot_components(source_idx)
                                          
    #ica_plot = ica.plot_components(source_idx)

    # select ICA sources and reconstruct MEG signals, compute clean ERFs
    # Add detected artefact sources to exclusion list
    # We now add the eog artefacts to the ica.exclusion list
    if not ecg_source_idx:
        print("No ECG components above threshold were identified for subject " + name +
        " - selecting the component with the highest score under threshold")
        ecg_exclude = [np.absolute(ecg_scores).argmax()]
        ecg_source_idx=[np.absolute(ecg_scores).argmax()]
    elif ecg_source_idx:
        ecg_exclude += ecg_source_idx[:n_max_ecg]
    ica.exclude += ecg_exclude

    if not eog_source_idx:
        if np.absolute(eog_scores).any>0.3:
            eog_exclude=[np.absolute(eog_scores).argmax()]
            eog_source_idx=[np.absolute(eog_scores).argmax()]
            print("No EOG components above threshold were identified " + name +
            " - selecting the component with the highest score under threshold above 0.3")
        elif not np.absolute(eog_scores).any>0.3:
            eog_exclude=[]
            print("No EOG components above threshold were identified" + name)
    elif eog_source_idx:
         eog_exclude += eog_source_idx

    ica.exclude += eog_exclude

    print('########## saving')
    if len(eog_exclude) == 0:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg_none' + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' + map(str, ecg_exclude)[0] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] + '.pdf', format = 'pdf')
    elif len(eog_exclude) == 1:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg_none' + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg' + map(str, ecg_exclude)[0] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] + '.pdf', format = 'pdf')
    elif len(eog_exclude) == 2:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg_none' + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg' + map(str, ecg_exclude)[0] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] + '.pdf', format = 'pdf')
    
    # plot the scores for the different components highlighting in red that/those related to ECG
    #scores_plots=plt.figure()
    #ax = plt.subplot(2,1,1)
    scores_plots_ecg=ica.plot_scores(ecg_scores, exclude=ecg_source_idx, title=title % 'ecg')
    scores_plots_ecg.savefig(saveRoot + name + '_ecg_scores.pdf', format = 'pdf')
    #ax = plt.subplot(2,1,2)
    scores_plots_eog=ica.plot_scores(eog_scores, exclude=eog_source_idx, title=title % 'eog')
    scores_plots_eog.savefig(saveRoot + name + '_eog_scores.pdf', format = 'pdf')
    
    #if len(ecg_exclude) > 0:    
    # estimate average artifact
    #source_clean_ecg=plt.figure()
    #ax = plt.subplot(2,1,1)
    source_source_ecg=ica.plot_sources(ecg_evoked, exclude=ecg_source_idx)
    source_source_ecg.savefig(saveRoot + name + '_ecg_source.pdf', format = 'pdf')
    #ax = plt.subplot(2,1,2)
    source_clean_ecg=ica.plot_overlay(ecg_evoked, exclude=ecg_source_idx)
    source_clean_ecg.savefig(saveRoot + name + '_ecg_clean.pdf', format = 'pdf')
    #clean_plot.savefig(saveRoot + name + '_ecg_clean.pdf', format = 'pdf')
        
    #if len(eog_exclude) > 0:
    source_source_eog=ica.plot_sources(eog_evoked, exclude=eog_source_idx)
    source_source_eog.savefig(saveRoot + name + '_eog_source.pdf', format = 'pdf')
    source_clean_eog=ica.plot_overlay(eog_evoked, exclude=eog_source_idx)
    source_clean_eog.savefig(saveRoot + name + '_eog_clean.pdf', format = 'pdf')
   
    
    overl_plot = ica.plot_overlay(raw)
    overl_plot.savefig(saveRoot + name + '_overl.pdf', format = 'pdf')
                
    plt.close('all')
    ## restore sensor space data
    icaList = ica.apply(raw)
    return(icaList, ica)
예제 #9
0
def preproc(subject):
    global report
    from mne.preprocessing import ICA, create_ecg_epochs, create_eog_epochs
    from mne.io import read_raw_fif
    import numpy as np

    raw_path = op.join(rest_dir, subject, 'meg_clean', 'nose-pts-out_raw.fif')
    clean_raw_path = op.join(rest_dir, subject, 'meg_clean', 'clean_raw.fif')
    if not os.path.exists(
            raw_path):  # skip subjects that have T1 but do not have MEG data
        return
    raw = read_raw_fif(raw_path, preload=True)

    pick_meg = mne.pick_types(raw.info,
                              meg=True,
                              eeg=False,
                              stim=False,
                              ref_meg=False)
    pick_eog1 = mne.pick_channels(raw.ch_names, ['EOG061'])
    pick_eog2 = mne.pick_channels(raw.ch_names, ['EOG062'])
    pick_ecg = mne.pick_channels(raw.ch_names, ['ECG063'])
    if pick_eog1.size == 0 or pick_eog2.size == 0 or pick_ecg.size == 0:
        logFile.write("Subject " + subject +
                      ": EOG and/or ECG channels not found.\n")
        return

    ##-- Filtering, PSD --##
    fig = raw.plot_psd(area_mode='range', average=False, picks=pick_meg)
    report.add_figs_to_section(fig,
                               captions=subject + ' => PSD before filtering',
                               section='Filtering')
    raw.notch_filter((50, 100),
                     filter_length='auto',
                     fir_design='firwin',
                     phase='zero',
                     picks=np.append(pick_meg,
                                     (pick_ecg, pick_eog1, pick_eog2)))
    raw.filter(1., None, fir_design='firwin',
               phase='zero')  # high-pass filtering at 1 Hz
    raw.resample(
        200, npad="auto"
    )  # set sampling frequency to 200Hz (antialiasing filter at 100 Hz)

    ##-- Artifact removal --##
    random_state = 23  # we want to have the same decomposition and the same order of components each time it is run for reproducibility
    ica = ICA(n_components=25, method='fastica', random_state=random_state)
    reject = dict(
        mag=5e-12, grad=4000e-13
    )  # avoid fitting ICA on large environmental artifacts that would dominate the variance and decomposition
    try:
        ica.fit(raw, picks=pick_meg, reject=reject)
    except:
        logFile.write("Subject " + subject +
                      ": ICA could not run. Large environmental artifacts.\n")
        return
    fig = ica.plot_components(inst=raw)
    report.add_figs_to_section(fig,
                               captions=[subject + ' => ICA components'] *
                               len(fig),
                               section='Artifact removal')

    # EOG artifact
    eog_epochs = create_eog_epochs(raw, reject=reject)
    if eog_epochs.events.size != 0:
        eog_inds, scores = ica.find_bads_eog(eog_epochs)
        if len(eog_inds) != 0:
            fig = ica.plot_properties(eog_epochs,
                                      picks=eog_inds,
                                      psd_args={'fmax': 35.},
                                      image_args={'sigma': 1.})
            report.add_figs_to_section(
                fig,
                captions=[subject + ' => ICA correlated with EOG'] * len(fig),
                section='Artifact removal')
            ica.exclude.extend(eog_inds)
        else:
            logFile.write("Subject " + subject +
                          ": No ICA component correlated with EOG\n")
    else:
        logFile.write("Subject " + subject + ": No EOG events found\n")

    # ECG artifact
    ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5)
    if ecg_epochs.events.size != 0:
        ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
        if len(ecg_inds) != 0:
            fig = ica.plot_properties(ecg_epochs,
                                      picks=ecg_inds,
                                      psd_args={'fmax': 35.})
            report.add_figs_to_section(
                fig,
                captions=[subject + ' => ICA correlated with ECG'] * len(fig),
                section='Artifact removal')
            ica.exclude.extend(ecg_inds)
        else:
            logFile.write("Subject " + subject +
                          ": No ICA component correlated with ECG\n")
    else:
        logFile.write("Subject " + subject + ": No ECG events found\n")

    raw_clean = raw.copy()
    ica.apply(raw_clean)

    fig = raw_clean.plot_psd(area_mode='range', picks=pick_meg)
    report.add_figs_to_section(
        fig,
        captions=subject + ' => PSD after filtering and artifact correction',
        section='Filtering')

    raw_clean.save(clean_raw_path, overwrite=True)
예제 #10
0
def compute_ica(subject):
    """Function will compute ICA on raw and apply the ICA.

    params:
    subject : str
        the subject id to be loaded
    """
    raw = Raw(save_folder + "%s_filtered_data_mc_raw_tsss.fif" % subject,
              preload=True)

    # ICA Part
    ica = ICA(n_components=0.95, method='fastica', max_iter=256)

    picks = mne.pick_types(raw.info, meg=True, eeg=True,
                           stim=False, exclude='bads')

    ica.fit(raw, picks=picks, decim=decim, reject=reject)

    # maximum number of components to reject
    n_max_ecg, n_max_eog = 3, 1

    ##########################################################################
    # 2) identify bad components by analyzing latent sources.
    title = 'Sources related to %s artifacts (red) for sub: %s'

    # generate ECG epochs use detection via phase statistics
    ecg_epochs = create_ecg_epochs(raw, ch_name="ECG002",
                                   tmin=-.5, tmax=.5, picks=picks)
    n_ecg_epochs_found = len(ecg_epochs.events)
    sel_ecg_epochs = np.arange(0, n_ecg_epochs_found, 10)
    ecg_epochs = ecg_epochs[sel_ecg_epochs]

    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    fig = ica.plot_scores(scores, exclude=ecg_inds,
                          title=title % ('ecg', subject))
    fig.savefig(save_folder + "pics/%s_ecg_scores.png" % subject)

    if ecg_inds:
        show_picks = np.abs(scores).argsort()[::-1][:5]

        fig = ica.plot_sources(raw, show_picks, exclude=ecg_inds,
                               title=title % ('ecg', subject), show=False)
        fig.savefig(save_folder + "pics/%s_ecg_sources.png" % subject)
        fig = ica.plot_components(ecg_inds, title=title % ('ecg', subject),
                                  colorbar=True)
        fig.savefig(save_folder + "pics/%s_ecg_component.png" % subject)

        ecg_inds = ecg_inds[:n_max_ecg]
        ica.exclude += ecg_inds

    # estimate average artifact
    ecg_evoked = ecg_epochs.average()
    del ecg_epochs

    # plot ECG sources + selection
    fig = ica.plot_sources(ecg_evoked, exclude=ecg_inds)
    fig.savefig(save_folder + "pics/%s_ecg_sources_ave.png" % subject)

    # plot ECG cleaning
    ica.plot_overlay(ecg_evoked, exclude=ecg_inds)
    fig.savefig(save_folder + "pics/%s_ecg_sources_clean_ave.png" % subject)

    # DETECT EOG BY CORRELATION
    # HORIZONTAL EOG
    eog_epochs = create_eog_epochs(raw, ch_name="EOG001")
    eog_inds, scores = ica.find_bads_eog(raw)
    fig = ica.plot_scores(scores, exclude=eog_inds,
                          title=title % ('eog', subject))
    fig.savefig(save_folder + "pics/%s_eog_scores.png" % subject)

    fig = ica.plot_components(eog_inds, title=title % ('eog', subject),
                              colorbar=True)
    fig.savefig(save_folder + "pics/%s_eog_component.png" % subject)

    eog_inds = eog_inds[:n_max_eog]
    ica.exclude += eog_inds

    del eog_epochs

    ##########################################################################
    # Apply the solution to Raw, Epochs or Evoked like this:
    raw_ica = ica.apply(raw, copy=False)
    ica.save(save_folder + "%s-ica.fif" % subject)  # save ICA componenets
    # Save raw with ICA removed
    raw_ica.save(save_folder + "%s_filtered_ica_mc_raw_tsss.fif" % subject,
                 overwrite=True)
    plt.close("all")
예제 #11
0
def preprocess_ICA_fif_to_ts(fif_file, ECG_ch_name, EoG_ch_name, l_freq, h_freq, down_sfreq, variance, is_sensor_space, data_type):
    import os
    import numpy as np

    import mne
    from mne.io import Raw
    from mne.preprocessing import ICA, read_ica
    from mne.preprocessing import create_ecg_epochs, create_eog_epochs
    from mne.report import Report

    from nipype.utils.filemanip import split_filename as split_f

    report = Report()

    subj_path, basename, ext = split_f(fif_file)
    (data_path, sbj_name) = os.path.split(subj_path)
    print data_path

    # Read raw
    # If None the compensation in the data is not modified.
    # If set to n, e.g. 3, apply gradient compensation of grade n as for
    # CTF systems (compensation=3)
    raw = Raw(fif_file, preload=True)

    # select sensors
    select_sensors = mne.pick_types(raw.info, meg=True, ref_meg=False,
                                    exclude='bads')
    picks_meeg = mne.pick_types(raw.info, meg=True, eeg=True, exclude='bads')

    # save electrode locations
    sens_loc = [raw.info['chs'][i]['loc'][:3] for i in select_sensors]
    sens_loc = np.array(sens_loc)

    channel_coords_file = os.path.abspath("correct_channel_coords.txt")
    print '*** ' + channel_coords_file + '***'
    np.savetxt(channel_coords_file, sens_loc, fmt='%s')

    # save electrode names
    sens_names = np.array([raw.ch_names[pos] for pos in select_sensors],dtype = "str")

    # AP 21032016 
#    channel_names_file = os.path.join(data_path, "correct_channel_names.txt") 
    channel_names_file = os.path.abspath("correct_channel_names.txt")
    np.savetxt(channel_names_file,sens_names , fmt = '%s')
 
    ### filtering + downsampling
    raw.filter(l_freq=l_freq, h_freq=h_freq, picks=picks_meeg,
               method='iir', n_jobs=8)
#    raw.filter(l_freq = l_freq, h_freq = h_freq, picks = picks_meeg,
#               method='iir')
#    raw.resample(sfreq=down_sfreq, npad=0)

    ### 1) Fit ICA model using the FastICA algorithm
    # Other available choices are `infomax` or `extended-infomax`
    # We pass a float value between 0 and 1 to select n_components based on the
    # percentage of variance explained by the PCA components.
    ICA_title = 'Sources related to %s artifacts (red)'
    is_show = False # visualization
    reject = dict(mag=4e-12, grad=4000e-13)

    # check if we have an ICA, if yes, we load it
    ica_filename = os.path.join(subj_path,basename + "-ica.fif")  
    if os.path.exists(ica_filename) is False:
        ica = ICA(n_components=variance, method='fastica', max_iter=500) # , max_iter=500
        ica.fit(raw, picks=select_sensors, reject=reject) # decim = 3, 

        has_ICA = False
    else:
        has_ICA = True
        print ica_filename + '   exists!!!'
        ica = read_ica(ica_filename)
        ica.exclude = []

    # 2) identify bad components by analyzing latent sources.
    # generate ECG epochs use detection via phase statistics

    # if we just have exclude channels we jump these steps
#    if len(ica.exclude)==0:
    n_max_ecg = 3
    n_max_eog = 2

    # check if ECG_ch_name is in the raw channels
    if ECG_ch_name in raw.info['ch_names']:
        ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5,
                                       picks=select_sensors,
                                       ch_name=ECG_ch_name)
    # if not  a synthetic ECG channel is created from cross channel average
    else:
        ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5,
                                       picks=select_sensors)

    # ICA for ECG artifact
    # threshold=0.25 come default
    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    print scores
    print '\n len ecg_inds *** ' + str(len(ecg_inds)) + '***\n'
    if len(ecg_inds) > 0:
        ecg_evoked = ecg_epochs.average()

        fig1 = ica.plot_scores(scores, exclude=ecg_inds,
                               title=ICA_title % 'ecg', show=is_show)

        show_picks = np.abs(scores).argsort()[::-1][:5] # Pick the five largest scores and plot them

        # Plot estimated latent sources given the unmixing matrix.
        #ica.plot_sources(raw, show_picks, exclude=ecg_inds, title=ICA_title % 'ecg', show=is_show)
        t_start = 0
        t_stop = 30 # take the fist 30s
        fig2 = ica.plot_sources(raw, show_picks, exclude=ecg_inds, title=ICA_title % 'ecg' + ' in 30s' 
                                            ,start = t_start, stop  = t_stop, show=is_show)

        # topoplot of unmixing matrix columns
        fig3 = ica.plot_components(show_picks, title=ICA_title % 'ecg', colorbar=True, show=is_show)

        ecg_inds = ecg_inds[:n_max_ecg]
        ica.exclude += ecg_inds
    
        fig4 = ica.plot_sources(ecg_evoked, exclude=ecg_inds, show=is_show)  # plot ECG sources + selection
        fig5 = ica.plot_overlay(ecg_evoked, exclude=ecg_inds, show=is_show)  # plot ECG cleaning
    
        fig = [fig1, fig2, fig3, fig4, fig5]
        report.add_figs_to_section(fig, captions=['Scores of ICs related to ECG',
                                                  'Time Series plots of ICs (ECG)',
                                                  'TopoMap of ICs (ECG)', 
                                                  'Time-locked ECG sources', 
                                                  'ECG overlay'], section = 'ICA - ECG')    
    
    # check if EoG_ch_name is in the raw channels
    # if EoG_ch_name is empty if data_type is fif, ICA routine automatically looks for EEG61, EEG62
    # otherwise if data_type is ds we jump this step
    if not EoG_ch_name and data_type=='ds':
        eog_inds = []
    else:
        if EoG_ch_name in raw.info['ch_names']:        
            ### ICA for eye blink artifact - detect EOG by correlation
            eog_inds, scores = ica.find_bads_eog(raw, ch_name = EoG_ch_name)
        else:
            eog_inds, scores = ica.find_bads_eog(raw)

    if len(eog_inds) > 0:  
        
        fig6 = ica.plot_scores(scores, exclude=eog_inds, title=ICA_title % 'eog', show=is_show)
        report.add_figs_to_section(fig6, captions=['Scores of ICs related to EOG'], 
                           section = 'ICA - EOG')
                           
        # check how many EoG ch we have
        rs = np.shape(scores)
        if len(rs)>1:
            rr = rs[0]
            show_picks = [np.abs(scores[i][:]).argsort()[::-1][:5] for i in range(rr)]
            for i in range(rr):
                fig7 = ica.plot_sources(raw, show_picks[i][:], exclude=eog_inds, 
                                    start = raw.times[0], stop  = raw.times[-1], 
                                    title=ICA_title % 'eog',show=is_show)       
                                    
                fig8 = ica.plot_components(show_picks[i][:], title=ICA_title % 'eog', colorbar=True, show=is_show) # ICA nel tempo

                fig = [fig7, fig8]
                report.add_figs_to_section(fig, captions=['Scores of ICs related to EOG', 
                                                 'Time Series plots of ICs (EOG)'],
                                            section = 'ICA - EOG')    
        else:
            show_picks = np.abs(scores).argsort()[::-1][:5]
            fig7 = ica.plot_sources(raw, show_picks, exclude=eog_inds, title=ICA_title % 'eog', show=is_show)                                    
            fig8 = ica.plot_components(show_picks, title=ICA_title % 'eog', colorbar=True, show=is_show) 
            fig = [fig7, fig8]            
            report.add_figs_to_section(fig, captions=['Time Series plots of ICs (EOG)',
                                                      'TopoMap of ICs (EOG)',],
                                            section = 'ICA - EOG') 
        
        eog_inds = eog_inds[:n_max_eog]
        ica.exclude += eog_inds
        
        if EoG_ch_name in raw.info['ch_names']:
            eog_evoked = create_eog_epochs(raw, tmin=-.5, tmax=.5, picks=select_sensors, 
                                   ch_name=EoG_ch_name).average()
        else:
            eog_evoked = create_eog_epochs(raw, tmin=-.5, tmax=.5, picks=select_sensors).average()               
       
        fig9 = ica.plot_sources(eog_evoked, exclude=eog_inds, show=is_show)  # plot EOG sources + selection
        fig10 = ica.plot_overlay(eog_evoked, exclude=eog_inds, show=is_show)  # plot EOG cleaning

        fig = [fig9, fig10]
        report.add_figs_to_section(fig, captions=['Time-locked EOG sources',
                                                  'EOG overlay'], section = 'ICA - EOG')

    fig11 = ica.plot_overlay(raw, show=is_show)
    report.add_figs_to_section(fig11, captions=['Signal'], section = 'Signal quality') 
   
    ### plot all topographies and time seris of the ICA components
    n_ica_components = ica.mixing_matrix_.shape[1]
    
    n_topo = 10;
    n_fig  = n_ica_components/n_topo;
    n_plot = n_ica_components%n_topo;

    print '*************** n_fig = ' + str(n_fig) + ' n_plot = ' + str(n_plot) + '********************'
    fig = []
    t_start = 0
    t_stop = None # 60 if we want to take the fist 60s
    for n in range(0,n_fig):
        fig_tmp = ica.plot_components(range(n_topo*n,n_topo*(n+1)),title='ICA components', show=is_show)    
        fig.append(fig_tmp)
        fig_tmp = ica.plot_sources(raw, range(n_topo*n,n_topo*(n+1)), 
                                    start = t_start, stop  = t_stop, 
                                    title='ICA components')     
        fig.append(fig_tmp)
    
#    if n_plot > 0:
#        fig_tmp = ica.plot_components(range(n_fig*n_topo,n_ica_components), title='ICA components', show=is_show)    
#        fig.append(fig_tmp)
#        fig_tmp = ica.plot_sources(raw, range(n_fig*n_topo,n_ica_components), 
#                                        start = t_start, stop  = t_stop,
#                                        title='ICA components')     
#        fig.append(fig_tmp)   
#   
#    for n in range(0, len(fig)):
#        report.add_figs_to_section(fig[n], captions=['TOPO'], section = 'ICA Topo Maps')   
     
    if n_plot > 5:
        n_fig_l  = n_plot//5
                
        print '*************************** ' + str(n_fig_l) + ' *********************************'
        for n in range(0,n_fig_l):
            print range(n_fig*n_topo+5*n, n_fig*n_topo+5*(n+1))
            fig_tmp = ica.plot_components(range(n_fig*n_topo+5*n, n_fig*n_topo+5*(n+1)),title='ICA components')    
            fig.append(fig_tmp)
            fig_tmp = ica.plot_sources(raw, range(n_fig*n_topo+5*n, n_fig*n_topo+5*(n+1)), 
                                    start = t_start, stop  = t_stop, 
                                    title='ICA components')     
            fig.append(fig_tmp)
        
        print range(n_fig*n_topo+5*(n+1),n_ica_components)
        fig_tmp = ica.plot_components(range(n_fig*n_topo+5*(n+1),n_ica_components), title='ICA components')    
        fig.append(fig_tmp)
        fig_tmp = ica.plot_sources(raw, range(n_fig*n_topo+5*(n+1),n_ica_components), 
                                        start = t_start, stop  = t_stop, 
                                        title='ICA components')     
        fig.append(fig_tmp)   
        
    for n in range(0, len(fig)):
        report.add_figs_to_section(fig[n], captions=['TOPO'], section = 'ICA Topo Maps')       
    
    report_filename = os.path.join(subj_path,basename + "-report.html")
    print '******* ' + report_filename
    report.save(report_filename, open_browser=False, overwrite=True)
        
        
    # 3) apply ICA to raw data and save solution and report
    # check the amplitudes do not change
#    raw_ica_file = os.path.abspath(basename[:i_raw] + 'ica-raw.fif')
    raw_ica_file = os.path.join(subj_path, basename + '-preproc-raw.fif')
    raw_ica = ica.apply(raw)

    raw_ica.resample(sfreq=down_sfreq, npad=0)

    raw_ica.save(raw_ica_file, overwrite=True)

    # save ICA solution
    print ica_filename
    if has_ICA is False:
        ica.save(ica_filename)

    # 4) save data
    data_noIca, times = raw[select_sensors, :]
    data, times = raw_ica[select_sensors, :]

    print data.shape
    print raw.info['sfreq']

    ts_file = os.path.abspath(basename + "_ica.npy")
    np.save(ts_file, data)
    print '***** TS FILE ' + ts_file + '*****'

    if is_sensor_space:
        return ts_file, channel_coords_file, channel_names_file, raw.info['sfreq']
    else:
#        return raw_ica, channel_coords_file, channel_names_file, raw.info['sfreq']
        return raw_ica_file, channel_coords_file, channel_names_file, raw.info['sfreq']
예제 #12
0
#
# License: BSD (3-clause)

import mne
from mne.io import Raw
from mne.preprocessing import ICA, create_ecg_epochs
from mne.datasets import sample

print(__doc__)

###############################################################################
# Fit ICA model using the FastICA algorithm, detect and inspect components

data_path = sample.data_path()
raw_fname = data_path + "/MEG/sample/sample_audvis_filt-0-40_raw.fif"

raw = Raw(raw_fname, preload=True)
raw.filter(1, 30, method="iir")
raw.pick_types(meg=True, eeg=False, exclude="bads", stim=True)

# longer + more epochs for more artifact exposure
events = mne.find_events(raw, stim_channel="STI 014")
epochs = mne.Epochs(raw, events, event_id=None, tmin=-0.2, tmax=0.5)

ica = ICA(n_components=0.95, method="fastica").fit(epochs)

ecg_epochs = create_ecg_epochs(raw, tmin=-0.5, tmax=0.5)
ecg_inds, scores = ica.find_bads_ecg(ecg_epochs)

ica.plot_components(ecg_inds)
예제 #13
0
                              random_state=25)  #,method='infomax')
                    ica.fit(ep, picks=our_picks)

                    eog_ic = []

                    for ch in [
                            'E25', 'E17', 'E8', 'E21', 'E14', 'E125', 'E126',
                            'E127', 'E128'
                    ]:  #insert EOG channels
                        eog_idx, scores = ica.find_bads_eog(ep, ch_name=ch)
                        eog_ic.append(eog_idx)
                    print(eog_ic)

                    ecg_ic = []
                    for ch in []:  # insert ECG channels
                        ecg_idx, scores = ica.find_bads_ecg(ep, ch_name=ch)
                        ecg_ic.append(ecg_idx)

                    print(ecg_ic)
                    reject_ic = []
                    for eog_inds in eog_ic:
                        for ele in eog_inds:
                            if (ele not in reject_ic) and (ele < 35):
                                reject_ic.append(ele)
                    for ecg_inds in ecg_ic:
                        for ele in ecg_inds:
                            if (ele not in reject_ic) and (ele < 35):
                                reject_ic.append(ele)

                    print(reject_ic)
def runICA(raw,saveRoot,name):

    saveRoot = saveRoot    
    icaList = [] 
    ica = []
    n_max_ecg = 3   # max number of ecg components 
#    n_max_eog_1 = 2 # max number of vert eog comps
#    n_max_eog_2 = 2 # max number of horiz eog comps          
    ecg_source_idx, ecg_scores, ecg_exclude = [], [], []
    eog_source_idx, eog_scores, eog_exclude = [], [], []
    #horiz = 1       # will later be modified to horiz = 0 if no horizontal EOG components are identified                   
    ica = ICA(n_components=0.90,n_pca_components=64,max_pca_components=100,noise_cov=None)
        
    ica.fit(raw)
    #*************
    eog_picks = mne.pick_types(raw.info, meg=False, eeg=False, stim=False, eog=True, ecg=False, emg=False)[0]
    ecg_picks = mne.pick_types(raw.info, meg=False, eeg=False, stim=False, ecg=True, eog=False, emg=False)[0]
    ica_picks = mne.pick_types(raw.info, meg=True, eeg=False, eog=False, ecg=False,
                   stim=False, exclude='bads')
    ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=ica_picks)
    ecg_evoked = ecg_epochs.average()
    eog_evoked = create_eog_epochs(raw, tmin=-.5, tmax=.5, picks=ica_picks).average()

    ecg_source_idx, ecg_scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    eog_source_idx, eog_scores = ica.find_bads_eog(raw,ch_name=raw.ch_names[eog_picks].encode('ascii', 'ignore'))
       
    # defining a title-frame for later use
    title = 'Sources related to %s artifacts (red)'

    # extracting number of ica-components and plotting their topographies
    source_idx = range(0, ica.n_components_)
    ica_plot = ica.plot_components(source_idx, ch_type="mag")                                           

    # select ICA sources and reconstruct MEG signals, compute clean ERFs
    # Add detected artefact sources to exclusion list
    # We now add the eog artefacts to the ica.exclusion list
    if not ecg_source_idx:
        print("No ECG components above threshold were identified for subject " + name +
        " - selecting the component with the highest score under threshold")
        ecg_exclude = [np.absolute(ecg_scores).argmax()]
        ecg_source_idx=[np.absolute(ecg_scores).argmax()]
    elif ecg_source_idx:
        ecg_exclude += ecg_source_idx[:n_max_ecg]
    ica.exclude += ecg_exclude

    if not eog_source_idx:
        if np.absolute(eog_scores).any>0.3:
            eog_exclude=[np.absolute(eog_scores).argmax()]
            eog_source_idx=[np.absolute(eog_scores).argmax()]
            print("No EOG components above threshold were identified " + name +
            " - selecting the component with the highest score under threshold above 0.3")
        elif not np.absolute(eog_scores).any>0.3:
            eog_exclude=[]
            print("No EOG components above threshold were identified" + name)
    elif eog_source_idx:
         eog_exclude += eog_source_idx

    ica.exclude += eog_exclude

    print('########## saving')
    if len(eog_exclude) == 0:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg_none' + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' + map(str, ecg_exclude)[0] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] + '.pdf', format = 'pdf')
    elif len(eog_exclude) == 1:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg_none' + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg' + map(str, ecg_exclude)[0] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] + '.pdf', format = 'pdf')
    elif len(eog_exclude) == 2:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg_none' + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg' + map(str, ecg_exclude)[0] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '.pdf', format = 'pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] + '_' + map(str, eog_exclude)[1] +
            '-ecg' + map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] + '.pdf', format = 'pdf')
    
    # plot the scores for the different components highlighting in red that/those related to ECG
    scores_plots_ecg=ica.plot_scores(ecg_scores, exclude=ecg_source_idx, title=title % 'ecg')
    scores_plots_ecg.savefig(saveRoot + name + '_ecg_scores.pdf', format = 'pdf')
    scores_plots_eog=ica.plot_scores(eog_scores, exclude=eog_source_idx, title=title % 'eog')
    scores_plots_eog.savefig(saveRoot + name + '_eog_scores.pdf', format = 'pdf')
    source_source_ecg=ica.plot_sources(ecg_evoked, exclude=ecg_source_idx)
    source_source_ecg.savefig(saveRoot + name + '_ecg_source.pdf', format = 'pdf')
    #ax = plt.subplot(2,1,2)
    source_clean_ecg=ica.plot_overlay(ecg_evoked, exclude=ecg_source_idx)
    source_clean_ecg.savefig(saveRoot + name + '_ecg_clean.pdf', format = 'pdf')
    #clean_plot.savefig(saveRoot + name + '_ecg_clean.pdf', format = 'pdf')
        
    #if len(eog_exclude) > 0:
    source_source_eog=ica.plot_sources(eog_evoked, exclude=eog_source_idx)
    source_source_eog.savefig(saveRoot + name + '_eog_source.pdf', format = 'pdf')
    source_clean_eog=ica.plot_overlay(eog_evoked, exclude=eog_source_idx)
    source_clean_eog.savefig(saveRoot + name + '_eog_clean.pdf', format = 'pdf')
   
    
    overl_plot = ica.plot_overlay(raw)
    overl_plot.savefig(saveRoot + name + '_overl.pdf', format = 'pdf')
    
    event_id = 999
    ecg_events, _, _ = mne.preprocessing.find_ecg_events(raw, event_id,
                             ch_name=raw.ch_names[ecg_picks].encode('UTF8'))
    picks = mne.pick_types(raw.info, meg=False, eeg=False, stim=False, ecg=True)

    tmin, tmax = -0.1, 0.1
    epochs_ecg = mne.Epochs(raw, ecg_events, event_id, tmin, tmax,picks=picks)
    data_ecg = epochs_ecg.get_data()

    event_id = 998
    eog_events = mne.preprocessing.find_eog_events(raw, event_id,
                                   ch_name=raw.ch_names[eog_picks].encode('UTF8'))
    picks = mne.pick_types(raw.info, meg=False, eeg=False, stim=False, eog=True,
                           exclude='bads')
    tmin, tmax = -0.5, 0.5
    epochs_eog = mne.Epochs(raw, eog_events, event_id, tmin, tmax,picks=[picks[0]])#,
    data_eog = epochs_eog.get_data()

    plSize = 1
    pltRes = 128
    ecg_eogAvg=plt.figure(figsize=(20,10))
    ax = plt.subplot(2,3,1)
    plt.plot(1e3 * epochs_ecg.times, np.squeeze(data_ecg).T)
    plt.xlabel('Times (ms)')
    plt.title('ECG')
    plt.ylabel('ECG')
    plt.show()                   
    ax2 = plt.subplot(2,3,2)
    plot_evoked_topomap(ecg_evoked, times=0, average=0.02, ch_type='mag',colorbar=False,
                        size=plSize, res=pltRes,
                        axes=ax2)
    ax3= plt.subplot(2,3,3)
    plot_evoked_topomap(ecg_evoked, times=0, average=0.02, ch_type='grad',colorbar=False,
                        size=plSize, res=pltRes,                            
                        axes=ax3)
    ax = plt.subplot(2,3,4)
    plt.plot(1e3 * epochs_eog.times, np.squeeze(data_eog).T)
    plt.xlabel('Times (ms)')
    plt.title('EOG')
    plt.ylabel('EOG')
    ax = plt.subplot(2,3,5)
    plot_evoked_topomap(eog_evoked, times=0, average=0.05, ch_type='mag',colorbar=False,
                        size=plSize, res=pltRes,                            
                        axes=ax)
    ax = plt.subplot(2,3,6)
    plot_evoked_topomap(eog_evoked, times=0, average=0.05, ch_type='grad',colorbar=False,
                size=plSize, res=pltRes, show=False,                            
                axes=ax)
    plt.tight_layout()
    ecg_eogAvg.savefig(saveRoot + name +'_ecg_eog_Avg.pdf',format = 'pdf')
            
    plt.close('all')
    ## restore sensor space data
    icaList = ica.apply(raw)
    return(icaList, ica)
예제 #15
0
def main(fname):
    from mne import pick_types
    from sys import argv
    from mne.io import read_raw_fif
    from mne.preprocessing import ICA, create_eog_epochs, create_ecg_epochs
    import numpy as np
    import matplotlib.pyplot as plt

    #%% parameters
    #fname=argv[1]
    reject_ica = {'mag': 6e-12, 'grad': 6e-10}
    #ecg_ch='MEG0141'

    #%% read and filter data
    Raw = read_raw_fif(fname, preload=True)
    Raw.filter(1, 40, fir_design='firwin')
    #Events=find_events(Raw, min_duration=0.003)

    #%% run ICA for automatic ocular & cardiac rejection (plot the rejected topos)
    picks_ica = pick_types(Raw.info, meg=True)
    ica = ICA(n_components=0.98, method='fastica')
    ica.fit(Raw, picks=picks_ica, reject=reject_ica, decim=4)
    ecg_epochs = create_ecg_epochs(
        Raw, reject=reject_ica
    )  # ch_name='MEG0111') # find the ECG events automagically
    eog_epochs = create_eog_epochs(
        Raw, reject=reject_ica)  # find the EOG events automagically
    #ecg_epochs.average().plot_joint(times=0)
    #eog_epochs.average().plot_joint(times=0)
    ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    print(ecg_inds)
    eog_inds, eog_scores = ica.find_bads_eog(eog_epochs)
    print(eog_inds)
    #ica.plot_overlay(ecg_average, exclude=ecg_inds) # does not work?
    try:
        ica.plot_components(ch_type='mag',
                            picks=ecg_inds,
                            title=fname,
                            show=False)
    except IndexError as exc:
        pass
    except ValueError as exc:
        pass
    try:
        ica.plot_components(ch_type='mag',
                            picks=eog_inds,
                            title=fname,
                            show=False)
    except IndexError as exc:
        pass
    except ValueError as exc:
        pass
    plt.show(block=False)
    ica.exclude.extend(eog_inds)
    ica.exclude.extend(ecg_inds)
    # Save changes to the data:
    #Raw.copy().crop(10,20).plot()
    Raw = ica.apply(Raw)
    #Raw.copy().crop(10,20).plot()
    #Raw=ica.apply(Raw,exclude=[eog_inds]) # list of the ICA components to exclude!!!
    return Raw, ica
        ica = ICA(n_components=90, random_state=25)
        ica.fit(eyes_open, picks=our_picks_EO)

        eog_ic = []
        for ch in [
                'E25', 'E17', 'E8', 'E21', 'E14', 'E125', 'E126', 'E127',
                'E128'
        ]:  #insert EOG channels
            eog_idx, scores = ica.find_bads_eog(eyes_open, ch_name=ch)
            eog_ic.append(eog_idx)

        print(eog_ic)

        ecg_ic = []
        for ch in []:  # insert ECG channels
            ecg_idx, scores = ica.find_bads_ecg(eyes_open, ch_name=ch)
            ecg_ic.append(ecg_idx)

        print(ecg_ic)

        reject_ic = []
        for eog_inds in eog_ic:
            for ele in eog_inds:
                if ele not in reject_ic:
                    reject_ic.append(ele)
        for ecg_inds in ecg_ic:
            for ele in ecg_inds:
                if el not in reject_ic:
                    reject_ic.append(el)

        print(reject_ic)
예제 #17
0
    raw = raw_notch_BPF

    picks = mne.pick_types(raw.info, meg=True, eeg=True, eog=True, stim=False)

    ica = ICA(n_components=n_components, method=method)

    reject = dict(grad=200e-12, mag=4e-12)

    ica.fit(raw, picks=picks, decim=decim, reject=reject)

    eog_epochs = create_eog_epochs(raw)
    ecg_epochs = create_ecg_epochs(raw, reject=reject)

    eog_inds, scores_eog = ica.find_bads_eog(eog_epochs)
    ecg_inds, scores_ecg = ica.find_bads_ecg(ecg_epochs)

    eog_inds = eog_inds[:n_max_eog]
    ecg_inds = ecg_inds[:n_max_ecg]

    # eog_inds = [0,40]

    ica.exclude += eog_inds
    ica.exclude += ecg_inds

    ica.apply(inst=raw, exclude=eog_inds)
    ica.apply(inst=raw, exclude=ecg_inds)

    #pick_av = np.abs((scores_eog[0]+scores_eog[1])/2).argsort()[::-1][:5]
    #pick_0 = np.abs(scores_eog[0]).argsort()[::-1][:5]
    #pick_1 = np.abs(scores_eog[1]).argsort()[::-1][:5]
예제 #18
0
def camcan_preproc(subject):
    data_folder = '/Users/work/camcan'
    data_file = os.path.join(data_folder, subject,
                             '_ses-rest_task-rest_proc-raw.fif')
    #data_file = os.path.join(data_folder,
    #                                    'sub-CC _ses-rest_task-rest_proc-raw_sss.fif')
    report = mne.Report(verbose=True)
    report.save('report_basic.html', overwrite=True)
    # read file
    raw = mne.io.read_raw_fif(data_file, preload=True)
    print(raw.info)
    fig = raw.plot_psd(fmax=50, show=False)
    report.add_figs_to_section(fig, captions='Raw', section='PSD')
    meg_channels = mne.pick_types(raw.info,
                                  meg=True,
                                  stim=False,
                                  ref_meg=False)
    eog1 = mne.pick_channels(raw.ch_names, ['EOG061'])
    eog2 = mne.pick_channels(raw.ch_names, ['EOG062'])
    ecg = mne.pick_channels(raw.ch_names, ['ECG063'])
    mag_channels = mne.pick_types(raw.info, meg='mag')
    # Bandpass between 1 and 45 Hz, bandstop between 50 and 100
    raw.filter(1, 45)
    freqs = (50, 100)
    raw.notch_filter(freqs=freqs)
    fig = raw.plot_psd(fmax=50, show=False)
    report.add_figs_to_section(fig,
                               captions='After bandpass and notch filters',
                               section='PSD')
    # 2s epochs
    events = mne.make_fixed_length_events(raw,
                                          start=0,
                                          stop=None,
                                          duration=2.0,
                                          overlap=0)
    reject = dict(grad=4000e-13, mag=4e-12, eog=250e-6)  #from mne tutorial
    epochs = mne.Epochs(raw,
                        events,
                        baseline=None,
                        preload=True,
                        reject=reject)
    # Topoplot before ICA
    fig = epochs.plot_psd_topomap(ch_type='mag', normalize=True, show=False)
    report.add_figs_to_section(fig,
                               captions='Topoplot before ICA',
                               section='Topoplots')
    # ICA to remove artefacts
    from mne.preprocessing import ICA, create_ecg_epochs, create_eog_epochs
    ica = ICA(n_components=0.95, method='fastica').fit(epochs)
    fig = ica.plot_components(show=False)
    ica.exclude = []
    report.add_figs_to_section(fig,
                               captions=('ICA components', ' '),
                               section='ICA')
    # Find ECG artefacts
    ecg_epochs = create_ecg_epochs(raw)
    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, threshold='auto')
    fig = ica.plot_components(ecg_inds, show=False)
    ica.exclude += ecg_inds
    report.add_figs_to_section(fig, captions='ECG components', section='ICA')
    # Find EOG artefacts
    eog_epochs = create_eog_epochs(raw, tmin=-.5, tmax=.5)
    eog_inds, scores = ica.find_bads_eog(eog_epochs)
    fig = ica.plot_components(eog_inds, show=False)
    ica.exclude += eog_inds
    report.add_figs_to_section(fig, captions='EOG components', section='ICA')
    # Apply ICA
    cleaned = epochs.copy()
    ica.apply(cleaned)
    fig = cleaned.plot_psd_topomap(ch_type='mag', normalize=True, show=False)
    report.add_figs_to_section(fig,
                               captions='Topoplot after artefact rejection',
                               section='Preprocessed')
    report.save('report.html', overwrite=True)
    # save fif file
    clean_file = os.path.join(data_folder, subject, '_cleaned.fif')
    cleaned.save(clean_file, overwrite=True)
예제 #19
0
def compute_ica(raw,
                subject,
                n_components=0.99,
                picks=None,
                decim=None,
                reject=None,
                ecg_tmin=-0.5,
                ecg_tmax=0.5,
                eog_tmin=-0.5,
                eog_tmax=0.5,
                n_max_ecg=3,
                n_max_eog=1,
                n_max_ecg_epochs=200,
                img_scale=1.0,
                report=None):
    """Run ICA in raw data

    Parameters
    ----------,
    raw : instance of Raw
        Raw measurements to be decomposed.
    subject : str
        The name of the subject.
    picks : array-like of int, shape(n_channels, ) | None
        Channels to be included. This selection remains throughout the
        initialized ICA solution. If None only good data channels are used.
        Defaults to None.
    n_components : int | float | None | 'rank'
        The number of components used for ICA decomposition. If int, it must be
        smaller then max_pca_components. If None, all PCA components will be
        used. If float between 0 and 1 components can will be selected by the
        cumulative percentage of explained variance.
        If 'rank', the number of components equals the rank estimate.
        Defaults to 0.99.
    decim : int | None
        Increment for selecting each nth time slice. If None, all samples
        within ``start`` and ``stop`` are used. Defalts to None.
    reject : dict | None
        Rejection parameters based on peak to peak amplitude.
        Valid keys are 'grad' | 'mag' | 'eeg' | 'eog' | 'ecg'.
        If reject is None then no rejection is done. You should
        use such parameters to reject big measurement artifacts
        and not EOG for example. It only applies if `inst` is of type Raw.
        Defaults to {'mag': 5e-12}
    ecg_tmin : float
        Start time before ECG event. Defaults to -0.5.
    ecg_tmax : float
        End time after ECG event. Defaults to 0.5.
    eog_tmin : float
        Start time before rog event. Defaults to -0.5.
    eog_tmax : float
        End time after rog event. Defaults to 0.5.
    n_max_ecg : int | None
        The maximum number of ECG components to exclude. Defaults to 3.
    n_max_eog : int | None
        The maximum number of EOG components to exclude. Defaults to 1.
    n_max_ecg_epochs : int
        The maximum number of ECG epochs to use for phase-consistency
        estimation. Defaults to 200.
    scale_img : float
        The scaling factor for the report. Defaults to 1.0.
    report : instance of Report | None
        The report object. If None, a new report will be generated.

    Returns
    -------
    ica : isntance of ICA
        The ICA solution.
    report : instance of Report
        The report object.
    """
    if report is None:
        report = Report(subject=subject, title='ICA preprocessing')
    if n_components == 'rank':
        n_components = raw.estimate_rank(picks=picks)
    ica = ICA(n_components=n_components, max_pca_components=None, max_iter=256)
    ica.fit(raw, picks=picks, decim=decim, reject=reject)

    comment = []
    for ch in ('mag', 'grad', 'eeg'):
        if ch in ica:
            comment += [ch.upper()]
    if len(comment) > 0:
        comment = '+'.join(comment) + ' '
    else:
        comment = ''

    topo_ch_type = 'mag'
    if 'GRAD' in comment and 'MAG' not in comment:
        topo_ch_type = 'grad'
    elif 'EEG' in comment:
        topo_ch_type = 'eeg'

    ############################################################################
    # 2) identify bad components by analyzing latent sources.

    title = '%s related to %s artifacts (red) ({})'.format(subject)

    # generate ECG epochs use detection via phase statistics

    ecg_epochs = create_ecg_epochs(raw,
                                   tmin=ecg_tmin,
                                   tmax=ecg_tmax,
                                   picks=None,
                                   reject={'mag': 5e-12})
    n_ecg_epochs_found = len(ecg_epochs.events)
    n_max_ecg_epochs = min(n_max_ecg_epochs, n_ecg_epochs_found)
    sel_ecg_epochs = np.arange(n_ecg_epochs_found)
    rng = np.random.RandomState(42)
    rng.shuffle(sel_ecg_epochs)
    ecg_epochs = ecg_epochs[sel_ecg_epochs[:n_max_ecg_epochs]]

    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    if len(ecg_inds) > 0:
        ecg_evoked = ecg_epochs.average(picks=picks)
        del ecg_epochs
        fig = ica.plot_scores(scores,
                              exclude=ecg_inds,
                              title=title % ('scores', 'ecg'))
        report.add_figs_to_section(fig,
                                   'scores ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        fig = ica.plot_sources(raw,
                               ecg_inds,
                               exclude=ecg_inds,
                               title=title % ('components', 'ecg'))
        report.add_figs_to_section(fig,
                                   'sources ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        fig = ica.plot_components(ecg_inds,
                                  ch_type=topo_ch_type,
                                  title='',
                                  colorbar=True)
        report.add_figs_to_section(fig,
                                   title % ('sources', 'ecg'),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        ecg_inds = ecg_inds[:n_max_ecg]
        ica.exclude += ecg_inds

        fig = ica.plot_sources(ecg_evoked, exclude=ecg_inds)
        report.add_figs_to_section(fig,
                                   'evoked sources ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        fig = ica.plot_overlay(ecg_evoked, exclude=ecg_inds)
        report.add_figs_to_section(fig,
                                   'rejection overlay ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

    # detect EOG by correlation
    eog_inds, scores = ica.find_bads_eog(raw)
    if len(eog_inds) > 0:
        fig = ica.plot_scores(scores,
                              exclude=eog_inds,
                              title=title % ('scores', 'eog'))
        report.add_figs_to_section(fig,
                                   'scores ({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)

        fig = ica.plot_sources(raw,
                               eog_inds,
                               exclude=ecg_inds,
                               title=title % ('sources', 'eog'))
        report.add_figs_to_section(fig,
                                   'sources',
                                   section=comment + 'EOG',
                                   scale=img_scale)

        fig = ica.plot_components(eog_inds,
                                  ch_type=topo_ch_type,
                                  title='',
                                  colorbar=True)
        report.add_figs_to_section(fig,
                                   title % ('components', 'eog'),
                                   section=comment + 'EOG',
                                   scale=img_scale)

        eog_inds = eog_inds[:n_max_eog]
        ica.exclude += eog_inds

        # estimate average artifact
        eog_evoked = create_eog_epochs(raw,
                                       tmin=eog_tmin,
                                       tmax=eog_tmax,
                                       picks=None).average(picks=picks)
        fig = ica.plot_sources(eog_evoked, exclude=eog_inds)
        report.add_figs_to_section(fig,
                                   'evoked sources ({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)

        fig = ica.plot_overlay(eog_evoked, exclude=eog_inds)
        report.add_figs_to_section(fig,
                                   'rejection overlay({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)

    # check the amplitudes do not change
    if len(ica.exclude) > 0:
        fig = ica.plot_overlay(raw)  # EOG artifacts remain
        report.add_figs_to_section(fig,
                                   'rejection overlay({})'.format(subject),
                                   section=comment + 'RAW',
                                   scale=img_scale)

    return ica, report
예제 #20
0
# bipolar reference from frontal EEG sensors and use that as virtual EOG
# channel. This carries a risk however: you must hope that the frontal EEG
# channels only reflect EOG and not brain dynamics in the prefrontal cortex (or
# you must not care about those prefrontal signals).
#
# For ECG, it is easier: :meth:`~mne.preprocessing.ICA.find_bads_ecg` can use
# cross-channel averaging of magnetometer or gradiometer channels to construct
# a virtual ECG channel, so if you have MEG channels it is usually not
# necessary to pass a specific channel name.
# :meth:`~mne.preprocessing.ICA.find_bads_ecg` also has two options for its
# ``method`` parameter: ``'ctps'`` (cross-trial phase statistics [3]_) and
# ``'correlation'`` (Pearson correlation between data and ECG channel).

ica.exclude = []
# find which ICs match the ECG pattern
ecg_indices, ecg_scores = ica.find_bads_ecg(raw, method='correlation')
ica.exclude = ecg_indices

# barplot of ICA component "ECG match" scores
ica.plot_scores(ecg_scores)

# plot diagnostics
ica.plot_properties(raw, picks=ecg_indices)

# plot ICs applied to raw data, with ECG matches highlighted
ica.plot_sources(raw)

# plot ICs applied to the averaged ECG epochs, with ECG matches highlighted
ica.plot_sources(ecg_evoked)

###############################################################################
예제 #21
0
def autodenoise_MEG(subject, run):

    ###############################################################################
    import numpy as np

    import mne
    import os.path as op
    import os
    import matplotlib
    matplotlib.use('Agg')

    from mne.report import Report
    from mne.io import Raw
    from mne.preprocessing import ICA
    from mne.preprocessing import create_ecg_epochs, create_eog_epochs

    data_path = '/neurospin/meg/meg_tmp/MTT_MEG_Baptiste/MEG/'
    raw_fname = data_path + subject + '/' + run + '_trans_sss.fif'
    # ICA
    report = Report(subject)

    raw = Raw(raw_fname, preload=True)
    raw.filter(None, 30, n_jobs=4)

    picks = mne.pick_types(raw.info,
                           meg=True,
                           eeg=False,
                           eog=False,
                           stim=False,
                           exclude='bads')

    ica = ICA(n_components=0.95, method='fastica')
    ica.fit(raw, picks=picks, decim=4)

    # maximum number of components to reject
    n_max_ecg, n_max_eogv, n_max_eogh = 3, 3, 3

    title = 'Sources related to %s artifacts (red)'

    # Create the results directory if it doesn't exist
    results_dir = op.join(data_path, subject, 'artefactICA')
    if not op.exists(results_dir):
        os.makedirs(results_dir)
    #ica_fname = '%s_ica' % (subject)

    ###############################################################################
    # generate ECG epochs use detection via phase statistics
    ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=picks)

    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    fig1 = ica.plot_scores(scores,
                           exclude=ecg_inds,
                           title=title % 'ecg',
                           labels='ecg')
    report.add_figs_to_section(fig1, captions='ECGcomp', section='ICA')

    show_picks = np.abs(scores).argsort()[::-1][:5]

    fig2 = ica.plot_sources(raw,
                            show_picks,
                            exclude=ecg_inds,
                            title=title % 'ecg')
    report.add_figs_to_section(fig2, captions='ECGcomptime', section='ICA')
    fig3 = ica.plot_components(ecg_inds, title=title % 'ecg', colorbar=True)
    report.add_figs_to_section(fig3, captions='ECGcomptopo', section='ICA')

    ecg_inds = ecg_inds[:n_max_ecg]

    report.save((results_dir + '/' + run + '.html'),
                open_browser=False,
                overwrite=True)
    ###############################################################################
    # detect vertical EOG by correlation

    eogv_inds = []
    eogv_inds, scores = ica.find_bads_eog(raw, ch_name='EOG061')
    fig4 = ica.plot_scores(scores,
                           exclude=eogv_inds,
                           title=title % 'eogv',
                           labels='ecg')
    report.add_figs_to_section(fig4, captions='EOGvcomp', section='ICA')

    show_picks = np.abs(scores).argsort()[::-1][:5]

    fig5 = ica.plot_sources(raw,
                            show_picks,
                            exclude=eogv_inds,
                            title=title % 'eogv')
    report.add_figs_to_section(fig5, captions='EOGvcomptime', section='ICA')
    fig6 = ica.plot_components(eogv_inds, title=title % 'eogv', colorbar=True)
    report.add_figs_to_section(fig6, captions='EOGvcomptopo', section='ICA')

    eogv_inds = eogv_inds[:n_max_eogv]

    report.save((results_dir + '/' + run + '.html'),
                open_browser=False,
                overwrite=True)
    ###############################################################################
    # detect horizontal EOG by correlation

    eogh_inds = []
    eogh_inds, scores = ica.find_bads_eog(raw, ch_name='EOG062')
    fig7 = ica.plot_scores(scores,
                           exclude=eogh_inds,
                           title=title % 'eogh',
                           labels='ecg')
    report.add_figs_to_section(fig7, captions='EOGhcomp', section='ICA')

    show_picks = np.abs(scores).argsort()[::-1][:5]

    fig8 = ica.plot_sources(raw,
                            show_picks,
                            exclude=eogh_inds,
                            title=title % 'eogh')
    report.add_figs_to_section(fig8, captions='EOGhcomptime', section='ICA')
    fig9 = ica.plot_components(eogh_inds, title=title % 'eogh', colorbar=True)
    report.add_figs_to_section(fig9, captions='EOGhcomptopo', section='ICA')

    eogh_inds = eogh_inds[:n_max_eogh]

    report.save((results_dir + '/' + run + '.html'),
                open_browser=False,
                overwrite=True)
    ###############################################################################
    # estimate average artifact
    ecg_evoked = ecg_epochs.average()
    fig10 = ica.plot_sources(ecg_evoked,
                             exclude=ecg_inds)  # plot ECG sources + selection
    fig11 = ica.plot_overlay(ecg_evoked, exclude=ecg_inds)  # plot ECG cleaning
    report.add_figs_to_section(fig10, captions='ECG sources', section='ICA')
    report.add_figs_to_section(fig11, captions='ECG clean', section='ICA')

    eogv_evoked = create_eog_epochs(raw,
                                    tmin=-.5,
                                    ch_name='EOG061',
                                    tmax=.5,
                                    picks=picks).average()
    fig12 = ica.plot_sources(eogv_evoked,
                             exclude=eogv_inds)  # plot EOG sources + selection
    fig13 = ica.plot_overlay(eogv_evoked,
                             exclude=eogv_inds)  # plot EOG cleaning
    report.add_figs_to_section(fig12, captions='EOGv sources', section='ICA')
    report.add_figs_to_section(fig13, captions='EOGv clean', section='ICA')

    eogh_evoked = create_eog_epochs(raw,
                                    tmin=-.5,
                                    ch_name='EOG062',
                                    tmax=.5,
                                    picks=picks).average()
    fig14 = ica.plot_sources(eogh_evoked,
                             exclude=eogh_inds)  # plot EOG sources + selection
    fig15 = ica.plot_overlay(eogh_evoked,
                             exclude=eogh_inds)  # plot EOG cleaning
    report.add_figs_to_section(fig14, captions='EOGh sources', section='ICA')
    report.add_figs_to_section(fig15, captions='EOGh clean', section='ICA')

    # check the amplitudes do not change
    fig16 = ica.plot_overlay(raw)  # EOG artifacts remain
    report.add_figs_to_section(fig16, captions='avg', section='ICA')

    ###############################################################################
    # Create the results directory if it doesn't exist
    ica_dir = op.join(data_path, subject, 'mne_python/ICA')
    if not op.exists(ica_dir):
        os.makedirs(ica_dir)

    # mark bad components and save ica
    artifact_inds = list(np.unique(eogv_inds + eogh_inds + ecg_inds))
    ica.exclude = []
    ica.exclude = artifact_inds
    ica.save((ica_dir + '/ICA_MEG' + run))
def runICA(raw, saveRoot, name):

    saveRoot = saveRoot
    icaList = []
    ica = []
    n_max_ecg = 3  # max number of ecg components
    #    n_max_eog_1 = 2 # max number of vert eog comps
    #    n_max_eog_2 = 2 # max number of horiz eog comps
    ecg_source_idx, ecg_scores, ecg_exclude = [], [], []
    eog_source_idx, eog_scores, eog_exclude = [], [], []
    #horiz = 1       # will later be modified to horiz = 0 if no horizontal EOG components are identified
    ica = ICA(n_components=0.90,
              n_pca_components=64,
              max_pca_components=100,
              noise_cov=None)

    fit_picks = mne.pick_types(raw.info,
                               meg=True,
                               eeg=True,
                               eog=False,
                               ecg=False,
                               stim=False,
                               exclude='bads')
    ica.fit(raw, picks=fit_picks)
    #ica.fit(raw)
    #*************
    eog_picks = mne.pick_types(raw.info,
                               meg=False,
                               eeg=False,
                               stim=False,
                               eog=True,
                               ecg=False,
                               emg=False)[0]
    ecg_picks = mne.pick_types(raw.info,
                               meg=False,
                               eeg=False,
                               stim=False,
                               ecg=True,
                               eog=False,
                               emg=False)[0]
    ica_picks = mne.pick_types(raw.info,
                               meg=True,
                               eeg=True,
                               eog=False,
                               ecg=False,
                               stim=False,
                               exclude='bads')
    ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5, picks=ica_picks)
    ecg_evoked = ecg_epochs.average()
    eog_evoked = create_eog_epochs(raw, tmin=-.5, tmax=.5,
                                   picks=ica_picks).average()

    ecg_source_idx, ecg_scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    eog_source_idx, eog_scores = ica.find_bads_eog(
        raw, ch_name=raw.ch_names[eog_picks].encode('ascii', 'ignore'))
    #eog_source_idx_2, eog_scores_2 = ica.find_bads_eog(raw,ch_name='EOG002')
    #if not eog_source_idx_2:
    #    horiz = 0

    #show_picks = np.abs(scores).argsort()[::-1][:5]
    #ica.plot_sources(raw, show_picks, exclude=ecg_inds, title=title % 'ecg')

    # defining a title-frame for later use
    title = 'Sources related to %s artifacts (red)'

    # extracting number of ica-components and plotting their topographies
    source_idx = range(0, ica.n_components_)
    #ica_plot = ica.plot_components(source_idx, ch_type="mag")
    ica_plot = ica.plot_components(source_idx)

    #ica_plot = ica.plot_components(source_idx)

    # select ICA sources and reconstruct MEG signals, compute clean ERFs
    # Add detected artefact sources to exclusion list
    # We now add the eog artefacts to the ica.exclusion list
    if not ecg_source_idx:
        print(
            "No ECG components above threshold were identified for subject " +
            name +
            " - selecting the component with the highest score under threshold"
        )
        ecg_exclude = [np.absolute(ecg_scores).argmax()]
        ecg_source_idx = [np.absolute(ecg_scores).argmax()]
    elif ecg_source_idx:
        ecg_exclude += ecg_source_idx[:n_max_ecg]
    ica.exclude += ecg_exclude

    if not eog_source_idx:
        if np.absolute(eog_scores).any > 0.3:
            eog_exclude = [np.absolute(eog_scores).argmax()]
            eog_source_idx = [np.absolute(eog_scores).argmax()]
            print(
                "No EOG components above threshold were identified " + name +
                " - selecting the component with the highest score under threshold above 0.3"
            )
        elif not np.absolute(eog_scores).any > 0.3:
            eog_exclude = []
            print("No EOG components above threshold were identified" + name)
    elif eog_source_idx:
        eog_exclude += eog_source_idx

    ica.exclude += eog_exclude

    print('########## saving')
    if len(eog_exclude) == 0:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg_none' +
                             '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' +
                             map(str, ecg_exclude)[0] + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' +
                             map(str, ecg_exclude)[0] + '_' +
                             map(str, ecg_exclude)[1] + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(saveRoot + name + '_comps_eog_none-ecg' +
                             map(str, ecg_exclude)[0] + '_' +
                             map(str, ecg_exclude)[1] + '_' +
                             map(str, ecg_exclude)[2] + '.pdf',
                             format='pdf')
    elif len(eog_exclude) == 1:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog' +
                             map(str, eog_exclude)[0] + '-ecg_none' + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog' +
                             map(str, eog_exclude)[0] + '-ecg' +
                             map(str, ecg_exclude)[0] + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(saveRoot + name + '_comps_eog' +
                             map(str, eog_exclude)[0] + '-ecg' +
                             map(str, ecg_exclude)[0] + '_' +
                             map(str, ecg_exclude)[1] + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(
                saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
                '-ecg' + map(str, ecg_exclude)[0] + '_' +
                map(str, ecg_exclude)[1] + '_' + map(str, ecg_exclude)[2] +
                '.pdf',
                format='pdf')
    elif len(eog_exclude) == 2:
        if len(ecg_exclude) == 0:
            ica_plot.savefig(saveRoot + name + '_comps_eog' +
                             map(str, eog_exclude)[0] + '_' +
                             map(str, eog_exclude)[1] + '-ecg_none' + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 1:
            ica_plot.savefig(saveRoot + name + '_comps_eog' +
                             map(str, eog_exclude)[0] + '_' +
                             map(str, eog_exclude)[1] + '-ecg' +
                             map(str, ecg_exclude)[0] + '.pdf',
                             format='pdf')
        elif len(ecg_exclude) == 2:
            ica_plot.savefig(
                saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
                '_' + map(str, eog_exclude)[1] + '-ecg' +
                map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] +
                '.pdf',
                format='pdf')
        elif len(ecg_exclude) == 3:
            ica_plot.savefig(
                saveRoot + name + '_comps_eog' + map(str, eog_exclude)[0] +
                '_' + map(str, eog_exclude)[1] + '-ecg' +
                map(str, ecg_exclude)[0] + '_' + map(str, ecg_exclude)[1] +
                '_' + map(str, ecg_exclude)[2] + '.pdf',
                format='pdf')

    # plot the scores for the different components highlighting in red that/those related to ECG
    #scores_plots=plt.figure()
    #ax = plt.subplot(2,1,1)
    scores_plots_ecg = ica.plot_scores(ecg_scores,
                                       exclude=ecg_source_idx,
                                       title=title % 'ecg')
    scores_plots_ecg.savefig(saveRoot + name + '_ecg_scores.pdf', format='pdf')
    #ax = plt.subplot(2,1,2)
    scores_plots_eog = ica.plot_scores(eog_scores,
                                       exclude=eog_source_idx,
                                       title=title % 'eog')
    scores_plots_eog.savefig(saveRoot + name + '_eog_scores.pdf', format='pdf')

    #if len(ecg_exclude) > 0:
    # estimate average artifact
    #source_clean_ecg=plt.figure()
    #ax = plt.subplot(2,1,1)
    source_source_ecg = ica.plot_sources(ecg_evoked, exclude=ecg_source_idx)
    source_source_ecg.savefig(saveRoot + name + '_ecg_source.pdf',
                              format='pdf')
    #ax = plt.subplot(2,1,2)
    source_clean_ecg = ica.plot_overlay(ecg_evoked, exclude=ecg_source_idx)
    source_clean_ecg.savefig(saveRoot + name + '_ecg_clean.pdf', format='pdf')
    #clean_plot.savefig(saveRoot + name + '_ecg_clean.pdf', format = 'pdf')

    #if len(eog_exclude) > 0:
    source_source_eog = ica.plot_sources(eog_evoked, exclude=eog_source_idx)
    source_source_eog.savefig(saveRoot + name + '_eog_source.pdf',
                              format='pdf')
    source_clean_eog = ica.plot_overlay(eog_evoked, exclude=eog_source_idx)
    source_clean_eog.savefig(saveRoot + name + '_eog_clean.pdf', format='pdf')

    overl_plot = ica.plot_overlay(raw)
    overl_plot.savefig(saveRoot + name + '_overl.pdf', format='pdf')

    plt.close('all')
    ## restore sensor space data
    icaList = ica.apply(raw)
    return (icaList, ica)
예제 #23
0
파일: neuro.py 프로젝트: hyruuk/saflow
def saflow_preproc(filepath, savepath, reportpath):
    report = mne.Report(verbose=True)
    raw = read_raw_ctf(filepath, preload=True)
    raw_data = raw.copy().apply_gradient_compensation(
        grade=3)  #required for source reconstruction
    picks = mne.pick_types(raw_data.info, meg=True, eog=True, exclude='bads')
    fig = raw_data.plot(show=False)
    report.add_figs_to_section(fig, captions='Time series', section='Raw data')
    close(fig)
    fig = raw_data.plot_psd(average=False, picks=picks, show=False)
    report.add_figs_to_section(fig, captions='PSD', section='Raw data')
    close(fig)

    ## Filtering
    high_cutoff = 200
    low_cutoff = 0.5
    raw_data.filter(low_cutoff, high_cutoff, fir_design="firwin")
    raw_data.notch_filter(np.arange(60, high_cutoff + 1, 60),
                          picks=picks,
                          filter_length='auto',
                          phase='zero',
                          fir_design="firwin")
    fig = raw_data.plot_psd(average=False, picks=picks, fmax=120, show=False)
    report.add_figs_to_section(fig, captions='PSD', section='Filtered data')
    close(fig)

    ## ICA
    ica = ICA(n_components=20, random_state=0).fit(raw_data, decim=3)
    fig = ica.plot_sources(raw_data, show=False)
    report.add_figs_to_section(fig,
                               captions='Independent Components',
                               section='ICA')
    close(fig)

    ## FIND ECG COMPONENTS
    ecg_threshold = 0.50
    ecg_epochs = create_ecg_epochs(raw_data, ch_name='EEG059')
    ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs,
                                             ch_name='EEG059',
                                             method='ctps',
                                             threshold=ecg_threshold)
    fig = ica.plot_scores(ecg_scores, ecg_inds, show=False)
    report.add_figs_to_section(fig,
                               captions='Correlation with ECG (EEG059)',
                               section='ICA - ECG')
    close(fig)
    fig = list()
    try:
        fig = ica.plot_properties(ecg_epochs,
                                  picks=ecg_inds,
                                  image_args={'sigma': 1.},
                                  show=False)
        for i, figure in enumerate(fig):
            report.add_figs_to_section(figure,
                                       captions='Detected component ' + str(i),
                                       section='ICA - ECG')
            close(figure)
    except:
        print('No component to remove')

    ## FIND EOG COMPONENTS
    eog_threshold = 4
    eog_epochs = create_eog_epochs(raw_data, ch_name='EEG057')
    eog_inds, eog_scores = ica.find_bads_eog(eog_epochs,
                                             ch_name='EEG057',
                                             threshold=eog_threshold)
    fig = ica.plot_scores(eog_scores, eog_inds, show=False)
    report.add_figs_to_section(fig,
                               captions='Correlation with EOG (EEG057)',
                               section='ICA - EOG')
    close(fig)
    fig = list()
    try:
        fig = ica.plot_properties(eog_epochs,
                                  picks=eog_inds,
                                  image_args={'sigma': 1.},
                                  show=False)
        for i, figure in enumerate(fig):
            report.add_figs_to_section(figure,
                                       captions='Detected component ' + str(i),
                                       section='ICA - EOG')
            close(figure)
    except:
        print('No component to remove')

    ## EXCLUDE COMPONENTS
    ica.exclude = ecg_inds
    ica.apply(raw_data)
    ica.exclude = eog_inds
    ica.apply(raw_data)
    fig = raw_data.plot(show=False)
    # Plot the clean signal.
    report.add_figs_to_section(fig,
                               captions='After filtering + ICA',
                               section='Raw data')
    close(fig)
    ## SAVE PREPROCESSED FILE
    report.save(reportpath, open_browser=False, overwrite=True)
    raw_data.save(savepath, overwrite=False)

    return raw_data
예제 #24
0
Raw.filter(1, 40, fir_design='firwin')
Events = find_events(Raw)

#%% run ICA for automatic ocular & cardiac rejection (plot the rejected topos)
picks_ica = pick_types(Raw.info, meg=True)
ica = ICA(n_components=0.98, method='fastica')
ica.fit(Raw, picks=picks_ica, reject=reject_ica, decim=4)
ecg_epochs = create_ecg_epochs(
    Raw, ch_name='MEG0111', reject=reject_ica
)  # ch_name='MEG0141') # find the ECG events automagically
eog_epochs = create_eog_epochs(
    Raw, reject=reject_ica)  # find the EOG events automagically
ecg_epochs.average().plot_joint(times=0)
eog_epochs.average().plot_joint(times=0)
ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs,
                                         ch_name='MEG0111',
                                         method='ctps',
                                         threshold=0.2)
print(ecg_inds)
eog_inds, eog_scores = ica.find_bads_eog(eog_epochs)
print(eog_inds)
#ica.plot_overlay(ecg_average, exclude=ecg_inds) # does not work?
try:
    ica.plot_components(ch_type='mag', picks=ecg_inds)
except IndexError as exc:
    pass
try:
    ica.plot_components(ch_type='mag', picks=eog_inds)
except IndexError as exc:
    pass
ica.exclude.extend(eog_inds)
ica.exclude.extend(ecg_inds)
예제 #25
0
def test_ica_additional(method):
    """Test additional ICA functionality."""
    _skip_check_picard(method)

    tempdir = _TempDir()
    stop2 = 500
    raw = read_raw_fif(raw_fname).crop(1.5, stop).load_data()
    raw.del_proj()  # avoid warnings
    raw.set_annotations(Annotations([0.5], [0.5], ['BAD']))
    # XXX This breaks the tests :(
    # raw.info['bads'] = [raw.ch_names[1]]
    test_cov = read_cov(test_cov_name)
    events = read_events(event_name)
    picks = pick_types(raw.info,
                       meg=True,
                       stim=False,
                       ecg=False,
                       eog=False,
                       exclude='bads')[1::2]
    epochs = Epochs(raw,
                    events,
                    None,
                    tmin,
                    tmax,
                    picks=picks,
                    baseline=(None, 0),
                    preload=True,
                    proj=False)
    epochs.decimate(3, verbose='error')
    assert len(epochs) == 4

    # test if n_components=None works
    ica = ICA(n_components=None,
              max_pca_components=None,
              n_pca_components=None,
              random_state=0,
              method=method,
              max_iter=1)
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(epochs)
    # for testing eog functionality
    picks2 = np.concatenate([picks, pick_types(raw.info, False, eog=True)])
    epochs_eog = Epochs(raw,
                        events[:4],
                        event_id,
                        tmin,
                        tmax,
                        picks=picks2,
                        baseline=(None, 0),
                        preload=True)
    del picks2

    test_cov2 = test_cov.copy()
    ica = ICA(noise_cov=test_cov2,
              n_components=3,
              max_pca_components=4,
              n_pca_components=4,
              method=method)
    assert (ica.info is None)
    with pytest.warns(RuntimeWarning, match='normalize_proj'):
        ica.fit(raw, picks[:5])
    assert (isinstance(ica.info, Info))
    assert (ica.n_components_ < 5)

    ica = ICA(n_components=3,
              max_pca_components=4,
              method=method,
              n_pca_components=4,
              random_state=0)
    pytest.raises(RuntimeError, ica.save, '')

    ica.fit(raw, picks=[1, 2, 3, 4, 5], start=start, stop=stop2)

    # check passing a ch_name to find_bads_ecg
    with pytest.warns(RuntimeWarning, match='longer'):
        _, scores_1 = ica.find_bads_ecg(raw)
        _, scores_2 = ica.find_bads_ecg(raw, raw.ch_names[1])
    assert scores_1[0] != scores_2[0]

    # test corrmap
    ica2 = ica.copy()
    ica3 = ica.copy()
    corrmap([ica, ica2], (0, 0),
            threshold='auto',
            label='blinks',
            plot=True,
            ch_type="mag")
    corrmap([ica, ica2], (0, 0), threshold=2, plot=False, show=False)
    assert (ica.labels_["blinks"] == ica2.labels_["blinks"])
    assert (0 in ica.labels_["blinks"])
    # test retrieval of component maps as arrays
    components = ica.get_components()
    template = components[:, 0]
    EvokedArray(components, ica.info, tmin=0.).plot_topomap([0], time_unit='s')

    corrmap([ica, ica3],
            template,
            threshold='auto',
            label='blinks',
            plot=True,
            ch_type="mag")
    assert (ica2.labels_["blinks"] == ica3.labels_["blinks"])

    plt.close('all')

    # make sure a single threshold in a list works
    corrmap([ica, ica3],
            template,
            threshold=[0.5],
            label='blinks',
            plot=True,
            ch_type="mag")

    ica_different_channels = ICA(n_components=2,
                                 random_state=0).fit(raw, picks=[2, 3, 4, 5])
    pytest.raises(ValueError, corrmap, [ica_different_channels, ica], (0, 0))

    # test warnings on bad filenames
    ica_badname = op.join(op.dirname(tempdir), 'test-bad-name.fif.gz')
    with pytest.warns(RuntimeWarning, match='-ica.fif'):
        ica.save(ica_badname)
    with pytest.warns(RuntimeWarning, match='-ica.fif'):
        read_ica(ica_badname)

    # test decim
    ica = ICA(n_components=3,
              max_pca_components=4,
              n_pca_components=4,
              method=method,
              max_iter=1)
    raw_ = raw.copy()
    for _ in range(3):
        raw_.append(raw_)
    n_samples = raw_._data.shape[1]
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(raw, picks=picks[:5], decim=3)
    assert raw_._data.shape[1] == n_samples

    # test expl var
    ica = ICA(n_components=1.0,
              max_pca_components=4,
              n_pca_components=4,
              method=method,
              max_iter=1)
    with pytest.warns(UserWarning, match='did not converge'):
        ica.fit(raw, picks=None, decim=3)
    assert (ica.n_components_ == 4)
    ica_var = _ica_explained_variance(ica, raw, normalize=True)
    assert (np.all(ica_var[:-1] >= ica_var[1:]))

    # test ica sorting
    ica.exclude = [0]
    ica.labels_ = dict(blink=[0], think=[1])
    ica_sorted = _sort_components(ica, [3, 2, 1, 0], copy=True)
    assert_equal(ica_sorted.exclude, [3])
    assert_equal(ica_sorted.labels_, dict(blink=[3], think=[2]))

    # epochs extraction from raw fit
    pytest.raises(RuntimeError, ica.get_sources, epochs)
    # test reading and writing
    test_ica_fname = op.join(op.dirname(tempdir), 'test-ica.fif')
    for cov in (None, test_cov):
        ica = ICA(noise_cov=cov,
                  n_components=2,
                  max_pca_components=4,
                  n_pca_components=4,
                  method=method,
                  max_iter=1)
        with pytest.warns(None):  # ICA does not converge
            ica.fit(raw, picks=picks[:10], start=start, stop=stop2)
        sources = ica.get_sources(epochs).get_data()
        assert (ica.mixing_matrix_.shape == (2, 2))
        assert (ica.unmixing_matrix_.shape == (2, 2))
        assert (ica.pca_components_.shape == (4, 10))
        assert (sources.shape[1] == ica.n_components_)

        for exclude in [[], [0], np.array([1, 2, 3])]:
            ica.exclude = exclude
            ica.labels_ = {'foo': [0]}
            ica.save(test_ica_fname)
            ica_read = read_ica(test_ica_fname)
            assert (list(ica.exclude) == ica_read.exclude)
            assert_equal(ica.labels_, ica_read.labels_)
            ica.apply(raw)
            ica.exclude = []
            ica.apply(raw, exclude=[1])
            assert (ica.exclude == [])

            ica.exclude = [0, 1]
            ica.apply(raw, exclude=[1])
            assert (ica.exclude == [0, 1])

            ica_raw = ica.get_sources(raw)
            assert (ica.exclude == [
                ica_raw.ch_names.index(e) for e in ica_raw.info['bads']
            ])

        # test filtering
        d1 = ica_raw._data[0].copy()
        ica_raw.filter(4, 20, fir_design='firwin2')
        assert_equal(ica_raw.info['lowpass'], 20.)
        assert_equal(ica_raw.info['highpass'], 4.)
        assert ((d1 != ica_raw._data[0]).any())
        d1 = ica_raw._data[0].copy()
        ica_raw.notch_filter([10], trans_bandwidth=10, fir_design='firwin')
        assert ((d1 != ica_raw._data[0]).any())

        ica.n_pca_components = 2
        ica.method = 'fake'
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        assert (ica.n_pca_components == ica_read.n_pca_components)
        assert_equal(ica.method, ica_read.method)
        assert_equal(ica.labels_, ica_read.labels_)

        # check type consistency
        attrs = ('mixing_matrix_ unmixing_matrix_ pca_components_ '
                 'pca_explained_variance_ pre_whitener_')

        def f(x, y):
            return getattr(x, y).dtype

        for attr in attrs.split():
            assert_equal(f(ica_read, attr), f(ica, attr))

        ica.n_pca_components = 4
        ica_read.n_pca_components = 4

        ica.exclude = []
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        for attr in [
                'mixing_matrix_', 'unmixing_matrix_', 'pca_components_',
                'pca_mean_', 'pca_explained_variance_', 'pre_whitener_'
        ]:
            assert_array_almost_equal(getattr(ica, attr),
                                      getattr(ica_read, attr))

        assert (ica.ch_names == ica_read.ch_names)
        assert (isinstance(ica_read.info, Info))

        sources = ica.get_sources(raw)[:, :][0]
        sources2 = ica_read.get_sources(raw)[:, :][0]
        assert_array_almost_equal(sources, sources2)

        _raw1 = ica.apply(raw, exclude=[1])
        _raw2 = ica_read.apply(raw, exclude=[1])
        assert_array_almost_equal(_raw1[:, :][0], _raw2[:, :][0])

    os.remove(test_ica_fname)
    # check score funcs
    for name, func in get_score_funcs().items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(raw,
                                   target='EOG 061',
                                   score_func=func,
                                   start=0,
                                   stop=10)
        assert (ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(raw, start=0, stop=50, score_func=stats.skew)
    # check exception handling
    pytest.raises(ValueError, ica.score_sources, raw, target=np.arange(1))

    params = []
    params += [(None, -1, slice(2), [0, 1])]  # variance, kurtosis params
    params += [(None, 'MEG 1531')]  # ECG / EOG channel params
    for idx, ch_name in product(*params):
        ica.detect_artifacts(raw,
                             start_find=0,
                             stop_find=50,
                             ecg_ch=ch_name,
                             eog_ch=ch_name,
                             skew_criterion=idx,
                             var_criterion=idx,
                             kurt_criterion=idx)

    # Make sure detect_artifacts marks the right components.
    # For int criterion, the doc says "E.g. range(2) would return the two
    # sources with the highest score". Assert that's what it does.
    # Only test for skew, since it's always the same code.
    ica.exclude = []
    ica.detect_artifacts(raw,
                         start_find=0,
                         stop_find=50,
                         ecg_ch=None,
                         eog_ch=None,
                         skew_criterion=0,
                         var_criterion=None,
                         kurt_criterion=None)
    assert np.abs(scores[ica.exclude]) == np.max(np.abs(scores))

    evoked = epochs.average()
    evoked_data = evoked.data.copy()
    raw_data = raw[:][0].copy()
    epochs_data = epochs.get_data().copy()

    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_ecg(raw, method='ctps')
    assert_equal(len(scores), ica.n_components_)
    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_ecg(raw, method='correlation')
    assert_equal(len(scores), ica.n_components_)

    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_eog(raw)
    assert_equal(len(scores), ica.n_components_)

    idx, scores = ica.find_bads_ecg(epochs, method='ctps')

    assert_equal(len(scores), ica.n_components_)
    pytest.raises(ValueError,
                  ica.find_bads_ecg,
                  epochs.average(),
                  method='ctps')
    pytest.raises(ValueError, ica.find_bads_ecg, raw, method='crazy-coupling')

    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_eog(raw)
    assert_equal(len(scores), ica.n_components_)

    raw.info['chs'][raw.ch_names.index('EOG 061') - 1]['kind'] = 202
    with pytest.warns(RuntimeWarning, match='longer'):
        idx, scores = ica.find_bads_eog(raw)
    assert (isinstance(scores, list))
    assert_equal(len(scores[0]), ica.n_components_)

    idx, scores = ica.find_bads_eog(evoked, ch_name='MEG 1441')
    assert_equal(len(scores), ica.n_components_)

    idx, scores = ica.find_bads_ecg(evoked, method='correlation')
    assert_equal(len(scores), ica.n_components_)

    assert_array_equal(raw_data, raw[:][0])
    assert_array_equal(epochs_data, epochs.get_data())
    assert_array_equal(evoked_data, evoked.data)

    # check score funcs
    for name, func in get_score_funcs().items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(epochs_eog,
                                   target='EOG 061',
                                   score_func=func)
        assert (ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(epochs, score_func=stats.skew)

    # check exception handling
    pytest.raises(ValueError, ica.score_sources, epochs, target=np.arange(1))

    # ecg functionality
    ecg_scores = ica.score_sources(raw,
                                   target='MEG 1531',
                                   score_func='pearsonr')

    with pytest.warns(RuntimeWarning, match='longer'):
        ecg_events = ica_find_ecg_events(raw,
                                         sources[np.abs(ecg_scores).argmax()])
    assert (ecg_events.ndim == 2)

    # eog functionality
    eog_scores = ica.score_sources(raw,
                                   target='EOG 061',
                                   score_func='pearsonr')
    with pytest.warns(RuntimeWarning, match='longer'):
        eog_events = ica_find_eog_events(raw,
                                         sources[np.abs(eog_scores).argmax()])
    assert (eog_events.ndim == 2)

    # Test ica fiff export
    ica_raw = ica.get_sources(raw, start=0, stop=100)
    assert (ica_raw.last_samp - ica_raw.first_samp == 100)
    assert_equal(len(ica_raw._filenames), 1)  # API consistency
    ica_chans = [ch for ch in ica_raw.ch_names if 'ICA' in ch]
    assert (ica.n_components_ == len(ica_chans))
    test_ica_fname = op.join(op.abspath(op.curdir), 'test-ica_raw.fif')
    ica.n_components = np.int32(ica.n_components)
    ica_raw.save(test_ica_fname, overwrite=True)
    ica_raw2 = read_raw_fif(test_ica_fname, preload=True)
    assert_allclose(ica_raw._data, ica_raw2._data, rtol=1e-5, atol=1e-4)
    ica_raw2.close()
    os.remove(test_ica_fname)

    # Test ica epochs export
    ica_epochs = ica.get_sources(epochs)
    assert (ica_epochs.events.shape == epochs.events.shape)
    ica_chans = [ch for ch in ica_epochs.ch_names if 'ICA' in ch]
    assert (ica.n_components_ == len(ica_chans))
    assert (ica.n_components_ == ica_epochs.get_data().shape[1])
    assert (ica_epochs._raw is None)
    assert (ica_epochs.preload is True)

    # test float n pca components
    ica.pca_explained_variance_ = np.array([0.2] * 5)
    ica.n_components_ = 0
    for ncomps, expected in [[0.3, 1], [0.9, 4], [1, 1]]:
        ncomps_ = ica._check_n_pca_components(ncomps)
        assert (ncomps_ == expected)

    ica = ICA(method=method)
    with pytest.warns(None):  # sometimes does not converge
        ica.fit(raw, picks=picks[:5])
    with pytest.warns(RuntimeWarning, match='longer'):
        ica.find_bads_ecg(raw)
    ica.find_bads_eog(epochs, ch_name='MEG 0121')
    assert_array_equal(raw_data, raw[:][0])

    raw.drop_channels(['MEG 0122'])
    pytest.raises(RuntimeError, ica.find_bads_eog, raw)
    with pytest.warns(RuntimeWarning, match='longer'):
        pytest.raises(RuntimeError, ica.find_bads_ecg, raw)
예제 #26
0
파일: doica_trc.py 프로젝트: jshanna100/epi
proc_dir = root_dir+"proc/"
proclist = listdir(proc_dir)

l_freq = 0.3
h_freq = 200
n_jobs = "cuda"
max_thresh = 2e-3

for filename in proclist:
    this_match = re.match("c_EPI_(.*)-raw.fif", filename)
    if not this_match:
        continue
    file_id = this_match.groups(1)[0]
    raw = mne.io.Raw(proc_dir+filename, preload=True)
    raw_sel = raw.copy().pick_channels(["Cz", "Fz", "F3", "F4", "C3", "C4",
                                        "Pz", "Fp1", "Fp2", "O1", "O2",
                                        "VEOG", "HEOG", "ECG1+"])
    raw_sel.filter(l_freq=0.3, h_freq=30, n_jobs=4)
    raw_sel.resample(100, n_jobs="cuda")
    ica = ICA(method="picard")
    ica.fit(raw_sel)
    ica.save("{}sel_c_EPI_{}-ica.fif".format(proc_dir, file_id))

    bads_eog, scores = ica.find_bads_eog(raw_sel, ch_name="VEOG", threshold=2.3)
    bads_ecg ,scores = ica.find_bads_ecg(raw_sel, ch_name="ECG1+")
    bad_comps = bads_eog + bads_ecg
    raw_sel = ica.apply(raw_sel, exclude=bad_comps)

    raw_sel.save("{}csel_{}".format(proc_dir, filename), overwrite=True)
예제 #27
0
n_max_eog = 1  # here we bet on finding the vertical EOG components
eog_epochs = create_eog_epochs(raw_sss, reject=reject)  # get single EOG trials
eog_inds, scores = ica.find_bads_eog(eog_epochs)  # find via correlation
print(ica)
raw_sss.plot_psd(fmax=100)

#ica.plot_scores(scores, exclude=eog_inds)
#ica.plot_sources(eog_average, exclude=eog_inds)  # look at source time course

ica.apply(raw_sss, exclude=eog_inds)
print(ica)
raw_sss.plot_psd(fmax=100)

ecg_epochs = create_ecg_epochs(raw_sss, tmin=-.5, tmax=.5)
ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')

ica.apply(raw_sss, exclude=ecg_inds)
raw_sss.plot_psd(fmax=100)

ica.plot_properties(ecg_epochs, picks=ecg_inds, psd_args={'fmax': 35.})

#****************************************************************************#
#                                     ERP                                    #
#****************************************************************************#
tmin, tmax = -0.5, 0.7
event_id = {'Auditory/Left': 1}
events = mne.find_events(raw, 'STI 014')
picks = mne.pick_types(raw.info,
                       meg=True,
                       eeg=True,
예제 #28
0
def compute_ica(fif_file, ecg_ch_name, eog_ch_name, n_components, reject):
    """Compute ica solution"""

    import os

    import mne
    from mne.io import read_raw_fif
    from mne.preprocessing import ICA
    from mne.preprocessing import create_ecg_epochs, create_eog_epochs

    from nipype.utils.filemanip import split_filename as split_f

    subj_path, basename, ext = split_f(fif_file)

    raw = read_raw_fif(fif_file, preload=True)

    # select sensors
    select_sensors = mne.pick_types(raw.info, meg=True,
                                    ref_meg=False, exclude='bads')

    # 1) Fit ICA model using the FastICA algorithm
    # Other available choices are `infomax` or `extended-infomax`
    # We pass a float value between 0 and 1 to select n_components based on the
    # percentage of variance explained by the PCA components.

    # reject = dict(mag=1e-1, grad=1e-9)
    flat = dict(mag=1e-13, grad=1e-13)

    ica = ICA(n_components=n_components, method='fastica', max_iter=500)

    ica.fit(raw, picks=select_sensors, reject=reject, flat=flat)
    # -------------------- Save ica timeseries ---------------------------- #
    ica_ts_file = os.path.abspath(basename + "_ica-tseries.fif")
    ica_src = ica.get_sources(raw)
    ica_src.save(ica_ts_file)
    ica_src = None
    # --------------------------------------------------------------------- #

    # 2) identify bad components by analyzing latent sources.
    # generate ECG epochs use detection via phase statistics

    # if we just have exclude channels we jump these steps
    n_max_ecg = 3
    n_max_eog = 2

    # check if ecg_ch_name is in the raw channels
    if ecg_ch_name in raw.info['ch_names']:
        raw.set_channel_types({ecg_ch_name: 'ecg'})
    else:
        ecg_ch_name = None

    ecg_epochs = create_ecg_epochs(raw, tmin=-0.5, tmax=0.5,
                                   picks=select_sensors,
                                   ch_name=ecg_ch_name)

    ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs, method='ctps')

    ecg_evoked = ecg_epochs.average()
    ecg_epochs = None

    ecg_inds = ecg_inds[:n_max_ecg]
    ica.exclude += ecg_inds

    eog_ch_name = eog_ch_name.replace(' ', '')
    if set(eog_ch_name.split(',')).issubset(set(raw.info['ch_names'])):
        print('*** EOG CHANNELS FOUND ***')
        eog_inds, eog_scores = ica.find_bads_eog(raw, ch_name=eog_ch_name)
        eog_inds = eog_inds[:n_max_eog]
        ica.exclude += eog_inds
        eog_evoked = create_eog_epochs(raw, tmin=-0.5, tmax=0.5,
                                       picks=select_sensors,
                                       ch_name=eog_ch_name).average()
    else:
        print('*** NO EOG CHANNELS FOUND!!! ***')
        eog_inds = eog_scores = eog_evoked = None

    report_file = generate_report(raw=raw, ica=ica, subj_name=fif_file,
                                  basename=basename,
                                  ecg_evoked=ecg_evoked, ecg_scores=ecg_scores,
                                  ecg_inds=ecg_inds, ecg_ch_name=ecg_ch_name,
                                  eog_evoked=eog_evoked, eog_scores=eog_scores,
                                  eog_inds=eog_inds, eog_ch_name=eog_ch_name)

    report_file = os.path.abspath(report_file)

    ica_sol_file = os.path.abspath(basename + '_ica_solution.fif')

    ica.save(ica_sol_file)
    raw_ica = ica.apply(raw)
    raw_ica_file = os.path.abspath(basename + '_ica' + ext)
    raw_ica.save(raw_ica_file)

    return raw_ica_file, ica_sol_file, ica_ts_file, report_file
예제 #29
0
파일: artifacts.py 프로젝트: adswa/pymento
def remove_eyeblinks_and_heartbeat(raw, subject, figdir, events, eventid, rng):
    """
    Find and repair eyeblink and heartbeat artifacts in the data.
    Data should be filtered.
    Importantly, ICA is fitted on artificially epoched data with reject
    criteria estimates via the autoreject package - this is done to reject high-
    amplitude artifacts to influence the ICA solution.
    The ICA fit is then applied to the raw data.
    :param raw: Raw data
    :param subject: str, subject identifier, e.g., '001'
    :param figdir:
    :param rng: random state instance
    """
    # prior to an ICA, it is recommended to high-pass filter the data
    # as low frequency artifacts can alter the ICA solution. We fit the ICA
    # to high-pass filtered (1Hz) data, and apply it to non-highpass-filtered
    # data
    logging.info("Applying a temporary high-pass filtering prior to ICA")
    filt_raw = raw.copy()
    filt_raw.load_data().filter(l_freq=1., h_freq=None)
    # evoked eyeblinks and heartbeats for diagnostic plots

    eog_evoked = create_eog_epochs(filt_raw).average()
    eog_evoked.apply_baseline(baseline=(None, -0.2))
    if subject == '008':
        # subject 008's ECG channel is flat. It will not find any heartbeats by
        # default. We let it estimate heartbeat from magnetometers. For this,
        # we'll drop the ECG channel
        filt_raw.drop_channels('ECG003')
    ecg_evoked = create_ecg_epochs(filt_raw).average()
    ecg_evoked.apply_baseline(baseline=(None, -0.2))
    # make sure that we actually found sensible artifacts here
    eog_fig = eog_evoked.plot_joint()
    for i, fig in enumerate(eog_fig):
        fname = _construct_path([
            Path(figdir),
            f"sub-{subject}",
            "meg",
            f"evoked-artifact_eog_sub-{subject}_{i}.png",
        ])
        fig.savefig(fname)
    ecg_fig = ecg_evoked.plot_joint()
    for i, fig in enumerate(ecg_fig):
        fname = _construct_path([
            Path(figdir),
            f"sub-{subject}",
            "meg",
            f"evoked-artifact_ecg_sub-{subject}_{i}.png",
        ])
        fig.savefig(fname)
    # Chunk raw data into epochs to fit the ICA
    # No baseline correction as it would interfere with ICA.
    logging.info("Epoching filtered data")
    epochs = mne.Epochs(filt_raw,
                        events,
                        event_id=eventid,
                        tmin=0,
                        tmax=3,
                        picks='meg',
                        baseline=None)

    ## First, estimate rejection criteria for high-amplitude artifacts. This is
    ## done via autoreject
    #logging.info('Estimating bad epochs quick-and-dirty, to improve ICA')
    #ar = AutoReject(random_state=rng)
    # fit on first 200 epochs to save (a bit of) time
    #epochs.load_data()
    #ar.fit(epochs[:200])
    #epochs_ar, reject_log = ar.transform(epochs, return_log=True)

    # run an ICA to capture heartbeat and eyeblink artifacts.
    # set a seed for reproducibility.
    # When left to figure out the component number by itself, it ends up with
    # about 80. I'm setting n_components to 45 to have a chance at checking them
    # by hand.
    # We fit it on a set of epochs excluding the initial bad epochs following
    # https://github.com/autoreject/autoreject/blob/dfbc64f49eddeda53c5868290a6792b5233843c6/examples/plot_autoreject_workflow.py
    logging.info('Fitting the ICA')
    ica = ICA(max_iter='auto', n_components=45, random_state=rng)
    ica.fit(epochs)  #[~reject_log.bad_epochs])
    logging.info("Searching for eyeblink and heartbeat artifacts in the data")
    # get ICA components for the given subject
    if subject == '008':
        eog_indices = [10]
        ecg_indices = [29]
        #eog_indices = ica_comps[subject]['eog']
        #ecg_indices = ica_comps[subject]['ecg']
    # An initially manual component detection did not reproduce after a software
    # update - for now, we have to do the automatic detection for all but sub 8
    else:
        eog_indices, eog_scores = ica.find_bads_eog(filt_raw)
        ecg_indices, ecg_scores = ica.find_bads_ecg(filt_raw)
        logging.info(f"Identified the following EOG components: {eog_indices}")
        logging.info(f"Identified the following ECG components: {ecg_indices}")
    # visualize the components
    components = ica.plot_components()
    for i, fig in enumerate(components):
        fname = _construct_path([
            Path(figdir),
            f"sub-{subject}",
            "meg",
            f"ica-components_sub-{subject}_{i}.png",
        ])
        fig.savefig(fname)
    # visualize the time series of components and save it
    plt.rcParams['figure.figsize'] = 30, 20
    comp_sources = ica.plot_sources(epochs)
    fname = _construct_path([
        Path(figdir),
        f"sub-{subject}",
        "meg",
        f"ica-components_sources_sub-{subject}.png",
    ])
    comp_sources.savefig(fname)
    # reset plotting params
    plt.rcParams['figure.figsize'] = plt.rcParamsDefault['figure.figsize']

    # plot EOG components
    overlay_eog = ica.plot_overlay(eog_evoked,
                                   exclude=ica_comps[subject]['eog'])
    fname = _construct_path([
        Path(figdir),
        f"sub-{subject}",
        "meg",
        f"ica-eog-components_over-avg-epochs_sub-{subject}.png",
    ])
    overlay_eog.savefig(fname)
    # plot ECG components
    overlay_ecg = ica.plot_overlay(ecg_evoked,
                                   exclude=ica_comps[subject]['ecg'])
    fname = _construct_path([
        Path(figdir),
        f"sub-{subject}",
        "meg",
        f"ica-ecg-components_over-avg-epochs_sub-{subject}.png",
    ])
    overlay_ecg.savefig(fname)
    # plot EOG component properties
    figs = ica.plot_properties(filt_raw, picks=eog_indices)
    for i, fig in enumerate(figs):
        fname = _construct_path([
            Path(figdir),
            f"sub-{subject}",
            "meg",
            f"ica-property{i}_artifact-eog_sub-{subject}.png",
        ])
        fig.savefig(fname)
    # plot ECG component properties
    figs = ica.plot_properties(filt_raw, picks=ecg_indices)
    for i, fig in enumerate(figs):
        fname = _construct_path([
            Path(figdir),
            f"sub-{subject}",
            "meg",
            f"ica-property{i}_artifact-ecg_sub-{subject}.png",
        ])
        fig.savefig(fname)

    # Set the indices to be excluded
    ica.exclude = eog_indices
    ica.exclude.extend(ecg_indices)

    # plot ICs applied to the averaged EOG epochs, with EOG matches highlighted
    sources = ica.plot_sources(eog_evoked)
    fname = _construct_path([
        Path(figdir),
        f"sub-{subject}",
        "meg",
        f"ica-sources_artifact-eog_sub-{subject}.png",
    ])
    sources.savefig(fname)

    # plot ICs applied to the averaged ECG epochs, with ECG matches highlighted
    sources = ica.plot_sources(ecg_evoked)
    fname = _construct_path([
        Path(figdir),
        f"sub-{subject}",
        "meg",
        f"ica-sources_artifact-ecg_sub-{subject}.png",
    ])
    sources.savefig(fname)
    # apply the ICA to the raw data
    logging.info('Applying ICA to the raw data.')
    raw.load_data()
    ica.apply(raw)
예제 #30
0
파일: test_ica.py 프로젝트: rgoj/mne-python
def test_ica_additional():
    """Test additional ICA functionality"""
    stop2 = 500
    raw = io.Raw(raw_fname, preload=True).crop(0, stop, False).crop(1.5)
    picks = pick_types(raw.info, meg=True, stim=False, ecg=False, eog=False, exclude="bads")
    test_cov = read_cov(test_cov_name)
    events = read_events(event_name)
    picks = pick_types(raw.info, meg=True, stim=False, ecg=False, eog=False, exclude="bads")
    epochs = Epochs(raw, events[:4], event_id, tmin, tmax, picks=picks, baseline=(None, 0), preload=True)
    # for testing eog functionality
    picks2 = pick_types(raw.info, meg=True, stim=False, ecg=False, eog=True, exclude="bads")
    epochs_eog = Epochs(raw, events[:4], event_id, tmin, tmax, picks=picks2, baseline=(None, 0), preload=True)

    test_cov2 = deepcopy(test_cov)
    ica = ICA(noise_cov=test_cov2, n_components=3, max_pca_components=4, n_pca_components=4)
    assert_true(ica.info is None)
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks[:5])
    assert_true(isinstance(ica.info, Info))
    assert_true(ica.n_components_ < 5)

    ica = ICA(n_components=3, max_pca_components=4, n_pca_components=4)
    assert_raises(RuntimeError, ica.save, "")
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks=None, start=start, stop=stop2)

    # test warnings on bad filenames
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        ica_badname = op.join(op.dirname(tempdir), "test-bad-name.fif.gz")
        ica.save(ica_badname)
        read_ica(ica_badname)
    assert_true(len(w) == 2)

    # test decim
    ica = ICA(n_components=3, max_pca_components=4, n_pca_components=4)
    raw_ = raw.copy()
    for _ in range(3):
        raw_.append(raw_)
    n_samples = raw_._data.shape[1]
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks=None, decim=3)
    assert_true(raw_._data.shape[1], n_samples)

    # test expl var
    ica = ICA(n_components=1.0, max_pca_components=4, n_pca_components=4)
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks=None, decim=3)
    assert_true(ica.n_components_ == 4)

    # epochs extraction from raw fit
    assert_raises(RuntimeError, ica.get_sources, epochs)
    # test reading and writing
    test_ica_fname = op.join(op.dirname(tempdir), "test-ica.fif")
    for cov in (None, test_cov):
        ica = ICA(noise_cov=cov, n_components=2, max_pca_components=4, n_pca_components=4)
        with warnings.catch_warnings(record=True):  # ICA does not converge
            ica.fit(raw, picks=picks, start=start, stop=stop2)
        sources = ica.get_sources(epochs).get_data()
        assert_true(ica.mixing_matrix_.shape == (2, 2))
        assert_true(ica.unmixing_matrix_.shape == (2, 2))
        assert_true(ica.pca_components_.shape == (4, len(picks)))
        assert_true(sources.shape[1] == ica.n_components_)

        for exclude in [[], [0]]:
            ica.exclude = [0]
            ica.save(test_ica_fname)
            ica_read = read_ica(test_ica_fname)
            assert_true(ica.exclude == ica_read.exclude)

            ica.exclude = []
            ica.apply(raw, exclude=[1])
            assert_true(ica.exclude == [])

            ica.exclude = [0, 1]
            ica.apply(raw, exclude=[1])
            assert_true(ica.exclude == [0, 1])

            ica_raw = ica.get_sources(raw)
            assert_true(ica.exclude == [ica_raw.ch_names.index(e) for e in ica_raw.info["bads"]])

        # test filtering
        d1 = ica_raw._data[0].copy()
        with warnings.catch_warnings(record=True):  # dB warning
            ica_raw.filter(4, 20)
        assert_true((d1 != ica_raw._data[0]).any())
        d1 = ica_raw._data[0].copy()
        with warnings.catch_warnings(record=True):  # dB warning
            ica_raw.notch_filter([10])
        assert_true((d1 != ica_raw._data[0]).any())

        ica.n_pca_components = 2
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        assert_true(ica.n_pca_components == ica_read.n_pca_components)

        # check type consistency
        attrs = "mixing_matrix_ unmixing_matrix_ pca_components_ " "pca_explained_variance_ _pre_whitener"
        f = lambda x, y: getattr(x, y).dtype
        for attr in attrs.split():
            assert_equal(f(ica_read, attr), f(ica, attr))

        ica.n_pca_components = 4
        ica_read.n_pca_components = 4

        ica.exclude = []
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        for attr in [
            "mixing_matrix_",
            "unmixing_matrix_",
            "pca_components_",
            "pca_mean_",
            "pca_explained_variance_",
            "_pre_whitener",
        ]:
            assert_array_almost_equal(getattr(ica, attr), getattr(ica_read, attr))

        assert_true(ica.ch_names == ica_read.ch_names)
        assert_true(isinstance(ica_read.info, Info))

        sources = ica.get_sources(raw)[:, :][0]
        sources2 = ica_read.get_sources(raw)[:, :][0]
        assert_array_almost_equal(sources, sources2)

        _raw1 = ica.apply(raw, exclude=[1])
        _raw2 = ica_read.apply(raw, exclude=[1])
        assert_array_almost_equal(_raw1[:, :][0], _raw2[:, :][0])

    os.remove(test_ica_fname)
    # check scrore funcs
    for name, func in score_funcs.items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(raw, target="EOG 061", score_func=func, start=0, stop=10)
        assert_true(ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(raw, score_func=stats.skew)
    # check exception handling
    assert_raises(ValueError, ica.score_sources, raw, target=np.arange(1))

    params = []
    params += [(None, -1, slice(2), [0, 1])]  # varicance, kurtosis idx params
    params += [(None, "MEG 1531")]  # ECG / EOG channel params
    for idx, ch_name in product(*params):
        ica.detect_artifacts(
            raw,
            start_find=0,
            stop_find=50,
            ecg_ch=ch_name,
            eog_ch=ch_name,
            skew_criterion=idx,
            var_criterion=idx,
            kurt_criterion=idx,
        )

    idx, scores = ica.find_bads_ecg(raw, method="ctps")
    assert_equal(len(scores), ica.n_components_)
    idx, scores = ica.find_bads_ecg(raw, method="correlation")
    assert_equal(len(scores), ica.n_components_)
    idx, scores = ica.find_bads_ecg(epochs, method="ctps")
    assert_equal(len(scores), ica.n_components_)
    assert_raises(ValueError, ica.find_bads_ecg, epochs.average(), method="ctps")
    assert_raises(ValueError, ica.find_bads_ecg, raw, method="crazy-coupling")

    idx, scores = ica.find_bads_eog(raw)
    assert_equal(len(scores), ica.n_components_)
    raw.info["chs"][raw.ch_names.index("EOG 061") - 1]["kind"] = 202
    idx, scores = ica.find_bads_eog(raw)
    assert_true(isinstance(scores, list))
    assert_equal(len(scores[0]), ica.n_components_)

    # check score funcs
    for name, func in score_funcs.items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(epochs_eog, target="EOG 061", score_func=func)
        assert_true(ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(epochs, score_func=stats.skew)

    # check exception handling
    assert_raises(ValueError, ica.score_sources, epochs, target=np.arange(1))

    # ecg functionality
    ecg_scores = ica.score_sources(raw, target="MEG 1531", score_func="pearsonr")

    with warnings.catch_warnings(record=True):  # filter attenuation warning
        ecg_events = ica_find_ecg_events(raw, sources[np.abs(ecg_scores).argmax()])

    assert_true(ecg_events.ndim == 2)

    # eog functionality
    eog_scores = ica.score_sources(raw, target="EOG 061", score_func="pearsonr")
    with warnings.catch_warnings(record=True):  # filter attenuation warning
        eog_events = ica_find_eog_events(raw, sources[np.abs(eog_scores).argmax()])

    assert_true(eog_events.ndim == 2)

    # Test ica fiff export
    ica_raw = ica.get_sources(raw, start=0, stop=100)
    assert_true(ica_raw.last_samp - ica_raw.first_samp == 100)
    assert_true(len(ica_raw._filenames) == 0)  # API consistency
    ica_chans = [ch for ch in ica_raw.ch_names if "ICA" in ch]
    assert_true(ica.n_components_ == len(ica_chans))
    test_ica_fname = op.join(op.abspath(op.curdir), "test-ica_raw.fif")
    ica.n_components = np.int32(ica.n_components)
    ica_raw.save(test_ica_fname, overwrite=True)
    ica_raw2 = io.Raw(test_ica_fname, preload=True)
    assert_allclose(ica_raw._data, ica_raw2._data, rtol=1e-5, atol=1e-4)
    ica_raw2.close()
    os.remove(test_ica_fname)

    # Test ica epochs export
    ica_epochs = ica.get_sources(epochs)
    assert_true(ica_epochs.events.shape == epochs.events.shape)
    ica_chans = [ch for ch in ica_epochs.ch_names if "ICA" in ch]
    assert_true(ica.n_components_ == len(ica_chans))
    assert_true(ica.n_components_ == ica_epochs.get_data().shape[1])
    assert_true(ica_epochs.raw is None)
    assert_true(ica_epochs.preload is True)

    # test float n pca components
    ica.pca_explained_variance_ = np.array([0.2] * 5)
    ica.n_components_ = 0
    for ncomps, expected in [[0.3, 1], [0.9, 4], [1, 1]]:
        ncomps_ = _check_n_pca_components(ica, ncomps)
        assert_true(ncomps_ == expected)
# to definitely register this component as a bad one to be removed
# there is the ``ica.exclude`` attribute, a simple Python list
ica.exclude.extend(eog_inds)

# from now on the ICA will reject this component even if no exclude
# parameter is passed, and this information will be stored to disk
# on saving

# uncomment this for reading and writing
# ica.save('my-ica.fif')
# ica = read_ica('my-ica.fif')

###############################################################################
# Exercise: find and remove ECG artifacts using ICA!
ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5)
ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
ica.plot_properties(ecg_epochs, picks=ecg_inds, psd_args={'fmax': 35.})


###############################################################################
# What if we don't have an EOG channel?
# -------------------------------------
#
# We could either:
#
# 1. make a bipolar reference from frontal EEG sensors and use as virtual EOG
#    channel. This can be tricky though as you can only hope that the frontal
#    EEG channels only reflect EOG and not brain dynamics in the prefrontal
#    cortex.
# 2. go for a semi-automated approach, using template matching.
#
예제 #32
0
    def raw_preprocessing(self, raw, use_ica=True, use_ssp=True):

        # Filter

        raw.info['bads'] = self.bad_channels

        # Remove power-line noise
        raw.notch_filter(np.arange(60, 241, 60),
                         picks=self.picks,
                         filter_length='auto',
                         phase=self.phase)
        raw.filter(l_freq=self.l_freq,
                   h_freq=self.h_freq,
                   phase=self.phase,
                   fir_window=self.fir_window,
                   fir_design=self.fir_design)

        # Add EEG reference
        raw.set_eeg_reference(projection=True)

        # TODO: some mechanism to control this
        if use_ica:
            # supported ica_channels = ['mag', 'grad', 'eeg', 'seeg', 'ecog', 'hbo', 'hbr', 'eog']
            ica_picks = mne.pick_types(raw.info,
                                       meg=True,
                                       eeg=False,
                                       eog=False,
                                       stim=False,
                                       exclude='bads')
            n_components = 25
            decim = 3

            # maximum number of components to reject
            n_max_ecg, n_max_eog = 3, 1  # here we don't expect horizontal EOG components

            # ica = run_ica(raw, n_components=0.95)

            ica = ICA(n_components=n_components,
                      method='fastica',
                      noise_cov=None)
            ica.fit(raw, decim=decim, picks=ica_picks, reject=self.reject)

            # generate ECG epochs use detection via phase statistics

            ecg_epochs = create_ecg_epochs(raw, reject=self.reject)

            ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')

            ecg_inds = ecg_inds[:n_max_ecg]
            ica.exclude += ecg_inds

            # detect EOG by correlation

            eog_inds, scores = ica.find_bads_eog(raw)

            eog_inds = eog_inds[:n_max_eog]
            ica.exclude += eog_inds

            ica.apply(raw)

        if use_ssp:
            if self.ecg:
                ecg_projs, _ = compute_proj_ecg(raw)
                raw.info['projs'] += ecg_projs
            if self.blink:
                eog_projs, _ = compute_proj_eog(raw)
                raw.info['projs'] += eog_projs

        raw.apply_proj()
        return raw
예제 #33
0
def find_ecg_eog_components(raw,
                            apply_lohipass=True,
                            plot=True,
                            save_epochs=True,
                            save_fn=None,
                            ask_user=True):
    """
    Try filtering the raw data file with ICA: identify components suspicious as ECG/EoG components.
    
    :type raw: mne.io.fiff.raw.Raw
    :param apply_lohipass: Whether to apply a low-pass & hi-pass filter
    :param plot: Whether to plot figures
    :param save_epochs: Whether to store epochs in the returned value (set to False in order to save space)
    :param save_fn: Save the returned dict in the specified file

    :return: dict
    """

    #-- 1Hz high pass is often helpful for fitting ICA
    print('======== Loading data =========')
    raw.load_data()

    if apply_lohipass:
        print('\n======== Filtering data =========')
        raw.filter(1, 40, n_jobs=multiprocessing.cpu_count())

    picks_meg = mne.pick_types(raw.info,
                               meg=True,
                               eeg=False,
                               eog=False,
                               stim=False,
                               exclude='bads')

    #-- Create ICA and fit it to the data
    reject = dict(mag=5e-12, grad=4000e-13)
    print('\n======== ICA: identifying components =========')
    ica = ICA(n_components=25, method='fastica', random_state=23)
    ica.fit(raw, picks=picks_meg, decim=3, reject=reject)

    #----------- Filter EoG data  ---------------

    print('\n======== Detecting EoG components =========')

    eog_epochs = create_eog_epochs(raw, reject=reject)  # get single EOG trials
    eog_average = create_eog_epochs(raw, reject=reject,
                                    picks=picks_meg).average()

    #-- Find components that correlate with the EoG data
    eog_inds, eog_scores = ica.find_bads_eog(
        eog_epochs)  # find via correlation

    if len(eog_inds) > 0:
        eog_inds_desc = ",".join([str(i) for i in eog_inds])
        print('>>> EoG components: [%s]' % eog_inds_desc)

    else:
        print(">>> No EoG components were found.")

    #----------- Filter ECG data  ---------------

    print('\n======== Detecting ECG components =========')

    ecg_average = create_ecg_epochs(raw, reject=reject,
                                    picks=picks_meg).average()
    ecg_epochs = create_ecg_epochs(raw, reject=reject)

    #-- Find components that correlate with the ECG data
    ecg_inds, ecg_scores = ica.find_bads_ecg(ecg_epochs)

    if len(ecg_inds) > 0:
        ecg_inds_desc = ",".join([str(i) for i in ecg_inds])
        print('>>> ECG components: [%s]' % ecg_inds_desc)

    else:
        print(">>> No ECG components were found.")

    res = dict(ica=ica,
               ecg_inds=ecg_inds,
               eog_inds=eog_inds,
               ecg_epochs=ecg_epochs,
               eog_epochs=eog_epochs,
               ecg_scores=ecg_scores,
               eog_scores=eog_scores,
               ecg_average=ecg_average,
               eog_average=eog_average,
               bad_components=list(set(eog_inds + ecg_inds)),
               reject=reject)

    if plot:
        plot_ecg_eog_components(res)
        plt.show()
        plt.pause(1)

    if ask_user:
        print('---------------------------------------- \n')
        print('Do you want to update the ECG components ?')
        print('---------------------------------------- \n')

        ecg_comp = input()
        if ecg_comp == 'no':
            print('>>> ECG components: [%s]' % ecg_inds)
        else:
            ecg_inds = ecg_comp

        print('---------------------------------------- \n')
        print('Do you want to update the EOG components ?')
        print('---------------------------------------- \n')

        eog_comp = input()
        if eog_comp == 'no':
            print('>>> ECG components: [%s]' % ecg_inds)
        else:
            eog_inds = eog_comp

    ica.exclude.extend(eog_inds)
    ica.exclude.extend(ecg_inds)

    res = dict(ica=ica,
               ecg_inds=ecg_inds,
               eog_inds=eog_inds,
               ecg_epochs=ecg_epochs,
               eog_epochs=eog_epochs,
               ecg_scores=ecg_scores,
               eog_scores=eog_scores,
               ecg_average=ecg_average,
               eog_average=eog_average,
               bad_components=list(set(eog_inds + ecg_inds)),
               reject=reject)

    if not save_epochs:
        del res['ecg_epochs']
        del res['eog_epochs']

    if save_fn is not None:
        print('Saving results in %s' % save_fn)
        with open(save_fn, 'wb') as fp:
            pickle.dump(res, fp)
            ica.save(save_fn[:-4] + '-ica.fif')
        print('Saved.')

    return res
예제 #34
0
# bipolar reference from frontal EEG sensors and use that as virtual EOG
# channel. This carries a risk however: you must hope that the frontal EEG
# channels only reflect EOG and not brain dynamics in the prefrontal cortex (or
# you must not care about those prefrontal signals).
#
# For ECG, it is easier: :meth:`~mne.preprocessing.ICA.find_bads_ecg` can use
# cross-channel averaging of magnetometer or gradiometer channels to construct
# a virtual ECG channel, so if you have MEG channels it is usually not
# necessary to pass a specific channel name.
# :meth:`~mne.preprocessing.ICA.find_bads_ecg` also has two options for its
# ``method`` parameter: ``'ctps'`` (cross-trial phase statistics [3]_) and
# ``'correlation'`` (Pearson correlation between data and ECG channel).

ica.exclude = []
# find which ICs match the ECG pattern
ecg_indices, ecg_scores = ica.find_bads_ecg(raw, method='correlation',
                                            threshold='auto')
ica.exclude = ecg_indices

# barplot of ICA component "ECG match" scores
ica.plot_scores(ecg_scores)

# plot diagnostics
ica.plot_properties(raw, picks=ecg_indices)

# plot ICs applied to raw data, with ECG matches highlighted
ica.plot_sources(raw, show_scrollbars=False)

# plot ICs applied to the averaged ECG epochs, with ECG matches highlighted
ica.plot_sources(ecg_evoked)

###############################################################################
def compute_ica(raw, subject, n_components=0.99, picks=None, decim=None,
                reject=None, ecg_tmin=-0.5, ecg_tmax=0.5, eog_tmin=-0.5,
                eog_tmax=0.5, n_max_ecg=3, n_max_eog=1,
                n_max_ecg_epochs=200, show=True, img_scale=1.0,
                random_state=None, report=None, artifact_stats=None):
    """Run ICA in raw data

    Parameters
    ----------,
    raw : instance of Raw
        Raw measurements to be decomposed.
    subject : str
        The name of the subject.
    picks : array-like of int, shape(n_channels, ) | None
        Channels to be included. This selection remains throughout the
        initialized ICA solution. If None only good data channels are used.
        Defaults to None.
    n_components : int | float | None | 'rank'
        The number of components used for ICA decomposition. If int, it must be
        smaller then max_pca_components. If None, all PCA components will be
        used. If float between 0 and 1 components can will be selected by the
        cumulative percentage of explained variance.
        If 'rank', the number of components equals the rank estimate.
        Defaults to 0.99.
    decim : int | None
        Increment for selecting each nth time slice. If None, all samples
        within ``start`` and ``stop`` are used. Defalts to None.
    reject : dict | None
        Rejection parameters based on peak to peak amplitude.
        Valid keys are 'grad' | 'mag' | 'eeg' | 'eog' | 'ecg'.
        If reject is None then no rejection is done. You should
        use such parameters to reject big measurement artifacts
        and not EOG for example. It only applies if `inst` is of type Raw.
        Defaults to {'mag': 5e-12}
    ecg_tmin : float
        Start time before ECG event. Defaults to -0.5.
    ecg_tmax : float
        End time after ECG event. Defaults to 0.5.
    eog_tmin : float
        Start time before rog event. Defaults to -0.5.
    eog_tmax : float
        End time after rog event. Defaults to 0.5.
    n_max_ecg : int | None
        The maximum number of ECG components to exclude. Defaults to 3.
    n_max_eog : int | None
        The maximum number of EOG components to exclude. Defaults to 1.
    n_max_ecg_epochs : int
        The maximum number of ECG epochs to use for phase-consistency
        estimation. Defaults to 200.
    show : bool
        Show figure if True
    scale_img : float
        The scaling factor for the report. Defaults to 1.0.
    random_state : None | int | instance of np.random.RandomState
        np.random.RandomState to initialize the FastICA estimation.
        As the estimation is non-deterministic it can be useful to
        fix the seed to have reproducible results. Defaults to None.
    report : instance of Report | None
        The report object. If None, a new report will be generated.
    artifact_stats : None | dict
        A dict that contains info on amplitude ranges of artifacts and
        numbers of events, etc. by channel type.

    Returns
    -------
    ica : instance of ICA
        The ICA solution.
    report : dict
        A dict with an html report ('html') and artifact statistics ('stats').
    """
    if report is None:
        report = Report(subject=subject, title='ICA preprocessing')
    if n_components == 'rank':
        n_components = raw.estimate_rank(picks=picks)
    ica = ICA(n_components=n_components, max_pca_components=None,
              random_state=random_state, max_iter=256)
    ica.fit(raw, picks=picks, decim=decim, reject=reject)

    comment = []
    for ch in ('mag', 'grad', 'eeg'):
        if ch in ica:
            comment += [ch.upper()]
    if len(comment) > 0:
        comment = '+'.join(comment) + ' '
    else:
        comment = ''

    topo_ch_type = 'mag'
    if 'GRAD' in comment and 'MAG' not in comment:
        topo_ch_type = 'grad'
    elif 'EEG' in comment:
        topo_ch_type = 'eeg'

    ###########################################################################
    # 2) identify bad components by analyzing latent sources.

    title = '%s related to %s artifacts (red) ({})'.format(subject)

    # generate ECG epochs use detection via phase statistics
    reject_ = {'mag': 5e-12, 'grad': 5000e-13, 'eeg': 300e-6}
    if reject is not None:
        reject_.update(reject)
    for ch_type in ['mag', 'grad', 'eeg']:
        if ch_type not in ica:
            reject_.pop(ch_type)

    picks_ = np.array([raw.ch_names.index(k) for k in ica.ch_names])
    if 'eeg' in ica:
        if 'ecg' in raw:
            picks_ = np.append(picks_,
                               pick_types(raw.info, meg=False, ecg=True)[0])
        else:
            logger.info('There is no ECG channel, trying to guess ECG from '
                        'magnetormeters')

    if artifact_stats is None:
        artifact_stats = dict()

    ecg_epochs = create_ecg_epochs(raw, tmin=ecg_tmin, tmax=ecg_tmax,
                                   keep_ecg=True, picks=picks_, reject=reject_)

    n_ecg_epochs_found = len(ecg_epochs.events)
    artifact_stats['ecg_n_events'] = n_ecg_epochs_found
    n_max_ecg_epochs = min(n_max_ecg_epochs, n_ecg_epochs_found)
    artifact_stats['ecg_n_used'] = n_max_ecg_epochs

    sel_ecg_epochs = np.arange(n_ecg_epochs_found)
    rng = np.random.RandomState(42)
    rng.shuffle(sel_ecg_epochs)
    ecg_ave = ecg_epochs.average()

    report.add_figs_to_section(ecg_ave.plot(), 'ECG-full', 'artifacts')
    ecg_epochs = ecg_epochs[sel_ecg_epochs[:n_max_ecg_epochs]]
    ecg_ave = ecg_epochs.average()
    report.add_figs_to_section(ecg_ave.plot(), 'ECG-used', 'artifacts')

    _put_artifact_range(artifact_stats, ecg_ave, kind='ecg')

    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    if len(ecg_inds) > 0:
        ecg_evoked = ecg_epochs.average()
        del ecg_epochs

        fig = ica.plot_scores(scores, exclude=ecg_inds, labels='ecg',
                              title='', show=show)

        report.add_figs_to_section(fig, 'scores ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        current_exclude = [e for e in ica.exclude]  # issue #2608 MNE
        fig = ica.plot_sources(raw, ecg_inds, exclude=ecg_inds,
                               title=title % ('components', 'ecg'), show=show)

        report.add_figs_to_section(fig, 'sources ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)
        ica.exclude = current_exclude

        fig = ica.plot_components(ecg_inds, ch_type=topo_ch_type,
                                  title='', colorbar=True, show=show)
        report.add_figs_to_section(fig, title % ('sources', 'ecg'),
                                   section=comment + 'ECG', scale=img_scale)
        ica.exclude = current_exclude

        ecg_inds = ecg_inds[:n_max_ecg]
        ica.exclude += ecg_inds
        fig = ica.plot_sources(ecg_evoked, exclude=ecg_inds, show=show)
        report.add_figs_to_section(fig, 'evoked sources ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        fig = ica.plot_overlay(ecg_evoked, exclude=ecg_inds, show=show)
        report.add_figs_to_section(fig,
                                   'rejection overlay ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

    # detect EOG by correlation
    picks_eog = np.concatenate(
        [picks_, pick_types(raw.info, meg=False, eeg=False, ecg=False,
                            eog=True)])

    eog_epochs = create_eog_epochs(raw, tmin=eog_tmin, tmax=eog_tmax,
                                   picks=picks_eog, reject=reject_)
    artifact_stats['eog_n_events'] = len(eog_epochs.events)
    artifact_stats['eog_n_used'] = artifact_stats['eog_n_events']
    eog_ave = eog_epochs.average()
    report.add_figs_to_section(eog_ave.plot(), 'EOG-used', 'artifacts')
    _put_artifact_range(artifact_stats, eog_ave, kind='eog')

    eog_inds = None
    if len(eog_epochs.events) > 0:
        eog_inds, scores = ica.find_bads_eog(eog_epochs)

    if eog_inds is not None and len(eog_epochs.events) > 0:
        fig = ica.plot_scores(scores, exclude=eog_inds, labels='eog',
                              show=show, title='')
        report.add_figs_to_section(fig, 'scores ({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)

        current_exclude = [e for e in ica.exclude]  # issue #2608 MNE
        fig = ica.plot_sources(raw, eog_inds, exclude=ecg_inds,
                               title=title % ('sources', 'eog'), show=show)
        report.add_figs_to_section(fig, 'sources', section=comment + 'EOG',
                                   scale=img_scale)
        ica.exclude = current_exclude

        fig = ica.plot_components(eog_inds, ch_type=topo_ch_type,
                                  title='', colorbar=True, show=show)
        report.add_figs_to_section(fig, title % ('components', 'eog'),
                                   section=comment + 'EOG', scale=img_scale)
        ica.exclude = current_exclude

        eog_inds = eog_inds[:n_max_eog]
        ica.exclude += eog_inds

        eog_evoked = eog_epochs.average()
        fig = ica.plot_sources(eog_evoked, exclude=eog_inds, show=show)
        report.add_figs_to_section(
            fig, 'evoked sources ({})'.format(subject),
            section=comment + 'EOG', scale=img_scale)

        fig = ica.plot_overlay(eog_evoked, exclude=eog_inds, show=show)
        report.add_figs_to_section(
            fig, 'rejection overlay({})'.format(subject),
            section=comment + 'EOG', scale=img_scale)
    else:
        del eog_epochs

    # check the amplitudes do not change
    if len(ica.exclude) > 0:
        fig = ica.plot_overlay(raw, show=show)  # EOG artifacts remain
        html = _render_components_table(ica)
        report.add_htmls_to_section(
            html, captions='excluded components',
            section='ICA rejection summary (%s)' % ch_type)
        report.add_figs_to_section(
            fig, 'rejection overlay({})'.format(subject),
            section=comment + 'RAW', scale=img_scale)
    return ica, dict(html=report, stats=artifact_stats)
title = 'Sources related to %s artifacts (red)'

# generate ECG epochs use detection via phase statistics

picks = mne.pick_types(raw.info, meg=True, eeg=False, eog=True, ecg=True,
                       stim=False, exclude='bads')

# create_ecg_epochs is strange: it strips the channels of anything non M/EEG
# UNLESS picks=None
picks=None
ecg_epochs = create_ecg_epochs(raw, ch_name='ECG002', tmin=-.5, tmax=.5, picks=picks, verbose=True)

# This will work with the above, but uses MASSIVE RAM
# Not sure the ECG quality is good enough for the QRS-detector
ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps', ch_name='ECG002')
# This creates a synthetic ECG from magnetometers, probably better...
ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps', ch_name='ECG002')

fig = ica.plot_scores(scores, exclude=ecg_inds, title=title % 'ecg')
fig.savefig(img_folder + '/ica_ecg_scores.png')

show_picks = np.abs(scores).argsort()[::-1][:5]

fig = ica.plot_sources(raw, show_picks, exclude=ecg_inds, title=title % 'ecg')
fig.savefig(img_folder + '/ica_ecg_sources.png')
fig = ica.plot_components(ecg_inds, title=title % 'ecg', colorbar=True)
fig.set_size_inches(12.,8.)
fig.savefig(img_folder + '/ica_ecg_components.png')

ecg_inds = ecg_inds[:n_max_ecg]
    reject = dict(grad=200e-12, mag=4e-12)

    # Run the ICA decomposition on raw data
    ica_fruit.fit(raw_fruit, picks=picks_fruit, decim=decim, reject=reject)
    ica_odour.fit(raw_odour, picks=picks_odour, decim=decim, reject=reject)
    ica_milk.fit(raw_milk, picks=picks_milk, decim=decim, reject=reject)
    ica_LD.fit(raw_LD, picks=picks_LD, decim=decim, reject=reject)

    # Conveniently generates epochs around EOG artifact events
    ecg_epochs_fruit = create_ecg_epochs(raw_fruit, reject=reject)
    ecg_epochs_odour = create_ecg_epochs(raw_odour, reject=reject)
    ecg_epochs_milk = create_ecg_epochs(raw_milk, reject=reject)
    ecg_epochs_LD = create_ecg_epochs(raw_LD, reject=reject)

    # Detecting EOG related components using correlation
    ecg_inds_fruit, scores_fruit = ica_fruit.find_bads_ecg(ecg_epochs_fruit)
    ecg_inds_odour, scores_odour = ica_odour.find_bads_ecg(ecg_epochs_odour)
    ecg_inds_milk, scores_milk = ica_milk.find_bads_ecg(ecg_epochs_milk)
    ecg_inds_LD, scores_LD = ica_LD.find_bads_ecg(ecg_epochs_LD)

    ecg_inds_fruit = ecg_inds_fruit[:n_max_ecg]
    ecg_inds_odour = ecg_inds_odour[:n_max_ecg]
    ecg_inds_milk = ecg_inds_milk[:n_max_ecg]
    ecg_inds_LD = ecg_inds_LD[:n_max_ecg]

    # Excluding the list of sources indices obtained in the previous line
    ica_fruit.exclude += ecg_inds_fruit
    ica_odour.exclude += ecg_inds_odour
    ica_milk.exclude += ecg_inds_milk
    ica_LD.exclude += ecg_inds_LD
예제 #38
0
                    (subject, condition))

        fig = ica.plot_components(eog_inds,
                                  title=title % ('eog', subject),
                                  colorbar=True)
        fig.savefig(ica_folder + "plots/%s_%s_eog_component.png" %
                    (subject, condition))
        fig = ica.plot_overlay(epochs.average(), exclude=eog_inds, show=False)
        fig.savefig(ica_folder + "plots/%s_%s_eog_excluded.png" %
                    (subject, condition))
        fig = ica.plot_properties(epochs, picks=eog_inds)
        fig[0].savefig(ica_folder + "plots/%s_%s_plot_properties.png" %
                       (subject, condition))

    # ECG
    ecg_inds, scores = ica.find_bads_ecg(epochs)
    ica.exclude += ecg_inds

    if ecg_inds:
        fig = ica.plot_components(ecg_inds,
                                  title=title % ('ecg', subject),
                                  colorbar=True)
        fig.savefig(ica_folder + "plots/%s_%s_ecg_component.png" %
                    (subject, condition))
        fig = ica.plot_overlay(epochs.average(), exclude=ecg_inds, show=False)
        fig.savefig(ica_folder + "plots/%s_%s_ecg_excluded.png" %
                    (subject, condition))
        fig = ica.plot_properties(epochs, picks=ecg_inds)
        fig[0].savefig(ica_folder + "plots/%s_%s_plot_properties.png" %
                       (subject, condition))
예제 #39
0
# peak-to-peak amplitude rejection parameters
reject = dict(grad=4000e-13, mag=4e-12)
# longer + more epochs for more artifact exposure
events = mne.find_events(raw, stim_channel='STI 014')
epochs = mne.Epochs(raw,
                    events,
                    event_id=None,
                    tmin=-0.2,
                    tmax=0.5,
                    reject=reject)

###############################################################################
# Fit ICA model using the FastICA algorithm, detect and plot components
# explaining ECG artifacts.

ica = ICA(n_components=0.95, method='fastica').fit(epochs)

ecg_epochs = create_ecg_epochs(raw, tmin=-.5, tmax=.5)
ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, threshold='auto')

ica.plot_components(ecg_inds)

###############################################################################
# Plot properties of ECG components:
ica.plot_properties(epochs, picks=ecg_inds)

###############################################################################
# Plot the estimated source of detected ECG related components
ica.plot_sources(raw, picks=ecg_inds)
예제 #40
0
def test_ica_additional():
    """Test additional ICA functionality"""
    tempdir = _TempDir()
    stop2 = 500
    raw = Raw(raw_fname).crop(1.5, stop, False)
    raw.load_data()
    picks = pick_types(raw.info, meg=True, stim=False, ecg=False,
                       eog=False, exclude='bads')
    test_cov = read_cov(test_cov_name)
    events = read_events(event_name)
    picks = pick_types(raw.info, meg=True, stim=False, ecg=False,
                       eog=False, exclude='bads')
    epochs = Epochs(raw, events[:4], event_id, tmin, tmax, picks=picks,
                    baseline=(None, 0), preload=True)
    # test if n_components=None works
    with warnings.catch_warnings(record=True):
        ica = ICA(n_components=None,
                  max_pca_components=None,
                  n_pca_components=None, random_state=0)
        ica.fit(epochs, picks=picks, decim=3)
    # for testing eog functionality
    picks2 = pick_types(raw.info, meg=True, stim=False, ecg=False,
                        eog=True, exclude='bads')
    epochs_eog = Epochs(raw, events[:4], event_id, tmin, tmax, picks=picks2,
                        baseline=(None, 0), preload=True)

    test_cov2 = test_cov.copy()
    ica = ICA(noise_cov=test_cov2, n_components=3, max_pca_components=4,
              n_pca_components=4)
    assert_true(ica.info is None)
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks[:5])
    assert_true(isinstance(ica.info, Info))
    assert_true(ica.n_components_ < 5)

    ica = ICA(n_components=3, max_pca_components=4,
              n_pca_components=4)
    assert_raises(RuntimeError, ica.save, '')
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks=[1, 2, 3, 4, 5], start=start, stop=stop2)

    # test corrmap
    ica2 = ica.copy()
    corrmap([ica, ica2], (0, 0), threshold='auto', label='blinks', plot=True,
            ch_type="mag")
    corrmap([ica, ica2], (0, 0), threshold=2, plot=False, show=False)
    assert_true(ica.labels_["blinks"] == ica2.labels_["blinks"])
    assert_true(0 in ica.labels_["blinks"])
    plt.close('all')

    # test warnings on bad filenames
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter('always')
        ica_badname = op.join(op.dirname(tempdir), 'test-bad-name.fif.gz')
        ica.save(ica_badname)
        read_ica(ica_badname)
    assert_naming(w, 'test_ica.py', 2)

    # test decim
    ica = ICA(n_components=3, max_pca_components=4,
              n_pca_components=4)
    raw_ = raw.copy()
    for _ in range(3):
        raw_.append(raw_)
    n_samples = raw_._data.shape[1]
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks=None, decim=3)
    assert_true(raw_._data.shape[1], n_samples)

    # test expl var
    ica = ICA(n_components=1.0, max_pca_components=4,
              n_pca_components=4)
    with warnings.catch_warnings(record=True):
        ica.fit(raw, picks=None, decim=3)
    assert_true(ica.n_components_ == 4)

    # epochs extraction from raw fit
    assert_raises(RuntimeError, ica.get_sources, epochs)
    # test reading and writing
    test_ica_fname = op.join(op.dirname(tempdir), 'test-ica.fif')
    for cov in (None, test_cov):
        ica = ICA(noise_cov=cov, n_components=2, max_pca_components=4,
                  n_pca_components=4)
        with warnings.catch_warnings(record=True):  # ICA does not converge
            ica.fit(raw, picks=picks, start=start, stop=stop2)
        sources = ica.get_sources(epochs).get_data()
        assert_true(ica.mixing_matrix_.shape == (2, 2))
        assert_true(ica.unmixing_matrix_.shape == (2, 2))
        assert_true(ica.pca_components_.shape == (4, len(picks)))
        assert_true(sources.shape[1] == ica.n_components_)

        for exclude in [[], [0]]:
            ica.exclude = [0]
            ica.labels_ = {'foo': [0]}
            ica.save(test_ica_fname)
            ica_read = read_ica(test_ica_fname)
            assert_true(ica.exclude == ica_read.exclude)
            assert_equal(ica.labels_, ica_read.labels_)
            ica.exclude = []
            ica.apply(raw, exclude=[1])
            assert_true(ica.exclude == [])

            ica.exclude = [0, 1]
            ica.apply(raw, exclude=[1])
            assert_true(ica.exclude == [0, 1])

            ica_raw = ica.get_sources(raw)
            assert_true(ica.exclude == [ica_raw.ch_names.index(e) for e in
                                        ica_raw.info['bads']])

        # test filtering
        d1 = ica_raw._data[0].copy()
        with warnings.catch_warnings(record=True):  # dB warning
            ica_raw.filter(4, 20)
        assert_true((d1 != ica_raw._data[0]).any())
        d1 = ica_raw._data[0].copy()
        with warnings.catch_warnings(record=True):  # dB warning
            ica_raw.notch_filter([10])
        assert_true((d1 != ica_raw._data[0]).any())

        ica.n_pca_components = 2
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        assert_true(ica.n_pca_components == ica_read.n_pca_components)

        # check type consistency
        attrs = ('mixing_matrix_ unmixing_matrix_ pca_components_ '
                 'pca_explained_variance_ _pre_whitener')

        def f(x, y):
            return getattr(x, y).dtype

        for attr in attrs.split():
            assert_equal(f(ica_read, attr), f(ica, attr))

        ica.n_pca_components = 4
        ica_read.n_pca_components = 4

        ica.exclude = []
        ica.save(test_ica_fname)
        ica_read = read_ica(test_ica_fname)
        for attr in ['mixing_matrix_', 'unmixing_matrix_', 'pca_components_',
                     'pca_mean_', 'pca_explained_variance_',
                     '_pre_whitener']:
            assert_array_almost_equal(getattr(ica, attr),
                                      getattr(ica_read, attr))

        assert_true(ica.ch_names == ica_read.ch_names)
        assert_true(isinstance(ica_read.info, Info))

        sources = ica.get_sources(raw)[:, :][0]
        sources2 = ica_read.get_sources(raw)[:, :][0]
        assert_array_almost_equal(sources, sources2)

        _raw1 = ica.apply(raw, exclude=[1])
        _raw2 = ica_read.apply(raw, exclude=[1])
        assert_array_almost_equal(_raw1[:, :][0], _raw2[:, :][0])

    os.remove(test_ica_fname)
    # check scrore funcs
    for name, func in get_score_funcs().items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(raw, target='EOG 061', score_func=func,
                                   start=0, stop=10)
        assert_true(ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(raw, score_func=stats.skew)
    # check exception handling
    assert_raises(ValueError, ica.score_sources, raw,
                  target=np.arange(1))

    params = []
    params += [(None, -1, slice(2), [0, 1])]  # varicance, kurtosis idx params
    params += [(None, 'MEG 1531')]  # ECG / EOG channel params
    for idx, ch_name in product(*params):
        ica.detect_artifacts(raw, start_find=0, stop_find=50, ecg_ch=ch_name,
                             eog_ch=ch_name, skew_criterion=idx,
                             var_criterion=idx, kurt_criterion=idx)
    with warnings.catch_warnings(record=True):
        idx, scores = ica.find_bads_ecg(raw, method='ctps')
        assert_equal(len(scores), ica.n_components_)
        idx, scores = ica.find_bads_ecg(raw, method='correlation')
        assert_equal(len(scores), ica.n_components_)
        idx, scores = ica.find_bads_ecg(epochs, method='ctps')
        assert_equal(len(scores), ica.n_components_)
        assert_raises(ValueError, ica.find_bads_ecg, epochs.average(),
                      method='ctps')
        assert_raises(ValueError, ica.find_bads_ecg, raw,
                      method='crazy-coupling')

        idx, scores = ica.find_bads_eog(raw)
        assert_equal(len(scores), ica.n_components_)
        raw.info['chs'][raw.ch_names.index('EOG 061') - 1]['kind'] = 202
        idx, scores = ica.find_bads_eog(raw)
        assert_true(isinstance(scores, list))
        assert_equal(len(scores[0]), ica.n_components_)

    # check score funcs
    for name, func in get_score_funcs().items():
        if name in score_funcs_unsuited:
            continue
        scores = ica.score_sources(epochs_eog, target='EOG 061',
                                   score_func=func)
        assert_true(ica.n_components_ == len(scores))

    # check univariate stats
    scores = ica.score_sources(epochs, score_func=stats.skew)

    # check exception handling
    assert_raises(ValueError, ica.score_sources, epochs,
                  target=np.arange(1))

    # ecg functionality
    ecg_scores = ica.score_sources(raw, target='MEG 1531',
                                   score_func='pearsonr')

    with warnings.catch_warnings(record=True):  # filter attenuation warning
        ecg_events = ica_find_ecg_events(raw,
                                         sources[np.abs(ecg_scores).argmax()])

    assert_true(ecg_events.ndim == 2)

    # eog functionality
    eog_scores = ica.score_sources(raw, target='EOG 061',
                                   score_func='pearsonr')
    with warnings.catch_warnings(record=True):  # filter attenuation warning
        eog_events = ica_find_eog_events(raw,
                                         sources[np.abs(eog_scores).argmax()])

    assert_true(eog_events.ndim == 2)

    # Test ica fiff export
    ica_raw = ica.get_sources(raw, start=0, stop=100)
    assert_true(ica_raw.last_samp - ica_raw.first_samp == 100)
    assert_true(len(ica_raw._filenames) == 0)  # API consistency
    ica_chans = [ch for ch in ica_raw.ch_names if 'ICA' in ch]
    assert_true(ica.n_components_ == len(ica_chans))
    test_ica_fname = op.join(op.abspath(op.curdir), 'test-ica_raw.fif')
    ica.n_components = np.int32(ica.n_components)
    ica_raw.save(test_ica_fname, overwrite=True)
    ica_raw2 = Raw(test_ica_fname, preload=True)
    assert_allclose(ica_raw._data, ica_raw2._data, rtol=1e-5, atol=1e-4)
    ica_raw2.close()
    os.remove(test_ica_fname)

    # Test ica epochs export
    ica_epochs = ica.get_sources(epochs)
    assert_true(ica_epochs.events.shape == epochs.events.shape)
    ica_chans = [ch for ch in ica_epochs.ch_names if 'ICA' in ch]
    assert_true(ica.n_components_ == len(ica_chans))
    assert_true(ica.n_components_ == ica_epochs.get_data().shape[1])
    assert_true(ica_epochs._raw is None)
    assert_true(ica_epochs.preload is True)

    # test float n pca components
    ica.pca_explained_variance_ = np.array([0.2] * 5)
    ica.n_components_ = 0
    for ncomps, expected in [[0.3, 1], [0.9, 4], [1, 1]]:
        ncomps_ = ica._check_n_pca_components(ncomps)
        assert_true(ncomps_ == expected)
예제 #41
0
def compute_ica(raw,
                subject,
                n_components=0.99,
                picks=None,
                decim=None,
                reject=None,
                ecg_tmin=-0.5,
                ecg_tmax=0.5,
                eog_tmin=-0.5,
                eog_tmax=0.5,
                n_max_ecg=3,
                n_max_eog=1,
                n_max_ecg_epochs=200,
                show=True,
                img_scale=1.0,
                random_state=None,
                report=None,
                artifact_stats=None):
    """Run ICA in raw data

    Parameters
    ----------,
    raw : instance of Raw
        Raw measurements to be decomposed.
    subject : str
        The name of the subject.
    picks : array-like of int, shape(n_channels, ) | None
        Channels to be included. This selection remains throughout the
        initialized ICA solution. If None only good data channels are used.
        Defaults to None.
    n_components : int | float | None | 'rank'
        The number of components used for ICA decomposition. If int, it must be
        smaller then max_pca_components. If None, all PCA components will be
        used. If float between 0 and 1 components can will be selected by the
        cumulative percentage of explained variance.
        If 'rank', the number of components equals the rank estimate.
        Defaults to 0.99.
    decim : int | None
        Increment for selecting each nth time slice. If None, all samples
        within ``start`` and ``stop`` are used. Defalts to None.
    reject : dict | None
        Rejection parameters based on peak to peak amplitude.
        Valid keys are 'grad' | 'mag' | 'eeg' | 'eog' | 'ecg'.
        If reject is None then no rejection is done. You should
        use such parameters to reject big measurement artifacts
        and not EOG for example. It only applies if `inst` is of type Raw.
        Defaults to {'mag': 5e-12}
    ecg_tmin : float
        Start time before ECG event. Defaults to -0.5.
    ecg_tmax : float
        End time after ECG event. Defaults to 0.5.
    eog_tmin : float
        Start time before rog event. Defaults to -0.5.
    eog_tmax : float
        End time after rog event. Defaults to 0.5.
    n_max_ecg : int | None
        The maximum number of ECG components to exclude. Defaults to 3.
    n_max_eog : int | None
        The maximum number of EOG components to exclude. Defaults to 1.
    n_max_ecg_epochs : int
        The maximum number of ECG epochs to use for phase-consistency
        estimation. Defaults to 200.
    show : bool
        Show figure if True
    scale_img : float
        The scaling factor for the report. Defaults to 1.0.
    random_state : None | int | instance of np.random.RandomState
        np.random.RandomState to initialize the FastICA estimation.
        As the estimation is non-deterministic it can be useful to
        fix the seed to have reproducible results. Defaults to None.
    report : instance of Report | None
        The report object. If None, a new report will be generated.
    artifact_stats : None | dict
        A dict that contains info on amplitude ranges of artifacts and
        numbers of events, etc. by channel type.

    Returns
    -------
    ica : instance of ICA
        The ICA solution.
    report : dict
        A dict with an html report ('html') and artifact statistics ('stats').
    """
    if report is None:
        report = Report(subject=subject, title='ICA preprocessing')
    if n_components == 'rank':
        n_components = raw.estimate_rank(picks=picks)
    ica = ICA(n_components=n_components,
              max_pca_components=None,
              random_state=random_state,
              max_iter=256)
    ica.fit(raw, picks=picks, decim=decim, reject=reject)

    comment = []
    for ch in ('mag', 'grad', 'eeg'):
        if ch in ica:
            comment += [ch.upper()]
    if len(comment) > 0:
        comment = '+'.join(comment) + ' '
    else:
        comment = ''

    topo_ch_type = 'mag'
    if 'GRAD' in comment and 'MAG' not in comment:
        topo_ch_type = 'grad'
    elif 'EEG' in comment:
        topo_ch_type = 'eeg'

    ###########################################################################
    # 2) identify bad components by analyzing latent sources.

    title = '%s related to %s artifacts (red) ({})'.format(subject)

    # generate ECG epochs use detection via phase statistics
    reject_ = {'mag': 5e-12, 'grad': 5000e-13, 'eeg': 300e-6}
    if reject is not None:
        reject_.update(reject)
    for ch_type in ['mag', 'grad', 'eeg']:
        if ch_type not in ica:
            reject_.pop(ch_type)

    picks_ = np.array([raw.ch_names.index(k) for k in ica.ch_names])
    if 'eeg' in ica:
        if 'ecg' in raw:
            picks_ = np.append(picks_,
                               pick_types(raw.info, meg=False, ecg=True)[0])
        else:
            logger.info('There is no ECG channel, trying to guess ECG from '
                        'magnetormeters')

    if artifact_stats is None:
        artifact_stats = dict()

    ecg_epochs = create_ecg_epochs(raw,
                                   tmin=ecg_tmin,
                                   tmax=ecg_tmax,
                                   keep_ecg=True,
                                   picks=picks_,
                                   reject=reject_)

    n_ecg_epochs_found = len(ecg_epochs.events)
    artifact_stats['ecg_n_events'] = n_ecg_epochs_found
    n_max_ecg_epochs = min(n_max_ecg_epochs, n_ecg_epochs_found)
    artifact_stats['ecg_n_used'] = n_max_ecg_epochs

    sel_ecg_epochs = np.arange(n_ecg_epochs_found)
    rng = np.random.RandomState(42)
    rng.shuffle(sel_ecg_epochs)
    ecg_ave = ecg_epochs.average()

    report.add_figs_to_section(ecg_ave.plot(), 'ECG-full', 'artifacts')
    ecg_epochs = ecg_epochs[sel_ecg_epochs[:n_max_ecg_epochs]]
    ecg_ave = ecg_epochs.average()
    report.add_figs_to_section(ecg_ave.plot(), 'ECG-used', 'artifacts')

    _put_artifact_range(artifact_stats, ecg_ave, kind='ecg')

    ecg_inds, scores = ica.find_bads_ecg(ecg_epochs, method='ctps')
    if len(ecg_inds) > 0:
        ecg_evoked = ecg_epochs.average()
        del ecg_epochs

        fig = ica.plot_scores(scores,
                              exclude=ecg_inds,
                              labels='ecg',
                              title='',
                              show=show)

        report.add_figs_to_section(fig,
                                   'scores ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        current_exclude = [e for e in ica.exclude]  # issue #2608 MNE
        fig = ica.plot_sources(raw,
                               ecg_inds,
                               exclude=ecg_inds,
                               title=title % ('components', 'ecg'),
                               show=show)

        report.add_figs_to_section(fig,
                                   'sources ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)
        ica.exclude = current_exclude

        fig = ica.plot_components(ecg_inds,
                                  ch_type=topo_ch_type,
                                  title='',
                                  colorbar=True,
                                  show=show)
        report.add_figs_to_section(fig,
                                   title % ('sources', 'ecg'),
                                   section=comment + 'ECG',
                                   scale=img_scale)
        ica.exclude = current_exclude

        ecg_inds = ecg_inds[:n_max_ecg]
        ica.exclude += ecg_inds
        fig = ica.plot_sources(ecg_evoked, exclude=ecg_inds, show=show)
        report.add_figs_to_section(fig,
                                   'evoked sources ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

        fig = ica.plot_overlay(ecg_evoked, exclude=ecg_inds, show=show)
        report.add_figs_to_section(fig,
                                   'rejection overlay ({})'.format(subject),
                                   section=comment + 'ECG',
                                   scale=img_scale)

    # detect EOG by correlation
    picks_eog = np.concatenate([
        picks_,
        pick_types(raw.info, meg=False, eeg=False, ecg=False, eog=True)
    ])

    eog_epochs = create_eog_epochs(raw,
                                   tmin=eog_tmin,
                                   tmax=eog_tmax,
                                   picks=picks_eog,
                                   reject=reject_)
    artifact_stats['eog_n_events'] = len(eog_epochs.events)
    artifact_stats['eog_n_used'] = artifact_stats['eog_n_events']
    eog_ave = eog_epochs.average()
    report.add_figs_to_section(eog_ave.plot(), 'EOG-used', 'artifacts')
    _put_artifact_range(artifact_stats, eog_ave, kind='eog')

    eog_inds = None
    if len(eog_epochs.events) > 0:
        eog_inds, scores = ica.find_bads_eog(eog_epochs)

    if eog_inds is not None and len(eog_epochs.events) > 0:
        fig = ica.plot_scores(scores,
                              exclude=eog_inds,
                              labels='eog',
                              show=show,
                              title='')
        report.add_figs_to_section(fig,
                                   'scores ({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)

        current_exclude = [e for e in ica.exclude]  # issue #2608 MNE
        fig = ica.plot_sources(raw,
                               eog_inds,
                               exclude=ecg_inds,
                               title=title % ('sources', 'eog'),
                               show=show)
        report.add_figs_to_section(fig,
                                   'sources',
                                   section=comment + 'EOG',
                                   scale=img_scale)
        ica.exclude = current_exclude

        fig = ica.plot_components(eog_inds,
                                  ch_type=topo_ch_type,
                                  title='',
                                  colorbar=True,
                                  show=show)
        report.add_figs_to_section(fig,
                                   title % ('components', 'eog'),
                                   section=comment + 'EOG',
                                   scale=img_scale)
        ica.exclude = current_exclude

        eog_inds = eog_inds[:n_max_eog]
        ica.exclude += eog_inds

        eog_evoked = eog_epochs.average()
        fig = ica.plot_sources(eog_evoked, exclude=eog_inds, show=show)
        report.add_figs_to_section(fig,
                                   'evoked sources ({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)

        fig = ica.plot_overlay(eog_evoked, exclude=eog_inds, show=show)
        report.add_figs_to_section(fig,
                                   'rejection overlay({})'.format(subject),
                                   section=comment + 'EOG',
                                   scale=img_scale)
    else:
        del eog_epochs

    # check the amplitudes do not change
    if len(ica.exclude) > 0:
        fig = ica.plot_overlay(raw, show=show)  # EOG artifacts remain
        html = _render_components_table(ica)
        report.add_htmls_to_section(html,
                                    captions='excluded components',
                                    section='ICA rejection summary (%s)' %
                                    ch_type)
        report.add_figs_to_section(fig,
                                   'rejection overlay({})'.format(subject),
                                   section=comment + 'RAW',
                                   scale=img_scale)
    return ica, dict(html=report, stats=artifact_stats)