Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix postsynaptic trace edge case #1137

Merged
merged 47 commits into from
Apr 8, 2019
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
febaad5
fixed bug and added testbench for postsynaptic trace function
Nov 28, 2018
d089391
added assertion failure upon fall-through case
Nov 28, 2018
a725a1b
updated the example
Nov 29, 2018
85fa1eb
refactor postsynaptic trace demo script to unit test
Jan 7, 2019
2ca0a85
replace history-based calculation of postsynaptic trace with private …
Jan 9, 2019
fc879a2
update unit test to account for multiple spikes within one (dmin) tim…
Jan 10, 2019
15825ec
update postsynaptic trace unit test to account for multiple spikes wi…
Jan 10, 2019
38010cb
added debugging code to archiving node
Jan 10, 2019
abea27a
update postsynaptic trace unit test to account for multiple spikes wi…
Jan 10, 2019
aea2949
add new, stricter condition for removing spikes from the postsynaptic…
Feb 21, 2019
cf2c991
added new parameter to register_stdp_connection() to pass synaptic delay
Feb 21, 2019
ee90db9
refactor testbench
Feb 21, 2019
e7e55ac
postsynaptic trace fixes for #1034; updated testbench
Feb 27, 2019
41060e3
postsynaptic trace fixes for #1034: cleanup
Feb 27, 2019
fd2a9d7
postsynaptic trace fixes for #1034: cleanup
Feb 27, 2019
7d4fb0e
postsynaptic trace fixes for #1034: cleanup
Feb 27, 2019
ba09243
postsynaptic trace fixes for #1034: cleanup
Feb 27, 2019
76a7160
postsynaptic trace fixes for #1034: cleanup
Feb 27, 2019
73fc9c3
pep8
Feb 27, 2019
5a91180
clang-format
Feb 27, 2019
4a11b18
homogenise comments/formatting between get_K_value() and get_K_values()
Mar 13, 2019
a868258
fix member variable initialisation order
Mar 13, 2019
6d0828e
fix line lengths to <80 characters
Mar 13, 2019
9370f60
minor code beautifications; comments typography
Mar 13, 2019
f3e894a
make plotting optional in the testbench
Mar 13, 2019
271a85e
Merge remote-tracking branch 'upstream/master' into traces-refactor_f…
Mar 13, 2019
0383c17
fix register_stdp_connection() API change in clopath_connection
Mar 13, 2019
6ef4e33
pep8
Mar 13, 2019
8407c3c
fix reference to `@check_stack` in postsynaptic trace unit test
Mar 17, 2019
6cc14a3
Merge remote-tracking branch 'upstream/master' into traces-refactor_f…
Mar 17, 2019
ae902d2
fix reference to `nest.set_verbosity()` in postsynaptic trace unit test
Mar 17, 2019
e956582
clang-format
Mar 25, 2019
ec11b5f
split postsynaptic trace testbench into pure (regression) test part a…
Mar 25, 2019
ee8cd49
clean up postsynaptic trace regression test
Mar 26, 2019
c662f2e
clean up (PEP8) postsynaptic trace regression test
Mar 26, 2019
40a1a28
removed check_stack from postsynaptic trace regression test
Mar 26, 2019
d1c8543
minor cleanup of postsynaptic trace regression test and Jupyter notebook
Mar 26, 2019
3f87224
add reference to Jupyter notebook in regression test
Mar 26, 2019
90b5c28
change verbosity level to the maximum defined
Apr 1, 2019
39ea006
Merge remote-tracking branch 'upstream/master' into traces-refactor_f…
Apr 1, 2019
d7ed53b
remove unused NEST name 'pre_trace'
Apr 1, 2019
eefa1aa
minor refactoring based on PR comments
Apr 1, 2019
389e715
Merge remote-tracking branch 'upstream/master' into traces-refactor_f…
Apr 8, 2019
320c659
add documentation header; minor refactoring based on PR comments
Apr 8, 2019
acd122f
remove stray line left over from refactoring
Apr 8, 2019
bb5b275
remove copyright header from Jupyter notebook
Apr 8, 2019
0eead87
add figure legend
Apr 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
680 changes: 680 additions & 0 deletions doc/model_details/test_post_trace.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion models/clopath_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class ClopathConnection : public Connection< targetidentifierT >

ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down
9 changes: 4 additions & 5 deletions models/stdp_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class STDPConnection : public Connection< targetidentifierT >

ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down Expand Up @@ -220,7 +220,7 @@ STDPConnection< targetidentifierT >::send( Event& e,
const CommonSynapseProperties& )
{
// synapse STDP depressing/facilitation dynamics
double t_spike = e.get_stamp().get_ms();
const double t_spike = e.get_stamp().get_ms();

// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Expand Down Expand Up @@ -255,9 +255,8 @@ STDPConnection< targetidentifierT >::send( Event& e,
weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ) );
}

