Concentration doesn't flow. Charge flows, mass flows, but not concentration.
If you're having difficulty recording a particular variable that an NMODL-specified mechanism "should" be calculating, it might be because the NMODL code doesn't expose that variable to hoc or Python. Your examples indicate that you want to record the calcium current produced by particular ion channels. This is possible as long as the NMODL code for your ion channels declares the current to be RANGE.
Here's an example of a mechanism that generates a particular ionic current in such a way that you can't get at it if there are any other mechanisms that produce a current carried by the same ionic species:
Code: Select all
NEURON {
SUFFIX kleak
USEION k READ ek WRITE ik
}
PARAMETER {
g = 0.001 (siemens/cm2)
ek = -65 (millivolt)
}
ASSIGNED {
ik (milliamp/cm2)
v (millivolt)
}
BREAKPOINT {
ik = g*(v - ek)
}
The ik produced by this mechanism is added to the total transmembrane potassium current, but there will be no hoc or Python variable that tells you how much potassium current is attributable to this particular channel. That's a real problem if the segment contains other mechanisms that also WRITE ik.
The fix is to tell NMODL that there needs to be such a variable. The obscure way, sure to confuse yourself and others, is to simply declare ik as a RANGE variable in the NEURON block like this:
Code: Select all
NEURON {
SUFFIX kleak
USEION k READ ek WRITE ik
RANGE ik
}
This takes advantage of a side-effect of the RANGE statement. Compile the mod file and presto! there is now an ik_kleak variable that tells how much current this particular mechanism generates. What makes this confusing is that a month from now, someone will ask "Why did you declare ik to be a RANGE variable? Isn't ik automatically a RANGE variable? [editor's note: it is] And doesn't USEION x WRITE ix tell NMODL that ix should be a RANGE variable? [editor's note: it does]" When that happens, you're probably not going to remember that you deliberately included the
RANGE ik
statement because of its side-effect. Just another example of why it's not a good idea to write code that relies on side-effects.
Instead, it's safer to use statements that are quite explicit about what's going on. The way to do this is declare a new variable i in the NEURON block
Code: Select all
NEURON {
SUFFIX kleak
USEION k READ ek WRITE ik
RANGE i
}
specify its units in the ASSIGNED block
Code: Select all
ASSIGNED {
ik (milliamp/cm2)
i (milliamp/cm2)
v (millivolt)
}
and calculate its value in the BREAKPOINT block
Code: Select all
BREAKPOINT {
i = g*(v - ek)
ik = i
}
Now there will be an i_kleak variable that hoc and Python can access.
These examples are density mechanisms, so the currents they report are in mA/cm2. To convert this to absolute current, you have to multiply by the surface area of the segment to which the current belongs. Note that NEURON has an area() function that returns the area of a segment in um2 (multiply by 1e-8 to convert to cm2 -- see
https://www.neuron.yale.edu/neuron/stat ... .html#area
By the way,
https://www.neuron.yale.edu/neuron/stat ... f-sections contains a lot of information that might be good to review from time to time.