model of DCN pyramidal neuron
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
3.1 KiB

from __future__ import print_function
from scipy import interpolate
import numpy as np
def find_point(x, y, peakindex, val, direction="left", limits=None):
"""
Given a waveform defined by *x* and *y* arrays, return the first time
at which the waveform crosses (y[peakindex] * val). The search begins at
*peakindex* and proceeds in *direction*.
Optionally, *limits* may specify a smaller search region in the form of
(t0, t1, dt).
"""
# F = interpolate.UnivariateSpline(x, y, s=0) # declare function
# To find x at y then do:
istart = 0
iend = len(y)
if limits is not None:
istart = int(limits[0] / limits[2])
iend = int(limits[1] / limits[2])
yToFind = y[peakindex] * val
if direction == "left":
yreduced = np.array(y[istart:peakindex]) - yToFind
try:
Fr = interpolate.UnivariateSpline(x[istart:peakindex], yreduced, s=0)
except:
print("find_point: insufficient time points for analysis")
print("arg lengths:", len(x[istart:peakindex]), len(yreduced))
print("istart, peakindex: ", istart, peakindex)
print("ytofine: ", yToFind)
raise
res = float("nan")
return res
res = Fr.roots()
if len(res) > 1:
res = res[-1]
else:
yreduced = np.array(y[peakindex:iend]) - yToFind
try:
Fr = interpolate.UnivariateSpline(x[peakindex:iend], yreduced, s=0)
except:
print("find_point: insufficient time points for analysis?")
print("arg lengths:", len(x[peakindex:iend]), len(yreduced))
raise
res = float("nan")
return res
res = Fr.roots()
if len(res) > 1:
res = res[0]
# pdb.set_trace()
try:
res.pop()
except:
pass
if not res: # tricky - an empty list is False, but does not evaluate to False
res = float("nan") # replace with a NaN
else:
res = float(res) # make sure is just a simple number (no arrays)
return res
def find_crossing(data, start=0, direction=1, threshold=0):
"""Return the index at which *data* crosses *threshold*, starting
at index *start* and proceeding in *direction* (+/-1).
The value returned is a float indicating the interpolated index
position where the data crosses threshold, or NaN if the threshold was
never crossed.
"""
# Note: this function is very similar in purpose to find_point, but was
# added due to issues with interpolate.UnivariateSpline
assert direction in (1, -1)
cross_rising = data[start] < threshold
def test(x):
if cross_rising:
return x > threshold
else:
return x < threshold
while True:
next_ind = start + direction
if next_ind < 0 or next_ind >= len(data):
return np.nan
if test(data[next_ind]):
# crossed; return interpolated value
s1 = data[next_ind] - threshold
s2 = threshold = data[start]
return (next_ind * s2 + start * s1) / (s2 + s1)
start = next_ind