/*
 *  ticket-459.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-459 - test that changing the leak reversal potential leaves all other neuron parameters else unchanged

Synopsis: (ticket-459.sli) run -> dies if assertion fails

Description:
For all models having a reversal potential E_L, we change this potential and check that
all other parameters and properties of the model remain unchanged. #459 reports that the 
order in which E_L and V_th are set determines which values are actually set. This is a
direct consequence of incorrect handling of changes to E_L, which show up as changes in,
e.g. V_m and V_th as a side effect of changing E_L. This happened in those neuron models
that internally represent voltages relative to E_L and did not adjust those values on
changes to E_L.

Author: Plesser
FirstVersion: 2011-02-12
*/

/unittest (8831) require
/unittest using

M_ERROR setverbosity

% Execute test for one model
% Argument: model name
% Result: true or false
/run_test
{
  /model Set
  model Create /nrn Set

  % find any keys to double values that are not finite
  % set them to finite value to make sure that they will
  % be tested below
  /infdict << >> def
  model GetDefaults /mdefs Set
  mdefs keys 
  {  /k Set mdefs k get DoubleQ { FiniteQ not { infdict k -150. put } if } if pop }
  forall
  nrn infdict SetStatus

  nrn GetStatus /pre Set
  pre /E_L get /ELorig Set

  ELorig 1.0 add /ELnew Set   
  nrn << /E_L ELnew >> SetStatus
  nrn GetStatus /post Set

  pre keys post keys eq assert
  % compare all numeric pre-post values, except changed E_L
  pre /E_L undef pre keys
  { 
    /key Set 
     pre key get DoubleQ
     {
        dup post key get sub abs % |post-pre| < 1e-15 |pre|
        exch abs 1e-15 mul leq 
     }
     { pop true }
     ifelse
  } Map 
  true exch { and } Fold
  dup not { model =only (  FAILED) = } if
} 
def

{
  modeldict keys { 
    dup GetDefaults /E_L known
    { 
      run_test 
    }
    {
      pop   % no E_L, pass, true by default
      true
    } ifelse
  } Map
  true exch { and } Fold
}
assert_or_die