/*
* test_sinusoidal_gamma_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_sinusoidal_gamma_generator_nostats - test basic properties of sinusoidal gamma generator
Synopsis: (test_sinusoidal_gamma_generator) run -> dies if assertion fails
Description:
This test asserts that
- that /individual_spike_trains is true by default
- the /individual_spike_trains property can be set on the model, but not on instances
- that instances inherit the correct /individual_spike_trains value
- that different targets (on same or different threads)
* identical spike trains if /individual_spike_trains is false
* different spike trains otherwise
- that a multimeter can be connected to record the rate
* independent of /individual_spike_trains ..., only a single trace is returned
- the recorded rate profile is tested against expectation
This test DOES NOT test the statistical properties of the spike trains generated.
Author: Plesser
FirstVersion: May 2013
SeeAlso: test_sinusoidal_gamma_generator_mpi
*/
% return success if generator not known due to missing GSL
modeldict /sinusoidal_gamma_generator known not
{
(Skipping test: generator missing) ==
quit
} if
(unittest) run
/unittest using
M_ERROR setverbosity
% test 1: individual_spike_trains true by default
{
ResetKernel
/sinusoidal_gamma_generator Create
/individual_spike_trains get
} assert_or_die
(passed 1) ==
% test 2: individual_spike_trains can be set on model and is passed on
{
ResetKernel
/sinusoidal_gamma_generator << /individual_spike_trains false >> SetDefaults
/sinusoidal_gamma_generator Create
/individual_spike_trains get
not
} assert_or_die
(passed 2) ==
% test 2a: individual_spike_trains can be set on model and is passed on
{
ResetKernel
/sinusoidal_gamma_generator
/sspg << /individual_spike_trains false >> CopyModel
/sspg Create
/individual_spike_trains get
not
} assert_or_die
(passed 2a) ==
% test 3: individual_spike_trains cannot be set on instances
{
ResetKernel
/spg /sinusoidal_gamma_generator Create def
mark
{
spg << /individual_spike_trains false >> SetStatus
} stopped
{
/passed true def
% we got an exception, need to clean up
errordict /message undef
errordict /command undef
errordict begin /newerror false def end
}
{
/passed false def
} ifelse
counttomark npop pop % clear stack, including mark
passed
} assert_or_die
(passed 3) ==
% function building n neuron network with spike detectors
% num_nrns build_simple_net -> [ spike_detectors ]
/build_simple_net
{
/n Set
/pnet /subnet Create def
pnet ChangeSubnet
/parrot_neuron n Create ;
0 ChangeSubnet
/parrots pnet GetLocalLeaves def
/snet /subnet Create def
snet ChangeSubnet
/spike_detector n << /withtime true /withgid false >> Create ;
0 ChangeSubnet
/sdets snet GetLocalLeaves def
/gen /sinusoidal_gamma_generator Create def
gen parrots DivergentConnect
[parrots sdets] { Connect } ScanThread
sdets
} def
% return true if all arrays inside an array are identical
% [l1 l2 ...] all_equal -> bool
/all_equal
{
dup First /reference Set
true exch { reference eq and } Fold
} def
% return true if all arrays inside an array are different from each other
% [l1 l2 ...] all_different -> bool
/all_different
{
empty
{
; true
}
{
/items Set
items [ 1 -2 ] Take % all except last element
{
2 add % need to add 2 to make up for 0-based MapIndexed
-1 2 arraystore items exch Take
exch /item Set
true exch { item neq and } Fold
} MapIndexed
true exch { and } Fold
} ifelse
} def
% Run test for given value for individual spike train and thread number
% individual(true/false) num_threads nrns_per_thread test4_function -> bool
/test4_function
{
/nrns_per_thread Set
/num_threads Set
/individual Set
ResetKernel
0 << /local_num_threads num_threads >> SetStatus
/sinusoidal_gamma_generator
<<
/dc 100.
/ac 50.
/freq 10.
/order 3.
/individual_spike_trains individual
>> SetDefaults
/sdets num_threads nrns_per_thread mul build_simple_net def
1000. Simulate
sdets { [/events /times] get cva } Map
individual
{
all_different
}
{
all_equal
}
ifelse
} def
% test 4a: single thread, one spike train for all targets
{
false 1 4 test4_function
} assert_or_die
(passed 4a) ==
% test 4b: single thread, different spike trains for all targets
{
true 1 4 test4_function
} assert_or_die
(passed 4b) ==
% test 4c: two threads, one spike train for all targets
{
false 2 4 test4_function
} assert_or_die
(passed 4c) ==
% test 4d: two threads, different spike trains for all targets
{
true 2 4 test4_function
} assert_or_die
(passed 4d) ==
% now let's add multimeters
% function building n neuron network with multimeter
% num_nrns build_simple_net -> [ multimeter ]
/build_mm_net
{
/n Set
/pnet /subnet Create def
pnet ChangeSubnet
/parrot_neuron n Create ;
0 ChangeSubnet
/parrots pnet GetLocalLeaves def
/gen /sinusoidal_gamma_generator Create def
/mm /multimeter << /record_from [ /rate ] >> Create def
gen parrots DivergentConnect
mm gen Connect
mm
} def
% Run test for given value for individual spike train and thread number
% individual(true/false) num_threads nrns_per_thread test4_function -> bool
/test5_function
{
/nrns_per_thread Set
/num_threads Set
/individual Set
ResetKernel
0 << /local_num_threads num_threads >> SetStatus
/sinusoidal_gamma_generator
<<
/dc 100.
/ac 50.
/freq 10.
/order 3.
/individual_spike_trains individual
>> SetDefaults
/mm num_threads nrns_per_thread mul build_mm_net def
/tsim 100. def
tsim Simulate
/ndata tsim cvi 1 sub def
% times and rates must be arrays of ndata points
mm [/events /times] get length ndata eq
mm [/events /rate ] get length ndata eq
and
} def
% test 5a: single thread, one spike train for all targets
{
false 1 4 test5_function
} assert_or_die
(passed 5a) ==
% test 5b: single thread, different spike trains for all targets
{
true 1 4 test5_function
} assert_or_die
(passed 5b) ==
% test 5c: two threads, one spike train for all targets
{
false 2 4 test5_function
} assert_or_die
(passed 5c) ==
% test 5d: two threads, different spike trains for all targets
{
true 2 4 test5_function
} assert_or_die
(passed 5d) ==
%% finally, check multimeter whether rate is correct
{
ResetKernel
/dc 1. def
/ac 0.5 def
/freq 10. def
/phi 2. def
/order 3. def
/sinusoidal_gamma_generator
<<
/dc dc
/ac ac
/freq freq
/phi phi
/order order
>> SetDefaults
/mm 1 build_mm_net def
mm << /start 100. >> SetStatus % leave time for equilibration
/tsim 200. def
tsim Simulate
/t mm [ /events /times ] get cva def
/r mm [ /events /rate ] get cva def
/r0 dc ac 2. Pi mul freq 1000. div mul t mul phi add { sin } Map mul add def
true r r0 sub { abs 1e-14 lt and } Fold
} assert_or_die
(passed 6) ==
endusing