Menu

KS Workbench How-to's

Keisuke Sehara

KS Workbench How-to's

Here I describe brief instructions about how you can use KS Workbench.

<Table of Contents>

Managing datasets

storage.DataModel class

KS Workbench heavily engage this class because of its ability to easily reference instances' attributes. In DataModel object, the following expressions mean the same:

:::python
model["attrname"]
model.attrname

Thus you don't have to quote every time you want access to the attributes, but still you can use bracket-based referencing for easy automation/looping.

Loading a wave

Case 1: test pulses + current injections

:::python
w = vivo.TestPulseWave.loadWave('t3')   # for wave name 't3'

It will do the analyses for test pulses and action potentials. Adding 'checkresistance=True' or 'checkAP=True' will cause the function to generate plots.

<Structure of a wave object>
R = (duration x sweeps)
T = (number of test pulses per sweep x sweeps)

  • w: the wave object
    • v: raw voltage traces (shape: R)
    • stim: raw stimulus traces (shape: R)
    • test: raw test-pulse traces
    • stimremoved: only stimulus artifacts removed from 'v' (just dropping samples as NaN)
    • testremoved: only test-pulse artifacts removed from 'v' (interpolating the corresponding periods with linear traces)
    • bothremoved: both stimulus and test-pulse artifacts removed from 'v'
    • testpulses: information about test pulses (in current-clamp mode)
      • baseline: baseline membrane potential just before the test pulse (number of test pulses per sweep x sweeps)
      • response: the response membrane potential (in mV) upon beginning of the test pulse ("_post" corresponds to the ending phase)
      • resistance: the membrane resistance, calculated as (response - baseline)/injected-current
      • curves: the coefficients for the fitted exponential curve (num test pulses x sweeps x num coefficients)
      • baseline_post:
      • response_post:
      • resistance_post:
      • inj_start: sample index from which (inclusive) the stimulus starts
      • inj_end: sample index at which (exclusive?) the stimulus ends
      • inj_value: the value of the test pulse
    • stimpulses: information about stimuli
      • fromidx: sample index from which (inclusive) the stimulus starts
      • toidx: sample index at which (exclusive) the stimulus ends
      • length: length (in samples) of the stimulus pulse
      • value: value (in pA in current clamp, or other appropriate units) of the stimulus pulse (can be negative)
      • window: recording trace during the stimulus pulse
    • AP: information about action potentials generated during recording
      • number: number of action potential generation detected for each sweep
      • threshold: threshold of action potential generation detected for each sweep
      • latency: latency of action potential generation (with respect to stimulus pulse initiation) detected for each sweep
      • response: action potential generation during stimulus pulses
        • number:
        • threshold:
        • latency:
      • first: the first action potential detected during stimulus pulses
        • index: sample index (from the beginning of recorded sweep) of the first action potential
        • threshold:
        • latency:

Case 2: current injections only

