-
Notifications
You must be signed in to change notification settings - Fork 2
/
multiAMPA.mod
271 lines (214 loc) · 6.83 KB
/
multiAMPA.mod
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
TITLE multiple AMPA receptors
COMMENT
-----------------------------------------------------------------------------
Mechanism for handling multiple presynaptic entries to the same compartment;
up to 1000 synapses can be handled using a different pointer that must be set
for each presynaptic variable using addlink. Optimization algorithm from
Lytton, W.W., Neural Computation, in press, 1996. This mechanism allows
considerable acceleration of the simulation time if many receptors of the same
type must be simulated in the same compartment.
This file was configured for AMPA receptors. The mechanism was a first-order
kinetic model with pulse of transmitter (see Destexhe, A., Mainen, Z. and
Sejnowski, T.J. Neural Computation, 6: 14-18, 1994).
Parameters were obtained from fitting the model to whole-cell recorded AMPA
postsynaptic currents (Xiang et al., Soc Neurosci. Abstracts 18: 1350, 1992).
The fit was performed using a simplex algorithm using short pulses of
transmitter (0.5 mM during 0.3 ms).
-----------------------------------------------------------------------------
EXAMPLE OF HOW TO USE:
create POST,PRE[10] // create compartments
objectvar c // create an object
c = new multiAMPA() // create multiple AMPA kinetic synapses
POST c.loc(0.5) // localize synapse on postsyn compartment
c.gmax = 0.001 // assign max conductance of each syn (mu S)
c.allocate(10) // allocate space for 10 presyn variables
for i=0,9 { // link presynaptic variables
c.addlink(&PRE[i].v)
}
-----------------------------------------------------------------------------
WARNINGS:
- only ok for synaptic mechanisms where all weights are equal
(see Lytton paper for implementation of different weights)
Alain Destexhe, Laval University, 1995
-----------------------------------------------------------------------------
ENDCOMMENT
: defines maximal number of possible links to presynaptic variables
: this number should correpond to the number of pointers pre00, pre01, ...
: defined in the NEURON block
DEFINE MAXSYNAMPA 250
VERBATIM
static int MAXSYNAMPA = 250;
ENDVERBATIM
INDEPENDENT {t FROM 0 TO 1 WITH 1 (ms)}
NEURON {
POINT_PROCESS multiAMPA
NONSPECIFIC_CURRENT i
RANGE Ron, Roff, ri, nsyn, non, g, gmax
GLOBAL Cmax, Cdur, Alpha, Beta, Erev, Prethresh, Deadtime, Rinf, Rtau
}
UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(umho) = (micromho)
(mM) = (milli/liter)
}
PARAMETER {
dt (ms)
Cmax = 0.5 (mM) : max transmitter concentration
Cdur = 0.3 (ms) : transmitter duration (rising phase)
Alpha = 0.94 (/ms mM) : forward (binding) rate
Beta = 0.18 (/ms) : backward (unbinding) rate
Erev = 0 (mV) : reversal potential
gmax (umho) : maximum conductance of each synapse
Prethresh = 0 : voltage level nec for release
Deadtime = 1 (ms) : mimimum time between release events
}
ASSIGNED {
on[MAXSYNAMPA] : state of each synapse
TL[MAXSYNAMPA] (ms) : time since last event for each synapse
ri[MAXSYNAMPA] : state variable of each synapse
lastrelease[MAXSYNAMPA] (ms) : last release for each synapse
Ron : sum of all "on" synapses
Roff : sum of all "off" synapses
nsyn : number of synapses
non : number of synapses on
Rinf : steady state channels open
Rtau (ms) : time constant of channel binding
v (mV) : postsynaptic voltage
i (nA) : total current = g*(v - Erev)
g (umho) : total conductance
trel (ms) : temp var
ptr_array_ampa : pointer array
}
INITIAL { LOCAL j
FROM j=0 TO nsyn-1 {
on[j] = 0
TL[j] = -9e9
lastrelease[j] = -9e9
ri[j] = 0
}
Ron = 0
Roff = 0
non = 0
Rinf = Cmax*Alpha / (Cmax*Alpha + Beta)
Rtau = 1 / ((Alpha * Cmax) + Beta)
}
BREAKPOINT {
if(gmax > 0) {
SOLVE release
g = gmax * (Ron+Roff)
i = g*(v - Erev)
} else {
i = 0
}
}
PROCEDURE release() { LOCAL q,j
FROM j=0 TO nsyn-1 { : update Ron, Roff, non for each synapse
trel = ((t - lastrelease[j]) - Cdur) : time since last release ended
if (trel > Deadtime) { : ready for another release?
if (presynaptic(j) > Prethresh) { : spike occured?
on[j] = 1 : start new release
non = non + 1
lastrelease[j] = t : memorize release time
ri[j] = ri[j] * exptable( - Beta * (t-TL[j]))
: evaluate state variable
TL[j] = t : memorize last event
Ron = Ron + ri[j] : increase Ron
Roff = Roff - ri[j] : decrease Roff
if(Roff < 1e-9) { Roff = 0 } : prevent roundoff errors
}
} else if (trel < 0) { : still releasing?
: do nothing
} else if (on[j] > 0) { : end of release ?
on[j] = 0 : stop release
non = non - 1
ri[j] = Rinf + (ri[j]-Rinf) * exptable(- (t-TL[j]) / Rtau)
: evaluate state variable
TL[j] = t : memorize last event
Ron = Ron - ri[j] : decrease Ron
Roff = Roff + ri[j] : increase Roff
if(Ron < 1e-9) { Ron = 0 } : prevent roundoff errors
}
}
if(Roff > 0) { : update Roff
Roff = Roff * exptable(- Beta * dt)
if(Roff < 1e-9) { Roff = 0 } : prevent roundoff errors
}
if(non > 0) { : update Ron
q = non * Rinf
Ron = q + (Ron - q) * exptable(- dt / Rtau)
}
}
FUNCTION exptable(x) {
TABLE FROM -25 TO 25 WITH 10000
if ((x > -25) && (x < 25)) {
exptable = exp(x)
} else {
exptable = 0.
}
}
:FUNCTION exptable(x) {
: TABLE FROM -10 TO 10 WITH 10000
:
: if ((x > -10) && (x < 10)) {
: exptable = exp(x)
: } else {
: exptable = 0.
: }
:}
:FUNCTION exptable(x) {
: if(x > -50) {
: exptable = exp(x)
: } else {
: exptable = 0.
: }
:}
:-------------------------------------------------------------------
: Procedures for pointer arrays in nmodl
: create a pointer array and link its pointers to variables passed
: from hoc (adapted from Mike Hines)
:-------------------------------------------------------------------
VERBATIM
#define ppampa ((double***)(&(ptr_array_ampa)))
extern double* hoc_pgetarg();
ENDVERBATIM
:
: Procedure to allocate space for n pointers
:
PROCEDURE allocate(n) {
VERBATIM
if (*ppampa) {
free(*ppampa);
}
*ppampa = ((double**) hoc_Ecalloc((int)_ln, sizeof(double *))), hoc_malchk();
ENDVERBATIM
}
:
: procedure to get the value of a presynaptic variable
: index is the number of the presynaptic var
:
FUNCTION presynaptic(index) {
VERBATIM
if(_lindex >= nsyn) {
printf("Warning: attempt to use pointer outside range\n");
printf(" trying to use pointer number %d\n",(int)_lindex);
printf(" but number of defined pointers was nsyn=%d.\n",(int) nsyn);
}
_lpresynaptic = *((*ppampa)[(int)_lindex]);
ENDVERBATIM
}
:
: procedure to add a new presynaptic variable
: the address of the variable is passed as argument (from hoc)
: a new pointer is then linked to that variable
:
PROCEDURE addlink() {
VERBATIM
if(++nsyn > MAXSYNAMPA) {
printf("Exceeding maximum of allowed links MAXSYNAMPA=%d\n",MAXSYNAMPA);
printf(" edit the nmodl code to increase the maximum allowed.\n");
exit(-1);
}
(*ppampa)[(int)(nsyn-1)] = hoc_pgetarg(1);
ENDVERBATIM
}