Obtaining NetCon actual pre-section along fraction x value?

Moderator: wwlytton

Post Reply
JustasB
Posts: 28
Joined: Tue Dec 08, 2015 8:17 pm
Location: Tempe, AZ, USA
Contact:

Obtaining NetCon actual pre-section along fraction x value?

Post by JustasB »

Given a NetCon instance whose source is section membrane potential, is it possible to extract the actual x value location on the pre-section?

For example, the following minimal python code only returns either 0, 0.5, or 1.0 fractions.

Code: Select all

from neuron import h, gui
soma = h.Section()
soma.nseg = 10
h.NetCon(soma(0)._ref_v,None).preloc() # OK - returns 0
h.NetCon(soma(1)._ref_v,None).preloc() # OK - returns 1.0
h.NetCon(soma(0.5)._ref_v,None).preloc() # OK - returns 0.5
h.NetCon(soma(0.25)._ref_v,None).preloc() # Problem - returns 0.5 instead of 0.25
h.NetCon(soma(0.75)._ref_v,None).preloc() # Problem - returns 0.5 instead of 0.75
I understand this is due to a warning mentioned in the documentation:
https://neuron.yale.edu/neuron/static/p ... Con.preloc
Warning: The return value of x is .5 unless the source is a membrane potential and located at 0, or 1, in which case value returned is 0 or 1, respectively. Therefore it does not necessarily correspond to the actual x value location.
Given the above limitation of preloc(), is there any other way to obtain the actual along pre-section fraction that was originally used when creating the NetCon instance?

Note: In my use case, I'm comparing a sizable number of models created by others, and modifying the original models to keep track of the along fractions would not be practical.
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Obtaining NetCon actual pre-section along fraction x value?

Post by ted »

As far as I know, there is no built-in function that returns the range location of a NetCon's spike detector. A user-level workaround would be to add a few data structures and revise model setup code so that the necessary information is stored in one or more lists at the time of NetCon creation.
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: Obtaining NetCon actual pre-section along fraction x value?

Post by hines »

I will create a new python specific method pyseg = NetCon.preseg() which returns a nrn.Segment object from which you can get
NetCon.preseg().x and NetCon.preseg().sec
It will return None if the NetCon has no source, the source is on a different process (possible with MPI), or the source is not a voltage.
Will get back to you when the change has been committed to the github repository. With this method, the section will not be pushed onto
the section stack so there will be no need for a corresponding h.pop_section()
JustasB
Posts: 28
Joined: Tue Dec 08, 2015 8:17 pm
Location: Tempe, AZ, USA
Contact:

Re: Obtaining NetCon actual pre-section along fraction x value?

Post by JustasB »

Thank you!
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: Obtaining NetCon actual pre-section along fraction x value?

Post by hines »

The change is
https://github.com/nrnhines/nrn/commit/ ... 1f2355e595
Both preloc and preseg have been changed to return a arc position from 0 to 1 (if the threshold is a voltage variable)
which is relative to the end that has a parent (ie. not relative to the section orientation specified by the the section connection (returned by
section.orientation())). Note that if the threshold variable is not voltage or if there is no source, preseg() returns None and preloc() returns
-2.0 or -1.0 respectively. Only preloc returning >= 0 needs to have a corresponding h.pop_section. In no case is pop_section needed for preseg().

My test example is

Code: Select all

$ cat preloc.py
from neuron import h, gui
soma = h.Section()
soma.nseg = 10
print(h.NetCon(soma(0)._ref_v,None).preseg().x == 0.0)
print(h.NetCon(soma(1)._ref_v,None).preseg().x == 1.0)
print(h.NetCon(soma(0.5)._ref_v,None).preseg().x == 0.55)
print(h.NetCon(soma(0.25)._ref_v,None).preseg().x == 0.25)
print(h.NetCon(soma(0.75)._ref_v,None).preseg().x == 0.75)
print(h.NetCon(soma(0.75)._ref_cm,None).preseg() == None)
The result printed is

Code: Select all

$ nrniv -python preloc.py
NEURON -- VERSION 7.5 master (af83c99) 2018-01-25
Duke, Yale, and the BlueBrain Project -- Copyright 1984-2016
See http://neuron.yale.edu/neuron/credits

True
True
True
True
True
True
>>> 
Note that because there are an even number of segments in this test, there is no segment with a center at 0.5 and the segment containing 0.5
resolves to the segment with center 0.55
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: Obtaining NetCon actual pre-section along fraction x value?

Post by hines »

... relative to the end that has a parent (ie. not relative to the section orientation specified by the the section connection (returned by
section.orientation()))
That is a bug and fixed in the latest changeset
https://github.com/nrnhines/nrn/commit/ ... 51e8c300b0

A better test is

Code: Select all

$ cat preloc.py
from neuron import h, gui
d1 = h.Section()
d2 = h.Section()
d2.connect(d1(1), 1)
d1.nseg=5
d2.nseg=5

h.topology()

def eq(x, y):
 return abs(x - y) < 1e-11

def test(sec, x):
  nc = h.NetCon(sec(x)._ref_v, None, sec=sec)
  print (eq(nc.preseg().x, x), x, nc.preseg().x)
  ncx = nc.preloc()
  print (eq(ncx,  x), x, ncx)
  h.pop_section()

for sec in [d1, d2]:
  test(sec, 0.)
  test(sec, 1.)
  test(sec, 0.1)

pc = h.ParallelContext()
e = h.ExpSyn(d1(.5))
nc = pc.gid_connect(0, e)
print (nc.preseg() == None)
print (nc.preloc() == -1.)
h.pop_section()

nc = h.NetCon(d2(.1)._ref_cm, None, sec=d2)
print (nc.preseg() == None)
print (nc.preloc() == -2.)
h.pop_section()
which results in

Code: Select all

$ nrniv -python preloc.py
NEURON -- VERSION 7.5 master (e786f17) 2018-01-26
Duke, Yale, and the BlueBrain Project -- Copyright 1984-2016
See http://neuron.yale.edu/neuron/credits


|-----|       __nrnsec_0x1bd7740(0-1)
       `----|       __nrnsec_0x1bd77a0(1-0)

(True, 0.0, 0.0)
(True, 0.0, 0.0)
(True, 1.0, 1.0)
(True, 1.0, 1.0)
(True, 0.1, 0.1)
(True, 0.1, 0.1)
(True, 0.0, 0.0)
(True, 0.0, 0.0)
(True, 1.0, 1.0)
(True, 1.0, 1.0)
(True, 0.1, 0.09999999999999998)
(True, 0.1, 0.09999999999999998)
True
True
True
True
>>> 
Post Reply