COMMENT
Noise current characterized by normal distribution
with user-specified mean and standard deviation.
Borrows from NetStim's code so it can be linked with an external instance
of the Random class in order to generate output that is independent of
other instances of NUnif.
User specifies the time at which the noise starts,
the duration of the noise,
and the interval at which new samples are drawn,
For fixed dt integration, interval must be > dt (ideally a whole multiple of dt).
Current varies linearly with time between samples.
Note that, with fixed dt, roundoff error may occasionally
cause slight jitter (+-dt) in the actual sample intervals.
This will be most noticeable if the sample interval is
only a small multiple of dt.
With adaptive integration, jitter will happen very rarely, if at all.
ENDCOMMENT
NEURON {
: POINT_PROCESS InUp : noisy current source, uniform distribution, piecewise linear in time
POINT_PROCESS InNp : noisy current source, normal distribution, piecewise linear in time
NONSPECIFIC_CURRENT i
RANGE delay, dur, per
: RANGE lo, hi
RANGE mean, stdev
RANGE genevent, y1
THREADSAFE : true only if every instance has its own distinct Random
POINTER donotuse
}
UNITS {
(nA) = (nanoamp)
(mA) = (milliamp)
}
PARAMETER {
delay (ms) : delayay until noise starts
dur (ms) <0, 1e9> : duration of noise
per = 0.1 (ms) <1e-9, 1e9> : period i.e. interval at which new random values are returned
: lo = 0 (nA)
: hi = 1 (nA)
mean = 0 (nA)
stdev = 1 (nA)
genevent = 0 (1) : if 1, generates an output event for each new value
: enables use of NetCon.record to execute hoc code
: e.g. to capture each new value just once
}
ASSIGNED {
on
ival (nA)
i (nA)
donotuse
t0 (ms)
y0 (nA)
y1 (nA)
}
INITIAL {
on = 0
ival = 0
i = 0
net_send(delay, 1)
}
PROCEDURE seed(x) {
set_seed(x)
}
BEFORE BREAKPOINT {
if (on==0) {
i = 0
} else {
i = y0 + ((t-t0)/per)*(y1 - y0)
}
}
BREAKPOINT {
: i = ival
}
FUNCTION yval() (nA) {
: yval = (hi-lo)*urand() + lo
yval = mean + nrand()*stdev : first sample
}
NET_RECEIVE (w) {
if (dur>0) {
if (flag==1) {
if (on==0) { : turn on
on=1
net_send(dur,1) : to turn it off
net_send(per, 2) : prepare for next sample
t0 = t
y0 = yval()
y1 = yval()
if (genevent==1) {
net_event(t) : to trigger recording of the new value
}
} else {
if (on==1) { : turn off
on=0
y0 = 0
y1 = 0
}
}
}
if (flag==2) {
if (on==1) {
net_send(per, 2) : prepare for next sample
t0 = t
y0 = y1
y1 = yval()
if (genevent==1) {
net_event(t) : to trigger recording of the new value
}
}
}
}
}
VERBATIM
#ifndef NRN_VERSION_GTEQ_8_2_0
double nrn_random_pick(void* r);
void* nrn_random_arg(int argpos);
#define RANDCAST
#else
#define RANDCAST (Rand*)
#endif
ENDVERBATIM
COMMENT
: FUNCTION erand() {
FUNCTION urand() {
VERBATIM
if (_p_donotuse) {
/*
: Supports separate independent but reproducible streams for
: each instance. However, the corresponding hoc Random
: distribution MUST be set to Random.uniform(0,1)
*/
// _lerand = nrn_random_pick(_p_donotuse);
_lurand = nrn_random_pick(_p_donotuse);
}else{
/* only can be used in main thread */
if (_nt != nrn_threads) {
hoc_execerror("multithread random in InUnif"," only via hoc Random");
}
ENDVERBATIM
: the old standby. Cannot use if reproducible parallel sim
: independent of nhost or which host this instance is on
: is desired, since each instance on this cpu draws from
: the same stream
: erand = exprand(1)
urand = scop_random()
VERBATIM
}
ENDVERBATIM
}
ENDCOMMENT
: FUNCTION erand() {
: FUNCTION urand() {
FUNCTION nrand() {
VERBATIM
if (_p_donotuse) {
/*
: Supports separate independent but reproducible streams for
: each instance. However, the corresponding hoc Random
: : distribution MUST be set to Random.uniform(0,1)
: distribution MUST be set to Random.normal(0,1)
*/
// _lerand = nrn_random_pick(_p_donotuse);
// _lurand = nrn_random_pick(_p_donotuse);
_lnrand = nrn_random_pick(RANDCAST _p_donotuse);
}else{
/* only can be used in main thread */
if (_nt != nrn_threads) {
hoc_execerror("multithread random in InUnif"," only via hoc Random");
}
ENDVERBATIM
: the old standby. Cannot use if reproducible parallel sim
: independent of nhost or which host this instance is on
: is desired, since each instance on this cpu draws from
: the same stream
: erand = exprand(1)
: urand = scop_random()
nrand = normrand(0,stdev/(1(nA)))
VERBATIM
}
ENDVERBATIM
}
PROCEDURE noiseFromRandom() {
VERBATIM
{
void** pv = (void**)(&_p_donotuse);
if (ifarg(1)) {
*pv = nrn_random_arg(1);
}else{
*pv = (void*)0;
}
}
ENDVERBATIM
}