From e5bdbd3b5f56d406003e98b2269ba417688aa0fb Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Thu, 20 Jun 2024 17:38:24 +0200 Subject: [PATCH] ensure compatibility with NESTML custom as well as NEST built-in synaptic plasticity models --- .../codegeneration/nest_code_generator.py | 1 + ...f_psc_exp_nonlineardendrite_neuron.nestml} | 28 +++++++++++++-- ...tml => stdsp_no_permanence_synapse.nestml} | 36 ++++++++++++++++--- ...est_built_in_and_nestml_plastic_synapse.py | 15 ++++---- 4 files changed, 65 insertions(+), 15 deletions(-) rename tests/nest_tests/resources/{iaf_psc_exp_nonlineardendrite_alternate.nestml => iaf_psc_exp_nonlineardendrite_neuron.nestml} (78%) rename tests/nest_tests/resources/{stdsp_synapse_no_permanence.nestml => stdsp_no_permanence_synapse.nestml} (58%) diff --git a/pynestml/codegeneration/nest_code_generator.py b/pynestml/codegeneration/nest_code_generator.py index a4514efde..64ad13f17 100644 --- a/pynestml/codegeneration/nest_code_generator.py +++ b/pynestml/codegeneration/nest_code_generator.py @@ -169,6 +169,7 @@ def __init__(self, options: Optional[Mapping[str, Any]] = None): def run_nest_target_specific_cocos(self, neurons: Sequence[ASTModel], synapses: Sequence[ASTModel]): for synapse in synapses: synapse_name_stripped = removesuffix(removesuffix(synapse.name.split("_with_")[0], "_"), FrontendConfiguration.suffix) + assert synapse_name_stripped in self.get_option("delay_variable").keys(), "Please specify a ``delay_variable`` for the synapse '" + synapse_name_stripped + "'" delay_variable = self.get_option("delay_variable")[synapse_name_stripped] CoCoNESTSynapseDelayNotAssignedTo.check_co_co(delay_variable, synapse) if Logger.has_errors(synapse): diff --git a/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite_alternate.nestml b/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite_neuron.nestml similarity index 78% rename from tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite_alternate.nestml rename to tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite_neuron.nestml index 12a9b6262..b69c38475 100644 --- a/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite_alternate.nestml +++ b/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite_neuron.nestml @@ -1,4 +1,29 @@ -neuron iaf_psc_exp_nonlineardendrite: +""" +iaf_psc_exp_nonlineardendrite_alternate.nestml +############################################## + + +Copyright statement ++++++++++++++++++++ + +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 . +""" +model iaf_psc_exp_nonlineardendrite_neuron: state: V_m mV = 0mV # membrane potential in mV @@ -8,7 +33,6 @@ neuron iaf_psc_exp_nonlineardendrite: ref_counts integer = 0 equations: - # exponential shaped postsynaptic current kernel kernel I_kernel1 = exp(-1/tau_syn1*t) diff --git a/tests/nest_tests/resources/stdsp_synapse_no_permanence.nestml b/tests/nest_tests/resources/stdsp_no_permanence_synapse.nestml similarity index 58% rename from tests/nest_tests/resources/stdsp_synapse_no_permanence.nestml rename to tests/nest_tests/resources/stdsp_no_permanence_synapse.nestml index 016d54ffd..b099d4dfe 100644 --- a/tests/nest_tests/resources/stdsp_synapse_no_permanence.nestml +++ b/tests/nest_tests/resources/stdsp_no_permanence_synapse.nestml @@ -1,12 +1,36 @@ +""" +stdsp_no_permanence_synapse.nestml +################################## -synapse stdsp_synapse_no_permanence: + +Copyright statement ++++++++++++++++++++ + +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 . +""" +model stdsp_no_permanence_synapse: state: - w real = 1. @nest::weight - t_last_pre_spike ms = -1ms + w real = 1 + t_last_pre_spike ms = -1 ms parameters: - d ms = 2.0 ms @nest::delay # !!! cannot have a variable called "delay" + d ms = 2.0 ms lambda real = .01 lambda_minus real = .01 tau_tr_pre ms = 20 ms @@ -54,5 +78,7 @@ synapse stdsp_synapse_no_permanence: w = max(Wmin, w_) # deliver spike to postsynaptic partner - deliver_spike(w, d) + emit_spike(w, d) + update: + integrate_odes() diff --git a/tests/nest_tests/test_built_in_and_nestml_plastic_synapse.py b/tests/nest_tests/test_built_in_and_nestml_plastic_synapse.py index 7bcc63d05..6b99fa08f 100644 --- a/tests/nest_tests/test_built_in_and_nestml_plastic_synapse.py +++ b/tests/nest_tests/test_built_in_and_nestml_plastic_synapse.py @@ -35,17 +35,16 @@ class TestBuiltInAndNESTMLPlasticSynapse: r"""Test that synaptic plasticity works with both a NEST built-in plastic synapse and a NESTML custom plastic synapse attached to the same neuron.""" - neuron_model = "iaf_psc_exp_nonlineardendrite" - synapse_model = "stdsp_synapse_no_permanence" + neuron_model = "iaf_psc_exp_nonlineardendrite_neuron" + synapse_model = "stdsp_no_permanence_synapse" def setup_nest(self): - files = [f"{TestBuiltInAndNESTMLPlasticSynapse.neuron_model}_alternate.nestml", + files = [f"{TestBuiltInAndNESTMLPlasticSynapse.neuron_model}.nestml", f"{TestBuiltInAndNESTMLPlasticSynapse.synapse_model}.nestml"] input_path = [os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", s)) for s in files] generate_nest_target( input_path=input_path, - target_path="module", logging_level="DEBUG", module_name=f"nestml_{TestBuiltInAndNESTMLPlasticSynapse.neuron_model}_{TestBuiltInAndNESTMLPlasticSynapse.synapse_model}_module", suffix="_nestml", @@ -57,12 +56,11 @@ def setup_nest(self): "post_ports": ["post_spikes", ["z_post", "z"]], } ], - }, + "delay_variable": {"stdsp_no_permanence_synapse": "d"}, + "weight_variable": {"stdsp_no_permanence_synapse": "w"} + } ) - # install custom neuron models - nest.Install(f"nestml_{TestBuiltInAndNESTMLPlasticSynapse.neuron_model}_{TestBuiltInAndNESTMLPlasticSynapse.synapse_model}_module") - def _test_plasticity(self, neuron_model, synapse_model): print("testing plasticity for synapse mode " + str(synapse_model)) @@ -73,6 +71,7 @@ def _test_plasticity(self, neuron_model, synapse_model): initial_weight = 123. nest.ResetKernel() + nest.Install(f"nestml_{TestBuiltInAndNESTMLPlasticSynapse.neuron_model}_{TestBuiltInAndNESTMLPlasticSynapse.synapse_model}_module") # create pre and post neurons pre_neuron = nest.Create(neuron_model)