Hi Thorben,

After doing a diff with the iaf_psc_exp source code, I believe this is the problematic part:

if ( S_.r_ref_ == 0 ) // neuron not refractory, so evolve V
      S_.V_m_ = S_.V_m_ * V_.P22_ + S_.i_syn_ex_ * V_.P21ex_                                                            // membrane potential equals membrane potential times exponetial decay plus postsynpatic excitatory/inhibitory currents time numerical stability factor plus new input current times exponential decay
        + S_.i_syn_in_ * V_.P21in_ + ( P_.I_e_ + S_.i_0_ ) * V_.P20_;                                           // S_.V_m : membrane potential
    else                                                                                    // V_.P22 : membrane potential decay
        {                                                                                                                                                                               // S_.i_syn_ex / S_.i_syn_in : excitatory / inhibitory postsynaptic current
        }                                                                                                                                                                               // V_.P21in / V_.P21ex : numeric stability criterion parameter
                                                                                                                                                                                        // P_.I_e : static input current
        {                                                                                       // S_.i_0_ : presynaptic input current this timestep 
        }                                                                                                                                                                               // S_.i_1_ : presynaptic input current next timestep
        
        {
        }
        
      --S_.r_ref_; // neuron is absolute refractory


The syntax seems wrong for the ELSE part (maybe due to automatic source code formatting), with the presence of empty brackets. This means --S_.r_ref_ is executed at every timestep and thus the IF part S_.r_ref_ == 0 (which updates V_m) is never executed.
Just remove the unnecessary brackets in the ELSE part.

if ( S_.r_ref_ == 0 ) // neuron not refractory, so evolve V
      S_.V_m_ = S_.V_m_ * V_.P22_ + S_.i_syn_ex_ * V_.P21ex_ + S_.i_syn_in_ * V_.P21in_ + ( P_.I_e_ + S_.i_0_ ) * V_.P20_;
else     
--S_.r_ref_; // neuron is absolute refractory

I hope this helps.

Cordially,
Simon

On Tue, 2019-07-02 at 09:51 +0000, tschoepe@techfak.uni-bielefeld.de wrote:
Dear All,

I am relatively new to nest and want to implement a new neuron model.
I've worked a lot with SpiNNaker previously. 
I am a research assistant and PhD student at the Technical Faculty in Bielefeld, Germany.

Currently, I am trying to implement a new neuron model into nest. Because I want to use
this model later on in the neurorbotics platform (NRP) I directly installed the NRP
and I am using the nest version installed together with the NRP.

I followed the instructions at:
https://nest.github.io/nest-simulator/extension_modules
I am able to install mymodule and to run the neuron model pif_psc_alpha coming with it.
Now I tried to extend mymodule with a new neuron model. To achieve that I copied the
iaf_psc_exp model's cpp and h file, renamed them to iaf_psc_exp_semd and changed them
according to pif_psc_alpha. 
I was able to include the model into the nest library and run a short example script.
Unfortunately, the iaf_psc_exp_semd model doesn't react to any stimulation with spikes.
The membrane potential always stays at E_L.
When I use the same python script but with the iad_psc_exp model I see a clear change
in the membrane potential. 
Could someone check the files I've created for the new iaf_psc_exp_semd model to see
what is wrong/missing?

Thanks a lot and best regards,
Thorben Schoepe

First file:

/*
 *  iaf_psc_exp_semd.h
 *
 *  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/>.
 *
 */

#ifndef IAF_PSC_EXP_SEMD_H
#define IAF_PSC_EXP_SEMD_H

// Includes from nestkernel:
#include "archiving_node.h"
#include "connection.h"
#include "event.h"
#include "nest_types.h"
#include "recordables_map.h"
#include "ring_buffer.h"
#include "universal_data_logger.h"

// Includes from sli:
#include "dictdatum.h"

