Example #1
0
    def __init__(self, data, samplerate, pure_range=None):
        """
        """
        # process the pure range
        if pure_range is None:
            pure_range = (None, None)
        self._pure_range = pure_range

        # run pca
        sys.stdout.write("Running PCA...")
        Wpca, pca_data = pca(
            data[:, pure_range[0]:pure_range[1]])  #, ncomps, eigratio)

        # Run iwasobi
        sys.stdout.write("Running IWASOBI ICA...")
        sys.stdout.flush()
        #(W,Winit,ISR,signals) = iwasobi(data[:,pure_range[0]:pure_range[1]])
        (W, Winit, ISR, signals) = iwasobi(pca_data)

        # combine the iwasobi weights with the pca weights
        W = np.dot(W, Wpca)
        A = np.linalg.pinv(W)

        # reorder the signals by loading (reordered from high to low)
        ind = np.argsort(np.abs(A).sum(0))[::-1]
        A = A[:, ind]
        W = W[ind, :]
        signals = signals[ind, :]

        self._ICA_weights = A
        #A = np.linalg.inv(W)
        sys.stdout.write("DONE!\n")
        sys.stdout.flush()

        # expand signals to span the entire dataset if necessary
        if (not pure_range[0] is None) or (not pure_range[1] is None):
            #Xmean=data[:,pure_range[0]:pure_range[1]].mean(1)
            #signals = np.add(np.dot(W,data).T,np.dot(W,Xmean)).T
            signals = np.dot(W, data)

        self._components = signals
        self._samplerate = samplerate
        self._data = data
Example #2
0
    def __init__(self, data, samplerate, pure_range=None):
        """
        """
        # process the pure range
        if pure_range is None:
            pure_range = (None,None)
        self._pure_range = pure_range

        # run pca
        sys.stdout.write("Running PCA...")
        Wpca,pca_data = pca(data[:,pure_range[0]:pure_range[1]]) #, ncomps, eigratio)

        # Run iwasobi
        sys.stdout.write("Running IWASOBI ICA...")
        sys.stdout.flush()
        #(W,Winit,ISR,signals) = iwasobi(data[:,pure_range[0]:pure_range[1]])
        (W,Winit,ISR,signals) = iwasobi(pca_data)

        # combine the iwasobi weights with the pca weights
        W = np.dot(W,Wpca)
        A = np.linalg.pinv(W)

        # reorder the signals by loading (reordered from high to low)
        ind = np.argsort(np.abs(A).sum(0))[::-1]
        A = A[:,ind]
        W = W[ind,:]
        signals = signals[ind,:]

        self._ICA_weights = A
        #A = np.linalg.inv(W)
        sys.stdout.write("DONE!\n")
        sys.stdout.flush()

        # expand signals to span the entire dataset if necessary
        if (not pure_range[0] is None) or (not pure_range[1] is None):
            #Xmean=data[:,pure_range[0]:pure_range[1]].mean(1)
            #signals = np.add(np.dot(W,data).T,np.dot(W,Xmean)).T
            signals = np.dot(W,data)

        self._components = signals
        self._samplerate = samplerate
        self._data = data
