Example #1
0
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
Example #2
0
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
Example #3
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))
Example #4
0
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())
Example #5
0
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())
Example #6
0
def analyze_iv(pulses, trace_start=0, factor=1.0):
    """Creates an IV for the currently active channel.

    Keyword arguments:
    pulses --      Number of pulses for the IV.
    trace_start -- ZERO-BASED index of the first trace to be
                   used for the IV. Note that this is one less
                   than what is diplayed in the drop-down box.
    factor --      Multiply result with an optional factor, typically
                   from some external scaling.
    Returns:
    True upon success, False otherwise.
    """

    if (stf.check_doc() == False):
        print("Couldn\'t find an open file; aborting now.")
        return False

    if (pulses < 1):
        print("Number of pulses has to be greater or equal 1.")
        return False

    # create an empty array (will contain random numbers)
    channel = list()
    for m in range(pulses):
        # A temporary array to calculate the average:
        set = np.empty((int(
            (stf.get_size_channel() - m - 1 - trace_start) / pulses) + 1,
                        stf.get_size_trace(trace_start + m)))
        n_set = 0
        for n in range(trace_start + m, stf.get_size_channel(), pulses):
            # Add this trace to set:
            set[n_set, :] = stf.get_trace(n)
            n_set = n_set + 1

        # calculate average and create a new section from it, multiply:
        channel.append(np.average(set, 0) * factor)

    stf.new_window_list(channel)

    return True
Example #7
0
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)
Example #8
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))
Example #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
Example #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
Example #11
0
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 )
Example #12
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
Example #13
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