Page 1 of 1

xpanel between python and hoc

Posted: Wed Jan 24, 2018 12:34 pm
by bschneiders
I made an xpanel for my model so that I can demo it for my collaborators. I found the translation between Python and hoc not so smooth though so I wanted to see if I was missing something.

It seemed like all I would need to do is use "h.xvalue" to update constants, and then have my own initialization procedure so that the model would be reset before each run, using the updated parameters. Each of these (updating parameters, and running my own initialization) work on their own but there is some disconnect where my model is not correctly updating.

I wrote “myinit()” in Python and implement it using

Code: Select all

initnew = h.FInitializeHandler(0,myinit) 
Getting an xpanel up is also no problem. I follow the syntax shown here: ... tml#xvalue
As a detail, I have done this as a Python class when using action procedures in Python, and otherwise not as a class.

I include a print statement within “myinit” so I can see that a given value is at least updated in Python after changing it within my xpanel. If I print that value directly in terminal though, it is clear that it is not actually updated - I believe this means that it is not updated in hoc.

Here is an example:

For an IClamp in the soma, I have a parameter called "somastim_amp" which defines the hoc "IClamp.amp" parameter. If I increase "somastim_amp" from 0 to 1 nA using the xpanel, and print "somastim_amp" in terminal, it will indeed report a value of 1 nA (this is a Python variable). Within "myinit()", the update implementation looks like:

Code: Select all

stimIC = h.IClamp(.5, sec = soma)
stimIC.amp = somastim_amp
print "stimIC.amp = “, stimIC.amp, " and somastim_amp = “, somastim_amp
The print statement yields the same value for both. However, if I print "somastim_amp" and "stimIC.amp" in terminal directly, I get "somastim_amp = 1" and "stimIC.amp = 0", and it is clear from my voltage traces that the soma stimulus was not updated from 0 nA to 1 nA in the run.

I also tried using action procedures in Python in the manner indicated in the same above link. This ran fine but still didn't solve the problem.

What ultimately worked was to write hoc procedures for the update action procedures instead of in Python. So, following the same example, I have a short hoc procedure that reads:

Code: Select all

proc update_stim_amp() {
	nrnpython("stimIC.amp = somastim_amp") 	
and I have a similar procedure for every parameter, loaded in before I initialize and run the model. So I'm essentially running python code in hoc to make the updates go through.

This is a very longwinded post to just ask if there is a simpler, less clunky way to do this than what I am already doing. Am I just missing a step that ensures my "myinit" procedure gets run through hoc too? Thanks!

Re: xpanel between python and hoc

Posted: Thu Jan 25, 2018 1:46 pm
by ted
There are a couple of ways to make your task easier. One is to just use the NEURON Main Menu's GUI interface to manage signal sources such as IClamps. That should work well for a single cell model, as long as you can look at the stick figure of the model cell in the PointProcessManager's shape plot and figure out where to attach the IClamp.

If you also want to use the NMM's Graphs (very convenient for space plots), it would be best to create all sections in hoc (because a section created by e.g.
soma = h.Section()
or even
soma = h.Section( name = 'soma' )
will have an automatically generated hoc name that is long and ugly and--worse yet--DIFFERENT from session to session). Fortunately you can do that without having to write any hoc code--just use the CellBuilder to set up the model cell as a class, save that class to a hoc file, and then use it with your own Python code like so:

Code: Select all

from neuron import h,gui
h.load_file("mycellclass.hoc") # a hoc-defined model cell class exported from a CellBuilder
cell = h.Pyr # assumes the hoc class name is Pyr 
# now hoc has a single instance of the Pyr class called Pyr[0]
At this point, you can use NEURON's GUI tools to show a Shape plot of the cell, attach IClamps and/or SEClamps, create a RunControl panel for launching simulations, plot graphs of variables that belong to the sections in Pyr[0], e.g. Pyr[0].soma.v(0.5) would be the hoc name of membrane potential at the middle of the soma (the section that would be known to Python as cell.soma). AND you can use the NMM toolbar's
File / save session
to save a .ses file that you can reuse in the future to recreate the GUI that you created, like so:

