def peak_search_example(): # implementation of the peak search example in # https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_widths.html from scipy.signal import chirp, find_peaks, peak_widths x = np.linspace(0, 6 * np.pi, 1000) x = np.sin(x) + 0.6 * np.sin( 2.6 * x) # Create a test signal with two overlayed harmonics # Find all peaks and calculate their widths at the relative height of 0.5 # (contour line at half the prominence height) and 1 (at the lowest contour line at full prominence height) peaks, _ = find_peaks(x) results_half = peak_widths(x, peaks, rel_height=0.5) results_half[0] # widths print(results_half[0]) results_full = peak_widths(x, peaks, rel_height=1) results_full[0] # widths # Plot signal, peaks and contour lines at which the widths where calculated plt.plot(x) plt.plot(peaks, x[peaks], "x") plt.hlines(*results_half[1:], color="C2") #plt.hlines(*results_full[1:], color="C3") plt.show()
def to_dataframe(result, meta, directory, line_num="average", save=False): peaks, _ = find_peaks(-result, distance=50) SS = peak_prominences(-result, peaks, wlen = 70) CD50 = peak_widths(-result, peaks, rel_height=0.5, prominence_data=SS) CD90 = peak_widths(-result, peaks, rel_height=0.9, prominence_data=SS) time_frame = meta['Timepoint'][-1]/600 *100 max_contract = [] max_relax = [] for i in range (len(peaks)): max_contract.append(np.max(np.diff(-result[SS[1][i]:peaks[i]]))*time_frame) max_relax.append(np.min(np.diff(-result[peaks[i]:SS[2][i]:]))*time_frame) df = pd.DataFrame(result[SS[1]], columns = ['Basal length']) df['Peak length in um'] = result[peaks] df['Time to peak in msec'] = peaks*time_frame - SS[1]*time_frame df['CD90 in msec'] = CD90[0] * time_frame df['CD50 in msec'] = CD50[0] * time_frame df['Max contractile in um/msec'] = max_contract df['Max relaxation in um/msec'] = max_relax int_peak = np.zeros(len(peaks), 'int') int_peak[1:] = np.diff(peaks) df['Peak intervals in ms'] = int_peak *time_frame beat_rate = np.zeros(len(peaks)) beat_rate[1:] = 6000/((np.diff(peaks)*time_frame)/2) df['Beating rate in beat/min'] = beat_rate if save == True: try: df.to_csv(directory+'/'+'line'+line_num+'_'+'{}.csv'.format(meta["Name"])) except FileNotFoundError: df.to_csv('line'+line_num+'_'+'{}.csv'.format(meta["Name"])) return df
def shiftFlatTop(xscale, data, method=1): if method == 1: loc, width, height = genGuessGaussian(xscale, data) guess = [width, loc, height, 0, height / 1.1] peak_idx, properties = find_peaks(data, height=np.amax(data)) width_info = peak_widths(data, peak_idx) width_idx = width_info[0] s = slice(int(peak_idx - 3 * width_idx), int(peak_idx + 3 * width_idx)) _x = xscale[s] _data = data[s] params, error, resid = fitFlatTopGaussian(_x, _data, guess, plot=True, verbose=False) mean = params[1] x_shift = xscale - mean else: loc, width, height = genGuessGaussian(xscale, data) guess = [width / 3, width / 3.5, loc, 2 * height * width, 0, 0] peak_idx, properties = find_peaks(data, height=np.amax(data)) width_info = peak_widths(data, peak_idx) width_idx = width_info[0] s = slice(int(peak_idx - 3 * width_idx), int(peak_idx + 3 * width_idx)) _x = xscale[s] _data = data[s] params, error, resid = fitVoigtLinBG(_x, _data, guess, plot=True, verbose=False) mean = params[2] x_shift = xscale - mean return x_shift
def find_curves(distribution): """Receives a "continuous" function data and returns it's peaks and widths. Assumes simmetry from peaks.""" peaks_idx, _ = find_peaks(distribution, distance=5 ) half = peak_widths(distribution, peaks_idx, rel_height=0.5)[:2] full = peak_widths(distribution, peaks_idx, rel_height=1)[:2] return (peaks_idx, half, full)
def findpeak(self, hthres=0, pthres=0): ''' hthresh and pthres are measured in how many std the height (or the prominence) of the peak is computed. The height of the peak is computed with respect to the mean of the signal ''' index = np.ones(1) index_final = np.array([], dtype='int') ledge = np.array([], dtype='int') redge = np.array([], dtype='int') count = 0 while len(index) > 0: print index_final print ledge, redge if np.size(index_final) != 0: for i in range(len(index_final)): data_masked[ledge[i]:redge[i]] = ( data_masked[ledge[i]] + data_masked[redge[i]]) / 2. else: data_masked = self.data.copy() y_std = np.std(data_masked) y_mean = np.mean(data_masked) print y_std, y_mean if count >= 2: sys.exit() if hthres != 0 and pthres == 0: index, param = sgn.find_peaks(data_masked, height=y_mean + hthres * y_std, distance=100) elif pthres != 0 and hthres == 0: index, param = sgn.find_peaks(data_masked, prominence=pthres * y_std) elif hthres != 0 and pthres != 0: index, param = sgn.find_peaks(data_masked, height = y_mean + hthres*y_std, \ prominence = pthres*y_std) plt.plot(data_masked) plt.plot(index, self.data[index], 'x') plt.show() ledget = sgn.peak_widths(data_masked, index)[2] redget = sgn.peak_widths(data_masked, index)[3] index_final = np.append(index_final, index.astype(int)) ledge = np.append(ledge, np.floor(ledget).astype(int)) redge = np.append(redge, np.ceil(redget).astype(int)) count += 1 self.peakind = index_final.copy() return self.peakind
def get_features(df): """Get features from sensor data For each sensor, peaks, promenences and periodograms features are computed. Parameters: df: pd.DataFrame Dataframe with 10 columns, corresponding to data from sensors Returns: features: list List with features """ features = [] # zeros_crossings features.extend(librosa.zero_crossings(df.values, axis=0).sum(axis=0)) # find_peaks features.extend(df.apply(find_peaks, axis=0).iloc[0, :].apply(len).values) # peak_widths_max λ0 = lambda x: np.max(peak_widths(x, find_peaks(x)[0])[0]) if len( find_peaks(x)[0]) != 0 else 0 features.extend(df.apply(λ0).values) # peak_widths_mean λ01 = lambda x: np.mean(peak_widths(x, find_peaks(x)[0])[0]) if len( find_peaks(x)[0]) != 0 else 0 features.extend(df.apply(λ01).values) # peak_prominences_max λ1 = lambda x: np.max(peak_prominences(x, find_peaks(x)[0])[0]) if len( find_peaks(x)[0]) != 0 else 0 features.extend(df.apply(λ1).values) # peak_prominences_mean λ11 = lambda x: np.mean(peak_prominences(x, find_peaks(x)[0])[0]) if len( find_peaks(x)[0]) != 0 else 0 features.extend(df.apply(λ11).values) # periodogram_max λ2 = lambda x: np.max(periodogram(x[~x.isna()], 100)[1]) if ~x.isna().all( ) else 0 features.extend(np.sqrt(df.apply(λ2).values)) # Es un estimado del RMS # periodogram_mean λ3 = lambda x: np.mean(periodogram(x[~x.isna()], 100)[1]) if ~x.isna().all( ) else 0 features.extend(df.apply(λ3).values) return features
def lmfit_voigt_startparams(data, peaks): global values values = [ 'amplitude', 'xcenter', 'ycenter', 'xsigma', 'ysigma', 'xgamma', 'ygamma', 'angle', 'eta' ] startparams = pd.DataFrame(data=[[ 0.0, ] * len(values)], index=[ 'model0_', ], columns=values) costrains = pd.DataFrame(data=[[np.inf, 0, False], [np.inf, 0, False], [np.inf, 0, False], [np.inf, 0, False], [np.inf, 0, False], [np.inf, 0, False], [np.inf, 0, False], [np.pi, -np.pi, False], [1, 0, False]], index=values, columns=('max', 'min', 'vary')) for i in range(len(peaks[0])): amplitude = data[2][peaks[0][i]][peaks[1][i]] xcenter = data[0][peaks[0][i]][peaks[1][i]] ycenter = data[1][peaks[0][i]][peaks[1][i]] omegapeakposi = peak_widths(data[2].T[peaks[1][i]], [ peaks[0][i], ]) omegapeak_width = abs( data[0][fine_round(omegapeakposi[3])][peaks[1][i]] - data[0][fine_round(omegapeakposi[2])][peaks[1][i]]) twothetapeakposi = peak_widths(data[2][peaks[0][i]], [ peaks[1][i], ]) twothetapeak_width = abs( data[1][peaks[0][i]][fine_round(twothetapeakposi[2])] - data[1][peaks[0][i]][fine_round(twothetapeakposi[3])]) xsigma = omegapeak_width / (2 * np.sqrt(2 * np.log(2))) xgamma = omegapeak_width ysigma = twothetapeak_width / (2 * np.sqrt(2 * np.log(2))) ygamma = twothetapeak_width angle = np.pi / 2 eta = 0 name = 'model' + str(i) + '_' startparams.loc[name] = [ amplitude, xcenter, ycenter, xsigma, ysigma, xgamma, ygamma, angle, eta ] return startparams, costrains
def __call__(self, image, IIR): result = None #validating that we're getting the correct number of pixels if(image is not None): # check if IIR exists if IIR is None: IIR = np.zeros(image.shape, dtype=image.dtype) # do the matchy filter and normalize delayed_denominator = self.delayed_denominator if self.delayed_denominator is None: delayed_denominator = np.ones(image.shape, dtype=image.dtype) convolved = np.convolve( \ (image-IIR)/ delayed_denominator, \ self.kernel) convolved /= np.max(convolved) # get first peak and its fwhm first_peak = np.argmax(convolved) first_fwhms = peak_widths(convolved, [first_peak], rel_height=0.5) # find more peaks by looking at anything > 25% of the first peak amplitude height = self.height * convolved[first_peak] peaks, _ = find_peaks(convolved, height=height, distance=first_fwhms[0][0]*2) peaks_amp = convolved[peaks] sort_indices = np.flip(np.argsort(peaks_amp)) peaks_sort = peaks[sort_indices] peaks_amp_sort = peaks_amp[sort_indices] results_half = peak_widths(convolved, peaks_sort, rel_height=0.5) # check if we have second peak amplitude_next = None if len(peaks_sort) > 1: amplitude_next = peaks_amp_sort[1] # gather result result = EdgeFinderResult(edge=peaks_sort[0], \ amplitude=peaks_amp_sort[0], \ fwhm=first_fwhms[0][0], \ amplitude_next=amplitude_next, \ ref_amplitude=np.mean(IIR), \ convolved=convolved, \ results_half=results_half) return result
def FindMargins(img): intensity_hist = cv2.reduce(img, 0, cv2.REDUCE_SUM, dtype=cv2.CV_32S).T ## smoothen the intensity histogram using savgol to avoid noise x = np.reshape(intensity_hist, len(intensity_hist)) window_size = int(img.shape[1]/22) ## magic num! if (window_size%2 == 0): window_size = window_size+1 intensity_hist_s = ss.savgol_filter(x, window_size, 5) intensity_hist_s = intensity_hist_s.astype(int) ## TODO reexamine prominence here - not same as for horizontal lines can be a stricter bound maxval = np.max(intensity_hist_s) peaks, _ = ss.find_peaks(intensity_hist_s, prominence=maxval/10, distance=10) """ plt.figure(figsize=(10,5)) plt.xticks(range(0, img.shape[1], int(img.shape[1]/10))) plt.xlim([0, img.shape[1]]) plt.plot(intensity_hist) plt.plot(intensity_hist_s, color='green') plt.plot(peaks, intensity_hist[peaks], "x") plt.show() """ data = ss.peak_widths(intensity_hist_s, peaks, rel_height=1) #print('peak width data', data) widest_peak_index = np.argmax(data[0]) #print('widest peak index', widest_peak_index) left_index = data[2][widest_peak_index] right_index = data[3][widest_peak_index] return int(left_index), int(right_index)
def get_peak_fwhm(se_hist_tof): """get the fwhm of a peak Arguments: se_hist_tof {[pandas.Series]} -- [the index is the time difference in picoseconds, the value is the counts for each time diff.] path_save_img {[string]} -- [the pave for the saved image] Returns: [ndarray] -- [return:4*N array, where N is the number of peiclo: 0::FWHM, 1:heigh of the FWHM, 3: left pos;4: right pos] """ #get the max of the series values. tof_max=se_hist_tof.max() # peaks, _ = find_peaks(se_hist_tof.values) ar_width=np.array(se_hist_tof.index.array) peak_prominence=tof_max-100 peaks, _ = find_peaks(se_hist_tof.values,width=ar_width,prominence=peak_prominence) """find the peaks of the curve. 1: the width parameter does not work accordingly. the peak index is always from 0~length. 2: the prominence parameter is used to make sure only choose the most prominent peak. Otherwise there will be a lot of peaks. Returns: [type] -- [the positions of all the peaks] """ peak_fwhm_pos=peak_widths(se_hist_tof.values,peaks,rel_height=0.5) """get the widths of all the peaks Returns: [multi-dimention arrays,4*N] -- [where N is the number of peiclo: 0::FWHM, 1:heigh of the FWHM, 3: left pos;4: right pos] """ # print(se_hist_tof.values.shape) print(peak_fwhm_pos) return peak_fwhm_pos
def find_temp_peak(baseline_array, height=2, prominence=1, **kwargs): ''' Funciton to evaluate the Delta Temperature curve obtained from the subtraction of the baseline. The peak(s) of the curve are determined, as well as their width to extract their onset. Parameters ---------- baseline_array : pd.Series Delta Temperature curve obtained from the subtraction of the baseline heigth : int Minimum height of the peaks in the delta temperature curve prominence : int minimum prominence of the peaks in the delta temperature curve Returns ------- peak_left_onset : list List containing the index of the left-side onset of the peak(s) peak_max : list List containing the index of the peak(s) ''' peaks, properties = find_peaks(baseline_array, height=height, prominence=prominence, **kwargs) peak_left_onset = [] peak_max = [] for i in range(len(peaks)): peaks_w = peak_widths(baseline_array, [peaks[i]]) peak_left_onset.append(int(round(peaks_w[2][0]))) peak_max.append(peaks[i]) return peak_left_onset, peak_max
def get_peaks(self): ''' finds and labels the peaks of each 1D slice of spectrogram. These are the locations of the modes. ''' peaks_map = np.zeros_like(self.arr[1].T) peaks_index = [] widths_list = [] Height_list = [] time_index = [] for i in range(len(self.arr[1][0])): slce = self.arr[1][:, i] # These properties can be tweaked to fine-tune the results. smooth_arr = gaussian_filter1d(slce, 10) peaks, properties = find_peaks(smooth_arr, prominence=(np.mean( abs(smooth_arr)), None), distance=75, height=0, width=0) widths = peak_widths(smooth_arr, peaks, rel_height=0.5) Height_list.append(properties['peak_heights'].tolist()) peaks_index.append(peaks.tolist()) widths_list.append(widths[0].tolist()) time_index.append([i] * len(peaks.tolist())) for e, w in enumerate( zip(properties['left_ips'], properties['right_ips'])): peaks_map[i][round(w[0]):round(w[1])] = properties[ 'width_heights'][e] peaks_map[i][peaks] = properties['peak_heights'] Height_list = np.asarray(Height_list, dtype=object) peaks_index = np.asarray(peaks_index, dtype=object) widths_list = np.asarray(widths_list, dtype=object) time_index = np.asarray(time_index, dtype=object) return time_index, peaks_index, widths_list, Height_list, peaks_map
def max_peak_width(show=True): p = plot() signals, names = plot_signals(show=False) crack_lengths = CL_by_cycle(show=False) for plate_signals, plate_names, cracks in zip(signals, names, crack_lengths): x = [] y = [] for signal, cycle_name, crack in zip(plate_signals, plate_names, cracks): n = int(cycle_name[3:]) peaks, _ = sig.find_peaks(signal['ch2']) widths = sig.peak_widths(signal['ch2'], peaks, rel_height=1.0) x.append(crack[0,1]) y.append(np.max(widths)) if show: p.plot_one_series(x, y, label = cycle_name[:2]) if show: p.label_axes("Crack length (mm)", "Largest peak width") p.show_plot() p.close()
def peak_width(self, peaks, hthres=5, pthres=0, window=100): ''' Function to estimate the width of the peaks. Window is the parameter used by the algorith to find the minimum left and right of the peak. The minimum at left and right is used to compute the width of the peak ''' #peaks = self.findpeak(hthres=hthres, pthres=pthres) y_mean = np.mean(self.data) if np.amin(self.data) > 0: data_to_despike = self.data - y_mean else: data_to_despike = self.data.copy() param = sgn.peak_widths(np.abs(data_to_despike), peaks, rel_height=1.0) ledge = np.array([], dtype='int') redge = np.array([], dtype='int') for i in range(len(peaks)): left_edge, = np.where(np.abs(data_to_despike[peaks[i]-window:peaks[i]]) == \ np.amin(np.abs(data_to_despike[peaks[i]-window:peaks[i]]))) right_edge, = np.where(np.abs(data_to_despike[peaks[i]:peaks[i]+window]) == \ np.amin(np.abs(data_to_despike[peaks[i]:peaks[i]+window]))) left_edge += (peaks[i] - window) right_edge += peaks[i] ledge = np.append(ledge, left_edge[-1]) redge = np.append(redge, right_edge[-1]) print('INDEX', i, peaks[i], left_edge, right_edge) print('PEAKS', left_edge, right_edge, peaks[i]) print(len(peaks), len(ledge), len(redge)) return param[0].copy(), ledge, redge
def find_curves(distribution, count=2): """Receives a "continuous" function data and returns it's peaks and widths. Assumes simmetry from peaks.""" peaks_idx, _ = find_peaks(distribution) peaks_idx = peaks_idx[distribution[peaks_idx].argsort()[-count:][::-1]] half = peak_widths(distribution, peaks_idx, rel_height=0.5)[:2] return (peaks_idx, half)
def auto_peak_find(self): self.df_new = [] peaks, _ = find_peaks(self.A, height=0.01) width_parameters = peak_widths(self.A, peaks, rel_height=0.5) widths = np.empty(len(peaks)) heights = np.empty(len(peaks)) pks = np.empty(len(peaks)) index = np.empty(len(peaks)) for ii in range(0, len(peaks)): widths[ii] = np.abs( self.unit_conversion(self.wL[int(width_parameters[2][ii])], self.output_units, 'eV') - self.unit_conversion(self.wL[int(width_parameters[3][ii])], self.output_units, 'eV')) heights[ii] = self.A[peaks[ii]] pks[ii] = self.wL[peaks[ii]] index[ii] = peaks[ii] self.df_new = pd.DataFrame({ 'index': index, 'w0': pks, 'height': heights, 'fwhm': widths }) self.df_new = self.df_new.sort_values(['height'], ascending=False) self.df_new = self.df_new.reset_index(drop=True) self.df_og = self.df_new
def find_real_peaks(hist_norm, min_relhight=0.01): """ 定位波峰 T=0.0004 :param hist_norm: ndarray 归一化的直方图 :return: real_peaks_idx ndarray 波峰在直方图中的横坐标 """ rel_max, = argrelmax(hist_norm, order=3) # 极大值横坐标 # Calculate the prominence of each peak in a signal. # 如果 prominences 的值(这里指的是元素的值) 小于了 0.001就不算一个peak widths, width_heights, left_ips, right_ips = peak_widths(hist_norm, rel_max, rel_height=0.618) # width_heights is the height of the contour lines at which the widths where evaluated. # calculate contour_width_heights by width_heights and peak heights # 如果 contour_width_heights 的值(这里指的是元素的值) 小于了 0.001就不算一个peak, 因为这个值是"半"峰高 contour_width_heights = hist_norm[rel_max] - width_heights # all_areas = widths * width_heights # 这个作为计算峰面积不合适 all_areas = widths * contour_width_heights # 半峰高和 max_hist = hist_norm.max() print('max_hist={}, 0.01 * max_hist={}, 0.1 * max_hist={}'.format( max_hist, 0.01 * max_hist, 0.1 * max_hist)) temp_idx1 = contour_width_heights > 0.01 * max_hist temp_idx2 = all_areas > 0.1 * max_hist temp_idx = np.where(temp_idx1 & temp_idx2) real_peaks_idx = rel_max[temp_idx] # print('real_peaks_idx={}'.format(real_peaks_idx)) print('width_height={}'.format(width_heights[temp_idx])) print('contour_width_heights={}'.format(contour_width_heights[temp_idx])) print('widths={}'.format(widths[temp_idx])) print('areas={}'.format(all_areas[temp_idx])) print('real_peaks_idx={}'.format(real_peaks_idx)) return real_peaks_idx
def _spike_widths(self): """Find spike widths and translate to physical units.""" # obtain data about width of spikes; note that returned widths will be # in terms of index positions in voltage array spikes_width_data = peak_widths( self._V, self._spikes_ind, rel_height=0.5) # retrieve left and right interpolated positions specifying horizontal # start and end positions of the found spike widths left_ips, right_ips = spikes_width_data[2:] # membrane potential as interpolation function V_interpolate = interp1d(x=self._ind_arr, y=self._V) # voltage spike width in terms of physical units (instead of position # in array) self._V_spike_widths = V_interpolate( right_ips) - V_interpolate(left_ips) # prepare spike width data for plotting in terms of physical units: # time as interpolation function time_interpolate = interp1d(x=self._ind_arr, y=self._time) # interpolated width positions in terms of physical units left_ips_physical = time_interpolate(left_ips) right_ips_physical = time_interpolate(right_ips) # the height of the contour lines at which the widths where evaluated width_heights = spikes_width_data[1] # assemble data of contour lines at which the widths where calculated self._spikes_width_data_physical = ( width_heights, left_ips_physical, right_ips_physical)
def get_jet_width(im, rho, theta): """ Calculate the jet width. Parameters ---------- img : ndarray ROI of the on-axis image. rho : float Distance from (0,0) to the line in pixels. theta : float Angle of the shortest vector from (0,0) to the line in radians. Returns ------- w : float Jet width in pixels. """ rows, column_indices = np.ogrid[:im.shape[0], :im.shape[1]] r = np.asarray([ int((rho + y * np.sin(theta)) / np.cos(theta)) for y in range(im.shape[0]) ]) r = r % im.shape[1] column_indices = column_indices - r[:, np.newaxis] s = im[rows, column_indices].sum(axis=0) return peak_widths(s, [s.argmax()])[0]
def _turn_intervals_to_Event(event, serie): ''' Find events in a temporal interval that contain one or several events ''' spec = { 'time': np.arange(0, len(serie[event.begin:event.end])), 'y': serie[event.begin:event.end].values, 'model': [{ 'type': 'GaussianModel' }, { 'type': 'GaussianModel' }, { 'type': 'GaussianModel' }, { 'type': 'GaussianModel' }, { 'type': 'GaussianModel' }] } model, params = _generate_model(spec) output = model.fit(spec['y'], params, x=spec['time']) fitted_integral = output.best_fit pos = find_peaks(fitted_integral)[0] width = peak_widths(fitted_integral, pos) ref_index = serie[event.begin:event.end].index clouds = [ evt.Event(ref_index[int(width[2][x])], ref_index[int(width[3][x])]) for x in np.arange(0, len(width[0])) ] return clouds
def streak_angle_raw(self): """ Jet streak calculation Returns: jet angle, jet intensity (as standard deviations from the mean), jet width """ import numpy as np from scipy.signal import peak_widths im1 = self.corr[1,-100:,:100] im2 = self.corr[17,-100:,:100] proj1 = np.zeros((100,80)) proj2 = np.zeros((100,80)) for a in range(-40,40): for i in range(im1.shape[0]): proj1[i,a+40]=im1[i,self.proj_map_1[i,a+40]] proj2[i,a+40]=im2[i,self.proj_map_2[i,a+40]] s = proj1.sum(axis=0)+proj2.sum(axis=0) s -= s.mean() s /= np.roll(s,10-s.argmax())[20:].std() peak = s[1:-1].argmax()+1 try: peakwidth = peak_widths(s, [peak])[0][0] except Exception as e: peakwidth = 5 return (np.pi*(peak-40)/360.0, s.max(), peakwidth)
def find_bragg_peak_rc(q, cps): #use for substrate peaks actually orig_peaks = find_peaks_cwt(cps, np.linspace(1, 10, num=50)) widths, width_heights, left_ips, right_ips = peak_widths(cps, orig_peaks, rel_height=.999) print(widths) plt.figure() plt.plot(q, cps) plt.plot(q[orig_peaks], cps[orig_peaks], "x") plt.hlines(width_heights, q[left_ips.astype(np.int)], q[right_ips.astype(np.int)]) plt.yscale("log") #create an array of the values of the peaks loc_max_vals = cps[orig_peaks] #find the two highest peak values max_1_val = heapq.nlargest(1, loc_max_vals) #find the position of the array containing the values of the peaks associated with the highest peak (also corresponds to position #in array of positions of peak values in first_deriv) loc_max_pos_1 = np.where( loc_max_vals == max_1_val[0]) #find position of highest peak in first_deriv array peaks_pos_1 = orig_peaks[loc_max_pos_1] return left_ips[loc_max_pos_1].astype(np.int), right_ips[loc_max_pos_1].astype(np.int)
def FWHM(freq_f, timestep): """ Find the Full Width Half Max of a function by returning the width at the halfway point of the highest peak in the frequency domain. Parameters ---------- freq_f : np.ndarray one-dimensional frequency-domain data timestep : float/int incremental change in the independent variable Returns ------- FWHM : float/int the full width half max of the signal in the frequency domain """ length = len(freq_f) PS = np.real(freq_f * np.conj(freq_f) / length) freq = np.real(fftfreq(length) * 2 * np.pi / timestep) L = np.arange(1, np.floor(length / 2), dtype='int') peaks, _ = find_peaks(PS[L]) sf = abs(freq[L][0] - freq[L][1]) results_half = peak_widths(PS[L], peaks, rel_height=0.5) FWHM = results_half[0][np.where( results_half[1] == max(results_half[1]))] * sf FWHM = FWHM[0] return FWHM
def find_fraunhofer_center(field: np.ndarray, ic: np.ndarray, debug: bool = False) -> float: """Extract the field at which the Fraunhofer is centered. Parameters ---------- field : np.ndarray 1D array of the magnetic field applied of the JJ. ic : np.ndarray 1D array of the JJ critical current. Returns ------- float Field at which the center of the pattern is located. """ max_loc = np.argmax(ic) width, *_ = peak_widths(ic, [max_loc], rel_height=0.5) width_index = int(round(width[0] * 0.65)) subset_field = field[max_loc - width_index:max_loc + width_index + 1] subset_ic = ic[max_loc - width_index:max_loc + width_index + 1] model = GaussianModel() params = model.guess(subset_ic, subset_field) out = model.fit(subset_ic, params, x=subset_field) if debug: plt.figure() plt.plot(field, ic) plt.plot(subset_field, out.best_fit) plt.show() return out.best_values["center"]
def Peak_locate(y, dis, prom, width, bincenters): """ The parameters below will need to be adjusted depending on the source you are using. You will need to look at the inital histogram to make a guess for the parameters. IF you're using Na22. The parameters should need not be adjusted. Parameters: Y: histogrammed data. dis: distance between peaks. Will only look at peaks that are further apart than 'distance' prom: 'height' of peak. Only looks at peaks with a height greater than 'prominance' wid: minimum width of peaks to look for. Only looks at peaks with a width greater than 'width' bincenters: x-axis values returned from histogramming the data spectrum """ Y = y peaks, properties = find_peaks(Y, distance=dis, prominence=prom, width=width) widths = peak_widths(Y, peaks) #inital peak width guess amp = y[peaks] #intial peak amplitude guess ADC_loc = [] # inital peak location guess for x in peaks: a = bincenters[x] ADC_loc.append(a) return ADC_loc, peaks, widths, amp
def estimate_peak_width(data, mask=None): """ Estimates the FWHM of the spectral features (arc lines) by inspecting pixels around the brightest peaks. Parameters ---------- data : ndarray 1D data array mask : ndarray/None mask to apply to data Returns ------- float : estimate of FWHM of features in pixels """ if mask is None: goodpix = np.ones_like(data, dtype=bool) else: goodpix = ~mask.astype(bool) widths = [] niters = 0 while len(widths) < 10 and niters < 100: index = np.argmax(data * goodpix) with warnings.catch_warnings(): # width=0 warnings warnings.simplefilter("ignore") width = signal.peak_widths(data, [index], 0.5)[0][0] # Block 2 * FWHM hi = int(index + width + 1.5) lo = int(index - width) if all(goodpix[lo:hi]) and width > 0: widths.append(width) goodpix[lo:hi] = False niters += 1 return sigma_clip(widths).mean()
def get_jet_width(im, rho, theta): '''Calculates the jet width Parameters ---------- img : ndarray ROI of the on-axis image rho : float Distance from (0,0) to the line in pixels theta : float Angle of the shortest vector from (0,0) to the line in radians Returns ------- w : float Jet width in pixels ''' import numpy as np from scipy.signal import peak_widths rows, column_indices = np.ogrid[:im.shape[0], :im.shape[1]] r = np.asarray([ int((rho + y * np.sin(theta)) / np.cos(theta)) for y in range(im.shape[0]) ]) r = r % im.shape[1] column_indices = column_indices - r[:, np.newaxis] s = im[rows, column_indices].sum(axis=0) w = peak_widths(s, [s.argmax()])[0] return w
def peak_feature_extracter(signal, window_size, stride): feature = [] for start in range(0, len(signal), stride): if len(signal) < start + window_size: break ts_range = signal[start:start + window_size] # calculate peak feature peaks, _ = find_peaks(ts_range, threshold=0.05) if len(peaks) == 0: num_of_peaks = 0. min_width_of_peak = 0. max_width_of_peak = 0. mean_width_of_peak = 0. std_width_of_peak = 0. min_height_of_peak = 0. max_height_of_peak = 0. mean_height_of_peak = 0. std_height_of_peak = 0. min_prominence = 0. max_prominence = 0. mean_prominence = 0. std_prominence = 0. else: widths = peak_widths(ts_range, peaks, rel_height=0.5) num_of_peaks = len(peaks) / len(ts_range) min_width_of_peak = np.min(widths[0]) / 100 max_width_of_peak = np.max(widths[0]) / 100 mean_width_of_peak = np.mean(widths[0]) / 100 #std_width_of_peak = np.std(widths[0])/100 min_height_of_peak = np.min(widths[1]) max_height_of_peak = np.max(widths[1]) mean_height_of_peak = np.mean(widths[1]) #std_height_of_peak = np.std(widths[1]) prominences = peak_prominences(ts_range, peaks)[0] min_prominence = np.min(prominences) max_prominence = np.max(prominences) mean_prominence = np.mean(prominences) #std_prominence = np.std(prominences) feature.append( np.asarray([ num_of_peaks, min_width_of_peak, max_width_of_peak, mean_width_of_peak, #std_width_of_peak, min_height_of_peak, max_height_of_peak, mean_height_of_peak, #std_height_of_peak, min_prominence, max_prominence, mean_prominence #std_prominence ])) return feature
def streak_angle_raw(self): """ Jet streak calculation Returns: jet angle, jet intensity (as standard deviations from the mean), jet width """ sq = 0 asic = self.asic im1 = asic[sq][-100:, :100] im2 = asic[(sq + 2) % 4][-100:, :100] proj1 = np.zeros((100, 80)) proj2 = np.zeros((100, 80)) for a in range(-40, 40): for i in range(im1.shape[0]): proj1[i, a + 40] = im1[i, self.proj_map_1[i, a + 40]] proj2[i, a + 40] = im2[i, self.proj_map_2[i, a + 40]] s = proj1.sum(axis=0) + proj2.sum(axis=0) s -= s.mean() s /= np.roll(s, 10 - s.argmax())[20:].std() peak = s[1:-1].argmax() + 1 try: peakwidth = peak_widths(s, [peak])[0][0] except Exception: peakwidth = 5 return (np.pi * (peak - 40) / 360.0, s.max(), peakwidth)
def delete_lowest_valued_peaks_mask(frame, num_peaks=1, display_plots=False, title=None, label='1', color='blue'): """ Returns a mask for the frame that deletes the num_peaks lowest-valued peaks in the histogram of pixel values. Only works for grayscale/1-channel images (to speed this up) """ # Some semi-thresholded values :) num_bins = max(int((np.amax(frame) - np.amin(frame)) / 4), 10) hist, bins = np.histogram(frame, bins=num_bins) hist[0] = 0 # get rid of stuff that was thresholded to 0 peaks, properties = find_peaks(hist, prominence=100) widths = peak_widths(hist, peaks, rel_height=peak_width_height)[0] if len(peaks) > 0: i = 0 mask = cv2.bitwise_not( cv2.inRange( frame, (bins[peaks[i]] + bins[peaks[i] + 1]) // 2 - widths[i] * 2, (bins[peaks[i]] + bins[peaks[i] + 1]) // 2 + widths[i] * 2)) # To support deleting multiple peaks for j in range(num_peaks - 1): i = j + 1 if len(peaks) > i: mask = cv2.bitwise_and( cv2.bitwise_not( cv2.inRange( frame, (bins[peaks[i]] + bins[peaks[i] + 1]) // 2 - widths[i] * 2, (bins[peaks[i]] + bins[peaks[i] + 1]) // 2 + widths[i] * 2)), mask) else: mask = np.ones(frame.shape, np.uint8) # frame = cv2.bitwise_and(frame, frame, mask=mask) if display_plots: fig = plt.figure(hash(title)) plt.clf() ax = plt.gca() ax.set_xlim([0, 255]) # Plot values in this channel plt.plot(bins[1:], hist, label=label, color=color) # Plot peaks plt.plot(bins[peaks + 1], hist[peaks], "x") # Plot peak widths plt.hlines(hist[peaks] * 0.9, bins[peaks + 1] - widths // 2, bins[peaks + 1] + widths // 2) plt.title(title) plt.legend() plt.draw() return mask
def detect_peaks(self, chromotogram: list): _peaks, _properties = find_peaks(chromotogram[1], prominence=1, width=2) if len(_peaks) == 0: return [True, None] _peak_width = peak_widths(chromotogram[1], _peaks, rel_height=1) peak_regions = list() indices = sorted(np.array(_peak_width[2:4]).flatten()) for _peak in _peaks: peak_regions.append(self.find_peak_width(_peak, indices)) upper_limit_abundance = np.max(_properties['prominences']) lower_limit_abundance = 0.1 * upper_limit_abundance interference_peaks_index = [ i for i in range(len(_peaks)) if _peaks[i] >= lower_limit_abundance and _peaks[i] <= upper_limit_abundance ] if len(interference_peaks_index) >= 5: #Not quantifiable return [False, None] narrowed_chromotograms = [[ chromotogram[0][peak_region[0]:peak_region[1] + 1], chromotogram[1][peak_region[0]:peak_region[1] + 1] ] for peak_region in peak_regions] return [True, narrowed_chromotograms]
def find_anchors(pos, min_count=3, min_dis=20000, wlen=800000, res=10000): from collections import Counter from scipy.signal import find_peaks, peak_widths min_dis = max(min_dis//res, 1) wlen = min(wlen//res, 20) count = Counter(pos) refidx = range(min(count)-1, max(count)+2) # extend 1 bin signal = np.r_[[count[i] for i in refidx]] summits = find_peaks(signal, height=min_count, distance=min_dis)[0] sorted_summits = [(signal[i],i) for i in summits] sorted_summits.sort(reverse=True) # sort by peak count peaks = set() records = {} for _, i in sorted_summits: tmp = peak_widths(signal, [i], rel_height=1, wlen=wlen)[2:4] li, ri = int(np.round(tmp[0][0])), int(np.round(tmp[1][0])) lb = refidx[li] rb = refidx[ri] if not len(peaks): peaks.add((refidx[i], lb, rb)) for b in range(lb, rb+1): records[b] = (refidx[i], lb, rb) else: for b in range(lb, rb+1): if b in records: # merge anchors m_lb = min(lb, records[b][1]) m_rb = max(rb, records[b][2]) summit = records[b][0] # always the highest summit peaks.remove(records[b]) break else: # loop terminates normally m_lb, m_rb, summit = lb, rb, refidx[i] peaks.add((summit, m_lb, m_rb)) for b in range(m_lb, m_rb+1): records[b] = (summit, m_lb, m_rb) return peaks