namespace mynest
{
/* BeginDocumentation
   Name: iaf_psc_exp - Leaky integrate-and-fire neuron model with exponential
                       PSCs.

   Description:
   iaf_psc_expp is an implementation of a leaky integrate-and-fire model
   with exponential shaped postsynaptic currents (PSCs) according to [1].
   Thus, postsynaptic currents have an infinitely short rise time.

   The threshold crossing is followed by an absolute refractory period (t_ref)
   during which the membrane potential is clamped to the resting potential
   and spiking is prohibited.

   The linear subthresold dynamics is integrated by the Exact
   Integration scheme [2]. The neuron dynamics is solved on the time
   grid given by the computation step size. Incoming as well as emitted
   spikes are forced to that grid.

   An additional state variable and the corresponding differential
   equation represents a piecewise constant external current.

   The general framework for the consistent formulation of systems with
   neuron like dynamics interacting by point events is described in
   [2]. A flow chart can be found in [3].

   Remarks:
   The present implementation uses individual variables for the
   components of the state vector and the non-zero matrix elements of
   the propagator.  Because the propagator is a lower triangular matrix
   no full matrix multiplication needs to be carried out and the
   computation can be done "in place" i.e. no temporary state vector
   object is required.

   The template support of recent C++ compilers enables a more succinct
   formulation without loss of runtime performance already at minimal
   optimization levels. A future version of iaf_psc_exp will probably
   address the problem of efficient usage of appropriate vector and
   matrix objects.

   Parameters:
   The following parameters can be set in the status dictionary.

   E_L          double - Resting membrane potential in mV.
   C_m          double - Capacity of the membrane in pF
   tau_m        double - Membrane time constant in ms.
   tau_syn_ex   double - Time constant of postsynaptic excitatory currents in ms
   tau_syn_in   double - Time constant of postsynaptic inhibitory currents in ms
   t_ref        double - Duration of refractory period (V_m = V_reset) in ms.
   V_m          double - Membrane potential in mV
   V_th         double - Spike threshold in mV.
   V_reset      double - Reset membrane potential after a spike in mV.
   I_e          double - Constant input current in pA.
   t_spike      double - Point in time of last spike in ms.

Remarks:

   If tau_m is very close to tau_syn_ex or tau_syn_in, the model
   will numerically behave as if tau_m is equal to tau_syn_ex or
   tau_syn_in, respectively, to avoid numerical instabilities.
   For details, please see IAF_Neruons_Singularity.ipynb in the
   NEST source code (docs/model_details).

   iaf_psc_exp can handle current input in two ways: Current input
   through receptor_type 0 are handled as stepwise constant current
   input as in other iaf models, i.e., this current directly enters
   the membrane potential equation. Current input through
   receptor_type 1, in contrast, is filtered through an exponential
   kernel with the time constant of the excitatory synapse,
   tau_syn_ex. For an example application, see [4].

   References:
   [1] Misha Tsodyks, Asher Uziel, and Henry Markram (2000) Synchrony Generation
   in Recurrent Networks with Frequency-Dependent Synapses, The Journal of
   Neuroscience, 2000, Vol. 20 RC50 p. 1-5
   [2] Rotter S & Diesmann M (1999) Exact simulation of time-invariant linear
   systems with applications to neuronal modeling. Biologial Cybernetics
   81:381-402.
   [3] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001) State space
   analysis of synchronous spiking in cortical neural networks.
   Neurocomputing 38-40:565-571.
   [4] Schuecker J, Diesmann M, Helias M (2015) Modulated escape from a
   metastable state driven by colored noise.
   Physical Review E 92:052119

   Sends: SpikeEvent

   Receives: SpikeEvent, CurrentEvent, DataLoggingRequest

   SeeAlso: iaf_psc_exp_ps

   FirstVersion: March 2006
   Author: Moritz Helias
*/

/**
 * Leaky integrate-and-fire neuron with exponential PSCs.
 */
class iaf_psc_exp_semd : public nest::Archiving_Node
{

public:
  iaf_psc_exp_semd();
  iaf_psc_exp_semd( const iaf_psc_exp_semd& );

  /**
   * Import sets of overloaded virtual functions.
   * @see Technical Issues / Virtual Functions: Overriding, Overloading, and
   * Hiding
   */
  using nest::Node::handle;
  using nest::Node::handles_test_event;

  nest::port send_test_event( Node&, nest::port, nest::synindex, bool );

  void handle( nest::SpikeEvent& );
  void handle( nest::CurrentEvent& );
  void handle( nest::DataLoggingRequest& );

