Page 1 of 1

### Adding white nose to current injection

Posted: Mon Sep 27, 2010 6:21 pm
Dear all,

I am trying to model an external current input with white Gaussian noise, i.e., I = f(t) + D*n(t), where f(t) is a given deterministic function and n(t) represents white Gaussian noise with standard deviation D. I did a search in the forum and found the function normrand(). Here is my code:

Code: Select all

``````NEURON {
POINT_PROCESS IClampNoise
RANGE i,del,dur,f0,f1,r,torn,std,bias
ELECTRODE_CURRENT i
}

UNITS {
(nA) = (nanoamp)
}

PARAMETER {
del=50    (ms)
dur=200   (ms)
torn=500  (ms)
std=0.2   (nA)
f0=0.2    (nA)
f1=0.8    (nA)
r =60
bias = 0 (nA)
}

ASSIGNED {
i (nA)
amp (nA)
noise (nA)
}

BREAKPOINT {
at_time(del)
at_time(del + dur)

if (t < del) {
i=0
} else{
if (t < del+dur) {
noise = normrand(0,std)
amp = f0 + 0.5*(f1-f0)*(tanh((t-torn)/(r/3)-3)+1)
i = amp + noise + bias
}else{
i = 0
}
}
}
``````

It seems the code can produce the noisy input. However, the neuron voltage became unstable with this input (goes to very large negative value) and the following warning message appears in the hoc screen: exp(826.416) out of range, returning exp(700). To see whether the white noise causes instability, I set the parameter std to 0 (no noise is produced by NMODL) and generated noise in the hoc file like this:

Code: Select all

``````objref r
r = new Random()
r.normal(0,d^2)

var = r.repick()
Stim2.bias = var
}``````
And the neuron now responds normally to the noisy input. So I reasoned the way I modeled the white noise with normrand() was not correct in the NMODL. I looked over some similar postings in the forum, but haven't found a good and direct answer to my problem, though I guess it should be pretty simple. Please advise and thank you very much in advance!

Sincerely,
Guoshi Li

### Re: Adding white nose to current injection

Posted: Wed Sep 29, 2010 10:36 am
You're probably just seeing the effect of normrand returning the occasional very large negative or positive result. That's the nature of the normal distribution. The error message suggests that your model contains a gating variable that is an exponential function of membrane potential, which is gagging on an unrealistically large value of membrane potential. To test these speculations, you could examine the time course of membrane potential and the current delivered by your IClampNoise object(s).

### Re: Adding white nose to current injection

Posted: Wed Sep 29, 2010 10:50 am
I take it back. Attaching an instance of IClampNoise to a single compartment model with passive membrane properties and running several simulations, I see several instances in which v jumps abruptly by tens or hundreds of mV, in the absence of anything in IClampNoise.i that could account for the jump. This is with
NEURON -- VERSION 7.2 (436:cbc0331180f8) 2010-04-05

### Re: Adding white noise to current injection

Posted: Wed Sep 29, 2010 12:17 pm
Hi, Ted,

Thank you very much for your help. I guess this is probably due to the incorrect use of the function normrand( ) in NMODL. If I don't use normrand(), are there any other functions to use to generate white noise in NMODL? How can I find out those functions and their usage? Do I need to write C code to implement this?

Thanks again!
GL

### Re: Adding white nose to current injection

Posted: Wed Sep 29, 2010 12:20 pm
Michael Hines pointed out the source of the problem: calling a random number generator in a BREAKPOINT block. The BREAKPOINT block is executed twice on each time step, with slightly different values of v, in order to calculate the derivative di/dv (conductance of the point process). Calling normrand twice causes large random changes in the numerator of the di/dv calculation, which means the current source no longer has a conductance of 0 but instead has a (potentially very large) fluctuating conductance.

The solution is to use a BEFORE BREAKPOINT block to calcuate the value that is to be assigned to i. But the BREAKPOINT block must still exist, to make sure that the value of i will actually be updated on each call to fadvance().

So here's the revised mod file, which should work properly (at least it does in my tests):

Code: Select all

``````NEURON {
POINT_PROCESS IClampNoise
RANGE i,del,dur,f0,f1,r,torn,std,bias
ELECTRODE_CURRENT i
}

UNITS {
(nA) = (nanoamp)
}

PARAMETER {
del=50    (ms)
dur=200   (ms)
torn=500  (ms)
std=0.2   (nA)
f0=0.2    (nA)
f1=0.8    (nA)
r =60
bias = 0 (nA)
}

ASSIGNED {
ival (nA)
i (nA)
amp (nA)
noise (nA)
on (1)
}

INITIAL {
i = 0
on = 0
net_send(del, 1)
}

PROCEDURE seed(x) {
set_seed(x)
}

BEFORE BREAKPOINT {
if  (on) {
noise = normrand(0,std*1(/nA))*1(nA)
amp = f0 + 0.5*(f1-f0)*(tanh((t-torn)/(r/3)/(1(ms))-3)+1)
ival = amp + noise + bias
} else {
ival = 0
}
}

BREAKPOINT {
i = ival
}

if (flag == 1) {
if (on == 0) {
: turn it on
on = 1
: prepare to turn it off
net_send(dur, 1)
} else {
: turn it off
on = 0
}
}
}``````

