/* * test_pp_psc_delta.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_pp_psc_delta - test of pp_psc_delta neuron functionality Synopsis: (test_pp_psc_delta) run -> compare spike train statistics with expectations Description: This simulation tests the basic functionality of the pp_psc_delta neuron model. Specifically, it checks whether: - the firing rate is close to the preset one - the fixed dead-time is respected in all cases - for randomly distributed dead-times, the mean and the variance of the dead-times are close to the theoretical values - the threshold adaptation works by looking for negative serial correlation of the inter-spike intervals All of these tests are based on random number realizations, which is necessary since the model is stochastic. Thus there is a finite probability for the test to fail, 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 alarms 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 neuron model pp_psc_delta. Remarks: This test script is based on the python version test_pp_psc_delta.py and was adapted to SLI using test_iaf_dc_aligned.sli as a guideline. The commented code is the original python test code. Author: June 2011, Deger, Zaytsev SeeAlso: pp_psc_delta */ /unittest (6688) require /unittest using 0.2 /err Set % 1) check for reasonable firing rate % 2) check if fixed dead-time is respected /check_rate_and_fixed_dead_time { % test parameters 25.0 /d Set 10.0 /lam Set 100000.0 /T Set ResetKernel /pp_psc_delta Create /nrn Set << /tau_m 10.0 /C_m 250.0 /dead_time d /dead_time_random false /dead_time_shape 1 /with_reset false /tau_sfa 34.0 /q_sfa 0.0 /c_1 0.0 /c_2 lam /c_3 0.25 /I_e 0.0 /t_ref_remaining 0.0 >> /params Set nrn params SetStatus /spike_detector Create /sd Set nrn 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) 1.0 lam div d 1e-3 mul add /mu_ana Set 1.0 mu_ana div /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( min(isi)>=d ) 0.0 /t Set spikes cva { dup t sub exch /t Set } Map /l Set l Rest Min d geq assert_or_die } def %3) check if random dead-time moments are respected /check_random_dead_time { % test parameters 50.0 /d Set 10 /n Set 1.0e6 /lam Set 10000.0 /T Set ResetKernel /pp_psc_delta Create /nrn Set << /tau_m 10.0 /C_m 250.0 /dead_time d /dead_time_random true /dead_time_shape 10 /with_reset false /tau_sfa 34.0 /q_sfa 0.0 /c_1 0.0 /c_2 lam /c_3 0.25 /I_e 0.0 /t_ref_remaining 0.0 >> /params Set nrn params SetStatus /spike_detector Create /sd Set nrn 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) 1.0 lam div d 1e-3 mul add /mu_ana Set 1.0 mu_ana div /rate_ana Set %1.0 1.0 lam div d 1e-3 mul add div /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 Rest /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 %ratio_mean = isi_mean / d 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_mean d div /ratio_mean Set 1.0 err sub ratio_mean leq ratio_mean 1.0 err add leq and assert_or_die %isi_var_th = n / (n/d)**2 %ratio_var = isi_var / isi_var_th %assert( 1.0<=ratio_var<=1.5 ) n d div dup mul n exch div /isi_var_th Set isi_var isi_var_th div /ratio_var Set 1.0 err sub ratio_var leq ratio_var 1.0 err add leq and assert_or_die } def % 4) check if threshold adaptation works by looking for negative serial correlation of ISI /check_adapting_threshold { %# test parameters 1e-8 /d Set 30.0 /lam Set 10000.0 /T Set ResetKernel /pp_psc_delta Create /nrn Set << /tau_m 10.0 /C_m 250.0 /dead_time d /dead_time_random false /dead_time_shape 1 /with_reset false /tau_sfa 34.0 /q_sfa 7.0 /c_1 0.0 /c_2 lam /c_3 0.25 /I_e 0.0 /t_ref_remaining 0.0 >> /params Set nrn params SetStatus /spike_detector Create /sd Set nrn 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) 1.0 lam div d 1e-3 mul add /mu_ana Set 1.0 mu_ana div /rate_ana Set %1.0 1.0 lam div d 1e-3 mul add div /rate_ana Set % ratio = rate_sim / rate_ana rate_sim rate_ana div /ratio Set %# Adaptive threshold changes rate, thus not asserted here %0.5 ratio lt %ratio 1.5 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 Rest /isi Set % # compute moments of ISI to get mean and variance % isi_m1 = isi[-1] % isi_m2 = isi[-1]**2 % isi_12 = 0. % for t,t1 in zip(isi[:-1],isi[1:]): % isi_m1 += t % isi_m2 += t**2 % isi_12 += t*t1 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 size exch pop /isi_size Set 0. /isi_12 Set [] isi_size 1 sub append /dummylist Set dummylist Range {dup isi exch get exch 1 sub isi exch get mul isi_12 add /isi_12 Set} forall % % isi_mean = isi_m1 / len(isi) % isi_var = (isi_m2 - isi_m1)**2 / len(isi) % isi_corr = (isi_12 / (len(isi)-1) - isi_mean**2) / isi_var isi_m1 isi_size div /isi_mean Set isi_m2 isi_size div isi_mean dup mul sub /isi_var Set isi_size 1 sub isi_12 exch div isi_mean dup mul sub isi_var div /isi_corr 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. % assert( -1.0<isi_corr<0.0 ) -1.0 isi_corr lt isi_corr 0. lt and assert_or_die } def check_rate_and_fixed_dead_time check_random_dead_time check_adapting_threshold