def jjm_count(start, delta, threshold=0, up=True, trace=None, mark=True): """ Counts the number of events (e.g action potentials (AP)) in the current trace. Arguments: start -- starting time (in ms) to look for events. delta -- time interval (in ms) to look for events. threshold -- (optional) detection threshold (default = 0). up -- (optional) True (default) will look for upward events, False downwards. trace -- (optional) zero-based index of the trace in the current channel, if None, the current trace is selected. mark -- (optional) if True (default), set a mark at the point of threshold crossing Returns: An integer with the number of events. Examples: count_events(500,1000) returns the number of events found between t=500 ms and t=1500 ms above 0 in the current trace and shows a stf marker. count_events(500,1000,0,False,-10,i) returns the number of events found below -10 in the trace i and shows the corresponding stf markers. """ # sets the current trace or the one given in trace. if trace is None: sweep = stf.get_trace_index() else: if type(trace) !=int: print "trace argument admits only integers" return False sweep = trace # set the trace described in sweep stf.set_trace(sweep) # transform time into sampling points dt = stf.get_sampling_interval() pstart = int( round(start/dt) ) pdelta = int( round(delta/dt) ) # select the section of interest within the trace selection = stf.get_trace()[pstart:(pstart+pdelta)] # algorithm to detect events EventCounter,i = 0,0 # set counter and index to zero # list of sample points sample_points = [] # choose comparator according to direction: if up: comp = lambda a, b: a > b else: comp = lambda a, b: a < b # run the loop while i<len(selection): if comp(selection[i],threshold): EventCounter +=1 if mark: sample_point = pstart+i; sample_points.append(sample_point); stf.set_marker(pstart+i, selection[i]) while i<len(selection) and comp(selection[i],threshold): i+=1 # skip values if index in bounds AND until the value is below/above threshold again else: i+=1 time_points = [sample_point*dt for sample_point in sample_points]; return (EventCounter, sample_points, time_points)
def find_ADPs(AP_peak_indicies): ADP_values = [] ADP_indicies = [] ##slices for peak in range(len(AP_peak_indicies)-1): ADP_search = stf.get_trace()[AP_peak_indicies[peak]:AP_peak_indicies[peak+1]] min_value = np.min(ADP_search) min_index = AP_peak_indicies[peak] + np.argmin(ADP_search) stf.set_marker(min_index, min_value) ADP_values.append(min_value) ADP_indicies.append(min_index) return(ADP_values, ADP_indicies)
def automated_search_triexponential(trace_region_to_search, search_period, threshold, min_btw_events, tau_rise, tau_1_decay, tau_2_decay): """searches section of trace based on a user input triexponential function (tau_rise, tau_1_decay, tau_2_decay)""" #converts some inputs to sample points min_samples_btw_events = min_btw_events / stf.get_sampling_interval() #pull out region to search region_to_search = stf.get_trace( )[trace_region_to_search[0]:trace_region_to_search[1]] #list to store detected events event_times = [] #creates vector of time points t = np.linspace(0, 50, (50 / stf.get_sampling_interval())) #creates triexponential pattern function p_t = [(1 - math.exp(-(t_point - 0) / tau_rise)) * (math.exp(-(t_point - 0) / tau_1_decay)) * (math.exp(-(t_point - 0) / tau_2_decay)) for t_point in t] #slides window along pt = 0 while pt < range(len(region_to_search) - int(min_samples_btw_events)): EPSC_test = stf.get_trace()[pt:( pt + (search_period / stf.get_sampling_interval()))] corr_coeff = stats.pearsonr(p_t, EPSC_test)[0] if corr_coeff > threshold: stf.set_marker(pt, region_to_search[trace_region_to_search[0] + pt]) event_times.append(pt * stf.get_sampling_interval()) pt += min_samples_btw_events else: pt += 1 return (event_times)
def find_thresholds(input_trace, input_trace_si, ADP_sample_points): #take derivative of trace, assume relevant trace is set to current trace #get_dv_dt_as_numpy(input_array, si, *argv) _1stderivative = dv_dt_V.get_dv_dt_as_numpy(input_trace, input_trace_si) #take 2nd derivative of trace _2ndderivative = dv_dt_V.get_dv_dt_as_numpy(_1stderivative, input_trace_si) _3rdderivative = dv_dt_V.get_dv_dt_as_numpy(_2ndderivative, input_trace_si) #will need to filter trace here #try with using sigma of 1 _3rdderivative_filtered = _3rdderivative #trace_filtering.filter_1d_numpy(_3rdderivative, 1, False) #find peak time points #use ADP sample points, estimate an AP width of 10ms to work backword from to capture peak threshold_points = [] threshold_indicies = [] for x in range(len(ADP_sample_points)): if x == 0: earlier_point = int(ADP_sample_points[x]) - int( round(50 / input_trace_si)) else: earlier_point = int(ADP_sample_points[x - 1]) point = ADP_sample_points[x] deriv_peak_search = _3rdderivative_filtered[earlier_point:point] threshold_points.append(np.max(deriv_peak_search)) threshold_index = earlier_point + np.argmax(deriv_peak_search) threshold_indicies.append(threshold_index) #marker function is not working here, not sure why, also maybe a good point to set a #voltage bound on detecting the threshold stf.set_marker(threshold_index, input_trace[threshold_index]) #use peak time points to pull out the voltage values from the 1st trace, these are voltage values return (threshold_indicies)
def find_baseline_amplitude(sigma): # gaussian filter with sigma 10 trace_ = stf.get_trace() trace_filtered = ndimage.filters.gaussian_filter(trace_, sigma) # take derivative si = stf.get_sampling_interval() #read V values from trace, V_values = stf.get_trace() #compute dv and by iterating over voltage vectors dv = [V_values[i + 1] - V_values[i] for i in range(len(V_values) - 1)] #compute dv/dt dv_dt = [(dv[i] / si) for i in range(len(dv))] # find index of derivative peak deriv_max = np.argmin(dv_dt) # use derivative peak index to get baseline from original trace # use a mean of 10 sample points baseline = np.mean(trace_[deriv_max - 10:deriv_max]) stf.set_marker(deriv_max, baseline) peak_amplitude = np.min(stf.get_trace()) peak_index = np.argmin(stf.get_trace()) stf.set_marker(peak_index, peak_amplitude) peak_from_baseline = peak_amplitude - baseline return (baseline, peak_amplitude, peak_from_baseline)
def find_AP_peak_ADP_trace(*argv): """ count number of APs, find ADPs and thesholds in indicated trace with current injection/gradually increasing steps inputs: (time (msec) to start search, length of search region, starting current value, current delta between traces, threshold value, deflection direction ('up'/'down'), mark traces (True/False))""" ##if times are input, use those, otherwise use peak cursor settings #TO DO: optional change to threshold_values and deflection_direction if len(argv) > 0: trace_selection = argv[0] threshold_value = float(argv[1]) deflection_direction = argv[2] mark_option = argv[3] start_msec = float(argv[4]) delta_msec = float(argv[5]) else: trace_selection = stf.get_trace_index() threshold_value = 0 deflection_direction = 'up' mark_option = True start_msec = float(stf.get_peak_start(True)) delta_msec = float(stf.get_peak_end(True) - start_msec) stf.set_trace(trace_selection) ##gets AP counts and sample points in current trace if deflection_direction == 'up': direction_input = True else: direction_input = False ##count function will return number of APs in trace and sample points for subsequent functions trace_count, trace_sample_points_absolute = jjm_count( start_msec, delta_msec, threshold=threshold_value, up=direction_input, trace=trace_selection, mark=mark_option) ##finds afterdepolarizations--minimums between peaks trace_ADP_values, trace_ADP_indicies = find_ADPs( trace_sample_points_absolute) trace_si = stf.get_sampling_interval() trace_ADP_times = [sample * trace_si for sample in trace_ADP_indicies] trace_AP_values, trace_AP_indicies = find_ADPs( trace_sample_points_absolute) trace_si = stf.get_sampling_interval() trace_ADP_times = [sample * trace_si for sample in trace_AP_indicies] trace_thresholds_indicies = find_thresholds(stf.get_trace(trace_selection), trace_si, trace_ADP_indicies) trace_threshold_values = [ stf.get_trace(trace_selection)[index] for index in trace_thresholds_indicies ] trace_threshold_times = [ sample * trace_si for sample in trace_thresholds_indicies ] for sample, mv in zip(trace_thresholds_indicies, trace_threshold_values): stf.set_marker(sample, mv) for x in range(len(trace_threshold_values)): if trace_threshold_values[ x] > threshold_value or trace_threshold_values[ x] < trace_ADP_values[x]: trace_threshold_values[x] = 'NaN' #arrays for output ADP_out_array = np.transpose(np.array([trace_ADP_times, trace_ADP_values])) threshold_out_array = np.transpose( np.array([trace_threshold_times, trace_threshold_values])) out_array = np.hstack([ADP_out_array, threshold_out_array]) df_out = pd.DataFrame( out_array, columns=['ADP time', 'ADP (mV)', 'threshold time', 'threshold (mV)']) return (trace_count, df_out)
def count_events(start, delta, threshold=0, up=True, trace=None, mark=True): """ Counts the number of events (e.g action potentials (AP)) in the current trace. Arguments: start -- starting time (in ms) to look for events. delta -- time interval (in ms) to look for events. threshold -- (optional) detection threshold (default = 0). up -- (optional) True (default) will look for upward events, False downwards. trace -- (optional) zero-based index of the trace in the current channel, if None, the current trace is selected. mark -- (optional) if True (default), set a mark at the point of threshold crossing Returns: An integer with the number of events. Examples: count_events(500,1000) returns the number of events found between t=500 ms and t=1500 ms above 0 in the current trace and shows a stf marker. count_events(500,1000,0,False,-10,i) returns the number of events found below -10 in the trace i and shows the corresponding stf markers. """ # sets the current trace or the one given in trace. if trace is None: sweep = stf.get_trace_index() else: if type(trace) !=int: print('trace argument admits only integers') return False sweep = trace # set the trace described in sweep stf.set_trace(sweep) # transform time into sampling points dt = stf.get_sampling_interval() pstart = int( round(start/dt) ) pdelta = int( round(delta/dt) ) # select the section of interest within the trace selection = stf.get_trace()[pstart:(pstart+pdelta)] # algorithm to detect events event_counter, i = 0, 0 # set counter and index to zero # choose comparator according to direction: if up: comp = lambda a, b: a > b else: comp = lambda a, b: a < b # run the loop while i < len(selection): if comp(selection[i], threshold): event_counter += 1 if mark: stf.set_marker(pstart+i, selection[i]) while i < len(selection) and comp(selection[i], threshold): i += 1 # skip until value is below/above threshold else: i += 1 return event_counter