Event-based synaptic noise mechanism

NMODL and the Channel Builder.
Post Reply
iraikov
Posts: 17
Joined: Wed Mar 18, 2015 11:53 am
Location: University of California, Irvine

Event-based synaptic noise mechanism

Post by iraikov »

Hello,

I would like to convert the synaptic noise mechanism Gfluct2 https://bitbucket.org/mbezaire/dentate/ ... fluct2.mod for use with NEURON's variable timestep solver, and on another thread Ted suggested that I try to use the event delivery mechanism to avoid being dependent on dt. So I have placed the equations from the BREAKPOINT block in Gfluct2 in a NET_RECEIVE block which is invoked at a predefined interval (code included below). However the current computed in this new mechanism seems to have no effect on the cell in which it is placed. What am I doing wrong? I am including below just the INITIAL and NET_RECEIVE blocks, I can provide the whole file if necessary. Thanks for any help.

Code: Select all

INITIAL {
	g_e1 = 0
	g_i1 = 0
	if(tau_e != 0) {
		D_e = 2 * std_e * std_e / tau_e
		exp_e = exp(-randinterval/tau_e)
		amp_e = std_e * sqrt( (1-exp(-2*randinterval/tau_e)) )
	}
	if(tau_i != 0) {
		D_i = 2 * std_i * std_i / tau_i
		exp_i = exp(-randinterval/tau_i)
		amp_i = std_i * sqrt( (1-exp(-2*randinterval/tau_i)) )
        }
        net_send(0,1)
}


NET_RECEIVE (w) {
    
    if(tau_e!=0) {
	g_e1 =  exp_e * g_e1 + amp_e * mynormrand(0,1)
    }
    if(tau_i!=0) {
	g_i1 =  exp_i * g_i1 + amp_i * mynormrand(0,1)
    }
    
    if(tau_e==0) {
	g_e = std_e * mynormrand(0,1)
    }
    if(tau_i==0) {
	g_i = std_i * mynormrand(0,1)
    }
    g_e = g_e0 + g_e1
    if(g_e < 0) { g_e = 0 }
    g_i = g_i0 + g_i1
    if(g_i < 0) { g_i = 0 }
    i = g_e * (v - E_e) + g_i * (v - E_i)
    
    :printf("oup: t = %g v = %g i = %g g_e = %g g_i = %g E_e = %g E_i = %g\n", t, v, i, g_e, g_i, E_e, E_i)

    net_send(randinterval,1)
}
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Event-based synaptic noise mechanism

Post by ted »

Sorry for the delay in replying. I approached this with some trepidation (always a good idea when doing something that might break working code written by someone else), but this turned out to be much easier than expected.

Starting from the Gfluct2.mod file used by Bezaire, make the following changes:

1. Change the first
ENDCOMMENT
to

Code: Select all

Modified 4/7/2015 by Ted Carnevale
Uses events to control times at which conductances are updated,
so this mechanism can be used with adaptive integration.
Produces exactly same results as original Gfluct2 does
if h is set equal to dt by a hoc or Python statement
and fixed dt integration is used.
ENDCOMMENT
2. In the NEURON block right after the POINT_PROCESS statement insert
RANGE h
3. In the PARAMETER block change
dt (ms)
to

Code: Select all

: dt (ms)
h = 0.025 (ms) : interval at which conductances are to be updated
                 : for fixed dt simulation, should be an integer multiple of dt
4. In the INITIAL block replace every dt with h, and change the closing curly bracket of that block to

Code: Select all

  if ((tau_e != 0) || (tau_i != 0)) {
    net_send(h, 1)
  }
}
5. Comment out the first 7 lines in the BREAKPOINT block, i.e. change them to

Code: Select all

:  SOLVE oup
:  if(tau_e==0) {
:    g_e = std_e * mynormrand(0,1)
:  }
:  if(tau_i==0) {
:    g_i = std_i * mynormrand(0,1)
:  }
6. At the tail end of the mod file, insert this

Code: Select all

NET_RECEIVE (w) {
  if (flag==1) {
    oup()
    net_send(h, 1)
  }
}
Explanation:
dt cannot be used if a mod file is to be compatible with adaptive integration. However, this mechanism does need to know the interval at which conductances are to be updated. Might as well call that h, as is the common practice in many academic papers on this kind of stuff. h should be a RANGE variable so that different instances of this mechanism can be updated at different intervals. When this mechanism is used in fixed time step simulations, h should be set equal to an integer multiple of dt (1, 2, 3 etc.).

The net_send statement in the INITIAL block only has to be called if at least one conductance is to fluctuate; this happens only if at least one of the time constants is > 0. net_send(h, 1) launches a self event with flag==1 that arrives at time t+h.

The first statement in the BREAKPOINT block is no longer needed because PROCEDURE oup() is automatically called when a self event arrives. The next 6 lines never did anything useful in the original mod file (their actions are completely undone by subsequent statements), so why bother executing them?

The NET_RECEIVE block specifies what to do when a self event with flag==1 arrives--in this case, call PROCEDURE oup() and then launch another self event with flag==1 that will arrive at t+h.

Note that simulations that use this event-driven mechanism will not execute more quickly than those that use the original mod file. However, the simulations will be executed with adaptive integration, which should produce more accurate results than if fixed dt were used.
iraikov
Posts: 17
Joined: Wed Mar 18, 2015 11:53 am
Location: University of California, Irvine

Re: Event-based synaptic noise mechanism

Post by iraikov »

This is great Ted, thanks so much for doing all the hard work for me :-) The new mechanism works reasonably well even with a large h, so I will try it out in the network and see if the variable timestep method will make a difference there.
Post Reply