def jjm_resistance(baseline_start, baseline_end, cap_trans_start, cap_trans_end, amplitude): #time arguments in msec, amplitude argument in mV stf.set_channel(0) stf.set_base_start(baseline_start, True) stf.set_base_end(baseline_end, True) stf.set_peak_start(cap_trans_start, True) stf.set_peak_end(cap_trans_end, True) stf.measure() baseline = float(stf.get_base()) peak = float(stf.get_peak()) real_peak = baseline - peak amplitude = float(amplitude) amplitude_V = amplitude / (10**(3)) real_peak_A = real_peak / (10**(12)) Rs_Ohm = amplitude_V / abs(real_peak_A) Rs = Rs_Ohm / (10**(6)) return (real_peak, Rs)
def final(): """Creates a final template""" stf.set_peak_start(100) stf.set_peak_end(599) stf.set_fit_start(100) stf.set_fit_end(599) stf.set_peak_mean(3) stf.set_base_start(0) stf.set_base_end(100) stf.measure() return stf.leastsq(5)
def preliminary(): """Creates a preliminary template""" stf.set_peak_start(209900) stf.set_peak_end(210500) stf.set_fit_start(209900) stf.set_fit_end(210400) stf.set_peak_mean(3) stf.set_base_start(209600) stf.set_base_end(209900) stf.measure() return stf.leastsq(5)
def batch_cursors(): """Sets appropriate cursor positions for analysing the extracted events.""" stf.set_peak_start(100) stf.set_peak_end(598) stf.set_fit_start(120) stf.set_fit_end(598) stf.set_peak_mean(3) stf.set_base_start(0) stf.set_base_end(100) stf.measure()
def batch_cursors(): """ Sets peak, base and fit cursors around a synaptic event for the batch analysis of the extracted events. """ stf.base.cursor_index = (000, 100) stf.peak.cursor_index = (100, 598) stf.fit.cursor_index = (120, 598) stf.set_peak_mean(3) stf.measure() # update cursors
def yvalue(origin, interval): stf.set_fit_start(origin, True) stf.set_fit_end(origin + interval, True) stf.measure() x = int(stf.get_fit_end(False)) y = [] for i in range(stf.get_size_channel()): stf.set_trace(i) y.append(stf.get_trace(i)[x]) return y
def update(self): """ update current trace sampling rate, cursors position and measurements (peak, baseline & AP kinetics) according to the threshold value set at construction or when the object is called with a threshold argument. """ # set slope stf.set_slope(self._thr) # on stf v0.93 or above # update sampling rate self._dt = stf.get_sampling_interval() # update cursors and AP kinetics (peak and half-width) stf.measure()
def final(): """ Sets peak, base and fit cursors around a synaptic event and performs a biexponetial fit to create the final template for event detection. """ stf.base.cursor_index = (000, 100) stf.peak.cursor_index = (100, 599) stf.fit.cursor_index = (100, 599) stf.set_peak_mean(3) stf.measure() # update cursors return stf.leastsq(5)
def preliminary(): """ Sets peak, base and fit cursors around a synaptic event and performs a biexponential fit to create the preliminary template for event detection. """ stf.base.cursor_index = (209600, 209900) stf.peak.cursor_index = (209900, 210500) stf.fit.cursor_index = (209900, 210400) stf.set_peak_mean(3) stf.measure() # update cursors return stf.leastsq(5)
def resistance( base_start, base_end, peak_start, peak_end, amplitude): """Calculates the resistance from a series of voltage clamp traces. Keyword arguments: base_start -- Starting index (zero-based) of the baseline cursors. base_end -- End index (zero-based) of the baseline cursors. peak_start -- Starting index (zero-based) of the peak cursors. peak_end -- End index (zero-based) of the peak cursors. amplitude -- Amplitude of the voltage command. Returns: The resistance. """ if not stf.check_doc(): print('Couldn\'t find an open file; aborting now.') return 0 #A temporary array to calculate the average: array = np.empty( (stf.get_size_channel(), stf.get_size_trace()) ) for n in range( 0, stf.get_size_channel() ): # Add this trace to set: array[n] = stf.get_trace( n ) # calculate average and create a new section from it: stf.new_window( np.average(set, 0) ) # set peak cursors: # -1 means all points within peak window. if not stf.set_peak_mean(-1): return 0 if not stf.set_peak_start(peak_start): return 0 if not stf.set_peak_end(peak_end): return 0 # set base cursors: if not stf.set_base_start(base_start): return 0 if not stf.set_base_end(base_end): return 0 # measure everything: stf.measure() # calculate r_seal and return: return amplitude / (stf.get_peak()-stf.get_base())
def jjm_peak(baseline_start, baseline_end, p_start, p_end): #time arguments in msec, amplitude argument in mV stf.set_channel(0) stf.set_base_start(baseline_start, True) stf.set_base_end(baseline_end, True) stf.set_peak_start(p_start, True) stf.set_peak_end(p_end, True) stf.measure() baseline = float(stf.get_base()) peak = float(stf.get_peak()) real_peak = abs(baseline - peak) return (real_peak)
def resistance(base_start, base_end, peak_start, peak_end, amplitude): """Calculates the resistance from a series of voltage clamp traces. Keyword arguments: base_start -- Starting index (zero-based) of the baseline cursors. base_end -- End index (zero-based) of the baseline cursors. peak_start -- Starting index (zero-based) of the peak cursors. peak_end -- End index (zero-based) of the peak cursors. amplitude -- Amplitude of the voltage command. Returns: The resistance. """ if not stf.check_doc(): print('Couldn\'t find an open file; aborting now.') return 0 #A temporary array to calculate the average: array = np.empty((stf.get_size_channel(), stf.get_size_trace())) for n in range(0, stf.get_size_channel()): # Add this trace to set: array[n] = stf.get_trace(n) # calculate average and create a new section from it: stf.new_window(np.average(set, 0)) # set peak cursors: # -1 means all points within peak window. if not stf.set_peak_mean(-1): return 0 if not stf.set_peak_start(peak_start): return 0 if not stf.set_peak_end(peak_end): return 0 # set base cursors: if not stf.set_base_start(base_start): return 0 if not stf.set_base_end(base_end): return 0 # measure everything: stf.measure() # calculate r_seal and return: return amplitude / (stf.get_peak() - stf.get_base())
def increment_params(params, is_time, increment): """increment cursors by input time points""" peak_1_s = params[0] + increment peak_1_e = params[1] + increment peak_2_s = params[2] + increment peak_2_e = params[3] + increment stf.set_base_start(peak_1_s, is_time=True) stf.set_base_end(peak_1_e, is_time=True) stf.set_peak_start(peak_2_s, is_time=True) stf.set_peak_end(peak_2_e, is_time=True) stf.measure() print(peak_1_s, peak_1_e, peak_2_s, peak_2_e) return (params)
def set_params(params): """sets baseline and peak curors to input time values (use timevalues not samples""" peak_1_s = params[0] peak_1_e = params[1] peak_2_s = params[2] peak_2_e = params[3] stf.set_base_start(peak_1_s, is_time=True) stf.set_base_end(peak_1_e, is_time=True) stf.set_peak_start(peak_2_s, is_time=True) stf.set_peak_end(peak_2_e, is_time=True) stf.measure() print(peak_1_s, peak_1_e, peak_2_s, peak_2_e) return (params)
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 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 fit_experiment(params, pulse_length, function_to_fit): num_sweeps = stf.get_size_channel() stf.set_channel(0) stf.set_trace(0) #jjm_analysis.set_params(params); #stf.measure(); #this is in samples #peak_index = stf.peak_index(); #stf.set_fit_start(peak_index, is_time=False); #fit_start_time = peak_index*stf.get_sampling_interval(); #stf.set_fit_end(fit_start_time+pulse_length-(10*stf.get_sampling_interval()), is_time=True); #fit_func = stf.leastsq(function_to_fit); #fit_func['Baseline(pA)']=stf.get_base(); #fit_df = pd.DataFrame(fit_func, index=[0]); fits = [] traces = [] for x in range(0, num_sweeps): stf.set_trace(x) jjm_analysis.set_params(params) stf.measure() #this is in samples peak_index = stf.peak_index() stf.set_fit_start(peak_index, is_time=False) fit_start_time = peak_index * stf.get_sampling_interval() stf.set_fit_end(fit_start_time + pulse_length - (10 * stf.get_sampling_interval()), is_time=True) sweep_fit = stf.leastsq(function_to_fit) sweep_fit['Baseline(pA)'] = stf.get_base() fits.append(sweep_fit) traces.append(x) fit_df = pd.DataFrame(fits) return (fit_df)
def timeconstants(fitwindow, pulsewindow, ichannel=0, vchannel=1): """ Compute and plot decay time constants Parameters ---------- fitwindow : (float, float), optional Window for fitting time constant (time in ms from beginning of sweep) None for current cursor settings. Default: None pulsewindow : (float, float), optional Window for voltage pulse measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None ichannel : int, optional current channel number. Default: 0 vchannel : int, optional voltage channel number. Default: 1 Returns ------- v_commands : numpy.ndarray Command voltages taus : numpy.ndarray Time constants """ import stf if not stf.check_doc(): return None nchannels = stf.get_size_recording() if nchannels < 2: sys.stderr.write( "Function requires 2 channels (0: current; 1: voltage)\n") return dt = stf.get_sampling_interval() v_commands = [] taus = [] fig = stf.mpl_panel(figsize=(12, 8)).fig fig.clear() gs = gridspec.GridSpec(4, 8) ax_currents = stfio_plot.StandardAxis(fig, gs[:3, :4], hasx=False, hasy=False) ax_voltages = stfio_plot.StandardAxis(fig, gs[3:, :4], hasx=False, hasy=False, sharex=ax_currents) for ntrace in range(stf.get_size_channel()): stf.set_trace(ntrace) stf.set_channel(ichannel) trace = stf.get_trace() ax_currents.plot(np.arange(len(trace)) * dt, trace) if fitwindow is not None: stf.fit.cursor_time = fitwindow res = stf.leastsq(0, False) taus.append(res['Tau_0']) # Measure pulse amplitude stf.set_channel(vchannel) trace = stf.get_trace() ax_voltages.plot(np.arange(len(trace)) * dt, trace) stf.set_peak_direction("up") stf.set_peak_mean(-1) if pulsewindow is not None: stf.peak.cursor_time = pulsewindow stf.measure() v_commands.append(stf.peak.value) stfio_plot.plot_scalebars(ax_currents, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=ichannel)) stfio_plot.plot_scalebars(ax_voltages, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=vchannel)) v_commands = np.array(v_commands) taus = np.array(taus) ax_taus = plot_iv(taus, v_commands, "ms", stf.get_yunits(channel=vchannel), fig, 122) # Reset peak computation to single sampling point stf.set_peak_mean(1) # Reset active channel stf.set_channel(ichannel) # Compute conductances: stf.show_table_dictlist({ "Voltage ({0})".format(stf.get_yunits(channel=vchannel)): v_commands.tolist(), "Taus (ms)": taus.tolist(), }) return v_commands, taus
def iv(peakwindow=None, basewindow=None, pulsewindow=None, erev=None, peakmode="both", ichannel=0, vchannel=1, exclude=None): """ Compute and plot an IV curve for currents Parameters ---------- peakwindow : (float, float), optional Window for peak measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None basewindow : (float, float), optional Window for baseline measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None pulsewindow : (float, float), optional Window for voltage pulse measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None erev : float, optional End of v clamp pulse in ms or None to determine automatically. Default: None peakmode : string, optional Peak direction - one of "up", "down", "both" or "mean". Default: "up" ichannel : int, optional current channel number. Default: 0 vchannel : int, optional voltage channel number. Default: 1 exclude : list of ints, optional List of trace indices to be excluded from the analysis. Default: None Returns ------- v_commands : numpy.ndarray Command voltages ipeaks : numpy.ndarray Peak currents gpeaks : numpy.ndarray Peak normalized conductances g_fit : numpy.ndarray Half-maximal voltage and slope of best-fit Boltzmann function """ import stf if not stf.check_doc(): return None nchannels = stf.get_size_recording() if nchannels < 2: sys.stderr.write( "Function requires 2 channels (0: current; 1: voltage)\n") return dt = stf.get_sampling_interval() olddirection = stf.get_peak_direction() v_commands = [] ipeaks = [] if basewindow is not None: stf.base.cursor_time = basewindow fig = stf.mpl_panel(figsize=(12, 8)).fig fig.clear() gs = gridspec.GridSpec(4, 8) ax_currents = stfio_plot.StandardAxis( fig, gs[:3, :4], hasx=False, hasy=False) ax_voltages = stfio_plot.StandardAxis( fig, gs[3:, :4], hasx=False, hasy=False, sharex=ax_currents) for ntrace in range(stf.get_size_channel()): if exclude is not None: if ntrace in exclude: continue stf.set_trace(ntrace) stf.set_channel(ichannel) trace = stf.get_trace() ax_currents.plot(np.arange(len(trace))*dt, trace) # Measure only downward peaks (inward currents) if peakmode is "mean": stf.set_peak_direction("up") stf.set_peak_mean(-1) else: stf.set_peak_direction(peakmode) # Set peak computation to single sampling point stf.set_peak_mean(1) if peakwindow is not None: stf.peak.cursor_time = peakwindow stf.measure() if basewindow is not None: ipeaks.append(stf.peak.value-stf.base.value) else: ipeaks.append(stf.peak.value) # Measure pulse amplitude stf.set_channel(vchannel) trace = stf.get_trace() ax_voltages.plot(np.arange(len(trace))*dt, trace) stf.set_peak_direction("up") stf.set_peak_mean(-1) if pulsewindow is not None: stf.peak.cursor_time = pulsewindow stf.measure() v_commands.append(stf.peak.value) stfio_plot.plot_scalebars( ax_currents, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=0)) stfio_plot.plot_scalebars( ax_voltages, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=1)) v_commands = np.array(v_commands) ipeaks = np.array(ipeaks) if erev is None: # Find first zero crossing in ipeaks: for npulse in range(ipeaks.shape[0]-1): if np.sign(ipeaks[npulse]) != np.sign(ipeaks[npulse+1]): # linear interpolation m1 = (ipeaks[npulse+1]-ipeaks[npulse]) / ( v_commands[npulse+1]-v_commands[npulse]) c1 = ipeaks[npulse] - m1*v_commands[npulse] erev = -c1/m1 break if erev is None: sys.stderr.write( "Could not determine reversal potential. Aborting now\n") return None # Reset peak computation to single sampling point stf.set_peak_mean(1) stf.set_peak_direction(olddirection) # Reset active channel stf.set_channel(ichannel) # Compute conductances: gpeaks, g_fit = gv(ipeaks, v_commands, erev) ax_ipeaks = plot_iv( ipeaks, v_commands, stf.get_yunits(channel=ichannel), stf.get_yunits(channel=1), fig, 222) ax_ipeaks.set_title("Peak current") ax_gpeaks = plot_gv( gpeaks, v_commands, stf.get_yunits(channel=vchannel), g_fit, fig, 224) ax_gpeaks.set_title("Peak conductance") stf.show_table_dictlist({ "Voltage ({0})".format( stf.get_yunits(channel=vchannel)): v_commands.tolist(), "Peak current ({0})".format( stf.get_yunits(channel=ichannel)): ipeaks.tolist(), "Peak conductance (g/g_max)": gpeaks.tolist(), }) return v_commands, ipeaks, gpeaks, g_fit
def EPSPtrains(latency=200, numStim=4, intvlList=[1, 0.8, 0.6, 0.4, 0.2, 0.1, 0.08, 0.06, 0.04, 0.02]): # Initialize numTrains = len(intvlList) # Number of trains intvlArray = np.array(intvlList) * 1000 # Units in ms si = stf.get_sampling_interval() # Units in ms # Background subtraction traceBaselines = [] subtractedTraces = [] k = 1e-4 x = [i * stf.get_sampling_interval() for i in range(stf.get_size_trace())] for i in range(numTrains): stf.set_trace(i) z = x y = stf.get_trace() traceBaselines.append(y) ridx = [] if intvlArray[i] > 500: for j in range(numStim): ridx += range( int(round(((intvlArray[i] * j) + latency - 1) / si)), int(round( ((intvlArray[i] * (j + 1)) + latency - 1) / si)) - 1) else: ridx += range( int(round((latency - 1) / si)), int( round(((intvlArray[i] * (numStim - 1)) + latency + 500) / si)) - 1) ridx += range(int(round(4999 / si)), int(round(5199 / si))) z = np.delete(z, ridx, 0) y = np.delete(y, ridx, 0) yi = np.interp(x, z, y) yf = signal.symiirorder1(yi, (k**2), 1 - k) traceBaselines.append(yf) subtractedTraces.append(stf.get_trace() - yf) stf.new_window_list(traceBaselines) stf.new_window_list(subtractedTraces) # Measure depolarization # Initialize variables a = [] b = [] # Set baseline start and end cursors stf.set_base_start(np.round( (latency - 50) / si)) # Average during 50 ms period before stimulus stf.set_base_end(np.round(latency / si)) # Set fit start cursor stf.set_fit_start(np.round(latency / si)) stf.set_fit_end( np.round(((intvlArray[1] * (numStim - 1)) + latency + 1000) / si)) # Include a 1 second window after last stimulus # Start AUC calculations for i in range(numTrains): stf.set_trace(i) stf.measure() b.append(stf.get_base()) n = int(stf.get_fit_end() + 1 - stf.get_fit_start()) x = np.array([k * stf.get_sampling_interval() for k in range(n)]) y = stf.get_trace()[int(stf.get_fit_start()):int(stf.get_fit_end() + 1)] a.append(np.trapz(y - b[i], x)) # Units in V.s return a
def wcp(V_step=-5, step_start=10, step_duration=20): """ Measures whole cell properties. Specifically, this function returns the voltage clamp step estimates of series resistance, input resistance, cell membrane resistance, cell membrane capacitance, cell surface area and specific membrane resistance. The series (or access) resistance is obtained my dividing the voltage step by the peak amplitude of the current transient (Ogden, 1994): Rs = V / Ip The input resistance is obtained by dividing the voltage step by the average amplitude of the steady-state current (Barbour, 2014): Rin = V / Iss The cell membrane resistance is calculated by subtracting the series resistance from the input resistance (Barbour, 1994): Rm = Rin - Rs The cell membrane capacitance is estimated by dividing the transient charge by the size of the voltage-clamp step (Taylor et al. 2012): Cm = Q / V The cell surface area is estimated by dividing the cell capacitance by the specific cell capacitance, c (1.0 uF/cm^2; Gentet et al. 2000; Niebur, 2008): Area = Cm / c The specific membrane resistance is calculated by multiplying the cell membrane resistance with the cell surface area: rho = Rm * Area Users should be aware of the approximate nature of determining cell capacitance and derived parameters from the voltage-clamp step method (Golowasch, J. et al., 2009) References: Barbour, B. (2014) Electronics for electrophysiologists. Microelectrode Techniques workshop tutorial. www.biologie.ens.fr/~barbour/electronics_for_electrophysiologists.pdf Gentet, L.J., Stuart, G.J., and Clements, J.D. (2000) Direct measurement of specific membrane capacitance in neurons. Biophys J. 79(1):314-320 Golowasch, J. et al. (2009) Membrane Capacitance Measurements Revisited: Dependence of Capacitance Value on Measurement Method in Nonisopotential Neurons. J Neurophysiol. 2009 Oct; 102(4): 2161-2175. Niebur, E. (2008), Scholarpedia, 3(6):7166. doi:10.4249/scholarpedia.7166 www.scholarpedia.org/article/Electrical_properties_of_cell_membranes (revision #13938, last accessed 30 April 2018) Ogden, D. Chapter 16: Microelectrode electronics, in Ogden, D. (ed.) Microelectrode Techniques. 1994. 2nd Edition. Cambridge: The Company of Biologists Limited. Taylor, A.L. (2012) What we talk about when we talk about capacitance measured with the voltage-clamp step method J Comput Neurosci. 32(1):167-175 """ # Error checking if stf.get_yunits() != "pA": raise ValueError('The recording is not voltage clamp') # Prepare variables from input arguments si = stf.get_sampling_interval() t0 = step_start / si l = step_duration / si # Set cursors and update measurements stf.set_base_start((step_start - 1) / si) stf.set_base_end(t0 - 1) stf.set_peak_start(t0) stf.set_peak_end((step_start + 1) / si) stf.set_fit_start(t0) stf.set_fit_end(t0 + l - 1) stf.set_peak_direction("both") stf.measure() # Calculate series resistance (Rs) from initial transient b = stf.get_base() Rs = 1000 * V_step / (stf.get_peak() - b) # in Mohm # Calculate charge delivered during the voltage clamp step n = int(stf.get_fit_end() + 1 - stf.get_fit_start()) x = [i * stf.get_sampling_interval() for i in range(n)] y = stf.get_trace()[int(stf.get_fit_start()):int(stf.get_fit_end() + 1)] Q = np.trapz(y - b, x) # Set cursors and update measurements stf.set_base_start(t0 + l - 1 - (step_duration / 4) / si) stf.set_base_end(t0 + l - 1) stf.measure() # Measure steady state current and calculate input resistance I = stf.get_base() - b Rin = 1000 * V_step / I # in Mohm # Calculate cell membrane resistance Rm = Rin - Rs # in Mohm # Calculate voltage-clamp step estimate of the cell capacitance t = x[-1] - x[0] Cm = (Q - I * t) / V_step # in pF # Estimate membrane surface area, where the capacitance per unit area is 1.0 uF/cm^2 A = Cm * 1e-06 / 1.0 # in cm^2 # Calculate specific membrane resistance rho = 1e+03 * Rm * A # in kohm.cm^2; usually 10 at rest # Create table of results retval = [] retval += [("Holding current (pA)", b)] retval += [("Series resistance (Mohm)", Rs)] retval += [("Input resistance (Mohm)", Rin)] retval += [("Cell resistance (Mohm)", Rm)] retval += [("Cell capacitance (pF)", Cm)] retval += [("Surface area (um^2)", A * 1e+04**2)] retval += [("Membrane resistivity (kohm.cm^2)", rho)] retval = dict(retval) stf.show_table(retval, "Whole-cell properties") return retval
def glu_iv(pulses=13, subtract_base=True): """Calculates an iv from a repeated series of fast application and voltage pulses. Keyword arguments: pulses -- Number of pulses for the iv. subtract_base -- If True (default), baseline will be subtracted. Returns: True if successful. """ # Some ugly definitions for the time being # Cursors are in ms here. gFitEnd = 330.6 # fit end cursor is variable gFSelect = 0 # Monoexp gDictSize = stf.leastsq_param_size( gFSelect) + 2 # Parameters, chisqr, peak value gBaseStart = 220.5 # Start and end of the baseline before the control pulse, in ms gBaseEnd = 223.55 gPeakStart = 223.55 # Start and end of the peak cursors for the control pulse, in ms gPeakEnd = 253.55 if (gDictSize < 0): print('Couldn\'t retrieve function id=%d, aborting now.' % gFSelect) return False if (not (stf.check_doc())): print('Couldn\'t find an open file; aborting now.') return False # analyse iv, subtract baseline if requested: ivtools.analyze_iv(pulses) if (subtract_base == True): if (not (stf.set_base_start(gBaseStart, True))): return False if (not (stf.set_base_end(gBaseEnd, True))): return False stf.measure() stf.select_all() stf.subtract_base() # set cursors: if (not (stf.set_peak_start(gPeakStart, True))): return False if (not (stf.set_peak_end(gPeakEnd, True))): return False if (not (stf.set_base_start(gBaseStart, True))): return False if (not (stf.set_base_end(gBaseEnd, True))): return False if (not (stf.set_fit_end(gFitEnd, True))): return False if (not (stf.set_peak_mean(3))): return False if (not (stf.set_peak_direction("both"))): return False # A list for dictionary keys and values: dict_keys = [] dict_values = np.empty((gDictSize, stf.get_size_channel())) firstpass = True for n in range(0, stf.get_size_channel()): if (stf.set_trace(n) == False): print('Couldn\'t set a new trace; aborting now.') return False print('Analyzing trace %d of %d' % (n + 1, stf.get_size_channel())) # set the fit window cursors: if (not (stf.set_fit_start(stf.peak_index()))): return False # Least-squares fitting: p_dict = stf.leastsq(gFSelect) if (p_dict == 0): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): if (firstpass == True): dict_keys.append(k) dict_values[row][n] = v row = row + 1 if (firstpass): dict_keys.append("Peak amplitude") dict_values[row][n] = stf.get_peak() - stf.get_base() firstpass = False retDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: retDict[elem] = dict_values[entry].tolist() entry = entry + 1 return stf.show_table_dictlist(retDict)
def glu_iv( pulses = 13, subtract_base=True ): """Calculates an iv from a repeated series of fast application and voltage pulses. Keyword arguments: pulses -- Number of pulses for the iv. subtract_base -- If True (default), baseline will be subtracted. Returns: True if successful. """ # Some ugly definitions for the time being # Cursors are in ms here. gFitEnd = 330.6 # fit end cursor is variable gFSelect = 0 # Monoexp gDictSize = stf.leastsq_param_size( gFSelect ) + 2 # Parameters, chisqr, peak value gBaseStart = 220.5 # Start and end of the baseline before the control pulse, in ms gBaseEnd = 223.55 gPeakStart = 223.55 # Start and end of the peak cursors for the control pulse, in ms gPeakEnd = 253.55 if ( gDictSize < 0 ): print('Couldn\'t retrieve function id=%d, aborting now.'%gFSelect) return False if ( not(stf.check_doc()) ): print('Couldn\'t find an open file; aborting now.') return False # analyse iv, subtract baseline if requested: ivtools.analyze_iv( pulses ) if ( subtract_base == True ): if ( not(stf.set_base_start( gBaseStart, True )) ): return False if ( not(stf.set_base_end( gBaseEnd, True )) ): return False stf.measure() stf.select_all() stf.subtract_base() # set cursors: if ( not(stf.set_peak_start( gPeakStart, True )) ): return False if ( not(stf.set_peak_end( gPeakEnd, True )) ): return False if ( not(stf.set_base_start( gBaseStart, True )) ): return False if ( not(stf.set_base_end( gBaseEnd, True )) ): return False if ( not(stf.set_fit_end( gFitEnd, True )) ): return False if ( not(stf.set_peak_mean( 3 )) ): return False if ( not(stf.set_peak_direction( "both" )) ): return False # A list for dictionary keys and values: dict_keys = [] dict_values = np.empty( (gDictSize, stf.get_size_channel()) ) firstpass = True for n in range( 0, stf.get_size_channel() ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return False print('Analyzing trace %d of %d'%( n+1, stf.get_size_channel() ) ) # set the fit window cursors: if ( not(stf.set_fit_start( stf.peak_index() )) ): return False # Least-squares fitting: p_dict = stf.leastsq( gFSelect ) if ( p_dict == 0 ): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): if ( firstpass == True ): dict_keys.append( k ) dict_values[row][n] = v row = row+1 if ( firstpass ): dict_keys.append( "Peak amplitude" ) dict_values[row][n] = stf.get_peak()-stf.get_base() firstpass = False retDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: retDict[ elem ] = dict_values[entry].tolist() entry = entry+1 return stf.show_table_dictlist( retDict )
def timeconstants(fitwindow, pulsewindow, ichannel=0, vchannel=1): """ Compute and plot decay time constants Parameters ---------- fitwindow : (float, float), optional Window for fitting time constant (time in ms from beginning of sweep) None for current cursor settings. Default: None pulsewindow : (float, float), optional Window for voltage pulse measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None ichannel : int, optional current channel number. Default: 0 vchannel : int, optional voltage channel number. Default: 1 Returns ------- v_commands : numpy.ndarray Command voltages taus : numpy.ndarray Time constants """ import stf if not stf.check_doc(): return None nchannels = stf.get_size_recording() if nchannels < 2: sys.stderr.write( "Function requires 2 channels (0: current; 1: voltage)\n") return dt = stf.get_sampling_interval() v_commands = [] taus = [] fig = stf.mpl_panel(figsize=(12, 8)).fig fig.clear() gs = gridspec.GridSpec(4, 8) ax_currents = stfio_plot.StandardAxis( fig, gs[:3, :4], hasx=False, hasy=False) ax_voltages = stfio_plot.StandardAxis( fig, gs[3:, :4], hasx=False, hasy=False, sharex=ax_currents) for ntrace in range(stf.get_size_channel()): stf.set_trace(ntrace) stf.set_channel(ichannel) trace = stf.get_trace() ax_currents.plot(np.arange(len(trace))*dt, trace) if fitwindow is not None: stf.fit.cursor_time = fitwindow res = stf.leastsq(0, False) taus.append(res['Tau_0']) # Measure pulse amplitude stf.set_channel(vchannel) trace = stf.get_trace() ax_voltages.plot(np.arange(len(trace))*dt, trace) stf.set_peak_direction("up") stf.set_peak_mean(-1) if pulsewindow is not None: stf.peak.cursor_time = pulsewindow stf.measure() v_commands.append(stf.peak.value) stfio_plot.plot_scalebars( ax_currents, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=ichannel)) stfio_plot.plot_scalebars( ax_voltages, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=vchannel)) v_commands = np.array(v_commands) taus = np.array(taus) ax_taus = plot_iv( taus, v_commands, "ms", stf.get_yunits(channel=vchannel), fig, 122) # Reset peak computation to single sampling point stf.set_peak_mean(1) # Reset active channel stf.set_channel(ichannel) # Compute conductances: stf.show_table_dictlist({ "Voltage ({0})".format( stf.get_yunits(channel=vchannel)): v_commands.tolist(), "Taus (ms)": taus.tolist(), }) return v_commands, taus
def iv(peakwindow=None, basewindow=None, pulsewindow=None, erev=None, peakmode="both", ichannel=0, vchannel=1, exclude=None): """ Compute and plot an IV curve for currents Parameters ---------- peakwindow : (float, float), optional Window for peak measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None basewindow : (float, float), optional Window for baseline measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None pulsewindow : (float, float), optional Window for voltage pulse measurement (time in ms from beginning of sweep) None for current cursor settings. Default: None erev : float, optional End of v clamp pulse in ms or None to determine automatically. Default: None peakmode : string, optional Peak direction - one of "up", "down", "both" or "mean". Default: "up" ichannel : int, optional current channel number. Default: 0 vchannel : int, optional voltage channel number. Default: 1 exclude : list of ints, optional List of trace indices to be excluded from the analysis. Default: None Returns ------- v_commands : numpy.ndarray Command voltages ipeaks : numpy.ndarray Peak currents gpeaks : numpy.ndarray Peak normalized conductances g_fit : numpy.ndarray Half-maximal voltage and slope of best-fit Boltzmann function """ import stf if not stf.check_doc(): return None nchannels = stf.get_size_recording() if nchannels < 2: sys.stderr.write( "Function requires 2 channels (0: current; 1: voltage)\n") return dt = stf.get_sampling_interval() olddirection = stf.get_peak_direction() v_commands = [] ipeaks = [] if basewindow is not None: stf.base.cursor_time = basewindow fig = stf.mpl_panel(figsize=(12, 8)).fig fig.clear() gs = gridspec.GridSpec(4, 8) ax_currents = stfio_plot.StandardAxis(fig, gs[:3, :4], hasx=False, hasy=False) ax_voltages = stfio_plot.StandardAxis(fig, gs[3:, :4], hasx=False, hasy=False, sharex=ax_currents) for ntrace in range(stf.get_size_channel()): if exclude is not None: if ntrace in exclude: continue stf.set_trace(ntrace) stf.set_channel(ichannel) trace = stf.get_trace() ax_currents.plot(np.arange(len(trace)) * dt, trace) # Measure only downward peaks (inward currents) if peakmode is "mean": stf.set_peak_direction("up") stf.set_peak_mean(-1) else: stf.set_peak_direction(peakmode) # Set peak computation to single sampling point stf.set_peak_mean(1) if peakwindow is not None: stf.peak.cursor_time = peakwindow stf.measure() if basewindow is not None: ipeaks.append(stf.peak.value - stf.base.value) else: ipeaks.append(stf.peak.value) # Measure pulse amplitude stf.set_channel(vchannel) trace = stf.get_trace() ax_voltages.plot(np.arange(len(trace)) * dt, trace) stf.set_peak_direction("up") stf.set_peak_mean(-1) if pulsewindow is not None: stf.peak.cursor_time = pulsewindow stf.measure() v_commands.append(stf.peak.value) stfio_plot.plot_scalebars(ax_currents, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=0)) stfio_plot.plot_scalebars(ax_voltages, xunits=stf.get_xunits(), yunits=stf.get_yunits(channel=1)) v_commands = np.array(v_commands) ipeaks = np.array(ipeaks) if erev is None: # Find first zero crossing in ipeaks: for npulse in range(ipeaks.shape[0] - 1): if np.sign(ipeaks[npulse]) != np.sign(ipeaks[npulse + 1]): # linear interpolation m1 = (ipeaks[npulse + 1] - ipeaks[npulse]) / ( v_commands[npulse + 1] - v_commands[npulse]) c1 = ipeaks[npulse] - m1 * v_commands[npulse] erev = -c1 / m1 break if erev is None: sys.stderr.write( "Could not determine reversal potential. Aborting now\n") return None # Reset peak computation to single sampling point stf.set_peak_mean(1) stf.set_peak_direction(olddirection) # Reset active channel stf.set_channel(ichannel) # Compute conductances: gpeaks, g_fit = gv(ipeaks, v_commands, erev) ax_ipeaks = plot_iv(ipeaks, v_commands, stf.get_yunits(channel=ichannel), stf.get_yunits(channel=1), fig, 222) ax_ipeaks.set_title("Peak current") ax_gpeaks = plot_gv(gpeaks, v_commands, stf.get_yunits(channel=vchannel), g_fit, fig, 224) ax_gpeaks.set_title("Peak conductance") stf.show_table_dictlist({ "Voltage ({0})".format(stf.get_yunits(channel=vchannel)): v_commands.tolist(), "Peak current ({0})".format(stf.get_yunits(channel=ichannel)): ipeaks.tolist(), "Peak conductance (g/g_max)": gpeaks.tolist(), }) return v_commands, ipeaks, gpeaks, g_fit