-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsyncode.hoc
More file actions
330 lines (306 loc) · 13 KB
/
syncode.hoc
File metadata and controls
330 lines (306 loc) · 13 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
// $Id: syncode.hoc,v 1.53 2002/04/18 18:33:32 billl Exp $
proc syncode () {}
//* setup
load_file("decvec.hoc","decvec")
objref ncl, cells[10] // enough room for 10 cell types
objref CTYP[1],STYP[1] // for err messages involving cell and synapse types
ncl = new List()
strdef syn1,syn2
thresh = -20
// for ltr(XO,cvode.netconlist("", "", "")) print XO.precell,XO.postcell,XO.syn
//* synapse linking
//** geolink(s1,s2,s3) s1 for presyns and s2 for postsyns, connect s3's
// connects a layer to another assuming 1 dim netgeom
proc geolink() { local ii
if (numarg()==0) { print "\tgeolink(s1,s2,s3,v_conn)"
print " make connections from s1 to s2 connecting onto s3 type PPs."
print " vector_connect gives the prob of connection according to cell number"
return
}
sprint(temp_string_,"XO.soma ncl.append(new NetCon(&v(.5), YO.%s))",$s3)
for ltr (XO,new List($s1)) { // presyn list
for lvtr (YO,&x,new List($s2),$o4) { // postsyn list and vector
if (x==1) { // connect
print "connecting ",XO," to ",YO
execute(temp_string_)
}
}
$o4.rotate(1)
}
XO=nil YO=nil
}
//** nowraplk(s1,s2,s3) s1 for presyns and s2 for postsyns, connect s3's
// connects a layer to another assuming 1 dim netgeom
proc nowraplk() { local cnt
if (numarg()==0) { print "\tnowraplk(s1,s2,s3,v_conn,dist)"
print " make connections from s1 to s2 connecting onto s3 type PPs."
print " like geolink() statt no wraparound, only look out by dist from the cell"
return
}
sprint(temp_string_,"XO.soma ncl.append(new NetCon(&v(.5), YO.%s))",$s3)
dist=$5
tmplist=new List($s2)
cnt=tmplist.count
for ltr (XO,new List($s1),&y) { // presyn list
for ii=y-dist,y+dist {
if (ii>=0 && ii<cnt) if ($o4.x[ii]==1) {
YO=tmplist.object(ii)
print "connecting ",XO," to ",YO
execute(temp_string_)
}
}
$o4.rotate(1)
}
}
//** synlink(s1,s2,s3,[gmax,del]) s1 for presyns and s2 for postsyns, connect s3's
// eg synlink("PYR","INH","AMPA")
// provides full connectivity
proc synlink() { local gm,dl
if (numarg()==0) { print "\tsynlink(s1,s2,s3)"
print " make connections from all of type s1 to one of type s2 "
print " only connecting onto s3 type PPs."
print " Matching done with regexps."
return
}
if (numarg()==5) { gm=$4 dl=$5 } else { gm=0 dl=1 }
tmplist = new List($s3) // list of postsyn point processes
for ltr (XO,new List($s1)) { // presyn list
for ltr (YO,tmplist) {
if (pp_loc(YO,$s2,syn2)) {
sfunc.head(syn2,"\\.",syn2)
sprint(syn1,"%s",XO)
if (strcmp(syn1,syn2)!=0) { // don't allow self connects
print "connecting ",XO," to ",syn2
XO.soma ncl.append(new NetCon(&v(.5), YO, thresh, gm, dl))
}
}
}
}
}
//** synconn(l1,s2,s3,%div) l1 list of presyns and s2 for postsyns, connect s3's with given density
// eg synconn(PYRi,PYRi,AMPAi,pmat[PYR][PYR])
// provides % connectivity based on %div==%conv
objref convec,convec1,convec2 // vectors to count how much div is from each nrn
convec = new Vector(100)
convec1 = convec.c // a scratch vector
convec2 = convec.c // copy of convec used temporarily to blot out self-connect and redundent connects
proc synconn () { local pdiv,con,div,ii,jj,pre,prn,post,pon,sy,targ
if (numarg()==0) { print "\tsynconn(pre,post,mech,div)" return }
pre=$1 post=$2
if (numarg()==3) { sy=0 pdiv=$3 } else { sy=$4 pdiv=$3 }
prn = cells[$1].count // number of possible presyn sources
pon = cells[$2].count // number of possible postyn targets
div = int(pdiv*pon) // # out from each
con = int(pdiv*prn+1) // # into each; leave a little extra room
if (pdiv==1) con=-1 // flag for full connectivity
printf("\tdiv=%d,conv=%d\n",div,con)
convec.resize(pon) convec.fill(0) // counter for convergence
for ii=0,prn-1 { // sources
convec2.copy(convec) convec2.x[ii]=1e10 // block self-connect
for jj=1,div {
targ = pickpost(pon,con) // pick desired target
printf("SRC: %s -> TRG: %s (%s)\n",cells[pre].object(ii),cells[post].object(targ),cells[post].object(targ).syns(sy))
cells[pre].object(ii).conn(cells[post].object(targ).syns(sy))
}
}
}
proc synconn2 () { local pdiv,con,div,ii,jj,pre,prn,post,pon,sy,targ
if (numarg()==0) { print "\tsynconn(pre,post,mech,div)" return }
pre=$1 post=$2
if (numarg()==3) { sy=0 pdiv=$3 } else { sy=$3 pdiv=$4 }
prn = cells[$1].count // number of possible presyn sources
pon = cells[$2].count // number of possible postyn targets
div = int(pdiv*pon) // # out from each
con = int(pdiv*prn+1) // # into each; leave a little extra room
if (pdiv==1) con=-1 // flag for full connectivity
printf("\tdiv=%d,conv=%d\n",div,con)
convec.resize(pon) convec.fill(0) // counter for convergence
for ii=0,prn-1 { // sources
convec2.copy(convec) convec2.x[ii]=1e10 // block self-connect
for jj=1,div {
targ = pickpost(pon,con) // pick desired target
printf("SRC: %s -> TRG: %s (%s)\n",cells[pre].object(ii),cells[post].object(targ),cells[post].object(targ).syns(sy))
cells[pre].object(ii).conn(cells[post].object(targ).syns(sy))
}
}
}
//*** pickpost() tries to reduce divergence variance
// pickpost(postlist,maxcon,YO)
// maxcon == -1 means to ignore convergence
// MUST do convec.resize() and convec.fill(0) before using
func pickpost () { local ran, maxcon, maxpo, min, indx
maxcon = $2 // max convergence to be allowed
maxpo = $1 // number of postsyn choices
if (maxcon == -1) $o3 = $o1.object(fran(0,maxpo)) // just choose one randomly
min = convec2.min // convec should start all 0's
if (min >= maxcon) { // all full up
printf("Pickpost full WARNING: %d %d\n",min,maxdiv) vlk(convec2) }
convec1.indvwhere(convec2,"==",min) // look for all the smallest to fill up first
inx = convec1.x[fran(0,convec1.size-1)]
convec.x[inx]+=1
convec2.x[inx]=1e10 // block from reconnecting here
return inx
}
proc syn1to1 () { local pre,post,syn
pre=$1 post=$2
if (numarg()==3) syn=$3 else syn=0
if (cells[pre].count !=cells[post].count) {
printf("\tERROR: 1-to-1 connectivity requires same # of %s (=%d) and %s (=%d).\n",\
CTYP[pre].s,cells[pre].count,CTYP[post].s,cells[post].count) return }
for ltr2(XO,YO,cells[pre],cells[post]) {
printf("SRC: %s -> TRG: %s (%s)\n",XO,YO,YO.syns(syn))
XO.conn(YO.syns[syn])
}
}
//** simple netconnect routines: netconn(), netgen()
proc netconn () { local pre,post,syn,pri,poi
pre=$1 post=$2
if (numarg()==5) { syn=$3 pri=$4 poi=$5 } else { syn=0 pri=$3 poi=$4 }
cells[pre].object(pri).conn(cells[post].object(poi).syns[syn])
}
proc netgen () { ncl.append(new NetCon($o1, $o2)) }
//** syncopy() copies from one set of syns to another for colocalization
proc syncopy () {
if (numarg()==0) { printf("syncopy(to_type,[]): copy from type, post/type, pre/post/type\n") return }
sprint(temp_string_,"XO.precell.soma ncl.append(new NetCon(&v(.5),XO.postcell.%s",$s1)
if (numarg()==1) tmplist = cvode.netconlist("", "" , $s2)
if (numarg()==2) tmplist = cvode.netconlist("", $s2, $s3)
if (numarg()==3) tmplist = cvode.netconlist($s2, $s3, $s4)
for ltr(XO,tmplist) execute(temp_string_)
}
//* synapse setting
//** scale gmax
proc synscgmax () {
for ltr(XO,cvode.netconlist("" , "", $s1)) { XO.weight *= $2 }
}
//** set/get gmax
proc synsetgmax () {
if (numarg()==0) { print "synsetgmax(pre,post,type,wt)"
} else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , "", $s1)) XO.weight=$2
} else if (numarg()==3) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) XO.weight=$3
} else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.weight=$4
} else { print "ERROR: too many args" }
}
proc syngetgmax () {
if (numarg()==1) {
if (strcmp($s1,"help")==0) { printf("type,post/type,pre/post/type\n") } else {
for ltr(XO,cvode.netconlist("" , "", $s1)) printf("%g ",XO.weight) }
} else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) printf("%g ",XO.weight)
} else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.weight)
} else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.weight)
print ""
}
//** set/get delay
proc synsetdel () {
if (numarg()==2) {for ltr(XO,cvode.netconlist("" , "", $s1)) XO.delay=$2
} else if (numarg()==3) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) XO.delay=$3
} else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.delay=$4
} else { print "ERROR: too many args" }
}
proc syngetdel () {
if (numarg()==1) {for ltr(XO,cvode.netconlist("" , "", $s1)) printf("%g ",XO.delay)
} else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) printf("%g ",XO.delay)
} else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.delay)
} else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.delay)
print ""
}
//** set/get thresh
proc synsetthr () {
if (numarg()==1) {for ltr(XO,cvode.netconlist("" , "", "")) XO.threshold=$1
} else if (numarg()==2) {for ltr(XO,cvode.netconlist($s1 , "", "")) XO.threshold=$2
} else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1, "", $s2)) XO.threshold=$3
} else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.threshold=$4
} else { print "ERROR: too many args" }
}
proc syngetthr () {
if (numarg()==1) {for ltr(XO,cvode.netconlist($s1 , "", "")) printf("%g ",XO.threshold)
} else if (numarg()==2) {for ltr(XO,cvode.netconlist($s1, "", $s2)) printf("%g ",XO.threshold)
} else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.threshold)
} else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.threshold)
print ""
}
//** synremove: remove post, pre/post, pre/post/type; synshow
proc synremove () {
if (numarg()==0) { printf("synremove: remove post, pre/post, pre/post/type\n") return }
if (numarg()==1) tmplist = cvode.netconlist("", $s1 , "")
if (numarg()==2) tmplist = cvode.netconlist("", $s1, $s2)
if (numarg()==3) tmplist = cvode.netconlist($s1 , $s2, $s3)
if (tmplist.count>0) for ltr(XO,tmplist) ncl.remove(ncl.index(XO))
tmplist = nil // need to remove these references too
if (numarg()==1) tmplist = cvode.netconlist("", $s1 , "")
if (numarg()==2) tmplist = cvode.netconlist("", $s1, $s2)
if (numarg()==3) tmplist = cvode.netconlist($s1 , $s2, $s3)
if (tmplist.count>0) for ltr(XO,tmplist) printf("ERROR: %s removed from ncl but still exists\n",XO)
tmplist = nil
}
proc synshow () {
sprint(temp_string_,"x=XO.%s",$s2)
for ltr(XO,cvode.netconlist("" , "", $s1)) { execute(temp_string_) printf("%g ",x) }
print ""
}
//* informational procs
//** proc print_pp_location(PP), from doc/html/refman/nocmodl.html
proc print_pp_location() { local x //arg1 must be a point process
x = $o1.get_loc()
sectionname(section)
printf("%s located at %s(%g)\n", $o1, section, x)
pop_section()
}
//** pp_loc(PP,LOC,SCRATCH) returns true if point process PP is located in LOC (regexp match)
func pp_loc () { local x //arg1 must be a point process
x = 0
$o1.get_loc()
if (numarg()==3) { sectionname($s3) }
ifsec $s2 { x = 1 }
pop_section()
return x
}
//** ndivo, ncono, sdivo, scono: objects; ndivs, ncons, sdivs, scons: strings
func ndivo () { return cvode.netconlist($o1, "", "").count }
func ncono () { return cvode.netconlist("", $o1, "").count }
proc sdivo () {for ltr(XO,cvode.netconlist($o1, "", "")) prsxo() }
proc scono () {for ltr(XO,cvode.netconlist("", $o1, "")) prsxo() }
func ndivs () { return cvode.netconlist($s1, "", "").count }
func ncons () { return cvode.netconlist("", $s1, "").count }
proc sdivs () { for ltr(XO,cvode.netconlist($s1, "", "")) prsxo() }
proc scons () {
if (numarg()==0) for ltr(XO,cvode.netconlist("", "", "")) prsxo()
if (numarg()==1) for ltr(XO,cvode.netconlist("", $s1, "")) prsxo()
if (numarg()==2) for ltr(XO,cvode.netconlist("", $s1, $s2)) prsxo()
if (numarg()==3) for ltr(XO,cvode.netconlist($s1, $s2,$s3)) prsxo()
}
// print pre,post,syntype,threshold,weight,delay
proc prsxo () {
if (isobj(XO.precell,"NULLobject")) {
printf("%s->%s (%s) (t%g,w%g,d%g)\n",XO.pre,XO.postcell,XO.syn,XO.threshold,XO.weight,XO.delay)
} else {
printf("%s->%s (%s) (t%g,w%g,d%g)\n",XO.precell,XO.postcell,XO.syn,XO.threshold,XO.weight,XO.delay)
}
}
//* misc and commentary
// con=absolute convergence number, div=absolute div number
// con = %con * pre
// div * pre = con * post = S (total synapses)
// %div = div/post = S/(pre*post) = con/pre = %con
// div = %con * post
// maxdiv = int((1 + var) * div)
//** vari returns randomly chosen $1+/-$2
func frani () { return int(rdm.uniform($1,$2+1)) }
func uvari () { return $1 - $1*$2 + (rdm.uniform(0,1) * 2 * $1*$2) }
func gvari () { return $1 - (rdm.normal(0,1) * $1*$2) }
//** latlink() gives wrap-around
proc latlink () { local reach,ii
reach=$2
$o1.fill(0)
if (numarg()==3) $o1.x[0]=$3 // connect within the column
for ii=1,reach {
$o1.x[ii]=1
$o1.x[$o1.size-ii]=1
}
}
//** clearsyns()
proc clearsyns () {
for ltr(XO,ncl) XO.active(0)
ncl.remove_all
for ltr(XO,new List("NetCon")) printf("**** CLEARSYN WARNING %s STILL EXISTS ****\n",XO)
}