Driving synaptic event using vecStim

NMODL and the Channel Builder.
mattions
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Driving synaptic event using vecStim

Post by mattions »

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.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Driving synaptic event using vecStim

Post by ted »

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?
mattions
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Post by mattions »

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?
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Driving synaptic event using vecStim

Post by ted »

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.
mattions
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Post by mattions »

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.)
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Driving synaptic event using vecStim

Post by ted »

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.
regger
Posts: 21
Joined: Sun Apr 22, 2012 9:49 pm

Re: Driving synaptic event using vecStim

Post by regger »

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
mattions
Posts: 65
Joined: Tue Jul 15, 2008 11:21 am
Location: EMBL-EBI Cambridge UK

Re: Driving synaptic event using vecStim

Post by mattions »

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)
regger
Posts: 21
Joined: Sun Apr 22, 2012 9:49 pm

Re: Driving synaptic event using vecStim

Post by regger »

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.
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: Driving synaptic event using vecStim

Post by hines »

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: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: Driving synaptic event using vecStim

Post by hines »

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; }
regger
Posts: 21
Joined: Sun Apr 22, 2012 9:49 pm

Re: Driving synaptic event using vecStim

Post by regger »

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
Rivaldo
Posts: 6
Joined: Mon Jan 12, 2015 8:58 pm

Re: Driving synaptic event using vecStim

Post by Rivaldo »

Hello,

I have a general question on VecStim() and hope this is the right place to post it. Using "new VecStim()" brings up this error "VecStim is not a template". I tested this on several machines and all give me the same error. What I'm doing wrong?

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

Re: Driving synaptic event using vecStim

Post by ted »

Rivaldo wrote:Using "new VecStim()" brings up this error "VecStim is not a template". I tested this on several machines and all give me the same error. What I'm doing wrong?
You need to put a copy of the mod file that defines VecStim in the same directory as your hoc code, and then compile it with mknrndll or nrnivmodl.

That file is vecevent.mod, but you should use the latest version of that file, which Michael Hines has revised to prevent the problems described in previous posts in this thread. Here it is
https://www.neuron.yale.edu/ftp/ted/neuron/vecevent.mod
This file has also been committed to NEURON's mercurial repository, so it will be automatically included in future versions of NEURON.
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: Driving synaptic event using vecStim

Post by rlindroos »

Hi all,
We are trying to use the updated vecStim mechanism to run simulations in CoreNEURON.
Unfortunately the simulation fails with an error message saying that POINTER is not pointing to voltage or mechanism.

We have localized the error to the pointer in the vecStim mechanism (since the error goes away if we remove it).

Any ideas on how to avoid/fix this?


Thanks!
Robert
Post Reply