def computeRMS(self, fmin=11, fmax=16, reader=None): raise UserWarning( "The code of this function need to be recoded to use time rather than sample." ) if reader is None: reader = self.reader # The filters need the signal to be at least 3*nbTaps nbTaps = 1001 sampleDuration = max(nbTaps * 3, self.endSample - self.startSample) data = reader.read(self.channel, self.startSample, sampleDuration=sampleDuration) #print self.channel #, data signal = data[1][0] fs = data[0][0] # sampling rate # Defining EEG filters bandPassFilter = Filter(fs) bandPassFilter.create(low_crit_freq=fmin, high_crit_freq=fmax, order=nbTaps, btype="bandpass", ftype="FIR", useFiltFilt=True) signal = bandPassFilter.applyFilter(signal)[0:(self.endSample - self.startSample)] self.RMSAmp = sqrt(mean(signal**2))
def computeRMS(self, event, fmin=11, fmax=16): # The filters need the signal to be at least 3*nbTaps nbTaps = 1001.0 fs = self.getChannelFreq(event.channel) duration = max((nbTaps*3.0+1)/float(fs), event.duration()) data = self.read([event.channel], event.timeStart(), duration) signal = data[event.channel].signal # In some cases, the signal will be shorter than nbTaps*3.0/fs+1, # for example, when the spindle is too close to the end of the recording # epoch. In these time, we have to accept lower number of taps. if len(signal) < nbTaps*3.0+1: nbTaps = int((len(signal)-1)/3) # Defining EEG filters bandPassFilter = Filter(fs) bandPassFilter.create(low_crit_freq=fmin, high_crit_freq=fmax, order=int(nbTaps), btype="bandpass", ftype="FIR", useFiltFilt=True) try : signal = bandPassFilter.applyFilter(signal)[0:int(event.duration()*fs)] except ValueError: print((len(signal), nbTaps, max(nbTaps*3.0/fs, event.duration()), nbTaps*3.0/fs, event.duration())) raise event.properties["RMSAmp"] = np.sqrt(np.mean(signal**2))
def preprocessing(self, signal, time=None, samplingRate=None, channel=None): # Defining EEG filters order = int(min(3003, len(signal) - 3) / 3) bandPassFilter = Filter(samplingRate) bandPassFilter.create(low_crit_freq=self.lowFreq, high_crit_freq=self.highFreq, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) """ Splitting the process in chuck of 1M elements to avoid memory errors. """ NMAX = 1000000.0 N = len(signal) output = [[0]] for i in range(int(N / NMAX) + 1): block = signal[int(max(i * NMAX - 1, 0)):int(min(N, (i + 1) * NMAX + 1))] block = bandPassFilter.applyFilter(block) ########################## Computing Teager operator ###################### output.append(block[1:-1]**2 - block[:-2] * block[2:]) output.append([0]) return concatenate(output)
def preprocessing(self, signal, time=None, samplingRate=None, channel=None): # Defining EEG filters order = int(min(3003, len(signal) - 3) / 3) bandPassFilter = Filter(samplingRate) bandPassFilter.create(low_crit_freq=self.lowFreq, high_crit_freq=self.highFreq, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) # filtering can take a lot of memory. By making sure that the # garbage collector as passed just before the filtering, we # increase our chances to avoid a MemoryError gc.collect() signal = bandPassFilter.applyFilter(signal) ################################# RMS COMPUTATION ##################### windowNbSample = int(round(self.averagingWindowSize * samplingRate)) if mod(windowNbSample, 2) == 0: # We need an odd number. windowNbSample += 1 return self.averaging(np.abs(signal), windowNbSample)
def preprocessing(self, signal, time=None, samplingRate=None, channel=None): # Defining EEG filters order = int(min(3003, len(signal) - 3) / 3) bandPassFilter = Filter(samplingRate) bandPassFilter.create(low_crit_freq=self.lowFreq, high_crit_freq=self.highFreq, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) # filtering can take a lot of memory. By making sure that the # garbage collector as passed just before the filtering, we # increase our chances to avoid a MemoryError gc.collect() signal = bandPassFilter.applyFilter(signal) ################################# RMS COMPUTATION ##################### windowNbSample = int(round(self.averagingWindowSize * samplingRate)) if mod(windowNbSample, 2) == 0: # We need an odd number. windowNbSample += 1 # For selecting samples using a quantile-based thresholds, using abs(X) # or X**2 to rectify the X signal will give exactly the same result # since X**2 eqauls abs(X)**2 (for real numbers) and the transformation # from abs(X) to abs(X)**2 is monotonically increasing, meaning that # rank based statistics (such as quatiles) will give exactly the same # result. We use the numpy implementation of abs() because it is the # faster alternative. return np.sqrt(self.averaging(signal**2.0, windowNbSample))
def postDetectionComputation(self, EEGsignal, channelTime, startInds, stopInds, newEvents, fs): # The RMS amplitude computed here is the RMS amplitude of the # signal filtered in the spindle band. if self.computeRMS: order = int(min(3003, len(EEGsignal) - 3) / 3) bandPassFilter = Filter(fs) bandPassFilter.create(low_crit_freq=self.lowFreq, high_crit_freq=self.highFreq, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) filteredEEGSignal = bandPassFilter.applyFilter(EEGsignal) for startInd, stopInd, spindle in zip(startInds, stopInds, newEvents): spindle.RMSAmp = sqrt( mean(filteredEEGSignal[startInd:stopInd]**2)) if self.computeFreq: for startInd, stopInd, spindle in zip(startInds, stopInds, newEvents): sig = EEGsignal[startInd:stopInd] if sig.size < 512: sig = concatenate((sig, zeros(512 - sig.size))) FFT = abs(fft(sig)) freqs = fftfreq(sig.size, 1.0 / fs) FFT = FFT[(freqs >= self.lowFreq) * (freqs <= self.highFreq)] freqs = freqs[(freqs >= self.lowFreq) * (freqs <= self.highFreq)] spindle.meanFreq = sum(freqs * FFT) / sum(FFT) if self.computeFreqMode: for startInd, stopInd, spindle in zip(startInds, stopInds, newEvents): sig = EEGsignal[startInd:stopInd] if sig.size < fs * 10: sig = concatenate((sig, zeros(int(fs) * 10 - sig.size))) FFT = abs(fft(sig)) freqs = fftfreq(sig.size, 1.0 / fs) FFT = FFT[(freqs >= self.lowFreq) * (freqs <= self.highFreq)] freqs = freqs[(freqs >= self.lowFreq) * (freqs <= self.highFreq)] spindle.modeFreq = freqs[np.argmax(FFT)] if self.computeSlopeFreq: self.computeFreqSlope_atDetection(EEGsignal, fs, startInds, stopInds, newEvents, channelTime)
def preprocessing(self, data): # Defining EEG filters bandPassPassFilter = Filter(data.samplingRate) bandPassPassFilter.create(low_crit_freq=self.lowFreq, high_crit_freq=self.highFreq, order=1001, btype="bandpass", ftype="FIR", useFiltFilt=True) # filtering can take a lot of memory. By making sure that the # garbage collector as passed just before the filtering, we # increase our chances to avoid a MemoryError gc.collect() return bandPassPassFilter.applyFilter(data.signal)
def computeRMS(self, fmin, fmax, reader=None): if reader is None: reader = self.reader channelList = unique([s.channel for s in self.detectedEvents]) # Pickle data for each channel separatelly to simplify and accelerate # the reading of large files. if self.usePickled: self.reader.pickleCompleteRecord(channelList) for channel in channelList: data = self.reader.readChannel(channel, usePickled=self.usePickled) signal = data.signal fs = data.samplingRate # sampling rate t = self.reader.getChannelTime(self.detectedEvents[0].channel) # Defining EEG filters bandPassFilter = Filter(fs) bandPassFilter.create(low_crit_freq=fmin, high_crit_freq=fmax, order=1001, btype="bandpass", ftype="FIR", useFiltFilt=True) # filtering can take a lot of memory. By making sure that the # garbage collector as passed just before the filtering, we # increase our chances to avoid a MemoryError gc.collect() signal = bandPassFilter.applyFilter(signal) channelEvents = [ s for s in self.detectedEvents if s.channel == channel ] for event in channelEvents: indStart = bisect.bisect_left(t, event.startTime()) indEnd = indStart + int(event.timeDuration * fs) event.RMSAmp = np.sqrt( np.mean(signal[indStart:(indEnd + 1)]**2))
def preprocessing(self, data): # Defining EEG filters lowPassFilter = Filter(data.samplingRate) lowPassFilter.create(low_crit_freq=None, high_crit_freq=self.highFreq, order=1001, btype="lowpass", ftype="FIR", useFiltFilt=True) # filtering can take a lot of memory. By making sure that the # garbage collector as passed just before the filtering, we # increase our chances to avoid a MemoryError gc.collect() signal = lowPassFilter.applyFilter(data.signal) ########################## Computing Teager operator ###################### return concatenate( ([0], signal[1:-1]**2 - signal[:-2] * signal[2:], [0]))
def preprocessing(self, signal, time=None, samplingRate=None, channel=None): def hanningSquared(N): return np.hanning(N)**2 # Defining EEG filters order = int(min(3003, len(signal)-3)/3) alphaBandPassFilter = Filter(samplingRate) alphaBandPassFilter.create(low_crit_freq=self.alphaLowFreq, high_crit_freq=self.alphaHighFreq, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) deltaBandPassFilter = Filter(samplingRate) deltaBandPassFilter.create(low_crit_freq=self.deltaLowFreq, high_crit_freq=self.deltaHighFreq, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) # filtering can take a lot of memory. By making sure that the # garbage collector as passed just before the filtering, we # increase our chances to avoid a MemoryError gc.collect() alphaSignal = alphaBandPassFilter.applyFilter(signal) deltaSignal = deltaBandPassFilter.applyFilter(signal) ################################# RMS COMPUTATION ##################### alphaWindowNbSample = int(round(self.alphaAveragingWindowSize*samplingRate)) if np.mod(alphaWindowNbSample, 2) == 0 : # We need an odd number. alphaWindowNbSample += 1 deltaWindowNbSample = int(round(self.deltaAveragingWindowSize*samplingRate)) if np.mod(deltaWindowNbSample, 2) == 0 : # We need an odd number. deltaWindowNbSample += 1 deltaRMS = np.sqrt(self.averaging(deltaSignal**2, deltaWindowNbSample, hanningSquared)) alphaRMS = np.sqrt(self.averaging(alphaSignal**2, alphaWindowNbSample, hanningSquared)) return alphaRMS/deltaRMS
def computeFreqSlope(self, event, fmin=11, fmax=16, method="hilbert", beforePadding=2, afterPadding=2, doubleFilt=True, keep_curve=True): if method == "stransform": # The filters need the signal to be at least 3*nbTaps nbTaps = 1001.0 fs = self.getChannelFreq(event.channel) duration = max((nbTaps*3.0+1)/float(fs), event.duration()) data = self.read([event.channel], event.timeStart(), duration) signal = data[event.channel].signal nbMinSamples = int(self.getChannelFreq(event.channel)) N = len(signal) if len(signal) < nbMinSamples: signal = np.concatenate((signal, np.zeros(nbMinSamples - N))) X, fX = computeST(signal, fs, fmin=fmin-1, fmax=fmax+1) Y = abs(np.transpose(X)) regx = arange(N)/float(fs) regy = [] for i in range(N): try: result = trapz(fX*Y[:, i], fX)/float(trapz(Y[:, i], fX)) regy.append(result) #if np.isnan(result) or np.isnan(result): # print fX, Y[:, i], len(signal), event.duration() except: print((fX.shape, Y.shape, fX.shape)) print((i, self.recordsInfo[-1].startTime, self.recordsInfo[-1].duration, event.timeStart(), event.duration())) raise assert(not np.any(np.isnan(regy))) assert(not np.any(np.isinf(regy))) z = np.polyfit(regx, regy, deg=1) event.properties["slope"] = z[0] elif method == "hilbert": if event.channel == "": channel = self.getChannelLabels()[0] else: channel = event.channel fs = self.getChannelFreq(channel) data = self.read([channel], event.timeStart() + event.duration()/2.0 - beforePadding, afterPadding+beforePadding) decimate_factor = int(fs/100) signal = data[channel].signal signal -= np.mean(signal) signal = decimate(signal, decimate_factor, zero_phase=True) fs /= decimate_factor; bandPassFilter = Filter(fs) order = int(len(signal)/3)-1 if order % 2 == 0: order -= 1 # Need to be an odd number #order = min(1001, order) # No need for the order to be higher than 1001 order = min(3001, order) # No need for the order to be higher than 1001 bandPassFilter.create(low_crit_freq=fmin, high_crit_freq=fmax, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) signal = bandPassFilter.applyFilter(signal) if doubleFilt: signal = bandPassFilter.applyFilter(signal) analytic_signal = hilbert(signal) instantaneous_phase = np.unwrap(np.angle(analytic_signal)) instantaneous_frequency = (np.diff(instantaneous_phase) /(2.0*np.pi) * fs) freq = running_mean(np.abs(instantaneous_frequency), int(fs/4)) regy = freq[int(len(freq)/2-fs/4):int(len(freq)/2+fs/4)] regx = np.arange(len(regy))/float(fs) ransac = linear_model.RANSACRegressor() ransac.fit(regx[:, np.newaxis], regy) event.properties["slope"] = ransac.estimator_.coef_[0] if keep_curve: event.properties["slopeCurve"] = freq
def computeModeFreq(self, event, fmin=11, fmax=16, removeBaseline=True, method="hilbert", padding=6): if event.channel == "": channel = self.getChannelLabels()[0] else: channel = event.channel if method == "hilbert": fs = self.getChannelFreq(channel) data = self.read([channel], event.timeStart()-padding, event.duration()+padding) signal = data[channel].signal signal -= np.mean(signal) bandPassFilter = Filter(fs) order = int(len(signal)/3)-1 if order % 2 == 0: order -= 1 # Need to be an odd number order = min(1001, order) # No need for the order to be higher than 1001 bandPassFilter.create(low_crit_freq=fmin, high_crit_freq=fmax, order=order, btype="bandpass", ftype="FIR", useFiltFilt=True) padBeforeTime = (event.timeStart()-data[event.channel].startTime) indStart = int(padBeforeTime*fs) indEnd = int(indStart + event.duration()*fs) signal = bandPassFilter.applyFilter(signal)[indStart:indEnd] analytic_signal = hilbert(signal) instantaneous_phase = np.unwrap(np.angle(analytic_signal)) instantaneous_frequency = (np.diff(instantaneous_phase) / (2.0*np.pi) * fs) #hist = np.histogram(np.abs(instantaneous_frequency), bins=int((fmax-fmin+2)*10), range=(fmin-1, fmax+1)) #spinFreq = (hist[1][1:]+hist[1][:-1])/2 #density = hist[0] #freqMode = spinFreq[np.argmax(density)] freqs = np.linspace(fmin-1, fmax+1, (fmax-fmin+2)*100) density = gaussian_kde(np.abs(instantaneous_frequency)) #density.covariance_factor = lambda : .025 density._compute_covariance() freqMode = freqs[np.argmax(density(freqs))] ############# regx = arange(len(instantaneous_frequency))/float(fs) regy = np.abs(instantaneous_frequency) #for i in range(N): # try: # result = trapz(fX*Y[:, i], fX)/trapz(Y[:, i], fX) # regy.append(result) # #if np.isnan(result) or np.isnan(result): # # print fX, Y[:, i], len(signal), event.duration() # except: # print((fX.shape, Y.shape, fX.shape)) # print((i, self.recordsInfo[-1].startTime, self.recordsInfo[-1].duration, event.timeStart(), event.duration())) # raise # assert(not np.any(np.isnan(regy))) assert(not np.any(np.isinf(regy))) z = np.polyfit(regx, regy, deg=1) event.properties["slopeOriginHilbert"] = z[1] event.properties["slopeHilbert"] = z[0] ############# elif method == "FFT": freqs, FFT = self.getFFTEvent(event, fmin, fmax, removeBaseline) freqMode= freqs[np.argmax(FFT)] else: raise ValueError("method must be 'hilbert' or 'FFT'.") event.properties["modeFreq"] = freqMode
############################################################################### # Making and saving an example of ST plot ############################################################################### stPlot(t[:300], signal[:300], fmin=0, fmax=20, figname=os.path.join(path, "stExample.png")) ############################################################################### # Making and saving an example of filtering plots ############################################################################### # Defining EEG filters lowPassFilter = Filter(fs) lowPassFilter.create(low_crit_freq=None, high_crit_freq=10.0, order=1001, btype="lowpass", ftype="FIR", useFiltFilt=True) highPassFilter = Filter(fs) highPassFilter.create(low_crit_freq=8.0, high_crit_freq=None, order=1001, btype="highpass", ftype="FIR", useFiltFilt=True)