Example #3
0
def wica_clean(data,
               samplerate=None,
               pure_range=(None, None),
               EOG_elecs=[0, 1],
               std_fact=1.5,
               Kthr=2.5,
               num_mp_procs=0):
    """
    Clean data with the Wavelet-ICA method described here:

    N.P. Castellanos, and V.A. Makarov (2006). 'Recovering EEG brain signals: Artifact 
    suppression with wavelet enhanced independent component analysis'
    J. Neurosci. Methods, 158, 300--312.

    Instead of using the Infomax ICA algorithm, we use the (much much
    faster) IWASOBI algorithm.

    We also pick components to clean by only cleaning components that
    weigh heavily on the EOG electrodes.

    This ICA algorithm works better if you pass in data that have been
    high-pass filtered to remove big non-neural fluctuations and
    drifts.

    You do not have to run the ICA step on your entire dataset.
    Instead, it is possible to provide the start and end indicies for
    a continguous chunk of data that is 'clean' except for having lots
    of eyeblink examples.  This range will also be used inside the
    wavelet-based artifact correction code to determine the best
    threshold for identifying artifacts.  You do, however, want to try
    and make sure you provide enough samples for a good ICA
    decomposition.  A good rule of thumb is 3*(N^2) where N is the
    number of channels/sources.
    """
    # run pca
    sys.stdout.write("Running PCA...")
    Wpca, pca_data = pca(
        data[:, pure_range[0]:pure_range[1]])  #, ncomps, eigratio)

    # Run iwasobi
    sys.stdout.write("Running IWASOBI ICA...")
    sys.stdout.flush()
    #(W,Winit,ISR,signals) = iwasobi(data[:,pure_range[0]:pure_range[1]])
    (W, Winit, ISR, signals) = iwasobi(pca_data)
    W = np.dot(W, Wpca)
    A = np.linalg.pinv(W)
    #A = np.linalg.inv(W)
    sys.stdout.write("DONE!\n")
    sys.stdout.flush()

    # expand signals to span the entire dataset if necessary
    if (not pure_range[0] is None) or (not pure_range[1] is None):
        #Xmean=data[:,pure_range[0]:pure_range[1]].mean(1)
        #signals = np.add(np.dot(W,data).T,np.dot(W,Xmean)).T
        signals = np.dot(W, data)

    # pick which signals to clean (ones that weigh on EOG elecs)
    # vals = np.sum(np.abs(A[EOG_elecs,:]),0)
    # std_thresh = std_fact*np.std(vals)
    # comp_ind = np.nonzero(vals>=std_thresh)[0]
    comp_ind = []
    # loop over EOG elecs
    for e in EOG_elecs:
        # get the weights of each component onto that electrode
        vals = np.abs(A[e, :])
        # calculate the threshold that the std must exceed for that
        # component to be considered
        std_thresh = std_fact * np.std(vals)
        #comp_ind.extend(np.nonzero(vals>=std_thresh)[0].tolist())
        # loop over potential components
        for s in np.nonzero(vals >= std_thresh)[0].tolist():
            # calculate the weights of all electrodes into that component
            sweights = np.abs(A[:, s])
            # get threshold based on the std across those weights
            sthresh2 = std_fact * sweights.std()
            # see if that component crosses this second threshold
            if np.abs(A[e, s]) >= sthresh2:
                # yes, so append to the list to clean
                comp_ind.append(s)
    # Instead, try and make sure the weights are above the STD thresh
    # AND bigger for EOG elecs than for an elec like Pz

    comp_ind = np.unique(comp_ind)

    sys.stdout.write("Cleaning these components: " + str(comp_ind) + '\n')
    sys.stdout.flush()

    # remove strong artifacts
    if (not pure_range[0] is None) or (not pure_range[1] is None):
        # figure out the thresh for the range
        Cthr = remove_strong_artifacts(signals[:, pure_range[0]:pure_range[1]],
                                       comp_ind,
                                       Kthr,
                                       samplerate,
                                       num_mp_procs=num_mp_procs)
    else:
        Cthr = None
    Cthr = remove_strong_artifacts(signals,
                                   comp_ind,
                                   Kthr,
                                   samplerate,
                                   Cthr,
                                   num_mp_procs=num_mp_procs)

    # return cleaned data back in EEG space
    return np.dot(A, signals).astype(data.dtype)
