/* * test_ppd_sup_generator.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 <http://www.gnu.org/licenses/>. * */ /* BeginDocumentation Name: testsuite::test_ppd_sup_generator - sli script for test of ppd_sup_generator output Synopsis: (test_ppd_sup_generator) run -> compare spike train statistics with expectations Description: test_ppd_sup_generator is a collection of tests which require basic functionality of the generator. It tests 1) if the firing rate of a superposition is close to the preset one. 2) if the coefficient of variation of a superposition agrees with theory 3) if a fixed dead-time is respected absolutely in case of a single generated process. 4) if the coefficient of variation of a single process agrees with theory 5) if the spike trains generated for two different targets differ All of these tests are based on random number realizations, which is necessarily so since the model is stochastic. There is thus a finite probability of test failure, even if everything is fine. The choice of the variable err, which is the allowed relative deviation from the reference value, can be used to make the test more or less strict. Increasing T inside the test functions can also help to get more reliable statistics and a reduced probability of false alarms. The values are chosen to have a reasonable execution time. False alarm were never observed yet. Since random numbers are preserved through repetitions of the simulations, the test should work for sure as long as the random number generation procedure of nest is not changed. If it is changed, failure of the test is still very unlikely. The intention of this script is to make sure that there are no gross errors in the main functions of the ppd_sup_generator. It does not test the sinusoidal hazard feature yet. Remarks: This test script was adapted from test_pp_psc_delta.sli Author: June 2011, Moritz Deger SeeAlso: ppd_sup_generator, testsuite::test_pp_psc_delta, testsuite::test_poisson_generator_ps */ /unittest (6688) require /unittest using 0.2 /err Set % 1) check for reasonable superposition spike rate % 2) check if superposition cv agrees with theory /check_sup_rate_and_cv { % test parameters 25.0 /dead_time Set 10.0 /rate Set 10000.0 /T Set 5 /n_proc Set 1. /h Set ResetKernel << /resolution h >> /kernelparams Set 0 kernelparams SetStatus /ppd_sup_generator Create /psg Set << /rate rate /dead_time dead_time /n_proc n_proc /frequency 0. /amplitude 0. >> /params Set psg params SetStatus /spike_detector Create /sd Set psg sd Connect T Simulate sd GetStatus /events get /times get /spikes Set % rate_sim = size(spikes) / (T*1e-3) spikes cva size T 1e-3 mul div /rate_sim Set /spikes_array Set % rate_ana = 1./(1./lam + d*1e-3) rate n_proc mul /rate_ana Set % ratio = rate_sim / rate_ana rate_sim rate_ana div /ratio Set % this could fail due to bad luck. However, if it passes once, then it should % always do so, since the random numbers are reproducible in NEST. 1.0 err sub ratio lt ratio 1.0 err add lt and assert_or_die %isi = [] %for i in xrange(1,len(spikes)): % isi.append(spikes[i]-spikes[i-1]) 0.0 /t Set spikes cva { dup t sub exch /t Set } Map /isi Set %# compute moments of ISI to get mean and variance %isi_m1 = 0. %isi_m2 = 0. %for t in isi: % isi_m1 += t % isi_m2 += t**2 0. /isi_m1 Set 0. /isi_m2 Set isi { dup isi_m1 add /isi_m1 Set dup mul isi_m2 add /isi_m2 Set} forall %isi_mean = isi_m1 / len(isi) %isi_var = isi_m2/ len(isi) - isi_mean**2 %cvsq = isi_var/isi_mean**2 isi_m1 isi size exch pop div /isi_mean Set isi_m2 isi size exch pop div isi_mean dup mul sub /isi_var Set isi_var isi_mean 2 pow div /cvsq_sim Set %theoretical CV**2, see Deger et al 2011, JCNS 1.0 rate div 1e3 mul /mu Set 1.0 1.0 n_proc add div /cvfact1 Set n_proc 1.0 sub 2.0 1.0 dead_time mu div sub n_proc 1 add pow mul add /cvfact2 Set cvfact1 cvfact2 mul /cvsq_theo Set cvsq_sim cvsq_theo div /ratio_cvsq Set 1.0 err sub ratio_cvsq leq ratio_cvsq 1.0 err add leq and assert_or_die } def %3) check if single process respects dead-time /check_single_rate_and_dead_time { % test parameters 35.0 /dead_time Set 15.0 /rate Set 100000.0 /T Set 1 /n_proc Set 1.0 /h Set ResetKernel << /resolution h >> /kernelparams Set 0 kernelparams SetStatus /ppd_sup_generator Create /psg Set << /rate rate /dead_time dead_time /n_proc n_proc /frequency 0. /amplitude 0. >> /params Set psg params SetStatus /spike_detector Create /sd Set psg sd Connect T Simulate sd GetStatus /events get /times get /spikes Set % rate_sim = size(spikes) / (T*1e-3) spikes cva size T 1e-3 mul div /rate_sim Set /spikes_array Set % rate_ana = 1./(1./lam + d*1e-3) rate n_proc mul /rate_ana Set % ratio = rate_sim / rate_ana rate_sim rate_ana div /ratio Set % this could fail due to bad luck. However, if it passes once, then it should % always do so, since the random numbers are reproducible in NEST. 1.0 err sub ratio lt ratio 1.0 err add lt and assert_or_die %isi = [] %for i in xrange(1,len(spikes)): % isi.append(spikes[i]-spikes[i-1]) % Assert that min(isi)>=d 0.0 /t Set spikes cva { dup t sub exch /t Set } Map /isi Set isi Rest Min dead_time geq assert_or_die %# compute moments of ISI to get mean and variance %isi_m1 = 0. %isi_m2 = 0. %for t in isi: % isi_m1 += t % isi_m2 += t**2 0. /isi_m1 Set 0. /isi_m2 Set isi { dup isi_m1 add /isi_m1 Set dup mul isi_m2 add /isi_m2 Set} forall %isi_mean = isi_m1 / len(isi) %isi_var = isi_m2/ len(isi) - isi_mean**2 %cvsq = isi_var/isi_mean**2 isi_m1 isi size exch pop div /isi_mean Set isi_m2 isi size exch pop div isi_mean dup mul sub /isi_var Set isi_var isi_mean 2 pow div /cvsq_sim Set %theoretical CV**2, see Deger et al 2011, JCNS 1.0 rate div /mu Set mu dead_time sub /lam Set 1.0 lam div mu div 2 pow /cvsq_theo Set cvsq_sim cvsq_theo div /ratio_cvsq Set 1.0 err sub ratio_cvsq leq ratio_cvsq 1.0 err add leq and assert_or_die } def /check_different_outputs { % test parameters 5.0 /dead_time Set 25.0 /rate Set 10.0 /T Set 1000 /n_proc Set 0.01 /h Set ResetKernel << /resolution h >> /kernelparams Set 0 kernelparams SetStatus /ppd_sup_generator Create /psg Set << /rate rate /dead_time dead_time /n_proc n_proc /frequency 0. /amplitude 0. >> /params Set psg params SetStatus /spike_detector Create /sd1 Set /spike_detector Create /sd2 Set psg sd1 Connect psg sd2 Connect T Simulate %first we check if the spike trains are different [sd1 sd2] {[/events /times] get} forall neq % spike trains differ assert_or_die %and we also check the rates since we simulated anyway sd1 GetStatus /events get /times get /spikes1 Set sd2 GetStatus /events get /times get /spikes2 Set % rate_sim = size(spikes) / (T*1e-3) spikes1 cva size T 1e-3 mul div /rate_sim1 Set /spikes_array1 Set spikes2 cva size T 1e-3 mul div /rate_sim2 Set /spikes_array2 Set % rate_ana = 1./(1./lam + d*1e-3) rate n_proc mul /rate_ana Set % ratio = rate_sim / rate_ana rate_sim1 rate_ana div /ratio1 Set rate_sim2 rate_ana div /ratio2 Set % this could fail due to bad luck. However, if it passes once, then it should % always do so, since the random numbers are reproducible in NEST. 1.0 err sub ratio1 lt ratio1 1.0 err add lt and assert_or_die 1.0 err sub ratio2 lt ratio2 1.0 err add lt and assert_or_die } def check_sup_rate_and_cv check_single_rate_and_dead_time check_different_outputs