void nest::spike_detector::handle( SpikeEvent& e ) { // accept spikes only if detector was active when spike was // emitted if ( device_.is_active( e.get_stamp() ) ) { assert( e.get_multiplicity() > 0 ); long dest_buffer; if ( kernel() .modelrange_manager.get_model_of_gid( e.get_sender_gid() ) ->has_proxies() ) { // events from central queue dest_buffer = kernel().event_delivery_manager.read_toggle(); } else { // locally delivered events dest_buffer = kernel().event_delivery_manager.write_toggle(); } for ( int i = 0; i < e.get_multiplicity(); ++i ) { // We store the complete events Event* event = e.clone(); B_.spikes_[ dest_buffer ].push_back( event ); } } }
void nest::izhikevich::handle( SpikeEvent& e ) { assert( e.get_delay() > 0 ); B_.spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); }
void nest::iaf_neuron::handle( SpikeEvent& e ) { assert( e.get_delay() > 0 ); B_.spikes_.add_value( e.get_rel_delivery_steps( network()->get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); }
void nest::iaf_neuron_dif_alpha::handle(SpikeEvent & e) { assert(e.get_delay() > 0); B_.spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight() * e.get_multiplicity() ); //std::cout<<"spike handle "<<e.get_stamp().get_ms()<<"\n"; }
void nest::sinusoidal_poisson_generator::update( Time const& origin, const long from, const long to ) { assert( to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() ); assert( from < to ); const long start = origin.get_steps(); // random number generator librandom::RngPtr rng = kernel().rng_manager.get_rng( get_thread() ); // We iterate the dynamics even when the device is turned off, // but do not issue spikes while it is off. In this way, the // oscillators always have the right phase. This is quite // time-consuming, so it should be done only if the device is // on most of the time. for ( long lag = from; lag < to; ++lag ) { // update oscillator blocks, accumulate rate as sum of DC and N_osc_ AC // elements rate is instantaneous sum of state S_.rate_ = P_.rate_; const double new_y_0 = V_.cos_ * S_.y_0_ - V_.sin_ * S_.y_1_; S_.y_1_ = V_.sin_ * S_.y_0_ + V_.cos_ * S_.y_1_; S_.y_0_ = new_y_0; S_.rate_ += S_.y_1_; if ( S_.rate_ < 0 ) { S_.rate_ = 0; } // create spikes if ( S_.rate_ > 0 && device_.is_active( Time::step( start + lag ) ) ) { if ( P_.individual_spike_trains_ ) { DSSpikeEvent se; kernel().event_delivery_manager.send( *this, se, lag ); } else { V_.poisson_dev_.set_lambda( S_.rate_ * V_.h_ ); long n_spikes = V_.poisson_dev_.ldev( rng ); SpikeEvent se; se.set_multiplicity( n_spikes ); kernel().event_delivery_manager.send( *this, se, lag ); } } // store rate in Hz B_.logger_.record_data( origin.get_steps() + lag ); } }
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 nest::spike_generator::update(Time const & sliceT0, const long_t from, const long_t to) { if ( P_.spike_stamps_.empty() ) return; assert( !P_.precise_times_ || P_.spike_stamps_.size() == P_.spike_offsets_.size() ); assert( P_.spike_weights_.empty() || P_.spike_stamps_.size() == P_.spike_weights_.size() ); const Time tstart = sliceT0 + Time::step(from); const Time tstop = sliceT0 + Time::step(to); const Time& origin = device_.get_origin(); // We fire all spikes with time stamps up to including sliceT0 + to while ( S_.position_ < P_.spike_stamps_.size() ) { const Time tnext_stamp = origin + P_.spike_stamps_[S_.position_]; // this might happen due to wrong usage of the generator if ( tnext_stamp <= tstart ) { ++S_.position_; continue; } if ( tnext_stamp > tstop ) break; if ( device_.is_active(tnext_stamp) ) { SpikeEvent* se; // if we have to deliver weighted spikes, we need to get the // event back to set its weight according to the entry in // spike_weights_, so we use a DSSpike event and event_hook() if ( !P_.spike_weights_.empty() ) se = new DSSpikeEvent; else se = new SpikeEvent; if ( P_.precise_times_ ) se->set_offset(P_.spike_offsets_[S_.position_]); // we need to subtract one from stamp which is added again in send() long_t lag = Time(tnext_stamp - sliceT0).get_steps() - 1; // all spikes are sent locally, so offset information is always preserved network()->send(*this, *se, lag); delete se; } ++S_.position_; } }
void nest::iaf_psc_delta::handle( SpikeEvent& e ) { assert( e.get_delay() > 0 ); // EX: We must compute the arrival time of the incoming spike // explicity, since it depends on delay and offset within // the update cycle. The way it is done here works, but // is clumsy and should be improved. B_.spikes_.add_value( e.get_rel_delivery_steps( network()->get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); }
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() ); } } }
void nest::iaf_cond_delta::handle(SpikeEvent & e) { assert(e.get_delay() > 0); if(e.get_weight() > 0.0) B_.spikes_ex_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight() * e.get_multiplicity() ); else B_.spikes_in_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), -e.get_weight() * e.get_multiplicity() ); // note: conductance is positive for both exc and inh synapses but we use the sign of spike event weight to distinguish which kind of synapse it is }
void nest::aeif_cond_exp::handle(SpikeEvent &e) { assert ( e.get_delay() > 0 ); if(e.get_weight() > 0.0) B_.spike_exc_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight() * e.get_multiplicity()); else B_.spike_inh_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), -e.get_weight() * e.get_multiplicity()); // keep conductances positive }
void nest::hh_psc_alpha::handle(SpikeEvent & e) { assert(e.get_delay() > 0); if(e.get_weight() > 0.0) B_.spike_exc_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight() * e.get_multiplicity() ); else B_.spike_inh_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight() * e.get_multiplicity() ); // current input, keep negative weight }
void ginzburg::handle(SpikeEvent & e) { assert(e.get_delay() > 0); // The following logic implements the encoding: // 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(); long_t gid = e.get_sender_gid(); const Time &t_spike = e.get_stamp(); if (m == 1) { //multiplicity == 1, either a single 1->0 event or the first or second of a pair of 0->1 events if (gid == S_.last_in_gid_ && t_spike == S_.t_last_in_spike_) { // received twice the same gid, so transition 0->1 // take double weight to compensate for subtracting first event B_.spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), 2.0*e.get_weight()); } else { // count this event negatively, assuming it comes as single event // transition 1->0 B_.spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), -e.get_weight()); } } else // multiplicity != 1 if (m == 2) { // count this event positively, transition 0->1 B_.spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight()); } S_.last_in_gid_ = gid; S_.t_last_in_spike_ = t_spike; }
void nest::iaf_psc_exp_ps::emit_instant_spike_(const Time & origin, const long_t lag, const double_t spike_offs) { assert( S_.y2_ >= P_.U_th_ ); // ensure we are superthreshold // set stamp and offset for spike set_spiketime(Time::step(origin.get_steps() + lag + 1)); S_.last_spike_offset_ = spike_offs; // reset neuron and make it refractory S_.y2_ = P_.U_reset_; S_.is_refractory_ = true; // send spike SpikeEvent se; se.set_offset(S_.last_spike_offset_); network()->send(*this, se, lag); }
void nest::iaf_tum_2000::handle( SpikeEvent& e ) { assert( e.get_delay() > 0 ); if ( e.get_weight() >= 0.0 ) B_.spikes_ex_.add_value( e.get_rel_delivery_steps( network()->get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); else B_.spikes_in_.add_value( e.get_rel_delivery_steps( network()->get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); }
void ginzburg::update(Time const & origin, const long_t from, const long_t to) { assert(to >= 0 && (delay) from < Scheduler::get_min_delay()); assert(from < to); for ( long_t lag = from ; lag < to ; ++lag ) { // update the input current // the buffer for incoming spikes for every time step contains the difference // of the total input h with respect to the previous step, so sum them up S_.h_ += B_.spikes_.get_value(lag); // check, if the update needs to be done if ( Time::step(origin.get_steps()+lag) > S_.t_next_ ) { // change the state of the neuron with probability given by // gain function // if the state has changed, the neuron produces an event sent to all its targets bool new_y = V_.rng_->drand() < gain_(S_.h_); if ( new_y != S_.y_ ) { SpikeEvent se; // use multiplicity 2 to signalize transition to 1 state // use multiplicity 1 to signalize transition to 0 state se.set_multiplicity(new_y ? 2 : 1); network()->send(*this, se, lag); S_.y_ = new_y; } // draw next update interval from exponential distribution S_.t_next_ += Time::ms ( V_.exp_dev_(V_.rng_) * P_.tau_m_ ); } // of if (update now) // log state data B_.logger_.record_data(origin.get_steps() + lag); } // of for (lag ... }
void parrot_neuron_ps::update( Time const& origin, long_t const from, long_t const to ) { assert( to >= 0 ); assert( static_cast< delay >( from ) < kernel().connection_manager.get_min_delay() ); assert( from < to ); // at start of slice, tell input queue to prepare for delivery if ( from == 0 ) B_.events_.prepare_delivery(); for ( long_t lag = from; lag < to; ++lag ) { // time at start of update step long_t const T = origin.get_steps() + lag; double_t ev_offset; double_t ev_multiplicity; // parrot stores multiplicity in weight bool end_of_refract; while ( B_.events_.get_next_spike( T, ev_offset, ev_multiplicity, end_of_refract ) ) { const ulong_t multiplicity = static_cast< ulong_t >( ev_multiplicity ); // send spike SpikeEvent se; se.set_multiplicity( multiplicity ); se.set_offset( ev_offset ); kernel().event_delivery_manager.send( *this, se, lag ); for ( ulong_t i = 0; i < multiplicity; ++i ) { set_spiketime( Time::step( T + 1 ), ev_offset ); } } } }
void nest::iaf_psc_exp_canon::emit_spike_(Time const &origin, long_t const lag, double_t const t0, double_t const dt) { // we know that the potential is subthreshold at t0, super at t0+dt // compute spike time relative to beginning of step double_t const spike_offset = V_.h_ms_ - (t0+thresh_find_(dt)); set_spiketime(Time::step(origin.get_steps() + lag + 1)); S_.last_spike_offset_ = spike_offset; // reset neuron and make it refractory S_.y2_ = P_.U_reset_; S_.is_refractory_ = true; // send spike SpikeEvent se; se.set_offset(S_.last_spike_offset_); network()->send(*this, se, lag); return; }
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() ); }
//function handles exact spike times void nest::iaf_psc_alpha_presc::handle(SpikeEvent & e) { assert(e.get_delay() > 0 ); const long_t Tdeliver = e.get_rel_delivery_steps(network()->get_slice_origin()); const double_t spike_weight = V_.PSCInitialValue_ * e.get_weight() * e.get_multiplicity(); const double_t dt = e.get_offset(); // Building the new matrix for the offset of the spike // NOTE: We do not use get matrix, but compute only those // components we actually need for spike registration const double_t ps_e_TauSyn = numerics::expm1(-dt/P_.tau_syn_); // needed in any case const double_t ps_e_Tau = numerics::expm1(-dt/P_.tau_m_); const double_t ps_P31 = V_.gamma_sq_ * ps_e_Tau - V_.gamma_sq_ * ps_e_TauSyn - dt * V_.gamma_ * ps_e_TauSyn - dt * V_.gamma_; B_.spike_y1_.add_value(Tdeliver, spike_weight*ps_e_TauSyn + spike_weight); B_.spike_y2_.add_value(Tdeliver, spike_weight*dt*ps_e_TauSyn + spike_weight*dt); B_.spike_y3_.add_value(Tdeliver, spike_weight*ps_P31); }
void nest::iaf_psc_exp_ps::emit_spike_(const Time & origin, const long_t lag, const double_t t0, const double_t dt) { // we know that the potential is subthreshold at t0, super at t0+dt // compute spike time relative to beginning of step const double_t spike_offset = V_.h_ms_ - (t0 + bisectioning_(dt)); set_spiketime(Time::step(origin.get_steps() + lag + 1)); S_.last_spike_offset_ = spike_offset; // reset neuron and make it refractory S_.y2_ = P_.U_reset_; S_.is_refractory_ = true; // send spike SpikeEvent se; se.set_offset(spike_offset); network()->send(*this, se, lag); }
void nest::amat2_psc_exp::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 nest::sli_neuron::handle( SpikeEvent& e ) { assert( e.get_delay() > 0 ); if ( e.get_weight() > 0.0 ) B_.ex_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); else B_.in_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); }
void nest::iaf_cond_exp_sfa_rr::handle( SpikeEvent& e ) { assert( e.get_delay() > 0 ); if ( e.get_weight() > 0.0 ) B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); else B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); // ensure conductance is positive }
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 pif_psc_delta_canon_cvv::handle(SpikeEvent & e) { 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; B_.events_.add_spike(e.get_rel_delivery_steps(network()->get_slice_origin()), Tdeliver, e.get_offset(), e.get_weight() * e.get_multiplicity()); }
void nest::iaf_psc_alpha_canon::emit_instant_spike_( Time const& origin, const long_t lag, const double_t spike_offs ) { assert( S_.y3_ >= P_.U_th_ ); // ensure we are superthreshold // set stamp and offset for spike S_.last_spike_step_ = origin.get_steps() + lag + 1; S_.last_spike_offset_ = spike_offs; // reset neuron and make it refractory S_.y3_ = P_.U_reset_; S_.is_refractory_ = true; // send spike set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); kernel().event_delivery_manager.send( *this, se, lag ); return; }
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::iaf_psc_alpha_canon::emit_spike_( Time const& origin, const long_t lag, const double_t t0, const double_t dt ) { // we know that the potential is subthreshold at t0, super at t0+dt // compute spike time relative to beginning of step S_.last_spike_step_ = origin.get_steps() + lag + 1; S_.last_spike_offset_ = V_.h_ms_ - ( t0 + thresh_find_( dt ) ); // reset neuron and make it refractory S_.y3_ = P_.U_reset_; S_.is_refractory_ = true; // send spike set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); kernel().event_delivery_manager.send( *this, se, lag ); return; }
void nest::hh_cond_exp_traub::handle(SpikeEvent & e) { assert(e.get_delay() > 0); if(e.get_weight() > 0.0) { B_.spike_exc_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), e.get_weight() * e.get_multiplicity()); } else { // add with negative weight, ie positive value, since we are changing a // conductance B_.spike_inh_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()), -e.get_weight() * e.get_multiplicity()); } }