Example #4
0
def wica_clean(data, samplerate=None, pure_range=(None,None),
               EOG_elecs=[0,1], std_fact=1.5, Kthr=2.5,num_mp_procs=0):
    """
    Clean data with the Wavelet-ICA method described here:

    N.P. Castellanos, and V.A. Makarov (2006). 'Recovering EEG brain signals: Artifact 
    suppression with wavelet enhanced independent component analysis'
    J. Neurosci. Methods, 158, 300--312.

    Instead of using the Infomax ICA algorithm, we use the (much much
    faster) IWASOBI algorithm.

    We also pick components to clean by only cleaning components that
    weigh heavily on the EOG electrodes.

    This ICA algorithm works better if you pass in data that have been
    high-pass filtered to remove big non-neural fluctuations and
    drifts.

    You do not have to run the ICA step on your entire dataset.
    Instead, it is possible to provide the start and end indicies for
    a continguous chunk of data that is 'clean' except for having lots
    of eyeblink examples.  This range will also be used inside the
    wavelet-based artifact correction code to determine the best
    threshold for identifying artifacts.  You do, however, want to try
    and make sure you provide enough samples for a good ICA
    decomposition.  A good rule of thumb is 3*(N^2) where N is the
    number of channels/sources.
    """
    # run pca
    sys.stdout.write("Running PCA...")
    Wpca,pca_data = pca(data[:,pure_range[0]:pure_range[1]]) #, ncomps, eigratio)
    
    # Run iwasobi
    sys.stdout.write("Running IWASOBI ICA...")
    sys.stdout.flush()
    #(W,Winit,ISR,signals) = iwasobi(data[:,pure_range[0]:pure_range[1]])
    (W,Winit,ISR,signals) = iwasobi(pca_data)
    W = np.dot(W,Wpca)
    A = np.linalg.pinv(W)
    #A = np.linalg.inv(W)
    sys.stdout.write("DONE!\n")
    sys.stdout.flush()

    # expand signals to span the entire dataset if necessary
    if (not pure_range[0] is None) or (not pure_range[1] is None):
        #Xmean=data[:,pure_range[0]:pure_range[1]].mean(1)
        #signals = np.add(np.dot(W,data).T,np.dot(W,Xmean)).T
        signals = np.dot(W,data)

    # pick which signals to clean (ones that weigh on EOG elecs)
    # vals = np.sum(np.abs(A[EOG_elecs,:]),0)
    # std_thresh = std_fact*np.std(vals)
    # comp_ind = np.nonzero(vals>=std_thresh)[0]
    comp_ind = []
    # loop over EOG elecs
    for e in EOG_elecs:
        # get the weights of each component onto that electrode
        vals = np.abs(A[e,:])
        # calculate the threshold that the std must exceed for that
        # component to be considered
        std_thresh = std_fact*np.std(vals)
        #comp_ind.extend(np.nonzero(vals>=std_thresh)[0].tolist())
        # loop over potential components
        for s in np.nonzero(vals>=std_thresh)[0].tolist():
            # calculate the weights of all electrodes into that component
            sweights = np.abs(A[:,s])
            # get threshold based on the std across those weights
            sthresh2 = std_fact*sweights.std()
            # see if that component crosses this second threshold
            if np.abs(A[e,s]) >= sthresh2:
                # yes, so append to the list to clean
                comp_ind.append(s)
    # Instead, try and make sure the weights are above the STD thresh
    # AND bigger for EOG elecs than for an elec like Pz

    comp_ind = np.unique(comp_ind)

    sys.stdout.write("Cleaning these components: " + str(comp_ind) + '\n')
    sys.stdout.flush()

    # remove strong artifacts
    if (not pure_range[0] is None) or (not pure_range[1] is None):
        # figure out the thresh for the range
        Cthr = remove_strong_artifacts(signals[:,pure_range[0]:pure_range[1]],
                                       comp_ind,Kthr,
                                       samplerate,
                                       num_mp_procs=num_mp_procs)
    else:
        Cthr = None
    Cthr = remove_strong_artifacts(signals,comp_ind,Kthr,
                                   samplerate,Cthr,
                                   num_mp_procs=num_mp_procs)
    
    # return cleaned data back in EEG space
    return np.dot(A,signals).astype(data.dtype)