Source code for neuronunit.capabilities.spike_functions
"""Auxiliary helper functions for analysis of spiking."""
import numpy as np
import neo
from elephant.spike_train_generation import threshold_detection
from quantities import mV, ms
from numba import jit
import sciunit
import math
[docs]def get_spike_train(vm, threshold=0.0*mV):
"""
Inputs:
vm: a neo.core.AnalogSignal corresponding to a membrane potential trace.
threshold: the value (in mV) above which vm has to cross for there
to be a spike. Scalar float.
Returns:
a neo.core.SpikeTrain containing the times of spikes.
"""
spike_train = threshold_detection(vm, threshold=threshold)
return spike_train
[docs]def spikes2amplitudes(spike_waveforms):
"""
IN:
spike_waveforms: Spike waveforms, e.g. from get_spike_waveforms().
neo.core.AnalogSignal
OUT:
1D numpy array of spike amplitudes, i.e. the maxima in each waveform.
"""
n_spikes = spike_waveforms.shape[1]
ampls = np.array([spike_waveforms[:, i].max() for i in range(n_spikes)])
if n_spikes:
# Add units.
ampls = ampls * spike_waveforms[:, 0].units
return ampls
[docs]def spikes2widths(spike_waveforms):
"""
IN:
spike_waveforms: Spike waveforms, e.g. from get_spike_waveforms().
neo.core.AnalogSignal
OUT:
1D numpy array of spike widths, specifically the full width
at half the maximum amplitude.
"""
n_spikes = spike_waveforms.shape[1]
widths = []
for i in range(n_spikes):
s = spike_waveforms[:, i].squeeze()
try:
x_high = int(np.argmax(s))
high = s[x_high]
except:
high = 0
for k in s:
for i, j in enumerate(k):
if j > high:
high = j
x_high = i
if x_high > 0:
try: # Use threshold to compute half-max.
y = np.array(s)
dvdt = np.diff(y)
trigger = dvdt.max()/10
x_loc = int(np.where(dvdt >= trigger)[0][0])
thresh = (s[x_loc]+s[x_loc+1])/2
mid = (high+thresh)/2
except: # Use minimum value to compute half-max.
sciunit.log(("Could not compute threshold; using pre-spike "
"minimum to compute width"))
low = np.min(s[:x_high])
mid = (high+low)/2
n_samples = sum(s > mid) # Number of samples above the half-max.
widths.append(n_samples)
widths = np.array(widths, dtype='float')
if n_spikes:
# Convert from samples to time.
widths = widths*spike_waveforms.sampling_period
return widths
[docs]def spikes2thresholds(spike_waveforms):
"""
IN:
spike_waveforms: Spike waveforms, e.g. from get_spike_waveforms().
neo.core.AnalogSignal
OUT:
1D numpy array of spike thresholds, specifically the membrane potential
at which 1/10 the maximum slope is reached.
If the derivative contains NaNs, probably because vm contains NaNs
Return an empty list with the appropriate units
"""
n_spikes = spike_waveforms.shape[1]
thresholds = []
for i in range(n_spikes):
s = spike_waveforms[:, i].squeeze()
s = np.array(s)
dvdt = np.diff(s)
for j in dvdt:
if math.isnan(j):
return thresholds * spike_waveforms.units
trigger = dvdt.max()/10
x_loc = np.where(dvdt >= trigger)[0][0]
thresh = (s[x_loc]+s[x_loc+1])/2
thresholds.append(thresh)
return thresholds * spike_waveforms.units