Driving synaptic event using vecStim

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

Moderator: hines

Driving synaptic event using vecStim

Postby mattions » Thu Dec 09, 2010 6:49 pm

Dear all,
I'm trying to delivery synaptic input at fixed time to a vecevent mod from Neuron example, but with no effect.

This is the testcase I'm using to experiment this feature:
Code: Select all
from neuron import h
import neuron.gui

soma = h.Section(name='soma')
ampa = h.AMPA(0.5, sec=soma)
soma.insert('hh')

vecStim = h.VecStim()
vec = h.Vector(3)
vec.indgen()

vecStim.play(vec)

h.run()


This is the mod for the AMPA syn

Code: Select all
TITLE    AMPA synapse for nucleus accumbens model

: see comments below



NEURON {

   POINT_PROCESS AMPA

   RANGE gbar, tau_r, tau_d, scale, spkcnt, countflag, i, t1, ca_ratio, ical, itmp, qfact

   NONSPECIFIC_CURRENT i

   USEION cal WRITE ical VALENCE 2



}



UNITS {

   (nA) = (nanoamp)

   (mV) = (millivolt)

   (umho) = (micromho)

}



PARAMETER {

   gbar = 8.5e-4   (umho)    : approx 0.5:1 NMDA:AMPA ratio (Myme 2003)

                     :   with mg = 0, vh = -70, one pulse, NMDA = 300 pS

                     :   here AMPA = 593 pS (NMDA set to Dalby 2003)

   tau_r = 2.2    (ms)      : Gotz 1997, Table 1 - rise tau

   tau_d = 11.5     (ms)      : Gotz 1997, Table 1 - decay tau

   

   Erev = 0       (mV)      : reversal potential, Jahn 1998

   saturate = 1.2          : causes the conductance to saturate - matched to

                     :    Destexhe's reduced model in [1]

   qfact = 2            : convert 22 degC to 35 degC

   ca_ratio = 0.005         : ratio of calcium current to total current

}                     : Burnashev/Sakmann J Phys 1995 485:403-418

                     : with Carter/Sabatini Neuron 2004 44:483-493





ASSIGNED {

   g (umho)

   v (mV)         : postsynaptic voltage

   itmp   (nA)   : temp value of current

   i (nA)         : nonspecific current = g*(v - Erev)

   ical (nA)      : calcium current through AMPA synapse (Carter/Sabatini)

   t1 (ms)

   

   y1_add (/ms)    : value added to y1 when a presynaptic spike is registered

   y1_loc (/ms)



   countflag      : start/stop counting spikes delivered

   spkcnt         : counts number of events delivered to synapse

   scale         : scale allows the current to be scaled by weight

}               : so NetCon(...,2) gives 2*the current as NetCon(...,1)





STATE {

   y1 (/ms)

   y2             : sum of beta-functions, describing the total conductance

}



INITIAL {

     y1_add = 0

   scale = 0

   spkcnt = 0

   countflag = 0

   t1 = 0

   y1_loc = 0

}



BREAKPOINT {

     SOLVE betadyn METHOD cnexp

   g = gbar * y2

     itmp = scale * g * (v - Erev)

     i = (1-ca_ratio) * itmp

     ical = ca_ratio * itmp

}



DERIVATIVE betadyn {

   : dynamics of the beta-function, from [2]

   y1' = -y1 / (tau_d/qfact)

   y2' = y1 - y2 / (tau_r/qfact)

}



NET_RECEIVE( weight, y1_loc (/ms) ) {

   : updating the local y1 variable

   y1_loc = y1_loc*exp( -(t - t1) / (tau_d/qfact) )



   : y1_add is dependent on the present value of the local

   : y1 variable, y1_loc

   y1_add = (1 - y1_loc/saturate)



   : update the local y1 variable

   y1_loc = y1_loc + y1_add



   : presynaptic spike is finaly registered

   y1 = y1 + y1_add



   : store the spike time

   t1 = t



   spkcnt = spkcnt + 1



   scale = weight

}







Unfortunately not event is delivered and the voltage doesn't change at all.

Any idea what I'm doing wrong?

Thanks.
mattions
 
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Postby ted » Fri Dec 10, 2010 1:10 am

