def detect_burr(data, pv, left=None, right=None, method=0, minimum_peak_distance=100): titles = data.columns titleList = titles.values.tolist() if pv in titleList: pvn = titleList.index(pv) sta = DisplayData.showStatistic(data) print("statistic data:") print(sta) # use boxplot define threshold iqr = sta.loc['75%'][titles[pvn]] - sta.loc['25%'][titles[pvn]] if left is None: left = sta.loc['25%'][titles[pvn]] - 1.5 * iqr if right is None: right = sta.loc['75%'][titles[pvn]] + 1.5 * iqr print('min edge:', left, 'max edge:', right) burrdata = data[((data[titles[pvn]]) < left) | ((data[titles[pvn]]) > right)] LoadData.df2other(burrdata, 'csv', 'newfile.csv') y = data[titles[pvn]].values if method == 0: # find_peaks by scipy signal peaks, _ = signal.find_peaks(y, height=right) plt.plot(y, 'b', lw=1) plt.plot(peaks, y[peaks], "+", mec='r', mew=2, ms=8) plt.plot(np.zeros_like(y) + right, "--", color="gray") plt.title("find_peaks min_height:%7f" % right) plt.show() if method == 1: detect_peaks(y, mph=right, mpd=minimum_peak_distance, show=True) if method == 2: print('Detect peaks with minimum height and distance filters.') # thres=right/max(y) indexes = peakutils.peak.indexes(np.array(y), thres=right / max(y), min_dist=minimum_peak_distance) print('Peaks are: %s' % (indexes)) plt.plot(y, 'b', lw=1) for i in indexes: plt.plot(i, y[i], "+", mec='r', mew=2, ms=8) plt.plot(np.zeros_like(y) + right, "--", color="gray") plt.title("peakutils.peak thres:%f ,minimum_peak_distance:%d" % (right, minimum_peak_distance)) plt.show() else: print("Wrong PV name, not in ", titleList)
def extractFeatures(PPGdata): dataWindow = signal.medfilt(PPGdata, 3) # Power spectral density (self.sampleWindow/4 reading window, self.sampleWindow/(4*2) sequential window overlap) f, pxx = signal.welch(dataWindow, fs = 128, nperseg = 384/4) pxx = [10*np.log10(x) for x in pxx] # Mean amplitude of HF components (20 to 200Hz range) m = np.mean(pxx[20:200]) # LF/HF component magnitude ratio lfhfratio = (pxx[1] + pxx[2]) / (pxx[4] + pxx[5]) # Apply a 2nd order bandpass butterworth filter to attenuate heart rate components # other than heart signal's RR peaks. b, a = signal.butter(2, [1/100, 1/10], 'bandpass') dataWindow = signal.filtfilt(b, a, dataWindow) # Find the segment peaks' indices for peak occurrence variance feature. indices = detect_peaks.detect_peaks(dataWindow,mph = 0, mpd = 100,edge='rising',show=False) peakVariance = np.finfo(np.float64).max if len(indices) > 1: peakVariance = np.var(np.diff(indices)) # Calculate the heart rate number from number of peaks and start:end timeframe timeDifferenceInMinutes = 384 / 128 / 60 # print(timeDifferenceInMinutes) heartRate = float(len(indices)) / timeDifferenceInMinutes # features = [m, lfhfratio, peakVariance, heartRate] features = [m, lfhfratio, peakVariance, heartRate] return features
def sliding_window(fseq, window_size=3000, moving_size=200): WinNum = int((len(fseq) - window_size) / moving_size + 1) feature_matrix = np.zeros((WinNum, 6)) for i in range(int((len(fseq) - window_size) / moving_size + 1)): # yield fseq[i*moving_size:i*moving_size+window_size] feature_matrix[i, 0] = np.mean(fseq[i * moving_size:i * moving_size + window_size]) feature_matrix[i, 1] = np.std(fseq[i * moving_size:i * moving_size + window_size]) # p1 = peakdetect.peakdet(fseq[i*moving_size:i*moving_size+window_size], 30) # feature_matrix[i,2] = math.floor((len(p1[0])+len(p1[1]))/2) # new_p = get_br(0,window_size,1,fseq[i*moving_size:i*moving_size+window_size]) # feature_matrix[i,3] = new_p p2 = detect_peaks.detect_peaks(fseq[i * moving_size:i * moving_size + window_size], mph=3, mpd=120) feature_matrix[i, 2] = len(p2) feature_matrix[i, 3] = max(fseq[i * moving_size:i * moving_size + window_size]) feature_matrix[i, 4] = min(fseq[i * moving_size:i * moving_size + window_size]) a = 0 b = 0 for j in range(i * moving_size, i * moving_size + window_size): a += fseq[j]**2 for j in range(len(p2)): b += fseq[p2[j]]**2 feature_matrix[i, 5] = b / a * 100 return feature_matrix
def peaks(histarray, mph=None, mpd=1, threshold=0, edge='rising', kpsh=False, show=False): # put standard settings here and at the end make those variables settings to choose """ https://github.com/MonsieurV/py-findpeaks <-- many different methodologies to check out --------------- * ScyPy find_peaks_cwt does weird stuff, but generally works * findpeaks lightweight and fast, limited settings, show not integrated """ # square histarray to remove outliers (bogus detections)? # this needs to be adaptle according to the input data, above this height (95% of the data values) peaks are found # maybe loop until number of walls are found? <-- if number known before lim = np.percentile(histarray,95) # <-- parameter # this only gives all maxima, no settings possible # maxima = argrelextrema(temp[0], np.greater)[0] # findpeaks --> "Janko Slavic, https://github.com/jankoslavic/py-tools/tree/master/findpeaks" # ind = findpeaks(histarray, spacing=5, limit=5000) # detect_peaks --> "Marcos Duarte, https://github.com/demotu/BMC" """ possible settings: mph : {None, number}, optional (default = None) detect peaks that are greater than minimum peak height. mpd : positive integer, optional (default = 1) detect peaks that are at least separated by minimum peak distance (in number of data). threshold : positive number, optional (default = 0) detect peaks (valleys) that are greater (smaller) than `threshold` in relation to their immediate neighbors. edge : {None, 'rising', 'falling', 'both'}, optional (default = 'rising') for a flat peak, keep only the rising edge ('rising'), only the falling edge ('falling'), both edges ('both'), or don't detect a flat peak (None). kpsh : bool, optional (default = False) keep peaks with same height even if they are closer than `mpd`. """ # add 0 on both sides of histarray to prevent edge peaks not getting detected histarray = np.hstack((0, histarray)) histarray = np.append([histarray],[0]) indtemp = detect_peaks(histarray, mph=lim, mpd=3, threshold=0, edge='rising') # <-- parameter # move everything 1 to the left again because of 0 added at the beginning to detect edge peaks temp = [] for each in indtemp: temp.append(each - 1) ind = np.array(temp) return ind, lim
def sliding_window(fseq, window_size=3000, moving_size=200): WinNum = int((len(fseq) - window_size) / moving_size + 1) feature_matrix = np.zeros((WinNum, 9)) for i in range(int((len(fseq) - window_size) / moving_size + 1)): # yield fseq[i*moving_size:i*moving_size+window_size] feature_matrix[i, 0] = np.mean(fseq[i * moving_size:i * moving_size + window_size]) # mean fseq[i * moving_size:i * moving_size + window_size] = np.subtract( fseq[i * moving_size:i * moving_size + window_size], feature_matrix[i, 0]) feature_matrix[i, 1] = np.var(fseq[i * moving_size:i * moving_size + window_size]) # var feature_matrix[i, 2] = np.mean( np.abs( np.subtract( fseq[i * moving_size:i * moving_size + window_size - 1], fseq[i * moving_size + 1:i * moving_size + window_size]))) # v # p1 = peakdetect.peakdet(fseq[i*moving_size:i*moving_size+window_size], 30) # feature_matrix[i,2] = math.floor((len(p1[0])+len(p1[1]))/2) # new_p = get_br(0,window_size,1,fseq[i*moving_size:i*moving_size+window_size]) # feature_matrix[i,3] = new_p p2 = detect_peaks.detect_peaks(fseq[i * moving_size:i * moving_size + window_size], mph=3, mpd=120) feature_matrix[i, 3] = len(p2) # peak number (cycle) feature_matrix[i, 4] = max(fseq[i * moving_size:i * moving_size + window_size]) # max amplitude feature_matrix[i, 5] = min(fseq[i * moving_size:i * moving_size + window_size]) # min amplitude feature_matrix[i, 6] = np.mean(np.abs( (p2[1:len(p2)] - p2[0:len(p2) - 1]))) # average of peak distance feature_matrix[i, 7] = np.std(np.abs( (p2[1:len(p2)] - p2[0:len(p2) - 1] ))) / feature_matrix[i, 6] # CV of peak distance a = 0 b = 0 for j in range(i * moving_size, i * moving_size + window_size): a += fseq[j]**2 for j in range(len(p2)): b += fseq[p2[j]]**2 feature_matrix[i, 8] = b / a * 100 return feature_matrix
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np from vector import vector, plot_peaks from libs import detect_peaks print('Detect peaks without any filters.') indexes = detect_peaks.detect_peaks(vector) print('Peaks are: %s' % (indexes)) plot_peaks(np.array(vector), indexes, algorithm='detect_peaks from Marcos Duarte') print('Detect peaks with minimum height and distance filters.') indexes = detect_peaks.detect_peaks(vector, mph=7, mpd=2) print('Peaks are: %s' % (indexes)) plot_peaks(np.array(vector), indexes, mph=7, mpd=2, algorithm='detect_peaks from Marcos Duarte')
def extract_PPG_fea(PPGdata, fs=128): PPGdata = signal.medfilt(PPGdata, 3) b, a = signal.butter(2, [0.5 * 2 / fs, 50 * 2 / fs], 'bandpass') dataWindow = signal.filtfilt(b, a, PPGdata) # Find the segment peaks' indices for peak occurrence variance feature. indices = detect_peaks.detect_peaks(dataWindow, mph=None, mpd=50, edge='rising', show=False) IBI = np.array([]) # 两个峰值之之差的时间间隔 for i in range(len(indices) - 1): IBI = np.append(IBI, (indices[i + 1] - indices[i]) / fs) # IBI feas 7 mean_IBI = np.mean(IBI) rms_IBI = np.sqrt(np.mean(np.square(IBI))) std_IBI = np.std(IBI) skew_IBI = skew(IBI) kurt_IBI = kurtosis(IBI) per_above_IBI = float(IBI[IBI > mean_IBI + std_IBI].size) / float(IBI.size) per_below_IBI = float(IBI[IBI < mean_IBI - std_IBI].size) / float(IBI.size) IBI_feas = [ mean_IBI, rms_IBI, std_IBI, skew_IBI, kurt_IBI, per_above_IBI, per_below_IBI ] # HR feas 7 heart_rate = np.array([]) for i in range(len(IBI)): append_value = (PPGdata.size / fs) / IBI[i] if IBI[i] != 0 else 0 heart_rate = np.append(heart_rate, append_value) mean_heart_rate = np.mean(heart_rate) std_heart_rate = np.std(heart_rate) skew_heart_rate = skew(heart_rate) kurt_heart_rate = kurtosis(heart_rate) per_above_heart_rate = float(heart_rate[heart_rate > mean_heart_rate + std_heart_rate].size) / float( heart_rate.size) per_below_heart_rate = float(heart_rate[heart_rate < mean_heart_rate - std_heart_rate].size) / float( heart_rate.size) # HRV peakVariance = np.finfo(np.float64).max if len(indices) > 1: peakVariance = np.var(np.diff(indices)) HR_feas = [ mean_heart_rate, std_heart_rate, skew_heart_rate, kurt_heart_rate, per_above_heart_rate, per_below_heart_rate, peakVariance ] # power_0-0.6 freqs, power = getfreqs_power(dataWindow, fs, nperseg=dataWindow.size, scaling='spectrum') power_0_6 = [] for i in range(1, 40): power_0_6.append( getBand_Power(freqs, power, lower=0 + (i * 0.1), upper=0.1 + (i * 0.1))) Power_0_6_fea = power_0_6 # MSE fea MSE = multiScaleEntropy(indices, np.arange(1, 5), r=0.2 * np.std(indices), m=2) features = IBI_feas + HR_feas + MSE + power_0_6 return features