COMMENT
NetStimG() is based on NetStim() but has a Gaussian stochastic interval. The Poisson noise capability is 
retained. New parametrs are MeanInterval and SD (standard deviation) which control the interval
Mike Sikora July,2006
Added-The Start time is also Gaussian randomized vars MeanStart + StartSD
ENDCOMMENT

NEURON	{ 
  ARTIFICIAL_CELL NetStimG
  RANGE interval, number, MeanStart, StartSD
  RANGE noise,MeanInterval,SD
}

PARAMETER {
        MeanInterval = 10 (ms)
        SD = 0.5 (ms)
        MeanStart = 50 (ms) : Start of 1st spike
        StartSD = 1 : Standard deviation of 1st spike
	number	= 10 <0,1e9>	: number of spikes (independent of noise)
	noise		= 0 <0,1>	: amount of randomness (0.0 - 1.0)
}

ASSIGNED {
	event (ms)
	on
	ispike
	interval
}

PROCEDURE seed(x) {
	set_seed(x)
}

INITIAL {
        interval = normrand(MeanInterval,SD)
	on = 0
	ispike = 0
	if (noise < 0) {
		noise = 0
	}
	if (noise > 1) {
		noise = 1
	}
	if (number > 0) {
		: allowing MeanStart to be <0
		event = normrand(MeanStart,StartSD)
		: 
		if (event < 0) {
			event = 0
		}
		net_send(event, 3)
	}
}	

PROCEDURE init_sequence(t(ms)) {
	if (number > 0) {
		on = 1
		event = 0
		ispike = 0
	}
}

FUNCTION invl(mean (ms)) (ms) {
	if (mean <= 0.) {
		mean = .01 (ms) : I would worry if it were 0.
	}
	if (noise == 0) {
		invl = mean
	}else{
		invl = (1. - noise)*mean + noise*mean*exprand(1)
	}
}

PROCEDURE next_invl() {
	if (number > 0) {
                interval=normrand(MeanInterval,SD)
		event = invl(interval)
	}
	if (ispike >= number) {
		on = 0
	}
}

NET_RECEIVE (w) {
	if (flag == 0) { : external event
		if (w > 0 && on == 0) { : turn on spike sequence
			init_sequence(t)
			: randomize the first spike so on average it occurs at
			: noise*interval (most likely interval is always 0)
			next_invl()
			event = event - interval*(1. - noise)
			net_send(event, 1)
		}else if (w < 0 && on == 1) { : turn off spiking
			on = 0
		}
	}
	if (flag == 3) { : from INITIAL
		if (on == 0) {
			init_sequence(t)
			net_send(0, 1)
		}
	}
	if (flag == 1 && on == 1) {
		ispike = ispike + 1
		net_event(t)
		next_invl()
		if (on == 1) {
			net_send(event, 1)
		}
	}
}