Transporting hoc to python

When Python is the interpreter, what is a good
design for the interface to the basic NEURON
concepts.

Moderator: hines

Post Reply
maya
Posts: 6
Joined: Mon Sep 27, 2010 9:10 am

Transporting hoc to python

Post by maya » Tue Nov 09, 2010 5:38 am

I am transporting my hoc codes into python codes, but I have some questions:

1. How can I subtree() in python?
In hoc it is:

Code: Select all

apical = new SectionList()
  access apic[0]
    apical.subtree()
2. How can do a distance() function?
In hoc it is:

Code: Select all

distapic = new SectionList()
  access soma
  distance()												
  forsec apical {
	if (distance(0)>=350) {
		distapic.append()		
	}
  }
3. Why can't I set the values "global_ra" and "celsius" as I do with "nseg" and "cm"?

Code: Select all

for a in h.allsec():	
	a.nseg = 11
	a.insert("pas")
	a.e_pas = -70
	a.g_pas = 1/20000
	a.cm = 1
	a.global_ra = 80
	a.celsius = 34
Neuron returns the error:
a.global_ra = 80
AttributeError: 'nrn.Section' object has no attribute 'global_ra'
Thank's
Maya

vellamike

Re: Transporting hoc to python

Post by vellamike » Tue Nov 09, 2010 11:56 am

hi,

Did you ever work out how to do a distance() function?

ted
Site Admin
Posts: 5534
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Transporting hoc to python

Post by ted » Tue Nov 09, 2010 8:58 pm

maya wrote:1. How can I subtree() in python?
In hoc it is:

Code: Select all

apical = new SectionList()
  access apic[0]
    apical.subtree()
First, a comment about your hoc code:
Don't use access this way. You'll sabotage all graphs and hoc statements that use "naked range variables" (e.g. v, ina(0.7), ek(0.1)) to refer to a value in the default section--because access changes the section that is the default section. So if the first access statement executed in your hoc code is
access soma
then all graphs etc. that refer to v will really refer to soma.v(0.5). And when your program executes
access apic[0]
then, all of a sudden, all of your graphs etc. that refer to v will now refer to apic[0].v(0.5) instead. Got it?

You should use access only once--use it to specify the section in the model that is most important (usually soma)--and use either dot notation or section stack syntax whenever it is necessary to specify some other section. The fix for your particular hoc code is

Code: Select all

apical = new SectionList()
  apic[0] apical.subtree() // apic[0] is the "currently accessed section" when apical.subtree() is called
Here's how to make a SectionList that contains the subtree whose root section is apic
apical = h.SectionList()
apical.subtree(sec=apic)
2. How can do a distance() function?
In hoc it is:

Code: Select all

distapic = new SectionList()
  access soma
  distance()												
  forsec apical {
	if (distance(0)>=350) {
		distapic.append()		
	}
  }
So here's another example of "access abuse." The fix, of course, is to replace lines 2 and 3 with this:

Code: Select all

soma distance()
See if this bit of Python helps with your question about how to use distance to select a particular set of sections. It iterates over all members of the apical SectionList, and for each section will print the section name followed by the range of each internal node (i.e. normalized distance from the 0 end of the currently accessed section) and its path distance from the origin for path distances:

Code: Select all

for sec in apical:
   print h.secname()
   for seg in sec:
     print seg.x, h.distance(seg.x)
Now a question for you: don't you really want to build a set of sections whose _proximal_ ends (nodes at 0) are at some specified distance from the soma?
3. Why can't I set the values "global_ra" and "celsius" as I do with "nseg" and "cm"?
Because global_ra and celsius are global variables. They are not section variables or range variables, so syntax that tries to assocate them with an individual section will not work. And that's what the error message

Code: Select all

AttributeError: 'nrn.Section' object has no attribute 'global_ra' 
was trying to tell you. Instead, they pertain to all sections, so they are known to Python as h.global_ra and h.celsius.

vellamike

Re: Transporting hoc to python

Post by vellamike » Wed Nov 10, 2010 9:19 am

If I try this:

Code: Select all

for sec in apical:
   print h.secname()
   for seg in sec:
     print seg.x, h.distance(seg.x)
I get a message saying
Distance origin not valid. Need to initialize origin with distance()
So how do I set the origin to, for example, a segment in the soma?

Mike

ted
Site Admin
Posts: 5534
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Transporting hoc to python

Post by ted » Wed Nov 10, 2010 10:24 am

Based on various code examples scattered in Python-related threads on the NEURON Forum, and documentation of distance() and the NEURON-Python interface in the Programmer's Reference, one might guess that
h.distance(sec=soma, 0)
would set the origin to the 0 end of soma, and so it does.

vellamike

Re: Transporting hoc to python

Post by vellamike » Wed Nov 10, 2010 10:45 am

That gives me an error:

Code: Select all

    h.distance(sec=h.soma[0], 0) #set the origin as 0 end of origin_section
SyntaxError: non-keyword arg after keyword arg
I tried looking on the Neuron-Python forums for this but couldn't find any and haven't been able to find any relevant documentation on distance().

