Page 1 of 1

NetCon without point_process target

Posted: Thu Sep 22, 2016 5:50 am
by Nin
Hi everybody,

From what I understand in the NEURON book (page 335), we could use the record method of the NetCon class to collect the spikes times of a given segment. In Python, I implemented the following example: https://github.com/JoseGuzman/myIPython ... ikes.ipynb

Code: Select all

from neuron import h

cell1 = h.Section(name = 'cell1')
cell1.insert('hh')

cell2 = h.Section(name = 'cell2')
mysyn = h.ExpSyn(0.5, sec = cell2) # create dummy synapse

mynetcon = h.NetCon( cell1(0.5)._ref_v, mysyn, sec = cell1)
myhocvector = h.Vector()
mynetcon.record(myhocvector)


Since I don't want the NetCon to send the output to any point process, I would like to know if is it possible to set up a NetCon target without 1) having to define a new point_process and 2) having to define a new segment. This is very lengthy for every NetCon that record spikes.

PS:
In the book, there's a variable called 'nil' (what I understand is a dummy variable). In Python, tried the following:

Code: Select all

nil = h.objref() 
but returned the following error: TypeError: no HocObject interface for objref (hoc type 323)
Thanks

Re: NetCon without point_process target

Posted: Thu Sep 22, 2016 2:01 pm
by ted
Sorry that the Programmer's Reference is not yet completely updated. Here's an example lifted from the article
Lytton et al..
Simulation Neurotechnologies for Advancing Brain Research: Parallelizing Large Networks in NEURON.
Neural Computation
October 2016
28:2063–2090, 2016.
(associated source code available from ModelDB under accession number 188544).

This statement creates a NetCon that monitors membrane potential at soma(0.5):

Code: Select all

nc = h.NetCon(self.soma(0.5)._ref_v, None, sec=self.soma)
Notice that the additional argument
sec=self.soma
is needed. This is because self.soma(0.5)._ref_v returns a memory pointer but does not itself contain information about which section is being referenced.

You can then specify the NetCon's threshold for spike detection, and use its record() method to append spike times to a Vector. After that, you can free up memory by garbage collecting the NetCon, because its threshold detector will persist.

Re: NetCon without point_process target

Posted: Thu Sep 22, 2016 3:34 pm
by Nin
Thank you Ted, for your help, the None argument made my day!.

in the mean time, I tried to access cell1 object (nrn.Section) created in Python with the hoc interface and use a new NetCon:

Code: Select all

objref py
py = new PythonObject()

objref nc, foo

nc = new NetCon( py.cell1(0.5)._ref_v, foo, 0, 0, 0 ) 
But it doesn't work. Adding a reference doesn't work either:

Code: Select all

nc = new NetCon( &py.cell1(0.5)._ref_v,  foo, 0, 0, 0)
I would appreciate any help! I would like to create a Raster plot as described in the NEURON book.

Re: NetCon without point_process target

Posted: Fri Sep 23, 2016 2:51 pm
by ted
Send me the code you used to create the cell1 object so I can see exactly what happens when this

Code: Select all

objref py
py = new PythonObject()

objref nc, foo

nc = new NetCon( py.cell1(0.5)._ref_v, foo, 0, 0, 0 )
is executed.

Re: NetCon without point_process target

Posted: Fri Sep 30, 2016 12:21 pm
by ted
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)