/*
 *  test_amat2_psc_exp.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_amat2_psc_exp - sli script for overall test of amat2_psc_exp neuron model

    Synopsis: (test_amat2_psc_exp) run -> compares response to current step with reference data 

    Description:
    test_amat2_psc_exp.sli is an overall test of the mat2_neuron model connected
    to some useful devices.

    A DC current is injected into the neuron using a current generator
    device. The membrane potential the threshold potential as well as the
    spiking activity are recorded by corresponding devices.

    It can be observed how the current charges the membrane a spike
    is emitted the threshold potential is updated and evaluated whereas
    the membrane potential is not resetted and further evaluated too.
    Additionally the neuron becomes refractory after emitting a spike.

    The timing of the various events on the simulation grid is of
    particular interest and crucial for the consistency of the
    simulation scheme.

    Although 0.1 cannot be represented in the IEEE double data type it
    is safe to simulate with a resolution (computation step size) of 0.1
    ms because by default nest is built with a timebase enabling exact
    representation of 0.1 ms.

    The expected output is documented and briefly commented at the end of
    the script. The textual output of the multimeter documented in this file
    can be regenerated by setting adding /to_screen true to the SetStatus
    call of mm below.

    Other test programs discuss the various aspects of this script in detail
    see the SeeAlso key below.

    Author:  November 2014 Hans E Plesser based on test_mat2_psc_exp
    SeeAlso: testsuite::test_iaf, testsuite::test_iaf_i0, testsuite::test_iaf_i0_refractory, testsuite::test_iaf_dc
*/

(unittest) run
/unittest using

0.1 /h Set

% First Test -------------------------------------------------------
%
% This test is identical with test_mat2_psc_exp and ensures that 
% both models behave identically provided the voltage-dependent threshold
% component is deactivated (beta == 0). Since the models have different
% default parameter values we need to obtain default values from 
% mat2_psc_exp.

ResetKernel

0 << 
      /local_num_threads 1 
      /resolution h
  >> SetStatus

% explicitly set threshold omega here to ensure that after 
% change of definition of omega from relative to E_L to absolute
% we still get the original results; see #506.
/mat2p /mat2_psc_exp GetDefaults def
/amat2_psc_exp << /omega -51.0 
                  /beta 0.0 
                  /E_L mat2p/E_L ::
                  /I_e mat2p/I_e ::
                  /C_m mat2p/C_m ::
                  /tau_m mat2p/tau_m ::
                  /tau_syn_ex mat2p/tau_syn_ex ::
                  /tau_syn_in mat2p/tau_syn_in ::
                  /t_ref mat2p/t_ref ::
                  /tau_1 mat2p/tau_1 ::
                  /tau_2 mat2p/tau_2 ::
                  /alpha_1 mat2p/alpha_1 ::
                  /alpha_2 mat2p/alpha_2 ::
                  /tau_v mat2p/tau_m :: 10. add  % must differ from tau_m but is irrelevant for beta==0 
               >> Create /neuron Set

/dc_generator Create /dc_gen Set
dc_gen << /amplitude 2400. >> SetStatus

/multimeter Create /mm Set
mm <<
     /withtime true
     /interval h
     /record_from [/V_m /V_th] % record non-resetting membrane potential
                               % and evaluated threshold potential
     /time_in_steps true
   >> SetStatus

/spike_detector Create /sp_det Set
sp_det <<
         /withtime true
         /time_in_steps true
         /withgid true
       >> SetStatus


dc_gen neuron 1.0 h Connect
mm neuron     1.0 h Connect
neuron sp_det 1.0 h Connect

8 Simulate

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Expected output of this program:
% 
% The output send to std::cout is a superposition of the output of
% the multimeter and the spike detector. Both multimeter and spike
% detector are connected to the same neuron. 
%

{
 sp_det [/events [/times]] get cva   	     % array of recorded data
 eq                                          % compare
}

%%%%%%%%%%
% spike times (in steps)

[[11 32 54]] % The threshold potential crosses the membrane potential at time
     	     % step 31. But due to the refractory period of 2 ms the neuron
	         % is not allowed to fire until time step 32.

