Example #1
0
def fit_ica(raw,
            picks,
            reject,
            ecg_ch,
            eog_hor,
            eog_ver,
            flow_ecg,
            fhigh_ecg,
            flow_eog,
            fhigh_eog,
            ecg_thresh,
            eog_thresh,
            use_jumeg=True,
            random_state=42):
    """
    author: C.Kiefer; [email protected]
    
    Fit an ICA object to the raw file. Identify cardiac and ocular components
    and mark them for removal.

    Parameters:
    -----------
    inst : instance of Raw, Epochs or Evoked
        Raw measurements to be decomposed.
    picks : array-like of int
        Channels to be included. This selection remains throughout the
        initialized ICA solution. If None only good data channels are used.
    reject : dict | None
        Rejection parameters based on peak-to-peak amplitude.
        Valid keys are 'grad', 'mag', 'eeg', 'seeg', 'ecog', 'eog', 'ecg',
        'hbo', 'hbr'.
        If reject is None then no rejection is done. Example::

            reject = dict(grad=4000e-13, # T / m (gradiometers)
                          mag=4e-12, # T (magnetometers)
                          eeg=40e-6, # V (EEG channels)
                          eog=250e-6 # V (EOG channels)
                          )

        It only applies if `inst` is of type Raw.
    ecg_ch : array-like | ch_name | None
        ECG channel to which the sources shall be compared. It has to be
        of the same shape as the sources. If some string is supplied, a
        routine will try to find a matching channel. If None, a score
        function expecting only one input-array argument must be used,
        for instance, scipy.stats.skew (default).
    eog_hor : array-like | ch_name | None
        Horizontal EOG channel to which the sources shall be compared.
        It has to be of the same shape as the sources. If some string
        is supplied, a routine will try to find a matching channel. If
        None, a score function expecting only one input-array argument
        must be used, for instance, scipy.stats.skew (default).
    eog_ver : array-like | ch_name | None
        Vertical EOG channel to which the sources shall be compared.
        It has to be of the same shape as the sources. If some string
        is supplied, a routine will try to find a matching channel. If
        None, a score function expecting only one input-array argument
        must be used, for instance, scipy.stats.skew (default).
    flow_ecg : float
        Low pass frequency for ECG component identification.
    fhigh_ecg : float
        High pass frequency for ECG component identification.
    flow_eog : float
        Low pass frequency for EOG component identification.
    fhigh_eog : float
        High pass frequency for EOG component identification.
    ecg_thresh : float
        Threshold for ECG component idenfication.
    eog_thresh : float
        Threshold for EOG component idenfication.
    use_jumeg : bool
        Use the JuMEG scoring method for the identification of
        artifact components.
    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.

    Returns:
    --------
    ica : mne.preprocessing.ICA
        ICA object for raw file with ECG and EOG components marked for removal.

    """
    # increased iteration to make it converge
    # fix the number of components to 40, depending on your application you
    # might want to raise the number
    # 'extended-infomax', 'fastica', 'picard'

    logger.info('Start ICA FIT: init ICA object')
    ica = ICA(method='fastica',
              n_components=40,
              random_state=random_state,
              max_pca_components=None,
              max_iter=5000,
              verbose=False)

    logger.debug('ICA FIT: apply ICA.fit\n reject: {} \n picks: {}'.format(
        reject, picks))
    ica.fit(raw, picks=picks, decim=None, reject=reject, verbose=True)
    logger.info('Done ICA FIT')
    #######################################################################
    # identify bad components
    #######################################################################

    if use_jumeg:
        logger.info("JuMEG Computing scores and identifying components ...")
        #--- get ECG related components using JuMEG
        ic_ecg, sc_ecg = get_ics_cardiac(raw,
                                         ica,
                                         flow=flow_ecg,
                                         fhigh=fhigh_ecg,
                                         thresh=ecg_thresh,
                                         tmin=-0.5,
                                         tmax=0.5,
                                         name_ecg=ecg_ch,
                                         use_CTPS=True)  #[0]
        ic_ecg = list(set(ic_ecg))
        ic_ecg.sort()

        #--- get EOG related components using JuMEG
        ic_eog = get_ics_ocular(raw,
                                ica,
                                flow=flow_eog,
                                fhigh=fhigh_eog,
                                thresh=eog_thresh,
                                name_eog_hor=eog_hor,
                                name_eog_ver=eog_ver,
                                score_func='pearsonr')
        ic_eog = list(set(ic_eog))
        ic_eog.sort()

        #--- if necessary include components identified by correlation as well
        bads_list = []
        bads_list.extend(ic_ecg)
        bads_list.extend(ic_eog)
        bads_list.sort()
        ica.exclude = bads_list
        msg = [
            "JuMEG identified ICA components",
            "  -> ECG components: {}".format(ic_ecg),
            "  ->         scores: {}".format(sc_ecg[ic_ecg]),
            "  -> EOG components: {}".format(ic_eog)
        ]
        logger.debug("\n".join(msg))
    else:
        logger.info("MNE Computing scores and identifying components ...")
        ecg_scores = ica.score_sources(raw,
                                       target=ecg_ch,
                                       score_func='pearsonr',
                                       l_freq=flow_ecg,
                                       h_freq=fhigh_ecg,
                                       verbose=False)
        # horizontal channel
        eog1_scores = ica.score_sources(raw,
                                        target=eog_hor,
                                        score_func='pearsonr',
                                        l_freq=flow_eog,
                                        h_freq=fhigh_eog,
                                        verbose=False)
        # vertical channel
        eog2_scores = ica.score_sources(raw,
                                        target=eog_ver,
                                        score_func='pearsonr',
                                        l_freq=flow_eog,
                                        h_freq=fhigh_eog,
                                        verbose=False)

        # print the top ecg, eog correlation scores
        ecg_inds = np.where(np.abs(ecg_scores) > ecg_thresh)[0]
        eog1_inds = np.where(np.abs(eog1_scores) > eog_thresh)[0]
        eog2_inds = np.where(np.abs(eog2_scores) > eog_thresh)[0]

        highly_corr = list(
            set(np.concatenate((ecg_inds, eog1_inds, eog2_inds))))
        highly_corr.sort()

        highly_corr_ecg = list(set(ecg_inds))
        highly_corr_eog1 = list(set(eog1_inds))
        highly_corr_eog2 = list(set(eog2_inds))

        highly_corr_ecg.sort()
        highly_corr_eog1.sort()
        highly_corr_eog2.sort()

        # if necessary include components identified by correlation as well
        ica.exclude = highly_corr
        msg = [
            "MNE Highly correlated artifact components",
            "  -> ECG  : {} ".format(highly_corr_ecg),
            "  -> EOG 1: {} ".format(highly_corr_eog1),
            "  -> EOG 2: {} ".format(highly_corr_eog2)
        ]

        logger.debug("\n".join(msg))

    logger.info("done ICA FIT\n  -> excluded ICs: {}\n".format(ica.exclude))
    return ica
