Changing custom channel parameters through Python

When Python is the interpreter, what is a good
design for the interface to the basic NEURON
concepts.

Moderator: hines

Post Reply
BBAmp
Posts: 12
Joined: Fri Mar 26, 2010 2:36 pm

Changing custom channel parameters through Python

Post by BBAmp » Mon Aug 16, 2010 3:20 pm

Hello,

I understand the syntax for assigning values to an "internal" object like a soma is something like:

Code: Select all

for seg in soma:
  seg.hh.gnabar = 0.11
to change the gnabar of hh.

I am currently trying to do something similar for a parameter defined in an ses file.

I have a soma defined through Python (soma = Section()) and I loaded the custom channel created in channel builder using the h.load_file() command. I then inserted the custom channel with the code:

Code: Select all

h('insert X')
where X stands for the custom channel I wish to insert. I can't so soma.insert('X') so this was the best workaround I could find.

Then I have a problem with trying to change variables using the seg.hh.gnabar syntax. Lets assume that e is some parameter of X. I've tried:

Code: Select all

h('e_X = 1')   (successful but returns error later.. see below)
h(insert X {e = 1}')   (syntax error at '{' )
h('insert X e_X = 1')   (syntax error at e)
sec.X.e = 1   (... 'nrn.Section' object has no attribute 'X')
sec.e_X = 1   (ditto)


These all return syntax errors except for the very first. The first seems successful but when I try to connect a net stim object to the soma I get the error "point process not located in a section". I believe this is because the parameter was not changed after all and a syntax error prevented the cell from being created which in turn lead to a synapse connecting to a null object.

so my question is... what is the proper syntax for changing default channel builder parameters? I got around this before by editing the .ses file(s) to the parameters I wanted but I would like to know if there is a way to do this through Python.

Thank you,
-Youngmin Park
Last edited by BBAmp on Wed Aug 18, 2010 1:06 pm, edited 1 time in total.

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

Re: Re-defining/Changin custom channel parameters through Python

Post by ted » Tue Aug 17, 2010 1:43 pm

BBAmp wrote:I can't so soma.insert('X') so this was the best workaround I could find.
That's strange--soma.insert('X') works for me. Let's resolve this issue first, in case it is caused by a bug that may interfere with subsequent discussion. What version of NEURON are you running, and under what OS?

The answer to your motivating question--how to access the value of the density parameter for a distributed ("density") mechanism specified by a Channel Builder--is straightforward: the same way you would access the value of the density parameter of a distributed mechanism specified by NMODL.

For example, the hh mechanism (which is specified by NMODL code) has a sodium channel density parameter called gnabar_hh in hoc that is accessed by statements like

Code: Select all

soma for (x) print gnabar_hh(x)
but in Python one would write

Code: Select all

for seg in soma:
  print seg.hh.gnabar
Now suppose there is a sodium channel called myna with gating properties that are specified by a Channel Builder, and that its density parameter is called gbar_myna in hoc. This parameter would be accessed by statements like

Code: Select all

soma for (x) print gbar_myna(x)
but in Python one would write

Code: Select all

for seg in soma:
  print seg.myna.gbar

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

Re: Re-defining/Changin custom channel parameters through Python

Post by ted » Tue Aug 17, 2010 7:52 pm

If you enable the "transition aliases" feature
(ChannelBuild / Properties / Provide transition aliases)
the parameters used by the formulas that describe the voltage- or concentration-dependence of the gating variables become available to hoc. For example, suppose that ChannelBuild[0] has states C1 and C2, where the transition
C1<-> C2
has forward rate aC1C2 = A/(1 + exp(-k*(d-v))). Then A, d, and v will be known to hoc as
ChannelBuild[0].aliases.aC1C2.A, ChannelBuild[0].aliases.aC1C2.d, and ChannelBuild[0].aliases.aC1C2.v, respectively.

And just today, Michael Hines made the necessary changes to NEURON's source code so that these parameters will be available in Python as h.ChannelBuild[0].aliases.infC1C2.A etc.. See
http://www.neuron.yale.edu/hg/neuron/nr ... cbbf5090c7
This feature will be included in the next alpha installer for NEURON, and also in the next standard distribution (probably later this year). If you need it before then, you will have to download the latest development sources and compile as described here
http://www.neuron.yale.edu/neuron/download/getdevel

BBAmp
Posts: 12
Joined: Fri Mar 26, 2010 2:36 pm

Re: Changing custom channel parameters through Python

Post by BBAmp » Wed Aug 18, 2010 1:07 pm

Great, that will prove to be very useful.

Thanks for the help!

-Youngmin

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

Re: Changing custom channel parameters through Python

Post by ted » Wed Aug 18, 2010 1:24 pm

Thanks for asking questions that led to a further improvement of NEURON.

lempkas
Posts: 4
Joined: Wed Oct 05, 2011 12:14 pm

Re: Changing custom channel parameters through Python

Post by lempkas » Mon Oct 10, 2011 1:12 pm

I have been working on converting a single cell model with detailed anatomy and biophysics from Hoc to Python. I am currently having problems with custom ion channel mechanisms. I am able to insert the mechanisms, but I am having problems defining some of the specific parameters.

sec.insert(‘channel’)
sec.property = specific_value

I get the error the following error:

AttributeError: ‘nrn.Section’ object has no attribute ‘property’

For example, in the ‘AXNODE75’ channels Mod file below, I can define conductance properties (e.g. gnabar calling sec.gnabar_axnode75) and reversal potentials (e.g. ena calling sec.ena_axnode75). However, I am unable to define the parameters ‘vshift’ calling sec.vshift_axnode75 or ‘vtraub’ calling sec.vtraub_axnode75.

Code: Select all

TITLE Motor Axon Node channels
:
: Fast Na+, Persistant Na+, Slow K+, and Leakage currents 
: responsible for nodal action potential
: Iterative equations H-H notation rest = -75 mV
:


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

NEURON {
	SUFFIX axnode75
	NONSPECIFIC_CURRENT ina
	NONSPECIFIC_CURRENT inap
	NONSPECIFIC_CURRENT ik
	NONSPECIFIC_CURRENT il
	RANGE gnapbar, gnabar, gkbar, gl, ena, ek, el
	RANGE mp_inf, m_inf, h_inf, s_inf
	RANGE tau_mp, tau_m, tau_h, tau_s
}


UNITS {
	(mA) = (milliamp)
	(mV) = (millivolt)
}

PARAMETER {

	gnapbar = 0.01	(mho/cm2)
	gnabar	= 3.0	(mho/cm2)
	gkbar   = 0.08 	(mho/cm2)
	gl	= 0.007 (mho/cm2)
	ena     = 55.0  (mV)
	ek      = -85.0 (mV)
	el	= -85.0 (mV)
	celsius		(degC)
	dt              (ms)
	v               (mV)
	vshift=5
	vtraub=-80
	ampA = 0.01
	ampB = 27
	ampC = 10.2
	bmpA = 0.00025
	bmpB = 34
	bmpC = 10
	amA = 1.86
	amB = 21.4
	amC = 10.3
	bmA = 0.086
	bmB = 25.7
	bmC = 9.16
	ahA = 0.062
	ahB = 114.0
	ahC = 11.0
	bhA = 2.3
	bhB = 31.8
	bhC = 13.4
	asA = 0.3
	asB = -27
	asC = -5
	bsA = 0.03
	bsB = 10
	bsC = -1
}

STATE {
	mp m h s
}

ASSIGNED {
	inap    (mA/cm2)
	ina	(mA/cm2)
	ik      (mA/cm2)
	il      (mA/cm2)
	mp_inf
	m_inf
	h_inf
	s_inf
	tau_mp
	tau_m
	tau_h
	tau_s
	q10_1
	q10_2
	q10_3
}

BREAKPOINT {
	SOLVE states METHOD cnexp
	inap = gnapbar * mp*mp*mp * (v - ena)
	ina = gnabar * m*m*m*h * (v - ena)
	ik   = gkbar * s * (v - ek)
	il   = gl * (v - el)
}

DERIVATIVE states {   : exact Hodgkin-Huxley equations
       evaluate_fct(v)
	mp'= (mp_inf - mp) / tau_mp
	m' = (m_inf - m) / tau_m
	h' = (h_inf - h) / tau_h
	s' = (s_inf - s) / tau_s
}

UNITSOFF

INITIAL {
:
:	Q10 adjustment
:

	q10_1 = 2.2 ^ ((celsius-20)/ 10 )
	q10_2 = 2.9 ^ ((celsius-20)/ 10 )
	q10_3 = 3.0 ^ ((celsius-36)/ 10 )

	evaluate_fct(v)
	mp = mp_inf
	m = m_inf
	h = h_inf
	s = s_inf
}

PROCEDURE evaluate_fct(v(mV)) { LOCAL a,b,v2

	v2 = v - vshift

	a = q10_1*vtrap1(v2)
	b = q10_1*vtrap2(v2)
	tau_mp = 1 / (a + b)
	mp_inf = a / (a + b)

	a = q10_1*vtrap6(v2)
	b = q10_1*vtrap7(v2)
	tau_m = 1 / (a + b)
	m_inf = a / (a + b)

	a = q10_2*vtrap8(v2)
	b = q10_2*bhA / (1 + Exp(-(v2+bhB)/bhC))
	tau_h = 1 / (a + b)
	h_inf = a / (a + b)

	a = q10_3*asA / (Exp((v2-vtraub+asB)/asC) + 1) 
	b = q10_3*bsA / (Exp((v2-vtraub+bsB)/bsC) + 1)
	tau_s = 1 / (a + b)
	s_inf = a / (a + b)
}

FUNCTION vtrap(x) {
	if (x < -50) {
		vtrap = 0
	}else{
		vtrap = bsA / (Exp((x+bsB)/bsC) + 1)
	}
}

FUNCTION vtrap1(x) {
	if (fabs((x+ampB)/ampC) < 1e-6) {
		vtrap1 = ampA*ampC
	}else{
		vtrap1 = (ampA*(x+ampB)) / (1 - Exp(-(x+ampB)/ampC))
	}
}

FUNCTION vtrap2(x) {
	if (fabs((x+bmpB)/bmpC) < 1e-6) {
		vtrap2 = -bmpA*bmpC
	}else{
		vtrap2 = (bmpA*(-(x+bmpB))) / (1 - Exp((x+bmpB)/bmpC))
	}
}

FUNCTION vtrap6(x) {
	if (fabs((x+amB)/amC) < 1e-6) {
		vtrap6 = amA*amC
	}else{
		vtrap6 = (amA*(x+amB)) / (1 - Exp(-(x+amB)/amC))
	}
}

FUNCTION vtrap7(x) {
	if (fabs((x+bmB)/bmC) < 1e-6) {
		vtrap7 = -bmA*bmC
	}else{
		vtrap7 = (bmA*(-(x+bmB))) / (1 - Exp((x+bmB)/bmC))
	}
}

FUNCTION vtrap8(x) {
	if (fabs((x+ahB)/ahC) < 1e-6) {
		vtrap8 = -ahA*ahC
	}else{
		vtrap8 = (ahA*(-(x+ahB))) / (1 - Exp((x+ahB)/ahC)) 
	}
}

FUNCTION Exp(x) {
	if (x < -100) {
		Exp = 0
	}else{
		Exp = exp(x)
	}
}

UNITSON
Another example, in the ‘Cacum’ channel Mod file below, I am unable to define the concentration parameter, cai0, calling sec.cai0_Cacum.

Code: Select all

TITLE calcium accumulation for STh

COMMENT 

 Calcium accumulation into a volume of area*depth next to the
 membrane with an exponential decay (time constant tau) to resting
 level (given by the global calcium variable cai0_ca_ion).

 How the q10 works:
There is a q10 for the rates (alpha and beta's) called Q10.  The q10s
should have been measured at specific temperatures temp1 and temp2
(that are 10degC apart). Ideally, as Q10 is temperature dependant, we
should know these two temperatures.  We are going to follow the
more formal Arrhenius derived Q10 approach.   The temperature at
which this channel's kinetics were recorded is tempb (base
temperature).  What we then need to calculate is the desired rate
scale for now working at temperature celsius (rate_k).  This is given
by the empirical Arrhenius equation, using the Q10.  

ENDCOMMENT

NEURON {
	SUFFIX Cacum
	USEION ca READ ica WRITE cai
	GLOBAL con,cai0,buftau,activate_Q10,Q10,rate_k,temp1,temp2,tempb,depth
}

UNITS {
	(mM) = (milli/liter)
	(mA) = (milliamp)
	F = (faraday) (coulombs)	: Faradays constant 
}

PARAMETER {
        v (mV)
	dt (ms)
	con   = 0.0			: conversion constant (see INITIAL block)
        Avo   = 6.02e23			: Avogadro's number
	elc   = 1.602e-19 (coulombs)	: elementrary charge
	depth = 200.0 (nm)		: assume volume = area*depth
	cai0  = 0.0001(mM)		: replace cai0_ca_ion 
	buftau = 1.857456645e+02 (ms)
	cai0_ca_ion
	celsius

	activate_Q10 = 1
	Q10 = 1.2
	temp1 = 19.0 (degC)
	temp2 = 29.0 (degC)
	tempb = 23.0 (degC)
}

ASSIGNED {
	ica (mA/cm2)
        tau (ms)
	rate_k
}

STATE {
	cai (mM)
}

BREAKPOINT {
	SOLVE integrate METHOD cnexp
}

UNITSOFF

INITIAL {
	LOCAL ktemp,ktempb,ktemp1,ktemp2
	if (activate_Q10>0) {
	  ktemp  = celsius+273.0
	  ktempb = tempb+273.0
	  ktemp1 = temp1+273.0
	  ktemp2 = temp2+273.0
	  rate_k = exp( log(Q10)*((1/ktempb)-(1/ktemp))/((1/ktemp1)-(1/ktemp2)) )
	}else{
	  rate_k = 1.0
	}

	con=1e7/(depth*2.0*Avo*elc)	  : UNITS (derivation)
 			: ica             = (mA/cm2)
			:                 = (A/1e3cm2) 
			:                 = ((C/s)/1e3cm2)
			: depth           = (nm) = (1e-7cm)
			: ica/depth       = ((C/s)/1e3cm2) * 1/(1e-7cm)
			:                 = ((C/s)/1e3cm2) * 1e7/(cm)
			:                 = (1e7(C/s) * 1/(1e3cm3))
			:                 = (1e7(C/s) * 1/(litres))
			: 1e7*ica/depth   = ((C/s) * 1/(litres))
			:                 = ((C/litres) * 1/(s))
			:                 = ((C/litres) * 1/(1e3msec))
			:                 = ((C/litres) * 1e-3/(msec))
			: 1e4*ica/depth   = ((C/litres) * 1/(msec))
			: 1/(2*Avo*elc)   = (mol/C)
			:                 = (1e3mmol/C)
			: 1e3/(2*Avo*elc) = (mmol/C)
			: 1e4*ica/depth * 1e3/(2*Avo*elc) = ((C/litres) * 1/(msec)) 
			:                                   * (mmol/C)
			: ica*1e7/(depth*2*Avo*elc) = (mmol/litres) * (1/msec)
			: ica*con         = (mM) * (1/msec)
	tau=buftau/rate_k
	cai=cai0
}

DERIVATIVE integrate {
	cai' = -ica*con + (cai0 - cai)/tau
}

UNITSON
I am able to define the parameters above in NEURON using the original Hoc code, but not in Python. I am also able to define them in Python using the direct call to the Hoc interpreter with the h(‘ ‘) command. However, when I define an object in Python as a neuron section and try to define the parameters, I get the error mentioned above. The parameters are all in the PARAMETER block of the Mod file. It seems I am only able to define parameters that are defined as RANGE parameters in the NEURON block.

Any help would be greatly appreciated. Thanks!

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

Re: Changing custom channel parameters through Python

Post by ted » Tue Oct 11, 2011 4:49 pm

lempkas wrote:I have been working on converting a single cell model with detailed anatomy and biophysics from Hoc to Python.
Why bother? You're going to have to prove that your python implementation is identical to the original hoc implementation. What's wrong with using the hoc implemented model from Python?
sec.insert(‘channel’)
sec.property = specific_value

I get the error the following error:

AttributeError: ‘nrn.Section’ object has no attribute ‘property’
Strange.

Code: Select all

dend = h.Section()
dend.nseg = 5
dend.insert("hh")
for seg in dend:
  print seg.gnabar_hh
works fine so far.

Code: Select all

dend(0.3).gnabar_hh = 0.5
for seg in dend:
  print seg.gnabar_hh
worked fine again.

Code: Select all

dend.gnabar_hh = 1
for seg in dend:
  print seg.gnabar_hh
and again success.
I am unable to define the parameters ‘vshift’ calling sec.vshift_axnode75 or ‘vtraub’ calling sec.vtraub_axnode75.
Sure, because that's not how to do it.

lempkas
Posts: 4
Joined: Wed Oct 05, 2011 12:14 pm

Re: Changing custom channel parameters through Python

Post by lempkas » Wed Oct 12, 2011 1:39 am

Thanks. As I mentioned in the previous post, I was able to define properties such as conductances just fine. I only got problems when I tried to define "vshift" and "vtraub" for the AXNODE75 channels and "cai0" for the Cacum channel.
ted wrote:Sure, because that's not how to do it.
What is the correct way to do it? I tried making the same changes when going from Hoc to Python as I did for the conductances along with several other ways. What am I missing?
ted wrote:Why bother? You're going to have to prove that your python implementation is identical to the original hoc implementation. What's wrong with using the hoc implemented model from Python?
Good question. I was able to create the cell and run simulations in Python calling my Hoc code fairly easily. However, I have been having difficulties simulating synaptic inputs to the cell using 'NetCon' and 'Exp2Syn'. I have been able to run these simulations in Hoc but was having difficulty making the appropriate adjustments to call/execute them in Python. I was hoping that converting everything to Python would maybe make it easier to access all of the necessary sections and properties. It hasn't been too much work to convert my Hoc code to Python, but you are right I would need to show that my Python implementation is identical to the Hoc implementation. Maybe I will give it another try.

Sorry if I am asking silly questions. Thanks for the help.

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

Re: Changing custom channel parameters through Python

Post by ted » Wed Oct 12, 2011 11:04 am

Whoa, I made a big mistake. I had only glanced briefly at the nmodl source, and thought that vshift and vtraub were range variables--but they're not. The example code in my last post uses syntax that works only for range variables, which is completely off the mark. Sorry about that.

NMODL parameters that are not declared to be RANGE in the NEURON block are NMODL globals, i.e. have the same value for all instances of an NMODL-specified mechanism. Consequently there's no need to specify either the section or the segment, and the correct syntax for dealing with a density mechanism's globals is
h.varname_suffix
which for your particular case would be
h.vshift_axnode75
and
h.vtraub_axnode75
I was able to create the cell and run simulations in Python calling my Hoc code fairly easily. However, I have been having difficulties simulating synaptic inputs to the cell using 'NetCon' and 'Exp2Syn'. I have been able to run these simulations in Hoc but was having difficulty making the appropriate adjustments to call/execute them in Python. I was hoping that converting everything to Python would maybe make it easier to access all of the necessary sections and properties.
If "almost everything" works correctly, it's generally easier to fix the bit that doesn't, rather than reimplement from scratch. And even if the reimplementation seemed to go without a hitch, the burden of proof would still be on you to establish that your reimplementation was identical to the original.

That said, by writing Python code you did learn some new stuff, including how to access NMODL range and global variables with Python. By the way, the only silly questions are the ones that go unasked.

After you have a chance to read this reply, I'm going to split these most recent posts off into a new discussion thread with a title something like "accessing NMODL range and global params from Python"

If you're running into problems with NetCon and Exp2Syn, please post your question(s) in a new thread.

lempkas
Posts: 4
Joined: Wed Oct 05, 2011 12:14 pm

Re: Changing custom channel parameters through Python

Post by lempkas » Wed Oct 12, 2011 7:16 pm

Thanks, Ted. It worked like a charm.

The cell model that I have completely converted to Python seems to be working fine, but you're right and I am going to give the simulations with the original Hoc code another shot. If I can't figure out my problems with using 'NetCon', 'Exp2Syn', etc. from Python I will post my questions in a new thread.

Thanks so much!

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

Re: Changing custom channel parameters through Python

Post by ted » Thu Oct 13, 2011 1:44 pm

Thanks for using NEURON, and for asking questions that led to an exchange of information that others may find helpful!

Post Reply