Page 1 of 1

Iterating over just the sections within an object

Posted: Fri Mar 03, 2017 10:58 am
by pascal
I am writing one of my first programs in NEURON + Python, and I want to make sure that I am correctly iterating over just the sections within a newly-created object. (I realized that using for sec in h.allsec() iterates over all sections in the entire program, which is not what I want.) My toy class definition is as follows:

Code: Select all

class Cell(object):
    def __init__(self):
        self.createSections()
        self.defineBiophysics()

    def createSections(self):
        self.slist=h.SectionList() 
        self.soma=h.Section(name='soma', cell=self) 
        self.slist.append(sec=self.soma) 
        self.Bdend=h.Section(name='Bdend', cell=self)
        self.slist.append(sec=self.Bdend)
        self.Adend=h.Section(name='Adend', cell=self)
        self.slist.append(sec=self.Adend)
        
        #define connectivity between sections
        self.Bdend.connect(self.soma,0,0) 
        self.Adend.connect(self.soma,1,0) 

    def defineBiophysics(self):
        
        for sec in self.slist:
            sec.insert('pas')
            sec.e_pas = -70 #mv
            sec.g_pas = 1.0/28000.0 #S/cm2

Is this the appropriate way to iterate over just the sections within one object? It gives every appearance of working, but I want to make sure I'm not missing something that will come back to bite me down the road. Thanks.

Re: Iterating over just the sections within an object

Posted: Fri Mar 03, 2017 11:27 am
by ted
First a suggestion: call the list that contains all sections "all". That will be consistent with much, if not most, prior usage by others.

The tutorial
Scripting NEURON with Python
which you will find referenced on NEURON's Documentation page http://www.neuron.yale.edu/neuron/docs
doesn't include a relevant example?

If it doesn't, here's how you can answer your own question.
Make a cell class that defines a single compartment model cell--just a soma.
Create two instances of that class.
Assign different lengths to their somas.
Then iterate over each instance's all to print out the lengths of that instance's sections. If it doesn't work properly, make your best guess as to why, implement your fix, and test again.

Re: Iterating over just the sections within an object

Posted: Sun Mar 05, 2017 3:52 pm
by pascal
Ah, I did end up finding a good example in this portion of the tutorial: http://neuron.yale.edu/neuron/static/do ... tick2.html . Thanks.

Following the tutorial, I was able to clean up my code by using the wholetree method (rather than adding each individual section to the SectionList as I had before):

Code: Select all

class Cell(object):
    def __init__(self):
        self.createSections()
        self.defineBiophysics()
    #
    def createSections(self):
        self.soma=h.Section(name='soma', cell=self)
        self.Bdend=h.Section(name='Bdend', cell=self)
        self.Adend=h.Section(name='Adend', cell=self)
        #
        #define connectivity between sections
        self.Bdend.connect(self.soma,0,0)
        self.Adend.connect(self.soma,1,0)
        #
        self.all=h.SectionList() 
        self.all.wholetree(sec=self.soma) #make SectionList of all sections connected to the soma

    def defineBiophysics(self):
        for sec in self.all:
            sec.insert('pas')
            sec.e_pas = -70 #mv
            sec.g_pas = 1.0/28000.0 #S/cm2
I do have one more question, however: according to the documentation for SectionList, there is a method called printnames that does what its name suggests. However, when I call it, all it returns is "1.0" (when I was expecting it to return 'soma', 'Bdend', and 'Adend' in the above example). How can I actually get this method to work?

Re: Iterating over just the sections within an object

Posted: Mon Mar 06, 2017 11:28 am
by ted
according to the documentation for SectionList, there is a method called printnames that does what its name suggests. However, when I call it, all it returns is "1.0" (when I was expecting it to return 'soma', 'Bdend', and 'Adend' in the above example). How can I actually get this method to work?
Not sure how you invoked SectionList.printnames. When I call it, it works just fine

Code: Select all

>>> cell = Cell()
>>> cell.all.printnames()
<__main__.Cell object at 0xb732ddec>.soma
<__main__.Cell object at 0xb732ddec>.Bdend
<__main__.Cell object at 0xb732ddec>.Adend
as long as you don't mind the 1.0 that SectionList.printnames returns, and the ugliness of those section names. Note that the nice strings stipulated in the Python statements that created the sections become the Python names for the sections, but the hoc names also include the address of the Python Cell class instance.

To make a section have a nice name in both hoc and Python, the section must be created by executing a hoc statement. To make a top level model cell (one that is not an instance of some Cell class), one would do this
h("create soma, Adend, Bdend")
soma = h.soma
Adend = h.Adend
Bdend = h.Bdend
. . . other statements . . .

The easiest way to create a cell class definition so that each section's name will look nice in hoc AND Python is to write the cell class definition as a hoc template, and the easiest way to do that is by using a CellBuilder. I just now used the CellBuilder to create a model cell with the same topology as yours but with section names soma, adend, and bdend, and exported that as a cell class, with the hoc name Cell, to a file called cell.hoc. Then I executed

Code: Select all

nrngui -python
from neuron import h,gui
h('load_file("cell.hoc")')
cell = h.Cell()
That last statement should have created a new Python object called cell which is an instance of the model cell defined by the template in cell.hoc--but did it?

Code: Select all

>>> h('forall print secname()')
Cell[0].soma
Cell[0].adend
Cell[0].bdend
shows that hoc has an instance of the Cell class called Cell[0], and that instance has three sections with the desired names.

Code: Select all

>>> cell.all.printnames()
Cell[0].soma
Cell[0].adend
Cell[0].bdend
shows that the SectionList all contains three sections with the desired names.

Finally

Code: Select all

>>> h("topology()")

|-|       Cell[0].soma(0-1)
   `----------------------|       Cell[0].adend(0-1)
 `--------|       Cell[0].bdend(0-1)
confirms the topology and spatial discretization of the model, and

Code: Select all

>>> h("forsec Cell[0].all psection()")
will confirm the geometry and biophysical properties of Cell[0]'s sections.

Re: Iterating over just the sections within an object

Posted: Wed Mar 08, 2017 11:46 am
by pascal
That is very helpful--thank you!