def param_extr(filename, high_th, low_th, offset): signal = tp.trace_extr(filename) time = pu.time_vector(filename) """ Max Height """ mask_height = ~pu.disc_edges_full( signal, high_th, low_th ) + pu.disc_peak_full( signal, high_th, low_th, offset ) # exclude edge traces which contain partial pulses that do not report max height of integer traces if np.sum(mask_height) == 0: mask_height = np.ones(len(signal)).astype('bool') # # plt.plot(time,mask_height*np.max(signal)) height = np.max(signal[mask_height]) """ RMS """ rms = np.sqrt(np.mean(np.square(signal[mask_height]))) """ Background """ bg = tp.find_bg(signal) * 1e3 # height = np.max(signal) """ Area within discriminator """ mask_area = pu.disc_peak_full(signal, high_th, low_th, offset) area_win_abs = np.sum(np.abs(signal[mask_area])) area_win = np.sum(signal[mask_area]) # plt.plot(time,pu.disc_peak_full(signal,high_th,low_th,0)*np.max(signal)) # plt.plot(time,pu.disc_peak_full(signal,high_th,low_th,offset)*np.max(signal)) """ Simple area above threshold """ # area = np.sum(signal[signal>high_th]) """ Number of edges detected """ numedges = np.sum( mask_area[1:] > mask_area[:-1]) # if next element > current element, True and count return np.array( (filename, numedges, area_win, area_win_abs, height, rms, bg), dtype=[('filename', 'U256'), ('numedges', 'int8'), ('area_win', 'float64'), ('area_win_abs', 'float64'), ('height', 'float64'), ('rms', 'float64'), ('bg_mv', 'float64')])
def time_offset(time_v, signal, high_th, low_th, offset): """ shift a trace so that the steepest point is at time 0 steepest points must exist within discriminator window """ # start by finding the max of the derivative dt = np.diff(time_v)[0] # derivative of the signal, smoothed d_signal = savgol_filter(np.diff(signal), 301, 3) # ax = plt.gca() # ax2 = ax.twinx() # ax2.plot(d_signal/np.max(d_signal), color='green') # use peaks only if they are legitimate edges identified by the set-reset switch mask = pu.disc_peak_full(signal, high_th, low_th, offset) # print np.where(mask==True) # print peakutils.indexes(d_signal, .5, 3000) # find peaks in the derivative to find the steepest point idx = np.array([i for i in peakutils.indexes(d_signal, .5, 3000) if mask[i]==True]) # print idx if len(idx) == 0: return [np.nan for _ in time_v] idx_s = np.flipud(idx[d_signal[idx].argsort()])[0] try: time_p = peakutils.interpolate(time_v[:-1], d_signal, [idx_s])[0] except (RuntimeError, ValueError) as e: time_p = time_v[idx_s] n_shift = int(time_p / dt) return pa.shift(signal, - n_shift+int(len(signal)/2))
def fit_shift(time_s, signal, fit_model, high_th, low_th, offset): """ fit the trace with a sample pulse and shift it to match the staritngtime """ dt = np.diff(time_s)[0] d_signal = savgol_filter(np.diff(signal), 301, 3) # ax = plt.gca() # ax2 = ax.twinx() # ax2.plot(d_signal/np.max(d_signal), color='green') # use peaks only if they are legitimate edges identified by the set-reset switch mask = pu.disc_peak_full(signal, high_th, low_th, offset) # find peaks in the derivative to find the steepest point idx = np.array([i for i in peakutils.indexes(d_signal, .5, 3000) if mask[i]==True]) # print(time_s[idx]) # print time_v[left_edges], time_v[idx] if len(idx) == 0: return [np.nan for _ in time_s] idx_s = np.flipud(idx[d_signal[idx].argsort()]) # print(time_s[idx_s[0]]) p = Parameters() p.add('x_offset', time_s[np.argmax(signal)]) if len(idx_s) > 0: p.add('x_offset', time_s[idx_s[0]]) p.add('amplitude', 1, vary=1) result = fit_model.fit(signal, x=time_s, params=p, # weights=1 / 0.001 ) n_shift = int(result.best_values['x_offset'] / dt) # print(result.fit_report()) # result.plot_fit() # print n_shift*dt return pa.shift(signal, -n_shift+int(len(signal)/2))
def fit_two_cw(time, signal, two_pulse_fit, pulse_params, height_th, sigma0): # signal = signal - np.median(signal[signal<height_th]) (sum_a, sum_mu, sum_b, sum_tau, diff_a, diff_b, diff_tau) = pulse_params mask = pu.disc_peak_full(signal, height_th, 0, 0) # signal = signal - trcp.find_bg(signal[~mask]) # mask = pu.disc_peak_full(signal,height_th,0,0) # plt.plot(time,mask*np.max(signal),linestyle='--') left_edges = find_crossing(mask, 0.5, 'left') right_edges = find_crossing(mask, 0.5, 'right') one_x_offset_init_min = time[left_edges[0]] # one_x_offset_init_max = time[right_edges[0]] one_x_offset_init_max = time[ left_edges[0] + np.argmax(signal[left_edges[0]:right_edges[0]])] if len(left_edges) == 1: two_x_offset_init_min = one_x_offset_init_min two_x_offset_init_max = time[right_edges[0]] one_x_offset_init = one_x_offset_init_min two_x_offset_init = two_x_offset_init_max - 0.5e-6 else: two_x_offset_init_min = time[left_edges[1]] two_x_offset_init_max = time[ left_edges[1] + np.argmax(signal[left_edges[1]:right_edges[1]])] one_x_offset_init = (one_x_offset_init_min + one_x_offset_init_max) / 2 two_x_offset_init = (two_x_offset_init_min + two_x_offset_init_max) / 2 one_amplitude_init = sum_mu / 2 two_amplitude_init = sum_mu / 2 """Compulsory LMFIT for both overlapping and non-overlapping cases""" p = Parameters() p.add('one_x_offset', one_x_offset_init, min=one_x_offset_init_min, max=one_x_offset_init_max, vary=True) p.add('two_x_offset', two_x_offset_init, min=two_x_offset_init_min, max=two_x_offset_init_max, vary=True) p.add( 'sum_amplitudes', (one_amplitude_init + two_amplitude_init) * 1.01, #not sure why, but some assymetry is required... sum_mu can't be avg of sum_a and sum_b min=sum_a, max=sum_b, vary=True) p.add('diff_amplitudes', one_amplitude_init - two_amplitude_init, min=diff_a, max=diff_b, vary=True) p.add( 'one_amplitude', one_amplitude_init, expr='(sum_amplitudes + diff_amplitudes)/2', vary=True ) #warning: max >= 2 causes n=2 & noise to be fitted on a tau~0 2ph trace. p.add( 'two_amplitude', two_amplitude_init, expr='(sum_amplitudes - diff_amplitudes)/2', vary=True ) #warning: max >= 2 causes n=2 & noise to be fitted on a tau~0 2ph trace. result = two_pulse_fit.fit(np.array(signal), x=np.array(time), params=p, weights=1 / sigma0, method='powell') return result