exch assert_or_die


{                                            % reference data
 dup Transpose First /test_times Set         % times of reference

 mm [/events [/times /V_m /V_th]] get cva    % array of recorded data
  6 ToUnitTestPrecision                      % to precision of reference
  Transpose                                  % all recorded tuples
  {First test_times exch MemberQ } Select    % those with reference
 eq                                          % compare
}

%%%%%%%%%%
% time (in steps)  membrane potential V_m (in mV)  threshold V_th (in mV)

[
[ 1	-70		-51	 ] % <--- dc_gen is switched on
[ 2	-70		-51	 ] % <--- The DC current arrives at neuron
[ 3	-67.6238	-51	 ] % <-	  but has not affected the potential yet
[ 4	-65.2947	-51	 ] %   |
[ 5	-63.0117	-51	 ] %    - First evaluation of the DC current. The
[ 6	-60.774		-51	 ] %      threshold potential stays constant
[ 7	-58.5805	-51	 ] %      because it is at its resting level.
[ 8	-56.4305	-51	 ]
[ 9	-54.323		-51	 ]
[ 10	-52.2573	-51	 ]
[ 11	-50.2324	-12	 ] % <--- The membrane potential crossed the
[ 12	-48.2477	-12.3692 ] % <-   threshold potential the first time.
[ 13	-46.3023	-12.7346 ] %   |  The threshold potential is updated and
[ 14	-44.3953	-13.0965 ] %   |  the membrane potential is further evaluated
[ 15	-42.5262	-13.4548 ] %   |  without resetting.
[ 16	-40.694		-13.8095 ] %   |
[ 17	-38.8982	-14.1607 ] %    - The threshold potential decays double
[ 18	-37.1379	-14.5084 ] %      exponential towards its resting level.
[ 19	-35.4124	-14.8527 ]
[ 20	-33.7212	-15.1935 ]
[ 21	-32.0634	-15.531	 ]
]


exch assert_or_die

% ------------------------------------------------------------
% We now know that the model works including spike detection
% except for the yet untested voltage-dependent component.
% We study this in subthreshold mode where we can obtain 
% exact solutions. We set alpha1 and alpha2 to non-zero
% values. As there is no spike, they should not affect the result.
% and set a constant input current.
%
% Reference data obtained with Mathematica.

ResetKernel

0 << 
      /local_num_threads 1 
      /resolution h
  >> SetStatus

/amat2_psc_exp << /omega 2. 
                  /beta 2.0 
                  /E_L 0. 
				  /V_m -2.    % V_m < V_th for t < 10ms -> no spikes
                  /I_e 10.
                  /alpha_1 10.
                  /alpha_2 20.
               >> Create /neuron Set

/multimeter Create /mm Set
mm <<
     /withtime true
     /interval h 
     /record_from [/V_m /V_th /V_th_v] % record non-resetting membrane potential
                                       % threshold pot and kernel contrib
     /time_in_steps true
   >> SetStatus

mm neuron 1.0 h Connect

10.1 Simulate

{                                            % reference data
  dup Transpose First /test_times Set         % times of reference

  mm [/events [/times /V_m /V_th /V_th_v]] get cva    % array of recorded data
  6 ToUnitTestPrecision                      % to precision of reference
  Transpose                                  % all recorded tuples
  { First test_times exch MemberQ } Select   % those with reference
  eq                                          % compare
}

[
 [ 10 -1.76209 2.21168 0.211679]
 [ 20 -1.54683 2.71733 0.717335]
 [ 30 -1.35205 3.36815 1.36815]
 [ 40 -1.1758 4.06297 2.06297]
 [ 50 -1.01633 4.73557 2.73557]
 [ 60 -0.872029 5.34504 3.34504]
 [ 70 -0.741463 5.86852 3.86852]
 [ 80 -0.623322 6.29576 4.29576]
 [ 90 -0.516424 6.62509 4.62509]
 [100 -0.419699 6.86044 4.86044]
]

exch
assert_or_die




endusing
