Check if pointer is null in NMODL

NMODL and the Channel Builder.
Post Reply
ahwillia
Posts: 17
Joined: Wed Apr 23, 2014 2:17 pm

Check if pointer is null in NMODL

Post by ahwillia »

I am curious if the if statement in the code below is valid/good practice:

Code: Select all

DERIVATIVE state_change
  {
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  if(uPtr == NULL) {
    gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
  }
I am implementing a model that has homeostatically regulated maximal conductances (similar to https://senselab.med.yale.edu/modeldb/S ... odel=93321). The maximal conductances change over time in an activity-dependent manner when the pointer (uPtr) is set. However, sometimes I just want to run the code without this activity-dependent plasticity. In these cases, can I check for the NULL pointer using the code above? The intended outcome is for gbar to not change over time if the pointer is NULL.

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

Re: Check if pointer is null in NMODL

Post by ted »

I see what the implementer was up to. You're stuck with POINTERs, but you don't want to test for unresolved pointers (I seem to recall that hoc will simply generate an error message and stop execution). Even if hoc runs, it's not a good idea to have a key feature of a model (plasticity or non-plasticity) be an implicit consequence of what could be a mere programming accident (whether or not you remembered to use a setpointer statement). But there is still a principled way to get the effect that you want.

These 7 mechanisms generate membrane currents and have "plastic" conductance densities:
cas.mod
cat.mod
h.mod
ka.mod
kca.mod
kd.mod
na.mod
Each declares POINTER gbar, and has a BREAKPOINT block that contains a statement of the form
ix = gbar * gating variables * driving force
or statements similar to
g = gbar * gating variables
ix = g * driving force

Here's what I suggest you do. Read these "Steps" as sequences of incremental changes, in which each change is followed by testing to make sure that the model still works properly.

Step 1:

Code: Select all

For each mod file
  change gbar to gptr
  change the corresponding setpointer statement in hoc accordingly
  recompile the mod files
  run a simulation to make sure you didn't break anything
Step 2:

Code: Select all

For each mod file
  in the NEURON block insert the statements
    RANGE gbar
    GLOBAL plastic
  in the PARAMETER block insert
    plastic = 1 (1)
    gbar = somevalue
    where somevalue is whatever you want to be the default when plasticity is off
  in the BREAKPOINT block change
    ix = gptr * gating variables * driving force
    to
    if (plastic==1) {
      gbar = gptr
    }
    ix = gbar * gating variables * driving force
    If instead the BREAKPOINT block contained a
    g = gptr * gating variables
    statement, change it to
    if (plastic==1) {
      gbar = gptr
    }
    g = gbar * gating variables
  recompile the mod files
  run a simulation with plasticity enabled (the default condition) to make sure you didn't break anything
  use a hoc statement to set plasticity_suffix = 0 (where suffix is this mechanism's SUFFIX)
    and then run a simulation to verify that this mechanism's conductance is now constant
The fact that plastic is GLOBAL means that this parameter will affect all instances of a given mechanism. If you want to have more fine grained control--per segment control, actually--declare RANGE plastic instead.
ahwillia
Posts: 17
Joined: Wed Apr 23, 2014 2:17 pm

Re: Check if pointer is null in NMODL

Post by ahwillia »

Hi Ted -- thanks for the quick and thoughtful response.

I think your solution would work great for a one-compartment model, or for a multi-compartment model with a uniform distribution of 'plastic' conductances. This is the case for the original model I provided the link to.

But what if I want my 'plastic' conductances to have different densities in different compartments as a result of the activity-dependent changes? For example, I want the plasticity time constant to be different for the same ion channel in different compartments.

My solution to this was to have each instance of the channel mechanism update its own maximal conductance:

Code: Select all

DERIVATIVE state_change
  {
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
Here, alpha_g is the insertion rate constant for channels into the membrane, beta_g is the removal rate constant from the membrane, and uPtr is a pointer to the output of the conductance 'controller'. uPtr can be thought of as the amount of mRNA for the channel of interest. There is only one 'u' variable for each conductance, and it changes over time in response to calcium transients in the soma compartment.

Building on your advice, would it be acceptable to use the following code for my purposes (with 'plastic' being a range variable):

Code: Select all

DERIVATIVE state_change
  {
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  if(plastic == 1) {
      gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
  }
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Check if pointer is null in NMODL

Post by ted »

My suggestions focused on this specific issue
sometimes I just want to run the code without this activity-dependent plasticity . . . The intended outcome is for gbar to not change over time
and were posed in terms of the example in ModelDB to which you referred.
I want the plasticity time constant to be different for the same ion channel in different compartments

Code: Select all

DERIVATIVE state_change
  {
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
. . . would it be acceptable to use . . .

Code: Select all

DERIVATIVE state_change
  {
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  if(plastic == 1) {
      gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
  }
Seems OK as far as it goes, but you might want to be more explicit about what happens when plastic is not == 1.

Code: Select all

  if(plastic == 1) {
      gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  } else {
    gbar' = 0
  }
ahwillia
Posts: 17
Joined: Wed Apr 23, 2014 2:17 pm

Re: Check if pointer is null in NMODL

Post by ahwillia »

Great! This is easy to implement. Thanks for your help.

Out of curiousity, how does NEURON handle the line

Code: Select all

gbar' = 0
Will this slow the simulation down a little bit, or is it smart enough to ignore gbar in the integration routine entirely?

Thanks again!
ahwillia
Posts: 17
Joined: Wed Apr 23, 2014 2:17 pm

Re: Check if pointer is null in NMODL

Post by ahwillia »

I am now getting a list of compile-time errors. The first listed one is:

Code: Select all

invalid storage class for function 'state_change'
I get this error for the following code:

Code: Select all

DERIVATIVE state_change
  {  
  rates(v)  : Calculate minf, taum, hinf, tauh
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  if( plastic==1 ){
    gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  } else {
    gbar' = 0
  }
  }
This also causes the same error:

Code: Select all

DERIVATIVE state_change
  {  
  rates(v)  : Calculate minf, taum, hinf, tauh
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  if( plastic==1 ){
    gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
  }
The code below does not appear to cause an error. It compiles fine, but doesn't do what I want it to do.

Code: Select all

DERIVATIVE state_change
  {  
  rates(v)  : Calculate minf, taum, hinf, tauh
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  if( plastic==1 ){ }
  gbar' = (alpha_g * uPtr) - (beta_g * gbar)
  }
This suggests to me that the .mod file won't compile if a derivative is declared inside an if statement. I also tried to create two different DERIVATIVE blocks for plastic vs not plastic modes:

Code: Select all

BREAKPOINT
{
  if(plastic==1) {
      SOLVE plastic_state_change METHOD cnexp
  } else {
       SOLVE static_state_change METHOD cnexp
  }
  g = (gbar/surf_area)*m^3*h
  i = (1e-4)*(g*(v-ek))
}

DERIVATIVE plastic_state_change
{  
  rates(v)  : Calculate minf, taum, hinf, tauh
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
  gbar' = (alpha_g * uPtr) - (beta_g * gbar)
}

DERIVATIVE static_state_change
{  
  rates(v)  : Calculate minf, taum, hinf, tauh
  m' = (minf-m)/taum
  h' = (hinf-h)/tauh
}
This code also doesn't compile and gives the following error:

Code: Select all

syntax error:
 Illegal SOLVE statement:
 Illegal expression:
 Illegal statement:
 Illegal block at line 82 in file Aa_AT.mod
       SOLVE static_state_change METHOD cnexp
Should I start a new thread for this? About the use of if statements within the DERIVATIVE block? Thanks again for all the help.
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Check if pointer is null in NMODL

Post by ted »

There are many ways to skin a cat.

Suppose the original DERIVATIVE block is

Code: Select all

DERIVATIVE states {
  rates(v)
  m' = (minf - m)/tau_m
}
and you find that trying to compile this

Code: Select all

DERIVATIVE states {
  rates(v)
  if (fixed==0) {
    m' = (minf - m)/tau_m
  } else {
    m' = 0
  }
}
fails miserably. Split all of that logic into a FUNCTION like so

Code: Select all

FUNCTION dxdt(x, xinf, tau_x (ms))(/ms) {
  if (fixed==0) {
    dxdt = (xinf - x)/tau_x
  } else {
    dxdt = 0
  }
}
DERIVATIVE states {
  rates(v)
:  m' = (minf - m)/tau_m
  m' = dxdt(m, minf, tau_m)
}
and now you have something that works.
ahwillia
Posts: 17
Joined: Wed Apr 23, 2014 2:17 pm

Re: Check if pointer is null in NMODL

Post by ahwillia »

Excellent. Thank you!
Post Reply