Exemplo n.º 1
0
def plot_traces(plotwindow=None, ichannel=0, vchannel=1):
    """
    Show traces in a figure

    Parameters
    ----------
    plotwindow : (float, float), optional
        Plot window (in ms from beginning of trace)
        None for whole trace. Default: None
    ichannel : int, optional
        current channel number. Default: 0
    vchannel : int, optional
        voltage channel number. Default: 1
    """

    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()

    fig = stf.mpl_panel(figsize=(12, 8)).fig
    fig.clear()
    gs = gridspec.GridSpec(4, 1)
    ax_currents = stfio_plot.StandardAxis(
        fig, gs[:3, 0], hasx=False, hasy=False)
    ax_voltages = stfio_plot.StandardAxis(
        fig, gs[3:, 0], hasx=False, hasy=False, sharex=ax_currents)
    if plotwindow is not None:
        istart = int(plotwindow[0]/dt)
        istop = int(plotwindow[1]/dt)
    else:
        istart = 0
        istop = None

    for ntrace in range(stf.get_size_channel()):
        stf.set_trace(ntrace)
        stf.set_channel(ichannel)
        trace = stf.get_trace()[istart:istop]

        ax_currents.plot(np.arange(len(trace))*dt, trace)

        # Measure pulse amplitude
        stf.set_channel(vchannel)
        trace = stf.get_trace()[istart:istop]
        ax_voltages.plot(np.arange(len(trace))*dt, trace)

    # Reset active channel
    stf.set_channel(ichannel)

    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))
Exemplo n.º 2
0
    def plot_screen(self):
        import stf

        tsl = []
        try:
            l = stf.get_selected_indices()
            for idx in l:
                tsl.append(
                    stfio_plot.Timeseries(stf.get_trace(idx),
                                          stf.get_sampling_interval(),
                                          yunits=stf.get_yunits(),
                                          color='0.2'))
                fit = stf.get_fit(idx)
                if fit is not None:
                    self.axes.plot(fit[0],
                                   fit[1],
                                   color='0.4',
                                   alpha=0.5,
                                   lw=5.0)
        except:
            pass

        tsl.append(
            stfio_plot.Timeseries(stf.get_trace(),
                                  stf.get_sampling_interval(),
                                  yunits=stf.get_yunits()))
        if stf.get_size_recording() > 1:
            tsl2 = [
                stfio_plot.Timeseries(
                    stf.get_trace(trace=-1,
                                  channel=stf.get_channel_index(False)),
                    stf.get_sampling_interval(),
                    yunits=stf.get_yunits(
                        trace=-1, channel=stf.get_channel_index(False)),
                    color='r',
                    linestyle='-r')
            ]
            stfio_plot.plot_traces(tsl,
                                   traces2=tsl2,
                                   ax=self.axes,
                                   textcolor2='r',
                                   xmin=stf.plot_xmin(),
                                   xmax=stf.plot_xmax(),
                                   ymin=stf.plot_ymin(),
                                   ymax=stf.plot_ymax(),
                                   y2min=stf.plot_y2min(),
                                   y2max=stf.plot_y2max())
        else:
            stfio_plot.plot_traces(tsl,
                                   ax=self.axes,
                                   xmin=stf.plot_xmin(),
                                   xmax=stf.plot_xmax(),
                                   ymin=stf.plot_ymin(),
                                   ymax=stf.plot_ymax())
        fit = stf.get_fit()
        if fit is not None:
            self.axes.plot(fit[0], fit[1], color='0.2', alpha=0.5, lw=5.0)
Exemplo n.º 3
0
 def plot_screen(self):
     import stf
     
     tsl = []
     try:
         l = stf.get_selected_indices()
         for idx in l:
             tsl.append(stfio_plot.Timeseries(stf.get_trace(idx), 
                                              stf.get_sampling_interval(),
                                              yunits = stf.get_yunits(),
                                              color='0.2'))
             fit = stf.get_fit(idx)
             if fit is not None:
                 self.axes.plot(fit[0], fit[1], color='0.4', alpha=0.5, lw=5.0)
     except:
         pass
     
     tsl.append(stfio_plot.Timeseries(stf.get_trace(),
                                      stf.get_sampling_interval(),
                                      yunits = stf.get_yunits()))
     if stf.get_size_recording()>1:
         tsl2 = [stfio_plot.Timeseries(stf.get_trace(trace=-1, channel=stf.get_channel_index(False)),
                                       stf.get_sampling_interval(),
                                       yunits = stf.get_yunits(trace=-1, channel=stf.get_channel_index(False)),
                                       color='r', linestyle='-r')]
         stfio_plot.plot_traces(tsl, traces2=tsl2, ax=self.axes, textcolor2 = 'r',
                                xmin=stf.plot_xmin(), xmax=stf.plot_xmax(),
                                ymin=stf.plot_ymin(), ymax=stf.plot_ymax(), 
                                y2min=stf.plot_y2min(), y2max=stf.plot_y2max())
     else:
         stfio_plot.plot_traces(tsl, ax=self.axes,
                                xmin=stf.plot_xmin(), xmax=stf.plot_xmax(),
                                ymin=stf.plot_ymin(), ymax=stf.plot_ymax())
     fit = stf.get_fit()
     if fit is not None:
         self.axes.plot(fit[0], fit[1], color='0.2', alpha=0.5, lw=5.0)
