-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathauditory_nerve2018.py
99 lines (90 loc) · 4.41 KB
/
auditory_nerve2018.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from numpy import *
from inner_hair_cell2018 import resting_potential, peak_potential
#parameters
r1=220. #reserve pool max. replenishment rate
x=700 #RRP replenishment rate (Pangrisc 2010,Chapocnikov 2014)
M=14 # Max. vesicles in the ready release pool or release sites (reasonable, ref?)
M2=60 # Max. vesicles in the second pool, fitted parameter
# with the paramaters is 250 release/s, because of refractoriness the steady state spike rate goes around 200 spike/s
refr_tail=0.6e-3 # relative refreactory period (from Peterson and Heil 2014)
abs_refractoriness=0.6e-3 # absolute refractory period (from Peterson and Heil 2014)
ss=1.5e-3 #sensitivity of release rate on IHC potential, fitted paramter
tCa=0.2e-3 #time constant of the Ca2 channel
#driven exocytosis rate is a boltzmann version of Vm, low-pass filter with the time constant of the Ca2+ channels. This is a shortcut to tune the nonlinear relationship between Vm and exocytosis rate based on AF data. Ca2+ signaling varies substantialy between synapses of the same IHC (Frank 2009,Ohn 2016). We use a shortcut Vm->Exocytosis rate, otherwise Vm->Ca2+ (at individual synapse)->exocytosis rate would require the tuning of too many parameters (here one free parameter ss, and 2 fitted parameters sp,psr)
def auditory_nerve_fiber(Vm,fs,spont):
size=len(Vm[0,:])
dt=1.0/fs
if(spont==0):
sp=1 #spont rate
psr=800 #peak spike rate, based upon Taberner and Liberman 2005
elif(spont==1):
sp=10.0
psr=1.0e3
else:
sp=68.5
psr=3.0e3
#parameters for vesicles trafficking
# psr=2.7e3
# psr=psr*4;
r=r1/M2 # replenishment rate per vesicle location
M2_steady=M2-sp/r #steady state values
Msteady=M*(M2_steady/M2-sp/x)
wt=M2_steady+zeros([1,size]) #reserve pool
qt=Msteady+zeros([1,size]) #RRP
xdt=x*dt
rdt=r*dt
#parameters for refractoriness
alpha_ref=exp(-dt/refr_tail)
relRefFraction=zeros([1,size]) #how much the firing probability decreases due to relative refractoriness
available=1.0+zeros([1,size]) #number of fibers not in a refractory state
buf_lgt=int(round(abs_refractoriness*fs)) #length of buffer to store the firing history (in order to account for absolute refractoriness)
buf_ref=zeros([buf_lgt,size],dtype=float) #buffer to store the history of firing
buf_pointer=0
pp=psr/Msteady#/(1/(1+exp(-(peak_potential-vh)/ss))) #multiplier relating the activation nonlinearity (between 0 and 1) with actual firing rate
#parameters to relate Vm with firing rate
rat=log((psr-sp)/sp) #find half activation voltage of exocytosis rate based on peak and spontaneous rate
vh=rat*ss+resting_potential
k0=sqrt(1/(1+exp(-(resting_potential-vh)/ss)))+zeros([1,size]) #driven exocytosis rate at rest
#take the square root, filter it with a first order filter and then square it. This is equivalent to a second order activation of the ion channels
alphaCa=exp(-dt/tCa)
zero_time=int(50e-3*fs)
for i in range(zero_time):
vesicleReleaseRate=pp*(k0**2)
releaseProb=vesicleReleaseRate*dt
qt[qt>M]=M
wt[wt>M2]=M2
ejected=releaseProb*qt
replenishReserve= rdt*(M2-wt)
replenishRRP=xdt*fmax(wt/M2-qt/M,0)
qt= qt + replenishRRP - ejected
wt= wt - replenishRRP + replenishReserve
firing=(available-relRefFraction)*ejected
recovered=buf_ref[buf_pointer,:]
relRefFraction=alpha_ref*relRefFraction+(1-alpha_ref)*recovered
available=available-firing+recovered
buf_ref[buf_pointer,:]=firing
buf_pointer=mod(buf_pointer+1,buf_lgt)
k=k0
kin=sqrt(1/(1+exp(-(Vm-vh)/ss)))
solution=zeros_like(Vm)
for i in range(len(kin[:,0])):
k=alphaCa*k+(1-alphaCa)*kin[i,:]
vesicleReleaseRate=pp*(k**2)
releaseProb=vesicleReleaseRate*dt
qt[qt<0]=0
wt[wt<0]=0
qt[qt>M]=M
wt[wt>M2]=M2
ejected=releaseProb*qt
replenishReserve= rdt*(M2-wt)
replenishRRP=xdt*fmax(wt/M2-qt/M,0)
qt= qt + replenishRRP - ejected
wt= wt - replenishRRP + replenishReserve
firing=(available-relRefFraction)*ejected
recovered=buf_ref[buf_pointer,:]
relRefFraction=alpha_ref*relRefFraction+(1-alpha_ref)*recovered
available=available-firing+recovered
buf_ref[buf_pointer,:]=firing
buf_pointer=mod(buf_pointer+1,buf_lgt)
solution[i,:]=firing
return solution