// depression due to new pre-synaptic spike
weight_ =
depress_( weight_, target->get_K_value( t_spike - dendritic_delay ) );
const double _K_value = target->get_K_value( t_spike - dendritic_delay );
weight_ = depress_( weight_, _K_value );

e.set_receiver( *target );
e.set_weight( weight_ );
Expand Down
2 changes: 1 addition & 1 deletion models/stdp_connection_facetshw_hom.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ class STDPFACETSHWConnectionHom : public Connection< targetidentifierT >

ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down
2 changes: 1 addition & 1 deletion models/stdp_connection_hom.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class STDPConnectionHom : public Connection< targetidentifierT >
ConnTestDummyNode dummy_target;
ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

private:
Expand Down
2 changes: 1 addition & 1 deletion models/stdp_dopa_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class STDPDopaConnection : public Connection< targetidentifierT >
ConnTestDummyNode dummy_target;
ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down
2 changes: 1 addition & 1 deletion models/stdp_pl_connection_hom.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class STDPPLConnectionHom : public Connection< targetidentifierT >

ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down
2 changes: 1 addition & 1 deletion models/stdp_triplet_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class STDPTripletConnection : public Connection< targetidentifierT >

ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down
2 changes: 1 addition & 1 deletion models/vogels_sprekeler_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class VogelsSprekelerConnection : public Connection< targetidentifierT >

ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );

t.register_stdp_connection( t_lastspike_ - get_delay() );
t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
}

void
Expand Down
49 changes: 37 additions & 12 deletions nestkernel/archiving_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ nest::Archiving_Node::Archiving_Node()
, tau_minus_inv_( 1. / tau_minus_ )
, tau_minus_triplet_( 110.0 )
, tau_minus_triplet_inv_( 1. / tau_minus_triplet_ )
, max_delay_( -1.0 )
, trace_( 0. )
, last_spike_( -1.0 )
, Ca_t_( 0.0 )
, Ca_minus_( 0.0 )
Expand All @@ -66,6 +68,8 @@ nest::Archiving_Node::Archiving_Node( const Archiving_Node& n )
, tau_minus_inv_( n.tau_minus_inv_ )
, tau_minus_triplet_( n.tau_minus_triplet_ )
, tau_minus_triplet_inv_( n.tau_minus_triplet_inv_ )
, max_delay_( n.max_delay_ )
, trace_( n.trace_ )
, last_spike_( n.last_spike_ )
, Ca_t_( n.Ca_t_ )
, Ca_minus_( n.Ca_minus_ )
Expand All @@ -76,7 +80,7 @@ nest::Archiving_Node::Archiving_Node( const Archiving_Node& n )
}

void
Archiving_Node::register_stdp_connection( double t_first_read )
Archiving_Node::register_stdp_connection( double t_first_read, double delay )
{
// Mark all entries in the deque, which we will not read in future as read by
// this input input, so that we savely increment the incoming number of
Expand All @@ -93,26 +97,38 @@ Archiving_Node::register_stdp_connection( double t_first_read )
}

n_incoming_++;

max_delay_ = std::max( delay, max_delay_ );
}

double
nest::Archiving_Node::get_K_value( double t )
{
// case when the neuron has not yet spiked
if ( history_.empty() )
{
return Kminus_;
trace_ = 0.;
return trace_;
}

// search for the latest post spike in the history buffer that came strictly
// before `t`
int i = history_.size() - 1;
while ( i >= 0 )
{
if ( t - history_[ i ].t_ > kernel().connection_manager.get_stdp_eps() )
{
return ( history_[ i ].Kminus_
trace_ = ( history_[ i ].Kminus_
* std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) );
return trace_;
}
i--;
--i;
}
return 0;

// this case occurs when the trace was requested at a time precisely at or
// before the first spike in the history
trace_ = 0.;
return trace_;
}

void
Expand All @@ -127,7 +143,9 @@ nest::Archiving_Node::get_K_values( double t,
K_value = Kminus_;
return;
}
// case

// search for the latest post spike in the history buffer that came strictly
// before `t`
int i = history_.size() - 1;
while ( i >= 0 )
{
Expand All @@ -139,12 +157,11 @@ nest::Archiving_Node::get_K_values( double t,
* std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) );
return;
}
i--;
--i;
}

// we only get here if t< time of all spikes in history)

