# Injecting current spike in LIF neurons

**URL:** <https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936>\
**Category:** Support\
**Created:** [16 March 2023 09:41 UTC](https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936 "2023-03-16T09:41:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![JFRWKievits](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/jfrwkievits/32/503_2.png) [@JFRWKievits](https://brian.discourse.group/u/JFRWKievits)\
**Post date:** [16 March 2023 09:41 UTC](https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936/1 "2023-03-16T09:41:35Z")

</div>

Hi everyone!

I’m fairly new to Brian so I hope I’m posting this correctly. Please let me know if that’s not the case!

I’m simulating a basic network _N_ of _n_ neurons that are not connected to each other. The neurons are LIF and are set to fire using a bias current _i\_offset_ . I’m trying to simulate events that cause a sudden spike in the bias current to a random neuron in the network. To do so I’ve tried making a network operation that takes the _i\_offset_ of a certain neuron and adds a spike to it using a function of t:

```auto
 @network_operation(dt=500 * ms)
  def event():
        neuron = np.random.randint(low=0, high=n, dtype=int)
        i_offset_neuron = N.i_offset[neuron]
        base_i_offset = i_offset_neuron
        new_i_offset = 'base_i_offset + (10 / (1 + 1000 * t / second)) * nA'
        N.i_offset[neuron] = new_i_offset

```

The code does run but I don’t see any change in spiking behavior of the neuron (in either spike or statemonitor). Can anyone point out why this isn’t working as intended?  
The goal would be to have a spike added to the existing _i\_offset_. Also, I want to be able to quickly change the width and height of the spike (therefore I’m not using dirac delta functions).

Best,

Joris

---

<div class="post-metadata">

**Author:** ![mstimberg](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/mstimberg/32/11_2.png) [@mstimberg](https://brian.discourse.group/u/mstimberg)\
**Post date:** [16 March 2023 09:56 UTC](https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936/2 "2023-03-16T09:56:01Z")

</div>

Hi @JFRWKievits and welcome to the Brian forum 👋 . Could you please also post the definition of your `NeuronGroup` to see how `i_offset` is applied? Thanks!

---

<div class="post-metadata">

**Author:** ![JFRWKievits](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/jfrwkievits/32/503_2.png) [@JFRWKievits](https://brian.discourse.group/u/JFRWKievits)\
**Post date:** [16 March 2023 10:09 UTC](https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936/3 "2023-03-16T10:09:21Z")

</div>

Hi @mstimberg !

Of course!  
Here are the equations and Network setup. The gaussian function just provides a list of len(N) with normally distributed values around some ideal parameter value.

```auto
   eqs = """
    R : ohm
    i_offset : amp
    tau : second
    Vr : volt
    Vt : volt
    dv/dt = (R*i_offset-v)/tau : volt (unless refractory)
    """

    # The neurons with threshold voltage, reset voltage and refractoriness
    N = NeuronGroup(n, eqs, threshold='v > Vt', reset='v = Vr', refractory=t_ref, method='euler', name='neurons')
    N.Vr = gaussian(Vr_ideal, Vr_ideal * f, len(N))
    N.Vt = gaussian(Vt_ideal, Vt_ideal * f, len(N))
    N.tau = gaussian(tau_ideal, tau_ideal * f, len(N))
    N.R = N.tau / capacitance
    N.i_offset = 20 * nA

```

I hope this helps!

---

<div class="post-metadata">

**Author:** ![mstimberg](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/mstimberg/32/11_2.png) [@mstimberg](https://brian.discourse.group/u/mstimberg)\
**Post date:** [17 March 2023 13:09 UTC](https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936/4 "2023-03-17T13:09:00Z")

</div>

Hi again. So I hope I understand correctly what you want to do: every 500ms, you want to randomly select a neuron and have it’s `i_offset` current jump and then decay as an inverse of time, correct?

In your current `network_operation`, you assign to `N.i_offset`. An assignment to a variable sets its current value. In your case this is a string referring to time `t`, but this string will be _evaluated once_ when you do the assignment. According to your model equations, `i_offset` is a parameter, not a dynamical variable, so its value will not change after that assignment. Also, note that `t` refers to the time since the start of the simulation, so at `t=500*ms`, you’ll increase your `i_offset`only by 0.02nA.

There are several ways you can implement a dynamically decaying current spike. The easiest is to have it decay exponentially by defining it as a differential equation that decays back to the base value with time constant `tau_i` (changing this time constant allows you to change the width of the spike).

```auto
tau_i = 2*ms
base_i_offset = 20*nA
eqs = """
  R : ohm
  di_offset/dtau_i = (base_i_offset - i_offset)/tau_i : amp
  tau : second
  Vr : volt
  Vt : volt
  dv/dt = (R*i_offset-v)/tau : volt (unless refractory)
  """

# The neurons with threshold voltage, reset voltage and refractoriness
N = NeuronGroup(n, eqs, threshold='v > Vt', reset='v = Vr', refractory=t_ref, 
                method='euler', name='neurons')

```

You can then make the `i_offset` value jump up every 500ms. You could do this via a `network_operation`, but it might be more straightforward to pre-generate the indices of the neurons that should receive this spike, i.e. something like this:

```auto
n_spikes = 10
spike_trigger = SpikeGeneratorGroup(n, np.random.randint(n, size=n_spikes), 500*ms*(np.arange(n_spikes) + 1)
trigger = Synapses(spike_trigger, N, on_pre='i_offset += 10*nA')

```

If it is important to have an \frac{1}{1 + \alpha t} shape of the current, then you can put it directly into the definition of the current:

```auto
base_i_offset = 20*nA
eqs = """
  R : ohm
  i_offset = base_i_offset + (10 / (1 + 1000 * (t - last_injection) / second)) * nA : amp
  last_injection : second # time of the last current injection for this neuron
  tau : second
  Vr : volt
  Vt : volt
  dv/dt = (R*i_offset-v)/tau : volt (unless refractory)
  """
N = ...
N.last_injection = -1e9*second

```

Now, instead of directly increasing the current each time, you’ll just update the `last_injection` time:

```auto
spike_trigger = SpikeGeneratorGroup(...)
trigger = Synapses(spike_trigger, N, on_pre='last_injection = t')

```

I hope this all makes sense and I did not misunderstand what you are trying to do!

---

<div class="post-metadata">

**Author:** ![JFRWKievits](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/jfrwkievits/32/503_2.png) [@JFRWKievits](https://brian.discourse.group/u/JFRWKievits)\
**Post date:** [21 March 2023 12:07 UTC](https://brian.discourse.group/t/injecting-current-spike-in-lif-neurons/936/5 "2023-03-21T12:07:32Z")

</div>

@mstimberg this is fantastic, thank you so much!

I have implemented it as a ` network_operation` and it works beautifully.

Best,

Joris
