Calcium current in a POINT_PROCESS and units

NMODL and the Channel Builder.
Post Reply
stil
Posts: 28
Joined: Thu Jul 01, 2010 8:47 am
Location: Mulhouse - France

Calcium current in a POINT_PROCESS and units

Post by stil »

Hello all,

I might have misunderstood something again, related to the computation of Calcium current using USEION declaration in a POINT_PROCESS NMODL.

What i want to do is to WRITE ica, in a POINT_PROCESS AMPA5, using a fractional conductance.
In the following NMODL, i think i have declared correctly the USEION statement.
I have also declared parameters L, and d for Length and diameter (resp) of the section, since it seemed to me that L and diam were not visible from the mod mechanism (?)
finally, i have assigned the ica variable within an equation in the BREAKPOINT block. I tried a conversion from [nA], in which my NONSPECIFIC_CURRENT i is expressed, to [mA/cm2], in which it seemed that my ica would be expressed.

I voluntarily changed my fractional conductance to 0.5, for easier visualization. Finally, i obtain a ca current that is often greater than my overall current, instead of 'half-the value' i expected.

Would you mind telling me what is the best way to achieve this, please ?

Code: Select all

INDEPENDENT {t FROM 0 TO 1 WITH 1 (ms)}

NEURON {
	POINT_PROCESS AMPA5
	POINTER C
	USEION ca WRITE ica
	RANGE L, d
	RANGE gca
	RANGE C0, C1, C2, D1, D2, O
	RANGE g, gmax, rb
	GLOBAL Erev
	GLOBAL Rb, Ru1, Ru2, Rd, Rr, Ro, Rc
	GLOBAL vmin, vmax
	NONSPECIFIC_CURRENT i
}

UNITS {
	(nA) = (nanoamp)
	(mV) = (millivolt)
	(pS) = (picosiemens)
	(umho) = (micromho)
	(mM) = (milli/liter)
	(uM) = (micro/liter)
}

PARAMETER {

	Erev	= 0    (mV)	: reversal potential
	gmax	= 500  (pS)	: maximal conductance
	vmin = -120	(mV)
	vmax = 100	(mV)
	gca = 0.5 (1) : a fractional conductance
: Rates

	Rb	= 13   (/mM /ms): binding 
				: diffusion limited (DO NOT ADJUST)
	Ru1	= 0.0059  (/ms)	: unbinding (1st site)
	Ru2	= 86  (/ms)	: unbinding (2nd site)		
	Rd	= 0.9   (/ms)	: desensitization
	Rr	= 0.064 (/ms)	: resensitization 
	Ro	= 2.7    (/ms)	: opening
	Rc	= 0.2    (/ms)	: closing
	d (um)
	L (um)
}

ASSIGNED {
	v		(mV)		: postsynaptic voltage
	i 		(nA)		: current = g*(v - Erev)
	g 		(pS)		: conductance
	C 		(mM)		: pointer to glutamate concentration
	cai
	cao
	ica
	rb		(/ms)    : binding
}

STATE {
	: Channel states (all fractions)
	C0		: unbound
	C1		: single glu bound
	C2		: double glu bound
 	D1		: single glu bound, desensitized
 	D2		: double glu bound, desensitized
	O		: open state 2
}

INITIAL {
	C0=1
	C1=0
	C2=0
	D1=0
	D2=0
	O=0
}

BREAKPOINT {
	SOLVE kstates METHOD sparse

	g = gmax * O
	i = (1e-6) * g * (v - Erev)
	ica = gca * i : * 1e4 / (3.14 * diam *L)
}

KINETIC kstates {
	
	rb = Rb * C 

	~ C0  <-> C1	(rb,Ru1)
	~ C1 <-> C2	(rb,Ru2)
	~ C1 <-> D1	(Rd,Rr)
	~ C2 <-> D2	(Rd,Rr)
	~ C2 <-> O	(Ro,Rc)

	CONSERVE C0+C1+C2+D1+D2+O = 1
}
my hoc code :

Code: Select all

load_file("nrngui.hoc")

// Simulation Algorithm
objref cvode
cvode = new CVode(0)
cvode_active(1)
cvode.atol(1e-8)
cvode.rtol(1e-6)
cvode.condition_order(2)

// PRE PART
create PRE
// insert current injection
objref stim
PRE stim = new IClampTetanus(0.5)
stim.delay = 5
stim.thigh =1
stim.tlow = 10
stim.npulses = 1
stim.ntrains = 1
stim.trainperiod = 50
stim.ilow = 0.0
stim.ihigh = 1