Exemplo n.º 4
0
def savemat():
    """
    Save electrophysiology recordings to ephysIO HDF5-based Matlab
    v7.3 (.mat) files 
    """

    # Import required modules for file IO
    from Tkinter import Tk
    import tkFileDialog
    from gc import collect

    # Use file save dialog to obtain file path
    root = Tk()
    opt = dict(defaultextension='.mat',
               filetypes=[('MATLAB v7.3 (HDF5) file', '*.mat'),
                          ('All files', '*.*')])
    if 'savecwd' not in globals():
        global savecwd
    else:
        opt['initialdir'] = savecwd
    filepath = tkFileDialog.asksaveasfilename(**opt)
    root.destroy()

    if filepath != '':

        # Move to file directoty
        savecwd = filepath.rsplit('/', 1)[0]
        import os
        print filepath
        os.chdir(savecwd)
        filename = filepath.rsplit('/', 1)[1]

        # Get data from active Stimfit window
        import stf
        import numpy as np
        n = stf.get_size_channel()
        array = np.array([stf.get_trace(i).tolist() for i in range(n)])
        if np.any(np.isnan(array)) | np.any(np.isinf(array)):
            raise ValueError(
                "nan and inf values cannot be parsed into ephysIO")
        if stf.get_yunits() == 'pA':
            yunit = 'A'
            array = 1.0e-12 * array
        elif stf.get_yunits() == 'mV':
            yunit = 'V'
            array = 1.0e-03 * array
        else:
            yunit = stf.get_yunits()
            #print "Warning: Expected Y dimension units to be either pA or mV"

        # Create X dimension properties
        if stf.get_xunits() == 'ms':
            xunit = 's'
            xdiff = np.array([[1.0e-03 * stf.get_sampling_interval()]])
        else:
            raise ValueError("Expected X dimension units to be ms")

        # Calculate X dimension and add to array
        x = xdiff * np.arange(0.0, np.shape(array)[1], 1, 'float64')
        array = np.concatenate((np.array(x, ndmin=2), array), 0)

        # Get data recording notes
        notes = stf.get_recording_comment().split('\n')
        names = None

        import ephysIO
        ephysIO.MATsave(filepath, array, xunit, yunit, names, notes)

    collect()

    return
Exemplo n.º 5
0
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
Exemplo n.º 6
0
def plot_traces(plotwindow=None, ichannel=0, vchannel=1):
    """
    Show traces in a figure

    Parameters
    ----------
    plotwindow : (float, float), optional
        Plot window (in ms from beginning of trace)
        None for whole trace. Default: None
    ichannel : int, optional
        current channel number. Default: 0
    vchannel : int, optional
        voltage channel number. Default: 1
    """

    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()

    fig = stf.mpl_panel(figsize=(12, 8)).fig
    fig.clear()
    gs = gridspec.GridSpec(4, 1)
    ax_currents = stfio_plot.StandardAxis(fig,
                                          gs[:3, 0],
                                          hasx=False,
                                          hasy=False)
    ax_voltages = stfio_plot.StandardAxis(fig,
                                          gs[3:, 0],
                                          hasx=False,
                                          hasy=False,
                                          sharex=ax_currents)
    if plotwindow is not None:
        istart = int(plotwindow[0] / dt)
        istop = int(plotwindow[1] / dt)
    else:
        istart = 0
        istop = None

    for ntrace in range(stf.get_size_channel()):
        stf.set_trace(ntrace)
        stf.set_channel(ichannel)
        trace = stf.get_trace()[istart:istop]

        ax_currents.plot(np.arange(len(trace)) * dt, trace)

        # Measure pulse amplitude
        stf.set_channel(vchannel)
        trace = stf.get_trace()[istart:istop]
        ax_voltages.plot(np.arange(len(trace)) * dt, trace)

    # Reset active channel
    stf.set_channel(ichannel)

    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))
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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