Missing documents for pointprocess.get_loc() and .has_loc()

Suggestions for improvements to the NEURON Forum.
Post Reply
eacheon
Posts: 97
Joined: Wed Jan 18, 2006 2:20 pm

Missing documents for pointprocess.get_loc() and .has_loc()

Post by eacheon »

these two methods would be very useful to everybody, but they do not appear in the on line reference.
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Post by ted »

True. These methods, which apply to ALL point processes, aren't documented in the
Programmer's Reference.

I've never had a need to explicitly use has_loc() in my own programs, because I have
never had to deal with a point process that was not attached to a section (i.e. a point
process that has been "free'd").

However, get_loc() is another matter, especially when it is used in conjunction with loc(),
which is another undocumented method. Here are brief descriptions of these methods,
and a bit of code that illustrates their practical application:
Point processes: loc() and get_loc()
https://www.neuron.yale.edu/phpBB2/viewtopic.php?t=1057
refriend

Re: Missing documents for pointprocess.get_loc() and .has_loc()

Post by refriend »

I am using .get_loc() in a simple piece of code to determine the 3d coordinates of individual synapses in network of multiple cells. (Yes, I realize my code places the synapse on the centroid.)

Code: Select all

strdef section_name, cmd
objref this_synapse, syn_section

this_synapse = cells.o[3].synlist.o[2] // replace w/ parameter when functionalized
range_syn = this_synapse.get_loc() // (0-1) https://www.neuron.yale.edu/phpBB/viewtopic.php?f=28&t=1057&p=3551&hilit=synapse+location#p3551
section_name = secname()
sprint(cmd, "section_L = %s.L", section_name)	
execute(cmd)
// Find coordinates for 3d-coord prior to and after syn_range
ii = 0
while ( (arc3d(ii)/section_L) <= range_syn) ii = ii +1 // find surrounding 3d  indexes

range_prior = arc3d(ii-1)/section_L
range_post = arc3d(ii)/section_L
range_syn_normalized = (range_syn-range_prior)/(range_post - range_prior)
coord_x = range_syn_normalized * ( x3d(ii)-x3d(ii-1) ) 
coord_y = range_syn_normalized * ( y3d(ii)-y3d(ii-1) ) 
coord_z = range_syn_normalized * ( z3d(ii)-z3d(ii-1) ) 

pop_section()
Per your reference I expected secname() to return the name of the section upon which the synapse (cells.o[3].synlist.o[3]) resides (Default_Cell[1].dendrite[2]). Instead, secname() returns 'Default_Cell[0].soma'. My network consists of eight cells create in the following order:

Code: Select all

/*0 S0 */  {cell_append(new S_NetStim(),	60,	 120, 0)}
/*1 S1 */  {cell_append(new S_NetStim(),	51,	 120, 0)}
/*2 D2 */  {cell_append(new Default_Cell(),	32,	 123, 0)}
/*3 D3 */  {cell_append(new Default_Cell(),	33,	 123, 0)}
/*4 S4 */  {cell_append(new S_NetStim(),	54,	 120, 0)}
/*5 D5 */  {cell_append(new Default_Cell(),	35,	 123, 0)}
/*6 S6 */  {cell_append(new S_NetStim(),	60,	 125, 0)}
/*7 S7 */  {cell_append(new S_NetStim(),	60,	 124, 0)}
Am I misunderstanding the operation of (a) the stack, (b) .getloc(), (c) secname(), or (d) am I completely clueless?

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

Re: Missing documents for pointprocess.get_loc() and .has_loc()

Post by ted »

The problem lies in my description of how the section stack is affected by calling .get_loc(), which was incomplete and misleading. Your question prompted me to revisit this, and here's the TRUTH:

.get_loc() DOES push a section onto the stack, and there it remains, but only until the interpreter returns to the top level. Once the interpreter returns to the top level, the section is automatically popped off the section stack.

Code is at the top level of the interpreter unless it is inside a closed pair of curly brackets { }. For example, code inside a proc or func is not at the top level of the interpreter.

Example: copy this block of code to a file and use NEURON to execute that file.

Code: Select all

create soma, dend
access soma
connect dend(0), soma(1)

objref asyn
dend asyn = new AlphaSynapse(0.5)

print "default section: ", secname()

// test 0
print " "
print "Test 1:  Executing .get_loc() at top level"
asyn.get_loc()
print "Checking current section at top level: ", secname()

print " "
print "Test 2:  Executing .get_loc() at top level"
asyn.get_loc() {
  print "but curly brackets start a block of code that executes in the context"
  print "of that call, so when we test for the current section, we're not at"
  print "the top level, and the current section is: ", secname()
}