vellamike

Re: Transporting hoc to python

Post by vellamike » Wed Nov 10, 2010 10:59 am

I've written a small useful (to me) function which takes an origin section (probably more logical to make it accept a segment) and segment as input and returns the distance, I think the use of push() isn't necessary though if I can get the right way of setting the origin to work.

Code: Select all

def fromtodistance(origin_section,to_segment):

    to_section=to_segment.sec
    origin_section.push() #Make the origin section the currently accessed section (CAS)
    h.distance()#Set the origin to the CAS
    to_section.push() #Make it the currently accessed section (CAS)
    distance=h.distance(to_segment.x)
    h.pop_section() #prevent stack overflow
    return distance

ted
Site Admin
Posts: 5534
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Transporting hoc to python

Post by ted » Wed Nov 10, 2010 12:05 pm

Way too complex.

My mistake here:
ted wrote:. . . one might guess that
h.distance(sec=soma, 0)
would set the origin to the 0 end of soma, and so it does.
Meant to write
h.distance(sec=soma, seg=0)

This works to put the origin for distance measurements at the 0 end of soma.

However there is one problem:
h.distance(sec=soma, seg=x)
always puts the origin at the 0 end of soma regardless of the value of x.

hines
Site Admin
Posts: 1574
Joined: Wed May 18, 2005 3:32 pm

Re: Transporting hoc to python

Post by hines » Wed Nov 10, 2010 12:59 pm

SyntaxError: non-keyword arg after keyword arg
Non keyword args come first so the syntax is

Code: Select all

h.distance(0, sec=h.soma[0])
To set the origin (with an explicit section) to position x of the currently accessed section, use
h.distance(0 , x, sec=...)
This can be gleaned from
http://www.neuron.yale.edu/neuron/stati ... l#distance
along with the understanding that it is always possible to add the keyword arg, sec = ....
after the normal unnamed arg signature to set the currently accessed section during the scope of the function call.
However there is one problem:
h.distance(sec=soma, seg=x)
always puts the origin at the 0 end of soma regardless of the value of x.
Two problems: that is the signature for the hoc statement
soma distance()
which sets the origin to 0 of the currently accessed section. Note that there is no named arg called seg for the distance function. And if there was a named arg called seg, it would undoubtedly take a nrn.Segment object and not a double.

Code: Select all

def fromtodistance(origin_section,to_segment):
  ...
Apart from the fact that your implementation uses two pushes and only one pop. A simpler generic version would be

Code: Select all

def fromtodistance(origin_segment, to_segment):
  h.distance(0, origin_segment.x, sec=origin_segment.sec)
  return h.distance(to_segment.x, sec=to_segment.sec)
So the distance from the distal end of the soma to the middle of a dend section would be
print fromtodistance(soma(1), dend(.5))

vellamike

Re: Transporting hoc to python

Post by vellamike » Thu Nov 11, 2010 5:00 am

along with the understanding that it is always possible to add the keyword arg, sec = ....
after the normal unnamed arg signature to set the currently accessed section during the scope of the function call.
I didn't know that, it all fits into place now. Thanks both of you for your great help it's really appreciated!

maya
Posts: 6
Joined: Mon Sep 27, 2010 9:10 am

hoc "access" abuse

Post by maya » Thu Nov 11, 2010 7:19 am

About "access abuse":

When I write in a procedure :

Code: Select all

distal = new SectionList()
	dist=100
	apic[14](0) distance()
	hotzone.remove(hotzone)										
	forsec trunk {
		if (distance(0) <= dist) {
			distal.append()
		} 
	}
After changing the "access" as you suggested, the distances are not calculated from apic[14] - but for the soma ! And the "distal" list includes the wrong sections.
It was written like this:

Code: Select all

distal = new SectionList()
	dist=100
	access apic[14](0) 
        distance()
	hotzone.remove(hotzone)										
	forsec trunk {
		if (distance(0) <= dist) {
			distal.append()
		} 
	}
And it ran OK.. but as you wrote, it's not recommended and I read that I shouldn't write "access" in a procedure at all.
How cam I write it so that the distances are calculated from apic[14] ?

Thank's
Maya

ted
Site Admin
Posts: 5534
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: hoc "access" abuse

Post by ted » Thu Nov 11, 2010 12:12 pm

maya wrote:About "access abuse"
It seems you misinterpreted my post from Tue Nov 09, 2010 8:58 pm viewtopic.php?f=2&t=2114&p=8025#p8002, which provided a couple of examples of how to define the currently accessed section with "section stack syntax," which has the general form
sectionname statement

One example advised replacing

Code: Select all

apical = new SectionList()
access apic[0]
apical.subtree()
with

Code: Select all

apical = new SectionList()
apic[0] apical.subtree()
The other example advised rewriting

Code: Select all

access soma
distance()
like so

Code: Select all

soma distance()
But revising

Code: Select all

access apic[14](0)
distance()
in a way that applies section stack syntax produces this result

Code: Select all

apic[14] distance()
not

Code: Select all

soma distance()

Post Reply