Beispiel #1
0
void nest::iaf_psc_alpha_mod::handle(SpikeEvent & e)
{
  assert(e.get_delay() > 0);

  // port 0: spikes are normally handled.
  if(e.get_rport() == 0 ){
    if(e.get_weight() > 0.0)
      B_.ex_spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
			      e.get_weight() * e.get_multiplicity() );
    else
      B_.in_spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
			      e.get_weight() * e.get_multiplicity() );
  }
  // port 1: spikes act as modulators for all spikes that arrive at....
  if(e.get_rport() == 1 ){
    B_.modspikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
			    e.get_weight() * e.get_multiplicity() );
  }

  // ....port 2. These weights get modulated.
  if(e.get_rport() == 2 ){
    if(e.get_weight() > 0.0){
      double tmpweight =  e.get_weight() * (1.0 + S_.ymod_) ;
      tmpweight        = (tmpweight > P_.max_weight_ ? P_.max_weight_ : tmpweight);
      B_.ex_spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
			      tmpweight * e.get_multiplicity() );
    }

    else
      B_.in_spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
			      e.get_weight() * e.get_multiplicity() );
  }
}
void mynest::coronet_neuron::handle(SpikeEvent & e)
{
    assert(e.get_delay() > 0);
    assert(e.get_rport() < static_cast<int_t>(B_.spike_inputs_.size()));

    B_.spike_inputs_[e.get_rport()].
      add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
		e.get_weight() * e.get_multiplicity() );
}
void
nest::ht_neuron::handle( SpikeEvent& e )
{
  assert( e.get_delay() > 0 );
  assert( e.get_rport() < static_cast< int_t >( B_.spike_inputs_.size() ) );

  B_.spike_inputs_[ e.get_rport() ].add_value(
    e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ),
    e.get_weight() * e.get_multiplicity() );
}
void
nest::iaf_cond_alpha_mc::handle( SpikeEvent& e )
{
  assert( e.get_delay() > 0 );
  assert( 0 <= e.get_rport() && e.get_rport() < 2 * NCOMP );

  B_.spikes_[ e.get_rport() ].add_value(
    e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ),
    e.get_weight() * e.get_multiplicity() );
}
void
gif_psc_exp_multisynapse::handle( SpikeEvent& e )
{
  assert( e.get_delay() > 0 );
  assert( ( e.get_rport() > 0 )
    && ( ( size_t ) e.get_rport() <= P_.n_receptors_() ) );

  B_.spikes_[ e.get_rport() - 1 ].add_value(
    e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ),
    e.get_weight() * e.get_multiplicity() );
}
void
iaf_psc_alpha_multisynapse::handle( SpikeEvent& e )
{
  assert( e.get_delay_steps() > 0 );

  B_.spikes_[ e.get_rport() - 1 ].add_value(
    e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ),
    e.get_weight() * e.get_multiplicity() );
}
void
aeif_cond_alpha_multisynapse::handle( SpikeEvent& e )
{
  assert( e.get_delay() > 0 );
  assert( ( e.get_rport() > 0 ) && ( ( size_t ) e.get_rport() <= P_.num_of_receptors_ ) );

  if ( e.get_weight() > 0.0 )
  {
    B_.spike_exc_[ e.get_rport() - 1 ].add_value(
      e.get_rel_delivery_steps( network()->get_slice_origin() ),
      e.get_weight() * e.get_multiplicity() );
  }
  else
  {
    B_.spike_inh_[ e.get_rport() - 1 ].add_value(
      e.get_rel_delivery_steps( network()->get_slice_origin() ),
      -e.get_weight() * e.get_multiplicity() ); // keep conductances positive
  }
}
void
iaf_psc_alpha_multisynapse::handle( SpikeEvent& e )
{
  assert( e.get_delay() > 0 );

  for ( size_t i = 0; i < P_.num_of_receptors_; ++i )
  {
    if ( P_.receptor_types_[ i ] == e.get_rport() )
    {
      B_.spikes_[ i ].add_value( e.get_rel_delivery_steps( network()->get_slice_origin() ),
        e.get_weight() * e.get_multiplicity() );
    }
  }
}
// function handles exact spike times
void
parrot_neuron_ps::handle( SpikeEvent& e )
{
  // Repeat only spikes incoming on port 0, port 1 will be ignored
  if ( 0 == e.get_rport() )
  {
    assert( e.get_delay() > 0 );

    // We need to compute the absolute time stamp of the delivery time
    // of the spike, since spikes might spend longer than min_delay_
    // in the queue.  The time is computed according to Time Memo, Rule 3.
    const long_t Tdeliver = e.get_stamp().get_steps() + e.get_delay() - 1;

    // parrot ignores weight of incoming connection, store multiplicity
    B_.events_.add_spike(
      e.get_rel_delivery_steps(
        nest::kernel().simulation_manager.get_slice_origin() ),
      Tdeliver,
      e.get_offset(),
      static_cast< double_t >( e.get_multiplicity() ) );
  }
}
void
nest::correlospinmatrix_detector::handle( SpikeEvent& e )
{
  // The receiver port identifies the sending node in our
  // sender list.
  const rport curr_i = e.get_rport();

  // If this assertion breaks, the sender does not honor the
  // receiver port during connection or sending.
  assert( 0 <= curr_i && curr_i <= P_.N_channels_ - 1 );

  // accept spikes only if detector was active when spike was emitted
  Time const stamp = e.get_stamp();

  if ( device_.is_active( stamp ) )
  {

    // The following logic implements the decoding
    // A single spike signals a transition to 0 state, two spikes in same time step
    // signal the transition to 1 state.
    //
    // Remember the global id of the sender of the last spike being received
    // this assumes that several spikes being sent by the same neuron in the same time step
    // are received consecutively or are conveyed by setting the multiplicity accordingly.

    long_t m = e.get_multiplicity();
    bool down_transition = false;

    if ( m == 1 )
    { // multiplicity == 1, either a single 1->0 event or the first or second of a pair of 0->1
      // events
      if ( curr_i == S_.last_i_ && stamp == S_.t_last_in_spike_ )
      {
        // received twice the same gid, so transition 0->1
        // revise the last event written to the buffer
        S_.curr_state_[ curr_i ] = true;
        S_.last_change_[ curr_i ] = stamp.get_steps();
        S_.tentative_down_ = false; // previous event was first event of two, so no down transition
      }
      else
      {
        // count this event negatively, assuming it comes as single event
        // transition 1->0
        // assume it will stay alone, so meaning a down tansition

        if ( S_.tentative_down_ ) // really was a down transition, because we now have another event
        {
          down_transition = true;
        }

        S_.tentative_down_ = true;
      }
    }
    else // multiplicity != 1
      if ( m == 2 )
    {
      S_.curr_state_[ curr_i ] = true;

      if ( S_.tentative_down_ ) // really was a down transition, because we now have another double
      {                         // event
        down_transition = true;
      }

      S_.curr_state_[ S_.last_i_ ] = false;
      S_.last_change_[ curr_i ] = stamp.get_steps();
      S_.tentative_down_ = false; // previous event was first event of two, so no down transition
    }

    if ( down_transition ) // only do something on the downtransitions
    {
      long_t i = S_.last_i_;                // index of neuron making the down transition
      long_t t_i_on = S_.last_change_[ i ]; // last time point of change, must have been on

      const long_t t_i_off = S_.t_last_in_spike_.get_steps();

      // throw out all binary pulses from event list that are too old to enter the correlation
      // window
      BinaryPulselistType& otherPulses = S_.incoming_;

      // calculate the minimum of those neurons that switched on and are not off yet
      // every impulse in the queue that is further in the past than
      // this minimum - tau_max cannot contribute to the count covariance
      long_t t_min_on = t_i_on;
      for ( int n = 0; n < P_.N_channels_; n++ )
      {
        if ( S_.curr_state_[ n ] )
        {
          if ( S_.last_change_[ n ] < t_min_on )
          {
            t_min_on = S_.last_change_[ n ];
          }
        }
      }
      const double_t tau_edge = P_.tau_max_.get_steps() + P_.delta_tau_.get_steps();

      const delay min_delay = Scheduler::get_min_delay();
      while (
        !otherPulses.empty() && ( t_min_on - otherPulses.front().t_off_ ) >= tau_edge + min_delay )
        otherPulses.pop_front();


      // insert new event into history
      // must happen here so event is taken into account in autocorrelation
      const BinaryPulse_ bp_i( t_i_on, t_i_off, i );

      BinaryPulselistType::iterator insert_pos = std::find_if( S_.incoming_.begin(),
        S_.incoming_.end(),
        std::bind2nd( std::greater< BinaryPulse_ >(), bp_i ) );

      // insert before the position we have found
      // if no element greater found, insert_pos == end(), so append at the end of the deque
      S_.incoming_.insert( insert_pos, bp_i );


      // go through history of other binary pulses
      for ( BinaryPulselistType::const_iterator pulse_j = otherPulses.begin();
            pulse_j != otherPulses.end();
            ++pulse_j )
      {
        // id of other neuron
        long_t j = pulse_j->receptor_channel_;
        long_t t_j_on = pulse_j->t_on_;
        long_t t_j_off = pulse_j->t_off_;

        // minimum and maximum time difference in histogram
        long_t Delta_ij_min = std::max( t_j_on - t_i_off, -P_.tau_max_.get_steps() );
        long_t Delta_ij_max = std::min( t_j_off - t_i_on, P_.tau_max_.get_steps() );

        long_t t0 = P_.tau_max_.get_steps() / P_.delta_tau_.get_steps();
        long_t dt = P_.delta_tau_.get_steps();


        // zero time lag covariance

        long_t l = std::min( t_i_off, t_j_off ) - std::max( t_i_on, t_j_on );
        if ( l > 0 )
        {
          S_.count_covariance_[ i ][ j ][ t0 ] += l;
          if ( i != j )
          {
            S_.count_covariance_[ j ][ i ][ t0 ] += l;
          }
        }

        // non-zero time lag covariance
        for ( long_t Delta = Delta_ij_min / dt; Delta < 0; Delta++ )
        {
          long_t l =
            std::min( t_i_off, t_j_off - Delta * dt ) - std::max( t_i_on, t_j_on - Delta * dt );
          if ( l > 0 )
          {
            S_.count_covariance_[ i ][ j ][ t0 - Delta ] += l;
            S_.count_covariance_[ j ][ i ][ t0 + Delta ] += l;
          }
        }

        if ( i != j )
        {
          for ( long_t Delta = 1; Delta <= Delta_ij_max / dt; Delta++ )
          {
            long_t l =
              std::min( t_i_off, t_j_off - Delta * dt ) - std::max( t_i_on, t_j_on - Delta * dt );
            if ( l > 0 )
            {
              S_.count_covariance_[ i ][ j ][ t0 - Delta ] += l;
              S_.count_covariance_[ j ][ i ][ t0 + Delta ] += l;
            }
          }
        }
      } // loop over history

      S_.last_change_[ i ] = t_i_off;
    } // down transition happened

    S_.last_i_ = curr_i;
    S_.t_last_in_spike_ = stamp;

  } // device active
}
void
nest::correlomatrix_detector::handle( SpikeEvent& e )
{
  // The receiver port identifies the sending node in our
  // sender list.
  const rport sender = e.get_rport();

  // If this assertion breaks, the sender does not honor the
  // receiver port during connection or sending.
  assert( 0 <= sender && sender <= P_.N_channels_ - 1 );

  // accept spikes only if detector was active when spike was emitted
  Time const stamp = e.get_stamp();

  if ( device_.is_active( stamp ) )
  {
    const long_t spike_i = stamp.get_steps();

    // find first appearence of element which is greater than spike_i
    const Spike_ sp_i( spike_i, e.get_multiplicity() * e.get_weight(), sender );
    SpikelistType::iterator insert_pos = std::find_if(
      S_.incoming_.begin(), S_.incoming_.end(), std::bind2nd( std::greater< Spike_ >(), sp_i ) );

    // insert before the position we have found
    // if no element greater found, insert_pos == end(), so append at the end of the deque
    S_.incoming_.insert( insert_pos, sp_i );

    SpikelistType& otherSpikes = S_.incoming_;
    const double_t tau_edge = P_.tau_max_.get_steps() + 0.5 * P_.delta_tau_.get_steps();

    // throw away all spikes which are too old to
    // enter the correlation window
    const delay min_delay = Scheduler::get_min_delay();
    while (
      !otherSpikes.empty() && ( spike_i - otherSpikes.front().timestep_ ) >= tau_edge + min_delay )
      otherSpikes.pop_front();
    // all remaining spike times in the queue are >= spike_i - tau_edge - min_delay

    // only count events in histogram, if the current event is within the time window [Tstart,
    // Tstop]
    // this is needed in order to prevent boundary effects
    if ( P_.Tstart_ <= stamp && stamp <= P_.Tstop_ )
    {
      // calculate the effect of this spike immediately with respect to all
      // spikes in the past of the respectively other sources

      S_.n_events_[ sender ]++; // count this spike

      for ( SpikelistType::const_iterator spike_j = otherSpikes.begin();
            spike_j != otherSpikes.end();
            ++spike_j )
      {
        size_t bin;
        long_t other = spike_j->receptor_channel_;
        long_t sender_ind, other_ind;

        if ( spike_i < spike_j->timestep_ )
        {
          sender_ind = other;
          other_ind = sender;
        }
        else
        {
          sender_ind = sender;
          other_ind = other;
        }

        if ( sender_ind <= other_ind )
        {
          bin = -1. * std::floor( ( 0.5 * P_.delta_tau_.get_steps()
                                    - std::abs( spike_i - spike_j->timestep_ ) )
                        / P_.delta_tau_.get_steps() );
        }
        else
        {
          bin = std::floor(
            ( 0.5 * P_.delta_tau_.get_steps() + std::abs( spike_i - spike_j->timestep_ ) )
            / P_.delta_tau_.get_steps() );
        }

        if ( bin < S_.covariance_[ sender_ind ][ other_ind ].size() )
        {
          // weighted histogram
          S_.covariance_[ sender_ind ][ other_ind ][ bin ] +=
            e.get_multiplicity() * e.get_weight() * spike_j->weight_;
          if ( bin == 0 && ( spike_i - spike_j->timestep_ != 0 || other != sender ) )
            S_.covariance_[ other_ind ][ sender_ind ][ bin ] +=
              e.get_multiplicity() * e.get_weight() * spike_j->weight_;
          // pure (unweighted) count histogram
          S_.count_covariance_[ sender_ind ][ other_ind ][ bin ] += e.get_multiplicity();
          if ( bin == 0 && ( spike_i - spike_j->timestep_ != 0 || other != sender ) )
            S_.count_covariance_[ other_ind ][ sender_ind ][ bin ] += e.get_multiplicity();
        }
      }

    } // t in [TStart, Tstop]

  } // device active
}