Skip to content

Commit

Permalink
add ignore-and-fire neuron test
Browse files Browse the repository at this point in the history
  • Loading branch information
C.A.P. Linssen committed Jul 15, 2023
1 parent a5189c1 commit 977b5e1
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
53 changes: 53 additions & 0 deletions models/neurons/ignore_and_fire.nestml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
ignore_and_fire - Neuron generating spikes at fixed intervals irrespective of inputs
######################################################################################

Description
+++++++++++

The ``ignore_and_fire`` neuron is a neuron model generating spikes at a predefined ``firing_rate`` with a constant inter-spike interval ("fire"), irrespective of its inputs ("ignore"). In this simplest version of the ``ignore_and_fire`` neuron, the inputs from other neurons or devices are not processed at all (*). The ``ignore_and_fire`` neuron is primarily used for neuronal-network model verification and validation purposes, in particular, to evaluate the correctness and performance of connectivity generation and inter-neuron communication. It permits an easy scaling of the network size and/or connectivity without affecting the output spike statistics. The amount of network traffic is predefined by the user, and therefore fully controllable and predictable, irrespective of the network size and structure.

To create asynchronous activity for a population of ``ignore_and_fire`` neurons, the firing ``phase``s can be randomly initialised. Note that the firing ``phase`` is a real number, defined as the time to the next spike relative to the firing period.

(*) The model can easily be extended and equipped with any arbitrary input processing (such as calculating input currents with alpha-function shaped PSC kernels or updating the gating variables in the Hodgkin-Huxley model) or (after-) spike generation dynamics to make it more similar and comparable to other non-ignorant neuron models. In such extended ignore_and_fire models, the spike emission process would still be decoupled from the intrinsic neuron dynamics.

Authors
+++++++

Tetzlaff (February 2021; January 2022)

"""

neuron ignore_and_fire:

state:
phase real = 1. ## relative time to next spike (in (0,1])

parameters:
firing_rate Bq = 10. Bq ## firing rate

internals:
firing_period_steps integer = steps( 1. / firing_rate ) ## firing period in steps
phase_steps integer = steps( max(0.,phase) / firing_rate ) ## firing phase in steps

input:
spikes Bq <- spike ## the neuron receives spikes, but is not processing them

output:
spike

update:
integrate_odes()
if phase_steps == 0:
emit_spike()
phase_steps = firing_period_steps - 1
#println("spike")
else:
phase_steps -= 1

phase = 1. * phase_steps / firing_period_steps

#println(" ")
#println("firing_period_steps={firing_period_steps}")
#println("phase_steps={phase_steps}")
#println("phase={phase}")
2 changes: 1 addition & 1 deletion pynestml/codegeneration/nest_code_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def analyse_neuron(self, neuron: ASTNeuron) -> Tuple[Dict[str, ASTAssignment], D
self.non_equations_state_variables[neuron.get_name()].extend(
ASTUtils.all_variables_defined_in_block(neuron.get_state_blocks()))

return [], [], [], []
return {}, {}, [], []

if len(neuron.get_equations_blocks()) > 1:
raise Exception("Only one equations block per model supported for now")
Expand Down
3 changes: 3 additions & 0 deletions pynestml/transformers/synapse_post_neuron_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ def transform_neuron_synapse_pair_(self, neuron, synapse):
new_neuron = neuron.clone()
new_synapse = synapse.clone()

new_neuron.accept(ASTSymbolTableVisitor())
new_synapse.accept(ASTSymbolTableVisitor())

assert len(new_neuron.get_equations_blocks()) <= 1, "Only one equations block per neuron supported for now."
assert len(new_synapse.get_equations_blocks()) <= 1, "Only one equations block per synapse supported for now."
assert len(new_neuron.get_state_blocks()) <= 1, "Only one state block supported per neuron for now."
Expand Down
77 changes: 77 additions & 0 deletions tests/nest_tests/test_ignore_and_fire.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
#
# test_ignore_and_fire.py
#
# This file is part of NEST.
#
# Copyright (C) 2004 The NEST Initiative
#
# NEST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# NEST is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NEST. If not, see <http://www.gnu.org/licenses/>.

import numpy as np
import os
import pytest

import nest

from pynestml.frontend.pynestml_frontend import generate_nest_target

try:
import matplotlib
matplotlib.use("Agg")
import matplotlib.ticker
import matplotlib.pyplot as plt
TEST_PLOTS = True
except Exception:
TEST_PLOTS = False


class TestIgnoreAndFire:

neuron_model_name = "ignore_and_fire_nestml__with_stdp_nestml"
synapse_model_name = "stdp_nestml__with_ignore_and_fire_nestml"

@pytest.fixture(scope="module", autouse=True)
def setUp(self):
"""Generate the model code"""

codegen_opts = {"neuron_synapse_pairs": [{"neuron": "ignore_and_fire",
"synapse": "stdp",
"post_ports": ["post_spikes"]}]}

files = [os.path.join("models", "neurons", "ignore_and_fire.nestml"),
os.path.join("models", "synapses", "stdp_synapse.nestml")]
input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(
os.pardir, os.pardir, s))) for s in files]
generate_nest_target(input_path=input_path,
logging_level="DEBUG",
suffix="_nestml",
codegen_opts=codegen_opts)

def test_ignore_and_fire_with_stdp(self):
pre_spike_times = [10., 40., 50.]
resolution = 1. # [ms]
sim_time = 100. # [ms]

nest.set_verbosity("M_ALL")
nest.Install("nestmlmodule")
nest.ResetKernel()
nest.SetKernelStatus({"resolution": resolution})

pre_neuron = nest.Create(self.neuron_model_name)
post_neuron = nest.Create(self.neuron_model_name)

nest.Connect(pre_neuron, post_neuron, syn_spec={"synapse_model": self.synapse_model_name})

nest.Simulate(sim_time)

0 comments on commit 977b5e1

Please sign in to comment.