:::python
w = igor.IgorWave.loadwave('t3', attrnames=('v', 'stim')    # for wave name 't3'
w.AP = detect2.analyze_stimulus_pulses(w.v, w.stim, wavename=w.name, check=True)    # plots detected AP when 'check = True'

Use of TestPulseWave.loadwave() will raise an error.

<Structure of the object>

  • w: the wave object
    • v: raw voltage traces (shape: R)
    • stim: raw stimulus traces (shape: R)
    • AP: information about action potentials generated during recording
      • number: number of action potential generation detected for each sweep
      • threshold: threshold of action potential generation detected for each sweep
      • latency: latency of action potential generation (with respect to stimulus pulse initiation) detected for each sweep
      • response: action potential generation during stimulus pulses
        • number:
        • threshold:
        • latency:
      • first: the first action potential detected during stimulus pulses
        • index: sample index (from the beginning of recorded sweep) of the first action potential
        • threshold:
        • latency:

Working with Up/Down states

Prerequisite

You need to have scikit-learn module to work with Up/Down states.

Preparation of data objects

For waves with test/stimulus pulses, there is an easy way:

:::python
w = updown.prepare_updown_GMM('t3') # you don't even have to load the wave

<Structure of the object>
In addition to what's described above, you'll get following properties:

  • w
    • offset: slow fluctuation component of sweeps
    • residual: sweeps without slow fluctuation components
    • smoothed_residual: smoothed (i.e. high frequency-removed) residual sweeps
    • updown: information about Up/Down states
      • GMM: a Gaussian mixture model (GMM) object, which contains any fitting information
      • stateobj: an updown.StateStructure object, which takes care of Up/Down state information
      • testphases: an easy-access matrix for plot-phases of test pulses
      • stimphases: an easy-access array for plot-phases of stimulus pulses

Otherwise you need to perform stepwise calculation:

:::python
## (1) preparation of the 'filtered' membrane potentials
offsetdia = 30000  # diameter for offset calculation, for a HPF purpose
smoothdia = 500    # diameter for smoothing residual component, for an LPF purpose
w = igor.IgorWave.loadwave( 't3', attrnames=('v', 'stim') ) # load the wave as an IgorWave object

w.removed = vivo.remove_artifacts( w.v, w.stim, window_pre=-2, window_post=100,
                    interpolation='none' ) # remove stimulus pulse-derived artifacts
w.offset, w.residual = waves.subtract_offset( w.removed, offsetdia,
                    border=True, check=True, wavename=w.name ) # subtract slow fluctuations in the membrane potential (check=True for plotting)
w.smoothed_residual = waves.fast_smooth( w.residual, int(smoothdia/2), border=True ) # further smooth the residual component to filter out fast fluctuations

## (2) Gaussian mixture fitting
g = updown.fit_GMM( waves.validate(w.smoothed_residual), k=3, iteration=3, verbose=True, check=True,
                title='Histogram for residual component, '+w.name, xlabel='Residual [mV]',
                ylabel='Count', figname="fitting_"+w.name, legend=True ) # fit a GMM to the Vmem histogram
stateobj = updown.StateStructure.from_GMM( g, w.smoothed_residual, check=False, wavename=w.name)                        # generate a StateStructure object of the wave from the extracted GMM info

## (3) make all the information accessible from the wave, just in case
info = storage.DataModel()
info.GMM = g
info.stateobj = stateobj
w.updown = info

By this way, you can obtain a similar dataset, except for that you don't have test pulse-related properties.

sklearn.mixture.GMM class

This class represents Gaussian mixture model (GMM) fitting. It contains basic properties such as:

  • means_: the mean values (e.g. of Vmem histogram)
  • covars_: the variance/covariance values
  • weights_: the weight/proportion of different Gaussians in the model

In addition, if it was generated through updown.fit_GMM(), updown.calculate_updown_GMM() or updown.prepare_updown_GMM(), it should have the following attributes:

  • states_: an array of dictionaries sorted as (Down, Intermediate, Up), containing 'mu', 'sigma' and 'weight' keys
  • bic_: BIC values of the fitting occurred during fit_GMM() execution

Variables in 'updown' module

Variables in updown module are prepared so that you don't have to think (so much) about the order of states, or what color you use.

  • updown.DOWN, updown.UP, updown.INTERMEDIATE: the indices of each state when they are represented in an array (e.g. in g.states_ array)
  • updown.types['down'], updown.types['up'], updown.types['intermediate']: the same values, for string-based referencing
  • updown.levels: an array that contains -1 for Down, 1 for Up and 0 for Intermediate; may be used for plotting state transitions during recording
  • updown.colors, updown.colors2: arrays that can be used when plotting (e.g. blue for Down, red for Up, yellow for Intermediate)

'Plot phases'

In order to visually examine where any given time point is in terms of Up/Down states, I introduced a concept of 'plot phases', which can handle transition from one state to another, as well as time points within one state. There are two modes of phases depending on whether or not you 'look ahead' from the current state:

  • Look-ahead mode: this mode distinguishes two Down-to-Intermediate transitions, if one actually goes to Up state from here and the other does not. Similarly, two Down states are distinguished depending on whether or not it shifts to Up state in the next transition.
  • Non look-ahead mode: in this mode there are only four states: Down, Down-to-Up Intermediate, Up and Up-to-Down Intermediate

You can specify the mode using 'lookahead' boolean keyword argument of plot***() functions/methods. It is also possible to change the default mode by changing updown.lookahead_by_default variable.

updown.State class

This class represents a single period of a certain state during a sweep.

  • state: the state of this object. Can be updown.UP, updown.DOWN, or updown.INTERMEDIATE.
  • fromindex: sample index when this state starts (inclusive)
  • toindex: sample index when this state ends (inclusive)
  • indices: sample indices that this state covers (left inclusive, right exclusive; just like how slicing works in python)
  • length: duration of this state in samples
  • proceed: set when the state is Up or Down. If this state ends up in shifting to another state (Up->Down, Down->Up), it is set True
  • prev: the previous State object, or None if it is the first object in the sweep
  • next: the next State object, or None if it is the last object in the sweep

updown.StateStructure class

This class handles a sequence of state transition in a wave. You can obtain State objects by accessing like:

:::python
state = stateobj[0][2]  # State object #2 in sweep #0

You can obtain the plot phases like below:

:::python
ph = stateobj.plotphase(50000, 3, lookahead=True)   # sample index 50000 in sweep #3, in look-ahead mode

Project Members:


MongoDB Logo MongoDB