Instead of using the long-deprecated at_time(), this implementation employs a simple state machine (which uses NEURON's event delivery system) to control turning the current on and off. The value of "on" denotes whether the current source is or isn't delivering a current. In a simulation, fadvance() is called once per time step. At each call to fadvance(), if "on" is 1, i is assigned a value that depends on a single new evaluation of normrand; otherwise, is assigned a value of 0. The actual calculation of the new value of i is done in the BEFORE BREAKPOINT block (which is called once per fadvance()), and the value is stored in the intermediate variable ival. The actual assignment of the new value to i is done in the BREAKPOINT block (which is called twice per fadvance()).

The INITIAL block sets i to 0, and also sets up the state machine by assgning 0 to "on" and launching a self-event that will return after a delay of "del" ms (i.e. at time t = current time + del = del). The self-event is associated with a "flag" value of 1, so that the NET_RECEIVE block can test any events it receives and verify that the event is a self-event.

When this self-event arrives, the first part of the conditional statement inside the NET_RECEIVE block sets "on" to 1 and launches a second self-event that will return after a delay of "dur" ms. Arrival of this second self-event causes execution of the second part of the conditional, which swithces "on" back to 0, terminating the injected current.

A final note: this implementation contains PROCEDURE seed(), which should be called from hoc during initialization (e.g. by an FInitializeHandler) to specify the seed used by the random number generator. Otherwise successive runs will produce different results even though no parameters have been changed.

### Re: Adding white noise to current injection

Posted: Wed Sep 29, 2010 1:22 pm
Hi, Ted,

The revised mod file works in my model! Thank you and Michael Hines for solving this problem! The use of the NEURON's event delivery system to control the on and off of the current injection is really ingenious!

Best,
GL

### Re: Adding white nose to current injection

Posted: Wed Sep 29, 2010 1:27 pm
Good to hear it's working. The event delivery system offers many powerful and flexible ways to implement models and complex experimental/simulation protocols.

Thanks for using NEURON. If you publish anything that reports work done with NEURON, please be sure to cite it
How to cite NEURON
viewtopic.php?f=22&t=73
and also let me know so I can add your paper to NEURON's bibliography
http://www.neuron.yale.edu/neuron/stati ... ednrn.html

### Re: Adding white nose to current injection

Posted: Wed Sep 29, 2010 1:29 pm
Sure I will.

### Re: Adding white nose to current injection

Posted: Fri Aug 15, 2014 5:31 pm
Hi there
I have attempt to add a noisy conductance based synapse to my cell.
this the nmodl code

Code: Select all

``````
NEURON {
POINT_PROCESS Alpha2SynNoise
RANGE tau1, tau2, e, i, mean, stddev, del, dur
NONSPECIFIC_CURRENT i

RANGE g
}

UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(uS) = (microsiemens)
}

PARAMETER {
tau1=.1 (ms) <1e-9,1e9>
tau2 = 10 (ms) <1e-9,1e9>
e=0	(mV)
del=0    (ms)
dur=0    (ms)
mean=1
stddev=0.2
}

ASSIGNED {
v (mV)
i (nA)
g (uS)
factor
gnoise
on (1)
}

STATE {
A (uS)
B (uS)
}

INITIAL {
LOCAL tp
if (tau1/tau2 > .9999) {
tau1 = .9999*tau2
}
A = 0
B = 0
tp = (tau1*tau2)/(tau2 - tau1) * log(tau2/tau1)
factor = -exp(-tp/tau1) + exp(-tp/tau2)
factor = 1/factor

on = 0
net_send(del, 1)
}

PROCEDURE seed(x) {
set_seed(x)
}

BEFORE BREAKPOINT {
if  (on) {
gnoise = normrand(mean, stddev)
} else {
gnoise = 0
}
}

BREAKPOINT {
SOLVE state METHOD cnexp
g = (B - A)*gnoise
i = g*(v - e)
}

DERIVATIVE state {
A' = -A/tau1
B' = -B/tau2
}

A = A + weight*factor
B = B + weight*factor

if (flag == 1) {
if (on == 0) {
: turn it on
on = 1
: prepare to turn it off
net_send(dur, 1)
} else {
: turn it off
on = 0
}
}
}

``````
but I can not figure out the errors:(
nrniv: Segmentation violation

### Re: Adding white nose to current injection

Posted: Fri Aug 15, 2014 10:20 pm
The problem was from

Code: Select all

``````on = 0
net_send(del, 1)
``````
I just change it to

Code: Select all

``````on = 1
``````
and every thing gets fine!
but I can not understand why?!

### Re: Adding white nose to current injection

Posted: Tue Feb 26, 2019 9:18 am
Hi,
I would like to modify the IClampnoise in order to tune the frequency of the input signal

I would like to have something similar to the current generated by a sinusoidal function as

i= constantAmp*cos(2*pi*(t-del)*freq*(0.001))

where I can tune freq.

How can I change the amp=f0+0.5(f1-f0)(tanh((t-torn)/(r/3)-3)+1) expression in order to change the frequency of the signal?

Can you please explain the meaning of the torn and r terms?
Maybe tuning f0 and f1 can be a way to explore a frequency range?

Best
Menica