/*
 *  test_bernoulli_synapse.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_bernoulli_synapse - test of bernoulli_synapse connection

    Synopsis: (test_bernoulli_synapse) run -> measure average number of spikes transmitted 
    by a Bernoulli synapse (static synapse with stochastic transmission)

    Description:
    1000 spikes generated by spike_generator are sent to a parrot neuron using a 
    bernoulli_synapse with transmission probability 25%. Transmission is mediated
    by another parrot neuron that is connected to spike_generator via static synapse.
    If the average number of spikes detected by spike detectors is within three
    standard deviations from the mean of the binomial distribution, the synapse
    works fine. Also tests the interval of possible probabilities, [0, 1].

    FirstVersion: June 2017
    Author: Maximilian Schmidt, Milena Menezes Carvalho
*/

(unittest) run
/unittest using

% test parameters -------------------------------------------------
% number of spikes sent via bernoulli synapse to parrot neuron
/N_spikes 1000 def
% transmission probability of the bernoulli synapse
/p 0.25 def
% allowed absolute deviation: three standard deviations of the binomial distribution with (N_spikes, p)
/margin N_spikes p mul 1 p sub mul sqrt 3 mul def
% test routine ----------------------------------------------------

/test_bernoulli_run
{
  /seed Set
  ResetKernel
  0 << /rng_seeds [seed] >> SetStatus

  % build
  /spike_generator Create /sg Set
  /parrot_neuron Create /pre Set  
  /parrot_neuron Create /post Set
  /spike_detector Create /sd Set

  % set spike_generator 
  sg << /spike_times [1. N_spikes cvd] Range >> SetStatus

  % connect spike_generator to presynaptic parrot neuron
  % via static synapse
  [sg] [pre] << /rule /all_to_all >> << /model /static_synapse >> Connect

  % connect presynaptic parrot neuron to postsynaptic parrot neuron 
  % via bernoulli_synapse with transmission probability p
  [pre] [post] << /rule /all_to_all >> << /model /bernoulli_synapse /p_transmit p >> Connect

  % connect parrot neuron to spike_detector
  [post] [sd] Connect

  % simulate for 1002 ms to allow all spikes to be recorded accordingly
  N_spikes 2. add Simulate

  % get number of spikes transmitted
  sd GetStatus /events get /times get length /N_spikes_transmitted Set
  
  % mean value of spikes to be received with transmission probability p
  /mean N_spikes p mul def

  % check if error between number of spikes transmitted and mean is within the defined margin
  mean N_spikes_transmitted sub abs margin leq 
  assert_or_die
}
def

% Test 1: test 10 different rng seeds for test_bernoulli_run routine

[123 133] Range
{
  test_bernoulli_run
}
forall

% Test 2: test if p_transmit values are within the range [0, 1]

/parrot_neuron Create /pre Set
/parrot_neuron Create /post Set

{ 
  [pre] [post] << /rule /all_to_all >> << /model /bernoulli_synapse /p_transmit -0.1 >> Connect
} fail_or_die

{ 
  [pre] [post] << /rule /all_to_all >> << /model /bernoulli_synapse /p_transmit 1.1 >> Connect
} fail_or_die
