Modeling an external input voltage to the circuit?

Hi there!

Say I have a circuit, not unlike the following:

import numpy as np
from brian2 import Synapses, NeuronGroup, ms, mV, Hz, SpikeMonitor, Network, PoissonInput

params = {
    'v_0'       : -52 * mV,               # resting potential
    'v_rst'     : -52 * mV,               # reset potential after spike
    'v_th'      : -45 * mV,               # threshold for spiking
    't_mbr'     :  20 * ms,               # membrane time scale (capacitance * resistance = .002 * uF * 10. * Mohm)
    't_rfc'     : 2.2 * ms,
    'tau'       : 5 * ms,                 # time constant
    'r_poi'     : 150 * Hz,
    'f_poi'     : 250,
    'w_syn'     :0.275 * mV,
    "t_run": 1000 * ms,  # duration of trial
}

if __name__ == '__main__':
    connectivity_matrix = np.asarray([
        [0, 5, 0],
        [0, 0, -2],
        [0, 0, 0],
    ])
    eqs = '''
    dv/dt = (v_0 - v + g) / t_mbr : volt (unless refractory)
    dg/dt = -g / tau               : volt (unless refractory) 
    rfc                            : second
    '''

    neu = NeuronGroup(  # create neurons
        N=len(connectivity_matrix),
        model=eqs,
        method='linear',
        threshold='v > v_th',
        reset='v = v_rst; w = 0; g = 0 * mV',
        refractory='rfc',
        name='default_neurons',
        namespace=params
    )
    neu.v =-52 * mV
    neu.g = 0
    neu.rfc = 2.2 * ms

    sources, targets = connectivity_matrix.nonzero()
    syn = Synapses(neu, neu, 'w : volt', on_pre='g += w', delay=1.8 * ms, name='default_synapses')
    syn.connect(i=sources, j=targets)

    weight_per_synapse = 0.5*mV
    syn.w[:] = connectivity_matrix[(sources, targets)] * weight_per_synapse

    spike_monitor = SpikeMonitor(neu)
    net = Network(neu, syn, spike_monitor, *p_groups)
    net.run(duration=params['t_run'], report="stdout")
    print(spike_monitor.spike_trains().values())

As I understand it, without an Input Stimuli, the neural circuit will still fire over time and all that, based on the equations I put in (yes?). I’m basing this conclusion after reading through a few of the examples, like the IF_curve_Hodgkin_Huxley example. That’s great, if true. However, say I want to simulate what happens to the circuit if I were to apply an external voltage to some (or all) of the neurons, and to see how it affects the dynamics of the system? Sort of if I connected a battery to some neurons in a circuit?

From the documentation in the Input Stimuli page, I see

You can also generate an explicit list of spikes given via arrays using [SpikeGeneratorGroup]This object behaves just like a [NeuronGroup] in that you can connect it to other groups via a [Synapses] object, but you specify three bits of information: N the number of neurons in the group; indices an array of the indices of the neurons that will fire; and times an array of the same length as indices with the times that the neurons will fire a spike. The indices and times arrays are matching, so for example indices=[0,2,1] and times=[1*ms,2*ms,3*ms] means that neuron 0 fires at time 1 ms, neuron 2 fires at 2 ms and neuron 1 fires at 3 ms. Example use:

but that gives me the impression that I am connecting other neurons to the one of interest and simulating their firing times? Is that correct? Could it still be applicable for my use-case? I’m not a neuroscientist, so Ive got a lot of questions (as I’m sure you can see) Is N the number of neurons in my circuit, or the number of neurons that I’d like to be firing throughout the process?

Hi @itq. Injecting an external current into a neuron with an electrode is actually something that is done quite commonly in experiments (the technical term is “current clamp”). To inject such a current, you include it in the equations. This is what is done in the HH model you linked to:

# The model
eqs = Equations('''
dv/dt = (gl*(El-v) - g_na*(m*m*m)*h*(v-ENa) - g_kd*(n*n*n*n)*(v-EK) + I)/Cm : volt
# ...
I : amp
''')
group = NeuronGroup(...)
group.v = El
group.I = '0.7*nA * i / num_neurons'

The I is an injected current that is set to a value between 0 and 0.7nA, linearly spaced based on the index i of each neuron.

Now, your model is formulated slightly differently for simplicity, basically things are divided by gl from the HH equations. In your case, you’d therefore indeed “add a constant voltage” to the neuron, which physics-wise is a bit odd to say, but it’ll do :slight_smile:

You can either do:

    v_ext = 1*mV  # external input
    eqs = '''
    dv/dt = (v_0 - v + g + v_ext) / t_mbr : volt (unless refractory)
    dg/dt = -g / tau               : volt (unless refractory) 
    rfc                            : second
    '''

for the same input to all neurons, or:

    eqs = '''
    dv/dt = (v_0 - v + g + v_ext) / t_mbr : volt (unless refractory)
    dg/dt = -g / tau               : volt (unless refractory) 
    rfc                            : second
    v_ext                          : volt (constant)
    '''
    ...
    neu.v_ext = ... # one value for each neuron

to have a different input into each neuron.

Hope that helps!