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)
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
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])))
def final_lowpass(self, f=90): """Performs simple lowpass, removing sharp edges""" eeg = self.eeg eeg[:] = filtfilt_low(f,eeg[:],Fs=eeg.Fs)
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)
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)
def final_lowpass(self, f=90): """Performs simple lowpass, removing sharp edges""" eeg = self.eeg eeg[:] = filtfilt_low(f, eeg[:], Fs=eeg.Fs)
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]
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)