Unfortunately not event is delivered and the voltage doesn't change at all.
How do you know that no event is delivered? Have you tried driving an ExpSyn with VecEvent? A VecEvent is an artificial spiking cell. Where is the code for the NetCon that is necessary to convey events generated by the VecEvent to the synaptic mechanism you are trying to drive? Are you sure that the NetCon's weight is nonzero?
ted
Site Admin
 
Posts: 3587
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine

Re: Driving synaptic event using vecStim

Postby mattions » Fri Dec 10, 2010 7:25 am

Thanks for the hints

Actually I found out that the NetCon weight was zero, the AMPA gbar by default was too small.

This works:

Code: Select all
from neuron import h
import neuron.gui

soma = h.Section(name='soma')
soma.insert('hh')
ampa = h.AMPA(0.5, sec=soma)
ampa.gbar = 1 # Just increasing, for testing purpose

vecStim = h.VecStim()
vec = h.Vector([1, 2])
vecStim.play(vec)

netCon = h.NetCon(vecStim, ampa)
netCon.weight[0] = 1


And this is the version with the ExpSyn

Code: Select all
from neuron import h
import neuron.gui

soma = h.Section(name='soma')
soma.insert('hh')

expSyn = h.ExpSyn(0.5, soma)
expSyn.e = 10
expSyn.i = 3
expSyn.tau = 3

vecStim = h.VecStim()
vec = h.Vector([1, 2])
vecStim.play(vec)

netCon = h.NetCon(vecStim, expSyn)
netCon.weight[0] = 1


However I've set it up this to test a bigger code model.
The error I'm receiving is this one:

Code: Select all
net_send td-t = -6.93273e-320 SelfEvent target=VecStim[0] 7.58347762892499e-316 flag=1
Aborted



I don't understand. There is same flag I can turn on to help me in the debug?
mattions
 
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Postby ted » Fri Dec 10, 2010 11:45 am

Code: Select all
net_send td-t = -6.93273e-320 SelfEvent target=VecStim[0] 7.58347762892499e-316 flag=1
means the error is generated by a problem encountered by an instance of the VecStim class. More specifically, "net_send td-t = -6.93273e-320" suggests that the VecStim gagged on an invalid spike time.
ted
Site Admin
 
Posts: 3587
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine

Re: Driving synaptic event using vecStim

Postby mattions » Fri Dec 10, 2010 1:29 pm

What is an invalid spike time?
There are some times that are not valid?

I'm trying those time:
Code: Select all
155   160   165   170   175   


They are in ms. So the first event should be at 155 ms followed by other 4.

I'm switching from NetSource to a VecStim because I need to run event in precomputed time, which are not possible to replicate with a NetSource. (For example two trains of stimulation.)
mattions
 
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Postby ted » Fri Dec 10, 2010 8:52 pm

To diagnose the problem and suggest a solution, I'll have to be able to reproduce it. If you zip up just the code and data that are necessary to generate the error message and send it to me
ted dot carnevale at yale dot edu
I'll tell you what I discover.
ted
Site Admin
 
Posts: 3587
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine

Re: Driving synaptic event using vecStim

Postby regger » Mon Apr 23, 2012 4:41 pm

I know this is an older post, but I've run across the same error message. I found a way around it, just trying to understand now what's going on since I'm only beginning using NEURON...

I'm creating a bunch of VecStim events and store them in a python list. To set them with spike times, I iterate over the list, create a Vector with the spike time(s) for each VecStim and call the VecStim play() method with the newly created Vector as an argument, something like this:

Code: Select all
vecStimList = [neuron.h.VecStim() for src in spikeSoures]
for vecStim in vecStimList:
    t = whatever spike time
    tVec = neuron.h.Vector([t])
    vecStim.play(tVec)


This sometimes works, usually doesn't, giving a similar error message as described above, with net_send td-t = some negative number.
However, when I keep an explicit reference to the newly created vectors (e.g. just append them to a list), everything works just fine. So I guess what's happening is the vecStim.play() method doesn't copy the spike times, but keeps a reference to the Vector, which is no longer valid after leaving the loop? Does that have to do with the NEURON/python interface? Because I thought python manages reference counting automatically, so it shouldn't be a problem as long as a VecStim keeps a reference to a Vector. Or did I miss some simple scoping rule?

Thanks,

Robert
regger
 
