Point processes: loc() and get_loc()

A collection of noteworthy items selected by our moderators from discussions about making and using models with NEURON.

Moderators: ted, wwlytton, tom_morse

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

Point processes: loc() and get_loc()

Post by ted »

Sometimes it is necessary to place or determine the location of a point process under
program control. This can be done with loc() and get_loc(), which are methods that can
be used with any point process.

pointproc.loc(rangeval)
where pointproc is an objref that points to a point process, tries to place the point
process on the currently accessed section at the location specified by rangeval. If
rangeval < 0 or > 1, an "Arg out of range in user function" error message is generated.
If there is no node at the specified location, the point process will be placed at the
closest internal node.

pointproc.get_loc()
returns a numerical value equal to the location (range) at which the point process is
attached to its section. It also pushes that section onto the section stack. The section
will remain on the section stack until the interpreter returns to the top level. For more
information about this, see the next message in this discussion thread.

The following proc, which is derived from one that is used in an exercise in the NEURON
Summer Course, tries to place an AlphaSynapse at a specific location on the currently
accessed section. "Tries" because there may not be a node at the location specified by
putsyn's argument, yet the synapse will be placed somewhere as long as the
location lies in the range 0..1. As a side-effect, this procedure sets the global variable
synloc to a value that tells where the synapse was actually placed.

Code: Select all

synloc=0
objref asyn
soma asyn = new AlphaSynapse(0.5)

proc putsyn() {
	if ($1 < 0 || $1 > 1) {
		printf("%c",7)	// ring bell
		print "ERROR--location must be in the range [0, 1]" 
		synloc = -1
	} else {
		// say what we want
		asyn.loc($1)  // loc() tries to place asyn at $1 on the current section
		// find out what we got
		synloc = asyn.get_loc()
   /* Note: get_loc() pushes the section of the target point process onto the 
	section stack, so that, within this proc, it becomes the currently accessed
	section.  If we include any more statements inside this proc after calling get_loc(),
	we should first restore the accessed section to what it was before get_loc() was 
	called.  This can be done by calling
		pop_section()
   */
	}
}
Example:
Assuming that there is a section called dend,
dend putsyn(1/PI)
will move the AlphaSynapse to the internal node of dend that is closest to 1/PI.
ted
Site Admin
Posts: 6287
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

How get_loc() affects the section stack

Post by ted »

.get_loc() pushes 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
Post Reply