diff --git a/testsuite/pytests/sli2py_regressions/test_ticket_156.py b/testsuite/pytests/sli2py_regressions/test_ticket_156.py new file mode 100644 index 0000000000..4307f06671 --- /dev/null +++ b/testsuite/pytests/sli2py_regressions/test_ticket_156.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# +# test_ticket_156.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 . +import nest +import numpy as np +import pytest + + +def test_ticket_156(): + """ + Verify that poisson_generator_ps generates identical spike trains for given + start and stop times across different simulation resolutions and different targets. + + Protocol: + 1. poisson_generator_ps projects to two spike_recorders. + 2. Run for different resolutions, record precise spike times in ms. + 3. Test all spikes are in (start, stop]. + 4. Test for different results between spike_recorders. + 5. Test for identical results across resolutions. + """ + + ps_params = {"origin": 0.0, "start": 1.0, "stop": 2.0, "rate": 12345.0} # Expect ~ 12.3 spikes + + resolutions = [0.01, 0.1, 0.2, 0.5, 1.0] + simtime = ps_params["stop"] + 2.0 + + def check_limits(spks): + """Check if all spikes are within the specified limits.""" + ori = ps_params["origin"] + return np.min(spks) > ps_params["start"] + ori and np.max(spks) <= ps_params["stop"] + ori + + def single_trial(h): + """Run a single trial with a given resolution.""" + nest.ResetKernel() + nest.SetKernelStatus({"resolution": h}) + + pg = nest.Create("poisson_generator_ps", params=ps_params) + srs = [nest.Create("spike_recorder") for _ in range(2)] + + for sr in srs: + nest.Connect(pg, sr, syn_spec={"delay": 1.0, "weight": 1.0}) + + nest.Simulate(simtime) + return [nest.GetStatus(sr, "events")[0]["times"] for sr in srs] + + # Run trials for each resolution + results = [single_trial(h) for h in resolutions] + + # First test: Check limits + assert all(check_limits(np.concatenate(trial)) for trial in results), "Spike times out of bounds" + + # Second test: Different results between targets + assert all(not np.array_equal(trial[0], trial[1]) for trial in results), "Spike recorders have identical results" + + # Third test: Equality among runs + # Compare spike times across resolutions for each recorder separately + for i in range(2): + spike_times_across_resolutions = [trial[i] for trial in results] + reference_times = spike_times_across_resolutions[0] + assert all( + np.allclose(reference_times, times, atol=1e-15) for times in spike_times_across_resolutions[1:] + ), "Spike times not consistent across resolutions" diff --git a/testsuite/regressiontests/ticket-156.sli b/testsuite/regressiontests/ticket-156.sli deleted file mode 100644 index 75d0ce9056..0000000000 --- a/testsuite/regressiontests/ticket-156.sli +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ticket-156.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 . - * - */ - -/* - Test for Ticket 156. - - This test verifies that: - poisson_generator_ps generates identical spike trains for given - start and stop for different simulation resolutions, and different - trains for different targets. - - Protocol: - 1. poisson_generator_ps projects to two spike_recorders - 2. run for different resolutions, record precise spike times is ms - 3. test all spikes are in (start, stop] - 3. test for different results between spike_recorders - 4. test for identical results across resolutions -*/ - -(unittest) run -/unittest using - -/ps_params << - /origin 0.0 - /start 1.0 - /stop 2.0 - /rate 12345.0 % expect ~ 12.3 spikes ->> def - -/resolutions [0.01 0.1 0.2 0.5 1.0] def - -% ensure all spikes arrive at recorder -/simtime ps_params /stop get 2.0 add def - -/check_limits % true if all spikes in (origin+start, origin+stop] -{ - << >> begin - /spks Set - /ori ps_params /origin get def - spks Min ps_params /start get ori add gt - spks Max ps_params /stop get ori add leq - and - end -} def - -/single_trial -{ - << >> begin - /h Set - ResetKernel - << /resolution h >> SetKernelStatus - - /poisson_generator_ps Create /pg Set - pg ps_params SetStatus - - [ /spike_recorder Create - /spike_recorder Create - ] /srs Set - srs { pg exch 1.0 1.0 Connect } forall - - simtime Simulate - srs { [/events /times] get cva } Map - end -} def - -resolutions { single_trial } Map -/res Set - -(First test) = -% first test: limits -res Flatten check_limits - -(Second test) = -% second test: different results between targets -res { - arrayload ; neq -} Map - -(Third test) = -% third test: equality among runs -% Test for spike time equality to within 1.0e-16 ms. -res Transpose { - dup First /ref Set - Rest true exch { ref sub 0 exch { abs max } Fold 1.0e-15 lt and } Fold -} Map - -% collect -3 arraystore Flatten -true exch { and } Fold - -assert_or_die