So there are three issues to be discussed.
First, WATCH is perfectly accurate. It is the fact of doing numerical integration with a digital computer that forces the discretization of time that allows the watched variable to overshoot a threshold.
Second, regarding assignment to state variables in a BREAKPOINT block--the warning message didn't say it couldn't be done. It said that the result could be failure of a multistep integrator to work properly. Multistep integrators use information about the temporal evolution of state variables in the past in order to make a better prediction of their future values. This requires the variables and their first few derivatives to be continuous (the derivative order at which discontinuity is allowable depends on the details of the integration method). It was naive of me to suggest preventing overshoot by forcing XX to a particular value. That will work with NEURON's default integrator (implicit Euler) but it may not work with adaptive integration.
Third, the final issue is what to do about the threshold overshoot. If you have a mechanism with dynamics so simple that there is an analytical solution--as is the case for the example you sent--then given the current state of the mechanism at any time, its future behavior is completely predictable, and you can discover the time at which it will intersect threshold without having to do numerical integration.* All computation can then be done inside the NET_RECEIVE block and there is no need for a BREAKPOINT block at all. And if you use the ARTIFICIAL_CELL keword in the NEURON block, e.g.
Code: Select all
NEURON {
ARTIFICIAL_CELL Test
RANGE tau
}
and you can treat it the same way you would an IntFire or a NetStim. I didn't see anything in the example you sent that indicated that it has to be a point process.
For that matter, if all you want is a sequence of events at predetermined intervals, why not use a NetStim? The NetCon class's record() method allows events to trigger execution of arbitrary hoc statements. Or you could just use a combination of an FInitializeHandler and cvode.event to force execution of hoc statements at regular intervals.
*--depending on the details of the analytical solution, you might have to resort to Newton's method to discover when the solution crosses threshold, but that can be done to any reasonable degree of precision inside a NET_RECEIVE block much more quickly than the time required to integrate over a series of time steps. Granted, in this case your state variable will still over- or undershoot the threshold by a small amount, but you can decide how small the error is.