Page 1 of 1

at_time(event) keeps being true when t>event?

Posted: Thu Jan 30, 2014 1:32 pm
by patoorio
Hi,
I want to code a mechanism with a conductance that raises and then decreases exponentially. As it's a simple exponential, I don't want to use differential equations but rather an exponential function changing the initial and steady state value. However, the initial value has to be the actual g value at time=onset (or onset + duration) because it may not always reach steady state. The important part of the code is the following:

Code: Select all

INITIAL {
    g0=minG
    ginf=minG
    calcG()
    tref=0
}

BREAKPOINT {
    if(at_time(onset)) {
        g0=g
        ginf=maxG
        tref=onset
    }
    if(at_time(onset+dur)) {
        g0=g
        ginf=minG
        tref=onset+dur
    }
    calcG()   
    i = g*(v-e)
}
	
PROCEDURE calcG() {
    if (t < onset) {
	g=minG	
	}	
    if (t >= onset) {
        g = ginf - (ginf - g0)*exp(-(t-tref)/tau)
	}
}
So the idea is to change (g0,ginf) to (g(onset),maxG) and (g(onset+dur),minG) and do it only once, when either t==onset or t==onset + dur. From the nmodl400.pdf file, I read that 'at_time() returns a value of 1 (“true”) only during the “infinitesimal” step that ends at t = event_time + epsilon; otherwise it returns 0.'
However, what I see in the simulation is that whenever t=>onset, g0 keeps being updated each time step. What is the correct way of making something to happen only once, at a given time?
I'll welcome any alternative method to accomplish what I want, but still I'd like to know why at_time() is not working the way it is supposed to.

Thank you

Re: at_time(event) keeps being true when t>event?

Posted: Fri Jan 31, 2014 2:18 pm
by ted
patoorio wrote:I want to code a mechanism with a conductance that raises and then decreases exponentially.
Why not just use an ExpSyn and drive it with a single event delivered by a NetCon (that is use netcon.event(tdeliver)--see the documentation of the NetCon class's event method).
As it's a simple exponential, I don't want to use differential equations but rather an exponential function
This is a false economy. First, at_time is deprecated, which means that it is strongly recommended that it not be used in new code development. For one thing, code that uses at_time tends to be hard to understand. Events are far more flexible and powerful, and make it very easy to implement state machines that produce sequences and waveforms that range from very simple to quite complex.
Second, if your code uses a DERIVATIVE block with an ODE, and a SOLVE statement that uses METHOD cnexp, then compiling it with mknrndll or nrnivmodl will automatically generate code that

--if dt is fixed, uses the analytical solution of the ODE to algebraically assign values to conductance (this is what you're trying to do)
--if adaptive integration is being used, solves the ODE by numerical integration

You end up with clean looking NMODL source code that automatically works with either fixed dt or adaptive integration.
still I'd like to know why at_time() is not working the way it is supposed to.
Maybe the problem is in that old pdf--many things have changed since it was written.

Re: at_time(event) keeps being true when t>event?

Posted: Fri Jan 31, 2014 2:35 pm
by patoorio
Thanks a lot for your answer
ted wrote:Why not just use an ExpSyn and drive it with a single event delivered by a NetCon
Yes, that's more or less what I will do but with some modification because I want the conductance to raise exponentially, stay there for a variable period of time, and then decrease exponentially.
ted wrote:compiling it with mknrndll or nrnivmodl will automatically generate code that

--if dt is fixed, uses the analytical solution of the ODE to algebraically assign values to conductance (this is what you're trying to do)
--if adaptive integration is being used, solves the ODE by numerical integration
.
Mmmmm... I mainly intend to use it with adaptive integration. I will check how slow it gets, as I have like 50,000 of this processes (each one with a different onset time).

And just for the sake of completeness of the answer, is there a correct way of making something to happen only once, at a given time? (i.e. discontinuites in parameters or assigned). And I mean from the point of view of NMODL code.

Best Regards

Re: at_time(event) keeps being true when t>event?

Posted: Sat Feb 01, 2014 12:25 pm
by ted
patoorio wrote:I want the conductance to raise exponentially, stay there for a variable period of time, and then decrease exponentially.
To formalize the specification--do you want identical time constants for the rising and falling phases, or do you want them to be different?
I have like 50,000 of this processes (each one with a different onset time)
Will they be electrotonically close to each other? or will they be at significantly different locations in the same cell (or attached to different cells, which would be an equivalent computational burden)? By the way, if your model has 5e4 different compartments, it already has at least 5e4 ODEs, so a few more won't matter all that much.
is there a correct way of making something to happen only once, at a given time? (i.e. discontinuites in parameters or assigned).
The most powerful and flexible way to control "what happens and when it happens" is with events. An FinitializeHandler used with cvode.event or netcon.event is a good way to perturb model parameters via hoc, including things that affect mechanisms implemented with NMODL.
NMODL-specified mechanisms can also be controlled by self-events and events delivered by a NetCon. For some examples of mechanisms that use self-events, see
https://www.neuron.yale.edu/ftp/ted/neuron/ipulse.zip
https://www.neuron.yale.edu/ftp/ted/neuron/izap.zip
https://www.neuron.yale.edu/ftp/ted/neu ... ve_new.zip
https://www.neuron.yale.edu/ftp/ted/neuron/repsec.zip
https://www.neuron.yale.edu/ftp/ted/neu ... _noise.zip