From 321b6149b8e257a9b94435e60367d0a4f9b9f49d Mon Sep 17 00:00:00 2001 From: Ayssar_Juelich Date: Mon, 24 Apr 2023 13:40:16 +0200 Subject: [PATCH 1/4] Convert model_node_init --- .../sli2py_neurons/test_model_node_init.py | 74 +++++++++++++++ testsuite/unittests/model_node_init.sli | 94 ------------------- 2 files changed, 74 insertions(+), 94 deletions(-) create mode 100644 testsuite/pytests/sli2py_neurons/test_model_node_init.py delete mode 100644 testsuite/unittests/model_node_init.sli diff --git a/testsuite/pytests/sli2py_neurons/test_model_node_init.py b/testsuite/pytests/sli2py_neurons/test_model_node_init.py new file mode 100644 index 0000000000..4fed474b2d --- /dev/null +++ b/testsuite/pytests/sli2py_neurons/test_model_node_init.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# +# test_model_node_init.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 . + + +""" + Makeshift test to see if setting model params and then creating a neuron + and creating a neuron and then setting node params lead to the same + results. + + Works by connecting device to iaf_psc_alpha, measuring voltage trace over 1s + and comparing traces. +""" + +import pytest +import nest +from types import SimpleNamespace # to access dict with dot! + + +def _get_network_state(nc): + neuron = nest.Create("iaf_psc_alpha") + voltmeter = nest.Create("voltmeter") + + nest.Connect(nc, neuron) + nest.Connect(voltmeter, neuron) + nest.Simulate(1000) + volts = voltmeter.get("events")["V_m"] + + return (volts, nc.get()) + + +@pytest.fixture() +def model_data(): + return SimpleNamespace(**{"model": "mip_generator", "params": {"rate": 100.0, "p_copy": 0.5}}) + + +@pytest.fixture() +def use_set_defaults(model_data): + nest.ResetKernel() + nest.set(overwrite_files=True) + nest.SetDefaults(model_data.model, model_data.params) + model_instance = nest.Create(model_data.model) + return _get_network_state(model_instance) + + +@pytest.fixture() +def use_set_status(model_data): + nest.ResetKernel() + nest.set(overwrite_files=True) + model_instance = nest.Create(model_data.model) + model_instance.set(**model_data.params) + return _get_network_state(model_instance) + + +def test_network_equality(use_set_defaults, use_set_status): + assert (use_set_defaults[0] == use_set_status[0]).all() + assert use_set_defaults[1] == use_set_status[1] diff --git a/testsuite/unittests/model_node_init.sli b/testsuite/unittests/model_node_init.sli deleted file mode 100644 index fa1ab8e8b8..0000000000 --- a/testsuite/unittests/model_node_init.sli +++ /dev/null @@ -1,94 +0,0 @@ -/* - * model_node_init.sli - * - * 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 . - * - */ - -% SLI2PY: Generalize to all models, but do we need to simulate? Why not just read out values from neuron? -% SLI2PYComplexity: Medium - -/* model_node_init.sli - - Makeshift test to see if setting model params and then creating a neuron - and creating a neuron and then setting node params lead to the same - results. - - Works by connecting device to iaf_psc_alpha, measuring voltage trace over 1s - and comparing traces. - - todo: - generalize for more models -*/ - -(unittest) run -/unittest using - -%/model /step_current_generator def -%/params << /amplitude_times [ 100.0 200.0 300.0 500.0 ] -% /amplitude_values [ 100.0 -200.0 50.0 100.0 ] -% >> def - -/model /mip_generator def -/params << /rate 100.0 /p_copy 0.5 >> def - -/run_model { - - ResetKernel - << /overwrite_files true >> SetKernelStatus - - % expect boolean flag, if true init model, else init node - % leave voltmeter potential trace and node status dict on stack - /param_model Set - - param_model { - model params SetDefaults - } if - - model Create /m Set - - param_model not { - m params SetStatus - } if - - /iaf_psc_alpha Create /n Set - /voltmeter Create /vm Set - m n Connect - vm n Connect - - 1000 Simulate - - vm [ /events /V_m ] get cva - m GetStatus 0 get - 2 arraystore -} def - -% run once with model, once with node initialization -% and compare results -[true false] { run_model } Map -Transpose arrayload pop -/sdicts Set -/volts Set - -% test status dictionaries and voltage traces -{ - sdicts arrayload pop cva_d exch cva_d eq -} assert_or_die - -{ - volts arrayload pop eq -} assert_or_die From 24bf12f15467c2a1583ed4910239c779f60df848 Mon Sep 17 00:00:00 2001 From: Ayssar_Juelich Date: Mon, 24 Apr 2023 13:47:48 +0200 Subject: [PATCH 2/4] Rename function --- testsuite/pytests/sli2py_neurons/test_model_node_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/pytests/sli2py_neurons/test_model_node_init.py b/testsuite/pytests/sli2py_neurons/test_model_node_init.py index 4fed474b2d..93e16d3934 100644 --- a/testsuite/pytests/sli2py_neurons/test_model_node_init.py +++ b/testsuite/pytests/sli2py_neurons/test_model_node_init.py @@ -69,6 +69,6 @@ def use_set_status(model_data): return _get_network_state(model_instance) -def test_network_equality(use_set_defaults, use_set_status): +def test_set_status_vs_set_defaults(use_set_defaults, use_set_status): assert (use_set_defaults[0] == use_set_status[0]).all() assert use_set_defaults[1] == use_set_status[1] From 19697529366e2f9467493f4ab23409954d52f466 Mon Sep 17 00:00:00 2001 From: Ayssar_Juelich Date: Mon, 24 Apr 2023 17:19:44 +0200 Subject: [PATCH 3/4] Aggregate logic inside Class --- .../sli2py_neurons/test_model_node_init.py | 11 ++- .../test_common_props_setting.py | 90 +++++++++++++++++++ 2 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 testsuite/pytests/sli2py_synapses/test_common_props_setting.py diff --git a/testsuite/pytests/sli2py_neurons/test_model_node_init.py b/testsuite/pytests/sli2py_neurons/test_model_node_init.py index 93e16d3934..ac6283091f 100644 --- a/testsuite/pytests/sli2py_neurons/test_model_node_init.py +++ b/testsuite/pytests/sli2py_neurons/test_model_node_init.py @@ -31,7 +31,6 @@ import pytest import nest -from types import SimpleNamespace # to access dict with dot! def _get_network_state(nc): @@ -48,15 +47,15 @@ def _get_network_state(nc): @pytest.fixture() def model_data(): - return SimpleNamespace(**{"model": "mip_generator", "params": {"rate": 100.0, "p_copy": 0.5}}) + return {"model": "mip_generator", "params": {"rate": 100.0, "p_copy": 0.5}} @pytest.fixture() def use_set_defaults(model_data): nest.ResetKernel() nest.set(overwrite_files=True) - nest.SetDefaults(model_data.model, model_data.params) - model_instance = nest.Create(model_data.model) + nest.SetDefaults(model_data["model"], model_data["params"]) + model_instance = nest.Create(model_data["model"]) return _get_network_state(model_instance) @@ -64,8 +63,8 @@ def use_set_defaults(model_data): def use_set_status(model_data): nest.ResetKernel() nest.set(overwrite_files=True) - model_instance = nest.Create(model_data.model) - model_instance.set(**model_data.params) + model_instance = nest.Create(model_data["model"]) + model_instance.set(**model_data["params"]) return _get_network_state(model_instance) diff --git a/testsuite/pytests/sli2py_synapses/test_common_props_setting.py b/testsuite/pytests/sli2py_synapses/test_common_props_setting.py new file mode 100644 index 0000000000..62c03bc8f7 --- /dev/null +++ b/testsuite/pytests/sli2py_synapses/test_common_props_setting.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# +# test_common_props_setting +# +# 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 . + + +""" +Name: testsuite::test_common_props_setting - test that common properties can be set as defaults, not else + +Synopsis: (test_common_props_setting) run -> compare response with reference data + +Description: +For synapses with common properties, ensure that common and individual properties can be set by +SetDefaults and CopyModel, but that an exception is raised if they are set via an individual connection. + +FirstVersion: November 2014 + +Author: Hans E Plesser +""" + +import nest +import pytest + + +@pytest.fixture(autouse=True) +def prepare(): + nest.ResetKernel() + volt = nest.Create("volume_transmitter") + nest.SetDefaults("stdp_dopamine_synapse", {"vt": volt.tolist()[0]}) + + +@pytest.mark.parametrize('synapse', ["stdp_synapse_hom", "stdp_pl_synapse_hom", "stdp_facetshw_synapse_hom", + "stdp_dopamine_synapse"]) +class TestSettingCommonProps: + + def test_setting_common_props_on_original(self, synapse): + expected_values = {"tau_plus": 5.0, "weight": 2.0} + nest.SetDefaults(synapse, expected_values) + + actual_values = nest.GetDefaults(synapse, keys=expected_values.keys()) + assert actual_values == tuple(expected_values.values()) + + def test_setting_common_props_on_copy(self, synapse): + copied_syn = f"{synapse}_copy" + expected_values = {"tau_plus": 15.0, "weight": 20.0} + nest.CopyModel(synapse, copied_syn, expected_values) + + actual_values = nest.GetDefaults(copied_syn, keys=expected_values.keys()) + assert actual_values == tuple(expected_values.values()) + + def test_setting_non_common_props_on_instance(self, synapse): + + neuron = nest.Create("iaf_psc_alpha") + nest.Connect(neuron, neuron, syn_spec={'synapse_model': synapse}) + + single_edge = nest.GetConnections(source=neuron)[0] + single_edge.set(weight=3.0) + + assert single_edge.get("weight") == 3.0 + assert nest.GetDefaults(synapse)["weight"] != 3.0 + + def test_setting_common_props_on_instance(self, synapse): + + tau_plus_ref = nest.GetDefaults(synapse)["tau_plus"] + neuron = nest.Create("iaf_psc_alpha") + nest.Connect(neuron, neuron, syn_spec={'synapse_model': synapse}) + + single_edge = nest.GetConnections(source=neuron)[0] + + with pytest.raises(Exception): + single_edge.set(tau_plus=(tau_plus_ref + 1) * 3) + + actual_tau_plus_value = nest.GetDefaults(synapse)["tau_plus"] + assert actual_tau_plus_value == tau_plus_ref From 87a1f3afbe4cb3c2d309f840ff7f2ebd1bf6f10e Mon Sep 17 00:00:00 2001 From: Ayssar_Juelich Date: Tue, 25 Apr 2023 07:50:45 +0200 Subject: [PATCH 4/4] Fix piplines errors --- testsuite/pytests/sli2py_synapses/test_common_props_setting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/pytests/sli2py_synapses/test_common_props_setting.py b/testsuite/pytests/sli2py_synapses/test_common_props_setting.py index 62c03bc8f7..cbe5a95b9f 100644 --- a/testsuite/pytests/sli2py_synapses/test_common_props_setting.py +++ b/testsuite/pytests/sli2py_synapses/test_common_props_setting.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# test_common_props_setting +# test_common_props_setting.py # # This file is part of NEST. #