Having problem on set external current input

I wanna make simulation about external hyperpolarization current.

Main intention for this code is making hyperpolarization current on subpopulation of inhibitory neurons.

Minimal code to reproduce problem

from brian2 import *
import numpy as np
import random
import math
import multiprocessing
import time

'''inhibitory neuron'''

Cm = 1 * uF  # /cm**2

EL = -65 * mV
ENa = 55 * mV
EK = -90 * mV
gNa = 100 * msiemens
gK = 40 * msiemens

'''synapse decay time constant'''

t_ampa = 2 * ms
t_gaba = 4 * ms
t_gaba_sst = 12 * ms
t_gaba_ngfc = 20 * ms

eqs = '''
            dv/dt = (-gNa*m**3*h*(v-ENa) -gK*n**4*(v-EK) -gL*(v-EL) - gKZ*z*(v-EK)- I_ext) / Cm : volt 

            I_ext = g_ampa*(v-V_AMPA) + g_gaba*(v-V_GABA) + g_gaba_sst*(v-V_GABA) + I_photo: amp
            I_photo:amp
            dg_ampa/dt = -g_ampa/ t_ampa : siemens
            dg_gaba/dt = -g_gaba/ t_gaba : siemens
            dg_gaba_sst/dt = -g_gaba_sst/ t_gaba_sst : siemens
            dg_gaba_ngfc/dt = -g_gaba_ngfc/ t_gaba_ngfc : siemens
            m = alpham/(alpham+betam) : 1
            alpham = -0.1/mV*(v+30*mV)/(exp(-0.1/mV*(v+30*mV))-1)/ms : Hz
            betam = 4*exp(-(v+55*mV)/(18*mV))/ms : Hz
            dh/dt = 0.2*(alphah*(1-h)-betah*h) : 1
            alphah = 0.7*exp(-(v+44*mV)/(20*mV))/ms : Hz
            betah = 10/(exp(-0.1/mV*(v+28*mV))+1)/ms : Hz
            dn/dt = 0.2*(alphan*(1-n)-betan*n) : 1
            alphan = -0.1/mV*(v+34*mV)/(exp(-0.1/mV*(v+34*mV))-1)/ms : Hz
            betan = 1.25*exp(-(v+44*mV)/(80*mV))/ms : Hz
            dz/dt = (z_inf - z)/(60*ms) : 1
            z_inf = 1/(1+exp(-0.7*((v/(1 * mV) + 30)))) : 1
    '''



L_4_i = NeuronGroup(150, eqs, threshold='v>-48.8*mV', refractory='v>-48.8*mV', method='rk4')

L_4_i.namespace['gL'] = 0.1 * msiemens
L_4_i.namespace['gKZ'] = 0 * msiemens

for i in range(150):
    trans_ratio=0.5
    if(i < 150 * trans_ratio):
        L_4_i.namespace['I_photo'][i]= (-3.0  + 2.0 * random.random()) * 10**(-3) * mA
    else:
        L_4_i.namespace['I_photo'][i]= 0 *10**(-3) * mA

L_4_i.v = EL
L_4_i.h = 1

''' excitatory neuron '''

L_4_e = NeuronGroup(1600, eqs, threshold='v>-39.7*mV', refractory='v>-39.7*mV', method='rk4')

L_4_e.namespace['gL'] = 0.1 * msiemens
L_4_e.namespace['gKZ'] = 0.5 * msiemens

L_4_e.v = EL
L_4_e.h = 1

The error occurs :

ERROR      Brian 2 encountered an unexpected error. If you think this is a bug in Brian 2, please report this issue either to the discourse forum at <http://brian.discourse.group/>, or to the issue tracker at <https://github.com/brian-team/brian2/issues>. Please include this file with debug information in your report: C:\Users\omokn\AppData\Local\Temp\brian_debug_98mx2ghb.log  Additionally, you can also include a copy of the script that was run, available at: C:\Users\omokn\AppData\Local\Temp\brian_script_kkqmaob1.py Thanks! [brian2]
Traceback (most recent call last):
  File "C:\Users\omokn\OneDrive\바탕 화면\project\exp_trash.py", line 57, in <module>
    L_4_i.namespace['I_photo'][i]= (-3.0  + 2.0 * random.random()) * 10**(-3) * mA
    ~~~~~~~~~~~~~~~^^^^^^^^^^^
KeyError: 'I_photo'

I think I make several mistakes on handling namespace of neuron population. How can I fix these problem?

Hi @Bolloknoon. This use of the namespace is indeed not quite correct. You can use the namespace to set external scalar constants – you’d typically specify this as the namespace argument to NeuronGroup, but your approach should work as well. Note that you can also replace values directly in the equations (basically doing string replacement for you), e.g. with ... NeuronGroup(150, Equations(eqs, gL=0.1*mS, gKZ=0*mS), ...).

The situation for I_photo is different, because it is not a scalar constant, but a vector. Since you have – correctly – added I_photo to your equations, you should assign to it with L_4_i.I_photo = … directly, instead of using the namespace.
Note that in general it is more efficient to not use a loop but instead assign a single array. In your case, you could either use numpy’s array operations, or Brian’s builtin language – both should give the same result here:

# Using a numpy array
L_4_i.I_photo[:int(150*trans_ratio)]  =  (-3.0  + 2.0 * np.random.rand(int(150*trans_ratio))) * uA

A bit more compact using Brian’s own language:

L_4_i.I_photo['i<150*trans_ratio'] = '(-3.0  + 2.0 * rand()) * uA'
1 Like

I recognized right a minute before answer but I don’t exactly know why. Thanks for detailed explanation!

I self-solved this problem as:

    for i in range(150):
        if i < (150*trans_ratio):
            L_4_i.I_photo[i] = (-3.0  + 2.0 * random.random()) * 10**(-3) * mA
        else:
            L_4_i.I_photo[i] = 0 * mA

But your code make this more compact than I thought.

1 Like