NMODL Mechanism works with CVODE but not with fixed steps?

NMODL and the Channel Builder.
Post Reply
carl

NMODL Mechanism works with CVODE but not with fixed steps?

Post by carl »

I am having a strange problem - I normally run with CVODE, and I have several NMODL mechanisms that I wrote myself. In order to use an SEClamp I am running a fixed step simulation. To my surprise, the NMODL mechanisms that I have written do not function properly using fixed steps! As far as I can tell the ASSIGNED variables are set in the INITIAL block but are subsequently never updated. I was aware there are some designs that work under fixed steps but not with CVODE, but I am not aware of the reverse being true. As far as I can tell the mechanism(s) is(are) very standard based on the examples in the book. The only non-standard thing is that parameters are set from the hoc code, not given default values.

Here is an example of one of the mechanisms:

Code: Select all

TITLE Fast NA
: Fast Na channel, hodgkin huxley type
:
: by Carl Gold 04/11/04

NEURON {
	SUFFIX naf
	USEION na READ ena WRITE ina
	
	RANGE gbar
	RANGE minf, mtau, hinf, htau

	GLOBAL vhalf_m, vsteep_m, exp_m 
	GLOBAL tskew_m, tscale_m, toffset_m 
	
	GLOBAL vhalf_h, vsteep_h, exp_h
	GLOBAL tskew_h, tscale_h, toffset_h 
}

UNITS {
	(mA) = (milliamp)
	(mV) = (millivolt)
}

: NOTE - Initialize everything to zero - they are all reset from the hoc code 

PARAMETER {
	vhalf_m = 0 (mV)
	vsteep_m = 0 (mV)
	tskew_m = 0 
	tscale_m = 0 (ms)
	toffset_m = 0 (ms)
	exp_m = 0

	vhalf_h = 0 (mV)
	vsteep_h = 0 (mV)
	tskew_h = 0 
	tscale_h = 0 (ms)
	toffset_h = 0 (ms)
	exp_h = 0

	gbar = 0 (mho/cm2)
	

}

ASSIGNED {
	ena        (mV)       
	celsius    (degC)
	v          (mV)
	ina        (mA/cm2)
	minf
	mtau
	hinf
	htau
}

STATE {
	m
	h 

}

BREAKPOINT {
	SOLVE states METHOD cnexp
	ina = gbar*(m^exp_m)*(h^exp_h)*(v - ena)
}

INITIAL {

	rates(v)
	m = minf
	h = hinf
	ina = gbar*(m^exp_m)*(h^exp_h)*(v - ena)
}

DERIVATIVE states {
	rates(v)
	m' = (minf-m)/mtau
	h' = (hinf-h)/htau
}

PROCEDURE rates(v) {

	minf = var_inf(v, vhalf_m, vsteep_m)
	hinf = var_inf(v, vhalf_h, vsteep_h)

	mtau =  var_tau(v, vhalf_m, vsteep_m, tskew_m, tscale_m, toffset_m)
	htau =  var_tau(v, vhalf_h, vsteep_h, tskew_h, tscale_h, toffset_h)

}

FUNCTION var_inf(v(mV), vhalf(mV), vsteep(mV)) { 

	var_inf = 1 / (1 + exp((v - vhalf)/(vsteep))) 

}

FUNCTION var_tau(v (mV), vhalf (mV), vsteep (mV), tskew, tscale(ms), toffset(ms)) {

	var_tau = toffset + (tscale  / ( exp(-tskew*(v-vhalf)/vsteep) * (1+exp((v-vhalf)/vsteep)))  )


}
There must be something very obvious that I am missing here - but what is it???
ted
Site Admin
Posts: 6384
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Post by ted »

I don't see any obvious problems on a quick glance, but the acid test is to try to reproduce
the problem. Nonzero parameter values would be helpful.

One small note: it isn't necessary for the INITIAL block to reiterate assignment statements
that already exist in the BREAKPOINT block, i.e.
ina = gbar*(m^exp_m)*(h^exp_h)*(v - ena)
carl

Post by carl »

I have managed to isolate the source of the problem and it is very weird. Some background: the mod file shown above is actually a little bit different from how I really do things: I use the INCLUDE directive to share code between multiple mechanisms. In the mod file shown above, for simplicity, I combined a few files into one.

I have found that if I use the mod file without the INCLUDE directive (i.e. as one file per mechanism) then the mechanism works BOTH under CVode and under fixed steps. But when I use the INCLUDE directive with the mechanism divided into multiple files then it works only under CVode. Perhaps this may be due to the fact that the ordering of the blocks is different? I never knew this was of consequence.

I am emailing a small block of code that reproduces the bug to the administrator for further diagnosis - when we have a final resolution we will update this thread...
ted
Site Admin
Posts: 6384
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Post by ted »

The problem was that the DERIVATIVE block preceded the BREAKPOINT block. To quote
Michael Hines,
The problem is that sometimes the METHOD in the SOLVE statement
determines some of the parsing when the DERIVATIVE block is seen.
Because of this problem, nocmodl now prints an error message during mod file compilation:

Code: Select all

[hines@localhost mod_bad]$ nrnivmodl
/home/hines/tmp/mod_debug/mod_bad
naf.mod
naf.mod
"/home/hines/neuron/nrnobj/x86_64/bin/nocmodl" naf
Translating naf.mod into naf.c
INCLUDEing var_funcs.inc
INCLUDEing inact_gate_states.inc
INCLUDEing inact_na_currs.inc
The SOLVE statement must be before the DERIVATIVE block for states at
line 15 in file inact_na_currs.inc
        ina = gbar*(m^exp_m)*(h^exp_h)*(v - ena)
           ^
make: *** [naf.c] Error 1
[hines@localhost mod_bad]$
This fix requires version 5.9.1501 or above.

Readers who are interested in more information about the sequence of code blocks in
NMODL are referred to
https://www.neuron.yale.edu/phpBB2/view ... =1904#1904
Post Reply