/*
 *  test_gap_junction.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_gap_junction - Ensure that gap_junction connection can only be created between neurons which support them.

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

    Description:
    Ensure that NEST throws an exception if one tries to create illegal gap-junction connections. 
    Furthermore it is checked that the delay cannot be set for gap-junction connections.

    Author: Jan Hahne, October 2015
    SeeAlso: testsuite::test_hh_psc_alpha_gap, hh_psc_alpha_gap, gap_junction
  */

(unittest) run
/unittest using

% The following test needs the model hh_psc_alpha_gap, so
% this test should only run if we have GSL
skip_if_without_gsl

M_ERROR setverbosity

/setup
{
  ResetKernel

  2.0 /wfr_comm Set
  0 << /wfr_comm_interval wfr_comm >> SetStatus

  /iaf_neuron Create /neuron_no_gap Set
  /hh_psc_alpha_gap Create /neuron_gap Set
} def

% Check that accurate gap-junction connections can be created
{
  setup
  [neuron_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction >> 
  Connect
} pass_or_die

{
  setup
  [neuron_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction /weight 2.0 >> 
  Connect
} pass_or_die

{
  setup
  [neuron_gap] [neuron_gap]
  << /rule /all_to_all >> 
  << /model /gap_junction >> 
  Connect
} pass_or_die

% Check that delay cannot be set for gap-junction connections
{
  setup
  [neuron_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction /delay 2.0 >> 
  Connect
} fail_or_die

{
  setup
  [neuron_gap] [neuron_gap]
  << /rule /all_to_all >> 
  << /model /gap_junction /delay 2.0 >> 
  Connect
} fail_or_die

% Check that illegal gap-junction connections cannot be created
{
  setup
  [neuron_no_gap] [neuron_no_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction >> 
  Connect
} fail_or_die

{
  setup
  [neuron_no_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction >> 
  Connect
} fail_or_die

{
  setup
  [neuron_gap] [neuron_no_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction >> 
  Connect
} fail_or_die

% Check that non-symmetric gap-junction connections cannot be created
{
  setup
  [neuron_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric false >> 
  << /model /gap_junction /weight 2.0 >> 
  Connect
} fail_or_die

% Check that gap-junction connections contribute to the min_delay with wfr_comm_interval
{
  setup

  % First create one connection to change min_delay, max_delay... 
  neuron_no_gap neuron_no_gap 3.0 3.0 Connect

  0 /max_delay get /old_max Set
  0 /min_delay get /old_min Set

  % ... then create a gap-junction connection
  [neuron_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction >> 
  Connect

  0 /max_delay get /new_max Set
  0 /min_delay get /new_min Set

  % now check for correct min_delay and max_delay
  old_min wfr_comm leq 
  { 
    old_min new_min eq
  }
  {
    wfr_comm new_min eq  
  } ifelse
  old_max wfr_comm geq 
  { 
    old_max new_max eq 
  }
  {
    wfr_comm new_max eq   
  } ifelse
  and
} assert_or_die

% Check that gap-junction connections contribute to the max_delay with wfr_comm_interval
{
  setup

  % First create one connection to change min_delay, max_delay... 
  neuron_no_gap neuron_no_gap 1.0 1.0 Connect

  0 /max_delay get /old_max Set
  0 /min_delay get /old_min Set

  % ... then create a gap-junction connection
  [neuron_gap] [neuron_gap]
  << /rule /one_to_one /make_symmetric true >> 
  << /model /gap_junction >> 
  Connect

  0 /max_delay get /new_max Set
  0 /min_delay get /new_min Set

  % now check for correct min_delay and max_delay
  old_min wfr_comm leq 
  { 
    old_min new_min eq
  }
  {
    wfr_comm new_min eq  
  } ifelse
  old_max wfr_comm geq 
  { 
    old_max new_max eq 
  }
  {
    wfr_comm new_max eq   
  } ifelse
  and
} assert_or_die

endusing