  nest::port handles_test_event( nest::SpikeEvent&, nest::port );
  nest::port handles_test_event( nest::CurrentEvent&, nest::port );
  nest::port handles_test_event( nest::DataLoggingRequest&, nest::port );

  void get_status( DictionaryDatum& ) const;
  void set_status( const DictionaryDatum& );

private:
  void init_state_( const Node& proto );
  void init_buffers_();
  void calibrate();

  void update(nest::Time const&, const long, const long );

  // The next two classes need to be friends to access the State_ class/member
  friend class nest::RecordablesMap< iaf_psc_exp_semd >;
  friend class nest::UniversalDataLogger< iaf_psc_exp_semd >;

  // ----------------------------------------------------------------

  /**
   * Independent parameters of the model.
   */
  struct Parameters_
  {

    /** Membrane time constant in ms. */
    double Tau_;

    /** Membrane capacitance in pF. */
    double C_;

    /** Refractory period in ms. */
    double t_ref_;

    /** Resting potential in mV. */
    double E_L_;

    /** External current in pA */
    double I_e_;

    /** Threshold, RELATIVE TO RESTING POTENTAIL(!).
        I.e. the real threshold is (E_L_+Theta_). */
    double Theta_;

    /** reset value of the membrane potential */
    double V_reset_;

    /** Time constant of excitatory synaptic current in ms. */
    double tau_ex_;

    /** Time constant of inhibitory synaptic current in ms. */
    double tau_in_;

    Parameters_(); //!< Sets default parameter values

    void get( DictionaryDatum& ) const; //!< Store current values in dictionary

    /** Set values from dictionary.
     * @returns Change in reversal potential E_L, to be passed to State_::set()
     */
    double set( const DictionaryDatum& );
  };

  // ----------------------------------------------------------------

  /**
   * State variables of the model.
   */
  struct State_
  {
    // state variables
    //! synaptic stepwise constant input current, variable 0
    double i_0_;
    double i_1_;      //!< presynaptic stepwise constant input current
    double i_syn_ex_; //!< postsynaptic current for exc. inputs, variable 1
    double i_syn_in_; //!< postsynaptic current for inh. inputs, variable 1
    double V_m_;      //!< membrane potential, variable 2

    //! absolute refractory counter (no membrane potential propagation)
    int r_ref_;

    State_(); //!< Default initialization

    void get( DictionaryDatum&, const Parameters_& ) const;

    /** Set values from dictionary.
     * @param dictionary to take data from
     * @param current parameters
     * @param Change in reversal potential E_L specified by this dict
     */
    void set( const DictionaryDatum&, const Parameters_&, const double );
  };

  // ----------------------------------------------------------------

  /**
   * Buffers of the model.
   */
  struct Buffers_
  {
    Buffers_( iaf_psc_exp_semd& );
    Buffers_( const Buffers_&, iaf_psc_exp_semd& );

    /** buffers and sums up incoming spikes/currents */
    nest::RingBuffer spikes_ex_;
    nest::RingBuffer spikes_in_;
    std::vector< nest::RingBuffer > currents_;

    //! Logger for all analog data
    nest::UniversalDataLogger< iaf_psc_exp_semd > logger_;
  };

  // ----------------------------------------------------------------

  /**
   * Internal variables of the model.
   */
  struct Variables_
  {
    /** Amplitude of the synaptic current.
        This value is chosen such that a post-synaptic potential with
        weight one has an amplitude of 1 mV.
        @note mog - I assume this, not checked.
    */
    //    double PSCInitialValue_;

    // time evolution operator
    double P20_;
    double P11ex_;
    double P11in_;
    double P21ex_;
    double P21in_;
    double P22_;

    double weighted_spikes_ex_;
    double weighted_spikes_in_;

    int RefractoryCounts_;
  };

  // Access functions for UniversalDataLogger -------------------------------

  //! Read out the real membrane potential
  inline double
  get_V_m_() const
  {
    return S_.V_m_ + P_.E_L_;
  }

  inline double
  get_weighted_spikes_ex_() const
  {
    return V_.weighted_spikes_ex_;
  }

