programatically changing the temperature

NMODL and the Channel Builder.
Post Reply
porio

programatically changing the temperature

Post by porio »

Hi,

I'm trying to make a mechanism to introduce a 'temperature clamp' in my cell model. As a first approach, I wrote a NMODL code similar to the Example 3 of the Hines and Carnevale NMODL manual.

Code: Select all

TITLE Mechanism for a temperature clamp generating square T pulse.

NEURON {
	SUFFIX TClamp
	RANGE del, dur, temp1, temp2
}

PARAMETER {
	del = 100 (ms)
	dur = 300 (ms)
	temp1 = 35 (degC)
	temp2 = 20 (degC)
}

ASSIGNED {
	celsius (degC)
}

BREAKPOINT {
	at_time (del)
	at_time (del+dur)
	
	if (t < del +dur && t > del) {celsius = temp2} else {celsius = temp1}
}
However, I get the following message from mknrndll :

celsius is a special NEURON variable that should not be assigned a value in a model description file

Can I change the temperature of the system as a function of simulation time?

Thank you in advance.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: programatically changing the temperature

Post by ted »

That was a clever approach, and I can see how there's no way that one could
tell in advance that it wouldn't work.

It's actually much easier to change any parameter in the course of a simulation.
This code will drive celsius in a linear ramp from 6.3 to 20 deg C over the course
of 100 ms (pretty fast heating!).

Code: Select all

objref tempvec, tvec
tempvec = new Vector(3)
tvec = new Vector(3)
tempvec.x[0] = 6.3  // deg C
tvec.x[0] = 0
tempvec.x[1] = 20   // deg C
tvec.x[1] = 100
tempvec.x[2] = 20   // deg C
tvec.x[2] = 1e9

// third argument == 1 means play with interpolation
tempvec.play(&celsius, tvec, 1)
Comments:
1. A mechanism defined by NMODL code that has temperature-dependent
rate constants must be written in a way that allows celsius to affect the rates;
otherwise, changing celsius will have no effect on the simulation.
2. NMODL code that uses precalculated rate tables will have a TABLE
statement that includes
DEPEND celsius
if the rates are temperature dependent (see hh.mod for a good example).
At every fadvance(), if celsius has changed, the rate tables will be
recomputed. This will slow down the simulation noticeably when celsius
is driven by a "continuous" function, as in this example--until you get to
the top of the ramp, where celsius becomes constant, and the simulation
accelerates.
3. celsius, or any other parameter, can be made to jump abruptly from
one temperature to another by using FInitializeHandler and cvode.event(),
but that's a different story . . .
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

event-driven parameter changes

Post by ted »

3. celsius, or any other parameter, can be made to jump abruptly from
one temperature to another by using FInitializeHandler and cvode.event(),
but that's a different story . . .
I know somebody's going to ask sooner or later, so here's an example that uses
the event delivery system to generate a sequence of current pulses. Notice how
being able to use events from hoc spares us from having to fiddle around writing
new NMODL code.

Code: Select all

/*
This uses NEURON's event delivery system to control the current supplied
by an IClamp.  A similar strategy can be used to drive discontinuous 
changes in any other parameter.
1.  During simulation initialization, the stimulus current is set to 0, 
and an FInitializeHandler is used to launch an event that will arrive 
at the time when we want the first jump of stim.amp to occur.
2.  Arrival of this event causes proc seti() to be called.
3.  seti() assigns a new value to stim.amp, and uses the CVode class's 
event() method to launch two new events.  The first of these will come 
back in the future to turn off the stimulus.  The second will come back 
a bit later, to turn it back on again, and start a new cycle.
*/

objref stim
stim = new IClamp(0.5)

DUR = 0.1  // ms, duration of each pulse
AMP = 0.1  // nA
START = 5  // ms, time of first pulse
INTERVAL = 25  // ms, interval between pulse starts
// assumes DUR < INTERVAL

objref fih
fih = new FInitializeHandler("initi()")

STIMON = 0

proc initi() {
  STIMON = 0
  stim.del = 0    // we want to exert control over amp starting at 0 ms
  stim.dur = 1e9  // if we're going to change amp, 
                  // dur must be long enough to span all our changes
  cvode.event(START, "seti()")
}

proc seti() {
//  print "time is ", t
  if (STIMON==0) {
    STIMON = 1
    stim.amp = AMP
    cvode.event(t + DUR, "seti()")
    cvode.event(t + INTERVAL, "seti()")
  } else {
    STIMON = 0
    stim.amp = 0
  }
  // we've changed a parameter abruptly
  // so we really should re-initialize cvode
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
}
porio

Post by porio »

Thanks!!!!!!
Feanor
Posts: 26
Joined: Fri Nov 28, 2014 3:03 pm

Re: programatically changing the temperature

Post by Feanor »

Hello to all,

i would like to change the weight of a NetCon (i.e. many NetCon objects) at a point during the simulation. Would sending an event via

Code: Select all

cvode.event()
be the way to do it?

I have tried it, without success, and am wondering if I am not doing it properly or if it is not the way to go.

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

Re: programatically changing the temperature

Post by ted »

Feanor wrote:i would like to change the weight of a NetCon (i.e. many NetCon objects) at a point during the simulation.
Use an FInitializeHandler to make cvode.event launch an event that triggers a proc to change the weight(s) at the desired time. The resulting code will be simpler than the current pulse example because there's no need for conditional statements.
I have tried it, without success, and am wondering if I am not doing it properly
The answer is yes, but that's about as helpful as the "idiot lights" on the dashboard of a car. To provide more specific advice, I'd have to see your code.
Feanor
Posts: 26
Joined: Fri Nov 28, 2014 3:03 pm

Re: programatically changing the temperature

Post by Feanor »

Hello ted,

it was/is helpful, because knowing that I continued searching where the error is. Thank you.

I have another question on the same topic: is the part

Code: Select all

if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
necessary for this example (changing the weights of NetCons)? The results look the same with and without it.

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

Re: programatically changing the temperature

Post by ted »

Feanor wrote:I have another question on the same topic: is the part

Code: Select all

if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
necessary for this example (changing the weights of NetCons)?
Probably not unless you do something unorthodox with NetCon weight. However, I haven't seen your code so I don't know that, do i? These statements don't impose significant overhead, so there's not much to gain by deleting them. And if you do delete them, rest assured that in the future someone else will want to change some other parameter, and will follow your current example, but in circumstances that really do require this bit of code to be executed (e.g. a parameter whose value affects a kinetic scheme or an ODE or some calculation that is done in a BREAKPOINT block).
Feanor
Posts: 26
Joined: Fri Nov 28, 2014 3:03 pm

Re: programatically changing the temperature

Post by Feanor »

I see. Very well, thank you!
Post Reply