// return 0.0 for both K values
// this case occurs when the trace was requested at a time precisely at or
// before the first spike in the history
triplet_K_value = 0.0;
K_value = 0.0;
}
Expand Down Expand Up @@ -187,10 +204,17 @@ nest::Archiving_Node::set_spiketime( Time const& t_sp, double offset )
if ( n_incoming_ )
{
// prune all spikes from history which are no longer needed
// except the penultimate one. we might still need it.
// only remove a spike if:
// - its access counter indicates it has been read out by all connected
// STDP synapses, and
// - there is another, later spike, that is strictly more than
// (max_delay_ + eps) away from the new spike (at t_sp_ms)
while ( history_.size() > 1 )
{
if ( history_.front().access_counter_ >= n_incoming_ )
const double next_t_sp = history_[ 1 ].t_;
if ( history_.front().access_counter_ >= n_incoming_
&& t_sp_ms - next_t_sp > max_delay_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use and instead of &&.

+ kernel().connection_manager.get_stdp_eps() )
{
history_.pop_front();
}
Expand Down Expand Up @@ -226,6 +250,7 @@ nest::Archiving_Node::get_status( DictionaryDatum& d ) const
def< double >( d, names::tau_Ca, tau_Ca_ );
def< double >( d, names::beta_Ca, beta_Ca_ );
def< double >( d, names::tau_minus_triplet, tau_minus_triplet_ );
def< double >( d, names::post_trace, trace_ );
#ifdef DEBUG_ARCHIVER
def< int >( d, names::archiver_length, history_.size() );
#endif
Expand Down
12 changes: 8 additions & 4 deletions nestkernel/archiving_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define ARCHIVING_NODE_H

// C++ includes:
#include <algorithm>
#include <deque>

// Includes from nestkernel:
Expand Down Expand Up @@ -90,8 +91,6 @@ class Archiving_Node : public Node
* \fn int get_synaptic_elements_vacant(Name n)
* Get the number of synaptic elements of type n which are available
* for new synapse creation
* Returns a negative number to indicate that synaptic elements
* must be deleted during the next update
*/
int get_synaptic_elements_vacant( Name n ) const;

Expand Down Expand Up @@ -130,7 +129,9 @@ class Archiving_Node : public Node

/**
* \fn double get_K_value(long t)
* return the Kminus value at t (in ms).
* return the Kminus (synaptic trace) value at t (in ms). When the trace is
* requested at the exact same time that the neuron emits a spike, the trace
* value as it was just before the spike is returned.
*/
double get_K_value( double t );

Expand Down Expand Up @@ -167,7 +168,7 @@ class Archiving_Node : public Node
* t_first_read: The newly registered synapse will read the history entries
* with t > t_first_read.
*/
void register_stdp_connection( double t_first_read );
void register_stdp_connection( double t_first_read, double delay );

void get_status( DictionaryDatum& d ) const;
void set_status( const DictionaryDatum& d );
Expand Down Expand Up @@ -216,6 +217,9 @@ class Archiving_Node : public Node
double tau_minus_triplet_;
double tau_minus_triplet_inv_;

double max_delay_;
double trace_;

double last_spike_;

// spiking history needed by stdp synapses
Expand Down
2 changes: 2 additions & 0 deletions nestkernel/nest_names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,9 @@ const Name port_name( "port_name" );
const Name port_width( "port_width" );
const Name ports( "ports" );
const Name post_synaptic_element( "post_synaptic_element" );
const Name post_trace( "post_trace" );
const Name pre_synaptic_element( "pre_synaptic_element" );
const Name pre_trace( "pre_trace" );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like pre_trace is used anywhere. Can it be removed?

const Name precise_times( "precise_times" );
const Name precision( "precision" );
const Name print_time( "print_time" );
Expand Down
2 changes: 2 additions & 0 deletions nestkernel/nest_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ extern const Name port_name;
extern const Name port_width;
extern const Name ports;
extern const Name post_synaptic_element;
extern const Name post_trace;
extern const Name pre_synaptic_element;
extern const Name pre_trace;
extern const Name precise_times;
extern const Name precision;
extern const Name print_time;
Expand Down
2 changes: 1 addition & 1 deletion nestkernel/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ Node::send_test_event( Node&, rport, synindex, bool )
* throws IllegalConnection
*/
void
Node::register_stdp_connection( double )
Node::register_stdp_connection( double, double )
{
throw IllegalConnection();
}
Expand Down
2 changes: 1 addition & 1 deletion nestkernel/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ class Node
* @throws IllegalConnection
*
*/
virtual void register_stdp_connection( double );
virtual void register_stdp_connection( double, double );

/**
* Handle incoming spike events.
Expand Down
Loading