Time-varying maximal conductance

NMODL and the Channel Builder.
lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Time-varying maximal conductance

Post by lb5999 » Mon Jan 09, 2017 8:34 am

Hi NEURON Forum,

I want to force a model cell I have with the conductance of the K(ATP) channel, gbar_katp. In particular, I want to give gbar_katp a square wave shape in time.

Any idea how I would implement this in NEURON?

I am using insert pas as a proxy for a KATP channel mechanism.

Cheers,
L

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

Re: Time-varying maximal conductance

Post by ted » Mon Jan 09, 2017 1:43 pm

Easiest is to do this with events. Read about FInitializeHandler and cvode.event, then download
https://www.neuron.yale.edu/ftp/ted/neuron/ipulse.zip
and see how events were used to control the current delivered by an IClamp. The same strategy can be used to perturb any parameter in the course of a simulation.

Note the use of cvode.re_init necessitated by the abrupt parameter change.

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Thu Jan 12, 2017 9:21 am

Thanks for your reply ted.

So I've written the following (ammended from ipulse) to give g_pas a jump in its value for DUR = 3e3ms, at START = 3e3ms. I called it g_pas_step.hoc:

Code: Select all

tstop= 10e3

DUR = 3e3  // ms, duration of each pulse
g_pas = 0.5e-3
START = 3e3  // ms, time of first pulse
INTERVAL = 4e3  // ms, interval between pulse starts

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

STIMON = 0

proc initi() {
  STIMON = 0
  // if we're going to change amp,
                  // dur must be long enough to span all our changes
  cvode.event(START, "seti()")
// print "launched event that will turn on pulse at ", START
}

proc seti() {
// print "t = ", t
  if (STIMON==0) {
    STIMON = 1
    soma.g_pas = 0.6e-3
    cvode.event(t + DUR, "seti()")
// print "stim.amp = ", stim.amp, ", launched event to turn pulse off"
  } else {
    STIMON = 0
    stim.amp = 0
    cvode.event(t + 4e3, "seti()")
// print "stim.amp = ", stim.amp, ", launched event to turn next pulse on"
  }
  // we've changed a parameter abruptly
  // so we really should re-initialize cvode
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
}
I then call:

Code: Select all

load_file("nrngui.hoc")
load_file("model.ses")
chdir("H:/models/ipulse")
load_file("g_pas_step.hoc")
Trouble is, it simulates up until DUR = 3e3 then closes unexpectedly... What errors have I introduced to g_pas_step.hoc?

Thanks,
Linford

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Thu Jan 12, 2017 10:13 am

Code: Select all

 stim.amp = 0
There's one!

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Thu Jan 12, 2017 10:21 am

So the below seems to be working better, thanks!

Code: Select all

tstop= 10e3

DUR = 3e3  // ms, duration of each pulse
soma.g_pas = 0.5e-3
START = 3e3  // ms, time of first pulse
INTERVAL = 6e3  // ms, interval between pulse starts

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

STIMON = 0

proc initi() {
  STIMON = 0
  soma.g_pas=0.5e-3
  // if we're going to change amp,
                  // dur must be long enough to span all our changes
  cvode.event(START, "seti()")
// print "launched event that will turn on pulse at ", START
}

proc seti() {
// print "t = ", t
  if (STIMON==0) {
    STIMON = 1
    soma.g_pas = 0.6e-3
    cvode.event(t + DUR, "seti()")
// print "stim.amp = ", stim.amp, ", launched event to turn pulse off"
  } else {
    STIMON = 0
    soma.g_pas = 0.5e-3
    cvode.event(t + INTERVAL, "seti()")
// print "stim.amp = ", stim.amp, ", launched event to turn next pulse on"
  }
  // we've changed a parameter abruptly
  // so we really should re-initialize cvode
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
}

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Thu Jan 12, 2017 11:53 am

Hi Ted,

One question: I had some saved states that I opened, to initiate the equations from:

Code: Select all

objref svstate, f
svstate = new SaveState()
f = new File("states_Human1-1_1.dat")
svstate.fread(f)

proc init() {
  finitialize(v_init)
  svstate.restore()
  t = 0 // t is one of the "states"
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
  frecord_init()
}
When I try to call both my function g_pas_step.hoc (which includes the event code for giving a step change in g_pas) together with the above code for loading some intial states, it does not produce a step change in g_pas.

I have the following code:

Code: Select all

load_file("g_pas_step.hoc") // loads the file similar to ipulse.hoc

objref svstate, f
svstate = new SaveState()
f = new File("states_Human1-1_1.dat")
svstate.fread(f)

proc init() {
  finitialize(v_init)
  svstate.restore()
  t = 0 // t is one of the "states"
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
  frecord_init()
}

tstop=65e3
dt=0.1
steps_per_ms=1/dt
run()
How do I make this work?

Thanks for your help,
linford

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Mon Jan 16, 2017 4:26 am

This is the file I have for playing in a time-varying conductance after loading some saved states, but I am not sure how to get it working. I thought maybe have initi() set to cvode.active() and loading the saved states, and then having seti() refer to the 3 different cvode events would work, but it's not. Do have any thoughts on this ted?

