Minimal refractory time

Description of problem

I am working on modeling electronic neurons. The firing rates we are working on are far higher than for modeling biological neurons (around 300kHz).
I want to add a noise throught the refractory time but I encounter a problem. It seems that there is a minimal value for the refractory time. However, I have not read any thing about it on any papers/research related to Brian2.

Minimal code to reproduce problem

from brian2 import *
from brian2 import clear_cache
from brian2 import device
device.reinit()
start_scope()

defaultclock.dt = 0.0001*us  # a tiny tiny value in order to show that it is not because of the defaultclock that the refractory time doesn't work under 0.5us


duration = 10*us
threshold = 10*mV
tau = 5*us
eqs = '''
dv/dt = (not_refractory)*(v0 - v) / tau : volt 
v0 : volt
'''
group1 = NeuronGroup(1, eqs, threshold='v > threshold ', reset='v = 0*mV',
                    refractory=0.6*us, method='heun')
group2 = NeuronGroup(1, eqs, threshold='v > threshold ', reset='v = 0*mV',
                    refractory=0.4*us, method='heun')
group1.v = 0*mV
group1.v0 = '18*mV '
group2.v = 0*mV
group2.v0 = '18*mV'

v_monitor1 = StateMonitor(group1, 'v', record=True)  
v_monitor2 = StateMonitor(group2, 'v', record=True)  

run(duration, report='text', report_period = 60*second)

plot(v_monitor2.t/us, v_monitor2.v[0]/mV,label="refrac < 0.5us")
plot(v_monitor1.t/us, v_monitor1.v[0]/mV,label="refrac > 0.5us")
plt.axhline(y=threshold/mV, color='r', linestyle='--',label='threshold')
xlabel('Time (us)')
ylabel('Voltage (mV)')
legend()
show()

What you have aready tried

Changing the defaultclock.dt

Expected output (if relevant)

A refractory time <0.5*us

Actual output (if relevant)

For a refractory time <= 0.5*us, their is no refractory at all.

refrac

Full traceback of error (if relevant)

Hi @YannaelB, sorry about the late reply, I was on vacation last week. This is indeed a bug in Brian, thanks for reporting it! By accident, one path of the code generation translated the given refractory period into a string, and implicitly assumed that the refractory period was not extremely small. It should be an easy fix, but until then there’s also a simple workaround: you can specify the refractory period as a quantity (as you did), or as a string. The bug I mentioned only applies to quantities, so you can declare it using a string instead:

group1 = NeuronGroup(1, eqs, threshold='v > threshold ', reset='v = 0*mV',
                    refractory="0.6*us", method='heun')
group2 = NeuronGroup(1, eqs, threshold='v > threshold ', reset='v = 0*mV',
                    refractory="0.4*us", method='heun')

This will make it work correctly:
Figure_1

1 Like

For reference, here’s the GitHub issue I just opened: (Very) small refractory values get lost in code generation · Issue #1521 · brian-team/brian2 · GitHub

Thank you very much for your help

I’ve just merged the fix into the main branch of our repository, if you want you can therefore install the development version as explained in our documentation to get the fix: Installation — Brian 2 2.6.0 documentation We will probably have a “proper” release fairly soon, though, so you might rather want to wait to update and use the workaround until then.

PS: Not that it matters any more, but the bug did not only lead to 0.4µs being interpreted as 0.0µs, but 0.6µs did not work correctly either – it was interpreted as 1µs :blush:

1 Like