  inline double
  get_weighted_spikes_in_() const
  {
    return V_.weighted_spikes_in_;
  }

  inline double
  get_I_syn_ex_() const
  {
    return S_.i_syn_ex_;
  }

  inline double
  get_I_syn_in_() const
  {
    return S_.i_syn_in_;
  }

  // ----------------------------------------------------------------

  /**
   * @defgroup iaf_psc_exp_data
   * Instances of private data structures for the different types
   * of data pertaining to the model.
   * @note The order of definitions is important for speed.
   * @{
   */
  Parameters_ P_;
  State_ S_;
  Variables_ V_;
  Buffers_ B_;
  /** @} */

  //! Mapping of recordables names to access functions
  static nest::RecordablesMap< iaf_psc_exp_semd > recordablesMap_;
};


inline nest::port
mynest::iaf_psc_exp_semd::send_test_event( Node& target,
  nest::port receptor_type,
  nest::synindex,
  bool )
{
  nest::SpikeEvent e;
  e.set_sender( *this );
  return target.handles_test_event( e, receptor_type );
}

inline nest::port
mynest::iaf_psc_exp_semd::handles_test_event( nest::SpikeEvent&, nest::port receptor_type )
{
  if ( receptor_type != 0 )
    throw nest::UnknownReceptorType( receptor_type, get_name() );
  return 0;
}

inline nest::port
mynest::iaf_psc_exp_semd::handles_test_event( nest::CurrentEvent&, nest::port receptor_type )
{
  if ( receptor_type == 0 )
    return 0;
  else if ( receptor_type == 1 )
    return 1;
  else
    throw nest::UnknownReceptorType( receptor_type, get_name() );
}

inline nest::port
mynest::iaf_psc_exp_semd::handles_test_event( nest::DataLoggingRequest& dlr, nest::port receptor_type )
{
  if ( receptor_type != 0 )
    throw nest::UnknownReceptorType( receptor_type, get_name() );
  return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
}

inline void
iaf_psc_exp_semd::get_status( DictionaryDatum& d ) const
{
  P_.get( d );
  S_.get( d, P_ );
  Archiving_Node::get_status( d );

  ( *d )[ nest::names::recordables ] = recordablesMap_.get_list();
}

inline void
iaf_psc_exp_semd::set_status( const DictionaryDatum& d )
{
  Parameters_ ptmp = P_;                 // temporary copy in case of errors
  const double delta_EL = ptmp.set( d ); // throws if BadProperty
  State_ stmp = S_;                      // temporary copy in case of errors
  stmp.set( d, ptmp, delta_EL );         // throws if BadProperty

  // We now know that (ptmp, stmp) are consistent. We do not
  // write them back to (P_, S_) before we are also sure that
  // the properties to be set in the parent class are internally
  // consistent.
  Archiving_Node::set_status( d );

  // if we get here, temporaries contain consistent set of properties
  P_ = ptmp;
  S_ = stmp;
}

} // namespace

#endif // IAF_PSC_EXP_SEMD_H

Second file:

/*
 *  iaf_psc_exp_semd.cpp
 *
 *  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/>.
 *
 */

#include "iaf_psc_exp_semd.h"

// C++ includes:
#include <limits>

// Includes from libnestutil:
#include "numerics.h"
#include "propagator_stability.h"

// Includes from nestkernel:
#include "event_delivery_manager_impl.h"
#include "exceptions.h"
#include "kernel_manager.h"
#include "universal_data_logger_impl.h"

// Includes from sli:
#include "dict.h"
#include "dictutils.h"
#include "doubledatum.h"
#include "integerdatum.h"
#include "lockptrdatum.h"

using namespace nest;

/* ----------------------------------------------------------------
 * Recordables map
 * ---------------------------------------------------------------- */

nest::RecordablesMap< mynest::iaf_psc_exp_semd > mynest::iaf_psc_exp_semd::recordablesMap_;

