Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ignore-and-fire neuron test #934

Merged
merged 6 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions doc/models_library/ignore_and_fire.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
ignore_and_fire
###############


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)




Parameters
++++++++++
.. csv-table::
:header: "Name", "Physical unit", "Default value", "Description"
:widths: auto


"firing_rate", "Bq", "10.0Bq", "# firing rate"



State variables
+++++++++++++++

.. csv-table::
:header: "Name", "Physical unit", "Default value", "Description"
:widths: auto


"phase", "real", "1.0", "# relative time to next spike (in (0,1])"




Equations
+++++++++





Source code
+++++++++++

The model source code can be found in the NESTML models repository here: `ignore_and_fire <https://github.com/nest/nestml/tree/master/models/neurons/ignore_and_fire.nestml>`_.

Characterisation
++++++++++++++++

.. include:: ignore_and_fire_characterisation.rst


.. footer::

Generated at 2023-08-08 15:01:40.284515
9 changes: 9 additions & 0 deletions doc/models_library/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,15 @@ Wang-Buzsaki model with multiple synapses

Source file: `wb_cond_multisyn.nestml <https://www.github.com/nest/nestml/blob/master/models/neurons/wb_cond_multisyn.nestml>`_


:doc:`ignore_and_fire <ignore_and_fire>`
------------------------------------

Neuron generating spikes at fixed intervals irrespective of inputs

Source file: `ignore_and_fire.nestml <https://www.github.com/nest/nestml/blob/master/models/neurons/ignore_and_fire.nestml>`_


Synapse models
~~~~~~~~~~~~~~

Expand Down
48 changes: 48 additions & 0 deletions models/neurons/ignore_and_fire.nestml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
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.
pnbabu marked this conversation as resolved.
Show resolved Hide resolved

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
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 @@ -224,6 +224,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
88 changes: 88 additions & 0 deletions tests/nest_tests/test_ignore_and_fire.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -*- 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):
resolution = 1. # [ms]
sim_time = 1001. # [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)
pre_neuron.firing_rate = 10.
post_neuron.firing_rate = 100.
pre_sr = nest.Create("spike_recorder")
post_sr = nest.Create("spike_recorder")
nest.Connect(pre_neuron, pre_sr)
nest.Connect(post_neuron, post_sr)

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

nest.Simulate(sim_time)
pnbabu marked this conversation as resolved.
Show resolved Hide resolved

n_ev_pre = len(pre_sr.get("events")["times"])
n_ev_post = len(post_sr.get("events")["times"])

assert n_ev_pre == 10
assert n_ev_post == 100
clinssen marked this conversation as resolved.
Show resolved Hide resolved
Loading