: $Id: izap.mod,v 1.4 2015/05/28 02:42:00 ted Exp ted $ COMMENT izap.mod Delivers an oscillating current that starts at t = del >= 0. The frequency of the oscillation increases linearly with time from f0 at t == del to f1 at t == del + dur, where both del and dur are > 0. Uses event delivery system to ensure compatibility with adaptive integration. Original implementation 12/4/2008 NTC ENDCOMMENT NEURON { POINT_PROCESS Izap RANGE del, dur, f0, f1, amp, f, i ELECTRODE_CURRENT i } UNITS { (nA) = (nanoamp) PI = (pi) (1) } PARAMETER { del (ms) dur (ms) f0 (1/s) : frequency is in Hz f1 (1/s) amp (nA) } ASSIGNED { f (1/s) i (nA) on (1) } INITIAL { f = 0 i = 0 on = 0 if (del<0) { del=0 } if (dur<0) { dur=0 } if (f0<=0) { f0=0 (1/s) } if (f1<=0) { f1=0 (1/s) } : do nothing if dur == 0 if (dur>0) { net_send(del, 1) : to turn it on and start frequency ramp } } COMMENT The angular velocity in radians/sec is w = 2*PI*f, where f is the instantaneous frequency in Hz. Assume for the moment that the frequency ramp starts at t = 0. f = f0 + (f1 - f0)*t/dur Then the angular displacement is theta = 2*PI * ( f0*t + (f1 - f0)*(t^2)/(2*dur) ) = 2*PI * t * (f0 + (f1 - f0)*t/(2*dur)) But the ramp starts at t = del, so just substitute t-del for every occurrence of t in the formula for theta. ENDCOMMENT BREAKPOINT { if (on==0) { f = 0 i = 0 } else { f = f0 + (f1 - f0)*(t-del)/dur i = amp * sin( 2*PI * (t-del) * (f0 + (f1 - f0)*(t-del)/(2*dur)) * (0.001) ) } } NET_RECEIVE (w) { : respond only to self-events with flag > 0 if (flag == 1) { if (on==0) { on = 1 : turn it on net_send(dur, 1) : to stop frequency ramp, freezing frequency at f1 } else { on = 0 : turn it off } } }