/*
 *  ticket-478.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::ticket-478 Ensure that devices can only be connected using static synapses.

Synopsis: (ticket-478) run -> NEST exits if test fails

Description:
Ensure that NEST throws an exception if one tries to connect poisson_generator
(sending DSSpikeEvents), noise_generator (sending DSCurrentEvents) or multimeter
(sending DataLoggingRequest) to a neuron using a plastic synapse.

spike_generator slips through this test, since it usually sends SpikeEvent. But it
is no danger if it sends DSSpikeEvents for weighted spikes, since it sends precisely
one DSSpikeEvent per spike. 

Author: Hans Ekkehard Plesser, 2010-10-22
 */

(unittest) run
/unittest using

M_ERROR setverbosity


% Gap junctions not relevant for spiking devices as senders
/excluded_synapses [ /gap_junction ] def

% find all static and plastic synapses
% we identify as static all synapses that have the same default parameter names
% as static_synapse or static_synapse_lbl
/static_defaults
  /static_synapse GetDefaults keys { cvs } Map Sort
def
/static_lbl_defaults
  /static_synapse_lbl GetDefaults keys { cvs } Map Sort
def

/static_syn_models
  synapsedict keys
  { excluded_synapses exch MemberQ not } Select
  { GetDefaults keys { cvs } Map Sort static_defaults eq } Select
  { GetDefaults keys { cvs } Map Sort static_lbl_defaults eq } Select
def

/plastic_syn_models
  synapsedict keys
  { excluded_synapses exch MemberQ not } Select
  { GetDefaults keys { cvs } Map Sort static_defaults neq } Select
  { GetDefaults keys { cvs } Map Sort static_lbl_defaults neq } Select
def

% We perform the tests first for all relevant generators
/ds_models 
  [/gamma_sup_generator /mip_generator /noise_generator /poisson_generator 
   /ppd_sup_generator /sinusoidal_gamma_generator /poisson_generator_ps] 
  { modeldict exch known } Select   
def
            
ResetKernel
{
  static_syn_models
  { /st Set 
    % create new nodes for each connection to avoid any issues with prohibited multiple connections
    ds_models 
    { Create /iaf_neuron Create st Connect } forall  
  } forall
} pass_or_die

ResetKernel
plastic_syn_models
{
    /st Set
    ds_models
    {
      /d Set
      { d Create /iaf_neuron Create st Connect } fail_or_die
    } forall
} forall 

 % Now we test the multimeter. Since it uses non-zero rports, it must also fail on HPC synapses
 % We can currently only distinguish them by name. 
 /static_non_hpc_models static_syn_models { cvs -4 Take (_hpc) neq } Select def
 /models_to_fail plastic_syn_models  static_syn_models { cvs -4 Take (_hpc) eq } Select join def
 
ResetKernel
{
  static_non_hpc_models
  { /st Set 
    % create new nodes for each connection to avoid any issues with prohibited multiple connections
    /multimeter Create /iaf_neuron Create st Connect
  } forall
} pass_or_die

ResetKernel
models_to_fail
{
    /st Set
    /multimeter Create /iaf_neuron Create { st Connect } fail_or_die 
} forall 
  
endusing