namespace nest
{
// Override the create() method with one call to RecordablesMap::insert_()
// for each quantity to be recorded.
template <>
void
RecordablesMap< mynest::iaf_psc_exp_semd >::create()
{
  // use standard names whereever you can for consistency!
  insert_( names::V_m, &mynest::iaf_psc_exp_semd::get_V_m_ );
  insert_( names::weighted_spikes_ex, &mynest::iaf_psc_exp_semd::get_weighted_spikes_ex_ );
  insert_( names::weighted_spikes_in, &mynest::iaf_psc_exp_semd::get_weighted_spikes_in_ );
  insert_( names::I_syn_ex, &mynest::iaf_psc_exp_semd::get_I_syn_ex_ );
  insert_( names::I_syn_in, &mynest::iaf_psc_exp_semd::get_I_syn_in_ );
}
}

/* ----------------------------------------------------------------
 * Default constructors defining default parameters and state
 * ---------------------------------------------------------------- */

mynest::iaf_psc_exp_semd::Parameters_::Parameters_()
  : Tau_( 10.0 )             // in ms
  , C_( 250.0 )              // in pF
  , t_ref_( 2.0 )            // in ms
  , E_L_( -70.0 )            // in mV
  , I_e_( 0.0 )              // in pA
  , Theta_( -55.0 - E_L_ )   // relative E_L_
  , V_reset_( -70.0 - E_L_ ) // in mV
  , tau_ex_( 2.0 )           // in ms
  , tau_in_( 2.0 )           // in ms
{
}

mynest::iaf_psc_exp_semd::State_::State_()
  : i_0_( 0.0 )
  , i_syn_ex_( 0.0 )
  , i_syn_in_( 0.0 )
  , V_m_( 0.0 )
  , r_ref_( 0 )
{
}

/* ----------------------------------------------------------------
 * Parameter and state extractions and manipulation functions
 * ---------------------------------------------------------------- */

void
mynest::iaf_psc_exp_semd::Parameters_::get( DictionaryDatum& d ) const
{
  def< double >( d, names::E_L, E_L_ ); // resting potential
  def< double >( d, names::I_e, I_e_ );
  def< double >( d, names::V_th, Theta_ + E_L_ ); // threshold value
  def< double >( d, names::V_reset, V_reset_ + E_L_ );
  def< double >( d, names::C_m, C_ );
  def< double >( d, names::tau_m, Tau_ );
  def< double >( d, names::tau_syn_ex, tau_ex_ );
  def< double >( d, names::tau_syn_in, tau_in_ );
  def< double >( d, names::t_ref, t_ref_ );
}

double
mynest::iaf_psc_exp_semd::Parameters_::set( const DictionaryDatum& d )
{
  // if E_L_ is changed, we need to adjust all variables defined relative to
  // E_L_
  const double ELold = E_L_;
  updateValue< double >( d, names::E_L, E_L_ );
  const double delta_EL = E_L_ - ELold;

  if ( updateValue< double >( d, names::V_reset, V_reset_ ) )
    V_reset_ -= E_L_;
  else
    V_reset_ -= delta_EL;

  if ( updateValue< double >( d, names::V_th, Theta_ ) )
    Theta_ -= E_L_;
  else
    Theta_ -= delta_EL;

  updateValue< double >( d, names::I_e, I_e_ );
  updateValue< double >( d, names::C_m, C_ );
  updateValue< double >( d, names::tau_m, Tau_ );
  updateValue< double >( d, names::tau_syn_ex, tau_ex_ );
  updateValue< double >( d, names::tau_syn_in, tau_in_ );
  updateValue< double >( d, names::t_ref, t_ref_ );

  if ( V_reset_ >= Theta_ )
    throw nest::BadProperty( "Reset potential must be smaller than threshold." );

  if ( C_ <= 0 )
    throw nest::BadProperty( "Capacitance must be strictly positive." );

  if ( Tau_ <= 0 || tau_ex_ <= 0 || tau_in_ <= 0 )
    throw nest::BadProperty(
      "Membrane and synapse time constants must be strictly positive." );

  if ( t_ref_ < 0 )
    throw nest::BadProperty( "Refractory time must not be negative." );

  return delta_EL;
}

void
mynest::iaf_psc_exp_semd::State_::get( DictionaryDatum& d, const Parameters_& p ) const
{
  def< double >( d, names::V_m, V_m_ + p.E_L_ ); // Membrane potential
}

