-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLUTsyn_NMDA_5th_E3_dtc.mod
More file actions
389 lines (322 loc) · 8.29 KB
/
LUTsyn_NMDA_5th_E3_dtc.mod
File metadata and controls
389 lines (322 loc) · 8.29 KB
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
COMMENT
LUTsyn_NMDA_5th_E3_dtc.mod
This file implements the LUTsyn synapse model described in (Pham, 2021) for NMDA receptors
July 13, 2021
Duy-Tan Jonathan Pham
This software is Copyright © 2021 The University of Southern
California. All Rights Reserved.
Permission to use, copy, modify, and distribute this software
and its documentation for educational, research and non-profit
purposes, without fee, and without a written agreement is
hereby granted, provided that the above copyright notice, this
paragraph and the following three paragraphs appear in all copies.
Permission to make commercial use of this software may be obtained by contacting:
USC Stevens Center for Innovation
University of Southern California
1150 S. Olive Street, Suite 2300
Los Angeles, CA 90115, USA
This software program and documentation are copyrighted by The
University of Southern California. The software program and
documentation are supplied "as is", without any accompanying
services from USC. USC does not warrant that the operation of the
program will be uninterrupted or error-free. The end-user understands
that the program was developed for research purposes and is advised
not to rely exclusively on the program for any reason.
IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN CALIFORNIA BE
LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
UNIVERSITY OF SOUTHERN CALIFORNIA HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF SOUTHERN CALIFORNIA
SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
BASIS, AND THE UNIVERSITY OF SOUTHERN CALIFORNIA HAS NO OBLIGATIONS
TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
ENDCOMMENT
NEURON {
POINT_PROCESS LUTsyn_NMDA_5th_E3_dtc
RANGE gain, basis_gain, tau1, tau2, tau3, tau4, t4, t3, t2, t1, t0, MEM, scalar, order, open, gran, index
RANGE g0, g1, g2, alpha, g, e, open_Mg, nbNMDAR, C, B, E, factor, wf, v1
RANGE tc1, tc2, tc3, wtc2, wtc3
RANGE o1_tc1, o1_tc2, o1_tc3, o2_tc1, o2_tc2, o2_tc3, o3_tc1, o3_tc2, o3_tc3, o4_tc1, o4_tc2, o4_tc3, o5_tc1, o5_tc2, o5_tc3
RANGE factor1, factor2, factor3, factor4, factor5
RANGE o1_spks, o2_spks, o3_spks, o4_spks, o5_spks
POINTER gain_array
NONSPECIFIC_CURRENT i
}
UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(uS) = (microsiemens)
}
ASSIGNED {
i (nA) : EPSC
gain_array : pointer to look-up table
basis_gain : aka first-order amplitude
gain : dynamically changing amplitude value based on the LUT
tau1 : inter-pulse intervals (IPIs)
tau2
tau3
tau4
t4 : timings of the last 5 pulses
t3
t2
t1
t0
order : indicates the "order" of the present pulse based on timing events
open : open-state probability
gran : granularity in ms
MEM : memory window (normalized by granularity aka ratio R)
index : holds the one-dimensional index to access the LUT array
g : conductance
factor : scaling factor
wf
v1 : membrane voltage (so that python can "access" these values)
wtc3 : weighting factor for triple exponential
o1_spks : counts the number of spikes (pulses) for every order category
o2_spks
o3_spks
o4_spks
o5_spks
}
PARAMETER {
scalar = 1
alpha = 0.01
g0 = 0.0
g1 = 40.0 (pS)
g2 = 247.0 (pS)
Mg = 1
open_Mg = 0.0
v
e = 0
nbNMDAR = 1.235
tc1 = 0.1 (ms)
tc2 = 10 (ms)
tc3 = 11 (ms)
wtc2 = 0.5
o1_tc1 = 1 (ms)
o1_tc2 = 1 (ms)
o1_tc3 = 1 (ms)
factor1 = 1
o2_tc1 = 1 (ms)
o2_tc2 = 1 (ms)
o2_tc3 = 1 (ms)
factor2 = 1
o3_tc1 = 1 (ms)
o3_tc2 = 1 (ms)
o3_tc3 = 1 (ms)
factor3 = 1
o4_tc1 = 1 (ms)
o4_tc2 = 1 (ms)
o4_tc3 = 1 (ms)
factor4 = 1
o5_tc1 = 1 (ms)
o5_tc2 = 1 (ms)
o5_tc3 = 1 (ms)
factor5 = 1
}
INITIAL {
if (tc1/tc2 > .9999) {
tc1 = .9999*tc2
}
if (tc2/tc3 > .9999) {
tc2 = .9999*tc3
}
wtc3 = 1-wtc2
C = 0
B = 0
E = 0
tau1 = -1
tau2 = -1
tau3 = -1
tau4 = -1
t4 = 0
t3 = 0
t2 = 0
t1 = 0
t0 = 0
MEM = 200 :1000/5 (memory window size divided by granularity)
order = 0
index = 0
basis_gain = basis_gain / fabs(scalar)
gain = basis_gain
}
STATE{
C
B
E
}
BREAKPOINT {
SOLVE state METHOD cnexp
: triple exponential model
open = wtc2*B + wtc3*E - C
: simulate the magnesium blockade
g0 = g1 + ((g2 - g1) / (1 + exp(alpha * v * 0.001(1/mV))))
open_Mg = (open) / (1 + exp(-62 * v * 0.001(1/mV)) * Mg / 3.57)
g = g0 * open_Mg * 0.001
i = g * (v-e) * nbNMDAR
v1 = v
}
DERIVATIVE state {
C' = -C/tc1
B' = -B/tc2
E' = -E/tc3
}
NET_RECEIVE(weight (uS)) {
SOLVE update_taus : update the IPI values
SOLVE find_gain : find the LUT amplitude value based on the present IPI values
wf = weight*factor*gain
C = C + wf
B = B + wf
E = E + wf
}
PROCEDURE update_taus(){
: record the last 5 input pulse times
t4 = t3
t3 = t2
t2 = t1
t1 = t0
t0 = t
: adding 0.5 changes the floor function to be a round() function
: convert taus from time delays (ms) into array indices (modified by granularity)
tau1 = floor((t0 - t1)/gran + 0.5)
tau2 = floor((t0 - t2)/gran + 0.5)
tau3 = floor((t0 - t3)/gran + 0.5)
tau4 = floor((t0 - t4)/gran + 0.5)
}
PROCEDURE find_gain(){
: find what ORDER the current pulse is
if ((t0 != 0) && (t1 != 0) && (t2 != 0) && (t3 != 0) && (t4 != 0)) : fifth+ spike case
{
if (tau1 > (MEM - 4)) : first order case
{
order = 1
}
else if (tau2 > (MEM - 3)) : second order case
{
order = 2
}
else if (tau3 > (MEM - 2)) : third order case
{
order = 3
}
else if (tau4 > (MEM-1)): fourth order case
{
order = 4
}
else : fifth order+ case
{
order = 5
}
}
else if (t1 == 0) : first spike case
{
order = 1
}
else if (t2 == 0) : second spike case
{
if (tau1 > (MEM - 4)) : first order case
{
order = 1
}
else : second order case
{
order = 2
}
}
else if (t3 == 0) : third spike case
{
if (tau1 > (MEM - 4)) : first order case
{
order = 1
}
else if (tau2 > (MEM - 3)) : second order case
{
order = 2
}
else : third order case
{
order = 3
}
}
else if (t4 == 0) : fourth spike case
{
if (tau1 > (MEM - 4)) : first order case
{
order = 1
}
else if (tau2 > (MEM - 3)) : second order case
{
order = 2
}
else if (tau3 > (MEM - 2)) : third order case
{
order = 3
}
else :FOURTH ORDER CASE
{
order = 4
}
}
: based on the order, use the appropriate time constants and normalization factor
if (order == 1)
{
gain = basis_gain
tc1 = o1_tc1
tc2 = o1_tc2
tc3 = o1_tc3
factor = factor1
o1_spks = o1_spks + 1
}
else
: convert the multi-dimensional indices into a single one-dimensional index
{
if (order == 2)
{
index = convert_index(tau1,MEM-3,MEM-2,MEM-1)
tc1 = o2_tc1
tc2 = o2_tc2
tc3 = o2_tc3
factor = factor2
o2_spks = o2_spks + 1
}
else if (order == 3)
{
index = convert_index(tau1,tau2,MEM-2,MEM-1)
tc1 = o3_tc1
tc2 = o3_tc2
tc3 = o3_tc3
factor = factor3
o3_spks = o3_spks + 1
}
else if (order == 4)
{
index = convert_index(tau1,tau2,tau3,MEM-1)
tc1 = o4_tc1
tc2 = o4_tc2
tc3 = o4_tc3
factor = factor4
o4_spks = o4_spks + 1
}
else if (order == 5)
{
index = convert_index(tau1,tau2,tau3,tau4)
tc1 = o5_tc1
tc2 = o5_tc2
tc3 = o5_tc3
factor = factor5
o5_spks = o5_spks + 1
}
: use the index to access the look-up table
VERBATIM
gain = ((double*)_p_gain_array)[(int) index];
ENDVERBATIM
}
}
: convert multiple indices into one flattened index
FUNCTION convert_index (ind1, ind2, ind3, ind4){
UNITSOFF
convert_index = ((pow(ind4,4) - 6*pow(ind4,3) + 11*pow(ind4,2) - 6*(ind4))/24 + (pow(ind3,3) - 3*pow(ind3,2) + 2*(ind3))/6 + (pow(ind2,2) - (ind2))/2 + ind1 )
UNITSON
}