Code: Select all

from neuron import h,gui
h.load_file("mycellclass.hoc") # a hoc-defined model cell class exported from a CellBuilder
cell = h.Pyr # assumes the hoc class name is Pyr 
h.load_file("") # assumes the ses file you saved was called "rig" (like an experimental rig)
And you never have to write your own GUI code. All very nice to know now, but maybe not so helpful for dealing with your existing model.

So now let's focus on your present problem. Can you send me the Python code that you're using to deal with the IClamp, and maybe a toy model to use it with, so I can reproduce the problem you are seeing?

Re: xpanel between python and hoc

Posted: Fri Jan 26, 2018 2:17 pm
by bschneiders
Great - I just sent a toy model. Thank you!

Meanwhile I will look into your suggestions. One of the reasons I've been using python is to use the RxD module, but I'll look into making the morphology in hoc instead, and just using python for the RxD related parts.

Re: xpanel between python and hoc

Posted: Sun Feb 04, 2018 10:29 pm
by ted
I have emailed you a zip file that contains source code that I hope will give you some useful idioms for using NEURON's GUI from Python. Let me know if you have more questions about this. In the meantime, for the benefit of other readers who may stumble across this thread, here is a list of some of the issues that were directly or indirectly raised by your question, along with suggestions for dealing with them.

0. from neuron import h, gui
This will make the NEURON Main Menu and all of its tools available.
Also, importing the gui will ensure that the standard run system is available; this means that, unless you're doing something very unusual, you won't have to "roll your own simulation initialization or control code." Instead, just use
to initialize and launch a simulation.

1. To take maximum advantage of the GUI's features, make sure that all sections are created in hoc. When necessary to deal with them in Python, create Python aliases with names identical to the section names in hoc.
A. A toy model with just a few sections--
h('create soma, axon, dend')
soma = h.soma
axon = h.axon
B. A stick figure model created with the CellBuilder, or a model cell with detailed morphology e.g. from using Import3d to import a morphometric data file--
Save the configured CellBuilder to a .ses file so you can recreate it in the future if necessary. From the CellBuilder you can export a top-level specification of the model cell (top level means the sections are not wrapped in a cell class), but it's probably best to export a hoc cell class. If you do the latter, then you can create new instances of the cell class like so
pyr = h.Pyr() # assumes the hoc cell class is called Pyr
and each section will automatically have a Python name of the form

Why is this useful? All sections and cell objects will have meaningful hoc names, which is essential if you want to use the GUI's tools such as
  • Model View to verify the properties of your model cell
  • PointProcessManagers to attach signal sources like SEClamps, IClamps, or synaptic mechanisms, or even create instances of artificial spiking cells for debugging synaptic plasticity or testing very small networks
  • Graphs (including voltage axis graphs, space plots, and shape plots) to display the temporal and spatial variation of key variables such as membrane potential, clamp or synaptic currents, ionic concentrations, voltage-gated conductances, or gating variables
And of course you can use the Print&File Window Manager to select and save the graphs, etc. that you created to ses files that you can then later retrieve by load_file statements
Very handy for constructing custom user interfaces.

2. Suppose you have a top-level variable, and you need to assign a value to it with a statement that is not at the top level (e.g. a statement inside a procedure or in an h.xvaluel() or h.xpvalue() argument). Instead of using __main__, do this:
Before you get to the assignment statement, at the top level execute the following
import sys
thismodule = sys.modules[__name__]
Then past that point you can do things like the following

Code: Select all

# assumes ampa_g, g_single, and nchannels are top-level variables
# and nc is a NetCon that was created at the top level
def set_ampa_g():
  thismodule.ampa_g = g_single*nchannels
  nc.weight[0] = ampa_g

h.xpanel('Synaptic params')
h.xvalue('single channel g [nS]', (thismodule,'ampa_g'), 1, set_ampa_g)
h.xvalue('number of channels', (thismodule,'nchannels'), 1, set_ampa_g)
h.xvalue('ampa_g', (thismodule,'ampa_g')) # show result