array of point processes

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

Moderator: hines

Post Reply
patoorio
Posts: 81
Joined: Wed Jan 30, 2008 12:46 pm

array of point processes

Post by patoorio »

Hi,

I'm starting to figure out how to do some things in neuron+python. However, I'm kind of new to python yet and I have a (probably) basic question:
How do I translate a code like the following into python?

Code: Select all

objref GABAinp[N_in], GABApre[N_in], GABAconn[N_in]

for ii= 0,N_in-1 {
	GABAinp[ii] = new Exp2Syn(0.5)
	GABApre[ii] = new NetStim(0.5)
	GABAconn[ii] = new NetCon(GABApre[ii],GABAinp[ii])
	GABAconn[ii].weight = 0.0005
}
I'm still not sure how to make indexed arrays of objects in python, as I'm still beggining to understand arrays, lists and tuples.

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

Re: array of point processes

Post by ted »

Good question. Python has arrays, lists, and tuples because each of these things is good for a particular purpose. It's the purpose that determines which of these is best to use for managing a collection of objects.
patoorio wrote:How do I translate a code like the following into python?

Code: Select all

objref GABAinp[N_in], GABApre[N_in], GABAconn[N_in]

for ii= 0,N_in-1 {
	GABAinp[ii] = new Exp2Syn(0.5)
	GABApre[ii] = new NetStim(0.5)
	GABAconn[ii] = new NetCon(GABApre[ii],GABAinp[ii])
	GABAconn[ii].weight = 0.0005
}
I'm still not sure how to make indexed arrays of objects in python, as I'm still beggining to understand arrays, lists and tuples.
It's almost never a good idea to use an indexed array of objects. Lists of objects are usually a far superior way to manage collections of objects, whether you're writing hoc or Python.

The first question to ask is, which type of object is best to use for managing collections of synaptic mechanisms and NetCons. The problem with arrays is that you have to know how many elements are in the array. You have to define a symbolic constant, and every time you want to iterate over every element in the array you have to remember the name of the symbolic constant. What happens if SomeObject[j] is destroyed, where 0<=j<number_of_objects_in_this_array ? Will the objects whose indices are > j automatically be given new indices? If not, what happens when your iterator statement gets to ii = jj -- code fails, right? And what if you forget to assign a new value to the symbolic constant that keeps track of how many objects are in the array? Another code failure. And what if your model contains many different kinds of synaptic mechanisms, and you want to iterate over all of them--you can't just write

Code: Select all

for ii=0,total_number_of_synaptic_mechanism_instances-1 {
  statements that involve SomeName[ii]
}
because there isn't a single class name that refers to each of the different kinds of synaptic mechanisms.

These are some of the reasons why it's better to manage collections of objects with a List. A hoc implementation that uses Lists might look like this

Code: Select all

objref gabasyn, gabapre, gabanc
gabasyn = new List()
gabapre = new List()
gabanc = new List()
for ii=0,N_in-1 {
  gabasyn.append(new Exp2Syn(0.5))
  gabapre.append(new NetStim())
  gabanc.append(new NetCon(gabapre.o(ii), gabasyn.o(ii))
  gabanc.o(ii).weight = 0.0005
}
Then if you ever need to iterate over all elements of any of these lists, do something like this

Code: Select all

for ii=0,gabanc.count-1 {
  gabanc.o(ii).weight = 0.0004
}
The Python syntax for creating and using Lists is a bit different, but your transition from hoc to Python will be smoother if you start by using Lists rather than indexed arrays.

A final comment: these examples are a bit contrived, because if each gabasyn is going to have the same time constants and reversal potential, and they are all going to be attached to the same location (compartment) in a model, it would save runtime and memory to use a single instance of Exp2Syn. The code would then become

Code: Select all

objref gabasyn, gabapre, gabanc
gabasyn = Exp2Syn(0.5)
gabapre = new List()
gabanc = new List()
for ii=0,N_in-1 {
  gabapre.append(new NetStim())
  gabanc.append(new NetCon(gabapre.o(ii), gabasyn)
  gabanc.o(ii).weight = 0.0005
}
patoorio
Posts: 81
Joined: Wed Jan 30, 2008 12:46 pm

Re: array of point processes

Post by patoorio »

Thank you, Ted!
Indeed the lists are very straightforward in pyhton and much similar to the neuron code. I'll also keep lists in mind when doing something similar in hoc again.

About your final comment, I thought of that, and my first thought would be that it should be the same. But I had a second thought that it may not be the same to have a single synapse receiving all the weight increases. If at one time (or within a small time window) many synapses are activated, each of them will follow the raise and fall of conductance independently. However if one single synapse receives many weight increases at the same time, its conductance time course will not be the same as in the independent case. Am I wrong? Perhaps I'll do a simulation to check it, but that's my first intuition.

Cheers

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

Re: array of point processes

Post by ted »

patoorio wrote:About your final comment, I thought of that, and my first thought would be that it should be the same. But I had a second thought that it may not be the same to have a single synapse receiving all the weight increases. If at one time (or within a small time window) many synapses are activated, each of them will follow the raise and fall of conductance independently. However if one single synapse receives many weight increases at the same time, its conductance time course will not be the same as in the independent case.
If the ordinary differential equation (ODE) that governs the response of a synaptic mechanism to input events is linear, the system described by this equation is a linear system, and the superposition principle applies.

"So what?"

If the ODE that governs a synaptic conductance is linear, arrival of an event with weight wx at time tx produces a conductance whose time course can be found by convolving the unit impulse response of the ODE with the dirac delta function wx*delta(t-tx) i.e. an impulse that occurs at time tx and has integral equal to wx. From this we know that the conductance g(t) of a single instance of the synaptic mechanism driven by a stream of input events e1..en is identical to the sum of the conductances of n separate instances of the synaptic mechanism, each of which receives only one input event.

That is, given events e1..en that arrive at times t1..tn, consider two cases:
Case 1: n separate instances of a particular linear synaptic mechanism, where the jth instance receives event ej and has conductance gj(t) = G(ej) where G(ej) is the response of the ODE to event ej. The total synaptic conductance is G(e1) + G(e2) + . . . + G(en).
Case 2: a single instance of that same linear synaptic mechanism, but this one is driven by all n events. The conductance of this synaptic mechanism is g(t). The total synaptic conductance is
g(t) = G(e1, e2, . . ., en)
By superposition we know that
G(e1, e2, . . ., en) = G(e1) + G(e2) + . . . + G(en)
so
g(t) = SUMMA gj(t)
and a single instance of the synaptic mechanism driven by the ensemble of events produces the same conductance change as n instances of the mechanism, each of which receives only one event.
patoorio
Posts: 81
Joined: Wed Jan 30, 2008 12:46 pm

Re: array of point processes

Post by patoorio »

You are right.
Thanks!

EDIT: And it's waaay much faster!!!
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: array of point processes

Post by ted »

Speed is not everything, but it's not nothing either.
Post Reply