Excellent. In one step you can read your entire matrix into a hoc Matrix. Depending on layout of your matrix--
row 0 holds the series of time values, rows 1..N hold the series of temperatures for N physical locations,
or
column 0 holds the series of time values, columns 1..N hold the series of temperatures for N physical locations--
you can use the Matrix class's getrow or getcol to copy the values into N+1 vectors (one for time, the other N vectors for the temperature sequences).
Now, how to force temperature to be spatially inhomogeneous AND to fluctuate in the course of a simulation.
NEURON's built-in celsius is a global variable, so it can't be used to represent spatially nonuniform temperature. A workaround is to use an auxiliary distributed mechanism whose sole purpose is to provide a RANGE variable that represents local temperature. This is it:
Code: Select all
NEURON {
SUFFIX aux
RANGE celsiusx
}
ASSIGNED {
celsiusx (degC)
}
"Fine, how do I get my temperature-dependent mechanisms to use this celsiusx_aux(x) instead of the global celsius?"
Rewrite them so that they have a POINTER variable called celsiusx, and use that internally instead of celsius. For example, NEURON's built-in hh.mod contains these references to celsius:
Code: Select all
ASSIGNED {
. . .
: celsius (degC)
celsiusx (degC)
. . .
PROCEDURE rates(v(mV)) {
LOCAL alpha, beta, sum, q10
: don't bother with TABLEs if celsius is going to change during a simulation
: TABLE minf, mtau, hinf, htau, ninf, ntau DEPEND celsius FROM -100 TO 100 WITH 200
UNITSOFF
: q10 = 3^((celsius - 6.3)/10)
q10 = 3^((celsiusx - 6.3)/10)
. . .
Just change them like so:
Code: Select all
ASSIGNED {
. . .
celsius (degC)
. . .
PROCEDURE rates(v(mV)) {
LOCAL alpha, beta, sum, q10
TABLE minf, mtau, hinf, htau, ninf, ntau DEPEND celsius FROM -100 TO 100 WITH 200
UNITSOFF
q10 = 3^((celsius - 6.3)/10)
. . .
Also, be sure to declare celsiusx to be a POINTER in the NEURON block, comment out the THREADSAFE directive because pointers aren't threadsafe, and give your new mechanism a unique SUFFIX so its name won't collide with the original mechanism that used the built-in celsius:
Code: Select all
NEURON {
: SUFFIX hh
SUFFIX hhx
. . .
POINTER celsiusx
: POINTERs aren't threadsafe.
: THREADSAFE : assigned GLOBALs will be per thread
}
If you do everything correctly, your new mod files should pass modlunit testing and compile without error.
Next in your model specification code you need to insert these mechanisms into your sections, and after that you have to couple all the celsiusx POINTER variables in each segment to the celsiusx_aux variable in that same segment. I built a toy model with a couple of sections, plus hhx and na16 (modified versions of NEURON's builtin hh and a user's na16 mechanisms), so I had to do this:
forall for (x,0) setpointer celsiusx_hhx(x), celsiusx_aux(x)
forall for (x,0) setpointer celsiusx_na16(x), celsiusx_aux(x)
Notice that each segment's celsiusx_aux is the source of the celsiusx numerical values needed by the temperature-dependent mechanisms in that segment.
My toy cell was a ball and stick model with a soma and a dend, both having hhx and na16, and I wanted temperature to increase from 6.3 deg C at the soma end to 36.3 deg C at the distal end of dend. Which I did with
soma celsiusx_aux(0.5) = 6.3
dend for (x,0) celsiusx_aux(x) = 6.3 + 30*x
and a space plot of celsiusx_aux showed that temperature did vary with distance as desired.
All that remained was to launch a simulation and observe how the spike waveform changed with distance, because of the variation of temperature with distance along dend.
I'll email the relevant files to you in a zip file.