Way to change properties of a section's individual segment

Particularly useful chunks of hoc and/or NMODL code. May be pedestrian or stunningly brilliant, may make you gasp or bring tears to your eyes, but always makes you think "I wish I had written that; I'm sure going to steal it."
Post Reply
makrseke
Posts: 16
Joined: Mon Apr 03, 2017 6:43 am

Way to change properties of a section's individual segment

Post by makrseke »

Dear all,

I think I found a way to change the properties of the different segments inside one section, however I am not sure whether indeed this is correct. I will give below an example and I would really appreciate it if someone could tell me if indeed this does what I am aiming for (changing properties in parts/segments of a section).

EXAMPLE: Let's say we have a neuron-cell in NEURON, on which we wish to insert in one axon-branch (e.g. axon[4]) different properties in 90% of its (axon[4]) length: i.e. Have from 0%-10% channel-conductance equal to 0.12, from 10%-90% we want it to be equal to 0.002, and then again from 90%-100% equal to 0.12.

MY SOLUTION : Use the range-variables, but without actually ranging them. Also, we will need to increase the nseg to have accuracy of 0.1 (nseg = 11). That is to say:

Code: Select all

 axon[4].nseg = 11                            // Increase accuracy for changing properties - odd number over the d_lambda suggested value
gNa1 = 0.12
gNa2 = 0.002
axon[4].gmax_naf(0:0.1) = gNa1:gNa1          // Instead of varying the gNa1 to let's say gNa2, we want it to be gNa1 for all the first 10% of the axon[4]-length
axon[4].gmax_naf(0.1:0.9) = gNa2:gNa2       //  Changing properties inside the section to let's say gNa2 
axon[4].gmax_naf(0.9:1) = gNa1:gNa1        //   Again insert for the last 10% of the axon[4]-length gNa1 as a sodium conductance value 
When I ran the code, on the oc>| command window I wrote the following (to check if indeed this axon[4] had different conductance properties along its length) commands:

Code: Select all

>> axon[4].gmax_naf(0)          //  Result on the oc>|after enter : 0.12
>> axon[4].gmax_naf(0.1)       //   Result on the oc>|after enter : 0.12
>> axon[4].gmax_naf(0.2)      //    Result on the oc>|after enter : 0.002
>> axon[4].gmax_naf(0.5)     //     Result on the oc>|after enter : 0.002
>> axon[4].gmax_naf(0.9)    //      Result on the oc>|after enter : 0.002
>> axon[4].gmax_naf(1)     //       Result on the oc>|after enter : 0.12
Hence, on screen it shows that indeed the conductances are different in the desired parts of the axon[4]-branch.
But again I wanted to make sure the syntax is indeed accomplishing correctly what I aimed, by having indeed theses varied conductance-parts inside that one branch, in order to get correct results when tests-are performed on the cell.

Thank you very much in advance!

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

Re: Way to change properties of a section's individual segme

Post by ted »

How to specify spatial variation of a range variable parameter is a common problem. You are to be commended for your determination in digging up that old feature of hoc and trying to figure out how to use it for a good purpose. Unfortunately, the
sectionname.rangevarname(range0:range1) = value0:value1
syntax can be confusing and difficult to use. I don't even know where to find it in the Programmer's Reference, but if I did, I'd revise that entry to say that the approach is deprecated. It's kind of like those embarrassing pictures some people have posted on the web that they wish would just go away.

What's a better approach? Depends on what you are trying to accomplish. The most flexible approach is to specify that a parameter varies over a set of sections as a function of some distance metric. On NEURON's Documentation page http://www.neuron.yale.edu/neuron/docs see the ChannelBuilder tutorials--in particular, the third one
Specifying parameterized variation of biophysical properties
Set up a toy model cell that has the appropriate variation of channel density, verify that the resulting model is what it is supposed to be, and then save the configured CellBuilder to a ses file (for future reference), and export a hoc file of your toy model. In that hoc file you will find a procedure that you can reuse in your own model setup code. Note that if you change spatial discretization, you also have to execute the parameter varying procedure afterward.

If instead you want some parameter abc to have value0 in one part of a neurite and value1 in another part of that neurite, and you need to guarantee that the boundary between these different regions is not affected by nseg, then the best approach is to split the neurite into 2 or more sections, each of which will have its own value for abc.
makrseke
Posts: 16
Joined: Mon Apr 03, 2017 6:43 am

Re: Way to change properties of a section's individual segme

Post by makrseke »

Dear Ted,

Thank you very much for your answer.