Posts: 7
Joined: Sun Apr 22, 2012 9:49 pm

Re: Driving synaptic event using vecStim

Postby mattions » Tue Apr 24, 2012 3:28 am

The problem is tVec does not exist anymore outside the loop, therefore one solution is to create a vector list and add the vectors as you create them.

Code: Select all
vecStimList = [neuron.h.VecStim() for src in spikeSoures]
tVecList = [] # List to hold the Vectors
for i, vecStim in enumerate(vecStimList):
    t = whatever spike time
    tVec = neuron.h.Vector([t])
    tVecList.append(tVec) # Keeping the Vector alive outside the loop
    vecStim.play(tVec)
mattions
 
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Postby regger » Tue Apr 24, 2012 12:49 pm

Thanks, that's what I did too.
I guess my question is more that it seems a little unintuitive - you register the Vector with the VecStim using the play() method, and after that you still have to worry about the lifetime of the Vector. Naively, I guess I was expecting the play() method to copy the values inside the Vector or keep a reference to the whole Vector (that would keep tVec from becoming invalid after the loop); but I guess the python interface to NEURON is really more a wrapper around the C part and there's pointers being passed around, which would explain why it isn't working as I naively expected.
regger
 
Posts: 7
Joined: Sun Apr 22, 2012 9:49 pm

Re: Driving synaptic event using vecStim

Postby hines » Wed Apr 25, 2012 7:49 am

The same problem would occur with HOC. The vecevent.mod does not increment the reference count of the Vector it holds a pointer to, nor does it
register itself as an observer of the Vector. So the problem is that I chose the path of least programming effort (didn't bother to write a DESTRUCTOR block
for the mod file) at the expense of safety. To repair the problem one would have to add the following into PROCEDURE play at the end of its VERBATIM block.
Code: Select all
  hoc_obj_ref(*vector_pobj(*vv));

and in addition, create the following block to unref the Vector when the VecStim is destroyed
Code: Select all
DESTRUCTOR {
VERBATIM {
  void** vv;
  vv = (void**)(&space);
  if (*vv) {
    hoc_obj_unref(*vector_pobj(*vv));
  }
}
ENDVERBATIM
}

Also add prototypes to the functions used above to the VERBATIM block that already has extern void* vector_arg();
The following would suffice
Code: Select all
extern void hoc_obj_ref(void*);
extern void hoc_obj_unref(void*);
extern void** vector_obj(void*);


I did not execute the above so there may be typos but the idea is sound except for the case where one wants to call the play function
more than once (to replace a previous Vector). In that case one could safely assume that space is initailzed to 0 and replace the body of the
VERBATIM block with
Code: Select all
  void** vv;
  void* vtmp;
  if (ifarg(1)) {
    vtmp = vector_arg(1);
    hoc_obj_ref(*vector_pobj(vtmp));
  }
  vv = (void**)(&space);
  if (*vv) {
    hoc_obj_unref(*vector_pobj(*vv));
  }       

That is one needs to increment the new one before decrementing the old one. In case they are the same, we don't want the refcount to go to 0.
The reason for the bizarre use of void** is so that the 64bit space for a double can be used to hold a 64bit pointer pattern.
Note that one can turn off a VecStim without destroying it by using VecStim.play() with no args. Turn it back on by supplying a Vector arg.
Or one could resize the Vector to 0.
hines
Site Admin
 
Posts: 980
Joined: Wed May 18, 2005 3:32 pm

Re: Driving synaptic event using vecStim

Postby hines » Wed Apr 25, 2012 7:54 am

As I warned in the above, the idea is sound but there may be typos. One I see is in the last code block of the previous message where I forgot the last line
Code: Select all
  if (vtmp) { *vv = vtmp; }
hines
Site Admin
 
Posts: 980
Joined: Wed May 18, 2005 3:32 pm

Re: Driving synaptic event using vecStim

Postby regger » Wed Apr 25, 2012 11:01 am

That explains it. I was just confused in the beginning, but suspected something along this line. Thanks for the in-depth explanation!
Will try out your suggestions out when I get around to it soon hopefully.

Robert
regger
 
Posts: 7
Joined: Sun Apr 22, 2012 9:49 pm


Return to NEURON + Python

Who is online

Users browsing this forum: No registered users and 0 guests

cron