How nin's problem was resolved--
nin's program consisted of a main file, which contained the code that set up a model and ran a simulation in which membrane potentials and spike times were recorded, and a secondary file that was supposed to produce a raster plot of spike times. The main file worked properly; the problems were all in the secondary file.
The cell class that specified the properties of the cell instances in the network contained these statements to ensure that each cell instance would capture its own spike times to its own numpy array:
Code: Select all
# NetCon to monitor membrane potential at the soma (i.e APs)
self._nc = h.NetCon( self.soma(0.5)._ref_v, None, sec = self.soma )
self._nc.threshold = 0.0
self._spk_times = h.Vector()
self._nc.record(self._spk_times) # spike times
spk_times = property(lambda self: np.array(self._spk_times))
Each instance of the cell class had been appended to a python list called cells_list.
The code in the secondary file had to accomplish two tasks: copy the spike times from the cells in cells_list into a set of hoc Vectors, then use the Graph class's mark method to show each cell's spike times in a raster plot. nin had already done much of the work, and that made things easier for me. I think he just got tangled up in the differing syntaxes of hoc and python and reached a point where it was better to have another pair of eyes look at the problem. Been there myself.
Key parts of the solution were already in the file: using an instance of the PythonObject class so that hoc could access python objects, and using the hoc Vector class's from_python method to copy values from numpy arrays to hoc Vectors. However, it took some tinkering with toy problems to figure out exactly how to use these important tools properly in the context of nin's modeling strategy. Here's what worked for me.
To copy the spike times from the numpy arrays into a set of hoc Vectors, I used a hoc obfunc called makestveclist(). This function used an instance of the PythonObject class to enable iteration over the cells in the python cells_list, and the Vector class's from_python method to copy the spike times from their numpy arrays to corresponding hoc Vectors. makestveclist returned a hoc List whose elements were the resulting Vectors.
Code: Select all
objref py
py = new PythonObject() /* to access Python objects */
// returns a List of spike time vectors
obfunc makestveclist() { local i localobj tobj, tmpvec
tobj = new List()
for i=0,py.ncells-1 {
tmpvec = new Vector()
tmpvec.from_python(py.cell_list[i].spk_times)
print i // verify that the data were copied
tmpvec.printf()
tobj.append(tmpvec)
}
return tobj
}
objref stveclist
stveclist = makestveclist()
The product of this data copying was called stveclist, the ith element of which is a Vector that contains the spike times from the ith cell in the model. The procedure showRasterPlot iterates over these vectors and places a | mark on a Graph at a location whose x and y coordinates correspond to the spike time and the cell index.
Code: Select all
// $o1 is the Graph object that will get the plot
// $o2 is the List that contains the spike time vectors
proc showRasterPlot() { local i localobj yvec
$o1.erase_all()
for i = 0, py.ncells - 1 {
// Vector.c() creates Vector that has the same number of elements
yvec = $o2.o(i).c
yvec.fill(i+1)
yvec.mark($o1, $o2.object(i), "|", 6)
}
}
objref grp
grp = new Graph(0)
grp.view(0, 0, tstop, py.ncells, 4, 295, 339.84, 200)
// last four params are coordinates of the window (left, top), and its width and height
showRasterPlot(grp, stveclist)