Beispiel #1
0
def freqfilt_eeg(fn_in,fn_out,btype="lp",fl=None,fh=None,border=3,windowed=False):
    eeg = eegpy.open_eeg(fn_in)
    out = eegpy.F32(fn_out,"w+",shape=eeg.shape,cNames=eeg.channel_names,Fs=eeg.Fs)
    if btype == "lp":
        if not windowed:    
            out[:,:] = filtfilt_low(fl,eeg[:,:],Fs=eeg.Fs,border=border)
        else:
            for i in range(0,out.num_datapoints,100000):
                out[i:min(i+100000,out.num_datapoints),:] = filtfilt_low(fl,eeg[i:min(i+100000,out.num_datapoints),:],Fs=eeg.Fs,border=border)
    elif btype == "hp":
        #for i_c in range(eeg.num_channels):
        if not windowed:    
            out[:,:] = filtfilt_high(fh,eeg[:,:],Fs=eeg.Fs,border=border)
        else:
            for i in range(0,out.num_datapoints,100000):
                out[i:min(i+100000,out.num_datapoints),:] = filtfilt_high(fh,eeg[i:min(i+100000,out.num_datapoints),:],Fs=eeg.Fs,border=border)
    elif btype == "bp":
        if not windowed:    
            out[:,:] = filtfilt_band(fl,fh,eeg[:,:],Fs=eeg.Fs,border=border)
        else:
            for i in range(0,out.num_datapoints,100000):
                out[i:min(i+100000,out.num_datapoints),:] = filtfilt_band(fl,fh,eeg[i:min(i+100000,out.num_datapoints),:],Fs=eeg.Fs,border=border)
    elif btype == "bs":
        if not windowed:    
            out[:,:] = filtfilt_bandstop(fl,fh,eeg[:,:],Fs=eeg.Fs,border=border)
        else:
            for i in range(0,out.num_datapoints,100000):
                out[i:min(i+100000,out.num_datapoints),:] = filtfilt_bandstop(fl,fh,eeg[i:min(i+100000,out.num_datapoints),:],Fs=eeg.Fs,border=border)
Beispiel #2
0
    def calculate(self, cond_name=None):
        """After doing the setup, this method actually calculates the ERPs. 
        If no argument is supplied, then the data for all conditions are calculated."""
        if cond_name == None:
            cnames = self._times.keys()
        else:
            cnames = [cond_name]

        #self.check_for_artifacts()

        for c in cnames:
            if debug:
                print "Condition %s" % c
            #assert self._datadict.has_key(c) and self._is_calculated.has_key(c), "Key in dictionary missing!"
            #TODO: open file
            f = eegpy.open_eeg(self._dfile_name)
            #TODO: check timepoints
            ndp = f.numDatapoints
            tps_ok = True
            if debug:
                print ndp, str(f)
            for t in self._times[c]:
                #if debug:
                #    print "t = ", t
                if t + self._start_end[0] < 0 or t + self._start_end[1] > ndp:
                    tps_ok = False
                    break
            if tps_ok:
                #getData
                data = f.get_data_for_events(self._times[c], self._start_end)
                if self._lp_freq != None:
                    data = filtfilt_low(self._lp_freq, data, Fs=f.Fs)
                #Baseline-Korrektur
                data -= data[-self._start_end[0] - 200:-self._start_end[0],
                             ...].mean(axis=0)
                #calculate average
                self._datadict[c] = data[:, :,
                                         ~self._is_artifact[c]].mean(axis=2)
                #print "Shape datadict:", self._datadict[c].shape
                self._is_calculated[c] = True
            else:
                #TODO: some kind of error message
                print "Some problem with the timepoints occured. ndp:", ndp, "max_ts:", max(
                    self._times[c])
                pass
