-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsns.inc
218 lines (188 loc) · 6 KB
/
sns.inc
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
: $Id: sns.inc,v 1.29 1997/03/25 00:05:44 billl Exp $
COMMENT
USAGE: for most receptors
*****************************************************************************
NEURON {
POINT_PROCESS NAME
}
PARAMETER {
Cdur = 1.08 (ms) : transmitter duration (rising phase)
Alpha = 1 (/ms mM) : forward (binding) rate
Beta = 0.02 (/ms) : backward (unbinding) rate
Erev = -80 (mV) : reversal potential
Deadtime = 1 (ms) : mimimum time between release events
GMAX = 1 (umho) : reference conductance
DELAY = 0 (ms)
}
INCLUDE "sns.inc"
*****************************************************************************
USAGE: for NMDA receptor
*****************************************************************************
NEURON{ POINT_PROCESS NMDA
RANGE B
}
PARAMETER {
mg = 1. (mM) : external magnesium concentration
Cdur = 1. (ms) : transmitter duration (rising phase)
Alpha = 4. (/ms mM) : forward (binding) rate
Beta = 0.0067 (/ms) : backward (unbinding) rate 1/150
Erev = 0. (mV) : reversal potential
Deadtime = 1 (ms) : mimimum time between release events
GMAX = 1 (umho) : reference conductance
DELAY = 0 : axonal delay
}
ASSIGNED { B }
INCLUDE "sns.inc"
: EXTRA BREAKPOINT MUST BE BELOW THE INCLUDE
BREAKPOINT {
rates(v)
g = g * B : but don't really need to readjust conductance
i = i * B : i = g*(v - Erev)
}
PROCEDURE rates(v(mV)) {
TABLE B
DEPEND mg
FROM -100 TO 80 WITH 180
B = 1 / (1 + exp(0.062 (/mV) * -v) * (mg / 3.57 (mM)))
}
*****************************************************************************
see end for implementation comments
ENDCOMMENT
INDEPENDENT {t FROM 0 TO 1 WITH 1 (ms)}
NEURON {
NONSPECIFIC_CURRENT i
RANGE R, g
RANGE Ron, Roff, synon : accessible for debugging
GLOBAL GMAX, DELAY, Cdur, Alpha, Beta, Erev, Deadtime, Rinf, Rtau, q10, exptemp
}
INCLUDE "snsarr.inc" : array management routines
UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(umho) = (micromho)
(mM) = (milli/liter)
}
PARAMETER {
celsius
q10 = 1.
exptemp = 37.
}
ASSIGNED {
v (mV) : postsynaptic voltage
i (nA) : current = g*(v - Erev)
g (umho) : conductance
R : fraction of open channels, Ron + Roff
Ron : activation state while syn's turned on
Roff : activation state for decaying syns
Rinf : steady state channels open
Rtau (ms) : time constant of channel binding
synon : number of syns turned on at a time
drive : drive for ODE toward Rinf
qq10 : rate speed-up due to Q10
edt : rate factor for Ron
edb : decay factor for Roff
edc : rate factor for increasing Rcurr
dt
}
INITIAL {
: initialize GLOBAL parameters, in case user changes one
: this repeats unnecessarily for each instance
Rinf = Alpha / (Alpha + Beta)
qq10 = q10^((celsius-exptemp)/10.)
Rtau = 1 / (Alpha + Beta) / qq10
edt = exp(-dt/Rtau)
edb = exp(-Beta * dt)
edc = exp(-Cdur/Rtau)
drive = Rinf * (1. - edt)
: initialize RANGE parameters
synon = 0
R = 0
Ron = 0
Roff = 0
: do not initialize QUEU if it hasn't been allocated by init_arrays()
if (nsyn > 0) {
initq()
} else {
VERBATIM
printf("WARNING nsyn==0 ");
ENDVERBATIM
}
}
BREAKPOINT {
SOLVE release
R = Ron + Roff
g = GMAX * R
i = g*(v - Erev)
}
PROCEDURE release() {
if (nsyn>0) { : do not try accessing a queue that hasn't been allocated
VERBATIM
int who;
QueU *pqueu;
SynS *ppst;
pqueu = (QueU *)((unsigned long) queu);
while (t >= pqueu[(int)begsyn].time) { /* somebody spiked delay time ago */
ppst = (SynS *)((unsigned long) lpst);
who = pqueu[(int)begsyn].index; /* who spiked? */
/* calculate the decay that occurred since last activity ended */
ppst[who].Rcurr *= exptable(-Beta*(t-ppst[who].last));
/* transfer the value from Roff to Ron */
Ron += ppst[who].Rcurr;
Roff -= ppst[who].Rcurr;
synon += ppst[who].pgm; /* weight syn by percent gmax */
ppst[who].last = t + Cdur; /* time when syn will turn off */
popqh1(Cdur); /* next (also add Cdur to value on the queu) */
}
while (t >= pqueu[(int)endsyn].time) { /* somebody needs to be turned off */
ppst = (SynS *)((unsigned long) lpst); /* will do this assign twice in rare cases */
who = pqueu[(int)endsyn].index; /* who spiked? */
/* solve Rcurr forward in time till end of syn activity */
ppst[who].Rcurr = ppst[who].pgm*Rinf*(1.-edc) + ppst[who].Rcurr*edc;
Ron -= ppst[who].Rcurr;
Roff += ppst[who].Rcurr; /* transfer from on to off */
synon -= ppst[who].pgm; /* remove this percent of gmax */
if (synon<1e-11 && synon>-1e-11) { synon=0.; }
if (synon==0. || Ron < 0.) { Ron = 0.; }
popqh2(); /* next */
}
/* update R */
if (synon > 0) { /* one or more synapses turned on? */
Ron = synon*drive + Ron * edt; /* drive R toward Rinf */
}
Roff *= edb; /* Roff always decays toward 0 */
return 0;
ENDVERBATIM
}
}
FUNCTION getR(x) {
VERBATIM {
SynS pst;
double rnow;
double end, rinf;
pst = (PSTCAST[(int)_lx]);
end = pst.last;
rinf = pst.pgm * Rinf;
if (end < 0.) { /* not yet turned on */
rnow = 0.;
} else if (t >= end - dt/2) { /* decay */
rnow = pst.Rcurr * exptable(-Beta*(t-end));
} else { /* turning on */
rnow = rinf + (pst.Rcurr - rinf)*exptable((t-(end-Cdur))/(-Rtau));
}
if (pst.pgm != 0.) {
_lgetR = rnow/pst.pgm; /* scale it to 1 so it looks like a state variable */
} else {
_lgetR = 0.;
}
}
ENDVERBATIM
}
: only gets called for negative numbers
FUNCTION exptable(x) {
TABLE FROM -10 TO 0 WITH 1000
if ((x > -10) && (x < 0)) {
exptable = exp(x)
} else {
exptable = 0.
}
}