void
mynest::iaf_psc_exp_semd::State_::set( const DictionaryDatum& d,
  const Parameters_& p,
  double delta_EL )
{
  if ( updateValue< double >( d, names::V_m, V_m_ ) )
    V_m_ -= p.E_L_;
  else
    V_m_ -= delta_EL;
}

mynest::iaf_psc_exp_semd::Buffers_::Buffers_( iaf_psc_exp_semd& n )
  : logger_( n )
{
}

mynest::iaf_psc_exp_semd::Buffers_::Buffers_( const Buffers_&, iaf_psc_exp_semd& n )
  : logger_( n )
{
}

/* ----------------------------------------------------------------
 * Default and copy constructor for node
 * ---------------------------------------------------------------- */

mynest::iaf_psc_exp_semd::iaf_psc_exp_semd()
  : Archiving_Node()
  , P_()
  , S_()
  , B_( *this )
{
  recordablesMap_.create();
}

mynest::iaf_psc_exp_semd::iaf_psc_exp_semd( const iaf_psc_exp_semd& n )
  : Archiving_Node( n )
  , P_( n.P_ )
  , S_( n.S_ )
  , B_( n.B_, *this )
{
}

/* ----------------------------------------------------------------
 * Node initialization functions
 * ---------------------------------------------------------------- */

void
mynest::iaf_psc_exp_semd::init_state_( const Node& proto )
{
  const iaf_psc_exp_semd& pr = downcast< iaf_psc_exp_semd >( proto );
  S_ = pr.S_;
}

void
mynest::iaf_psc_exp_semd::init_buffers_()
{
  B_.spikes_ex_.clear(); // includes resize
  B_.spikes_in_.clear(); // includes resize
  B_.currents_.clear();  // includes resize
  B_.logger_.reset();
  Archiving_Node::clear_history();
}

void
mynest::iaf_psc_exp_semd::calibrate()
{
  B_.currents_.resize( 2 );
  // ensures initialization in case mm connected after Simulate
  B_.logger_.init();

  const double h = Time::get_resolution().get_ms();

  // numbering of state vaiables: i_0 = 0, i_syn_ = 1, V_m_ = 2

  // commented out propagators: forward Euler
  // needed to exactly reproduce Tsodyks network

  // these P are independent
  V_.P11ex_ = std::exp( -h / P_.tau_ex_ );
  // P11ex_ = 1.0-h/tau_ex_;

  V_.P11in_ = std::exp( -h / P_.tau_in_ );
  // P11in_ = 1.0-h/tau_in_;

  V_.P22_ = std::exp( -h / P_.Tau_ );
  // P22_ = 1.0-h/Tau_;

  // these are determined according to a numeric stability criterion
  V_.P21ex_ = propagator_32( P_.tau_ex_, P_.Tau_, P_.C_, h );
  V_.P21in_ = propagator_32( P_.tau_in_, P_.Tau_, P_.C_, h );

  // P21ex_ = h/C_;
  // P21in_ = h/C_;

  V_.P20_ = P_.Tau_ / P_.C_ * ( 1.0 - V_.P22_ );
  // P20_ = h/C_;

  // TauR specifies the length of the absolute refractory period as
  // a double in ms. The grid based iaf_psc_exp can only handle refractory
  // periods that are integer multiples of the computation step size (h).
  // To ensure consistency with the overall simulation scheme such conversion
  // should be carried out via objects of class nest::Time. The conversion
  // requires 2 steps:
  //     1. A time object r is constructed defining  representation of
  //        TauR in tics. This representation is then converted to computation
  //        time steps again by a strategy defined by class nest::Time.
  //     2. The refractory time in units of steps is read out get_steps(), a
  //        member function of class nest::Time.
  //
  // Choosing a TauR that is not an integer multiple of the computation time
  // step h will leed to accurate (up to the resolution h) and self-consistent
  // results. However, a neuron model capable of operating with real valued
  // spike time may exhibit a different effective refractory time.

  V_.RefractoryCounts_ = Time( Time::ms( P_.t_ref_ ) ).get_steps();
  // since t_ref_ >= 0, this can only fail in error
  assert( V_.RefractoryCounts_ >= 0 );
}