Beispiel #3
0
 def calculate(self, cond_name=None):
     """After doing the setup, this method actually calculates the ERPs. 
     If no argument is supplied, then the data for all conditions are calculated."""
     if cond_name == None:
         cnames = self._times.keys()
     else:
         cnames = [cond_name]
     
     #self.check_for_artifacts()
     
     for c in cnames:
         logger.debug("Condition %s" % c)
         #assert self._datadict.has_key(c) and self._is_calculated.has_key(c), "Key in dictionary missing!"
         f = self.eeg
         #TODO: check timepoints
         ndp = f.numDatapoints
         tps_ok = True
         logger.debug("datapoints: %s, input: %s" % (ndp, str(f)))
         for t in self._times[c]:
             #if debug:
             #    print "t = ", t
             if t+self._start_end[0]<0 or t+self._start_end[1]>ndp:
                 tps_ok=False
                 break
         if tps_ok:
             #getData
             data = f.get_data_for_events(self._times[c],self._start_end)
             if self._lp_freq!=None:
                 data = filtfilt_low(self._lp_freq,data,Fs=f.Fs)
             #Baseline-Korrektur
             data -= self._get_baseline_data(data).mean(axis=0)
             #calculate average
             self._datadict[c] = data[:,:,~self._is_artifact[c]].mean(axis=2)
             #print "Shape datadict:", self._datadict[c].shape
             self._is_calculated[c] = True
         else:
             raise ValueError("Some problem with the timepoints occured." +
                              "Number of datapoints: %i, Max. timepoint: %i" %(ndp, max(self._times[c])))
Beispiel #4
0
 def final_lowpass(self, f=90):
     """Performs simple lowpass, removing sharp edges"""
     eeg = self.eeg
     eeg[:] = filtfilt_low(f,eeg[:],Fs=eeg.Fs)
Beispiel #5
0
 def final_lowpass(self, f=None):
     """Performs simple lowpass, removing sharp edges"""
     if f == None:
         f = self._f_flp
     eeg = self._data
     eeg[:] = filtfilt_low(f,eeg[:],Fs=self._Fs)
Beispiel #6
0
def freqfilt_eeg(fn_in,
                 fn_out,
                 btype="lp",
                 fl=None,
                 fh=None,
                 border=3,
                 windowed=False):
    eeg = eegpy.open_eeg(fn_in)
    out = eegpy.F32(fn_out,
                    "w+",
                    shape=eeg.shape,
                    cNames=eeg.channel_names,
                    Fs=eeg.Fs)
    if btype == "lp":
        if not windowed:
            out[:, :] = filtfilt_low(fl, eeg[:, :], Fs=eeg.Fs, border=border)
        else:
            for i in range(0, out.num_datapoints, 100000):
                out[i:min(i + 100000, out.num_datapoints), :] = filtfilt_low(
                    fl,
                    eeg[i:min(i + 100000, out.num_datapoints), :],
                    Fs=eeg.Fs,
                    border=border)
    elif btype == "hp":
        #for i_c in range(eeg.num_channels):
        if not windowed:
            out[:, :] = filtfilt_high(fh, eeg[:, :], Fs=eeg.Fs, border=border)
        else:
            for i in range(0, out.num_datapoints, 100000):
                out[i:min(i + 100000, out.num_datapoints), :] = filtfilt_high(
                    fh,
                    eeg[i:min(i + 100000, out.num_datapoints), :],
                    Fs=eeg.Fs,
                    border=border)
    elif btype == "bp":
        if not windowed:
            out[:, :] = filtfilt_band(fl,
                                      fh,
                                      eeg[:, :],
                                      Fs=eeg.Fs,
                                      border=border)
        else:
            for i in range(0, out.num_datapoints, 100000):
                out[i:min(i + 100000, out.num_datapoints), :] = filtfilt_band(
                    fl,
                    fh,
                    eeg[i:min(i + 100000, out.num_datapoints), :],
                    Fs=eeg.Fs,
                    border=border)
    elif btype == "bs":
        if not windowed:
            out[:, :] = filtfilt_bandstop(fl,
                                          fh,
                                          eeg[:, :],
                                          Fs=eeg.Fs,
                                          border=border)
        else:
            for i in range(0, out.num_datapoints, 100000):
                out[i:min(i +
                          100000, out.num_datapoints), :] = filtfilt_bandstop(
                              fl,
                              fh,
                              eeg[i:min(i + 100000, out.num_datapoints), :],
                              Fs=eeg.Fs,
                              border=border)