//POST PART
create POST
POST{
	L = 1 //um
	diam = 1 //um
	nseg = 5
	Ra = 200 // cytoplasmic resistivity ohm.cm
	Cm = 1 // specific membrane capacitance uF.cm-2
	insert pas
	g_pas = 0.2//1/Rm
	e_pas = -80
}

objref clamp
POST clamp = new VClampTetanus(0.5)
clamp.delay = 50000
clamp.vlow = -65
clamp.vhigh = 10
clamp.rs = 1e-6

objref ampa
POST ampa = new AMPA5(0.5)
ampa.L = POST.L
ampa.d = POST.diam

setpointer ampa.C, stim.i      // assign presynaptic compartment
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Calcium current in a POINT_PROCESS and units

Post by ted »

First, let me apologize for the delay in getting back to you. You were on what might be the right track, but there are many details that must be dealt with in setting up a mechanism with nmodl. Also, the "best" way to do something depends on the user's actual goal, which is not always apparent. For example, the question of whether you really need a synaptic mechanism that uses a POINTER to connect the pre- and postsynaptic cells, or whether you would be better off with something that accomplishes this coupling with events is yet to be answered.

Not knowing the answer, I had to assume something about the time course of glutamate concentration on the synaptic cleft in order to create and test a working mechanism, so I assumed that
(1) glutamate is either absent, or present at some constant concentration, e.g. 1 mM to start (eventually I ran tests with peak conc 0.1 mM, because 1 mM produced a large depolarization in my model cell)
(2) the transition between these conditions is rapid
(3) the duration of nonzero [glu] is 1 ms

What follows is the resulting mechanism, the core of a program that tests this mechanism, and some comments about the implementation.

Code: Select all

NEURON {
	POINT_PROCESS AMPA5
	POINTER C
	USEION ca WRITE ica
	GLOBAL Rb, Ru1, Ru2, Rd, Rr, Ro, Rc
	RANGE g
	GLOBAL Erev
	RANGE gmax, gca
	NONSPECIFIC_CURRENT i
	RANGE ica
}

UNITS {
	(nA) = (nanoamp)
	(mV) = (millivolt)
	(pS) = (picosiemens)
	(umho) = (micromho)
	(mM) = (milli/liter)
	(uM) = (micro/liter)
	(um) = (micron)
}

PARAMETER {
	Erev	= 0    (mV)	: reversal potential
	gmax	= 500  (pS)	: maximal conductance
	gca = 0.5 (1) : a fractional conductance

	Rb	= 13   (/mM /ms): binding 
				: diffusion limited (DO NOT ADJUST)
	Ru1	= 0.0059  (/ms)	: unbinding (1st site)
	Ru2	= 86  (/ms)	: unbinding (2nd site)		
	Rd	= 0.9   (/ms)	: desensitization
	Rr	= 0.064 (/ms)	: resensitization 
	Ro	= 2.7    (/ms)	: opening
	Rc	= 0.2    (/ms)	: closing
}

ASSIGNED {
	v		(mV)		: postsynaptic voltage
	i 		(nA)		: current = g*(v - Erev)
	g 		(pS)		: conductance
	C 		(mM)		: pointer to glutamate concentration
	ica  (nA) : so you can plot the calcium current generated by this mechanism
}

STATE {
	: Channel states (all fractions)
	C0		: unbound
	C1		: single glu bound
	C2		: double glu bound
 	D1		: single glu bound, desensitized
 	D2		: double glu bound, desensitized
	O		: open state 2
}

INITIAL {
	C0=1
	C1=0
	C2=0
	D1=0
	D2=0
	O=0
	SOLVE kstates STEADYSTATE sparse
}

BREAKPOINT {
	SOLVE kstates METHOD sparse

	g = gmax * O
	i = (1e-6) * g * (v - Erev)
	: are you sure you don't want ica = gca*g*(v - eca) ?
	: in which case you'll want to READ eca
	ica = gca * i
}

KINETIC kstates {
	COMPARTMENT 1 (m3) {C} : big so xmtr conc will not be affected by binding to receptor

	~ C0 + C <-> C1	(Rb,Ru1)
	~ C1 + C <-> C2	(Rb,Ru2)
	~ C1 <-> D1	(Rd,Rr)
	~ C2 <-> D2	(Rd,Rr)
	~ C2 <-> O	(Ro,Rc)

	CONSERVE C0+C1+C2+D1+D2+O = 1
}
Comments:
The INDEPENDENT statement was omitted; INDEPENDENT statements are irrelevant to NEURON.

