/*
 *  test_iaf_dc_aligned_automatic.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_iaf_dc_aligned_automatic - sli script for test of iaf_neuron resolution independence 

Synopsis: (test_iaf_dc_aligned_automatic) run -> compare response with reference data


Description:

  test_iaf_dc_aligned_automatic.sli is a modified version of 
  test_iaf_dc_aligned_delay.sli .

  The code of this program is now identical to
  test_iaf_dc_aligned_delay.sli. Previous versions used a different
  definition of start which was not independent of the resolution.
  Therefore, an additional device property /on was required.  See
  test_iaf_dc_aligned_automatic.sli for details.

  The documentation below refers to the old definition of start

  The output generated is exactly identical to the output of the 
  previous file. The dependence  of the simulation script on the 
  computation step size is completely removed by using the capability
  of the DC generator to adjust the required starting time to the 
  computation time step. This functionality is implemented in the Device
  base class and, thus, available to all devices.

  Instead of specifying the start time of the generator as in 
  test_iaf_dc_aligned_delay.sli, the emission time of the first current
  event is specified. A device can only take action in a step t-h -> t.
  When t-h represents the start time of the device, t is the earliest time
  stamp of an emitted event. In our case the time stamp is the onset of the
  current. Thus, both times can not simultaneously be independent of the 
  computation time step h. It is sufficient to specify one of the two measures,
  the other one is computed automatically. Internally, only the start time 
  is stored. A warning is issued when both measures are specified because 
  a difference other than h would be meaningless and a difference of h may
  not be representable by the two double values. In case both properties are 
  specified, on  overrides start. The timer of the device does not rely on
  computing differences between doubles but uses the exact representation of 
  time provided by the simulation kernel.

  An inspection of the property dictionary of the DC generator at different
  computation step sizes shows the relationship between DC generator 
  on and start.

    h=0.1ms                   h=0.5ms  
    <<                        <<
       /start 1.9                /start 1.5
       /on 2.0                   /on 2.0
    >>                         >>

  No output of the spike detector is visible here because of the short simulation
  time of only 6 ms. Set the simulation time to larger values to verify the 
  consistency of voltage meter and spike detector.

  The expected output is documented at the end of the script.

  July 2004,
   updated, Diesmann

Author:  February 2004, Diesmann, Gewaltig, Plesser
SeeAlso: testsuite::test_iaf_dc, testsuite::test_iaf_dc_aligned, testsuite::test_iaf_dc_aligned_delay
*/


/unittest (6688) require
/unittest using


1.0 /max_h Set       % in ms, maximal computation time step

1.0 /dc_delay Set    % in ms, delay of the connection from 
                     % DC generator to neuron

3.0 /dc_visible Set  % in ms, desired onset of the DC current
                     % in the neuron

dc_visible dc_delay sub /dc_on Set
                     % the onset time of the DC generator 
                     % required to make the current visible at
                     % the neuron at the desired time

dc_delay /max_delay Set
                     % the maximal delay tolereated by the 
                     % simulation kernel (in ms) needs to be
                     % larger or equal to the maximal delay
                     % used in this script



dc_delay max_h lt
{
 cout (Delay between DC generator and neuron is too small) <-- endl
      (for the range of step sizes to be tested) <-- endl ;
} if

dc_delay max_delay gt
{
 cout (the maximal delay tolerated by the simulation kernel) <-- endl
      (is too small for the specified delays) <-- endl ;
} if




/AlignedInjection  
{
 << >> begin    
 /d Set /h Set   
 
  ResetKernel

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


  /iaf_neuron Create /neuron Set

  /dc_generator Create /dc_gen Set
  dc_gen <<  
           /amplitude 1000.          % in pA
           /origin 0.                % in ms
           /start  dc_on             % in ms,   was /on dc_on
          >> SetStatus %  ^
                       %  |
                       %   -- SLI code does not depend on
                       %      computation step size h.

  /voltmeter Create /vm Set
  vm << /withtime true /to_memory true /time_in_steps true /interval h >> SetStatus

  /spike_detector Create /sd Set 
  sd << /withtime true /to_memory true /time_in_steps true >> SetStatus

  dc_gen neuron 1.0 dc_delay Connect
                     %  ^
  vm neuron Connect  %  | 
                     %   --- no dependence on the computation 
  neuron sd Connect  %       step size h

  6 Simulate

  
 d Transpose First /test_times Set          % times of reference

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

 d eq                                       % compare

 end
} def




{
 % h d,  vector of resolutions and compressed reference data   
 InflateUnitTestData 

 Transpose {AlignedInjection} MapThread

 true exch {and} Fold   % remove this line to see individual results
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%
% Expected output of this program:
% 
% The output send to std::cout is a superposition of the output of  
% the voltmeter and the spike detector. Both, voltmeter and spike 
% detector are connected to the same neuron. 
%
%
% h=   (in ms)
[0.1   0.2    0.5   1.0]
%
% time                    voltage
[
% ...
[ 25            5           -70]
[ 26     12                 -70]
[ 27                        -70]
[ 28     14                 -70]
[ 29                        -70]
[ 30     15     6     3     -70] %  <---- Current starts to affect
[ 31                        -69.602]  %   neuron (visible in state variable
[ 32     16                 -69.2079] %   y0). This is the desired onset of
[ 33                        -68.8178] %    t= 3.0 ms.
[ 34     17                 -68.4316]
[ 35            7           -68.0492]
[ 36     18                 -67.6706]
[ 37                        -67.2958]
[ 38     19                 -66.9247]
[ 39                        -66.5572]
[ 40     20     8     4     -66.1935]
[ 41                        -65.8334]
[ 42     21                 -65.4768]
% ...
]
%


rolld assert_or_die