print "Closing the block of code returns us to top level,"
print "and the current section is: ", secname()

proc test_3() {
  print "proc test_3 executes .get_loc()"
  asyn.get_loc()
  print "Within proc test_3, current section is: ", secname()
}

print " "
print "Test 3"
test_3()
print "After return to top level, current section is: ", secname()

proc test_4() {
  print "proc test_4 calls proc test_3"
  test_3()
  print "After return from proc test_3, but still inside proc test_4,"
  print "current section is: ", secname()
}

print " "
print "Test 4"
test_4()
print "After return to top level, current section is: ", secname()
You will get this output:

Code: Select all

default section: soma
 
Test 1:  Executing .get_loc() at top level
        0.5 
Checking current section at top level: soma
 
Test 2:  Executing .get_loc() at top level
but curly brackets start a block of code that executes in the context
of that call, so when we test for the current section, we're not at
the top level, and the current section is: dend
Closing the block of code returns us to top level,
and the current section is: soma
 
Test 3
proc test_3 executes .get_loc
Within proc test_3, current section is: dend
After return to top level, current section is: soma
 
Test 4
proc test_4 calls proc test_3
proc test_3 executes .get_loc
Within proc test_3, current section is: dend
After return from proc test_3, but still inside proc test_4,
current section is: dend
After return to top level, current section is: soma
refriend

Re: Missing documents for pointprocess.get_loc() and .has_loc()

Post by refriend »

Very interesting. I amended your code and encountered one strange occurrence. Where is the '0.5' in revised Test 3 coming from? It doesn't occur elsewhere.

(I've commented the lines added or edited).

Code: Select all

create soma, dend, axon // added axon
access soma
connect dend(0), soma(0)
connect axon(0), soma(1) // added axon

objref asyn, asyn2
dend asyn = new AlphaSynapse(0.5)
axon asyn2 = new AlphaSynapse(0.7) // added asyn2
print "default section: ", secname()

// test 0
print " "
print "Test 1:  Executing .get_loc() at top level"
asyn.get_loc()
print "Checking current section at top level: ", secname()

print " "
print "Test 2:  Executing .get_loc() at top level"
asyn.get_loc() {
	print "but curly brackets start a block of code that executes in the context"
	print "of that call, so when we test for the current section, we're not at"
	print "the top level, and the current section is: ", secname()
}

print "Closing the block of code returns us to top level,"
print "and the current section is: ", secname()

proc test_3() {
	print "proc test_3 executes .get_loc()"
	asyn.get_loc()
	print "Within proc test_3, current section is: ", secname()
}

print " "
print "Test 3"
test_3()
asyn2.get_loc() // changed to asyn2
print "After return to top level, current section is: ", secname()

proc test_4() {
	print "proc test_4 calls proc test_3"
	test_3()
	print "After return from proc test_3, but still inside proc test_4,"
	asyn2.get_loc() // added asyn2
	print "current section is: ", secname()
}

print " "
print "Test 4"
test_4()
print "After return to top level, current section is: ", secname()
Results:

Code: Select all

default section: soma
 
Test 1:  Executing .get_loc() at top level
        0.5 
Checking current section at top level: soma
 
Test 2:  Executing .get_loc() at top level
but curly brackets start a block of code that executes in the context
of that call, so when we test for the current section, we're not at
the top level, and the current section is: dend
Closing the block of code returns us to top level,
and the current section is: soma
 
Test 3
proc test_3 executes .get_loc()
Within proc test_3, current section is: dend
        0.5 
After return to top level, current section is: soma
 
Test 4
proc test_4 calls proc test_3
proc test_3 executes .get_loc()
Within proc test_3, current section is: dend
After return from proc test_3, but still inside proc test_4,
current section is: axon
After return to top level, current section is: soma
oc>
As always, thanks!
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Missing documents for pointprocess.get_loc() and .has_loc()

Post by ted »

asyn2.get_loc(), which returns a numeric value, is executed at the top level.

Thank you for raising a question that helped me refine my understanding, and the documentation, of what get_loc does. I have now edited the related discussion thread in the "Hot tips" area of The NEURON Forum.
refriend

Re: Missing documents for pointprocess.get_loc() and .has_loc()

Post by refriend »

Interesting. So a command's success/returned value is only 'echoed' to the terminal when at the top level. I've actually used {cmd} before but never fully understood why it worked to suppress echoed output.

Multiple lessons learned today. Thanks.
Post Reply