NEURON block
Unused stuff has been eliminated from the NEURON block and other blocks. Examples:
L and d. Synaptic mechanisms are implemented as point processes, and point processes generate currents in absolute units, not density units. I have never found it necessary to use L in any mod file. diam may be useful for mod files that specify accumulation mechanisms, but are rarely useful in point processes.
Declaration of the STATEs as being RANGE variables. STATEs are automatically RANGE variables and do not have to be declared as such.
vmin and vmax were unused.
rb is not useful and has been eliminated (see discussion of KINETIC block).
ica is declared RANGE so you can plot the calcium current that is generated by an instance of AMPA5. Otherwise, this variable would have been inaccessible to hoc.

INITIAL block
The assignment statements are fine if [glu] is initially supposed to be 0.
SOLVE kstates STEADYSTATE sparse
was inserted so that the mechanism can properly initialize itself even if initial [glu] is nonzero.

BREAKPOINT block
Are you sure you want to calculate ica as gca * i, rather than
ica = gca*g*(v - eca) ?
The latter would require you to change the USEION ca statement to
USEION ca READ eca WRITE ica
and also to do something that specifies the value of eca--e.g., if there is no mechanism that WRITEs cai, you could simply use a hoc statement such as
eca = 60 // or whatever you like

KINETIC block
The original formulation was
rb = Rb * C
~ C0 <-> C1 (rb,Ru1)
~ C1 <-> C2 (rb,Ru2)
but this might cause problems if you ever decide to allow receptor + C to consume C.
I rewrote these as
~ C0 + C <-> C1 (Rb,Ru1)
~ C1 + C <-> C2 (Rb,Ru2)
but that required a COMPARTMENT statement for consistency of units
COMPARTMENT 1 (m3) { C }
This particular statement makes C effectively constant (its volume of distribution is huge, so there's a lot more C than there is receptor).

modlunit passes this revised mechanism without complaint.

Here's the hoc file that I used to exercise this mechanism:

Code: Select all

load_file("nrngui.hoc")

START = 1 // time at which [glu] changes from 0 to CONC
DUR = 1 // duration of nonzero CONC
CONC = 0.1 // mM

create soma
access soma
soma {
  L = 10
  diam = 100/L/PI
  insert pas
  g_pas = 1/1e4
}

v_init = -70

objref syn
syn = new AMPA5(0.5)

glu = 0 // dummy variable--will be synaptic cleft [glu] in mM

setpointer syn.C, glu

// user interface

load_file("rig.ses") // a RunControl panel, plot of soma.v(0.5) vs.t,
  // and graphs of AMPA5's g, i, ica, and O

// simulation flow control AKA "protocol"

objref fih
fih = new FInitializeHandler("initglu()") // [glu] = 0 at start

GLUON = 0

proc initglu() {
  GLUON = 0  
  glu = 0
  cvode.event(START, "setglu()")
}

proc setglu() {
//  print "time is ", t
  if (GLUON==0) {
    GLUON = 1
    glu = CONC
    cvode.event(t + DUR, "setglu()")
  } else {
    GLUON = 0
    glu = 0
  }
  // we have changed a parameter abruptly
  // so we really should re-initialize cvode
  if (cvode.active()) {
    cvode.re_init()
  } else {
    fcurrent()
  }
}
It sets up a single compartment model with 100 um2 surface area, g_pas = 0.0001 S/cm2 (tau_m = 10 ms). This model uses a dummy variable called glu, whose value is controlled by a state machine implemented with NEURON's event delivery system. The FInitializeHandler ensures that glu = 0 at the start of each simulation, and also launches an event that causes execution of setglu() when t = START. This first execution of setglu() increases glu to a nonzero value and launches another event that causes a second execution of setglu(). The second execution of setglu() cuts glu back to 0. With a little revision, you could easily make this state machine generate a series of pulses of glu--as many as you like.

I'll email you the whole thing in a zip file so you can try it for yourself. Unzip it, run nrnivmodl (or mknrndll), then execute
nrngui init.hoc
or double click on init.hoc, and finally click on the Init & Run button.

At this point, my question is: are you going to have something that generates a detailed time course of glu, i.e. not just a rectangular pulse? Or is something like a rectangular pulse (or the response of a set of ODEs or reactions to an impulse, e.g. presynaptic spike) adequate? (in which case something implemented with a NET_RECEIVE block, rather than a POINTER, may be more suitable)
Post Reply