From what I understand, it is impossible to achieve the correct spatial accuracy with rangevar and nseg in order to manage having specific parts/segments of one single section with distinct parameter-biophysics' properties. It is a bit strange though how it shows on the commend screen at the 0.1 normalized-location of the axon that the gNa+ is 0.12 and for the 0.4 normalized location it shows that it is 0.002. What does that mean? What is it showing? Does it mean that it changed something but not what we wish? Or is it simply a faulty indication? I am only asking to understand a bit better certain things and how they react.

FOR THE PROBLEM I TRY TO ANSWER:

Indeed, I wanted to have in one single section every time the first 10% of the section with one specific gNa+ conductance, then the 80% of that same section having another different value of gNa+ conductance, and finally the last 10% of the section with the same gNa+ as the first 10%.

Hence, I know it would be best to go with what you suggested as a second solution.

However, I am having one predicament here:
The code I am structuring inserts a realistic-cell topology with way too many axon-sections (axon) and the change of one of those sections' biophysics properties of gNa+ is decided to happen or not for each axon via a control variable that interchanges its "1" ("yes-change") or "0" ("no-do-not-change") value after some random steps. Hence, it is not known from the beginning which axon's will need to have those conductance-values changed. Also, I cannot "mess" with the sections by splitting one section to 3 for having the previously described effect:

I wanted to have in one single section every time the first 10% of the section with one specific gNa+ conductance, then the 80% of that same section having another different value of gNa+ conductance, and finally the last 10% of the section with the same gNa+ as the first 10%.


Since I will have to do so in the cell-template by hand and there are too many connections, and the rest of the axon sections that would also need to change in total number --> axon will be axon, axon[i+1], axon[i+2]. So the every previous axon[i+1] will have to become axon[i+3]. And that will increase for every new axon splitting into 3 other sections.

I am sure you can see my challenge here.

I will try using your first suggestion a bit altered:

- Create a subset per axon that is decided to have by my control-variable changed the gNa+,
- Create a step_down-step_up-step_down function (like a spatial-dependent square-wave function) for having the conductance vary the desired way, and which I will have
- inserted via the SubsetDomainIterator class, inside my main model code and not the template file which I simply open to create the main topology once inside my main hoc code.

I am not sure whether that may work at all/ is possible, but trying never hurt.

I would really appreciate it if I could have your thoughts on that as well.

I will post again if I get positive or negative results. Thanks again!

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

Re: Way to change properties of a section's individual segme

Post by ted »

makrseke wrote:From what I understand, it is impossible to achieve the correct spatial accuracy with rangevar and nseg in order to manage having specific parts/segments of one single section with distinct parameter-biophysics' properties.
A correct statement would be that it is possible to conceive of arbitrary spatial variation of parameters that may require some effort to achieve.
It is a bit strange though how it shows on the commend screen at the 0.1 normalized-location of the axon that the gNa+ is 0.12 and for the 0.4 normalized location it shows that it is 0.002.
Was that result unexpected?
The section's first two internal nodes are at 0.045... and 0.136..., so this statement
axon[4].gmax_naf(0:0.1) = gNa1:gNa1
affects only the first segment. Likewise, the section's last two internal nodes are at 0.863... and 0.954..., so this statement
axon[4].gmax_naf(0.1:0.9) = gNa2:gNa2
affects the middle 9 segments. Consequently gmax_naf will be 0.12 in the first and last segments, and 0.002 in all the other segments, which is exactly as your code specifies.
I wanted to have in one single section every time the first 10% of the section with one specific gNa+ conductance, then the 80% of that same section having another different value of gNa+ conductance, and finally the last 10% of the section with the same gNa+ as the first 10%.

Hence, I know it would be best to go with what you suggested as a second solution.

However, I am having one predicament here:
The code I am structuring inserts a realistic-cell topology with way too many axon-sections (axon) and the change of one of those sections' biophysics properties of gNa+ is decided to happen or not for each axon via a control variable that interchanges its "1" ("yes-change") or "0" ("no-do-not-change") value after some random steps. Hence, it is not known from the beginning which axon's will need to have those conductance-values changed. Also, I cannot "mess" with the sections by splitting one section to 3
Then let me suggest a different approach. nseg = 10 guarantees that the length of each segment is exactly 10% of section length. For each section that is to have your particular nonuniform channel distribution, do the following
nseg = 10
gbar_whatever = 0.002
gbar_whatever(0.05) = 0.12
gbar_whatever(0.95) = 0.12
This is easily done on the fly by appending each section that is to be altered to a sectionlist that is created just before you do whatever it is that decides which sections are to be perturbed. Then after all decisions have been made, iterate over the sectionlist and do the necessary assignments. Example:

Code: Select all

func perturbthis() {
  code that decides whether the currently accessed section 
  will be perturbed
  return 1 if yes, 0 if no
}

// iterates over all sections with the base name "axon"
// and returns a SectionList whose elements are those that are to be perturbed
obfunc makechangelist() { localobj slist
  slist = new SectionList()
  forsec "axon" if (perturbthis()==1) slist.append()
  return slist
}

objref changelist
changelist = makechangelist()

proc changethem() {
  forsec $o1 {
    nseg = 10
    gbar_whatever = 0.002
    gbar_whatever(0.05) = 0.12
    gbar_whatever(0.95) = 0.12
  }
}

changethem(changelist)
I will have to do so in the cell-template by hand
It's not clear why that would be necessary, but that's a topic for a separate discussion.
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Way to change properties of a section's individual segme

Post by ted »

Of course the drawback of changing nseg to an even number is that the changed sections will not have a node at 0.5, so references that are nominally at the midpoint, such as v(0.5), will actually pertain to the node at of variables that are nominally at that location will actually pertain to 0.45 or 0.55, depending on roundoff error.
makrseke
Posts: 16
Joined: Mon Apr 03, 2017 6:43 am

Re: Way to change properties of a section's individual segme

Post by makrseke »

Dear Ted,

I think I understand better now your first response too. Thank you very much a lot for elaborating and thank you for proposing another way too, it's really helpful!

For affirming this answer:
Was that result unexpected?
The section's first two internal nodes are at 0.045... and 0.136..., so this statement
axon[4].gmax_naf(0:0.1) = gNa1:gNa1
affects only the first segment. Likewise, the section's last two internal nodes are at 0.863... and 0.954..., so this statement
axon[4].gmax_naf(0.1:0.9) = gNa2:gNa2
affects the middle 9 segments. Consequently gmax_naf will be 0.12 in the first and last segments, and 0.002 in all the other segments, which is exactly as your code specifies.
No it was as I expected it to be, however I wasn't sure if the syntax I wrote was indeed applying it. In other words the code I wrote initially is indeed working properly in this example, however it is better (for ensuring we do not make a mistake in spatial resolution) to use one of the other approaches, right?
Then let me suggest a different approach. nseg = 10 guarantees that the length of each segment is exactly 10% of section length. For each section that is to have your particular nonuniform channel distribution, do the following
nseg = 10
gbar_whatever = 0.002
gbar_whatever(0.05) = 0.12
gbar_whatever(0.95) = 0.12
This is easily done on the fly by appending each section that is to be altered to a sectionlist that is created just before you do whatever it is that decides which sections are to be perturbed. Then after all decisions have been made, iterate over the sectionlist and do the necessary assignments. Example:

Code: Select all

CODE: SELECT ALL
func perturbthis() {
  code that decides whether the currently accessed section 
  will be perturbed
  return 1 if yes, 0 if no
}

// iterates over all sections with the base name "axon"
// and returns a SectionList whose elements are those that are to be perturbed
obfunc makechangelist() { localobj slist
  slist = new SectionList()
  forsec "axon" if (perturbthis()==1) slist.append()
  return slist
}

objref changelist
changelist = makechangelist()

proc changethem() {
  forsec $o1 {
    nseg = 10
    gbar_whatever = 0.002
    gbar_whatever(0.05) = 0.12
    gbar_whatever(0.95) = 0.12
  }
}

changethem(changelist)
Of course the drawback of changing nseg to an even number is that the changed sections will not have a node at 0.5, so references that are nominally at the midpoint, such as v(0.5), will actually pertain to the node at of variables that are nominally at that location will actually pertain to 0.45 or 0.55, depending on roundoff error.
Thank you for the second approach that you proposed. I though about using the nseg =10, however as you said, I tried to avoid having the inaccuracy round-off error. Maybe I will go with that eventually, since using on the fly the appending of the desired section to a sectionlist, seems a great idea. Thank you very much!

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

Re: Way to change properties of a section's individual segme

Post by ted »

In other words the code I wrote initially is indeed working properly in this example, however it is better (for ensuring we do not make a mistake in spatial resolution) to use one of the other approaches, right?
Clarity of code is probably the most important reason to avoid the
sectionname.rangevarname(range0:range1) = value0:value1
syntax.
makrseke
Posts: 16
Joined: Mon Apr 03, 2017 6:43 am

Re: Way to change properties of a section's individual segme

Post by makrseke »

Great, thanks a lot Ted!
Post Reply