Code: Select all

/*
- This uses NEURON's event delivery system to control g_pas over time
- It comes from a file from ted called ipulse.hoc
- It gives g_pas an initial value of 0.5e-3, and then changes it at t = START ms to 0.6e-3 for t = DUR ms.
*/

chdir("H:/models/")

objref svstate, f
svstate = new SaveState()
f = new File("states_saved.dat")
svstate.fread(f)

proc init() {
  finitialize(v_init)
  svstate.restore()
  t = 0 // t is one of the "states"
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
  frecord_init()
}

DUR = 3e3  // ms, duration of each pulse
soma.g_pas = 0.5e-3
START = 3e3  // ms, time of first pulse
INTERVAL = 6e3  // ms, interval between pulse starts

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

STIMON = 0

proc initi() {
  STIMON = 0
  soma.g_pas=0.5e-3
  // if we're going to change amp,
                  // dur must be long enough to span all our changes
  cvode.event(START, "seti()")
// print "launched event that will turn on pulse at ", START
}

proc seti() {
// print "t = ", t
  if (STIMON==0) {
    STIMON = 1
    soma.g_pas = 0.6e-3
    cvode.event(t + DUR, "seti()")
// print "stim.amp = ", stim.amp, ", launched event to turn pulse off"
  } else {
    STIMON = 0
    soma.g_pas = 0.5e-3
    cvode.event(t + INTERVAL, "seti()")
// print "stim.amp = ", stim.amp, ", launched event to turn next pulse on"
  }
  // we've changed a parameter abruptly
  // so we really should re-initialize cvode
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
}


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

Re: Time-varying maximal conductance

Post by ted » Tue Jan 17, 2017 1:45 pm

Restoring saved states seems to be interfering with execution of the procedure specified by the FInitializeHandler. A workaround that succeeds for me today with VERSION 7.5 (1439:892e9d15bd2a) 2016-06-01 is to comment out the code that defines the FInitializeHandler, and instead append the proc that it calls to the end of the custom init procedure. In the context of your particular program, that means changing

Code: Select all

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

Code: Select all

// objref fih
// fih = new FInitializeHandler("initi()")
and changing

Code: Select all

  frecord_init()
}
to

Code: Select all

  frecord_init()
  initi()
}
I would prefer to keep the program more modular, by completely separating the statements that do savestate restore from those that launch the state machine that governs conductance. But maybe I can convince myself that it's already quite modular enough, because,
except for one nexus,
the code that deals with saved states is separate from the code that implements the state machine. That nexus is a few lines of code in proc init, the very procedure which, before the advent of events, was the preferred place for inserting custom initialization code. And those few lines of code really do belong in proc init because they pertain directly to initialization of saved states and initialization of the state machine.

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Wed Jan 25, 2017 7:31 am

Great, thanks Ted!

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Wed Jan 25, 2017 7:42 am

Hi Ted,

This is great because now I can give step changes to my conductance parameters. What if I want to change a parameter (in my case, the maximal conductance of a channel) continuously at each timestep?

In particular I want to model an inwardly rectifying potassium (IRK) channel. The maximal conductance of this channel I want to equate to a T_rel (transmitter that is released by another component of my model) at each timestep. Why am I doing this? The transmitter activates the IRK channels - normally via receptor activation and a G-protein cascade, but I am not interested in this pathway (at least at the moment).

Thanks!

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

Re: Time-varying maximal conductance

Post by ted » Wed Jan 25, 2017 10:11 am

Vector class's play method.

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Wed Jan 25, 2017 12:42 pm

Hi Ted,

OK that's great. I'm having trouble implementing this... If I have a variable that is being generated from a run (soma.T_rel) and I want to force another variable in the simulation (gbar_irk) with this value, at each time step, do I simply write:

Code: Select all

objectvar vsrc
vsrc = new Vector()
vsrc = soma.T_rel
dt=0.1
vsrc.play(&soma.gbar_irk,dt)
And that will update at each timestep?

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

Re: Time-varying maximal conductance

Post by ted » Wed Jan 25, 2017 11:09 pm

Sorry, I had the notion that you knew the time course of the fluctuating conductance in advance, and merely wanted to use that as a forcing function. Instead, you want the conductance to depend on some variable whose value is calculated during the simulation, right?

lb5999
Posts: 56
Joined: Mon Oct 11, 2010 9:12 am

Re: Time-varying maximal conductance

Post by lb5999 » Thu Jan 26, 2017 4:20 am

Hi Ted,

Yes that is right.

Thanks.

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

Re: Time-varying maximal conductance

Post by ted » Thu Jan 26, 2017 6:22 pm

What you want to do can be accomplished with one or more pointer variables and some NMODL code. At this point it's probably best to take the discussion to plain old email, and I'm going to ask you to tell me (by email) whether you want your conductance to be an instantaneous (algebraic) function of some existing hoc variable, or instead want it to be the solution to an ODE?

Post Reply