def getMinMax(dataArray): maxima = [] minima = [] peaksMax, peaksMin = peakdetect(dataArray, lookahead=peakDetectLookAhead, delta=peakDetectDelta) maxima = [p[0] for p in peaksMax] minima = [p[0] for p in peaksMin] # If the first minima is before the first maxima, then we need to shift it over # so we are always start with a max peak, as we will be looking for decay information. while len(minima) > 0 and len(maxima) > 0 and minima[0] < maxima[0]: minima = minima[1:] # We need the maxima and minima to be the same size to we don't get any out of bounds errors while (len(minima) > len(maxima)): minima = minima[:-1] # A good signal shouldn't have only a single peak with no minimum, # if it does this will add a minimum point for the smallest value after # the peak. This will prevent some empty trace errors for an otherwise # unusable result set. if len(maxima) == 1 and len(minima) == 0: lastMinimum=getIndexAtAmplitude(dataArray[maxima[0]:], 0, True) minima.append(maxima[0]+lastMinimum) # We need the maxima and minima to be the same size to we don't get any out of bounds errors while (len(minima) < len(maxima)): maxima = maxima[:-1] # If it's a really noisy signal, where no peaks could be detected, the following # will place a peak where the max value is and a minimum at the lowest value after # that peak. This will prevent some other empty trace errors for an otherwise # unusable result set. if len(maxima) == 0 and len(minima) == 0: maxima.append(numpy.argmax(dataArray[:-2])) lastMinimum=getIndexAtAmplitude(dataArray[maxima[0]:], 0, True) minima.append(maxima[0]+lastMinimum) return [minima, maxima]
def genHistoPeaks(colors): hist = np.histogram(colors, 1024) # peak histograms fh = filtfilt(*butter(3, 0.1), hist[0]) pk = peakdetect(fh, lookahead=20) return pk
with h5.File(fpath, 'r') as fd: kc_grp = fd['kc'] kcggn_grp = fd['kc_ggn'] kc_amp_scount = [] kcggn_amp_scount = [] amp_nodes = [] axes_stim.plot(fd['kc/amp_0'][2, :], fd['kc/amp_0'][0, :]) fig_stim.suptitle('Current injection') for name, node in kc_grp.items(): fields = [fname.decode() for fname in node.attrs['fields']] tidx = fields.index('t') vidx = fields.index('kc') v = node[vidx, :] t = node[tidx, :] peaks, troughs = peakdetect(v, x_axis=t, lookahead=20, delta=0.1 * np.std(v)) kc_amp_scount.append((node.attrs['amp'], len(peaks))) if (node.attrs['amp'] >= istart) and (node.attrs['amp'] <= iend): amp_nodes.append((node.attrs['amp'], name)) print(amp_nodes[-1]) amp_nodes = sorted(amp_nodes, key=lambda x: x[0]) fig_vm, axes_vm = plt.subplots(nrows=len(amp_nodes), ncols=2, sharex='all', sharey='all', frameon=False) print('Number of qualifying nodes for Vm plot', len(amp_nodes)) # Plot the KC Vm for ii in range(0, len(amp_nodes)): amp, node = amp_nodes[ii]
if '1.0 mV' == str(v.units): continue if np.isnan(v)[0] == True: continue protocol_type = 'Voltage_clamp' v = v.magnitude t = np.arange(0, len(v)/20000.0, 1.0/20000) v_filtered = signal.sosfilt(b_filter, v) aI, bI = 60000, 657000 T, V = t[aI:bI], v[aI:bI] ax1 = plt.subplot(211) ax1.plot(T, V, label = str(trace.name).split("-")[0]) ax1.legend() ax2 = plt.subplot(212) ax2.plot(t[aI:bI] , v_filtered[aI:bI] , label='filtered trace') ax2.legend() # PEAKS maxP, minP = analytic_wfm.peakdetect(v_filtered[aI:bI], t[aI:bI]) minP = [x for x in minP if abs(x[1]) > 10] x, y = zip(*minP) plt.plot(x, y, 'o') plt.tight_layout() plt.savefig('a.png')
def find_peaks(contours, baseline, wave_position, image, freq_line, ahead_sensitivity=0.1, delta_sensitivity=0.5): """ Identify peaks and troughs based on filtered contours. Parameters ---------- contours : array_like Filtered contours (x-coord, y-coord) baseline : int Y-coordinate of baseline. wave_position: string Position of waves relative to baseline ("up" or "down") image : array_like Processed image. freq_line : int Y-coordinate of the row at which wave peaks begin to separate. ahead_sensitivity : default=0.2 Proportion of the maximum vertical span of contour points that is used as the delta argument for the peakdetect function. delta_sensitivity : default=0.5 Proportion of span between min contour Y-value and max contour Y-value that is given as the delta parameter to the peakdetect function. Returns ------- peaks : array_like Array containing coordinates (x-coord, y-coord) of identified peaks troughs : array_like Array containing coordinates (x-coord, y-coord) of identified peaks """ # Set delta based on proportion of the vertical span of contours vertical_span = np.max(contours[:, 1]) - np.min(contours[:, 1]) delta_val = vertical_span * delta_sensitivity # Set lookahead based on frequency of waves at the blur threshold blur_row = image[freq_line, :] white_row = np.where(blur_row == 255) first_white = np.min(white_row) last_white = np.max(white_row) horizontal_span = last_white - first_white # Count consecutive black pixels in section of horizontal span blur_span = blur_row[first_white:last_white] condition = blur_span == 0 length, count = [], 0 for i in range(len(condition)): if condition[i]: count += 1 elif not condition[i] and count > 0: length.append(count) count = 0 if i == len(condition) - 1 and count > 0: length.append(count) if i == len(condition) - 1 and count == 0: length.append(0) long = [elem for elem in length if elem > 80] num_waves = len(long) # Set lookahead_val based on wave frequency if num_waves == 0: wave_freq = 400 else: wave_freq = horizontal_span / num_waves lookahead_val = int(round(wave_freq * ahead_sensitivity)) maxpeaks, minpeaks = peakdetect(y_axis=contours[:, 1], x_axis=contours[:, 0], lookahead=lookahead_val, delta=delta_val) # If no peaks or troughs found, try different delta sensitivity values delta_sens = delta_sensitivity while True: if bool(maxpeaks) and bool(minpeaks): break elif delta_sens <= 0.05: break else: delta_sens = delta_sens - 0.05 delta_val = vertical_span * delta_sens maxpeaks, minpeaks = peakdetect(y_axis=contours[:, 1], x_axis=contours[:, 0], lookahead=lookahead_val, delta=delta_val) # If no valid RRI, try changing lookahead sensitivity ahead_sense = ahead_sensitivity while True: if bool(maxpeaks): maxpeaks = np.vstack(maxpeaks) else: maxpeaks = None if bool(minpeaks): minpeaks = np.vstack(minpeaks) else: minpeaks = None if wave_position == WavePosition.UP: rri = calc_rri(peaks=minpeaks, troughs=maxpeaks, baseline=baseline, wave_position=wave_position) else: rri = calc_rri(peaks=maxpeaks, troughs=minpeaks, baseline=baseline, wave_position=wave_position) if np.mean(rri) != 0 and (len(minpeaks) == len(maxpeaks)): break elif ahead_sense <= 0.01: break else: ahead_sense = round(ahead_sense - 0.01, 2) lookahead_val = int(round(wave_freq * ahead_sense)) delta_val = vertical_span * delta_sensitivity maxpeaks, minpeaks = peakdetect(y_axis=contours[:, 1], x_axis=contours[:, 0], lookahead=lookahead_val, delta=delta_val) if type(maxpeaks) != np.ndarray: maxpeaks = None if type(minpeaks) != np.ndarray: minpeaks = None if wave_position == WavePosition.UP: peaks = minpeaks troughs = maxpeaks else: peaks = maxpeaks troughs = minpeaks return peaks, troughs
def getStartPeakEnd(dataArray): minima = numpy.array([], dtype=numpy.integer) maxima = numpy.array([], dtype=numpy.integer) reverseMinima = numpy.array([], dtype=numpy.integer) # First we get the regular max and min using peak detection #peaksMax, peaksMin = peakdetect(dataArray, lookahead=peakDetectLookAhead, delta=peakDetectDelta) peaksMax, peaksMin = peakdetect(dataArray, lookahead=peakDetectLookAhead) #peaksMax, peaksMin = peakdetect(dataArray) maxima = numpy.array([p[0] for p in peaksMax]) minima = numpy.array([p[0] for p in peaksMin]) # If the first minima is before the first maxima, then we need to shift it over # so we are always start with a max peak, as we will be looking for decay information. while len(minima) > 0 and len(maxima) > 0 and minima[0] < maxima[0]: minima = minima[1:] # We need the reverseMinima, maxima, and minima to be the same size to we don't get any out of bounds errors smallestAmount = min([len(maxima), len(minima)]) while (len(maxima) > smallestAmount): maxima = maxima[:-1] while (len(minima) > smallestAmount): minima = minima[:-1] if printVerbose == True: print "getStartPeakEnd - maxima: {0}".format(maxima) print "getStartPeakEnd - minima: {0}".format(minima) if len(maxima) > 0 and len(minima) > 0: newDelta = abs( numpy.average(numpy.abs(dataArray[minima] - dataArray[maxima])) / 10) if printVerbose == True: print "getStartPeakEnd - ewDelta: {0}".format(newDelta) if newDelta and ~numpy.isnan(newDelta): #peaksMax, peaksMin = peakdetect(dataArray, lookahead=peakDetectLookAhead, delta=newDelta) peaksMax, peaksMin = peakdetect(dataArray, lookahead=peakDetectLookAhead) maxima = numpy.array([p[0] for p in peaksMax]) minima = numpy.array([p[0] for p in peaksMin]) # In order to get the beginning of the peak, we reverse the wave form, and then capture the minima #peaksMax, peaksMin = peakdetect(dataArray[::-1], lookahead=peakDetectLookAhead, delta=newDelta) peaksMax, peaksMin = peakdetect(dataArray[::-1], lookahead=peakDetectLookAhead) reverseMinima = numpy.array([p[0] for p in peaksMin]) reverseMinima = (len(dataArray) - 1) - reverseMinima reverseMinima = reverseMinima[::-1] else: # In order to get the beginning of the peak, we reverse the wave form, and then capture the minima peaksMax, peaksMin = peakdetect(dataArray[::-1], lookahead=peakDetectLookAhead) reverseMinima = numpy.array([p[0] for p in peaksMin]) reverseMinima = (len(dataArray) - 1) - reverseMinima reverseMinima = reverseMinima[::-1] # Ideally, the returned data should be in the order of start, peak, and end # Thus, we need to remove data points that do not conform to that pattern in the beginning and end. # First, we check to make sure that the first maxima comes after the first reverseMinima while len(reverseMinima) > 0 and len( maxima) > 0 and reverseMinima[0] > maxima[0]: maxima = maxima[1:] # If the first minima is before the first maxima, then we need to shift it over # so we are always start with a max peak, as we will be looking for decay information. while len(minima) > 0 and len(maxima) > 0 and minima[0] < maxima[0]: minima = minima[1:] # We need the reverseMinima, maxima, and minima to be the same size to we don't get any out of bounds errors smallestAmount = min([len(reverseMinima), len(maxima), len(minima)]) while (len(reverseMinima) > smallestAmount): reverseMinima = reverseMinima[:-1] while (len(maxima) > smallestAmount): maxima = maxima[:-1] while (len(minima) > smallestAmount): minima = minima[:-1] fixedMinima = getFixedPeakEnd(reverseMinima, maxima, minima, dataArray) return [fixedMinima, reverseMinima, maxima, minima]