File: ring.hoc

package info (click to toggle)
neuron 8.2.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,760 kB
  • sloc: cpp: 149,571; python: 58,465; ansic: 50,329; sh: 3,510; xml: 213; pascal: 51; makefile: 35; sed: 5
file content (148 lines) | stat: -rw-r--r-- 4,448 bytes parent folder | download | duplicates (3)
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
{load_file("nrngui.hoc")}  // load the GUI and standard run libraries

objref pc
pc = new ParallelContext()

//////////////////////////////////
// Step 1: Define the cell classes
//////////////////////////////////

{load_file("cell.hoc")}

//////////////////////////////////////////////////////////////
// Steps 2 and 3 are to create the cells and connect the cells
//////////////////////////////////////////////////////////////

NCELL = 20  // total number of cells in the ring network
  // identical to total number of cells on all machines

objref cells, nclist  // cells will be a List that holds 
  // all instances of network cells that exist on this host
  // nclist will hold all NetCon instances that exist on this host
  // and connect network spike sources to targets on this host (nclist)

proc mkring() {
  mkcells($1)  // create the cells
  connectcells()  // connect them together
}

// creates the cells and appends them to a List called cells
// argument is the number of cells to be created
proc mkcells() {local i  localobj cell, nc, nil
  cells = new List()
  // each host gets every nhost'th cell,
  // starting from the id of the host
  // and continuing until all cells have been dealt out
  for (i=pc.id; i < $1; i += pc.nhost) {
    cell = new B_BallStick()
    cells.append(cell)
    pc.set_gid2node(i, pc.id)  // associate gid i with this host
    nc = cell.connect2target(nil)  // attach spike detector to cell
    pc.cell(i, nc)  // associate gid i with spike detector
  }
}

// connects the cells
// appends the NetCons to a List called nclist
proc connectcells() {local i, targid  localobj src, target, syn, nc
  nclist = new List()
  for i=0, NCELL - 1 {  // iterating over source gids
    targid = (i+1)%NCELL
    if (!pc.gid_exists(targid)) { continue }
    target = pc.gid2cell(targid)
    syn = target.synlist.object(0)  // the first object in synlist
        // is an ExpSyn with e = 0, therefore an excitatory synapse
    nc = pc.gid_connect(i, syn)
    nclist.append(nc)
    nc.delay = 1
    nc.weight = 0.01
  }
}

mkring(NCELL)  // go ahead and create the net!

//////////////////////////////////////////////////
// Instrumentation, i.e. stimulation and recording
//////////////////////////////////////////////////

// stim will be an artificial spiking cell that generates a "spike" event
// that is delivered to the first cell in the net by ncstim
// in order to initiate network spiking.
// We won't bother including this "external stimulus source" or its NetCon
// in the network's lists of cells or NetCons.
objref stim, ncstim
proc mkstim() {
  // exit if the first cell in the net does not exist on this host
  if (!pc.gid_exists(0)) { return }
  pc.gid2cell(0).soma stim = new IClamp(.5)
  stim.dur=1
  stim.amp=1
return
  stim = new NetStim()
  stim.number = 1
  stim.start = 0
  ncstim = new NetCon(stim, pc.gid2cell(0).synlist.object(0))
  ncstim.delay = 1 //cannot be 0 with multiple threads
  ncstim.weight = 0.01
}

mkstim()

objref tvec, idvec  // will be Vectors that record all spike times (tvec)
        // and the corresponding id numbers of the cells that spiked (idvec)
proc spikerecord() {local i  localobj nc, nil
  tvec = new Vector()
  idvec = new Vector()
  for i=0, cells.count-1 {
    nc = cells.object(i).connect2target(nil)
    nc.record(tvec, idvec, nc.srcgid)
    // the Vector will continue to record spike times
    // even after the NetCon has been destroyed
  }
}

spikerecord()

/////////////////////
// Simulation control
/////////////////////
nthread = 2
{cvode.cache_efficient(1)} // required for nrncore
{pc.nthread(nthread, 0)} // lowest_level_load stores nthread groups of cells

tstop = 100
{pc.set_maxstep(10)}
stdinit()
{pc.psolve(tstop)}

////////////////////////////
// Report simulation results
////////////////////////////

proc spikeout() { local i, rank localobj outdat
  pc.barrier()  // wait for all hosts to get to this point
  outdat = new File()
  if (pc.id==0) {
    outdat.wopen("out.dat")
    outdat.printf("\ntime\t cell\n")  // print header once
    outdat.close()
  }
  for rank=0, pc.nhost-1 {  // host 0 first, then 1, 2, etc.
    if (rank==pc.id) {
      outdat.aopen("out.dat")
      for i=0, tvec.size-1 {
        outdat.printf("%g\t %d\n", tvec.x[i], idvec.x[i])
      }
      outdat.close()
    }
    pc.barrier()  // wait for all hosts to get to this point
  }
}

spikeout()

{pc.nrnbbcore_write()}

{pc.runworker()}
{pc.done()}
quit()