Example #2
0
    if model_scores[idx][0] > MLICA_threshold:
        bads_MLICA.append(idx)
# visualisation
# ica.exclude = bads_MLICA
# ica.plot_sources(raw_ds_chop, block=True)

# compare MLICA to results from correlation and ctps analysis
ica.exclude = []

print 'Identifying components..'
# get ECG/EOG related components using JuMEG
ic_ecg = get_ics_cardiac(
    raw_filtered_chop,
    ica,
    flow=flow_ecg,
    fhigh=fhigh_ecg,
    thresh=ecg_thresh,
    tmin=-0.5,
    tmax=0.5,
    name_ecg=ecg_ch,
    use_CTPS=True)[0]  # returns both ICs and scores (take only ICs)
ic_eog = get_ics_ocular(raw_filtered_chop,
                        ica,
                        flow=flow_eog,
                        fhigh=fhigh_eog,
                        thresh=eog_thresh,
                        name_eog_hor=eog1_ch,
                        name_eog_ver=eog2_ch,
                        score_func='pearsonr')

bads_corr_ctps = list(ic_ecg) + list(ic_eog)
bads_corr_ctps = list(set(bads_corr_ctps))  # remove potential duplicates
Example #3
0
# -------------------------------------------------------
#ica_method = 'fastica'
ica_method = 'extended-infomax'
decim = 3
ica = ICA(method=ica_method, n_components=0.99)
ica.fit(raw, picks=picks_meg, decim=decim)
# -------------------------------------------------------
# before visual inspection of ICA components
# try the automatic version to see what we get
# -------------------------------------------------------
# search for ECG artifact components (should already be removed by OCARTA)
idx_ecg = get_ics_cardiac(raw,
                          ica,
                          flow=10,
                          fhigh=20,
                          tmin=-0.3,
                          tmax=0.3,
                          name_ecg='ECG 001',
                          use_CTPS=True,
                          thresh=0.3)
# search for EOG artifact components
idx_eog1 = get_ics_ocular(raw,
                          ica,
                          flow=1,
                          fhigh=10,
                          name_eog_hor='EOG 001',
                          score_func='pearsonr',
                          thresh=0.25)
idx_eog2 = get_ics_ocular(raw,
                          ica,
                          flow=1,
Example #4
0
                                                verbose=False)

                # print the top ecg, eog correlation scores
                ecg_inds = np.where(np.abs(ecg_scores) > ecg_thresh)[0]
                eog1_inds = np.where(np.abs(eog1_scores) > eog_thresh)[0]
                eog2_inds = np.where(np.abs(eog2_scores) > eog_thresh)[0]
                highly_corr = list(
                    set(np.concatenate((ecg_inds, eog1_inds, eog2_inds))))
                print 'Highly correlated artefact components are', highly_corr

                # get ECG/EOG related components using JUMEG
                ic_ecg = get_ics_cardiac(raw_filt_chop,
                                         ica,
                                         flow=flow_ecg,
                                         fhigh=fhigh_ecg,
                                         thresh=ecg_thresh,
                                         tmin=-0.5,
                                         tmax=0.5,
                                         name_ecg=ecg_ch,
                                         score_func='pearsonr',
                                         use_CTPS=True)
                ic_eog = get_ics_ocular(raw_filt_chop,
                                        ica,
                                        flow=flow_eog,
                                        fhigh=fhigh_eog,
                                        thresh=eog_thresh,
                                        name_eog_hor=eog1_ch,
                                        name_eog_ver=eog2_ch,
                                        score_func='pearsonr')
                print 'Identified ECG components are: ', ic_ecg
                print 'Identified EOG components are: ', ic_eog