Beispiel #7
0
 def final_lowpass(self, f=90):
     """Performs simple lowpass, removing sharp edges"""
     eeg = self.eeg
     eeg[:] = filtfilt_low(f, eeg[:], Fs=eeg.Fs)
Beispiel #8
0
class FmriFilterContinuous(object):
    """New approach to filtering, for continuous data only.
    Takes the eeg, finds slices automatically and does a kind of OBS-Filtering."""
    def __init__(self, eeg=None, slice_width=78, k=20, obs_size=5, f_lp=70):
        self.eeg = eeg
        self._slice_width = slice_width
        self.ch_for_slice_alignment = 14
        #self.cfsa = self.ch_for_slice_alignment
        self.num_neighbors = k
        self.obs_size = obs_size
        self.f_lp = f_lp
        self.slice_shift = 0  #Introduced for analysis, shifting of slice-timepoints
        self._pa_zeros = 5  #Number of zeros to pre-/append to slices

    def get_cfsa(self):
        return self.ch_for_slice_alignment

    def set_cfsa(self, cfsa):
        self.ch_for_slice_alignment = cfsa

    cfsa = property(get_cfsa, set_cfsa)

    def find_all_slice_artifacts(self):
        def update_pbar(num):
            """Callback for find_all_maxs"""
            if show_progressbar:
                pbar.update(num / 2)

        eeg = self.eeg
        #y = abs(smooth_windowed_eeg(eeg,[self.cfsa],self._slice_width))[:,0]
        #y = smooth_windowed_eeg_power(eeg,[self.cfsa],self._slice_width)[:,0]
        y = filtfilt_band(1, eeg.Fs / self._slice_width, eeg[:, self.cfsa])
        #pylab.plot(y[::10])
        #pylab.plot(eeg[:,14])
        print y.shape, self._slice_width
        #import pylab
        #pylab.ion()
        #pylab.plot(y[0:20000:1])
        #pylab.show()
        #raw_input()
        #pylab.plot(y[13000:20000:1])
        slcs_raw = find_all_maxs(y[:1000], ratio=0.6)  # First segment
        slcs_raw.sort()
        #print "t=", t
        #slcs_raw.append(t)
        offset = 0
        t = int(0.5 * self._slice_width)
        while (t > 0.4 * self._slice_width or (y.shape[0] - offset) > 10000
               ) and (y.shape[0] - offset) > self._slice_width * 2:
            #print (y.shape[0]-offset)
            #print t, offset, "-",
            offset = slcs_raw[-1] + self._slice_width / 2
            #print t, offset, "-",
            #pylab.plot(y[offset:offset+self._slice_width])
            #pylab.show()
            #raw_input()
            t = y[offset:offset + self._slice_width].argmax()
            slcs_raw.append(offset + t)
            #print slcs_raw[-1], slcs_raw[-1]-slcs_raw[-2], " - ",
            #time.sleep(0.1)
            #print t, offset
        print ""
        #pylab.plot(y[::10])
        if show_progressbar:
            pbar = ProgressBar(maxval=eeg.shape[0] / self._slice_width).start()
        #slcs_raw = find_all_maxs(y[:,0],0.3,self._slice_width,20,callback=update_pbar)
        print "Raw slice-positions found", len(slcs_raw), np.mean(
            np.diff(slcs_raw)), np.min(slcs_raw), np.max(slcs_raw)
        slcs_raw_diff = np.diff(slcs_raw)
        print "slcs_raw_diff: ", scoreatpercentile(
            slcs_raw_diff,
            5), scoreatpercentile(slcs_raw_diff,
                                  50), scoreatpercentile(slcs_raw_diff, 95)
        #raise Exception("Abbruch")
        y, fn = upsample_to_memmap(eeg[:, self.cfsa], 10)
        slcs_raw_ups = [x * 10 for x in slcs_raw]
        t = slcs_raw_ups[len(slcs_raw) / 2]
        template = y[t - self._slice_width * 10 / 2:t +
                     self._slice_width * 10 / 2]
        for i in range(5):
            t = slcs_raw_ups[len(slcs_raw) / 2 + i]
            template += y[t - self._slice_width * 10 / 2:t +
                          self._slice_width * 10 / 2]
        template /= 6
        offsets = []
        for i, t in enumerate(slcs_raw_ups):
            #offset = find_max_overlap(template, eeg[t-self._slice_width/2:t+self._slice_width/2,self.cfsa], 100)
            offset = find_max_overlap(
                template, y[t - self._slice_width * 10 / 2:t +
                            self._slice_width * 10 / 2], 100)
            offsets.append(offset)
        self.slcs_ups = [
            slcs_raw_ups[i] + offsets[i] + self.slice_shift
            for i in range(len(slcs_raw_ups))
        ]
        if show_progressbar:
            pbar.finish()
        print "Refined slice-positions found. Finished.", len(
            offsets), np.mean(offsets), np.median(offsets), np.min(
                offsets), np.max(offsets)
        print "Percentile 0.5,5,95,99.5 of offsets: ", scoreatpercentile(
            offsets, 0.5), scoreatpercentile(offsets, 5), scoreatpercentile(
                offsets, 95), scoreatpercentile(offsets, 99.5)
        #Adjusting _slice_width...
        print "Old slice_width:", self._slice_width
        self._new_slice_width = int(n.ceil(n.mean(n.diff(self.slcs_ups)))) / 10
        self._new_slice_width += 3  # Make slice wider to have no zombie-timepoints
        self._new_slice_width = self._new_slice_width + self._new_slice_width % 2
        #self._new_slice_width = (self._new_slice_width/2)*2 # make sw%2==0 (divisible by 2)
        print "New slice_width:", self._new_slice_width
        #raise Exception("Abbruch")
        return [x / 10 for x in self.slcs_ups]

    def remove_artifacts(self):
        """Tries to remove the artifacts. 
        Uses mixture of mean-subtraction and OBS-PCA-Subtraction
        Needs self.slcs to be set.
        Saves example data in self.examples to make evaluation of filter quality possible"""
        def obs_fit_error(p, y, x):
            err = n.zeros((x.shape[0]), "d")
            err += p[0]
            for i in range(self.obs_size):
                err += y[:, i] * p[i + 1]
            err -= x
            return abs(err**2).sum()

        def obs_fit_error_lsq(p, y, x):
            err = n.zeros((x.shape[0]), "d")
            err += p[0]
            for i in range(self.obs_size):
                err += y[:, i] * p[i + 1]
            err -= x
            return err

        def las_fit_error_lsq(p, y, x):
            """Local artifact subtraction"""
            err = p[0] * y
            err -= x
            return err

        #Shortnames
        eeg = self.eeg
        slcs = self.slcs_ups
        sw = self._new_slice_width * 10
        k = self.num_neighbors
        self.examples = []

        num_examples = 10

        #Loop over channels
        if show_progressbar:
            pbar = ProgressBar().start()
        for i_ch in range(eeg.num_channels):
            #Make Highpass-Version of channel
            #ch = eeg[:,i_ch].copy()
            y, fn = upsample_to_memmap(eeg[:, i_ch], 10)
            y_hp, fn_hp = tmp_memmap(dtype=y.dtype, shape=y.shape, mode="w+")
            y_hp[:] = filtfilt_high(1, y, Fs=10000.0)
            y_out, fn_out = tmp_memmap(dtype=y.dtype, shape=y.shape, mode="w+")
            y_out[:] = y[:]
            #ch_hp = filtfilt_high(1.0,ch,Fs=eeg.Fs)
            neighbors = n.zeros((sw + 2 * self._pa_zeros, k))
            #Prefill
            for i in range(k):
                #print neighbors[:,i].shape, eeg[slcs[i]-sw/2:slcs[i]+sw/2,i_ch].shape
                neighbors[:, i] = prepend_append_zeros(
                    y_hp[slcs[i] - sw / 2:slcs[i] + sw / 2], self._pa_zeros)
            #Loop over slices and filter
            next_subst = 0
            for i, t in enumerate(slcs):
                try:
                    if i > k / 2 and i < len(slcs) - k / 2:
                        neighbors[:, next_subst] = prepend_append_zeros(
                            y_hp[slcs[i + k / 2] - sw / 2:slcs[i + k / 2] +
                                 sw / 2], self._pa_zeros)
                        next_subst += 1
                        next_subst = next_subst % k
                    tmp = prepend_append_zeros(y[t - sw / 2:t + sw / 2],
                                               self._pa_zeros)
                    #Subtraction
                    #Shift/scale template
                    template = neighbors.mean(axis=1)
                    p = [1.0, 0]
                    p_las = leastsq(las_fit_error_lsq, p,
                                    args=(template, tmp))[0]
                    #print p_las[0],
                    tmp -= p_las[0] * template

                    #Beispieldaten speichern: Teil 1
                    if i_ch == self.ch_for_slice_alignment:
                        if i % (len(slcs) / num_examples) == (
                                len(slcs) / num_examples) / 2:
                            print "examples, Teil 1"
                            example = {}
                            example["raw"] = prepend_append_zeros(
                                y[t - sw / 2:t + sw / 2].copy(),
                                self._pa_zeros)
                            example["mean"] = p_las[0] * template
                    #OBS-Fit
                    components = pcafilt.unmix(
                        neighbors)  #OBS will be first 5 components
                    components -= components.mean(axis=0).reshape(
                        1, -1).repeat(components.shape[0],
                                      0)  #demeaning column-wise
                    obs = components[:, :self.obs_size].copy()
                    #Fit OBS to artifact
                    p = [0] + [0] * self.obs_size
                    #p_lsq = fmin(obs_fit_error,p,args=(obs,eeg[t-sw/2:t+sw/2,i_ch]),maxiter=1e5,maxfun=1e5)#[0]
                    p_lsq = leastsq(obs_fit_error_lsq, p, args=(obs, tmp))[0]
                    #print i,t,"p_lsq", p_lsq
                    fit = n.zeros((obs.shape[0]), "d")
                    fit += p_lsq[0]
                    for j in range(self.obs_size):
                        fit += obs[:, j] * p_lsq[j + 1]
                    tmp -= fit
                    try:
                        #eeg[t/10-sw/10/2:t/10+sw/10/2,i_ch] = tmp[self._pa_zeros:-self._pa_zeros][::10]
                        y_out[t - sw / 2:t +
                              sw / 2] = tmp[self._pa_zeros:-self._pa_zeros][:]
                    except ValueError, ve:
                        print i_ch, i, t, eeg[
                            t / 10 - sw / 10 / 2:t / 10 + sw / 10 / 2,
                            i_ch].shape, tmp[self._pa_zeros:-self.
                                             _pa_zeros][::10].shape

                    #Beispieldaten speichern: Teil 2
                    if i_ch == self.ch_for_slice_alignment:
                        if i % (len(slcs) / num_examples) == (
                                len(slcs) / num_examples) / 2:
                            print "examples, Teil 2"
                            #example["fit"] = n.zeros(example["raw"].shape) #fit.copy()
                            example["fit"] = fit.copy()
                            example["obs"] = obs.copy()
                            example["filt1"] = (tmp + fit).copy()
                            example["filt2"] = tmp.copy()
                            self.examples.append(example)

                    if show_progressbar:
                        pbar.update(
                            (i_ch + i / len(slcs)) * 100 / eeg.num_channels)
                except Exception, e:
                    print "Error occurred at slice at t=", t, ", ignored"
                    print e
            y_out[:] = filtfilt_low(self.f_lp, y_out[:], Fs=eeg.Fs * 10)
            eeg[:, i_ch] = y_out[::10]
Beispiel #9
0
 def final_lowpass(self, f=None):
     """Performs simple lowpass, removing sharp edges"""
     if f == None:
         f = self._f_flp
     eeg = self._data
     eeg[:] = filtfilt_low(f, eeg[:], Fs=self._Fs)