diff --git a/testsuite/pytests/sli2py_neurons/test_add_freeze_thaw.py b/testsuite/pytests/sli2py_neurons/test_add_freeze_thaw.py index 3877ba3a17..d81873da36 100644 --- a/testsuite/pytests/sli2py_neurons/test_add_freeze_thaw.py +++ b/testsuite/pytests/sli2py_neurons/test_add_freeze_thaw.py @@ -25,6 +25,7 @@ import numpy as np import pytest + import nest diff --git a/testsuite/pytests/sli2py_recording/test_multimeter_freeze_thaw.py b/testsuite/pytests/sli2py_recording/test_multimeter_freeze_thaw.py index dd37127108..b0526f932e 100644 --- a/testsuite/pytests/sli2py_recording/test_multimeter_freeze_thaw.py +++ b/testsuite/pytests/sli2py_recording/test_multimeter_freeze_thaw.py @@ -19,12 +19,11 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import nest import numpy as np import numpy.testing as nptest import pytest -import nest - def build_net(num_neurons): """ @@ -62,6 +61,16 @@ def simulate_freeze_thaw(num_neurons): return mm +def test_multimeter_freeze(): + """ + Ensure that frozen parameter can be set to False but not True on multimeter. + """ + + nest.Create("multimeter", params={"frozen": False}) + with pytest.raises(Exception): + nest.Create("multimeter", params={"frozen": True}) + + def test_freeze_thaw_simulation_against_only_thawed_simulation(): """ Verify identical results from freeze/thaw and non-freeze simulation. diff --git a/testsuite/pytests/test_multimeter.py b/testsuite/pytests/test_multimeter.py index c6de574e9c..5308084937 100644 --- a/testsuite/pytests/test_multimeter.py +++ b/testsuite/pytests/test_multimeter.py @@ -19,38 +19,74 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import numpy.testing as nptest import pytest import nest +# Obtain all models with non-empty recordables list +all_models_with_rec = [model for model in nest.node_models if nest.GetDefaults(model).get("recordables")] + + +@pytest.fixture(autouse=True) +def reset_kernel(): + nest.ResetKernel() -@pytest.fixture -def set_resolution(): + +def test_connect_multimeter_twice(): """ - Set resolution to power of two to avoid rounding issues. + Ensure one multimeter can only be connected once to one neuron. + + First, we check that a multimeter can be connected to a neuron once. Then, + we check that that we cannot connect the multimeter more than once. """ - nest.ResetKernel() - nest.resolution = 2**-3 + nrn = nest.Create("iaf_psc_alpha") + mm = nest.Create("multimeter") + nest.Connect(mm, nrn) + with pytest.raises(nest.kernel.NESTErrors.IllegalConnection): + nest.Connect(mm, nrn) -# Obtain all models with non-empty recordables list -models = [model for model in nest.node_models if nest.GetDefaults(model).get("recordables")] +@pytest.mark.parametrize("model", all_models_with_rec) +def test_receptors_with_multiple_multimeters(model): + """ + Test receptors when connecting to multiple multimeters. + + This test is to ensure that connections from two multimeters get + receptors 1 and 2 for all models with recordables. + """ + + nrn = nest.Create(model) + mm1 = nest.Create("multimeter", {"record_from": nrn.recordables}) + mm2 = nest.Create("multimeter", {"record_from": nrn.recordables}) + nest.Connect(mm1, nrn) + nest.Connect(mm2, nrn) + + mm1_receptor = nest.GetConnections(mm1).get("receptor") + mm2_receptor = nest.GetConnections(mm2).get("receptor") -@pytest.mark.parametrize("model", models) -def test_recordables_are_recorded(set_resolution, model): + assert mm1_receptor == 1 + assert mm2_receptor == 2 + + +@pytest.mark.parametrize("model", all_models_with_rec) +def test_recordables_are_recorded(model): """ Test that recordables are recorded. - For each model with recordables, set up minimal simulation - recording from all recordables and test that data is provided. - I also checks that the recording interval can be set. + For each model with recordables, set up minimal simulation recording + from all recordables and test that data is provided. The test checks + that the correct of amount of data is collected for each recordable. + It also checks that the recording interval can be set. .. note:: This test does not check if the data is meaningful. """ + nest.resolution = 2**-3 # Set to power of two to avoid rounding issues + recording_interval = 2 simtime = 10 num_data_expected = simtime / recording_interval - 1 @@ -68,42 +104,28 @@ def test_recordables_are_recorded(set_resolution, model): assert len(result[r]) == num_data_expected -@pytest.mark.parametrize("model", models) -def test_correct_amount_data_collected(model): +@pytest.mark.parametrize("model", all_models_with_rec) +def test_identical_recording_from_multiple_multimeters(model): """ - Test that the correct of amount of data is collected for each recordable. - - For all models providing a 'recordables' entry in their status dict, this - test checks whether the correct amount of data is collected for each - recordable quantity. + Test identical recordings from multimeters with same configurations. - .. note:: - This test does not check the content of the data collected. + In this test two identical multimeters are connected to the same neuron. + They should record identical data. """ - nest.ResetKernel() - nrn = nest.Create(model) - # if the model is compartmental, we need to add at least a root compartment if "compartments" in nest.GetDefaults(model): nrn.compartments = {"parent_idx": -1} recordables = nrn.recordables - mm = nest.Create("multimeter", {"record_from": recordables}) + mm1 = nest.Create("multimeter", {"record_from": recordables}) + mm2 = nest.Create("multimeter", {"record_from": recordables}) + + nest.Connect(mm1, nrn) + nest.Connect(mm2, nrn) - nest.Connect(mm, nrn) nest.Simulate(10.0) for recordable in recordables: - assert len(mm.events[recordable]) == 9 - - -def test_multimeter_freeze(): - """ - Ensure that frozen parameter can be set to False but not True on multimeter. - """ - - nest.Create("multimeter", params={"frozen": False}) - with pytest.raises(Exception): - nest.Create("multimeter", params={"frozen": True}) + nptest.assert_array_equal(mm1.events[recordable], mm2.events[recordable]) diff --git a/testsuite/unittests/test_multiple_multimeter.sli b/testsuite/unittests/test_multiple_multimeter.sli deleted file mode 100644 index bbb231567d..0000000000 --- a/testsuite/unittests/test_multiple_multimeter.sli +++ /dev/null @@ -1,156 +0,0 @@ -/* - * test_multiple_multimeter.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 . - * - */ - - -/** @BeginDocumentation -Name: testsuite::test_multiple_multimeter - test support for multiple multimeters - -Synopsis: (test_multiple_multimeter.sli) run -> dies if assertion fails - -Description: -This script tests support for multiple multimeters: -- Connections created must have receptor != 0 - (this test is crucial to find models that have not been modified from - - inline - port aeif_cond_alpha::connect_sender(DataLoggingRequest& dlr, - port receptor_type) - { - if (receptor_type != 0) - throw UnknownReceptorType(receptor_type, get_name()); - B_.logger_.connect_logging_device(dlr, recordablesMap_); - return 0; - } - - to - - inline - port aeif_cond_alpha::connect_sender(DataLoggingRequest& dlr, - port receptor_type) - { - if (receptor_type != 0) - throw UnknownReceptorType(receptor_type, get_name()); - return B_.logger_.connect_logging_device(dlr, recordablesMap_); - } - -- Check that one multimeter cannot be connected more than once to - one neuron - -- Multiple meters with identcial configurations connected to the - same neuron record identical data - -Author: Plesser -FirstVersion: 2011-02-04 -*/ - -(unittest) run -/unittest using - -M_ERROR setverbosity - -/* The following models do not support multimeter -*/ -/skip_list [ ] def - -/clear_error -{ - counttomark npop % pop all but mark - errordict begin /newerror false def end -} def - - -% first test: -% check that we can connect one multimeter once -{ - ResetKernel - << >> begin - /mm /multimeter Create def - /n /iaf_psc_alpha Create def - mm n Connect - end -} pass_or_die - -% second test: -% check that we cannot connect one multimeter twice -{ - ResetKernel - << >> begin - /mm /multimeter Create def - /n /iaf_psc_alpha Create def - mm n Connect - mm n Connect - end -} fail_or_die - - -% third test: -% check that connections from two multimeters get -% receptors 1 and 2 for all models with recordables -{ - << >> begin - GetKernelStatus /node_models get - { - ResetKernel - /model Set - model GetDefaults /recordables known - { - /n model Create def - /mmd << /record_from n /recordables get >> def - /mm1 /multimeter mmd Create def - /mm2 /multimeter mmd Create def - mm1 n Connect - mm2 n Connect - [mm1 mm2] { /m Set << /source m >> GetConnections - arrayload 1 eq assert /receptor get } Map - [1 2] eq - } - { true } - ifelse - } Map - - true exch { and } Fold -} assert_or_die - -% fourth test: -% run simulation to see that two multimeters record same stuff -{ - ResetKernel - << >> begin - /recvars [ /V_m ] def - /n /iaf_psc_alpha Create def - /mm1 /multimeter << /record_from recvars >> Create def - /mm2 /multimeter << /record_from recvars >> Create def - mm1 n Connect - mm2 n Connect - /pge /poisson_generator << /rate 10000. >> Create def - /pgi /poisson_generator << /rate 10000. >> Create def - pge n 1.0 1.0 Connect - pgi n -1.0 1.0 Connect - 100 Simulate - /e1 mm1 /events get def - /e2 mm2 /events get def - recvars { /rv Set [ e1 e2 ] { rv get cva } Map arrayload ; eq } Map - true exch { and } Fold - end -} assert_or_die - -endusing