void
mynest::iaf_psc_exp_semd::update( const Time& origin, const long from, const long to )
{
  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  // evolve from timestep 'from' to timestep 'to' with steps of h each
  for ( long lag = from; lag < to; ++lag )
  {
    if ( S_.r_ref_ == 0 ) // neuron not refractory, so evolve V
      S_.V_m_ = S_.V_m_ * V_.P22_ + S_.i_syn_ex_ * V_.P21ex_								// membrane potential equals membrane potential times exponetial decay plus postsynpatic excitatory/inhibitory currents time numerical stability factor plus new input current times exponential decay
        + S_.i_syn_in_ * V_.P21in_ + ( P_.I_e_ + S_.i_0_ ) * V_.P20_;						// S_.V_m : membrane potential
    else                                                                                    // V_.P22 : membrane potential decay
	{																						// S_.i_syn_ex / S_.i_syn_in : excitatory / inhibitory postsynaptic current
	}																						// V_.P21in / V_.P21ex : numeric stability criterion parameter
																							// P_.I_e : static input current
	{                                                                                       // S_.i_0_ : presynaptic input current this timestep 
	}																						// S_.i_1_ : presynaptic input current next timestep
	
	{
	}
	
      --S_.r_ref_; // neuron is absolute refractory

    // exponential decaying PSCs
    S_.i_syn_ex_ *= V_.P11ex_;
    S_.i_syn_in_ *= V_.P11in_;

    // add evolution of presynaptic input current
    S_.i_syn_ex_ += ( 1. - V_.P11ex_ ) * S_.i_1_;

    // the spikes arriving at T+1 have an immediate effect on the state of the
    // neuron

    V_.weighted_spikes_ex_ = B_.spikes_ex_.get_value( lag );
    V_.weighted_spikes_in_ = B_.spikes_in_.get_value( lag );

    S_.i_syn_ex_ += V_.weighted_spikes_ex_;
    S_.i_syn_in_ += V_.weighted_spikes_in_;

    if ( S_.V_m_ >= P_.Theta_ ) // threshold crossing
    {
      S_.r_ref_ = V_.RefractoryCounts_;
      S_.V_m_ = P_.V_reset_;

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // set new input current
    S_.i_0_ = B_.currents_[ 0 ].get_value( lag );
    S_.i_1_ = B_.currents_[ 1 ].get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}

void
mynest::iaf_psc_exp_semd::handle( SpikeEvent& e )
{
  assert( e.get_delay() > 0 );

  if ( e.get_weight() >= 0.0 )
    B_.spikes_ex_.add_value( e.get_rel_delivery_steps(
                               kernel().simulation_manager.get_slice_origin() ),
      e.get_weight() * e.get_multiplicity() );
  else
    B_.spikes_in_.add_value( e.get_rel_delivery_steps(
                               kernel().simulation_manager.get_slice_origin() ),
      e.get_weight() * e.get_multiplicity() );
}

void
mynest::iaf_psc_exp_semd::handle( CurrentEvent& e )
{
  assert( e.get_delay() > 0 );

  const double c = e.get_current();
  const double w = e.get_weight();

  // add weighted current; HEP 2002-10-04
  if ( 0 == e.get_rport() )
  {
    B_.currents_[ 0 ].add_value(
      e.get_rel_delivery_steps(
        kernel().simulation_manager.get_slice_origin() ),
      w * c );
  }
  if ( 1 == e.get_rport() )
  {
    B_.currents_[ 1 ].add_value(
      e.get_rel_delivery_steps(
        kernel().simulation_manager.get_slice_origin() ),
      w * c );
  }
}

void
mynest::iaf_psc_exp_semd::handle( DataLoggingRequest& e )
{
  B_.logger_.handle( e );
}
_______________________________________________
NEST Users mailing list -- users@nest-simulator.org
To unsubscribe send an email to users-leave@nest-simulator.org
-- 
___________________________________________________

Simon Brodeur
Étudiant au doctorat
Université de Sherbrooke
Département génie électrique et génie informatique
Laboratoire NECOTIS, C1-3036
Tél. : (819) 821-8000 poste 62187
Courriel: Simon.Brodeur@USherbrooke.ca
___________________________________________________