def count_aps(): """ Shows a result table with the number of action potentials (i.e events whose potential is above 0 mV) in selected traces. If no trace is selected, then the current trace is analyzed. Returns: False if document is not open. """ if not stf.check_doc(): print("Open file first") return False if len( stf.get_selected_indices() )==0: sel_trace = [ stf.get_trace_index()] else: sel_trace = stf.get_selected_indices() mytable = dict() for trace in sel_trace: tstart = 0 tend = stf.get_size_trace(trace)*stf.get_sampling_interval() threshold = 0 spikes = count_events(tstart, tend, threshold, True, trace, True) mytable["Trace %.3d" %trace] = spikes stf.show_table(mytable) return True
def count_aps(): """ Shows a result table with the number of action potentials (i.e events whose potential is above 0 mV) in selected traces. If no trace is selected, then the current trace is analyzed. Returns: False if document is not open. """ if not stf.check_doc(): print("Open file first") return False if len(stf.get_selected_indices()) == 0: sel_trace = [stf.get_trace_index()] else: sel_trace = stf.get_selected_indices() mytable = dict() for trace in sel_trace: tstart = 0 tend = stf.get_size_trace(trace) * stf.get_sampling_interval() threshold = 0 spikes = count_events(tstart, tend, threshold, True, trace, True) mytable["Trace %.3d" % trace] = spikes stf.show_table(mytable) return True
def monoexpfit(optimization=True, Tn=20): """ Fits monoexponential function with offset to data between the fit cursors in the current trace of the active channel using a Chebyshev-Levenberg- Marquardt hybrid algorithm. Optimization requires Scipy. Setting optimization to False forces this function to use just the Chebyshev algorithm. The maximum order of the Chebyshev polynomials can be set using Tn. """ # Get data fit_start = stf.get_fit_start() fit_end = stf.get_fit_end() y = np.double(stf.get_trace()[fit_start:fit_end]) si = stf.get_sampling_interval() l = len(y) t = si * np.arange(0, l, 1, np.double) # Define monoexponential function def f(t, *p): return p[0] + p[1] * np.exp(-t / p[2]) # Get initial values from Chebyshev transform fit init = chebexp(1, Tn) p0 = (init.get('Offset'), ) p0 += (init.get('Amp_0'), ) p0 += (init.get('Tau_0'), ) # Optimize (if applicable) if optimization == True: # Optimize fit using Levenberg-Marquardt algorithm options = {"ftol": 2.22e-16, "xtol": 2.22e-16, "gtol": 2.22e-16} [p, pcov] = optimize.curve_fit(f, t, y, p0, **options) elif optimization == False: p = list(p0) fit = f(t, *p) # Calculate SSE SSE = np.sum((y - fit)**2) # Plot fit in a new window matrix = np.zeros((2, stf.get_size_trace())) * np.nan matrix[0, :] = stf.get_trace() matrix[1, fit_start:fit_end] = fit stf.new_window_matrix(matrix) # Create table of results retval = [("p0_Offset", p[0])] retval += [("p1_Amp_0", p[1])] retval += [("p2_Tau_0", p[2])] retval += [("SSE", SSE)] retval += [("dSSE", 1.0 - np.sum((y - f(t, *p0))**2) / SSE)] retval += [("Time fit begins", fit_start * si)] retval += [("Time fit ends", fit_end * si)] retval = dict(retval) stf.show_table( retval, "monoexpfit, Section #%i" % float(stf.get_trace_index() + 1)) return
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 trainpeaks(): """ Measure a 20 Hz train of peaks starting at 260 ms into the trace """ pk = [] for i in range(5): stf.set_base_start( int(255 / stf.get_sampling_interval()) + (50 / stf.get_sampling_interval()) * i) stf.set_base_end( int(259 / stf.get_sampling_interval()) + (50 / stf.get_sampling_interval()) * i) stf.set_peak_start( int(260.5 / stf.get_sampling_interval()) + (50 / stf.get_sampling_interval()) * i) stf.set_peak_end( int(270.5 / stf.get_sampling_interval()) + (50 / stf.get_sampling_interval()) * i) stf.measure() pk.append(stf.get_peak() - stf.get_base()) # Create table of results dictlist = [("Peak 1", pk[0])] dictlist += [("Peak 2", pk[1])] dictlist += [("Peak 3", pk[2])] dictlist += [("Peak 4", pk[3])] dictlist += [("Peak 5", pk[4])] retval = dict(dictlist) stf.show_table(retval, "peaks, Section #%i" % float(stf.get_trace_index() + 1)) # Create table of results dictlist = [("Peak 1", pk[0] / pk[0] * 100)] dictlist += [("Peak 2", pk[1] / pk[0] * 100)] dictlist += [("Peak 3", pk[2] / pk[0] * 100)] dictlist += [("Peak 4", pk[3] / pk[0] * 100)] dictlist += [("Peak 5", pk[4] / pk[0] * 100)] retval = dict(dictlist) stf.show_table( retval, "norm peaks, Section #%i" % float(stf.get_trace_index() + 1)) return
def get_amplitude(base, peak, delta, trace=None): """ Calculates the amplitude deviation (peak-base) in units of the Y-axis Arguments: base -- Starting point (in ms) of the baseline cursor. peak -- Starting point (in ms) of the peak cursor. delta -- Time interval to calculate baseline/find the peak. trace -- Zero-based index of the trace to be processed, if None then current trace is computed. Returns: A float with the variation of the amplitude. False if Example: get_amplitude(980,1005,10,i) returns the variation of the Y unit of the trace i between peak value (10050+10) msec and baseline (980+10) msec """ # 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 intergers') return False sweep = trace # set base cursors: if not(stf.set_base_start(base, True)): return False # out-of range if not(stf.set_base_end(base+delta, True)): return False # set peak cursors: if not(stf.set_peak_start(peak, True)): return False # out-of range if not(stf.set_peak_end(peak+delta, True)): return False # update measurements stf.set_trace(sweep) amplitude = stf.get_peak()-stf.get_base() return amplitude
def get_amplitude(base, peak, delta, trace=None): """ Calculates the amplitude deviation (peak-base) in units of the Y-axis Arguments: base -- Starting point (in ms) of the baseline cursor. peak -- Starting point (in ms) of the peak cursor. delta -- Time interval to calculate baseline/find the peak. trace -- Zero-based index of the trace to be processed, if None then current trace is computed. Returns: A float with the variation of the amplitude. False if Example: get_amplitude(980,1005,10,i) returns the variation of the Y unit of the trace i between peak value (10050+10) msec and baseline (980+10) msec """ # 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 intergers') return False sweep = trace # set base cursors: if not (stf.set_base_start(base, True)): return False # out-of range if not (stf.set_base_end(base + delta, True)): return False # set peak cursors: if not (stf.set_peak_start(peak, True)): return False # out-of range if not (stf.set_peak_end(peak + delta, True)): return False # update measurements stf.set_trace(sweep) amplitude = stf.get_peak() - stf.get_base() return amplitude
def Train10AP(): """ An example function to perform peak measurements of a train of evoked fluorescence signals in the active window """ # Setup offset = 40 stf.set_base_start(0) stf.set_peak_start(offset - 2) stf.measure() base = stf.get_base() stf.set_peak_mean(1) stf.set_peak_direction("up") peak = [] # Get peak measurements for i in range(10): stf.set_peak_start(offset + (i * 4) - 2) stf.set_peak_end(offset + (i * 4) + 2) stf.measure() peak.append(stf.get_peak()) # Plot fit in a new window matrix = np.zeros((2, stf.get_size_trace())) * np.nan matrix[0, :] = stf.get_trace() for i in range(10): matrix[1, offset + (i * 4) - 1:offset + (i * 4) + 2] = peak[i] stf.new_window_matrix(matrix) # Create table of results retval = [] for i in range(10): retval += [("Peak %d" % (i), peak[i] - base)] retval = dict(retval) stf.show_table(retval, "Train10AP, Section #%i" % float(stf.get_trace_index() + 1)) return
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