diff --git a/doc/htmldoc/developer_space/axonal_delays.rst b/doc/htmldoc/developer_space/axonal_delays.rst
new file mode 100644
index 0000000000..5e3c405a56
--- /dev/null
+++ b/doc/htmldoc/developer_space/axonal_delays.rst
@@ -0,0 +1,86 @@
+.. _axonal_delays_dev:
+
+Axonal Delays
+=============
+
+Adding axonal delays to NEST is non-trivial when it comes to their interaction with spike-timing dependent plasticity (STDP).
+Axonal delays lower than their dendritic counterpart are non-problematic, however larger axonal delays cause causality
+issues due to the way how and when pre- and post-synaptic spikes are processed in NEST by synapses implementing STDP weight dynamics.
+
+If a pre-synaptic spike is processed at a synapse, it will also process all post-synaptic spikes that reached the synapse
+between the last and current pre-synaptic spike. Weight changes due facilitation (post-synaptic spike following a
+pre-synaptic one) or depression (pre-synaptic spike following a post-synaptic one) are only relevant at the time when pre-synaptic spikes
+reach the synapse, as this is the only point in time when the exact weight is of importance. Post-synaptic spikes can
+therefore be archived in the post-synaptic neuron until the next pre-synaptic spike is processed by the synapse.
+As all pre-synaptic spikes are delivered to their target synapse and neuron right after they have been communicated,
+they might be processed before they would actually reach the synapse when taking axonal delays into account.
+If the axonal delay is now larger than the dendritic delay, post-synaptic
+spikes occurring at time `t` will reach the synapse before pre-synaptic spikes occurring before `t`,
+but might not be taken into account by the pre-synaptic spike, if it was already communicated,
+and thus delivered, before `t`. Each pre-synaptic spike sent over a connection
+with a predominant axonal delay must therefore also process post-synaptic spikes which have not yet occurred,
+but could be emitted in the future. Multiple implementations were implemented and
+benchmarked before coming to the conclusion that the implementation at hand should be used inside NEST.
+
+The main idea of the axonal delays implementation in NEST is based on the fact, that neurons only emit few spikes per second.
+It should thus be rare that a post-synaptic spike occurs right after a pre-synaptic one in the critical region before
+the pre-synaptic spike reaches the synapse, but has already been processed. In typical networks, there will most likely
+only be few occurrences where causality becomes an issue. In order to still guarantee correct synaptic weights,
+incorrect STDP weight changes are rolled back, re-calculated, and the weight of pre-synaptic spike, which already reached
+the target neuron's ring buffer, is corrected. Undoing the STDP weight changes and re-calculating them obviously comes
+with a cost, however as only few such occurrences are to be expected, this solution is more efficient than restructuring
+the kernel to make sure axonal delays are always handled correctly (see Alternative implementations).
+
+Changes to the kernel and neuron models
+---------------------------------------
+
+Introducing axonal delays changes the way the min- and max-delays must be calculated, as they are now a combination of
+dendritic and axonal delays. The default value for the delay which is now referring to the dendritic delay remains 1,
+while the default value for axonal_delay is set to 0. In the default case, purely dendritic delay is assumed.
+
+The ``ArchivingNode`` was made axonal-delay-aware. Each pre-synaptic spike after which a correction could potentially follow,
+will be archived in the post-synaptic neuron in a dynamic ring-buffer-like structure. Post-synaptic spikes will then
+trigger a correction for all relevant pre-synaptic spikes in this buffer. The way spikes are received at a neuron is
+model-dependent, as the implementation of spike accumulation and buffering until being processed might vary between
+neuron models. Neurons models will therefore also have to handle correction of previously handled spikes differently.
+In the simplest case, all incoming spikes to a neuron are simply accumulated in a single scalar value per time slot.
+A correction of a previously handled spike would therefore just subtract the previous, wrong weight and add the new,
+corrected weight. Therefore, simply sending another spike with the difference of the old and new weight would be
+sufficient in this case. However, some neurons might have different buffers for spikes being sent over inhibitory and
+excitatory connections, which could be distinguished by the sign of the weight. If a new spike is now sent to correct
+an old one, the sign might be negative even though both the old and new weight were originally positive, the new weight
+is just smaller. In such a case, the spike would be accumulated in the wrong buffer.
+
+Instead of sending a regular ``SpikeEvent`` to signal a correction, a ``CorrectionSpikeEvent`` is sent. Overloading the handle
+function now allows handling the correction in the correct way, depending on the model implementation.
+Furthermore, neuron models must now call ``ArchivingNode::pre_run_hook_()`` in their derived pre_run_hook implementation
+and call ``reset_correction_entries_stdp_ax_delay_()`` at the end of their update implementation.
+Currently, only the ``iaf_psc_alpha`` neuron model supports STDP with axonal delays.
+All other neurons will act as if the delay of incoming connections was purely dendritic.
+
+Synapse models only support dendritic delay by default. If axonal delays are required, the synapse model must be derived
+from ``AxonalDelayConnection`` instead of ``Connection``. The ``AxonalDelayConnection`` is derived from ``Connection`` and adds a single
+double-precision member for the axonal delay. The main differences compared to synapses with purely dendritic delays are
+different handling of delays inside the send function and the addition of the ``correct_synapse_stdp_ax_delay`` which is
+called by the ``ConnectionManager`` when a synapse needs to re-calculate its weight given a new post-synaptic spike and a previous pre-synaptic one.
+Currently, only the ``stdp_pl_synapse_hom_ax_delay`` synapse model supports axonal delays.
+
+Changes to the python interface
+-------------------------------
+
+In general, the kernel was made axonal-delay-aware and this is reflected in the user interface, as it is now possible
+to set the ``names::dendritic_delay`` and ``names::axonal_delay`` for each synapse (given that the synapse model is
+derived from ``AxonalDelayConnection``).
+
+Remaining work
+---------------
+
+
+Currently, only one neuron and synapse model are supporting axonal delays. All neuron models that support STDP could
+also support axonal delays, without sacrificing performance, changing their behavior, or requiring more memory, but need
+to be adapted slightly (i.e., implement handle for ``CorrectionSpikeEvent``, call ``ArchivingNode::pre_run_hook_`` and call
+``reset_correction_entries_stdp_ax_delay_``).
+
+Existing STDP synapse models need one version with and one without axonal delays. Alternatively, synapse models could
+be templatized to either use only dendritic or dendritic and axonal delays. However, this branching should be resolved
+at compile time to not negatively impact performance.
diff --git a/doc/htmldoc/developer_space/index.rst b/doc/htmldoc/developer_space/index.rst
index f0b8125e4f..16b4ecd570 100644
--- a/doc/htmldoc/developer_space/index.rst
+++ b/doc/htmldoc/developer_space/index.rst
@@ -122,4 +122,5 @@ Developer guides
guidelines/styleguide/vim_support_sli
templates/*
sli_docs/index
+ axonal_delays
cppcomments
diff --git a/doc/htmldoc/examples/index.rst b/doc/htmldoc/examples/index.rst
index cbd061272b..287d7d4e00 100644
--- a/doc/htmldoc/examples/index.rst
+++ b/doc/htmldoc/examples/index.rst
@@ -219,6 +219,10 @@ PyNEST examples
* :doc:`/auto_examples/eprop_plasticity/eprop_supervised_regression_sine-waves`
* :doc:`/auto_examples/eprop_plasticity/eprop_supervised_classification_neuromorphic_mnist`
+ .. grid-item-card:: Axonal delays
+ :img-top: ../static/img/nest_logo-faded.png
+
+ * :doc:`/auto_examples/axonal_delays`
.. grid:: 1 1 2 3
@@ -340,4 +344,4 @@ PyNEST examples
../auto_examples/astrocytes/index
../auto_examples/EI_clustered_network/index
../auto_examples/eprop_plasticity/index
- ../auto_examples/wang_decision_making
+ ../auto_examples/wang_decision_making
\ No newline at end of file
diff --git a/doc/htmldoc/get-started_index.rst b/doc/htmldoc/get-started_index.rst
index 0e8ff5eb17..c84897eb83 100644
--- a/doc/htmldoc/get-started_index.rst
+++ b/doc/htmldoc/get-started_index.rst
@@ -159,6 +159,7 @@ More topics
* :ref:`sim_gap_junctions`
* :ref:`weight_normalization`
+ * :ref:`delays`
diff --git a/doc/htmldoc/synapses/delays.rst b/doc/htmldoc/synapses/delays.rst
new file mode 100644
index 0000000000..d8dab296d6
--- /dev/null
+++ b/doc/htmldoc/synapses/delays.rst
@@ -0,0 +1,73 @@
+.. _delays:
+
+Delays
+======
+
+
+In NEST, transmission delays are specified with the ``delay`` parameter.
+Delays are considered fully dendritic by all built-in models and therefore, the ``delay`` parameter is still used by
+most models.
+
+Since NEST 3.9, it is also possible to specify both explicit, heterogeneous axonal and dendritic delays for models
+supporting this feature. This is useful for STDP models and other models relying on the timing of spike arrival at the
+synapse.
+
+Currently, only ``stdp_pl_synapse_hom_ax_delay`` supports explicitly specifying axonal and dendritic delays with the
+``axonal_delay`` and ``dendtritic_delay`` parameters. For STDP with predominant axonal delays, neuron models must be
+adjusted to correctly handle these delays. At this point, only ``iaf_psc_alpha`` supports STDP with predominant axonal
+delays.
+
+When using ``stdp_pl_synapse_hom_ax_delay``:
+
+- The parameter ``delay`` is no longer valid. This is to prevent ambiguity between the two types of delays.
+- The parameter names ``dendritic_delay`` and ``axonal_delay`` have to be used to specify delay.
+- If these parameters are not explicitly provided, then the default values are used:
+
+ ``dendritic_delay: 1.0`` and ``axonal_delay: 0.0``.
+- If only axonal delay is provided and no dendritic delay, the dendritic delay is assumed to be 0 and vice-versa.
+
+
+Use of ``axonal_delay`` and ``dendritic_delay`` is the same as ``delay``:
+
+
+**Using syn_spec**
+
+.. code-block:: python
+
+ nest.Create("iaf_psc_alpha")
+ nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom", "delay": 1.0})
+
+.. code-block:: python
+
+ nest.Create("iaf_psc_alpha")
+ nest.Connect(neuron, neuron, syn_spec=
+ {"synapse_model": "stdp_pl_synapse_hom_ax_delay", "axonal_delay": 1.0, "dendritic_delay": 1.0})
+
+**Using SetStatus**
+
+.. code-block:: python
+
+ conn = nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom"})
+ nest.SetStatus(conn, {"delay": 1.0})
+
+.. code-block:: python
+
+ conn = nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay"})
+ nest.SetStatus(conn, {"axonal_delay": 1.0, "dendritic_delay": 1.0})
+
+**Using SetDefaults**
+
+.. code-block:: python
+
+ nest.SetDefaults("stdp_pl_synapse_hom", {"delay": 1.0})
+
+.. code-block:: python
+
+ nest.SetDefaults("stdp_pl_synapse_hom_ax_delay", {"axonal_delay": 1.0, "dendritic_delay": 1.0})
+
+
+.. seealso::
+
+ :doc:`Example using axonal delays `
+
+ For details on further developments see :ref:`axonal_delays_dev`.
diff --git a/libnestutil/nest_types.h b/libnestutil/nest_types.h
index 2e37234248..14ff0d299d 100644
--- a/libnestutil/nest_types.h
+++ b/libnestutil/nest_types.h
@@ -91,9 +91,15 @@ constexpr uint8_t NUM_BITS_LCID = 27U;
constexpr uint8_t NUM_BITS_PROCESSED_FLAG = 1U;
constexpr uint8_t NUM_BITS_MARKER_SPIKE_DATA = 2U;
constexpr uint8_t NUM_BITS_LAG = 14U;
-constexpr uint8_t NUM_BITS_DELAY = 21U;
constexpr uint8_t NUM_BITS_NODE_ID = 62U;
+// These types are used in delay_types.h and denote the space available for the dendritic and axonal portions of the
+// total transmission delay. The delay is only split into two parts for selected synapse types.
+// Given that axonal delays can be much larger than dendritic/backpropagation delays, they require more bits.
+constexpr uint8_t NUM_BITS_DENDRITIC_DELAY = 14U;
+constexpr uint8_t NUM_BITS_AXONAL_DELAY = sizeof( unsigned int ) * 8 - NUM_BITS_DENDRITIC_DELAY;
+
+
// Maximally allowed values for bitfields
constexpr uint64_t MAX_LCID = generate_max_value( NUM_BITS_LCID );
diff --git a/models/ac_generator.cpp b/models/ac_generator.cpp
index d7c5ea7751..79efcb0a7f 100644
--- a/models/ac_generator.cpp
+++ b/models/ac_generator.cpp
@@ -56,13 +56,12 @@ RecordablesMap< ac_generator >::create()
{
insert_( Name( names::I ), &ac_generator::get_I_ );
}
-}
/* ----------------------------------------------------------------
* Default constructors defining default parameters and state
* ---------------------------------------------------------------- */
-nest::ac_generator::Parameters_::Parameters_()
+ac_generator::Parameters_::Parameters_()
: amp_( 0.0 ) // pA
, offset_( 0.0 ) // pA
, freq_( 0.0 ) // Hz
@@ -70,7 +69,7 @@ nest::ac_generator::Parameters_::Parameters_()
{
}
-nest::ac_generator::Parameters_::Parameters_( const Parameters_& p )
+ac_generator::Parameters_::Parameters_( const Parameters_& p )
: amp_( p.amp_ )
, offset_( p.offset_ )
, freq_( p.freq_ )
@@ -78,8 +77,8 @@ nest::ac_generator::Parameters_::Parameters_( const Parameters_& p )
{
}
-nest::ac_generator::Parameters_&
-nest::ac_generator::Parameters_::operator=( const Parameters_& p )
+ac_generator::Parameters_&
+ac_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -94,19 +93,19 @@ nest::ac_generator::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::ac_generator::State_::State_()
+ac_generator::State_::State_()
: y_0_( 0.0 )
, y_1_( 0.0 ) // pA
, I_( 0.0 ) // pA
{
}
-nest::ac_generator::Buffers_::Buffers_( ac_generator& n )
+ac_generator::Buffers_::Buffers_( ac_generator& n )
: logger_( n )
{
}
-nest::ac_generator::Buffers_::Buffers_( const Buffers_&, ac_generator& n )
+ac_generator::Buffers_::Buffers_( const Buffers_&, ac_generator& n )
: logger_( n )
{
}
@@ -116,7 +115,7 @@ nest::ac_generator::Buffers_::Buffers_( const Buffers_&, ac_generator& n )
* ---------------------------------------------------------------- */
void
-nest::ac_generator::Parameters_::get( DictionaryDatum& d ) const
+ac_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::amplitude ] = amp_;
( *d )[ names::offset ] = offset_;
@@ -125,14 +124,14 @@ nest::ac_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::ac_generator::State_::get( DictionaryDatum& d ) const
+ac_generator::State_::get( DictionaryDatum& d ) const
{
( *d )[ names::y_0 ] = y_0_;
( *d )[ names::y_1 ] = y_1_;
}
void
-nest::ac_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
+ac_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::amplitude, amp_, node );
updateValueParam< double >( d, names::offset, offset_, node );
@@ -145,7 +144,7 @@ nest::ac_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::ac_generator::ac_generator()
+ac_generator::ac_generator()
: StimulationDevice()
, P_()
, S_()
@@ -154,7 +153,7 @@ nest::ac_generator::ac_generator()
recordablesMap_.create();
}
-nest::ac_generator::ac_generator( const ac_generator& n )
+ac_generator::ac_generator( const ac_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -168,20 +167,20 @@ nest::ac_generator::ac_generator( const ac_generator& n )
* ---------------------------------------------------------------- */
void
-nest::ac_generator::init_state_()
+ac_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::ac_generator::init_buffers_()
+ac_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
}
void
-nest::ac_generator::pre_run_hook()
+ac_generator::pre_run_hook()
{
B_.logger_.init();
@@ -206,7 +205,7 @@ nest::ac_generator::pre_run_hook()
}
void
-nest::ac_generator::update( Time const& origin, const long from, const long to )
+ac_generator::update( Time const& origin, const long from, const long to )
{
long start = origin.get_steps();
@@ -231,7 +230,7 @@ nest::ac_generator::update( Time const& origin, const long from, const long to )
}
void
-nest::ac_generator::handle( DataLoggingRequest& e )
+ac_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
@@ -241,7 +240,7 @@ nest::ac_generator::handle( DataLoggingRequest& e )
* ---------------------------------------------------------------- */
void
-nest::ac_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+ac_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -264,3 +263,5 @@ nest::ac_generator::set_data_from_stimulation_backend( std::vector< double >& in
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/aeif_cond_alpha.cpp b/models/aeif_cond_alpha.cpp
index dc8298bc3e..616347a0a4 100644
--- a/models/aeif_cond_alpha.cpp
+++ b/models/aeif_cond_alpha.cpp
@@ -426,6 +426,8 @@ nest::aeif_cond_alpha::init_buffers_()
void
nest::aeif_cond_alpha::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_cond_alpha_astro.cpp b/models/aeif_cond_alpha_astro.cpp
index 9b073b5487..e8e8224b2f 100644
--- a/models/aeif_cond_alpha_astro.cpp
+++ b/models/aeif_cond_alpha_astro.cpp
@@ -429,6 +429,8 @@ nest::aeif_cond_alpha_astro::init_buffers_()
void
nest::aeif_cond_alpha_astro::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_cond_alpha_multisynapse.cpp b/models/aeif_cond_alpha_multisynapse.cpp
index f027713973..ba018dfe0e 100644
--- a/models/aeif_cond_alpha_multisynapse.cpp
+++ b/models/aeif_cond_alpha_multisynapse.cpp
@@ -441,6 +441,8 @@ aeif_cond_alpha_multisynapse::init_buffers_()
void
aeif_cond_alpha_multisynapse::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_cond_beta_multisynapse.cpp b/models/aeif_cond_beta_multisynapse.cpp
index 5ef7e10717..7f2eb6f74f 100644
--- a/models/aeif_cond_beta_multisynapse.cpp
+++ b/models/aeif_cond_beta_multisynapse.cpp
@@ -449,6 +449,8 @@ aeif_cond_beta_multisynapse::init_buffers_()
void
aeif_cond_beta_multisynapse::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_cond_exp.cpp b/models/aeif_cond_exp.cpp
index cb0eb86d0c..470bbc002b 100644
--- a/models/aeif_cond_exp.cpp
+++ b/models/aeif_cond_exp.cpp
@@ -421,6 +421,8 @@ nest::aeif_cond_exp::init_buffers_()
void
nest::aeif_cond_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_psc_alpha.cpp b/models/aeif_psc_alpha.cpp
index b4a1b9c86e..19117202ee 100644
--- a/models/aeif_psc_alpha.cpp
+++ b/models/aeif_psc_alpha.cpp
@@ -416,6 +416,8 @@ nest::aeif_psc_alpha::init_buffers_()
void
nest::aeif_psc_alpha::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_psc_delta.cpp b/models/aeif_psc_delta.cpp
index 7cafe3ad64..1ff2f245a4 100644
--- a/models/aeif_psc_delta.cpp
+++ b/models/aeif_psc_delta.cpp
@@ -392,6 +392,8 @@ nest::aeif_psc_delta::init_buffers_()
void
nest::aeif_psc_delta::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_psc_delta_clopath.cpp b/models/aeif_psc_delta_clopath.cpp
index c45158ee77..93fbe91af9 100644
--- a/models/aeif_psc_delta_clopath.cpp
+++ b/models/aeif_psc_delta_clopath.cpp
@@ -460,6 +460,8 @@ nest::aeif_psc_delta_clopath::init_buffers_()
void
nest::aeif_psc_delta_clopath::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/aeif_psc_exp.cpp b/models/aeif_psc_exp.cpp
index 6b8aec869c..8cbe1b3c85 100644
--- a/models/aeif_psc_exp.cpp
+++ b/models/aeif_psc_exp.cpp
@@ -411,6 +411,8 @@ nest::aeif_psc_exp::init_buffers_()
void
nest::aeif_psc_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/amat2_psc_exp.cpp b/models/amat2_psc_exp.cpp
index 06bce3bd22..0a111f322e 100644
--- a/models/amat2_psc_exp.cpp
+++ b/models/amat2_psc_exp.cpp
@@ -264,6 +264,8 @@ nest::amat2_psc_exp::init_buffers_()
void
nest::amat2_psc_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/bernoulli_synapse.h b/models/bernoulli_synapse.h
index 78a6faa963..424723252d 100644
--- a/models/bernoulli_synapse.h
+++ b/models/bernoulli_synapse.h
@@ -96,12 +96,12 @@ EndUserDocs */
void register_bernoulli_synapse( const std::string& name );
template < typename targetidentifierT >
-class bernoulli_synapse : public Connection< targetidentifierT >
+class bernoulli_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -148,10 +148,10 @@ class bernoulli_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
bool
diff --git a/models/binary_neuron.h b/models/binary_neuron.h
index d3854d650e..4416dc3e15 100644
--- a/models/binary_neuron.h
+++ b/models/binary_neuron.h
@@ -434,6 +434,8 @@ template < class TGainfunction >
void
binary_neuron< TGainfunction >::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
V_.rng_ = get_vp_specific_rng( get_thread() );
diff --git a/models/clopath_synapse.h b/models/clopath_synapse.h
index 331907f0b2..ba1d976273 100644
--- a/models/clopath_synapse.h
+++ b/models/clopath_synapse.h
@@ -117,12 +117,12 @@ EndUserDocs */
void register_clopath_synapse( const std::string& name );
template < typename targetidentifierT >
-class clopath_synapse : public Connection< targetidentifierT >
+class clopath_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::REQUIRES_CLOPATH_ARCHIVING
@@ -147,7 +147,7 @@ class clopath_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -184,13 +184,13 @@ class clopath_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -237,11 +237,11 @@ template < typename targetidentifierT >
inline bool
clopath_synapse< targetidentifierT >::send( Event& e, size_t t, const CommonSynapseProperties& )
{
- 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
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ const double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry_extended >::iterator start;
diff --git a/models/cm_default.cpp b/models/cm_default.cpp
index 37b714929b..bc93c1b70b 100644
--- a/models/cm_default.cpp
+++ b/models/cm_default.cpp
@@ -303,6 +303,8 @@ nest::cm_default::init_recordables_pointers_()
void
nest::cm_default::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
logger_.init();
// initialize the pointers within the compartment tree
diff --git a/models/cont_delay_synapse.h b/models/cont_delay_synapse.h
index a5759c2622..ebd12cba92 100644
--- a/models/cont_delay_synapse.h
+++ b/models/cont_delay_synapse.h
@@ -81,12 +81,12 @@ EndUserDocs */
void register_cont_delay_synapse( const std::string& name );
template < typename targetidentifierT >
-class cont_delay_synapse : public Connection< targetidentifierT >
+class cont_delay_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -115,6 +115,7 @@ class cont_delay_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -198,10 +199,10 @@ class cont_delay_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
private:
diff --git a/models/cont_delay_synapse_impl.h b/models/cont_delay_synapse_impl.h
index 4a029b82a8..60429ad212 100644
--- a/models/cont_delay_synapse_impl.h
+++ b/models/cont_delay_synapse_impl.h
@@ -51,7 +51,7 @@ cont_delay_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const
ConnectionBase::get_status( d );
def< double >( d, names::weight, weight_ );
- def< double >( d, names::delay, Time( Time::step( get_delay_steps() ) ).get_ms() - delay_offset_ );
+ def< double >( d, names::delay, get_delay_ms() - delay_offset_ );
def< long >( d, names::size_of, sizeof( *this ) );
}
diff --git a/models/correlation_detector.cpp b/models/correlation_detector.cpp
index 3d7b09b8ae..e8cbb94cd1 100644
--- a/models/correlation_detector.cpp
+++ b/models/correlation_detector.cpp
@@ -47,11 +47,14 @@ nest::register_correlation_detector( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Default constructors defining default parameters and state
* ---------------------------------------------------------------- */
-nest::correlation_detector::Parameters_::Parameters_()
+correlation_detector::Parameters_::Parameters_()
: delta_tau_( get_default_delta_tau() )
, tau_max_( 10 * delta_tau_ )
, Tstart_( Time::ms( 0.0 ) )
@@ -59,7 +62,7 @@ nest::correlation_detector::Parameters_::Parameters_()
{
}
-nest::correlation_detector::Parameters_::Parameters_( const Parameters_& p )
+correlation_detector::Parameters_::Parameters_( const Parameters_& p )
: delta_tau_( p.delta_tau_ )
, tau_max_( p.tau_max_ )
, Tstart_( p.Tstart_ )
@@ -79,8 +82,8 @@ nest::correlation_detector::Parameters_::Parameters_( const Parameters_& p )
Tstop_.calibrate();
}
-nest::correlation_detector::Parameters_&
-nest::correlation_detector::Parameters_::operator=( const Parameters_& p )
+correlation_detector::Parameters_&
+correlation_detector::Parameters_::operator=( const Parameters_& p )
{
delta_tau_ = p.delta_tau_;
tau_max_ = p.tau_max_;
@@ -95,7 +98,7 @@ nest::correlation_detector::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::correlation_detector::State_::State_()
+correlation_detector::State_::State_()
: n_events_( 2, 0 )
, incoming_( 2 )
, histogram_()
@@ -110,7 +113,7 @@ nest::correlation_detector::State_::State_()
* ---------------------------------------------------------------- */
void
-nest::correlation_detector::Parameters_::get( DictionaryDatum& d ) const
+correlation_detector::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::delta_tau ] = delta_tau_.get_ms();
( *d )[ names::tau_max ] = tau_max_.get_ms();
@@ -119,7 +122,7 @@ nest::correlation_detector::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::correlation_detector::State_::get( DictionaryDatum& d ) const
+correlation_detector::State_::get( DictionaryDatum& d ) const
{
( *d )[ names::n_events ] = IntVectorDatum( new std::vector< long >( n_events_ ) );
( *d )[ names::histogram ] = DoubleVectorDatum( new std::vector< double >( histogram_ ) );
@@ -128,7 +131,7 @@ nest::correlation_detector::State_::get( DictionaryDatum& d ) const
}
bool
-nest::correlation_detector::Parameters_::set( const DictionaryDatum& d, const correlation_detector& n, Node* node )
+correlation_detector::Parameters_::set( const DictionaryDatum& d, const correlation_detector& n, Node* node )
{
bool reset = false;
double t;
@@ -170,7 +173,7 @@ nest::correlation_detector::Parameters_::set( const DictionaryDatum& d, const co
}
void
-nest::correlation_detector::State_::set( const DictionaryDatum& d, const Parameters_& p, bool reset_required, Node* )
+correlation_detector::State_::set( const DictionaryDatum& d, const Parameters_& p, bool reset_required, Node* )
{
std::vector< long > nev;
if ( updateValue< std::vector< long > >( d, names::n_events, nev ) )
@@ -191,7 +194,7 @@ nest::correlation_detector::State_::set( const DictionaryDatum& d, const Paramet
}
void
-nest::correlation_detector::State_::reset( const Parameters_& p )
+correlation_detector::State_::reset( const Parameters_& p )
{
n_events_.clear();
n_events_.resize( 2, 0 );
@@ -214,7 +217,7 @@ nest::correlation_detector::State_::reset( const Parameters_& p )
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::correlation_detector::correlation_detector()
+correlation_detector::correlation_detector()
: Node()
, device_()
, P_()
@@ -222,7 +225,7 @@ nest::correlation_detector::correlation_detector()
{
}
-nest::correlation_detector::correlation_detector( const correlation_detector& n )
+correlation_detector::correlation_detector( const correlation_detector& n )
: Node( n )
, device_( n.device_ )
, P_( n.P_ )
@@ -236,20 +239,20 @@ nest::correlation_detector::correlation_detector( const correlation_detector& n
* ---------------------------------------------------------------- */
void
-nest::correlation_detector::init_state_()
+correlation_detector::init_state_()
{
device_.init_state();
}
void
-nest::correlation_detector::init_buffers_()
+correlation_detector::init_buffers_()
{
device_.init_buffers();
S_.reset( P_ );
}
void
-nest::correlation_detector::pre_run_hook()
+correlation_detector::pre_run_hook()
{
device_.pre_run_hook();
}
@@ -260,12 +263,12 @@ nest::correlation_detector::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::correlation_detector::update( Time const&, const long, const long )
+correlation_detector::update( Time const&, const long, const long )
{
}
void
-nest::correlation_detector::handle( SpikeEvent& e )
+correlation_detector::handle( SpikeEvent& e )
{
// The receiver port identifies the sending node in our
// sender list.
@@ -354,7 +357,7 @@ nest::correlation_detector::handle( SpikeEvent& e )
}
void
-nest::correlation_detector::calibrate_time( const TimeConverter& tc )
+correlation_detector::calibrate_time( const TimeConverter& tc )
{
if ( P_.delta_tau_.is_step() )
{
@@ -372,3 +375,5 @@ nest::correlation_detector::calibrate_time( const TimeConverter& tc )
P_.Tstart_ = tc.from_old_tics( P_.Tstart_.get_tics() );
P_.Tstop_ = tc.from_old_tics( P_.Tstop_.get_tics() );
}
+
+}
\ No newline at end of file
diff --git a/models/correlomatrix_detector.cpp b/models/correlomatrix_detector.cpp
index bab3a03043..66e854b82a 100644
--- a/models/correlomatrix_detector.cpp
+++ b/models/correlomatrix_detector.cpp
@@ -39,7 +39,6 @@
// Includes from sli:
#include "arraydatum.h"
#include "dict.h"
-#include "dictutils.h"
void
nest::register_correlomatrix_detector( const std::string& name )
@@ -228,11 +227,11 @@ nest::correlomatrix_detector::State_::reset( const Parameters_& p )
count_covariance_.clear();
count_covariance_.resize( p.N_channels_ );
- for ( long i = 0; i < p.N_channels_; ++i )
+ for ( size_t i = 0; i < p.N_channels_; ++i )
{
covariance_[ i ].resize( p.N_channels_ );
count_covariance_[ i ].resize( p.N_channels_ );
- for ( long j = 0; j < p.N_channels_; ++j )
+ for ( size_t j = 0; j < p.N_channels_; ++j )
{
covariance_[ i ][ j ].resize( 1 + p.tau_max_.get_steps() / p.delta_tau_.get_steps(), 0 );
count_covariance_[ i ][ j ].resize( 1 + p.tau_max_.get_steps() / p.delta_tau_.get_steps(), 0 );
@@ -349,8 +348,8 @@ nest::correlomatrix_detector::handle( SpikeEvent& e )
for ( SpikelistType::const_iterator spike_j = otherSpikes.begin(); spike_j != otherSpikes.end(); ++spike_j )
{
size_t bin;
- long other = spike_j->receptor_channel_;
- long sender_ind, other_ind;
+ size_t other = spike_j->receptor_channel_;
+ size_t sender_ind, other_ind;
if ( spike_i < spike_j->timestep_ )
{
diff --git a/models/correlospinmatrix_detector.cpp b/models/correlospinmatrix_detector.cpp
index ec270da576..d4c62beb7b 100644
--- a/models/correlospinmatrix_detector.cpp
+++ b/models/correlospinmatrix_detector.cpp
@@ -41,18 +41,20 @@
#include "dict.h"
#include "dictutils.h"
+namespace nest
+{
+
void
-nest::register_correlospinmatrix_detector( const std::string& name )
+register_correlospinmatrix_detector( const std::string& name )
{
register_node_model< correlospinmatrix_detector >( name );
}
-
/* ----------------------------------------------------------------
* Default constructors defining default parameters and state
* ---------------------------------------------------------------- */
-nest::correlospinmatrix_detector::Parameters_::Parameters_()
+correlospinmatrix_detector::Parameters_::Parameters_()
: delta_tau_( get_default_delta_tau() )
, tau_max_( 10 * delta_tau_ )
, Tstart_( Time::ms( 0.0 ) )
@@ -61,7 +63,7 @@ nest::correlospinmatrix_detector::Parameters_::Parameters_()
{
}
-nest::correlospinmatrix_detector::Parameters_::Parameters_( const Parameters_& p )
+correlospinmatrix_detector::Parameters_::Parameters_( const Parameters_& p )
: delta_tau_( p.delta_tau_ )
, tau_max_( p.tau_max_ )
, Tstart_( p.Tstart_ )
@@ -83,8 +85,8 @@ nest::correlospinmatrix_detector::Parameters_::Parameters_( const Parameters_& p
}
-nest::correlospinmatrix_detector::Parameters_&
-nest::correlospinmatrix_detector::Parameters_::operator=( const Parameters_& p )
+correlospinmatrix_detector::Parameters_&
+correlospinmatrix_detector::Parameters_::operator=( const Parameters_& p )
{
delta_tau_ = p.delta_tau_;
tau_max_ = p.tau_max_;
@@ -101,7 +103,7 @@ nest::correlospinmatrix_detector::Parameters_::operator=( const Parameters_& p )
}
-nest::correlospinmatrix_detector::State_::State_()
+correlospinmatrix_detector::State_::State_()
: incoming_()
, last_i_( 0 )
, t_last_in_spike_( Time::neg_inf() )
@@ -115,7 +117,7 @@ nest::correlospinmatrix_detector::State_::State_()
* ---------------------------------------------------------------- */
void
-nest::correlospinmatrix_detector::Parameters_::get( DictionaryDatum& d ) const
+correlospinmatrix_detector::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::delta_tau ] = delta_tau_.get_ms();
( *d )[ names::tau_max ] = tau_max_.get_ms();
@@ -125,7 +127,7 @@ nest::correlospinmatrix_detector::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::correlospinmatrix_detector::State_::get( DictionaryDatum& d ) const
+correlospinmatrix_detector::State_::get( DictionaryDatum& d ) const
{
ArrayDatum* CountC = new ArrayDatum;
for ( size_t i = 0; i < count_covariance_.size(); ++i )
@@ -141,7 +143,7 @@ nest::correlospinmatrix_detector::State_::get( DictionaryDatum& d ) const
}
bool
-nest::correlospinmatrix_detector::Parameters_::set( const DictionaryDatum& d,
+correlospinmatrix_detector::Parameters_::set( const DictionaryDatum& d,
const correlospinmatrix_detector& n,
Node* node )
{
@@ -215,12 +217,12 @@ nest::correlospinmatrix_detector::Parameters_::set( const DictionaryDatum& d,
}
void
-nest::correlospinmatrix_detector::State_::set( const DictionaryDatum&, const Parameters_&, bool, Node* )
+correlospinmatrix_detector::State_::set( const DictionaryDatum&, const Parameters_&, bool, Node* )
{
}
void
-nest::correlospinmatrix_detector::State_::reset( const Parameters_& p )
+correlospinmatrix_detector::State_::reset( const Parameters_& p )
{
last_i_ = 0;
tentative_down_ = false;
@@ -253,7 +255,7 @@ nest::correlospinmatrix_detector::State_::reset( const Parameters_& p )
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::correlospinmatrix_detector::correlospinmatrix_detector()
+correlospinmatrix_detector::correlospinmatrix_detector()
: Node()
, device_()
, P_()
@@ -261,7 +263,7 @@ nest::correlospinmatrix_detector::correlospinmatrix_detector()
{
}
-nest::correlospinmatrix_detector::correlospinmatrix_detector( const correlospinmatrix_detector& n )
+correlospinmatrix_detector::correlospinmatrix_detector( const correlospinmatrix_detector& n )
: Node( n )
, device_( n.device_ )
, P_( n.P_ )
@@ -275,20 +277,20 @@ nest::correlospinmatrix_detector::correlospinmatrix_detector( const correlospinm
* ---------------------------------------------------------------- */
void
-nest::correlospinmatrix_detector::init_state_()
+correlospinmatrix_detector::init_state_()
{
device_.init_state();
}
void
-nest::correlospinmatrix_detector::init_buffers_()
+correlospinmatrix_detector::init_buffers_()
{
device_.init_buffers();
S_.reset( P_ );
}
void
-nest::correlospinmatrix_detector::pre_run_hook()
+correlospinmatrix_detector::pre_run_hook()
{
device_.pre_run_hook();
}
@@ -299,12 +301,12 @@ nest::correlospinmatrix_detector::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::correlospinmatrix_detector::update( Time const&, const long, const long )
+correlospinmatrix_detector::update( Time const&, const long, const long )
{
}
void
-nest::correlospinmatrix_detector::handle( SpikeEvent& e )
+correlospinmatrix_detector::handle( SpikeEvent& e )
{
// The receiver port identifies the sending node in our
// sender list.
@@ -392,7 +394,7 @@ nest::correlospinmatrix_detector::handle( SpikeEvent& e )
// 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_min_on = t_i_on;
- for ( int n = 0; n < P_.N_channels_; n++ )
+ for ( size_t n = 0; n < P_.N_channels_; n++ )
{
if ( S_.curr_state_[ n ] )
{
@@ -488,7 +490,7 @@ nest::correlospinmatrix_detector::handle( SpikeEvent& e )
}
void
-nest::correlospinmatrix_detector::calibrate_time( const TimeConverter& tc )
+correlospinmatrix_detector::calibrate_time( const TimeConverter& tc )
{
if ( P_.delta_tau_.is_step() )
{
@@ -508,3 +510,5 @@ nest::correlospinmatrix_detector::calibrate_time( const TimeConverter& tc )
S_.t_last_in_spike_ = tc.from_old_tics( S_.t_last_in_spike_.get_tics() );
}
+
+}
\ No newline at end of file
diff --git a/models/dc_generator.cpp b/models/dc_generator.cpp
index 7c5389914f..6e0365d756 100644
--- a/models/dc_generator.cpp
+++ b/models/dc_generator.cpp
@@ -52,24 +52,23 @@ RecordablesMap< dc_generator >::create()
{
insert_( Name( names::I ), &dc_generator::get_I_ );
}
-}
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::dc_generator::Parameters_::Parameters_()
+dc_generator::Parameters_::Parameters_()
: amp_( 0.0 ) // pA
{
}
-nest::dc_generator::Parameters_::Parameters_( const Parameters_& p )
+dc_generator::Parameters_::Parameters_( const Parameters_& p )
: amp_( p.amp_ )
{
}
-nest::dc_generator::Parameters_&
-nest::dc_generator::Parameters_::operator=( const Parameters_& p )
+dc_generator::Parameters_&
+dc_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -81,18 +80,18 @@ nest::dc_generator::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::dc_generator::State_::State_()
+dc_generator::State_::State_()
: I_( 0.0 ) // pA
{
}
-nest::dc_generator::Buffers_::Buffers_( dc_generator& n )
+dc_generator::Buffers_::Buffers_( dc_generator& n )
: logger_( n )
{
}
-nest::dc_generator::Buffers_::Buffers_( const Buffers_&, dc_generator& n )
+dc_generator::Buffers_::Buffers_( const Buffers_&, dc_generator& n )
: logger_( n )
{
}
@@ -102,13 +101,13 @@ nest::dc_generator::Buffers_::Buffers_( const Buffers_&, dc_generator& n )
* ---------------------------------------------------------------- */
void
-nest::dc_generator::Parameters_::get( DictionaryDatum& d ) const
+dc_generator::Parameters_::get( DictionaryDatum& d ) const
{
def< double >( d, names::amplitude, amp_ );
}
void
-nest::dc_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
+dc_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::amplitude, amp_, node );
}
@@ -118,7 +117,7 @@ nest::dc_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::dc_generator::dc_generator()
+dc_generator::dc_generator()
: StimulationDevice()
, P_()
, S_()
@@ -127,7 +126,7 @@ nest::dc_generator::dc_generator()
recordablesMap_.create();
}
-nest::dc_generator::dc_generator( const dc_generator& n )
+dc_generator::dc_generator( const dc_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -140,20 +139,20 @@ nest::dc_generator::dc_generator( const dc_generator& n )
* Node initialization functions
* ---------------------------------------------------------------- */
void
-nest::dc_generator::init_state_()
+dc_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::dc_generator::init_buffers_()
+dc_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
}
void
-nest::dc_generator::pre_run_hook()
+dc_generator::pre_run_hook()
{
B_.logger_.init();
@@ -166,7 +165,7 @@ nest::dc_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::dc_generator::update( Time const& origin, const long from, const long to )
+dc_generator::update( Time const& origin, const long from, const long to )
{
long start = origin.get_steps();
@@ -185,13 +184,13 @@ nest::dc_generator::update( Time const& origin, const long from, const long to )
}
void
-nest::dc_generator::handle( DataLoggingRequest& e )
+dc_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
void
-nest::dc_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+dc_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -210,3 +209,5 @@ nest::dc_generator::set_data_from_stimulation_backend( std::vector< double >& in
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/diffusion_connection.h b/models/diffusion_connection.h
index d7b250853a..75987d86de 100644
--- a/models/diffusion_connection.h
+++ b/models/diffusion_connection.h
@@ -92,12 +92,12 @@ EndUserDocs */
void register_diffusion_connection( const std::string& name );
template < typename targetidentifierT >
-class diffusion_connection : public Connection< targetidentifierT >
+class diffusion_connection : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::SUPPORTS_WFR;
@@ -125,14 +125,14 @@ class diffusion_connection : public Connection< targetidentifierT >
using ConnectionBase::get_target;
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
DiffusionConnectionEvent ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
/**
@@ -165,7 +165,13 @@ class diffusion_connection : public Connection< targetidentifierT >
}
void
- set_delay( double )
+ set_delay_ms( double )
+ {
+ throw BadProperty( "diffusion_connection has no delay." );
+ }
+
+ void
+ set_delay_steps( long )
{
throw BadProperty( "diffusion_connection has no delay." );
}
diff --git a/models/eprop_learning_signal_connection.h b/models/eprop_learning_signal_connection.h
index cc013a028b..af7c17d154 100644
--- a/models/eprop_learning_signal_connection.h
+++ b/models/eprop_learning_signal_connection.h
@@ -130,7 +130,7 @@ void register_eprop_learning_signal_connection( const std::string& name );
* Korcsak-Gorzo, Stapmanns, and Espinoza Valverde et al. (in preparation).
*/
template < typename targetidentifierT >
-class eprop_learning_signal_connection : public Connection< targetidentifierT >
+class eprop_learning_signal_connection : public Connection< targetidentifierT, TotalDelay >
{
public:
@@ -138,7 +138,7 @@ class eprop_learning_signal_connection : public Connection< targetidentifierT >
typedef CommonSynapseProperties CommonPropertiesType;
//! Type of the connection base.
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
//! Properties of the connection model.
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY;
@@ -159,14 +159,14 @@ class eprop_learning_signal_connection : public Connection< targetidentifierT >
//! Check if the target accepts the event and receptor type requested by the sender.
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex, const CommonPropertiesType& )
{
LearningSignalConnectionEvent ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
//! Send the learning signal event.
diff --git a/models/eprop_learning_signal_connection_bsshslm_2020.h b/models/eprop_learning_signal_connection_bsshslm_2020.h
index 5a6f5d5e5d..479ae47c89 100644
--- a/models/eprop_learning_signal_connection_bsshslm_2020.h
+++ b/models/eprop_learning_signal_connection_bsshslm_2020.h
@@ -133,7 +133,7 @@ void register_eprop_learning_signal_connection_bsshslm_2020( const std::string&
* according to Bellec et al. (2020).
*/
template < typename targetidentifierT >
-class eprop_learning_signal_connection_bsshslm_2020 : public Connection< targetidentifierT >
+class eprop_learning_signal_connection_bsshslm_2020 : public Connection< targetidentifierT, TotalDelay >
{
public:
@@ -141,7 +141,7 @@ class eprop_learning_signal_connection_bsshslm_2020 : public Connection< targeti
typedef CommonSynapseProperties CommonPropertiesType;
//! Type of the connection base.
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
//! Properties of the connection model.
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY;
@@ -162,14 +162,14 @@ class eprop_learning_signal_connection_bsshslm_2020 : public Connection< targeti
//! Check if the target accepts the event and receptor type requested by the sender.
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex, const CommonPropertiesType& )
{
LearningSignalConnectionEvent ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
//! Send the learning signal event.
diff --git a/models/eprop_synapse.h b/models/eprop_synapse.h
index 9b4a5679c2..cd1ca076d9 100644
--- a/models/eprop_synapse.h
+++ b/models/eprop_synapse.h
@@ -223,7 +223,7 @@ void register_eprop_synapse( const std::string& name );
* and default values could be set on it.
*/
template < typename targetidentifierT >
-class eprop_synapse : public Connection< targetidentifierT >
+class eprop_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
@@ -231,7 +231,7 @@ class eprop_synapse : public Connection< targetidentifierT >
typedef EpropSynapseCommonProperties CommonPropertiesType;
//! Type of the connection base.
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
/**
* Properties of the connection model.
@@ -260,7 +260,7 @@ class eprop_synapse : public Connection< targetidentifierT >
//! Move assignment operator
eprop_synapse& operator=( eprop_synapse&& );
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -298,7 +298,11 @@ class eprop_synapse : public Connection< targetidentifierT >
*
* @note This sets the optimizer_ member.
*/
- void check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& cp );
+ void check_connection( Node& s,
+ Node& t,
+ const size_t receptor_type,
+ const synindex syn_id,
+ const CommonPropertiesType& cp );
//! Set the synaptic weight to the provided value.
void
@@ -460,6 +464,7 @@ inline void
eprop_synapse< targetidentifierT >::check_connection( Node& s,
Node& t,
size_t receptor_type,
+ const synindex syn_id,
const CommonPropertiesType& cp )
{
// When we get here, delay has been set so we can check it.
@@ -469,7 +474,7 @@ eprop_synapse< targetidentifierT >::check_connection( Node& s,
}
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
t.register_eprop_connection();
diff --git a/models/eprop_synapse_bsshslm_2020.h b/models/eprop_synapse_bsshslm_2020.h
index 3ac9144827..8b4313083b 100644
--- a/models/eprop_synapse_bsshslm_2020.h
+++ b/models/eprop_synapse_bsshslm_2020.h
@@ -240,7 +240,7 @@ void register_eprop_synapse_bsshslm_2020( const std::string& name );
* and default values could be set on it.
*/
template < typename targetidentifierT >
-class eprop_synapse_bsshslm_2020 : public Connection< targetidentifierT >
+class eprop_synapse_bsshslm_2020 : public Connection< targetidentifierT, TotalDelay >
{
public:
@@ -248,7 +248,7 @@ class eprop_synapse_bsshslm_2020 : public Connection< targetidentifierT >
typedef EpropSynapseBSSHSLM2020CommonProperties CommonPropertiesType;
//! Type of the connection base.
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
/**
* Properties of the connection model.
@@ -277,7 +277,7 @@ class eprop_synapse_bsshslm_2020 : public Connection< targetidentifierT >
//! Move assignment operator
eprop_synapse_bsshslm_2020& operator=( eprop_synapse_bsshslm_2020&& );
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -315,7 +315,11 @@ class eprop_synapse_bsshslm_2020 : public Connection< targetidentifierT >
*
* @note This sets the optimizer_ member.
*/
- void check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& cp );
+ void check_connection( Node& s,
+ Node& t,
+ const size_t receptor_type,
+ const synindex syn_id,
+ const CommonPropertiesType& cp );
//! Set the synaptic weight to the provided value.
void
@@ -490,6 +494,7 @@ inline void
eprop_synapse_bsshslm_2020< targetidentifierT >::check_connection( Node& s,
Node& t,
size_t receptor_type,
+ const synindex syn_id,
const CommonPropertiesType& cp )
{
// When we get here, delay has been set so we can check it.
@@ -499,7 +504,7 @@ eprop_synapse_bsshslm_2020< targetidentifierT >::check_connection( Node& s,
}
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
t.register_eprop_connection();
@@ -614,8 +619,7 @@ eprop_synapse_bsshslm_2020< targetidentifierT >::set_status( const DictionaryDat
kappa_ = std::exp( -Time::get_resolution().get_ms() / tau_m_readout_ );
}
- const auto& gcm =
- dynamic_cast< const GenericConnectorModel< eprop_synapse_bsshslm_2020< targetidentifierT > >& >( cm );
+ const auto& gcm = dynamic_cast< const GenericConnectorModel< eprop_synapse_bsshslm_2020 >& >( cm );
const CommonPropertiesType& epcp = gcm.get_common_properties();
if ( weight_ < epcp.optimizer_cp_->get_Wmin() )
{
diff --git a/models/gamma_sup_generator.cpp b/models/gamma_sup_generator.cpp
index 5817c36f7f..e99acfbe0a 100644
--- a/models/gamma_sup_generator.cpp
+++ b/models/gamma_sup_generator.cpp
@@ -45,11 +45,14 @@ nest::register_gamma_sup_generator( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Constructor of internal states class
* ---------------------------------------------------------------- */
-nest::gamma_sup_generator::Internal_states_::Internal_states_( size_t num_bins,
+gamma_sup_generator::Internal_states_::Internal_states_( size_t num_bins,
unsigned long ini_occ_ref,
unsigned long ini_occ_act )
{
@@ -62,7 +65,7 @@ nest::gamma_sup_generator::Internal_states_::Internal_states_( size_t num_bins,
* ---------------------------------------------------------------- */
unsigned long
-nest::gamma_sup_generator::Internal_states_::update( double transition_prob, RngPtr rng )
+gamma_sup_generator::Internal_states_::update( double transition_prob, RngPtr rng )
{
std::vector< unsigned long > n_trans; // only set from poisson_dist_, bino_dist_ or 0, thus >= 0
n_trans.resize( occ_.size() );
@@ -127,7 +130,7 @@ nest::gamma_sup_generator::Internal_states_::update( double transition_prob, Rng
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::gamma_sup_generator::Parameters_::Parameters_()
+gamma_sup_generator::Parameters_::Parameters_()
: rate_( 0.0 ) // Hz
, gamma_shape_( 1 )
, n_proc_( 1 )
@@ -140,7 +143,7 @@ nest::gamma_sup_generator::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::gamma_sup_generator::Parameters_::get( DictionaryDatum& d ) const
+gamma_sup_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::rate ] = rate_;
( *d )[ names::gamma_shape ] = gamma_shape_;
@@ -148,7 +151,7 @@ nest::gamma_sup_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::gamma_sup_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
+gamma_sup_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< long >( d, names::gamma_shape, gamma_shape_, node );
if ( gamma_shape_ < 1 )
@@ -179,13 +182,13 @@ nest::gamma_sup_generator::Parameters_::set( const DictionaryDatum& d, Node* nod
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::gamma_sup_generator::gamma_sup_generator()
+gamma_sup_generator::gamma_sup_generator()
: StimulationDevice()
, P_()
{
}
-nest::gamma_sup_generator::gamma_sup_generator( const gamma_sup_generator& n )
+gamma_sup_generator::gamma_sup_generator( const gamma_sup_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
{
@@ -197,19 +200,19 @@ nest::gamma_sup_generator::gamma_sup_generator( const gamma_sup_generator& n )
* ---------------------------------------------------------------- */
void
-nest::gamma_sup_generator::init_state_()
+gamma_sup_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::gamma_sup_generator::init_buffers_()
+gamma_sup_generator::init_buffers_()
{
StimulationDevice::init_buffers();
}
void
-nest::gamma_sup_generator::pre_run_hook()
+gamma_sup_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
@@ -234,7 +237,7 @@ nest::gamma_sup_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::gamma_sup_generator::update( Time const& T, const long from, const long to )
+gamma_sup_generator::update( Time const& T, const long from, const long to )
{
if ( P_.rate_ <= 0 or P_.num_targets_ == 0 )
{
@@ -257,7 +260,7 @@ nest::gamma_sup_generator::update( Time const& T, const long from, const long to
void
-nest::gamma_sup_generator::event_hook( DSSpikeEvent& e )
+gamma_sup_generator::event_hook( DSSpikeEvent& e )
{
// get port number
const size_t prt = e.get_port();
@@ -281,7 +284,7 @@ nest::gamma_sup_generator::event_hook( DSSpikeEvent& e )
* ---------------------------------------------------------------- */
void
-nest::gamma_sup_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+gamma_sup_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -303,3 +306,5 @@ nest::gamma_sup_generator::set_data_from_stimulation_backend( std::vector< doubl
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/gap_junction.h b/models/gap_junction.h
index dd25df9776..cdec0490f0 100644
--- a/models/gap_junction.h
+++ b/models/gap_junction.h
@@ -84,13 +84,13 @@ EndUserDocs */
void register_gap_junction( const std::string& name );
template < typename targetidentifierT >
-class gap_junction : public Connection< targetidentifierT >
+class gap_junction : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties =
ConnectionModelProperties::REQUIRES_SYMMETRIC | ConnectionModelProperties::SUPPORTS_WFR;
@@ -116,14 +116,14 @@ class gap_junction : public Connection< targetidentifierT >
using ConnectionBase::get_target;
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
GapJunctionEvent ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
/**
@@ -152,7 +152,13 @@ class gap_junction : public Connection< targetidentifierT >
}
void
- set_delay( double )
+ set_delay_ms( double )
+ {
+ throw BadProperty( "gap_junction connection has no delay" );
+ }
+
+ void
+ set_delay_steps( long )
{
throw BadProperty( "gap_junction connection has no delay" );
}
@@ -168,9 +174,7 @@ template < typename targetidentifierT >
void
gap_junction< targetidentifierT >::get_status( DictionaryDatum& d ) const
{
- // We have to include the delay here to prevent
- // errors due to internal calls of
- // this function in SLI/pyNEST
+ // We have to include the delay here to prevent errors due to internal calls of this function in SLI/pyNEST
ConnectionBase::get_status( d );
def< double >( d, names::weight, weight_ );
def< long >( d, names::size_of, sizeof( *this ) );
@@ -188,7 +192,7 @@ void
gap_junction< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm )
{
// If the delay is set, we throw a BadProperty
- if ( d->known( names::delay ) )
+ if ( d->known( names::delay ) or d->known( names::dendritic_delay ) or d->known( names::axonal_delay ) )
{
throw BadProperty( "gap_junction connection has no delay" );
}
diff --git a/models/gif_cond_exp.cpp b/models/gif_cond_exp.cpp
index 43e7d96d19..fffe6eb9df 100644
--- a/models/gif_cond_exp.cpp
+++ b/models/gif_cond_exp.cpp
@@ -447,6 +447,8 @@ nest::gif_cond_exp::init_buffers_()
void
nest::gif_cond_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms();
diff --git a/models/gif_cond_exp_multisynapse.cpp b/models/gif_cond_exp_multisynapse.cpp
index 5a31ba490f..2988f4545b 100644
--- a/models/gif_cond_exp_multisynapse.cpp
+++ b/models/gif_cond_exp_multisynapse.cpp
@@ -451,6 +451,8 @@ nest::gif_cond_exp_multisynapse::init_buffers_()
void
nest::gif_cond_exp_multisynapse::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.sys_.dimension = S_.y_.size();
B_.logger_.init();
diff --git a/models/gif_psc_exp.cpp b/models/gif_psc_exp.cpp
index 0731dc8175..d7485c7e1a 100644
--- a/models/gif_psc_exp.cpp
+++ b/models/gif_psc_exp.cpp
@@ -282,6 +282,8 @@ nest::gif_psc_exp::init_buffers_()
void
nest::gif_psc_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms();
diff --git a/models/gif_psc_exp_multisynapse.cpp b/models/gif_psc_exp_multisynapse.cpp
index cfeca96ea4..ed2fb62550 100644
--- a/models/gif_psc_exp_multisynapse.cpp
+++ b/models/gif_psc_exp_multisynapse.cpp
@@ -297,6 +297,8 @@ nest::gif_psc_exp_multisynapse::init_buffers_()
void
nest::gif_psc_exp_multisynapse::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms();
diff --git a/models/glif_cond.cpp b/models/glif_cond.cpp
index a1434786b9..45a43acaa8 100644
--- a/models/glif_cond.cpp
+++ b/models/glif_cond.cpp
@@ -557,6 +557,8 @@ nest::glif_cond::init_buffers_()
void
nest::glif_cond::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms(); // in ms
diff --git a/models/glif_psc.cpp b/models/glif_psc.cpp
index b60dafc0ec..382947ddee 100644
--- a/models/glif_psc.cpp
+++ b/models/glif_psc.cpp
@@ -397,6 +397,8 @@ nest::glif_psc::init_buffers_()
void
nest::glif_psc::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms(); // in ms
diff --git a/models/glif_psc_double_alpha.cpp b/models/glif_psc_double_alpha.cpp
index f79de012d3..9f3863e4cd 100644
--- a/models/glif_psc_double_alpha.cpp
+++ b/models/glif_psc_double_alpha.cpp
@@ -432,6 +432,8 @@ nest::glif_psc_double_alpha::init_buffers_()
void
nest::glif_psc_double_alpha::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms(); // in ms
diff --git a/models/hh_cond_beta_gap_traub.cpp b/models/hh_cond_beta_gap_traub.cpp
index 7907b051c8..7fc53f4ac6 100644
--- a/models/hh_cond_beta_gap_traub.cpp
+++ b/models/hh_cond_beta_gap_traub.cpp
@@ -454,6 +454,8 @@ nest::hh_cond_beta_gap_traub::get_normalisation_factor( double tau_rise, double
void
nest::hh_cond_beta_gap_traub::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/hh_cond_exp_traub.cpp b/models/hh_cond_exp_traub.cpp
index 5aa908a15d..3507c089e0 100644
--- a/models/hh_cond_exp_traub.cpp
+++ b/models/hh_cond_exp_traub.cpp
@@ -375,6 +375,8 @@ nest::hh_cond_exp_traub::init_buffers_()
void
nest::hh_cond_exp_traub::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
V_.refractory_counts_ = Time( Time::ms( P_.t_ref_ ) ).get_steps();
diff --git a/models/hh_psc_alpha.cpp b/models/hh_psc_alpha.cpp
index 29e953b810..5e4e8d02cf 100644
--- a/models/hh_psc_alpha.cpp
+++ b/models/hh_psc_alpha.cpp
@@ -373,6 +373,8 @@ nest::hh_psc_alpha::init_buffers_()
void
nest::hh_psc_alpha::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/hh_psc_alpha_clopath.cpp b/models/hh_psc_alpha_clopath.cpp
index e0c35e830f..906dfcf71b 100644
--- a/models/hh_psc_alpha_clopath.cpp
+++ b/models/hh_psc_alpha_clopath.cpp
@@ -401,6 +401,8 @@ nest::hh_psc_alpha_clopath::init_buffers_()
void
nest::hh_psc_alpha_clopath::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/hh_psc_alpha_gap.cpp b/models/hh_psc_alpha_gap.cpp
index b26176784f..9f4aa14e85 100644
--- a/models/hh_psc_alpha_gap.cpp
+++ b/models/hh_psc_alpha_gap.cpp
@@ -439,6 +439,8 @@ nest::hh_psc_alpha_gap::init_buffers_()
void
nest::hh_psc_alpha_gap::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/ht_neuron.cpp b/models/ht_neuron.cpp
index 047ca61fa3..11aab65c90 100644
--- a/models/ht_neuron.cpp
+++ b/models/ht_neuron.cpp
@@ -714,6 +714,8 @@ nest::ht_neuron::get_synapse_constant( double tau_1, double tau_2, double g_peak
void
nest::ht_neuron::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/ht_synapse.h b/models/ht_synapse.h
index 1221e89116..004f1d89df 100644
--- a/models/ht_synapse.h
+++ b/models/ht_synapse.h
@@ -100,11 +100,11 @@ EndUserDocs */
void register_ht_synapse( const std::string& name );
template < typename targetidentifierT >
-class ht_synapse : public Connection< targetidentifierT >
+class ht_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -126,7 +126,7 @@ class ht_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -169,10 +169,10 @@ class ht_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
//! allows efficient initialization from ConnectorModel::add_connection()
diff --git a/models/iaf_bw_2001_exact.cpp b/models/iaf_bw_2001_exact.cpp
index 3855c27a53..59f35aaddd 100644
--- a/models/iaf_bw_2001_exact.cpp
+++ b/models/iaf_bw_2001_exact.cpp
@@ -529,7 +529,7 @@ void
nest::iaf_bw_2001_exact::handle( SpikeEvent& e )
{
assert( e.get_delay_steps() > 0 );
- assert( e.get_rport() <= static_cast< int >( B_.spikes_.size() ) );
+ assert( e.get_rport() <= B_.spikes_.size() );
const double steps = e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() );
const auto rport = e.get_rport();
diff --git a/models/iaf_chs_2007.cpp b/models/iaf_chs_2007.cpp
index b5c183d7b0..50a4a86d1c 100644
--- a/models/iaf_chs_2007.cpp
+++ b/models/iaf_chs_2007.cpp
@@ -198,6 +198,8 @@ nest::iaf_chs_2007::init_buffers_()
void
nest::iaf_chs_2007::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_chxk_2008.cpp b/models/iaf_chxk_2008.cpp
index 62559536ae..7ef64dcf3f 100644
--- a/models/iaf_chxk_2008.cpp
+++ b/models/iaf_chxk_2008.cpp
@@ -344,6 +344,8 @@ nest::iaf_chxk_2008::init_buffers_()
void
nest::iaf_chxk_2008::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_cond_alpha.cpp b/models/iaf_cond_alpha.cpp
index 7cbff968ee..e53a267a5c 100644
--- a/models/iaf_cond_alpha.cpp
+++ b/models/iaf_cond_alpha.cpp
@@ -358,6 +358,8 @@ nest::iaf_cond_alpha::init_buffers_()
void
nest::iaf_cond_alpha::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_cond_alpha_mc.cpp b/models/iaf_cond_alpha_mc.cpp
index 2b99b81025..7fa72fcb3f 100644
--- a/models/iaf_cond_alpha_mc.cpp
+++ b/models/iaf_cond_alpha_mc.cpp
@@ -558,6 +558,8 @@ nest::iaf_cond_alpha_mc::init_buffers_()
void
nest::iaf_cond_alpha_mc::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_cond_beta.cpp b/models/iaf_cond_beta.cpp
index a0f5d59c2e..c683b4f833 100644
--- a/models/iaf_cond_beta.cpp
+++ b/models/iaf_cond_beta.cpp
@@ -371,6 +371,8 @@ nest::iaf_cond_beta::get_normalisation_factor( double tau_rise, double tau_decay
void
nest::iaf_cond_beta::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_cond_exp.cpp b/models/iaf_cond_exp.cpp
index c777d686fd..6d6f41a3cc 100644
--- a/models/iaf_cond_exp.cpp
+++ b/models/iaf_cond_exp.cpp
@@ -336,6 +336,8 @@ nest::iaf_cond_exp::init_buffers_()
void
nest::iaf_cond_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_cond_exp_sfa_rr.cpp b/models/iaf_cond_exp_sfa_rr.cpp
index d37b461e06..b7a26a78c3 100644
--- a/models/iaf_cond_exp_sfa_rr.cpp
+++ b/models/iaf_cond_exp_sfa_rr.cpp
@@ -372,6 +372,8 @@ nest::iaf_cond_exp_sfa_rr::init_buffers_()
void
nest::iaf_cond_exp_sfa_rr::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_psc_alpha.cpp b/models/iaf_psc_alpha.cpp
index 053a30a22c..79714dfb1f 100644
--- a/models/iaf_psc_alpha.cpp
+++ b/models/iaf_psc_alpha.cpp
@@ -249,6 +249,8 @@ iaf_psc_alpha::init_buffers_()
void
iaf_psc_alpha::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
@@ -369,6 +371,7 @@ iaf_psc_alpha::update( Time const& origin, const long from, const long to )
// log state data
B_.logger_.record_data( origin.get_steps() + lag );
}
+ reset_correction_entries_stdp_ax_delay_();
}
void
@@ -385,6 +388,20 @@ iaf_psc_alpha::handle( SpikeEvent& e )
B_.input_buffer_.add_value( input_buffer_slot, s > 0 ? Buffers_::SYN_EX : Buffers_::SYN_IN, s );
}
+void
+iaf_psc_alpha::handle( CorrectionSpikeEvent& e )
+{
+ assert( e.get_delay_steps() > 0 );
+
+ const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo(
+ e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) );
+
+ const double s = ( e.get_new_weight() - e.get_weight() ) * e.get_multiplicity();
+
+ // separate buffer channels for excitatory and inhibitory inputs
+ B_.input_buffer_.add_value( input_buffer_slot, e.get_weight() > 0 ? Buffers_::SYN_EX : Buffers_::SYN_IN, s );
+}
+
void
iaf_psc_alpha::handle( CurrentEvent& e )
{
diff --git a/models/iaf_psc_alpha.h b/models/iaf_psc_alpha.h
index 21d4ff904c..d2b6a62296 100644
--- a/models/iaf_psc_alpha.h
+++ b/models/iaf_psc_alpha.h
@@ -228,10 +228,12 @@ class iaf_psc_alpha : public ArchivingNode
size_t send_test_event( Node&, size_t, synindex, bool ) override;
void handle( SpikeEvent& ) override;
+ void handle( CorrectionSpikeEvent& ) override;
void handle( CurrentEvent& ) override;
void handle( DataLoggingRequest& ) override;
size_t handles_test_event( SpikeEvent&, size_t ) override;
+ size_t handles_test_event( CorrectionSpikeEvent&, size_t ) override;
size_t handles_test_event( CurrentEvent&, size_t ) override;
size_t handles_test_event( DataLoggingRequest&, size_t ) override;
@@ -432,6 +434,16 @@ iaf_psc_alpha::handles_test_event( SpikeEvent&, size_t receptor_type )
return 0;
}
+inline size_t
+iaf_psc_alpha::handles_test_event( CorrectionSpikeEvent&, size_t receptor_type )
+{
+ if ( receptor_type != 0 )
+ {
+ throw UnknownReceptorType( receptor_type, get_name() );
+ }
+ return 0;
+}
+
inline size_t
iaf_psc_alpha::handles_test_event( CurrentEvent&, size_t receptor_type )
{
diff --git a/models/iaf_psc_alpha_multisynapse.cpp b/models/iaf_psc_alpha_multisynapse.cpp
index cee69d2889..916ccc8cfa 100644
--- a/models/iaf_psc_alpha_multisynapse.cpp
+++ b/models/iaf_psc_alpha_multisynapse.cpp
@@ -290,6 +290,8 @@ iaf_psc_alpha_multisynapse::init_buffers_()
void
iaf_psc_alpha_multisynapse::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_psc_alpha_ps.cpp b/models/iaf_psc_alpha_ps.cpp
index 885d1f2051..14899339b1 100644
--- a/models/iaf_psc_alpha_ps.cpp
+++ b/models/iaf_psc_alpha_ps.cpp
@@ -264,6 +264,8 @@ nest::iaf_psc_alpha_ps::init_buffers_()
void
nest::iaf_psc_alpha_ps::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
V_.h_ms_ = Time::get_resolution().get_ms();
diff --git a/models/iaf_psc_delta.cpp b/models/iaf_psc_delta.cpp
index 4de329ed60..64c193159e 100644
--- a/models/iaf_psc_delta.cpp
+++ b/models/iaf_psc_delta.cpp
@@ -236,6 +236,8 @@ nest::iaf_psc_delta::init_buffers_()
void
nest::iaf_psc_delta::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms();
diff --git a/models/iaf_psc_delta_ps.cpp b/models/iaf_psc_delta_ps.cpp
index 1da42f3dcc..61a612caea 100644
--- a/models/iaf_psc_delta_ps.cpp
+++ b/models/iaf_psc_delta_ps.cpp
@@ -245,6 +245,8 @@ nest::iaf_psc_delta_ps::init_buffers_()
void
iaf_psc_delta_ps::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
V_.h_ms_ = Time::get_resolution().get_ms();
diff --git a/models/iaf_psc_exp.cpp b/models/iaf_psc_exp.cpp
index 48385040db..a55d68b469 100644
--- a/models/iaf_psc_exp.cpp
+++ b/models/iaf_psc_exp.cpp
@@ -246,6 +246,8 @@ nest::iaf_psc_exp::init_buffers_()
void
nest::iaf_psc_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_psc_exp_htum.cpp b/models/iaf_psc_exp_htum.cpp
index dd38c565cd..ee4bd1521b 100644
--- a/models/iaf_psc_exp_htum.cpp
+++ b/models/iaf_psc_exp_htum.cpp
@@ -232,6 +232,8 @@ nest::iaf_psc_exp_htum::init_buffers_()
void
nest::iaf_psc_exp_htum::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
const double h = Time::get_resolution().get_ms();
diff --git a/models/iaf_psc_exp_multisynapse.cpp b/models/iaf_psc_exp_multisynapse.cpp
index 7c53921537..282ca50d6a 100644
--- a/models/iaf_psc_exp_multisynapse.cpp
+++ b/models/iaf_psc_exp_multisynapse.cpp
@@ -274,6 +274,8 @@ iaf_psc_exp_multisynapse::init_buffers_()
void
nest::iaf_psc_exp_multisynapse::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_psc_exp_ps.cpp b/models/iaf_psc_exp_ps.cpp
index 71f83acc78..275d860108 100644
--- a/models/iaf_psc_exp_ps.cpp
+++ b/models/iaf_psc_exp_ps.cpp
@@ -253,6 +253,8 @@ nest::iaf_psc_exp_ps::init_buffers_()
void
nest::iaf_psc_exp_ps::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/iaf_psc_exp_ps_lossless.cpp b/models/iaf_psc_exp_ps_lossless.cpp
index dcbf6435bf..a0ea8284d1 100644
--- a/models/iaf_psc_exp_ps_lossless.cpp
+++ b/models/iaf_psc_exp_ps_lossless.cpp
@@ -278,6 +278,8 @@ nest::iaf_psc_exp_ps_lossless::init_buffers_()
void
nest::iaf_psc_exp_ps_lossless::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/inhomogeneous_poisson_generator.cpp b/models/inhomogeneous_poisson_generator.cpp
index 8f0b5f58ba..3e503f2052 100644
--- a/models/inhomogeneous_poisson_generator.cpp
+++ b/models/inhomogeneous_poisson_generator.cpp
@@ -48,11 +48,14 @@ nest::register_inhomogeneous_poisson_generator( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::inhomogeneous_poisson_generator::Parameters_::Parameters_()
+inhomogeneous_poisson_generator::Parameters_::Parameters_()
: rate_times_() // ms
, rate_values_() // spikes/ms,
, allow_offgrid_times_( false )
@@ -65,7 +68,7 @@ nest::inhomogeneous_poisson_generator::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::inhomogeneous_poisson_generator::Parameters_::get( DictionaryDatum& d ) const
+inhomogeneous_poisson_generator::Parameters_::get( DictionaryDatum& d ) const
{
const size_t n_rates = rate_times_.size();
std::vector< double >* times_ms = new std::vector< double >();
@@ -81,7 +84,7 @@ nest::inhomogeneous_poisson_generator::Parameters_::get( DictionaryDatum& d ) co
}
void
-nest::inhomogeneous_poisson_generator::Parameters_::assert_valid_rate_time_and_insert( const double t )
+inhomogeneous_poisson_generator::Parameters_::assert_valid_rate_time_and_insert( const double t )
{
Time t_rate;
@@ -117,7 +120,7 @@ nest::inhomogeneous_poisson_generator::Parameters_::assert_valid_rate_time_and_i
}
void
-nest::inhomogeneous_poisson_generator::Parameters_::set( const DictionaryDatum& d, Buffers_& b, Node* )
+inhomogeneous_poisson_generator::Parameters_::set( const DictionaryDatum& d, Buffers_& b, Node* )
{
const bool times = d->known( names::rate_times );
const bool rates = updateValue< std::vector< double > >( d, names::rate_values, rate_values_ );
@@ -196,7 +199,7 @@ nest::inhomogeneous_poisson_generator::Parameters_::set( const DictionaryDatum&
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::inhomogeneous_poisson_generator::inhomogeneous_poisson_generator()
+inhomogeneous_poisson_generator::inhomogeneous_poisson_generator()
: StimulationDevice()
, P_()
, B_()
@@ -204,7 +207,7 @@ nest::inhomogeneous_poisson_generator::inhomogeneous_poisson_generator()
{
}
-nest::inhomogeneous_poisson_generator::inhomogeneous_poisson_generator( const inhomogeneous_poisson_generator& n )
+inhomogeneous_poisson_generator::inhomogeneous_poisson_generator( const inhomogeneous_poisson_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, B_( n.B_ )
@@ -216,13 +219,13 @@ nest::inhomogeneous_poisson_generator::inhomogeneous_poisson_generator( const in
* Node initialization functions
* ---------------------------------------------------------------- */
void
-nest::inhomogeneous_poisson_generator::init_state_()
+inhomogeneous_poisson_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::inhomogeneous_poisson_generator::init_buffers_()
+inhomogeneous_poisson_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.idx_ = 0;
@@ -230,7 +233,7 @@ nest::inhomogeneous_poisson_generator::init_buffers_()
}
void
-nest::inhomogeneous_poisson_generator::pre_run_hook()
+inhomogeneous_poisson_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
V_.h_ = Time::get_resolution().get_ms();
@@ -241,7 +244,7 @@ nest::inhomogeneous_poisson_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::inhomogeneous_poisson_generator::update( Time const& origin, const long from, const long to )
+inhomogeneous_poisson_generator::update( Time const& origin, const long from, const long to )
{
assert( P_.rate_times_.size() == P_.rate_values_.size() );
@@ -278,7 +281,7 @@ nest::inhomogeneous_poisson_generator::update( Time const& origin, const long fr
}
void
-nest::inhomogeneous_poisson_generator::event_hook( DSSpikeEvent& e )
+inhomogeneous_poisson_generator::event_hook( DSSpikeEvent& e )
{
poisson_distribution::param_type param( B_.rate_ * V_.h_ );
long n_spikes = V_.poisson_dist_( get_vp_specific_rng( get_thread() ), param );
@@ -295,7 +298,7 @@ nest::inhomogeneous_poisson_generator::event_hook( DSSpikeEvent& e )
* ---------------------------------------------------------------- */
void
-nest::inhomogeneous_poisson_generator::set_data_from_stimulation_backend( std::vector< double >& rate_time_update )
+inhomogeneous_poisson_generator::set_data_from_stimulation_backend( std::vector< double >& rate_time_update )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
// For the input backend
@@ -329,3 +332,5 @@ nest::inhomogeneous_poisson_generator::set_data_from_stimulation_backend( std::v
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/izhikevich.cpp b/models/izhikevich.cpp
index 9865f74427..c98e497614 100644
--- a/models/izhikevich.cpp
+++ b/models/izhikevich.cpp
@@ -184,6 +184,8 @@ nest::izhikevich::init_buffers_()
void
nest::izhikevich::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
}
diff --git a/models/jonke_synapse.h b/models/jonke_synapse.h
index e8bb578566..2def725129 100644
--- a/models/jonke_synapse.h
+++ b/models/jonke_synapse.h
@@ -165,12 +165,12 @@ class JonkeCommonProperties : public CommonSynapseProperties
void register_jonke_synapse( const std::string& name );
template < typename targetidentifierT >
-class jonke_synapse : public Connection< targetidentifierT >
+class jonke_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef JonkeCommonProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -194,7 +194,7 @@ class jonke_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -231,13 +231,13 @@ class jonke_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -306,7 +306,7 @@ jonke_synapse< targetidentifierT >::send( Event& e, size_t t, const JonkeCommonP
// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/mat2_psc_exp.cpp b/models/mat2_psc_exp.cpp
index 104d20af0f..441144acdc 100644
--- a/models/mat2_psc_exp.cpp
+++ b/models/mat2_psc_exp.cpp
@@ -243,6 +243,8 @@ nest::mat2_psc_exp::init_buffers_()
void
nest::mat2_psc_exp::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
diff --git a/models/mip_generator.cpp b/models/mip_generator.cpp
index bf60516e97..9d6790e053 100644
--- a/models/mip_generator.cpp
+++ b/models/mip_generator.cpp
@@ -39,11 +39,14 @@ nest::register_mip_generator( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::mip_generator::Parameters_::Parameters_()
+mip_generator::Parameters_::Parameters_()
: rate_( 0.0 ) // spks/s
, p_copy_( 1.0 )
{
@@ -54,14 +57,14 @@ nest::mip_generator::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::mip_generator::Parameters_::get( DictionaryDatum& d ) const
+mip_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::rate ] = rate_;
( *d )[ names::p_copy ] = p_copy_;
}
void
-nest::mip_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
+mip_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::rate, rate_, node );
updateValueParam< double >( d, names::p_copy, p_copy_, node );
@@ -81,13 +84,13 @@ nest::mip_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::mip_generator::mip_generator()
+mip_generator::mip_generator()
: StimulationDevice()
, P_()
{
}
-nest::mip_generator::mip_generator( const mip_generator& n )
+mip_generator::mip_generator( const mip_generator& n )
: StimulationDevice( n )
, P_( n.P_ ) // also causes deep copy of random nnumber generator
{
@@ -98,19 +101,19 @@ nest::mip_generator::mip_generator( const mip_generator& n )
* ---------------------------------------------------------------- */
void
-nest::mip_generator::init_state_()
+mip_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::mip_generator::init_buffers_()
+mip_generator::init_buffers_()
{
StimulationDevice::init_buffers();
}
void
-nest::mip_generator::pre_run_hook()
+mip_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
@@ -125,7 +128,7 @@ nest::mip_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::mip_generator::update( Time const& T, const long from, const long to )
+mip_generator::update( Time const& T, const long from, const long to )
{
for ( long lag = from; lag < to; ++lag )
{
@@ -148,7 +151,7 @@ nest::mip_generator::update( Time const& T, const long from, const long to )
}
void
-nest::mip_generator::event_hook( DSSpikeEvent& e )
+mip_generator::event_hook( DSSpikeEvent& e )
{
/*
We temporarily set the spike multiplicity here to the number of
@@ -186,7 +189,7 @@ nest::mip_generator::event_hook( DSSpikeEvent& e )
* Other functions
* ---------------------------------------------------------------- */
void
-nest::mip_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+mip_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -209,3 +212,5 @@ nest::mip_generator::set_data_from_stimulation_backend( std::vector< double >& i
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
diff --git a/models/noise_generator.cpp b/models/noise_generator.cpp
index 7bc72369da..804e4c62fe 100644
--- a/models/noise_generator.cpp
+++ b/models/noise_generator.cpp
@@ -55,13 +55,12 @@ RecordablesMap< noise_generator >::create()
{
insert_( Name( names::I ), &noise_generator::get_I_avg_ );
}
-}
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::noise_generator::Parameters_::Parameters_()
+noise_generator::Parameters_::Parameters_()
: mean_( 0.0 ) // pA
, std_( 0.0 ) // pA / sqrt(s)
, std_mod_( 0.0 ) // pA / sqrt(s)
@@ -72,7 +71,7 @@ nest::noise_generator::Parameters_::Parameters_()
{
}
-nest::noise_generator::Parameters_::Parameters_( const Parameters_& p )
+noise_generator::Parameters_::Parameters_( const Parameters_& p )
: mean_( p.mean_ )
, std_( p.std_ )
, std_mod_( p.std_mod_ )
@@ -91,8 +90,8 @@ nest::noise_generator::Parameters_::Parameters_( const Parameters_& p )
}
}
-nest::noise_generator::Parameters_&
-nest::noise_generator::Parameters_::operator=( const Parameters_& p )
+noise_generator::Parameters_&
+noise_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -109,20 +108,20 @@ nest::noise_generator::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::noise_generator::State_::State_()
+noise_generator::State_::State_()
: y_0_( 0.0 )
, y_1_( 0.0 ) // pA
, I_avg_( 0.0 ) // pA
{
}
-nest::noise_generator::Buffers_::Buffers_( noise_generator& n )
+noise_generator::Buffers_::Buffers_( noise_generator& n )
: next_step_( 0 )
, logger_( n )
{
}
-nest::noise_generator::Buffers_::Buffers_( const Buffers_& b, noise_generator& n )
+noise_generator::Buffers_::Buffers_( const Buffers_& b, noise_generator& n )
: next_step_( b.next_step_ )
, logger_( n )
{
@@ -133,7 +132,7 @@ nest::noise_generator::Buffers_::Buffers_( const Buffers_& b, noise_generator& n
* ---------------------------------------------------------------- */
void
-nest::noise_generator::Parameters_::get( DictionaryDatum& d ) const
+noise_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::mean ] = mean_;
( *d )[ names::std ] = std_;
@@ -144,14 +143,14 @@ nest::noise_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::noise_generator::State_::get( DictionaryDatum& d ) const
+noise_generator::State_::get( DictionaryDatum& d ) const
{
( *d )[ names::y_0 ] = y_0_;
( *d )[ names::y_1 ] = y_1_;
}
void
-nest::noise_generator::Parameters_::set( const DictionaryDatum& d, const noise_generator& n, Node* node )
+noise_generator::Parameters_::set( const DictionaryDatum& d, const noise_generator& n, Node* node )
{
updateValueParam< double >( d, names::mean, mean_, node );
updateValueParam< double >( d, names::std, std_, node );
@@ -189,7 +188,7 @@ nest::noise_generator::Parameters_::set( const DictionaryDatum& d, const noise_g
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::noise_generator::noise_generator()
+noise_generator::noise_generator()
: StimulationDevice()
, P_()
, S_()
@@ -198,7 +197,7 @@ nest::noise_generator::noise_generator()
recordablesMap_.create();
}
-nest::noise_generator::noise_generator( const noise_generator& n )
+noise_generator::noise_generator( const noise_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -212,13 +211,13 @@ nest::noise_generator::noise_generator( const noise_generator& n )
* ---------------------------------------------------------------- */
void
-nest::noise_generator::init_state_()
+noise_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::noise_generator::init_buffers_()
+noise_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
@@ -229,7 +228,7 @@ nest::noise_generator::init_buffers_()
}
void
-nest::noise_generator::pre_run_hook()
+noise_generator::pre_run_hook()
{
B_.logger_.init();
@@ -266,7 +265,7 @@ nest::noise_generator::pre_run_hook()
* ---------------------------------------------------------------- */
size_t
-nest::noise_generator::send_test_event( Node& target, size_t receptor_type, synindex syn_id, bool dummy_target )
+noise_generator::send_test_event( Node& target, size_t receptor_type, synindex syn_id, bool dummy_target )
{
StimulationDevice::enforce_single_syn_type( syn_id );
@@ -293,7 +292,7 @@ nest::noise_generator::send_test_event( Node& target, size_t receptor_type, syni
// Time Evolution Operator
//
void
-nest::noise_generator::update( Time const& origin, const long from, const long to )
+noise_generator::update( Time const& origin, const long from, const long to )
{
const long start = origin.get_steps();
@@ -344,7 +343,7 @@ nest::noise_generator::update( Time const& origin, const long from, const long t
}
void
-nest::noise_generator::event_hook( DSCurrentEvent& e )
+noise_generator::event_hook( DSCurrentEvent& e )
{
// get port number
const size_t prt = e.get_port();
@@ -357,7 +356,7 @@ nest::noise_generator::event_hook( DSCurrentEvent& e )
}
void
-nest::noise_generator::handle( DataLoggingRequest& e )
+noise_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
@@ -367,7 +366,7 @@ nest::noise_generator::handle( DataLoggingRequest& e )
* ---------------------------------------------------------------- */
void
-nest::noise_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+noise_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
ptmp.num_targets_ = P_.num_targets_;
@@ -395,7 +394,7 @@ nest::noise_generator::set_data_from_stimulation_backend( std::vector< double >&
}
void
-nest::noise_generator::calibrate_time( const TimeConverter& tc )
+noise_generator::calibrate_time( const TimeConverter& tc )
{
if ( P_.dt_.is_step() )
{
@@ -409,3 +408,5 @@ nest::noise_generator::calibrate_time( const TimeConverter& tc )
LOG( M_INFO, get_name(), msg );
}
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/poisson_generator.cpp b/models/poisson_generator.cpp
index 516a886bca..9cb2278fb9 100644
--- a/models/poisson_generator.cpp
+++ b/models/poisson_generator.cpp
@@ -36,18 +36,21 @@
#include "dictutils.h"
#include "doubledatum.h"
+
+namespace nest
+{
+
void
-nest::register_poisson_generator( const std::string& name )
+register_poisson_generator( const std::string& name )
{
register_node_model< poisson_generator >( name );
}
-
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::poisson_generator::Parameters_::Parameters_()
+poisson_generator::Parameters_::Parameters_()
: rate_( 0.0 ) // spks/s
{
}
@@ -58,13 +61,13 @@ nest::poisson_generator::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::poisson_generator::Parameters_::get( DictionaryDatum& d ) const
+poisson_generator::Parameters_::get( DictionaryDatum& d ) const
{
def< double >( d, names::rate, rate_ );
}
void
-nest::poisson_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
+poisson_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::rate, rate_, node );
if ( rate_ < 0 )
@@ -78,13 +81,13 @@ nest::poisson_generator::Parameters_::set( const DictionaryDatum& d, Node* node
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::poisson_generator::poisson_generator()
+poisson_generator::poisson_generator()
: StimulationDevice()
, P_()
{
}
-nest::poisson_generator::poisson_generator( const poisson_generator& n )
+poisson_generator::poisson_generator( const poisson_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
{
@@ -96,19 +99,19 @@ nest::poisson_generator::poisson_generator( const poisson_generator& n )
* ---------------------------------------------------------------- */
void
-nest::poisson_generator::init_state_()
+poisson_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::poisson_generator::init_buffers_()
+poisson_generator::init_buffers_()
{
StimulationDevice::init_buffers();
}
void
-nest::poisson_generator::pre_run_hook()
+poisson_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
@@ -123,7 +126,7 @@ nest::poisson_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::poisson_generator::update( Time const& T, const long from, const long to )
+poisson_generator::update( Time const& T, const long from, const long to )
{
if ( P_.rate_ <= 0 )
{
@@ -143,7 +146,7 @@ nest::poisson_generator::update( Time const& T, const long from, const long to )
}
void
-nest::poisson_generator::event_hook( DSSpikeEvent& e )
+poisson_generator::event_hook( DSSpikeEvent& e )
{
long n_spikes = V_.poisson_dist_( get_vp_specific_rng( get_thread() ) );
@@ -159,7 +162,7 @@ nest::poisson_generator::event_hook( DSSpikeEvent& e )
* ---------------------------------------------------------------- */
void
-nest::poisson_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+poisson_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -178,3 +181,5 @@ nest::poisson_generator::set_data_from_stimulation_backend( std::vector< double
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+}
diff --git a/models/poisson_generator_ps.cpp b/models/poisson_generator_ps.cpp
index 7a913d15bc..a44302dfe2 100644
--- a/models/poisson_generator_ps.cpp
+++ b/models/poisson_generator_ps.cpp
@@ -46,11 +46,14 @@ nest::register_poisson_generator_ps( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::poisson_generator_ps::Parameters_::Parameters_()
+poisson_generator_ps::Parameters_::Parameters_()
: rate_( 0.0 ) // spks/s
, dead_time_( 0.0 ) // ms
, num_targets_( 0 )
@@ -62,14 +65,14 @@ nest::poisson_generator_ps::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::poisson_generator_ps::Parameters_::get( DictionaryDatum& d ) const
+poisson_generator_ps::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::rate ] = rate_;
( *d )[ names::dead_time ] = dead_time_;
}
void
-nest::poisson_generator_ps::Parameters_::set( const DictionaryDatum& d, Node* node )
+poisson_generator_ps::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::dead_time, dead_time_, node );
if ( dead_time_ < 0 )
@@ -95,13 +98,13 @@ nest::poisson_generator_ps::Parameters_::set( const DictionaryDatum& d, Node* no
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::poisson_generator_ps::poisson_generator_ps()
+poisson_generator_ps::poisson_generator_ps()
: StimulationDevice()
, P_()
{
}
-nest::poisson_generator_ps::poisson_generator_ps( const poisson_generator_ps& n )
+poisson_generator_ps::poisson_generator_ps( const poisson_generator_ps& n )
: StimulationDevice( n )
, P_( n.P_ )
{
@@ -113,15 +116,15 @@ nest::poisson_generator_ps::poisson_generator_ps( const poisson_generator_ps& n
* ---------------------------------------------------------------- */
void
-nest::poisson_generator_ps::init_state_()
+poisson_generator_ps::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::poisson_generator_ps::init_buffers_()
+poisson_generator_ps::init_buffers_()
{
- nest::Device::init_buffers();
+ Device::init_buffers();
// forget all about past, but do not discard connection information
B_.next_spike_.clear();
@@ -129,7 +132,7 @@ nest::poisson_generator_ps::init_buffers_()
}
void
-nest::poisson_generator_ps::pre_run_hook()
+poisson_generator_ps::pre_run_hook()
{
StimulationDevice::pre_run_hook();
if ( P_.rate_ > 0 )
@@ -182,7 +185,7 @@ nest::poisson_generator_ps::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::poisson_generator_ps::update( Time const& T, const long from, const long to )
+poisson_generator_ps::update( Time const& T, const long from, const long to )
{
if ( P_.rate_ <= 0 or P_.num_targets_ == 0 )
{
@@ -210,7 +213,7 @@ nest::poisson_generator_ps::update( Time const& T, const long from, const long t
}
void
-nest::poisson_generator_ps::event_hook( DSSpikeEvent& e )
+poisson_generator_ps::event_hook( DSSpikeEvent& e )
{
// get port number
const size_t prt = e.get_port();
@@ -284,7 +287,7 @@ nest::poisson_generator_ps::event_hook( DSSpikeEvent& e )
}
void
-nest::poisson_generator_ps::set_data_from_stimulation_backend( std::vector< double >& input_param )
+poisson_generator_ps::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -304,3 +307,5 @@ nest::poisson_generator_ps::set_data_from_stimulation_backend( std::vector< doub
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
diff --git a/models/pp_cond_exp_mc_urbanczik.cpp b/models/pp_cond_exp_mc_urbanczik.cpp
index 04d58df15f..54f775f491 100644
--- a/models/pp_cond_exp_mc_urbanczik.cpp
+++ b/models/pp_cond_exp_mc_urbanczik.cpp
@@ -560,6 +560,8 @@ nest::pp_cond_exp_mc_urbanczik::init_buffers_()
void
nest::pp_cond_exp_mc_urbanczik::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
V_.rng_ = get_vp_specific_rng( get_thread() );
diff --git a/models/pp_psc_delta.cpp b/models/pp_psc_delta.cpp
index 482fde1dff..e165c99b35 100644
--- a/models/pp_psc_delta.cpp
+++ b/models/pp_psc_delta.cpp
@@ -294,6 +294,8 @@ nest::pp_psc_delta::init_buffers_()
void
nest::pp_psc_delta::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init();
V_.h_ = Time::get_resolution().get_ms();
diff --git a/models/ppd_sup_generator.cpp b/models/ppd_sup_generator.cpp
index 32eb092145..e4724d7b36 100644
--- a/models/ppd_sup_generator.cpp
+++ b/models/ppd_sup_generator.cpp
@@ -45,11 +45,14 @@ nest::register_ppd_sup_generator( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Constructor of age distribution class
* ---------------------------------------------------------------- */
-nest::ppd_sup_generator::Age_distribution_::Age_distribution_( size_t num_age_bins,
+ppd_sup_generator::Age_distribution_::Age_distribution_( size_t num_age_bins,
unsigned long ini_occ_ref,
unsigned long ini_occ_act )
{
@@ -63,7 +66,7 @@ nest::ppd_sup_generator::Age_distribution_::Age_distribution_( size_t num_age_bi
* ---------------------------------------------------------------- */
unsigned long
-nest::ppd_sup_generator::Age_distribution_::update( double hazard_step, RngPtr rng )
+ppd_sup_generator::Age_distribution_::update( double hazard_step, RngPtr rng )
{
unsigned long n_spikes; // only set from poisson_dev, bino_dev or 0, thus >= 0
if ( occ_active_ > 0 )
@@ -110,7 +113,7 @@ nest::ppd_sup_generator::Age_distribution_::update( double hazard_step, RngPtr r
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::ppd_sup_generator::Parameters_::Parameters_()
+ppd_sup_generator::Parameters_::Parameters_()
: rate_( 0.0 ) // Hz
, dead_time_( 0.0 ) // ms
, n_proc_( 1 )
@@ -125,7 +128,7 @@ nest::ppd_sup_generator::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::ppd_sup_generator::Parameters_::get( DictionaryDatum& d ) const
+ppd_sup_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::rate ] = rate_;
( *d )[ names::dead_time ] = dead_time_;
@@ -135,7 +138,7 @@ nest::ppd_sup_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::ppd_sup_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
+ppd_sup_generator::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::dead_time, dead_time_, node );
if ( dead_time_ < 0 )
@@ -174,13 +177,13 @@ nest::ppd_sup_generator::Parameters_::set( const DictionaryDatum& d, Node* node
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::ppd_sup_generator::ppd_sup_generator()
+ppd_sup_generator::ppd_sup_generator()
: StimulationDevice()
, P_()
{
}
-nest::ppd_sup_generator::ppd_sup_generator( const ppd_sup_generator& n )
+ppd_sup_generator::ppd_sup_generator( const ppd_sup_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
{
@@ -192,19 +195,19 @@ nest::ppd_sup_generator::ppd_sup_generator( const ppd_sup_generator& n )
* ---------------------------------------------------------------- */
void
-nest::ppd_sup_generator::init_state_()
+ppd_sup_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::ppd_sup_generator::init_buffers_()
+ppd_sup_generator::init_buffers_()
{
StimulationDevice::init_buffers();
}
void
-nest::ppd_sup_generator::pre_run_hook()
+ppd_sup_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
@@ -235,7 +238,7 @@ nest::ppd_sup_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::ppd_sup_generator::update( Time const& T, const long from, const long to )
+ppd_sup_generator::update( Time const& T, const long from, const long to )
{
if ( P_.rate_ <= 0 or P_.num_targets_ == 0 )
{
@@ -269,7 +272,7 @@ nest::ppd_sup_generator::update( Time const& T, const long from, const long to )
void
-nest::ppd_sup_generator::event_hook( DSSpikeEvent& e )
+ppd_sup_generator::event_hook( DSSpikeEvent& e )
{
// get port number
const size_t prt = e.get_port();
@@ -294,7 +297,7 @@ nest::ppd_sup_generator::event_hook( DSSpikeEvent& e )
* ---------------------------------------------------------------- */
void
-nest::ppd_sup_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+ppd_sup_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -319,3 +322,5 @@ nest::ppd_sup_generator::set_data_from_stimulation_backend( std::vector< double
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/pulsepacket_generator.cpp b/models/pulsepacket_generator.cpp
index 19b4db16c6..e609128907 100644
--- a/models/pulsepacket_generator.cpp
+++ b/models/pulsepacket_generator.cpp
@@ -47,11 +47,14 @@ nest::register_pulsepacket_generator( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Default constructors defining default parameters and variables
* ---------------------------------------------------------------- */
-nest::pulsepacket_generator::Parameters_::Parameters_()
+pulsepacket_generator::Parameters_::Parameters_()
: pulse_times_()
, a_( 0 )
, sdev_( 0.0 )
@@ -59,7 +62,7 @@ nest::pulsepacket_generator::Parameters_::Parameters_()
{
}
-nest::pulsepacket_generator::Variables_::Variables_()
+pulsepacket_generator::Variables_::Variables_()
: start_center_idx_( 0 )
, stop_center_idx_( 0 )
, tolerance( 0.0 )
@@ -71,7 +74,7 @@ nest::pulsepacket_generator::Variables_::Variables_()
* ---------------------------------------------------------------- */
void
-nest::pulsepacket_generator::Parameters_::get( DictionaryDatum& d ) const
+pulsepacket_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::pulse_times ] = DoubleVectorDatum( new std::vector< double >( pulse_times_ ) );
( *d )[ names::activity ] = a_;
@@ -79,7 +82,7 @@ nest::pulsepacket_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::pulsepacket_generator::Parameters_::set( const DictionaryDatum& d, pulsepacket_generator& ppg, Node* node )
+pulsepacket_generator::Parameters_::set( const DictionaryDatum& d, pulsepacket_generator& ppg, Node* node )
{
// We cannot use a single line here since short-circuiting may stop evaluation
// prematurely. Therefore, neednewpulse must be second arg on second line.
@@ -106,13 +109,13 @@ nest::pulsepacket_generator::Parameters_::set( const DictionaryDatum& d, pulsepa
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::pulsepacket_generator::pulsepacket_generator()
+pulsepacket_generator::pulsepacket_generator()
: StimulationDevice()
, P_()
{
}
-nest::pulsepacket_generator::pulsepacket_generator( const pulsepacket_generator& ppg )
+pulsepacket_generator::pulsepacket_generator( const pulsepacket_generator& ppg )
: StimulationDevice( ppg )
, P_( ppg.P_ )
{
@@ -123,19 +126,19 @@ nest::pulsepacket_generator::pulsepacket_generator( const pulsepacket_generator&
* ---------------------------------------------------------------- */
void
-nest::pulsepacket_generator::init_state_()
+pulsepacket_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::pulsepacket_generator::init_buffers_()
+pulsepacket_generator::init_buffers_()
{
StimulationDevice::init_buffers();
}
void
-nest::pulsepacket_generator::pre_run_hook()
+pulsepacket_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
assert( V_.start_center_idx_ <= V_.stop_center_idx_ );
@@ -170,7 +173,7 @@ nest::pulsepacket_generator::pre_run_hook()
void
-nest::pulsepacket_generator::update( Time const& T, const long, const long to )
+pulsepacket_generator::update( Time const& T, const long, const long to )
{
if ( ( V_.start_center_idx_ == P_.pulse_times_.size() and B_.spiketimes_.empty() )
or ( not StimulationDevice::is_active( T ) ) )
@@ -238,7 +241,7 @@ nest::pulsepacket_generator::update( Time const& T, const long, const long to )
* ---------------------------------------------------------------- */
void
-nest::pulsepacket_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+pulsepacket_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -262,3 +265,5 @@ nest::pulsepacket_generator::set_data_from_stimulation_backend( std::vector< dou
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/quantal_stp_synapse.h b/models/quantal_stp_synapse.h
index 3c866a3674..f33cbb10fe 100644
--- a/models/quantal_stp_synapse.h
+++ b/models/quantal_stp_synapse.h
@@ -109,11 +109,11 @@ EndUserDocs */
void register_quantal_stp_synapse( const std::string& name );
template < typename targetidentifierT >
-class quantal_stp_synapse : public Connection< targetidentifierT >
+class quantal_stp_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -135,7 +135,7 @@ class quantal_stp_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -172,10 +172,10 @@ class quantal_stp_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
void
diff --git a/models/rate_connection_delayed.h b/models/rate_connection_delayed.h
index 81c3f3ea40..433d5c5214 100644
--- a/models/rate_connection_delayed.h
+++ b/models/rate_connection_delayed.h
@@ -79,13 +79,13 @@ EndUserDocs */
void register_rate_connection_delayed( const std::string& name );
template < typename targetidentifierT >
-class rate_connection_delayed : public Connection< targetidentifierT >
+class rate_connection_delayed : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY;
@@ -112,14 +112,14 @@ class rate_connection_delayed : public Connection< targetidentifierT >
using ConnectionBase::get_target;
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
DelayedRateConnectionEvent ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
/**
diff --git a/models/rate_connection_instantaneous.h b/models/rate_connection_instantaneous.h
index 4d32e41cc0..083d63da1d 100644
--- a/models/rate_connection_instantaneous.h
+++ b/models/rate_connection_instantaneous.h
@@ -80,13 +80,13 @@ EndUserDocs */
void register_rate_connection_instantaneous( const std::string& name );
template < typename targetidentifierT >
-class rate_connection_instantaneous : public Connection< targetidentifierT >
+class rate_connection_instantaneous : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::SUPPORTS_WFR;
@@ -113,14 +113,14 @@ class rate_connection_instantaneous : public Connection< targetidentifierT >
using ConnectionBase::get_target;
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
InstantaneousRateConnectionEvent ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
/**
@@ -149,11 +149,15 @@ class rate_connection_instantaneous : public Connection< targetidentifierT >
}
void
- set_delay( double )
+ set_delay_ms( double )
{
- throw BadProperty(
- "rate_connection_instantaneous has no delay. Please use "
- "rate_connection_delayed." );
+ throw BadProperty( "rate_connection_instantaneous has no delay. Please use rate_connection_delayed." );
+ }
+
+ void
+ set_delay_steps( long )
+ {
+ throw BadProperty( "rate_connection_instantaneous has no delay. Please use rate_connection_delayed." );
}
private:
@@ -179,9 +183,7 @@ rate_connection_instantaneous< targetidentifierT >::set_status( const Dictionary
// If the delay is set, we throw a BadProperty
if ( d->known( names::delay ) )
{
- throw BadProperty(
- "rate_connection_instantaneous has no delay. Please use "
- "rate_connection_delayed." );
+ throw BadProperty( "rate_connection_instantaneous has no delay. Please use rate_connection_delayed." );
}
ConnectionBase::set_status( d, cm );
diff --git a/models/rate_neuron_ipn_impl.h b/models/rate_neuron_ipn_impl.h
index 286c22c0af..96286bffa2 100644
--- a/models/rate_neuron_ipn_impl.h
+++ b/models/rate_neuron_ipn_impl.h
@@ -63,7 +63,7 @@ RecordablesMap< rate_neuron_ipn< TNonlinearities > > rate_neuron_ipn< TNonlinear
* ---------------------------------------------------------------- */
template < class TNonlinearities >
-nest::rate_neuron_ipn< TNonlinearities >::Parameters_::Parameters_()
+rate_neuron_ipn< TNonlinearities >::Parameters_::Parameters_()
: tau_( 10.0 ) // ms
, lambda_( 1.0 ) // ms
, sigma_( 1.0 )
@@ -77,7 +77,7 @@ nest::rate_neuron_ipn< TNonlinearities >::Parameters_::Parameters_()
}
template < class TNonlinearities >
-nest::rate_neuron_ipn< TNonlinearities >::State_::State_()
+rate_neuron_ipn< TNonlinearities >::State_::State_()
: rate_( 0.0 )
, noise_( 0.0 )
{
@@ -89,7 +89,7 @@ nest::rate_neuron_ipn< TNonlinearities >::State_::State_()
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const
+rate_neuron_ipn< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const
{
def< double >( d, names::tau, tau_ );
def< double >( d, names::lambda, lambda_ );
@@ -107,7 +107,7 @@ nest::rate_neuron_ipn< TNonlinearities >::Parameters_::get( DictionaryDatum& d )
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node )
+rate_neuron_ipn< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::tau, tau_, node );
updateValueParam< double >( d, names::lambda, lambda_, node );
@@ -156,7 +156,7 @@ nest::rate_neuron_ipn< TNonlinearities >::Parameters_::set( const DictionaryDatu
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::State_::get( DictionaryDatum& d ) const
+rate_neuron_ipn< TNonlinearities >::State_::get( DictionaryDatum& d ) const
{
def< double >( d, names::rate, rate_ ); // Rate
def< double >( d, names::noise, noise_ ); // Noise
@@ -164,19 +164,19 @@ nest::rate_neuron_ipn< TNonlinearities >::State_::get( DictionaryDatum& d ) cons
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node )
+rate_neuron_ipn< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::rate, rate_, node ); // Rate
}
template < class TNonlinearities >
-nest::rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( rate_neuron_ipn< TNonlinearities >& n )
+rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( rate_neuron_ipn< TNonlinearities >& n )
: logger_( n )
{
}
template < class TNonlinearities >
-nest::rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, rate_neuron_ipn< TNonlinearities >& n )
+rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, rate_neuron_ipn< TNonlinearities >& n )
: logger_( n )
{
}
@@ -186,7 +186,7 @@ nest::rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, r
* ---------------------------------------------------------------- */
template < class TNonlinearities >
-nest::rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn()
+rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn()
: ArchivingNode()
, P_()
, S_()
@@ -197,7 +197,7 @@ nest::rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn()
}
template < class TNonlinearities >
-nest::rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn( const rate_neuron_ipn& n )
+rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn( const rate_neuron_ipn& n )
: ArchivingNode( n )
, nonlinearities_( n.nonlinearities_ )
, P_( n.P_ )
@@ -213,7 +213,7 @@ nest::rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn( const rate_neuron_ipn
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::init_buffers_()
+rate_neuron_ipn< TNonlinearities >::init_buffers_()
{
B_.delayed_rates_ex_.clear(); // includes resize
B_.delayed_rates_in_.clear(); // includes resize
@@ -237,8 +237,10 @@ nest::rate_neuron_ipn< TNonlinearities >::init_buffers_()
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::pre_run_hook()
+rate_neuron_ipn< TNonlinearities >::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init(); // ensures initialization in case mm connected after Simulate
const double h = Time::get_resolution().get_ms();
@@ -265,7 +267,7 @@ nest::rate_neuron_ipn< TNonlinearities >::pre_run_hook()
template < class TNonlinearities >
bool
-nest::rate_neuron_ipn< TNonlinearities >::update_( Time const& origin,
+rate_neuron_ipn< TNonlinearities >::update_( Time const& origin,
const long from,
const long to,
const bool called_from_wfr_update )
@@ -394,7 +396,7 @@ nest::rate_neuron_ipn< TNonlinearities >::update_( Time const& origin,
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e )
+rate_neuron_ipn< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e )
{
const double weight = e.get_weight();
@@ -431,7 +433,7 @@ nest::rate_neuron_ipn< TNonlinearities >::handle( InstantaneousRateConnectionEve
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::handle( DelayedRateConnectionEvent& e )
+rate_neuron_ipn< TNonlinearities >::handle( DelayedRateConnectionEvent& e )
{
const double weight = e.get_weight();
const long delay = e.get_delay_steps() - kernel().connection_manager.get_min_delay();
@@ -469,7 +471,7 @@ nest::rate_neuron_ipn< TNonlinearities >::handle( DelayedRateConnectionEvent& e
template < class TNonlinearities >
void
-nest::rate_neuron_ipn< TNonlinearities >::handle( DataLoggingRequest& e )
+rate_neuron_ipn< TNonlinearities >::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
diff --git a/models/rate_neuron_opn_impl.h b/models/rate_neuron_opn_impl.h
index 2479fe8c23..5bfe69c1ef 100644
--- a/models/rate_neuron_opn_impl.h
+++ b/models/rate_neuron_opn_impl.h
@@ -223,6 +223,8 @@ template < class TNonlinearities >
void
nest::rate_neuron_opn< TNonlinearities >::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init(); // ensures initialization in case mm connected after Simulate
const double h = Time::get_resolution().get_ms();
diff --git a/models/rate_transformer_node_impl.h b/models/rate_transformer_node_impl.h
index 2809b97130..b4823cbf67 100644
--- a/models/rate_transformer_node_impl.h
+++ b/models/rate_transformer_node_impl.h
@@ -167,6 +167,8 @@ template < class TNonlinearities >
void
nest::rate_transformer_node< TNonlinearities >::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init(); // ensures initialization in case mm connected after Simulate
}
diff --git a/models/sic_connection.h b/models/sic_connection.h
index 0cf806c2ac..7b94abbd20 100644
--- a/models/sic_connection.h
+++ b/models/sic_connection.h
@@ -66,13 +66,13 @@ EndUserDocs */
void register_sic_connection( const std::string& name );
template < typename targetidentifierT >
-class sic_connection : public Connection< targetidentifierT >
+class sic_connection : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
typedef SICEvent EventType;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY;
@@ -97,14 +97,14 @@ class sic_connection : public Connection< targetidentifierT >
using ConnectionBase::get_target;
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex, const CommonPropertiesType& )
{
EventType ge;
s.sends_secondary_event( ge );
ge.set_sender( s );
- Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
- Connection< targetidentifierT >::target_.set_target( &t );
+ Connection< targetidentifierT, TotalDelay >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
+ Connection< targetidentifierT, TotalDelay >::target_.set_target( &t );
}
/**
diff --git a/models/siegert_neuron.cpp b/models/siegert_neuron.cpp
index ec39ab5cec..895b78f569 100644
--- a/models/siegert_neuron.cpp
+++ b/models/siegert_neuron.cpp
@@ -296,6 +296,8 @@ nest::siegert_neuron::init_buffers_()
void
nest::siegert_neuron::pre_run_hook()
{
+ ArchivingNode::pre_run_hook_();
+
B_.logger_.init(); // ensures initialization in case mm connected after Simulate
const double h = Time::get_resolution().get_ms();
diff --git a/models/sinusoidal_gamma_generator.cpp b/models/sinusoidal_gamma_generator.cpp
index 30c49fe411..1b7399ed6e 100644
--- a/models/sinusoidal_gamma_generator.cpp
+++ b/models/sinusoidal_gamma_generator.cpp
@@ -47,14 +47,16 @@
#include "dictutils.h"
#include "doubledatum.h"
-namespace nest
-{
+
void
-register_sinusoidal_gamma_generator( const std::string& name )
+nest::register_sinusoidal_gamma_generator( const std::string& name )
{
register_node_model< sinusoidal_gamma_generator >( name );
}
+namespace nest
+{
+
RecordablesMap< sinusoidal_gamma_generator > sinusoidal_gamma_generator::recordablesMap_;
template <>
@@ -63,10 +65,8 @@ RecordablesMap< sinusoidal_gamma_generator >::create()
{
insert_( names::rate, &sinusoidal_gamma_generator::get_rate_ );
}
-}
-
-nest::sinusoidal_gamma_generator::Parameters_::Parameters_()
+sinusoidal_gamma_generator::Parameters_::Parameters_()
: om_( 0.0 ) // radian/ms
, phi_( 0.0 ) // radian
, order_( 1.0 )
@@ -77,7 +77,7 @@ nest::sinusoidal_gamma_generator::Parameters_::Parameters_()
{
}
-nest::sinusoidal_gamma_generator::Parameters_::Parameters_( const Parameters_& p )
+sinusoidal_gamma_generator::Parameters_::Parameters_( const Parameters_& p )
: om_( p.om_ )
, phi_( p.phi_ )
, order_( p.order_ )
@@ -88,8 +88,8 @@ nest::sinusoidal_gamma_generator::Parameters_::Parameters_( const Parameters_& p
{
}
-nest::sinusoidal_gamma_generator::Parameters_&
-nest::sinusoidal_gamma_generator::Parameters_::operator=( const Parameters_& p )
+sinusoidal_gamma_generator::Parameters_&
+sinusoidal_gamma_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -107,13 +107,13 @@ nest::sinusoidal_gamma_generator::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::sinusoidal_gamma_generator::State_::State_()
+sinusoidal_gamma_generator::State_::State_()
: rate_( 0 )
{
}
-nest::sinusoidal_gamma_generator::Buffers_::Buffers_( sinusoidal_gamma_generator& n )
+sinusoidal_gamma_generator::Buffers_::Buffers_( sinusoidal_gamma_generator& n )
: logger_( n )
, t0_ms_()
, // will be set in init_buffers_
@@ -123,7 +123,7 @@ nest::sinusoidal_gamma_generator::Buffers_::Buffers_( sinusoidal_gamma_generator
{
}
-nest::sinusoidal_gamma_generator::Buffers_::Buffers_( const Buffers_& b, sinusoidal_gamma_generator& n )
+sinusoidal_gamma_generator::Buffers_::Buffers_( const Buffers_& b, sinusoidal_gamma_generator& n )
: logger_( n )
, t0_ms_( b.t0_ms_ )
, Lambda_t0_( b.Lambda_t0_ )
@@ -136,7 +136,7 @@ nest::sinusoidal_gamma_generator::Buffers_::Buffers_( const Buffers_& b, sinusoi
* ---------------------------------------------------------------- */
void
-nest::sinusoidal_gamma_generator::Parameters_::get( DictionaryDatum& d ) const
+sinusoidal_gamma_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::rate ] = rate_ * 1000.0;
( *d )[ names::frequency ] = om_ / ( 2.0 * numerics::pi / 1000.0 );
@@ -147,7 +147,7 @@ nest::sinusoidal_gamma_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::sinusoidal_gamma_generator::Parameters_::set( const DictionaryDatum& d,
+sinusoidal_gamma_generator::Parameters_::set( const DictionaryDatum& d,
const sinusoidal_gamma_generator& n,
Node* node )
{
@@ -217,7 +217,7 @@ nest::sinusoidal_gamma_generator::Parameters_::set( const DictionaryDatum& d,
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::sinusoidal_gamma_generator::sinusoidal_gamma_generator()
+sinusoidal_gamma_generator::sinusoidal_gamma_generator()
: StimulationDevice()
, P_()
, S_()
@@ -226,7 +226,7 @@ nest::sinusoidal_gamma_generator::sinusoidal_gamma_generator()
recordablesMap_.create();
}
-nest::sinusoidal_gamma_generator::sinusoidal_gamma_generator( const sinusoidal_gamma_generator& n )
+sinusoidal_gamma_generator::sinusoidal_gamma_generator( const sinusoidal_gamma_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -239,13 +239,13 @@ nest::sinusoidal_gamma_generator::sinusoidal_gamma_generator( const sinusoidal_g
* ---------------------------------------------------------------- */
void
-nest::sinusoidal_gamma_generator::init_state_()
+sinusoidal_gamma_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::sinusoidal_gamma_generator::init_buffers_()
+sinusoidal_gamma_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
@@ -258,7 +258,7 @@ nest::sinusoidal_gamma_generator::init_buffers_()
// ----------------------------------------------------
inline double
-nest::sinusoidal_gamma_generator::deltaLambda_( const Parameters_& p, double t_a, double t_b ) const
+sinusoidal_gamma_generator::deltaLambda_( const Parameters_& p, double t_a, double t_b ) const
{
if ( t_a == t_b )
{
@@ -277,7 +277,7 @@ nest::sinusoidal_gamma_generator::deltaLambda_( const Parameters_& p, double t_a
// ----------------------------------------------------
void
-nest::sinusoidal_gamma_generator::pre_run_hook()
+sinusoidal_gamma_generator::pre_run_hook()
{
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
@@ -304,7 +304,7 @@ nest::sinusoidal_gamma_generator::pre_run_hook()
}
double
-nest::sinusoidal_gamma_generator::hazard_( size_t tgt_idx ) const
+sinusoidal_gamma_generator::hazard_( size_t tgt_idx ) const
{
// Note: We compute Lambda for the entire interval since the last spike/
// parameter change each time for better accuracy.
@@ -314,7 +314,7 @@ nest::sinusoidal_gamma_generator::hazard_( size_t tgt_idx ) const
}
void
-nest::sinusoidal_gamma_generator::update( Time const& origin, const long from, const long to )
+sinusoidal_gamma_generator::update( Time const& origin, const long from, const long to )
{
for ( long lag = from; lag < to; ++lag )
{
@@ -348,7 +348,7 @@ nest::sinusoidal_gamma_generator::update( Time const& origin, const long from, c
}
void
-nest::sinusoidal_gamma_generator::event_hook( DSSpikeEvent& e )
+sinusoidal_gamma_generator::event_hook( DSSpikeEvent& e )
{
// get port number --- see #737
const size_t tgt_idx = e.get_port();
@@ -363,7 +363,7 @@ nest::sinusoidal_gamma_generator::event_hook( DSSpikeEvent& e )
}
void
-nest::sinusoidal_gamma_generator::handle( DataLoggingRequest& e )
+sinusoidal_gamma_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
@@ -373,7 +373,7 @@ nest::sinusoidal_gamma_generator::handle( DataLoggingRequest& e )
* ---------------------------------------------------------------- */
void
-nest::sinusoidal_gamma_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+sinusoidal_gamma_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -399,4 +399,7 @@ nest::sinusoidal_gamma_generator::set_data_from_stimulation_backend( std::vector
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
-#endif // HAVE_GSL
+
+} // namespace nest
+
+#endif // HAVE_GSL
\ No newline at end of file
diff --git a/models/sinusoidal_poisson_generator.cpp b/models/sinusoidal_poisson_generator.cpp
index 6a24cfae5f..f7b87b170d 100644
--- a/models/sinusoidal_poisson_generator.cpp
+++ b/models/sinusoidal_poisson_generator.cpp
@@ -59,13 +59,12 @@ RecordablesMap< sinusoidal_poisson_generator >::create()
{
insert_( Name( names::rate ), &sinusoidal_poisson_generator::get_rate_ );
}
-}
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::sinusoidal_poisson_generator::Parameters_::Parameters_()
+sinusoidal_poisson_generator::Parameters_::Parameters_()
: om_( 0.0 ) // radian/ms
, phi_( 0.0 ) // radian
, rate_( 0.0 ) // spikes/ms
@@ -74,7 +73,7 @@ nest::sinusoidal_poisson_generator::Parameters_::Parameters_()
{
}
-nest::sinusoidal_poisson_generator::Parameters_::Parameters_( const Parameters_& p )
+sinusoidal_poisson_generator::Parameters_::Parameters_( const Parameters_& p )
: om_( p.om_ )
, phi_( p.phi_ )
, rate_( p.rate_ )
@@ -83,8 +82,8 @@ nest::sinusoidal_poisson_generator::Parameters_::Parameters_( const Parameters_&
{
}
-nest::sinusoidal_poisson_generator::Parameters_&
-nest::sinusoidal_poisson_generator::Parameters_::operator=( const Parameters_& p )
+sinusoidal_poisson_generator::Parameters_&
+sinusoidal_poisson_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -100,7 +99,7 @@ nest::sinusoidal_poisson_generator::Parameters_::operator=( const Parameters_& p
return *this;
}
-nest::sinusoidal_poisson_generator::State_::State_()
+sinusoidal_poisson_generator::State_::State_()
: y_0_( 0 )
, y_1_( 0 )
, rate_( 0 )
@@ -108,12 +107,12 @@ nest::sinusoidal_poisson_generator::State_::State_()
}
-nest::sinusoidal_poisson_generator::Buffers_::Buffers_( sinusoidal_poisson_generator& n )
+sinusoidal_poisson_generator::Buffers_::Buffers_( sinusoidal_poisson_generator& n )
: logger_( n )
{
}
-nest::sinusoidal_poisson_generator::Buffers_::Buffers_( const Buffers_&, sinusoidal_poisson_generator& n )
+sinusoidal_poisson_generator::Buffers_::Buffers_( const Buffers_&, sinusoidal_poisson_generator& n )
: logger_( n )
{
}
@@ -124,7 +123,7 @@ nest::sinusoidal_poisson_generator::Buffers_::Buffers_( const Buffers_&, sinusoi
* ---------------------------------------------------------------- */
void
-nest::sinusoidal_poisson_generator::Parameters_::get( DictionaryDatum& d ) const
+sinusoidal_poisson_generator::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::rate ] = rate_ * 1000.0;
( *d )[ names::frequency ] = om_ / ( 2.0 * numerics::pi / 1000.0 );
@@ -134,14 +133,14 @@ nest::sinusoidal_poisson_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::sinusoidal_poisson_generator::State_::get( DictionaryDatum& d ) const
+sinusoidal_poisson_generator::State_::get( DictionaryDatum& d ) const
{
( *d )[ names::y_0 ] = y_0_;
( *d )[ names::y_1 ] = y_1_;
}
void
-nest::sinusoidal_poisson_generator::Parameters_::set( const DictionaryDatum& d,
+sinusoidal_poisson_generator::Parameters_::set( const DictionaryDatum& d,
const sinusoidal_poisson_generator& n,
Node* node )
{
@@ -179,7 +178,7 @@ nest::sinusoidal_poisson_generator::Parameters_::set( const DictionaryDatum& d,
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::sinusoidal_poisson_generator::sinusoidal_poisson_generator()
+sinusoidal_poisson_generator::sinusoidal_poisson_generator()
: StimulationDevice()
, P_()
, S_()
@@ -188,7 +187,7 @@ nest::sinusoidal_poisson_generator::sinusoidal_poisson_generator()
recordablesMap_.create();
}
-nest::sinusoidal_poisson_generator::sinusoidal_poisson_generator( const sinusoidal_poisson_generator& n )
+sinusoidal_poisson_generator::sinusoidal_poisson_generator( const sinusoidal_poisson_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -201,20 +200,20 @@ nest::sinusoidal_poisson_generator::sinusoidal_poisson_generator( const sinusoid
* ---------------------------------------------------------------- */
void
-nest::sinusoidal_poisson_generator::init_state_()
+sinusoidal_poisson_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::sinusoidal_poisson_generator::init_buffers_()
+sinusoidal_poisson_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
}
void
-nest::sinusoidal_poisson_generator::pre_run_hook()
+sinusoidal_poisson_generator::pre_run_hook()
{
// ensures initialization in case mm connected after Simulate
B_.logger_.init();
@@ -234,7 +233,7 @@ nest::sinusoidal_poisson_generator::pre_run_hook()
}
void
-nest::sinusoidal_poisson_generator::update( Time const& origin, const long from, const long to )
+sinusoidal_poisson_generator::update( Time const& origin, const long from, const long to )
{
const long start = origin.get_steps();
@@ -287,7 +286,7 @@ nest::sinusoidal_poisson_generator::update( Time const& origin, const long from,
}
void
-nest::sinusoidal_poisson_generator::event_hook( DSSpikeEvent& e )
+sinusoidal_poisson_generator::event_hook( DSSpikeEvent& e )
{
poisson_distribution::param_type param( S_.rate_ * V_.h_ );
long n_spikes = V_.poisson_dist_( get_vp_specific_rng( get_thread() ), param );
@@ -300,7 +299,7 @@ nest::sinusoidal_poisson_generator::event_hook( DSSpikeEvent& e )
}
void
-nest::sinusoidal_poisson_generator::handle( DataLoggingRequest& e )
+sinusoidal_poisson_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
@@ -310,7 +309,7 @@ nest::sinusoidal_poisson_generator::handle( DataLoggingRequest& e )
* ---------------------------------------------------------------- */
void
-nest::sinusoidal_poisson_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
+sinusoidal_poisson_generator::set_data_from_stimulation_backend( std::vector< double >& input_param )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -335,3 +334,5 @@ nest::sinusoidal_poisson_generator::set_data_from_stimulation_backend( std::vect
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
diff --git a/models/spike_dilutor.cpp b/models/spike_dilutor.cpp
index b4d105a70d..bd63cb7490 100644
--- a/models/spike_dilutor.cpp
+++ b/models/spike_dilutor.cpp
@@ -36,18 +36,20 @@
#include "dict.h"
#include "dictutils.h"
+namespace nest
+{
+
void
-nest::register_spike_dilutor( const std::string& name )
+register_spike_dilutor( const std::string& name )
{
register_node_model< spike_dilutor >( name );
}
-
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::spike_dilutor::Parameters_::Parameters_()
+spike_dilutor::Parameters_::Parameters_()
: p_copy_( 1.0 )
{
}
@@ -57,13 +59,13 @@ nest::spike_dilutor::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::spike_dilutor::Parameters_::get( DictionaryDatum& d ) const
+spike_dilutor::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::p_copy ] = p_copy_;
}
void
-nest::spike_dilutor::Parameters_::set( const DictionaryDatum& d, Node* node )
+spike_dilutor::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< double >( d, names::p_copy, p_copy_, node );
if ( p_copy_ < 0 or p_copy_ > 1 )
@@ -76,14 +78,14 @@ nest::spike_dilutor::Parameters_::set( const DictionaryDatum& d, Node* node )
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::spike_dilutor::spike_dilutor()
+spike_dilutor::spike_dilutor()
: DeviceNode()
, device_()
, P_()
{
}
-nest::spike_dilutor::spike_dilutor( const spike_dilutor& n )
+spike_dilutor::spike_dilutor( const spike_dilutor& n )
: DeviceNode( n )
, device_( n.device_ )
, P_( n.P_ )
@@ -95,7 +97,7 @@ nest::spike_dilutor::spike_dilutor( const spike_dilutor& n )
* ---------------------------------------------------------------- */
void
-nest::spike_dilutor::init_state_()
+spike_dilutor::init_state_()
{
// This check cannot be done in the copy constructor because that is also used to
// create model prototypes. Since spike_dilutor is deprecated anyways, we put this
@@ -109,14 +111,14 @@ nest::spike_dilutor::init_state_()
}
void
-nest::spike_dilutor::init_buffers_()
+spike_dilutor::init_buffers_()
{
B_.n_spikes_.clear(); // includes resize
device_.init_buffers();
}
void
-nest::spike_dilutor::pre_run_hook()
+spike_dilutor::pre_run_hook()
{
device_.pre_run_hook();
}
@@ -126,7 +128,7 @@ nest::spike_dilutor::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::spike_dilutor::update( Time const& T, const long from, const long to )
+spike_dilutor::update( Time const& T, const long from, const long to )
{
for ( long lag = from; lag < to; ++lag )
{
@@ -149,7 +151,7 @@ nest::spike_dilutor::update( Time const& T, const long from, const long to )
}
void
-nest::spike_dilutor::event_hook( DSSpikeEvent& e )
+spike_dilutor::event_hook( DSSpikeEvent& e )
{
// Note: event_hook() receives a reference of the spike event that
// was originally created in the update function. There we set
@@ -182,8 +184,10 @@ nest::spike_dilutor::event_hook( DSSpikeEvent& e )
}
void
-nest::spike_dilutor::handle( SpikeEvent& e )
+spike_dilutor::handle( SpikeEvent& e )
{
B_.n_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ),
static_cast< double >( e.get_multiplicity() ) );
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/spike_generator.cpp b/models/spike_generator.cpp
index c6153ede4c..99fa5f1b4d 100644
--- a/models/spike_generator.cpp
+++ b/models/spike_generator.cpp
@@ -44,11 +44,14 @@ nest::register_spike_generator( const std::string& name )
}
+namespace nest
+{
+
/* ----------------------------------------------------------------
* Default constructor defining default parameters
* ---------------------------------------------------------------- */
-nest::spike_generator::Parameters_::Parameters_()
+spike_generator::Parameters_::Parameters_()
: spike_stamps_()
, spike_offsets_()
, spike_weights_()
@@ -65,7 +68,7 @@ nest::spike_generator::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::spike_generator::Parameters_::get( DictionaryDatum& d ) const
+spike_generator::Parameters_::get( DictionaryDatum& d ) const
{
const size_t n_spikes = spike_stamps_.size();
auto* times_ms = new std::vector< double >();
@@ -89,7 +92,7 @@ nest::spike_generator::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::spike_generator::Parameters_::assert_valid_spike_time_and_insert_( double t, const Time& origin, const Time& now )
+spike_generator::Parameters_::assert_valid_spike_time_and_insert_( double t, const Time& origin, const Time& now )
{
if ( t == 0.0 and not shift_now_spikes_ )
{
@@ -154,7 +157,7 @@ nest::spike_generator::Parameters_::assert_valid_spike_time_and_insert_( double
}
void
-nest::spike_generator::Parameters_::set( const DictionaryDatum& d,
+spike_generator::Parameters_::set( const DictionaryDatum& d,
State_& s,
const Time& origin,
const Time& now,
@@ -275,7 +278,7 @@ nest::spike_generator::Parameters_::set( const DictionaryDatum& d,
* Default constructor defining default state
* ---------------------------------------------------------------- */
-nest::spike_generator::State_::State_()
+spike_generator::State_::State_()
: position_( 0 )
{
}
@@ -285,14 +288,14 @@ nest::spike_generator::State_::State_()
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::spike_generator::spike_generator()
+spike_generator::spike_generator()
: StimulationDevice()
, P_()
, S_()
{
}
-nest::spike_generator::spike_generator( const spike_generator& n )
+spike_generator::spike_generator( const spike_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -305,19 +308,19 @@ nest::spike_generator::spike_generator( const spike_generator& n )
* ---------------------------------------------------------------- */
void
-nest::spike_generator::init_state_()
+spike_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::spike_generator::init_buffers_()
+spike_generator::init_buffers_()
{
StimulationDevice::init_buffers();
}
void
-nest::spike_generator::pre_run_hook()
+spike_generator::pre_run_hook()
{
StimulationDevice::pre_run_hook();
}
@@ -327,7 +330,7 @@ nest::spike_generator::pre_run_hook()
* Other functions
* ---------------------------------------------------------------- */
void
-nest::spike_generator::update( Time const& sliceT0, const long from, const long to )
+spike_generator::update( Time const& sliceT0, const long from, const long to )
{
if ( P_.spike_stamps_.empty() )
{
@@ -397,7 +400,7 @@ nest::spike_generator::update( Time const& sliceT0, const long from, const long
}
void
-nest::spike_generator::event_hook( DSSpikeEvent& e )
+spike_generator::event_hook( DSSpikeEvent& e )
{
e.set_weight( P_.spike_weights_[ S_.position_ ] * e.get_weight() );
e.get_receiver().handle( e );
@@ -409,7 +412,7 @@ nest::spike_generator::event_hook( DSSpikeEvent& e )
* ---------------------------------------------------------------- */
void
-nest::spike_generator::set_data_from_stimulation_backend( std::vector< double >& input_spikes )
+spike_generator::set_data_from_stimulation_backend( std::vector< double >& input_spikes )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -440,3 +443,5 @@ nest::spike_generator::set_data_from_stimulation_backend( std::vector< double >&
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/spike_recorder.cpp b/models/spike_recorder.cpp
index 5769fa60e7..fae95004f5 100644
--- a/models/spike_recorder.cpp
+++ b/models/spike_recorder.cpp
@@ -36,43 +36,47 @@
#include "dict.h"
#include "dictutils.h"
+
+namespace nest
+{
+
void
-nest::register_spike_recorder( const std::string& name )
+register_spike_recorder( const std::string& name )
{
register_node_model< spike_recorder >( name );
}
-nest::spike_recorder::spike_recorder()
+spike_recorder::spike_recorder()
: RecordingDevice()
{
}
-nest::spike_recorder::spike_recorder( const spike_recorder& n )
+spike_recorder::spike_recorder( const spike_recorder& n )
: RecordingDevice( n )
{
}
void
-nest::spike_recorder::pre_run_hook()
+spike_recorder::pre_run_hook()
{
RecordingDevice::pre_run_hook( RecordingBackend::NO_DOUBLE_VALUE_NAMES, RecordingBackend::NO_LONG_VALUE_NAMES );
}
void
-nest::spike_recorder::update( Time const&, const long, const long )
+spike_recorder::update( Time const&, const long, const long )
{
// Nothing to do. Writing to the backend happens in handle().
}
-nest::RecordingDevice::Type
-nest::spike_recorder::get_type() const
+RecordingDevice::Type
+spike_recorder::get_type() const
{
return RecordingDevice::SPIKE_RECORDER;
}
void
-nest::spike_recorder::get_status( DictionaryDatum& d ) const
+spike_recorder::get_status( DictionaryDatum& d ) const
{
RecordingDevice::get_status( d );
@@ -94,13 +98,13 @@ nest::spike_recorder::get_status( DictionaryDatum& d ) const
}
void
-nest::spike_recorder::set_status( const DictionaryDatum& d )
+spike_recorder::set_status( const DictionaryDatum& d )
{
RecordingDevice::set_status( d );
}
void
-nest::spike_recorder::handle( SpikeEvent& e )
+spike_recorder::handle( SpikeEvent& e )
{
// accept spikes only if detector was active when spike was emitted
if ( is_active( e.get_stamp() ) )
@@ -113,3 +117,5 @@ nest::spike_recorder::handle( SpikeEvent& e )
}
}
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/spin_detector.cpp b/models/spin_detector.cpp
index 190ece15cb..ca76c674e4 100644
--- a/models/spin_detector.cpp
+++ b/models/spin_detector.cpp
@@ -36,20 +36,22 @@
#include "dict.h"
#include "dictutils.h"
+namespace nest
+{
+
void
-nest::register_spin_detector( const std::string& name )
+register_spin_detector( const std::string& name )
{
register_node_model< spin_detector >( name );
}
-
-nest::spin_detector::spin_detector()
+spin_detector::spin_detector()
: last_in_node_id_( 0 )
, t_last_in_spike_( Time::neg_inf() )
{
}
-nest::spin_detector::spin_detector( const spin_detector& n )
+spin_detector::spin_detector( const spin_detector& n )
: RecordingDevice( n )
, last_in_node_id_( 0 )
, t_last_in_spike_( Time::neg_inf() ) // mark as not initialized
@@ -57,18 +59,18 @@ nest::spin_detector::spin_detector( const spin_detector& n )
}
void
-nest::spin_detector::init_buffers_()
+spin_detector::init_buffers_()
{
}
void
-nest::spin_detector::pre_run_hook()
+spin_detector::pre_run_hook()
{
- RecordingDevice::pre_run_hook( RecordingBackend::NO_DOUBLE_VALUE_NAMES, { nest::names::state } );
+ RecordingDevice::pre_run_hook( RecordingBackend::NO_DOUBLE_VALUE_NAMES, { names::state } );
}
void
-nest::spin_detector::update( Time const&, const long, const long )
+spin_detector::update( Time const&, const long, const long )
{
if ( last_in_node_id_ != 0 ) // if last_* is empty we dont write
{
@@ -77,14 +79,14 @@ nest::spin_detector::update( Time const&, const long, const long )
}
}
-nest::RecordingDevice::Type
-nest::spin_detector::get_type() const
+RecordingDevice::Type
+spin_detector::get_type() const
{
return RecordingDevice::SPIN_DETECTOR;
}
void
-nest::spin_detector::get_status( DictionaryDatum& d ) const
+spin_detector::get_status( DictionaryDatum& d ) const
{
// get the data from the device
RecordingDevice::get_status( d );
@@ -108,14 +110,14 @@ nest::spin_detector::get_status( DictionaryDatum& d ) const
}
void
-nest::spin_detector::set_status( const DictionaryDatum& d )
+spin_detector::set_status( const DictionaryDatum& d )
{
RecordingDevice::set_status( d );
}
void
-nest::spin_detector::handle( SpikeEvent& e )
+spin_detector::handle( SpikeEvent& e )
{
// accept spikes only if detector was active when spike was
// emitted
@@ -170,3 +172,5 @@ nest::spin_detector::handle( SpikeEvent& e )
}
}
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/spin_detector.h b/models/spin_detector.h
index 2cb2ef1775..05e4dcd243 100644
--- a/models/spin_detector.h
+++ b/models/spin_detector.h
@@ -180,7 +180,7 @@ spin_detector::receives_signal() const
}
inline void
-nest::spin_detector::calibrate_time( const TimeConverter& tc )
+spin_detector::calibrate_time( const TimeConverter& tc )
{
t_last_in_spike_ = tc.from_old_tics( t_last_in_spike_.get_tics() );
}
diff --git a/models/static_synapse.h b/models/static_synapse.h
index 25ebf2ce61..e049114ab3 100644
--- a/models/static_synapse.h
+++ b/models/static_synapse.h
@@ -63,14 +63,14 @@ EndUserDocs */
void register_static_synapse( const std::string& name );
template < typename targetidentifierT >
-class static_synapse : public Connection< targetidentifierT >
+class static_synapse : public Connection< targetidentifierT, TotalDelay >
{
double weight_;
public:
// this line determines which common properties to use
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -151,10 +151,10 @@ class static_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
bool
diff --git a/models/static_synapse_hom_w.h b/models/static_synapse_hom_w.h
index f6ea22c3df..66a1b9ee00 100644
--- a/models/static_synapse_hom_w.h
+++ b/models/static_synapse_hom_w.h
@@ -69,13 +69,13 @@ EndUserDocs */
void register_static_synapse_hom_w( const std::string& name );
template < typename targetidentifierT >
-class static_synapse_hom_w : public Connection< targetidentifierT >
+class static_synapse_hom_w : public Connection< targetidentifierT, TotalDelay >
{
public:
// this line determines which common properties to use
typedef CommonPropertiesHomW CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
// Explicitly declare all methods inherited from the dependent base
// ConnectionBase. This avoids explicit name prefixes in all places these
@@ -140,10 +140,10 @@ class static_synapse_hom_w : public Connection< targetidentifierT >
void get_status( DictionaryDatum& d ) const;
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
/**
diff --git a/models/stdp_dopamine_synapse.h b/models/stdp_dopamine_synapse.h
index 118c0054ff..83abb6f60f 100644
--- a/models/stdp_dopamine_synapse.h
+++ b/models/stdp_dopamine_synapse.h
@@ -193,12 +193,12 @@ STDPDopaCommonProperties::get_vt_node_id() const
void register_stdp_dopamine_synapse( const std::string& name );
template < typename targetidentifierT >
-class stdp_dopamine_synapse : public Connection< targetidentifierT >
+class stdp_dopamine_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef STDPDopaCommonProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -221,7 +221,7 @@ class stdp_dopamine_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -285,7 +285,11 @@ class stdp_dopamine_synapse : public Connection< targetidentifierT >
* \param receptor_type The ID of the requested receptor type
*/
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& cp )
+ check_connection( Node& s,
+ Node& t,
+ const size_t receptor_type,
+ const synindex syn_id,
+ const CommonPropertiesType& cp )
{
if ( not cp.volume_transmitter_ )
{
@@ -293,9 +297,9 @@ class stdp_dopamine_synapse : public Connection< targetidentifierT >
}
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -529,7 +533,7 @@ stdp_dopamine_synapse< targetidentifierT >::send( Event& e, size_t t, const STDP
Node* target = get_target( t );
// purely dendritic delay
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
double t_spike = e.get_stamp().get_ms();
@@ -588,7 +592,7 @@ stdp_dopamine_synapse< targetidentifierT >::trigger_update_weight( size_t t,
// postsyn. neuron
// purely dendritic delay
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t_last_update, t_trig] from postsyn.
// neuron
diff --git a/models/stdp_facetshw_synapse_hom.h b/models/stdp_facetshw_synapse_hom.h
index 2b103eed48..4de8c8c926 100644
--- a/models/stdp_facetshw_synapse_hom.h
+++ b/models/stdp_facetshw_synapse_hom.h
@@ -235,12 +235,12 @@ class STDPFACETSHWHomCommonProperties : public CommonSynapseProperties
* parameters are the same for all synapses.
*/
template < typename targetidentifierT >
-class stdp_facetshw_synapse_hom : public Connection< targetidentifierT >
+class stdp_facetshw_synapse_hom : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef STDPFACETSHWHomCommonProperties< targetidentifierT > CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -263,7 +263,7 @@ class stdp_facetshw_synapse_hom : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -312,13 +312,13 @@ class stdp_facetshw_synapse_hom : public Connection< targetidentifierT >
* \param receptor_type The ID of the requested receptor type
*/
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -498,7 +498,7 @@ stdp_facetshw_synapse_hom< targetidentifierT >::send( Event& e,
// t_lastspike_ = 0 initially
- double dendritic_delay = Time( Time::step( get_delay_steps() ) ).get_ms();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/stdp_nn_pre_centered_synapse.h b/models/stdp_nn_pre_centered_synapse.h
index ec2791efbf..f08cae4a4f 100644
--- a/models/stdp_nn_pre_centered_synapse.h
+++ b/models/stdp_nn_pre_centered_synapse.h
@@ -130,12 +130,12 @@ EndUserDocs */
void register_stdp_nn_pre_centered_synapse( const std::string& name );
template < typename targetidentifierT >
-class stdp_nn_pre_centered_synapse : public Connection< targetidentifierT >
+class stdp_nn_pre_centered_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -159,7 +159,7 @@ class stdp_nn_pre_centered_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -195,13 +195,13 @@ class stdp_nn_pre_centered_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -257,7 +257,7 @@ stdp_nn_pre_centered_synapse< targetidentifierT >::send( Event& e, size_t t, con
// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/stdp_nn_restr_synapse.h b/models/stdp_nn_restr_synapse.h
index 7562266dc3..2b6f58c95b 100644
--- a/models/stdp_nn_restr_synapse.h
+++ b/models/stdp_nn_restr_synapse.h
@@ -125,12 +125,12 @@ EndUserDocs */
void register_stdp_nn_restr_synapse( const std::string& name );
template < typename targetidentifierT >
-class stdp_nn_restr_synapse : public Connection< targetidentifierT >
+class stdp_nn_restr_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -154,7 +154,7 @@ class stdp_nn_restr_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -191,13 +191,13 @@ class stdp_nn_restr_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -252,7 +252,7 @@ stdp_nn_restr_synapse< targetidentifierT >::send( Event& e, size_t t, const Comm
// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/stdp_nn_symm_synapse.h b/models/stdp_nn_symm_synapse.h
index 92970ec8ec..23f205cbd8 100644
--- a/models/stdp_nn_symm_synapse.h
+++ b/models/stdp_nn_symm_synapse.h
@@ -127,12 +127,12 @@ EndUserDocs */
void register_stdp_nn_symm_synapse( const std::string& name );
template < typename targetidentifierT >
-class stdp_nn_symm_synapse : public Connection< targetidentifierT >
+class stdp_nn_symm_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -156,7 +156,7 @@ class stdp_nn_symm_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -193,13 +193,13 @@ class stdp_nn_symm_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -254,7 +254,7 @@ stdp_nn_symm_synapse< targetidentifierT >::send( Event& e, size_t t, const Commo
// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/stdp_pl_synapse_hom.h b/models/stdp_pl_synapse_hom.h
index b01a79c79d..257ee6f6ae 100644
--- a/models/stdp_pl_synapse_hom.h
+++ b/models/stdp_pl_synapse_hom.h
@@ -42,8 +42,8 @@ Synapse type for spike-timing dependent plasticity with power law
Description
+++++++++++
-``stdp_pl_synapse`` is a connector to create synapses with spike time
-dependent plasticity using homoegeneous parameters (as defined in [1]_).
+``stdp_pl_synapse_hom`` is a connector to create synapses with spike time
+dependent plasticity using homogeneous parameters (as defined in [1]_).
Parameters
++++++++++
@@ -131,12 +131,12 @@ class STDPPLHomCommonProperties : public CommonSynapseProperties
void register_stdp_pl_synapse_hom( const std::string& name );
template < typename targetidentifierT >
-class stdp_pl_synapse_hom : public Connection< targetidentifierT >
+class stdp_pl_synapse_hom : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef STDPPLHomCommonProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -159,7 +159,7 @@ class stdp_pl_synapse_hom : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -207,13 +207,13 @@ class stdp_pl_synapse_hom : public Connection< targetidentifierT >
* \param receptor_type The ID of the requested receptor type
*/
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -266,7 +266,7 @@ stdp_pl_synapse_hom< targetidentifierT >::send( Event& e, size_t t, const STDPPL
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ const double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
@@ -278,15 +278,17 @@ stdp_pl_synapse_hom< targetidentifierT >::send( Event& e, size_t t, const STDPPL
while ( start != finish )
{
minus_dt = t_lastspike_ - ( start->t_ + dendritic_delay );
- start++;
// get_history() should make sure that
// start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0
assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() );
weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt * cp.tau_plus_inv_ ), cp );
+
+ ++start;
}
// depression due to new pre-synaptic spike
- weight_ = depress_( weight_, target->get_K_value( t_spike - dendritic_delay ), cp );
+ const double K_minus = target->get_K_value( t_spike - dendritic_delay );
+ weight_ = depress_( weight_, K_minus, cp );
e.set_receiver( *target );
e.set_weight( weight_ );
diff --git a/models/stdp_pl_synapse_hom_ax_delay.cpp b/models/stdp_pl_synapse_hom_ax_delay.cpp
new file mode 100644
index 0000000000..cd20c81f2b
--- /dev/null
+++ b/models/stdp_pl_synapse_hom_ax_delay.cpp
@@ -0,0 +1,88 @@
+/*
+ * stdp_pl_synapse_hom_ax_delay.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 .
+ *
+ */
+
+#include "stdp_pl_synapse_hom_ax_delay.h"
+
+// Includes from nestkernel:
+#include "common_synapse_properties.h"
+#include "connector_model.h"
+#include "event.h"
+#include "nest_impl.h"
+
+// Includes from sli:
+#include "dictdatum.h"
+
+
+void
+nest::register_stdp_pl_synapse_hom_ax_delay( const std::string& name )
+{
+ register_connection_model< stdp_pl_synapse_hom_ax_delay >( name );
+}
+
+namespace nest
+{
+
+//
+// Implementation of class STDPPLHomAxDelayCommonProperties.
+//
+
+STDPPLHomAxDelayCommonProperties::STDPPLHomAxDelayCommonProperties()
+ : CommonSynapseProperties()
+ , tau_plus_( 20.0 )
+ , tau_plus_inv_( 1. / tau_plus_ )
+ , lambda_( 0.1 )
+ , alpha_( 1.0 )
+ , mu_( 0.4 )
+{
+}
+
+void
+STDPPLHomAxDelayCommonProperties::get_status( DictionaryDatum& d ) const
+{
+ CommonSynapseProperties::get_status( d );
+
+ def< double >( d, names::tau_plus, tau_plus_ );
+ def< double >( d, names::lambda, lambda_ );
+ def< double >( d, names::alpha, alpha_ );
+ def< double >( d, names::mu, mu_ );
+}
+
+void
+STDPPLHomAxDelayCommonProperties::set_status( const DictionaryDatum& d, ConnectorModel& cm )
+{
+ CommonSynapseProperties::set_status( d, cm );
+
+ updateValue< double >( d, names::tau_plus, tau_plus_ );
+ if ( tau_plus_ > 0. )
+ {
+ tau_plus_inv_ = 1. / tau_plus_;
+ }
+ else
+ {
+ throw BadProperty( "tau_plus > 0. required." );
+ }
+ updateValue< double >( d, names::lambda, lambda_ );
+ updateValue< double >( d, names::alpha, alpha_ );
+ updateValue< double >( d, names::mu, mu_ );
+}
+
+} // of namespace nest
diff --git a/models/stdp_pl_synapse_hom_ax_delay.h b/models/stdp_pl_synapse_hom_ax_delay.h
new file mode 100644
index 0000000000..a7489446c4
--- /dev/null
+++ b/models/stdp_pl_synapse_hom_ax_delay.h
@@ -0,0 +1,431 @@
+/*
+ * stdp_pl_synapse_hom_ax_delay.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 .
+ *
+ */
+
+#ifndef STDP_PL_SYNAPSE_HOM_AX_DELAY_H
+#define STDP_PL_SYNAPSE_HOM_AX_DELAY_H
+
+// C++ includes:
+#include
+
+// Includes from nestkernel:
+#include "archiving_node.h"
+#include "connection.h"
+
+namespace nest
+{
+
+/* BeginUserDocs: synapse, spike-timing-dependent plasticity
+
+Short description
++++++++++++++++++
+
+Synapse type for spike-timing dependent plasticity with power law and both dendritic and axonal delays
+
+Description
++++++++++++
+
+``stdp_pl_synapse_hom_ax_delay`` is a connector to create synapses with spike time dependent plasticity using
+ homogeneous parameters (as defined in [1]_). Both axonal and dendritic delays can be specified for this model.
+
+Parameters
+++++++++++
+
+========= ====== ====================================================
+ tau_plus ms Time constant of STDP window, potentiation
+ (tau_minus defined in postsynaptic neuron)
+ lambda real Learning rate
+ alpha real Asymmetry parameter (scales depressing increments as
+ alpha*lambda)
+ mu real Weight dependence exponent, potentiation
+========= ====== ====================================================
+
+The parameters can only be set by SetDefaults and apply to all synapses of
+the model.
+
+.. warning::
+
+ This synaptic plasticity rule does not take
+ :ref:`precise spike timing ` into
+ account. When calculating the weight update, the precise spike time part
+ of the timestamp is ignored.
+
+References
+++++++++++
+
+.. [1] Morrison A, Aertsen A, Diesmann M. (2007) Spike-timing dependent
+ plasticity in balanced random netrks. Neural Computation,
+ 19(6):1437-1467. DOI: https://doi.org/10.1162/neco.2007.19.6.1437
+
+Transmits
++++++++++
+
+SpikeEvent
+
+See also
+++++++++
+
+stdp_synapse, tsodyks_synapse, static_synapse
+
+EndUserDocs */
+
+/**
+ * Class containing the common properties for all synapses of type
+ * stdp_pl_synapse_hom_ax_delay.
+ */
+class STDPPLHomAxDelayCommonProperties : public CommonSynapseProperties
+{
+
+public:
+ /**
+ * Default constructor.
+ * Sets all property values to defaults.
+ */
+ STDPPLHomAxDelayCommonProperties();
+
+ /**
+ * Get all properties and put them into a dictionary.
+ */
+ void get_status( DictionaryDatum& d ) const;
+
+ /**
+ * Set properties from the values given in dictionary.
+ */
+ void set_status( const DictionaryDatum& d, ConnectorModel& cm );
+
+ // data members common to all connections
+ double tau_plus_;
+ double tau_plus_inv_; //!< 1 / tau_plus for efficiency
+ double lambda_;
+ double alpha_;
+ double mu_;
+};
+
+/**
+ * Class representing an STDP connection with homogeneous parameters, i.e. parameters are the same for all synapses.
+ */
+void register_stdp_pl_synapse_hom_ax_delay( const std::string& name );
+
+/**
+ * Class representing an STDP connection with homogeneous parameters, i.e.
+ * parameters are the same for all synapses.
+ */
+template < typename targetidentifierT >
+class stdp_pl_synapse_hom_ax_delay : public Connection< targetidentifierT, AxonalDendriticDelay >
+{
+
+public:
+ typedef STDPPLHomAxDelayCommonProperties CommonPropertiesType;
+ typedef Connection< targetidentifierT, AxonalDendriticDelay > ConnectionBase;
+
+ static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
+ | ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
+ | ConnectionModelProperties::SUPPORTS_LBL;
+
+ /**
+ * Default Constructor.
+ * Sets default values for all parameters. Needed by GenericConnectorModel.
+ */
+ stdp_pl_synapse_hom_ax_delay();
+
+ /**
+ * Copy constructor from a property object.
+ * Needs to be defined properly in order for GenericConnector to work.
+ */
+ stdp_pl_synapse_hom_ax_delay( const stdp_pl_synapse_hom_ax_delay& ) = default;
+ stdp_pl_synapse_hom_ax_delay& operator=( const stdp_pl_synapse_hom_ax_delay& ) = default;
+
+ // Explicitly declare all methods inherited from the dependent base
+ // ConnectionBase. This avoids explicit name prefixes in all places these
+ // functions are used. Since ConnectionBase depends on the template parameter,
+ // they are not automatically found in the base class.
+ using ConnectionBase::get_axonal_delay_ms;
+ using ConnectionBase::get_axonal_delay_steps;
+ using ConnectionBase::get_delay_steps;
+ using ConnectionBase::get_dendritic_delay_ms;
+ using ConnectionBase::get_dendritic_delay_steps;
+ using ConnectionBase::get_rport;
+ using ConnectionBase::get_target;
+
+ /**
+ * Get all properties of this connection and put them into a dictionary.
+ */
+ void get_status( DictionaryDatum& d ) const;
+
+ /**
+ * Set properties of this connection from the values given in dictionary.
+ */
+ void set_status( const DictionaryDatum& d, ConnectorModel& cm );
+
+ /**
+ * Send an event to the receiver of this connection.
+ * \param e The event to send
+ */
+ bool send( Event& e, size_t t, const STDPPLHomAxDelayCommonProperties& );
+
+ /**
+ * Framework for STDP with predominantly axonal delays:
+ * Correct this synapse and the corresponding previously sent spike
+ * taking into account a new post-synaptic spike.
+ */
+ void correct_synapse_stdp_ax_delay( const size_t tid,
+ const double t_last_spike,
+ double& weight_revert,
+ const double t_post_spike,
+ const STDPPLHomAxDelayCommonProperties& cp );
+
+ class ConnTestDummyNode : public ConnTestDummyNodeBase
+ {
+ public:
+ // Ensure proper overriding of overloaded virtual functions.
+ // Return values from functions are ignored.
+ using ConnTestDummyNodeBase::handles_test_event;
+ size_t
+ handles_test_event( SpikeEvent&, size_t ) override
+ {
+ return invalid_port;
+ }
+ };
+
+ /*
+ * This function calls check_connection on the sender and checks if the
+ * receiver accepts the event type and receptor type requested by the sender.
+ * Node::check_connection() will either confirm the receiver port by returning
+ * true or false if the connection should be ignored.
+ * We have to override the base class' implementation, since for STDP
+ * connections we have to call register_stdp_pl_connection on the target
+ * neuron to inform the Archiver to collect spikes for this connection.
+ *
+ * \param s The source node
+ * \param r The target node
+ * \param receptor_type The ID of the requested receptor type
+ */
+ void
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
+ {
+ if ( kernel().sp_manager.is_structural_plasticity_enabled() )
+ {
+ throw IllegalConnection( "Structural plasticity is not supported in combination with axonal delays." );
+ }
+
+ ConnTestDummyNode dummy_target;
+
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
+
+ if ( get_axonal_delay_ms() + get_dendritic_delay_ms() < kernel().connection_manager.get_stdp_eps() )
+ {
+ throw BadProperty( "Combination of axonal and dendritic delay has to be more than 0." );
+ }
+ t.register_stdp_connection( t_lastspike_ - get_dendritic_delay_ms() + get_axonal_delay_ms(),
+ get_dendritic_delay_ms(),
+ get_axonal_delay_ms() );
+
+ if ( get_axonal_delay_ms() >= get_dendritic_delay_ms() )
+ {
+ CorrectionSpikeEvent e;
+ t.handles_test_event( e, receptor_type );
+ }
+ }
+
+ void
+ set_weight( double w )
+ {
+ weight_ = w;
+ }
+
+private:
+ double
+ facilitate_( double w, double kplus, const STDPPLHomAxDelayCommonProperties& cp )
+ {
+ return w + ( cp.lambda_ * std::pow( w, cp.mu_ ) * kplus );
+ }
+
+ double
+ depress_( double w, double kminus, const STDPPLHomAxDelayCommonProperties& cp )
+ {
+ double new_w = w - ( cp.lambda_ * cp.alpha_ * w * kminus );
+ return new_w > 0.0 ? new_w : 0.0;
+ }
+
+ // data members of each connection
+ double weight_;
+ double Kplus_;
+ double t_lastspike_;
+};
+
+template < typename targetidentifierT >
+constexpr ConnectionModelProperties stdp_pl_synapse_hom_ax_delay< targetidentifierT >::properties;
+
+/**
+ * Send an event to the receiver of this connection.
+ * \param e The event to send
+ * \param p The port under which this connection is stored in the Connector.
+ */
+template < typename targetidentifierT >
+inline bool
+stdp_pl_synapse_hom_ax_delay< targetidentifierT >::send( Event& e,
+ size_t tid,
+ const STDPPLHomAxDelayCommonProperties& cp )
+{
+ // synapse STDP depressing/facilitation dynamics
+ const double axonal_delay_ms = get_axonal_delay_ms();
+ const double dendritic_delay_ms = get_dendritic_delay_ms();
+ const double t_spike = e.get_stamp().get_ms();
+
+ // t_lastspike_ = 0 initially
+ Node* target = get_target( tid );
+
+ // get spike history in relevant range (t1, t2] from postsynaptic neuron
+ std::deque< histentry >::iterator start;
+ std::deque< histentry >::iterator finish;
+ target->get_history( t_lastspike_ - dendritic_delay_ms + axonal_delay_ms,
+ t_spike - dendritic_delay_ms + axonal_delay_ms,
+ &start,
+ &finish );
+
+ // facilitation due to postsynaptic spikes since last pre-synaptic spike
+ double minus_dt;
+ while ( start != finish )
+ {
+ minus_dt = t_lastspike_ + axonal_delay_ms - ( start->t_ + dendritic_delay_ms );
+ // get_history() should make sure that
+ // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0
+ assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() );
+ weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt * cp.tau_plus_inv_ ), cp );
+ ++start;
+ }
+
+ // Framework for STDP with predominantly axonal delays:
+ // Store weight before depression for potential later correction
+ const double weight_revert = weight_;
+
+ // depression due to new pre-synaptic spike
+ const double K_minus = target->get_K_value( t_spike + axonal_delay_ms - dendritic_delay_ms );
+ weight_ = depress_( weight_, K_minus, cp );
+
+ e.set_receiver( *target );
+ e.set_weight( weight_ );
+ e.set_delay_steps( get_delay_steps() );
+ e.set_rport( get_rport() );
+ e();
+
+ // axonal_delay-dendritic_delay = total_delay-2*dendritic_delay
+ const long time_while_critical =
+ e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) - 2 * get_dendritic_delay_steps() + 1;
+ // Only add correction entry if there could potentially be any post-synaptic spike that occurs before the
+ // pre-synaptic one arrives at the synapse. Has to be strictly greater than min_delay, because a post-synaptic spike
+ // at time slice_origin+min_delay corresponds to the last update step in the current slice (before delivery) and was
+ // thus already known at time of delivery of the pre-synaptic one.
+ if ( time_while_critical > 0 )
+ {
+ static_cast< ArchivingNode* >( target )->add_correction_entry_stdp_ax_delay(
+ static_cast< SpikeEvent& >( e ), t_lastspike_, weight_revert, time_while_critical );
+ }
+
+ Kplus_ = Kplus_ * std::exp( ( t_lastspike_ - t_spike ) * cp.tau_plus_inv_ ) + 1.0;
+
+ t_lastspike_ = t_spike;
+
+ return true;
+}
+
+template < typename targetidentifierT >
+stdp_pl_synapse_hom_ax_delay< targetidentifierT >::stdp_pl_synapse_hom_ax_delay()
+ : ConnectionBase()
+ , weight_( 1.0 )
+ , Kplus_( 0.0 )
+ , t_lastspike_( 0.0 )
+{
+}
+
+template < typename targetidentifierT >
+void
+stdp_pl_synapse_hom_ax_delay< targetidentifierT >::get_status( DictionaryDatum& d ) const
+{
+
+ // base class properties, different for individual synapse
+ ConnectionBase::get_status( d );
+ def< double >( d, names::weight, weight_ );
+
+ // own properties, different for individual synapse
+ def< double >( d, names::Kplus, Kplus_ );
+ def< long >( d, names::size_of, sizeof( *this ) );
+}
+
+template < typename targetidentifierT >
+void
+stdp_pl_synapse_hom_ax_delay< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm )
+{
+ ConnectionBase::set_status( d, cm );
+ updateValue< double >( d, names::weight, weight_ );
+
+ updateValue< double >( d, names::Kplus, Kplus_ );
+}
+
+template < typename targetidentifierT >
+inline void
+stdp_pl_synapse_hom_ax_delay< targetidentifierT >::correct_synapse_stdp_ax_delay( const size_t tid,
+ const double t_last_spike,
+ double& weight_revert,
+ const double t_post_spike,
+ const STDPPLHomAxDelayCommonProperties& cp )
+{
+ const double t_spike = t_lastspike_; // no new pre-synaptic spike since last send()
+ const double wrong_weight = weight_; // incorrectly transmitted weight
+ weight_ = weight_revert; // removes the last depressive step
+ Node* target = get_target( tid );
+
+ const double axonal_delay_ms = get_axonal_delay_ms();
+ double dendritic_delay_ms = get_dendritic_delay_ms();
+
+ // facilitation due to new post-synaptic spike
+ const double minus_dt = t_last_spike + axonal_delay_ms - ( t_post_spike + dendritic_delay_ms );
+
+ double K_plus_revert;
+ // Only facilitate if not facilitated already (only if first correction for this post-spike)
+ if ( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() )
+ {
+ // Kplus value at t_last_spike_ needed
+ K_plus_revert = ( Kplus_ - 1.0 ) / std::exp( ( t_last_spike - t_spike ) * cp.tau_plus_inv_ );
+ weight_ = facilitate_( weight_, K_plus_revert * std::exp( minus_dt * cp.tau_plus_inv_ ), cp );
+
+ // update weight_revert in case further correction will be required later
+ weight_revert = weight_;
+ }
+
+ // depression taking into account new post-synaptic spike
+ const double K_minus = target->get_K_value( t_spike + axonal_delay_ms - dendritic_delay_ms );
+ weight_ = depress_( weight_, K_minus, cp );
+
+ // send a correcting event to the target neuron
+ CorrectionSpikeEvent e;
+ e.set_receiver( *target );
+ e.set_weight( wrong_weight );
+ e.set_new_weight( weight_ );
+ e.set_delay_steps( get_delay_steps() );
+ e.set_rport( get_rport() );
+ e.set_stamp( Time::ms_stamp( t_spike ) );
+ e();
+}
+
+} // of namespace nest
+
+#endif // of #ifndef STDP_PL_SYNAPSE_HOM_AX_DELAY_H
diff --git a/models/stdp_synapse.h b/models/stdp_synapse.h
index 61b3cbcafa..771a88dfbf 100644
--- a/models/stdp_synapse.h
+++ b/models/stdp_synapse.h
@@ -117,12 +117,12 @@ EndUserDocs */
void register_stdp_synapse( const std::string& name );
template < typename targetidentifierT >
-class stdp_synapse : public Connection< targetidentifierT >
+class stdp_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -146,7 +146,7 @@ class stdp_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -183,13 +183,13 @@ class stdp_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -245,7 +245,7 @@ stdp_synapse< targetidentifierT >::send( Event& e, size_t t, const CommonSynapse
// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/stdp_synapse_hom.h b/models/stdp_synapse_hom.h
index 803f513585..a8b8c9689f 100644
--- a/models/stdp_synapse_hom.h
+++ b/models/stdp_synapse_hom.h
@@ -157,12 +157,12 @@ class STDPHomCommonProperties : public CommonSynapseProperties
void register_stdp_synapse_hom( const std::string& name );
template < typename targetidentifierT >
-class stdp_synapse_hom : public Connection< targetidentifierT >
+class stdp_synapse_hom : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef STDPHomCommonProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -186,7 +186,7 @@ class stdp_synapse_hom : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -241,12 +241,12 @@ class stdp_synapse_hom : public Connection< targetidentifierT >
* \param receptor_type The ID of the requested receptor type
*/
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
private:
@@ -302,7 +302,7 @@ stdp_synapse_hom< targetidentifierT >::send( Event& e, size_t t, const STDPHomCo
// t_lastspike_ = 0 initially
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/stdp_triplet_synapse.h b/models/stdp_triplet_synapse.h
index f2a8f8ced3..ec8d265925 100644
--- a/models/stdp_triplet_synapse.h
+++ b/models/stdp_triplet_synapse.h
@@ -122,12 +122,12 @@ EndUserDocs */
void register_stdp_triplet_synapse( const std::string& name );
template < typename targetidentifierT >
-class stdp_triplet_synapse : public Connection< targetidentifierT >
+class stdp_triplet_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -157,7 +157,7 @@ class stdp_triplet_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places
// these functions are used. Since ConnectionBase depends on the template
// parameter, they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -206,13 +206,13 @@ class stdp_triplet_synapse : public Connection< targetidentifierT >
* \param receptor_type The ID of the requested receptor type
*/
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -264,7 +264,7 @@ inline bool
stdp_triplet_synapse< targetidentifierT >::send( Event& e, size_t t, const CommonSynapseProperties& )
{
double t_spike = e.get_stamp().get_ms();
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
Node* target = get_target( t );
// get spike history in relevant range (t1, t2] from postsynaptic neuron
diff --git a/models/step_current_generator.cpp b/models/step_current_generator.cpp
index d006dc30af..24f03f4303 100644
--- a/models/step_current_generator.cpp
+++ b/models/step_current_generator.cpp
@@ -49,28 +49,27 @@ RecordablesMap< step_current_generator >::create()
{
insert_( Name( names::I ), &step_current_generator::get_I_ );
}
-}
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::step_current_generator::Parameters_::Parameters_()
+step_current_generator::Parameters_::Parameters_()
: amp_time_stamps_()
, amp_values_() // pA
, allow_offgrid_amp_times_( false )
{
}
-nest::step_current_generator::Parameters_::Parameters_( const Parameters_& p )
+step_current_generator::Parameters_::Parameters_( const Parameters_& p )
: amp_time_stamps_( p.amp_time_stamps_ )
, amp_values_( p.amp_values_ )
, allow_offgrid_amp_times_( p.allow_offgrid_amp_times_ )
{
}
-nest::step_current_generator::Parameters_&
-nest::step_current_generator::Parameters_::operator=( const Parameters_& p )
+step_current_generator::Parameters_&
+step_current_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -84,19 +83,19 @@ nest::step_current_generator::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::step_current_generator::State_::State_()
+step_current_generator::State_::State_()
: I_( 0.0 ) // pA
{
}
-nest::step_current_generator::Buffers_::Buffers_( step_current_generator& n )
+step_current_generator::Buffers_::Buffers_( step_current_generator& n )
: idx_( 0 )
, amp_( 0 )
, logger_( n )
{
}
-nest::step_current_generator::Buffers_::Buffers_( const Buffers_&, step_current_generator& n )
+step_current_generator::Buffers_::Buffers_( const Buffers_&, step_current_generator& n )
: idx_( 0 )
, amp_( 0 )
, logger_( n )
@@ -108,7 +107,7 @@ nest::step_current_generator::Buffers_::Buffers_( const Buffers_&, step_current_
* ---------------------------------------------------------------- */
void
-nest::step_current_generator::Parameters_::get( DictionaryDatum& d ) const
+step_current_generator::Parameters_::get( DictionaryDatum& d ) const
{
std::vector< double >* times_ms = new std::vector< double >();
times_ms->reserve( amp_time_stamps_.size() );
@@ -121,8 +120,8 @@ nest::step_current_generator::Parameters_::get( DictionaryDatum& d ) const
( *d )[ names::allow_offgrid_times ] = BoolDatum( allow_offgrid_amp_times_ );
}
-nest::Time
-nest::step_current_generator::Parameters_::validate_time_( double t, const Time& t_previous )
+Time
+step_current_generator::Parameters_::validate_time_( double t, const Time& t_previous )
{
if ( t <= 0.0 )
{
@@ -166,7 +165,7 @@ nest::step_current_generator::Parameters_::validate_time_( double t, const Time&
}
void
-nest::step_current_generator::Parameters_::set( const DictionaryDatum& d, Buffers_& b, Node* )
+step_current_generator::Parameters_::set( const DictionaryDatum& d, Buffers_& b, Node* )
{
std::vector< double > new_times;
const bool times_changed = updateValue< std::vector< double > >( d, names::amplitude_times, new_times );
@@ -226,7 +225,7 @@ nest::step_current_generator::Parameters_::set( const DictionaryDatum& d, Buffer
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::step_current_generator::step_current_generator()
+step_current_generator::step_current_generator()
: StimulationDevice()
, P_()
, S_()
@@ -235,7 +234,7 @@ nest::step_current_generator::step_current_generator()
recordablesMap_.create();
}
-nest::step_current_generator::step_current_generator( const step_current_generator& n )
+step_current_generator::step_current_generator( const step_current_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -249,13 +248,13 @@ nest::step_current_generator::step_current_generator( const step_current_generat
* ---------------------------------------------------------------- */
void
-nest::step_current_generator::init_state_()
+step_current_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::step_current_generator::init_buffers_()
+step_current_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
@@ -265,7 +264,7 @@ nest::step_current_generator::init_buffers_()
}
void
-nest::step_current_generator::pre_run_hook()
+step_current_generator::pre_run_hook()
{
B_.logger_.init();
StimulationDevice::pre_run_hook();
@@ -277,7 +276,7 @@ nest::step_current_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::step_current_generator::update( Time const& origin, const long from, const long to )
+step_current_generator::update( Time const& origin, const long from, const long to )
{
assert( P_.amp_time_stamps_.size() == P_.amp_values_.size() );
@@ -319,7 +318,7 @@ nest::step_current_generator::update( Time const& origin, const long from, const
}
void
-nest::step_current_generator::handle( DataLoggingRequest& e )
+step_current_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
@@ -328,7 +327,7 @@ nest::step_current_generator::handle( DataLoggingRequest& e )
* Other functions
* ---------------------------------------------------------------- */
void
-nest::step_current_generator::set_data_from_stimulation_backend( std::vector< double >& time_amplitude )
+step_current_generator::set_data_from_stimulation_backend( std::vector< double >& time_amplitude )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -367,3 +366,5 @@ nest::step_current_generator::set_data_from_stimulation_backend( std::vector< do
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/step_rate_generator.cpp b/models/step_rate_generator.cpp
index dfe104987d..379df77866 100644
--- a/models/step_rate_generator.cpp
+++ b/models/step_rate_generator.cpp
@@ -49,28 +49,27 @@ RecordablesMap< step_rate_generator >::create()
{
insert_( Name( names::rate ), &step_rate_generator::get_rate_ );
}
-}
/* ----------------------------------------------------------------
* Default constructors defining default parameter
* ---------------------------------------------------------------- */
-nest::step_rate_generator::Parameters_::Parameters_()
+step_rate_generator::Parameters_::Parameters_()
: amp_time_stamps_()
, amp_values_() // pA
, allow_offgrid_amp_times_( false )
{
}
-nest::step_rate_generator::Parameters_::Parameters_( const Parameters_& p )
+step_rate_generator::Parameters_::Parameters_( const Parameters_& p )
: amp_time_stamps_( p.amp_time_stamps_ )
, amp_values_( p.amp_values_ )
, allow_offgrid_amp_times_( p.allow_offgrid_amp_times_ )
{
}
-nest::step_rate_generator::Parameters_&
-nest::step_rate_generator::Parameters_::operator=( const Parameters_& p )
+step_rate_generator::Parameters_&
+step_rate_generator::Parameters_::operator=( const Parameters_& p )
{
if ( this == &p )
{
@@ -84,19 +83,19 @@ nest::step_rate_generator::Parameters_::operator=( const Parameters_& p )
return *this;
}
-nest::step_rate_generator::State_::State_()
+step_rate_generator::State_::State_()
: rate_( 0.0 )
{
}
-nest::step_rate_generator::Buffers_::Buffers_( step_rate_generator& n )
+step_rate_generator::Buffers_::Buffers_( step_rate_generator& n )
: idx_( 0 )
, amp_( 0 )
, logger_( n )
{
}
-nest::step_rate_generator::Buffers_::Buffers_( const Buffers_&, step_rate_generator& n )
+step_rate_generator::Buffers_::Buffers_( const Buffers_&, step_rate_generator& n )
: idx_( 0 )
, amp_( 0 )
, logger_( n )
@@ -108,7 +107,7 @@ nest::step_rate_generator::Buffers_::Buffers_( const Buffers_&, step_rate_genera
* ---------------------------------------------------------------- */
void
-nest::step_rate_generator::Parameters_::get( DictionaryDatum& d ) const
+step_rate_generator::Parameters_::get( DictionaryDatum& d ) const
{
std::vector< double >* times_ms = new std::vector< double >();
times_ms->reserve( amp_time_stamps_.size() );
@@ -121,8 +120,8 @@ nest::step_rate_generator::Parameters_::get( DictionaryDatum& d ) const
( *d )[ names::allow_offgrid_times ] = BoolDatum( allow_offgrid_amp_times_ );
}
-nest::Time
-nest::step_rate_generator::Parameters_::validate_time_( double t, const Time& t_previous )
+Time
+step_rate_generator::Parameters_::validate_time_( double t, const Time& t_previous )
{
if ( t <= 0.0 )
{
@@ -166,7 +165,7 @@ nest::step_rate_generator::Parameters_::validate_time_( double t, const Time& t_
}
void
-nest::step_rate_generator::Parameters_::set( const DictionaryDatum& d, Buffers_& b, Node* )
+step_rate_generator::Parameters_::set( const DictionaryDatum& d, Buffers_& b, Node* )
{
std::vector< double > new_times;
const bool times_changed = updateValue< std::vector< double > >( d, names::amplitude_times, new_times );
@@ -226,7 +225,7 @@ nest::step_rate_generator::Parameters_::set( const DictionaryDatum& d, Buffers_&
* Default and copy constructor for node
* ---------------------------------------------------------------- */
-nest::step_rate_generator::step_rate_generator()
+step_rate_generator::step_rate_generator()
: StimulationDevice()
, P_()
, S_()
@@ -235,7 +234,7 @@ nest::step_rate_generator::step_rate_generator()
recordablesMap_.create();
}
-nest::step_rate_generator::step_rate_generator( const step_rate_generator& n )
+step_rate_generator::step_rate_generator( const step_rate_generator& n )
: StimulationDevice( n )
, P_( n.P_ )
, S_( n.S_ )
@@ -249,13 +248,13 @@ nest::step_rate_generator::step_rate_generator( const step_rate_generator& n )
* ---------------------------------------------------------------- */
void
-nest::step_rate_generator::init_state_()
+step_rate_generator::init_state_()
{
StimulationDevice::init_state();
}
void
-nest::step_rate_generator::init_buffers_()
+step_rate_generator::init_buffers_()
{
StimulationDevice::init_buffers();
B_.logger_.reset();
@@ -265,7 +264,7 @@ nest::step_rate_generator::init_buffers_()
}
void
-nest::step_rate_generator::pre_run_hook()
+step_rate_generator::pre_run_hook()
{
B_.logger_.init();
@@ -278,7 +277,7 @@ nest::step_rate_generator::pre_run_hook()
* ---------------------------------------------------------------- */
void
-nest::step_rate_generator::update( Time const& origin, const long from, const long to )
+step_rate_generator::update( Time const& origin, const long from, const long to )
{
assert( P_.amp_time_stamps_.size() == P_.amp_values_.size() );
@@ -332,7 +331,7 @@ nest::step_rate_generator::update( Time const& origin, const long from, const lo
}
void
-nest::step_rate_generator::handle( DataLoggingRequest& e )
+step_rate_generator::handle( DataLoggingRequest& e )
{
B_.logger_.handle( e );
}
@@ -341,7 +340,7 @@ nest::step_rate_generator::handle( DataLoggingRequest& e )
* Other functions
* ---------------------------------------------------------------- */
void
-nest::step_rate_generator::set_data_from_stimulation_backend( std::vector< double >& time_amplitude )
+step_rate_generator::set_data_from_stimulation_backend( std::vector< double >& time_amplitude )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -380,3 +379,5 @@ nest::step_rate_generator::set_data_from_stimulation_backend( std::vector< doubl
// if we get here, temporary contains consistent set of properties
P_ = ptmp;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/models/tanh_rate.cpp b/models/tanh_rate.cpp
index c1a41cb679..911da5cf24 100644
--- a/models/tanh_rate.cpp
+++ b/models/tanh_rate.cpp
@@ -68,29 +68,29 @@ nonlinearities_tanh_rate::set( const DictionaryDatum& d, Node* node )
*/
template <>
void
-RecordablesMap< nest::tanh_rate_ipn >::create()
+RecordablesMap< tanh_rate_ipn >::create()
{
// use standard names wherever you can for consistency!
- insert_( names::rate, &nest::tanh_rate_ipn::get_rate_ );
- insert_( names::noise, &nest::tanh_rate_ipn::get_noise_ );
+ insert_( names::rate, &tanh_rate_ipn::get_rate_ );
+ insert_( names::noise, &tanh_rate_ipn::get_noise_ );
}
template <>
void
-RecordablesMap< nest::tanh_rate_opn >::create()
+RecordablesMap< tanh_rate_opn >::create()
{
// use standard names wherever you can for consistency!
- insert_( names::rate, &nest::tanh_rate_opn::get_rate_ );
- insert_( names::noise, &nest::tanh_rate_opn::get_noise_ );
- insert_( names::noisy_rate, &nest::tanh_rate_opn::get_noisy_rate_ );
+ insert_( names::rate, &tanh_rate_opn::get_rate_ );
+ insert_( names::noise, &tanh_rate_opn::get_noise_ );
+ insert_( names::noisy_rate, &tanh_rate_opn::get_noisy_rate_ );
}
template <>
void
-RecordablesMap< nest::rate_transformer_tanh >::create()
+RecordablesMap< rate_transformer_tanh >::create()
{
// use standard names wherever you can for consistency!
- insert_( names::rate, &nest::rate_transformer_tanh::get_rate_ );
+ insert_( names::rate, &rate_transformer_tanh::get_rate_ );
}
} // namespace nest
diff --git a/models/tsodyks2_synapse.h b/models/tsodyks2_synapse.h
index a57f300244..cf64aea9a6 100644
--- a/models/tsodyks2_synapse.h
+++ b/models/tsodyks2_synapse.h
@@ -119,11 +119,11 @@ EndUserDocs */
void register_tsodyks2_synapse( const std::string& name );
template < typename targetidentifierT >
-class tsodyks2_synapse : public Connection< targetidentifierT >
+class tsodyks2_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -153,7 +153,7 @@ class tsodyks2_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -190,10 +190,10 @@ class tsodyks2_synapse : public Connection< targetidentifierT >
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
void
diff --git a/models/tsodyks_synapse.h b/models/tsodyks_synapse.h
index bb6c1e3938..3dfb0bab31 100644
--- a/models/tsodyks_synapse.h
+++ b/models/tsodyks_synapse.h
@@ -139,11 +139,11 @@ EndUserDocs */
void register_tsodyks_synapse( const std::string& name );
template < typename targetidentifierT >
-class tsodyks_synapse : public Connection< targetidentifierT >
+class tsodyks_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -173,7 +173,7 @@ class tsodyks_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -209,10 +209,10 @@ class tsodyks_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
void
diff --git a/models/tsodyks_synapse_hom.h b/models/tsodyks_synapse_hom.h
index e01c49f04b..b97c9fc4e9 100644
--- a/models/tsodyks_synapse_hom.h
+++ b/models/tsodyks_synapse_hom.h
@@ -173,11 +173,11 @@ class TsodyksHomCommonProperties : public CommonPropertiesHomW
void register_tsodyks_synapse_hom( const std::string& name );
template < typename targetidentifierT >
-class tsodyks_synapse_hom : public Connection< targetidentifierT >
+class tsodyks_synapse_hom : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef TsodyksHomCommonProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -242,10 +242,10 @@ class tsodyks_synapse_hom : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
}
void
diff --git a/models/urbanczik_synapse.h b/models/urbanczik_synapse.h
index 04fcd05d06..3ef6f72a0f 100644
--- a/models/urbanczik_synapse.h
+++ b/models/urbanczik_synapse.h
@@ -111,12 +111,12 @@ EndUserDocs */
void register_urbanczik_synapse( const std::string& name );
template < typename targetidentifierT >
-class urbanczik_synapse : public Connection< targetidentifierT >
+class urbanczik_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::REQUIRES_URBANCZIK_ARCHIVING
@@ -141,7 +141,7 @@ class urbanczik_synapse : public Connection< targetidentifierT >
// ConnectionBase. This avoids explicit name prefixes in all places these
// functions are used. Since ConnectionBase depends on the template parameter,
// they are not automatically found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -178,13 +178,13 @@ class urbanczik_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -225,7 +225,7 @@ urbanczik_synapse< targetidentifierT >::send( Event& e, size_t t, const CommonSy
double t_spike = e.get_stamp().get_ms();
// use accessor functions (inherited from Connection< >) to obtain delay and target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry_extended >::iterator start;
diff --git a/models/vogels_sprekeler_synapse.h b/models/vogels_sprekeler_synapse.h
index cf30380486..f7ddd4ddb5 100644
--- a/models/vogels_sprekeler_synapse.h
+++ b/models/vogels_sprekeler_synapse.h
@@ -92,12 +92,12 @@ EndUserDocs */
void register_vogels_sprekeler_synapse( const std::string& name );
template < typename targetidentifierT >
-class vogels_sprekeler_synapse : public Connection< targetidentifierT >
+class vogels_sprekeler_synapse : public Connection< targetidentifierT, TotalDelay >
{
public:
typedef CommonSynapseProperties CommonPropertiesType;
- typedef Connection< targetidentifierT > ConnectionBase;
+ typedef Connection< targetidentifierT, TotalDelay > ConnectionBase;
static constexpr ConnectionModelProperties properties = ConnectionModelProperties::HAS_DELAY
| ConnectionModelProperties::IS_PRIMARY | ConnectionModelProperties::SUPPORTS_HPC
@@ -123,7 +123,7 @@ class vogels_sprekeler_synapse : public Connection< targetidentifierT >
// Since ConnectionBase depends on the template parameter, they are not
// automatically
// found in the base class.
- using ConnectionBase::get_delay;
+ using ConnectionBase::get_delay_ms;
using ConnectionBase::get_delay_steps;
using ConnectionBase::get_rport;
using ConnectionBase::get_target;
@@ -161,13 +161,13 @@ class vogels_sprekeler_synapse : public Connection< targetidentifierT >
};
void
- check_connection( Node& s, Node& t, size_t receptor_type, const CommonPropertiesType& )
+ check_connection( Node& s, Node& t, const size_t receptor_type, const synindex syn_id, const CommonPropertiesType& )
{
ConnTestDummyNode dummy_target;
- ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
+ ConnectionBase::check_connection_( dummy_target, s, t, syn_id, receptor_type );
- t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() );
+ t.register_stdp_connection( t_lastspike_ - get_delay_ms(), get_delay_ms(), 0 );
}
void
@@ -223,7 +223,7 @@ vogels_sprekeler_synapse< targetidentifierT >::send( Event& e, size_t t, const C
// use accessor functions (inherited from Connection< >) to obtain delay and
// target
Node* target = get_target( t );
- double dendritic_delay = get_delay();
+ double dendritic_delay = get_delay_ms();
// get spike history in relevant range (t1, t2] from postsynaptic neuron
std::deque< histentry >::iterator start;
diff --git a/models/volume_transmitter.cpp b/models/volume_transmitter.cpp
index 659838b288..aa390aa45f 100644
--- a/models/volume_transmitter.cpp
+++ b/models/volume_transmitter.cpp
@@ -37,18 +37,20 @@
// Includes from sli:
#include "dictutils.h"
+namespace nest
+{
+
void
-nest::register_volume_transmitter( const std::string& name )
+register_volume_transmitter( const std::string& name )
{
register_node_model< volume_transmitter >( name );
}
-
/* ----------------------------------------------------------------
* Default constructor defining default parameters
* ---------------------------------------------------------------- */
-nest::volume_transmitter::Parameters_::Parameters_()
+volume_transmitter::Parameters_::Parameters_()
: deliver_interval_( 1 ) // in steps of mindelay
{
}
@@ -58,12 +60,13 @@ nest::volume_transmitter::Parameters_::Parameters_()
* ---------------------------------------------------------------- */
void
-nest::volume_transmitter::Parameters_::get( DictionaryDatum& d ) const
+volume_transmitter::Parameters_::get( DictionaryDatum& d ) const
{
def< long >( d, names::deliver_interval, deliver_interval_ );
}
-void ::nest::volume_transmitter::Parameters_::set( const DictionaryDatum& d, Node* node )
+void
+volume_transmitter::Parameters_::set( const DictionaryDatum& d, Node* node )
{
updateValueParam< long >( d, names::deliver_interval, deliver_interval_, node );
}
@@ -72,14 +75,14 @@ void ::nest::volume_transmitter::Parameters_::set( const DictionaryDatum& d, Nod
* Default and copy constructor for volume transmitter
* ---------------------------------------------------------------- */
-nest::volume_transmitter::volume_transmitter()
+volume_transmitter::volume_transmitter()
: Node()
, P_()
, local_device_id_( 0 )
{
}
-nest::volume_transmitter::volume_transmitter( const volume_transmitter& n )
+volume_transmitter::volume_transmitter( const volume_transmitter& n )
: Node( n )
, P_( n.P_ )
, local_device_id_( n.local_device_id_ )
@@ -87,7 +90,7 @@ nest::volume_transmitter::volume_transmitter( const volume_transmitter& n )
}
void
-nest::volume_transmitter::init_buffers_()
+volume_transmitter::init_buffers_()
{
B_.neuromodulatory_spikes_.clear();
B_.spikecounter_.clear();
@@ -95,14 +98,14 @@ nest::volume_transmitter::init_buffers_()
}
void
-nest::volume_transmitter::pre_run_hook()
+volume_transmitter::pre_run_hook()
{
// +1 as pseudo dopa spike at t_trig is inserted after trigger_update_weight
B_.spikecounter_.reserve( kernel().connection_manager.get_min_delay() * P_.deliver_interval_ + 1 );
}
void
-nest::volume_transmitter::update( const Time&, const long from, const long to )
+volume_transmitter::update( const Time&, const long from, const long to )
{
// spikes that arrive in this time slice are stored in spikecounter_
double t_spike;
@@ -139,8 +142,10 @@ nest::volume_transmitter::update( const Time&, const long from, const long to )
}
void
-nest::volume_transmitter::handle( SpikeEvent& e )
+volume_transmitter::handle( SpikeEvent& e )
{
B_.neuromodulatory_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ),
static_cast< double >( e.get_multiplicity() ) );
}
+
+}
\ No newline at end of file
diff --git a/models/weight_recorder.cpp b/models/weight_recorder.cpp
index 33f1fef67d..234fc469fe 100644
--- a/models/weight_recorder.cpp
+++ b/models/weight_recorder.cpp
@@ -39,34 +39,36 @@
#include "dict.h"
#include "dictutils.h"
+namespace nest
+{
+
void
-nest::register_weight_recorder( const std::string& name )
+register_weight_recorder( const std::string& name )
{
register_node_model< weight_recorder >( name );
}
-
// record time, node ID, weight and receiver node ID
-nest::weight_recorder::weight_recorder()
+weight_recorder::weight_recorder()
: RecordingDevice()
, P_()
{
}
-nest::weight_recorder::weight_recorder( const weight_recorder& n )
+weight_recorder::weight_recorder( const weight_recorder& n )
: RecordingDevice( n )
, P_( n.P_ )
{
}
-nest::weight_recorder::Parameters_::Parameters_()
+weight_recorder::Parameters_::Parameters_()
: senders_()
, targets_()
{
}
void
-nest::weight_recorder::Parameters_::get( DictionaryDatum& d ) const
+weight_recorder::Parameters_::get( DictionaryDatum& d ) const
{
if ( senders_.get() )
{
@@ -89,7 +91,7 @@ nest::weight_recorder::Parameters_::get( DictionaryDatum& d ) const
}
void
-nest::weight_recorder::Parameters_::set( const DictionaryDatum& d )
+weight_recorder::Parameters_::set( const DictionaryDatum& d )
{
if ( d->known( names::senders ) )
{
@@ -137,25 +139,24 @@ nest::weight_recorder::Parameters_::set( const DictionaryDatum& d )
}
void
-nest::weight_recorder::pre_run_hook()
+weight_recorder::pre_run_hook()
{
- RecordingDevice::pre_run_hook(
- { nest::names::weights }, { nest::names::targets, nest::names::receptors, nest::names::ports } );
+ RecordingDevice::pre_run_hook( { names::weights }, { names::targets, names::receptors, names::ports } );
}
void
-nest::weight_recorder::update( Time const&, const long, const long )
+weight_recorder::update( Time const&, const long, const long )
{
}
-nest::RecordingDevice::Type
-nest::weight_recorder::get_type() const
+RecordingDevice::Type
+weight_recorder::get_type() const
{
return RecordingDevice::WEIGHT_RECORDER;
}
void
-nest::weight_recorder::get_status( DictionaryDatum& d ) const
+weight_recorder::get_status( DictionaryDatum& d ) const
{
// get the data from the device
RecordingDevice::get_status( d );
@@ -181,7 +182,7 @@ nest::weight_recorder::get_status( DictionaryDatum& d ) const
}
void
-nest::weight_recorder::set_status( const DictionaryDatum& d )
+weight_recorder::set_status( const DictionaryDatum& d )
{
Parameters_ ptmp = P_;
ptmp.set( d );
@@ -192,7 +193,7 @@ nest::weight_recorder::set_status( const DictionaryDatum& d )
void
-nest::weight_recorder::handle( WeightRecorderEvent& e )
+weight_recorder::handle( WeightRecorderEvent& e )
{
// accept spikes only if recorder was active when spike was emitted
if ( is_active( e.get_stamp() ) )
@@ -212,3 +213,5 @@ nest::weight_recorder::handle( WeightRecorderEvent& e )
static_cast< long >( e.get_port() ) } );
}
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/modelsets/full b/modelsets/full
index 46d6c6ee5a..422b595f5b 100644
--- a/modelsets/full
+++ b/modelsets/full
@@ -118,6 +118,7 @@ stdp_nn_pre_centered_synapse
stdp_nn_restr_synapse
stdp_nn_symm_synapse
stdp_pl_synapse_hom
+stdp_pl_synapse_hom_ax_delay
stdp_synapse
stdp_facetshw_synapse_hom
stdp_synapse_hom
diff --git a/nestkernel/CMakeLists.txt b/nestkernel/CMakeLists.txt
index ab3257a89f..b24f2420b3 100644
--- a/nestkernel/CMakeLists.txt
+++ b/nestkernel/CMakeLists.txt
@@ -30,7 +30,7 @@ set ( nestkernel_sources
connection.h
connection_label.h
common_properties_hom_w.h
- syn_id_delay.h
+ delay_types.h
connector_base.h connector_base_impl.h
connector_model.h connector_model_impl.h connector_model.cpp
connection_id.h connection_id.cpp
diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp
index 7ad511eb3c..eb0484389d 100644
--- a/nestkernel/archiving_node.cpp
+++ b/nestkernel/archiving_node.cpp
@@ -33,7 +33,7 @@ namespace nest
// member functions for ArchivingNode
-nest::ArchivingNode::ArchivingNode()
+ArchivingNode::ArchivingNode()
: n_incoming_( 0 )
, Kminus_( 0.0 )
, Kminus_triplet_( 0.0 )
@@ -44,10 +44,14 @@ nest::ArchivingNode::ArchivingNode()
, max_delay_( 0 )
, trace_( 0.0 )
, last_spike_( -1.0 )
+ , has_predominant_stdp_ax_delay_( false )
{
+ const size_t num_time_slots =
+ kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay();
+ correction_entries_stdp_ax_delay_.resize( num_time_slots );
}
-nest::ArchivingNode::ArchivingNode( const ArchivingNode& n )
+ArchivingNode::ArchivingNode( const ArchivingNode& n )
: StructuralPlasticityNode( n )
, n_incoming_( n.n_incoming_ )
, Kminus_( n.Kminus_ )
@@ -59,17 +63,42 @@ nest::ArchivingNode::ArchivingNode( const ArchivingNode& n )
, max_delay_( n.max_delay_ )
, trace_( n.trace_ )
, last_spike_( n.last_spike_ )
+ , has_predominant_stdp_ax_delay_( false )
{
+ const size_t num_time_slots =
+ kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay();
+ correction_entries_stdp_ax_delay_.resize( num_time_slots );
}
void
-ArchivingNode::register_stdp_connection( double t_first_read, double delay )
+ArchivingNode::pre_run_hook_()
+{
+ if ( has_predominant_stdp_ax_delay_ )
+ {
+ const size_t num_time_slots =
+ kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay();
+ if ( correction_entries_stdp_ax_delay_.size() != num_time_slots )
+ {
+ correction_entries_stdp_ax_delay_.resize( num_time_slots );
+ }
+ }
+}
+
+void
+ArchivingNode::register_stdp_connection( const double t_first_read,
+ const double dendritic_delay,
+ const double axonal_delay )
{
// Mark all entries in the deque, which we will not read in future as read by
// this input, so that we safely increment the incoming number of
// connections afterwards without leaving spikes in the history.
// For details see bug #218. MH 08-04-22
+ if ( axonal_delay >= dendritic_delay )
+ {
+ has_predominant_stdp_ax_delay_ = true;
+ }
+
for ( std::deque< histentry >::iterator runner = history_.begin();
runner != history_.end() and ( t_first_read - runner->t_ > -1.0 * kernel().connection_manager.get_stdp_eps() );
++runner )
@@ -79,11 +108,11 @@ ArchivingNode::register_stdp_connection( double t_first_read, double delay )
n_incoming_++;
- max_delay_ = std::max( delay, max_delay_ );
+ max_delay_ = std::max( dendritic_delay + axonal_delay, max_delay_ );
}
double
-nest::ArchivingNode::get_K_value( double t )
+ArchivingNode::get_K_value( double t )
{
// case when the neuron has not yet spiked
if ( history_.empty() )
@@ -92,8 +121,7 @@ nest::ArchivingNode::get_K_value( double t )
return trace_;
}
- // search for the latest post spike in the history buffer that came strictly
- // before `t`
+ // search for the latest post spike in the history buffer that came strictly before `t`
int i = history_.size() - 1;
while ( i >= 0 )
{
@@ -112,10 +140,7 @@ nest::ArchivingNode::get_K_value( double t )
}
void
-nest::ArchivingNode::get_K_values( double t,
- double& K_value,
- double& nearest_neighbor_K_value,
- double& K_triplet_value )
+ArchivingNode::get_K_values( double t, double& K_value, double& nearest_neighbor_K_value, double& K_triplet_value )
{
// case when the neuron has not yet spiked
if ( history_.empty() )
@@ -150,7 +175,7 @@ nest::ArchivingNode::get_K_values( double t,
}
void
-nest::ArchivingNode::get_history( double t1,
+ArchivingNode::get_history( double t1,
double t2,
std::deque< histentry >::iterator* start,
std::deque< histentry >::iterator* finish )
@@ -178,7 +203,7 @@ nest::ArchivingNode::get_history( double t1,
}
void
-nest::ArchivingNode::set_spiketime( Time const& t_sp, double offset )
+ArchivingNode::set_spiketime( Time const& t_sp, double offset )
{
StructuralPlasticityNode::set_spiketime( t_sp, offset );
@@ -216,10 +241,12 @@ nest::ArchivingNode::set_spiketime( Time const& t_sp, double offset )
{
last_spike_ = t_sp_ms;
}
+
+ correct_synapses_stdp_ax_delay_( t_sp );
}
void
-nest::ArchivingNode::get_status( DictionaryDatum& d ) const
+ArchivingNode::get_status( DictionaryDatum& d ) const
{
def< double >( d, names::t_spike, get_spiketime_ms() );
def< double >( d, names::tau_minus, tau_minus_ );
@@ -234,7 +261,7 @@ nest::ArchivingNode::get_status( DictionaryDatum& d ) const
}
void
-nest::ArchivingNode::set_status( const DictionaryDatum& d )
+ArchivingNode::set_status( const DictionaryDatum& d )
{
// We need to preserve values in case invalid values are set
double new_tau_minus = tau_minus_;
@@ -265,7 +292,7 @@ nest::ArchivingNode::set_status( const DictionaryDatum& d )
}
void
-nest::ArchivingNode::clear_history()
+ArchivingNode::clear_history()
{
last_spike_ = -1.0;
Kminus_ = 0.0;
@@ -273,5 +300,71 @@ nest::ArchivingNode::clear_history()
history_.clear();
}
+void
+ArchivingNode::add_correction_entry_stdp_ax_delay( SpikeEvent& spike_event,
+ const double t_last_pre_spike,
+ const double weight_revert,
+ const double time_while_critical )
+{
+ assert( correction_entries_stdp_ax_delay_.size()
+ == static_cast< size_t >(
+ kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay() ) );
+ const long idx = kernel().event_delivery_manager.get_modulo( time_while_critical - 1 );
+ assert( static_cast< size_t >( idx ) < correction_entries_stdp_ax_delay_.size() );
+
+ const SpikeData& spike_data = spike_event.get_sender_spike_data();
+ correction_entries_stdp_ax_delay_[ idx ].push_back(
+ CorrectionEntrySTDPAxDelay( spike_data.get_lcid(), spike_data.get_syn_id(), t_last_pre_spike, weight_revert ) );
+}
+
+void
+ArchivingNode::reset_correction_entries_stdp_ax_delay_()
+{
+ if ( has_predominant_stdp_ax_delay_ )
+ {
+ const long mindelay_steps = kernel().connection_manager.get_min_delay();
+ assert( correction_entries_stdp_ax_delay_.size()
+ == static_cast< size_t >( mindelay_steps + kernel().connection_manager.get_max_delay() ) );
+
+ for ( long lag = 0; lag < mindelay_steps; ++lag )
+ {
+ const long idx = kernel().event_delivery_manager.get_modulo( lag );
+ assert( static_cast< size_t >( idx ) < correction_entries_stdp_ax_delay_.size() );
+
+ std::vector< CorrectionEntrySTDPAxDelay >().swap( correction_entries_stdp_ax_delay_[ idx ] );
+ }
+ }
+}
+
+void
+ArchivingNode::correct_synapses_stdp_ax_delay_( const Time& t_spike )
+{
+ if ( has_predominant_stdp_ax_delay_ )
+ {
+ const Time& ori = kernel().simulation_manager.get_slice_origin();
+ const Time& t_spike_rel = t_spike - ori;
+ const long maxdelay_steps = kernel().connection_manager.get_max_delay();
+ assert( correction_entries_stdp_ax_delay_.size()
+ == static_cast< size_t >( kernel().connection_manager.get_min_delay() + maxdelay_steps ) );
+
+ for ( long lag = t_spike_rel.get_steps() - 1; lag < maxdelay_steps + 1; ++lag )
+ {
+ const long idx = kernel().event_delivery_manager.get_modulo( lag );
+ assert( static_cast< size_t >( idx ) < correction_entries_stdp_ax_delay_.size() );
+
+ for ( CorrectionEntrySTDPAxDelay& it_corr_entry : correction_entries_stdp_ax_delay_[ idx ] )
+ {
+ kernel().connection_manager.correct_synapse_stdp_ax_delay( get_thread(),
+ it_corr_entry.syn_id_,
+ it_corr_entry.lcid_,
+ it_corr_entry.t_last_pre_spike_,
+ it_corr_entry.weight_revert_,
+ t_spike.get_ms() );
+ }
+ // indicate that the new spike was processed by these STDP synapses
+ history_.back().access_counter_ += correction_entries_stdp_ax_delay_[ idx ].size();
+ }
+ }
+}
} // of namespace nest
diff --git a/nestkernel/archiving_node.h b/nestkernel/archiving_node.h
index 86b402ed1a..2e3778d569 100644
--- a/nestkernel/archiving_node.h
+++ b/nestkernel/archiving_node.h
@@ -92,12 +92,31 @@ class ArchivingNode : public StructuralPlasticityNode
* 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, double delay ) override;
+ void register_stdp_connection( const double t_first_read,
+ const double dendritic_delay,
+ const double axonal_delay ) override;
void get_status( DictionaryDatum& d ) const override;
void set_status( const DictionaryDatum& d ) override;
+ /**
+ * Framework for STDP with predominantly axonal delays: Buffer a correction entry for a short time window.
+ *
+ * @param spike_event Incoming pre-synaptic spike which could potentially need a correction after the next
+ * post-synaptic spike.
+ * @param t_last_pre_spike The time of the last pre-synaptic spike that was processed before the current one.
+ * @param weight_revert The synaptic weight before depression after facilitation as baseline for potential later
+ * correction.
+ * @param time_while_critical The number of time steps until the spike no longer needs to be corrected.
+ */
+ void add_correction_entry_stdp_ax_delay( SpikeEvent& spike_event,
+ const double t_last_pre_spike,
+ const double weight_revert,
+ const double time_while_critical );
+
protected:
+ void pre_run_hook_();
+
/**
* Record spike history
*/
@@ -113,6 +132,8 @@ class ArchivingNode : public StructuralPlasticityNode
*/
void clear_history();
+ void reset_correction_entries_stdp_ax_delay_();
+
/**
* Number of incoming connections from STDP connectors.
*
@@ -142,6 +163,51 @@ class ArchivingNode : public StructuralPlasticityNode
// spiking history needed by stdp synapses
std::deque< histentry > history_;
+
+ /**
+ * Framework for STDP with predominantly axonal delays:
+ * Due to the long axonal delays, relevant spikes of this neuron might not yet be available at the time when incoming
+ * synapses are updated (spike delivery). Therefore, for each spike received through an STDP synapse with
+ * predominantly axonal delay, information is stored for a short period of time allowing for retrospective correction
+ * of the synapse and the already delivered spike.
+ */
+ struct CorrectionEntrySTDPAxDelay
+ {
+ CorrectionEntrySTDPAxDelay( const size_t lcid,
+ const synindex syn_id,
+ const double t_last_pre_spike,
+ const double weight_revert )
+ : lcid_( lcid )
+ , syn_id_( syn_id )
+ , t_last_pre_spike_( t_last_pre_spike )
+ , weight_revert_( weight_revert )
+ {
+ }
+
+ unsigned int lcid_; //!< local connection index
+ synindex syn_id_; //!< synapse-type index
+ double t_last_pre_spike_; //!< time of the last pre-synaptic spike before this spike
+ double weight_revert_; //!< synaptic weight to revert to (STDP depression needs to be undone)
+ };
+
+ //! check for correct correction entry size
+ using correction_entry_size = StaticAssert< sizeof( ArchivingNode::CorrectionEntrySTDPAxDelay ) == 24 >::success;
+
+protected:
+ /**
+ * Framework for STDP with predominantly axonal delays:
+ * Buffer of correction entries sorted by t_spike_pre + delay
+ * (i.e., the actual arrival time at this neuron).
+ */
+ std::vector< std::vector< CorrectionEntrySTDPAxDelay > > correction_entries_stdp_ax_delay_;
+ //! false by default and set to true if any incoming connection has predominant axonal delays
+ bool has_predominant_stdp_ax_delay_;
+
+ /**
+ * Framework for STDP with predominantly axonal delays:
+ * Triggered when this neuron spikes, to correct all relevant incoming STDP synapses with predominantly axonal delays
+ * and corresponding received spikes. */
+ void correct_synapses_stdp_ax_delay_( const Time& t_spike );
};
inline double
diff --git a/nestkernel/common_synapse_properties.cpp b/nestkernel/common_synapse_properties.cpp
index 2a5053c0c3..c3ada8d3b7 100644
--- a/nestkernel/common_synapse_properties.cpp
+++ b/nestkernel/common_synapse_properties.cpp
@@ -25,7 +25,6 @@
// Includes from nestkernel:
#include "connector_model.h"
#include "nest_timeconverter.h"
-#include "nest_types.h"
#include "node.h"
// Includes from models:
diff --git a/nestkernel/common_synapse_properties.h b/nestkernel/common_synapse_properties.h
index fab02945c6..4605190f8c 100644
--- a/nestkernel/common_synapse_properties.h
+++ b/nestkernel/common_synapse_properties.h
@@ -27,7 +27,6 @@
#include "connector_model.h"
#include "nest_datums.h"
#include "nest_types.h"
-#include "node.h"
// Includes from sli:
#include "dictdatum.h"
@@ -39,6 +38,7 @@ namespace nest
// forward declarations
class weight_recorder;
class ConnectorModel;
+class Node;
class TimeConverter;
/**
@@ -104,7 +104,6 @@ CommonSynapseProperties::get_weight_recorder() const
return weight_recorder_;
}
-
} // of namespace nest
#endif
diff --git a/nestkernel/conn_builder.cpp b/nestkernel/conn_builder.cpp
index f70f00f0b4..8a8a858a41 100644
--- a/nestkernel/conn_builder.cpp
+++ b/nestkernel/conn_builder.cpp
@@ -28,16 +28,18 @@
// Includes from nestkernel:
#include "conn_builder_impl.h"
#include "conn_parameter.h"
+#include "connection.h"
#include "connection_manager.h"
+#include "delay_types.h"
#include "exceptions.h"
#include "kernel_manager.h"
#include "nest_names.h"
#include "node.h"
+#include "target_identifier.h"
#include "vp_manager_impl.h"
// Includes from sli:
#include "dict.h"
-#include "fdstream.h"
#include "name.h"
// Includes from C++:
@@ -146,15 +148,23 @@ nest::BipartiteConnBuilder::BipartiteConnBuilder( NodeCollectionPTR sources,
}
// Synapse-specific parameters that should be skipped when we set default synapse parameters
- skip_syn_params_ = {
- names::weight, names::delay, names::min_delay, names::max_delay, names::num_connections, names::synapse_model
- };
+ skip_syn_params_ = { names::weight,
+ names::delay,
+ names::dendritic_delay,
+ names::axonal_delay,
+ names::min_delay,
+ names::max_delay,
+ names::num_connections,
+ names::synapse_model };
default_weight_.resize( syn_specs.size() );
default_delay_.resize( syn_specs.size() );
- default_weight_and_delay_.resize( syn_specs.size() );
+ default_dendritic_delay_.resize( syn_specs.size() );
+ default_axonal_delay_.resize( syn_specs.size() );
weights_.resize( syn_specs.size() );
delays_.resize( syn_specs.size() );
+ dendritic_delays_.resize( syn_specs.size() );
+ axonal_delays_.resize( syn_specs.size() );
synapse_params_.resize( syn_specs.size() );
synapse_model_id_.resize( syn_specs.size() );
synapse_model_id_[ 0 ] = kernel().model_manager.get_synapse_model_id( "static_synapse" );
@@ -166,7 +176,7 @@ nest::BipartiteConnBuilder::BipartiteConnBuilder( NodeCollectionPTR sources,
auto syn_params = syn_specs[ synapse_indx ];
set_synapse_model_( syn_params, synapse_indx );
- set_default_weight_or_delay_( syn_params, synapse_indx );
+ set_default_weight_or_delays_( syn_params, synapse_indx );
DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id_[ synapse_indx ] );
@@ -186,6 +196,8 @@ nest::BipartiteConnBuilder::BipartiteConnBuilder( NodeCollectionPTR sources,
{
reset_weights_();
reset_delays_();
+ reset_dendritic_delays_();
+ reset_axonal_delays_();
for ( auto params : synapse_params_ )
{
@@ -214,6 +226,16 @@ nest::BipartiteConnBuilder::~BipartiteConnBuilder()
delete delay;
}
+ for ( auto delay : dendritic_delays_ )
+ {
+ delete delay;
+ }
+
+ for ( auto delay : axonal_delays_ )
+ {
+ delete delay;
+ }
+
for ( auto params : synapse_params_ )
{
for ( auto synapse_parameter : params )
@@ -311,6 +333,8 @@ nest::BipartiteConnBuilder::connect()
// call reset on all parameters
reset_weights_();
reset_delays_();
+ reset_dendritic_delays_();
+ reset_axonal_delays_();
for ( auto params : synapse_params_ )
{
@@ -397,45 +421,37 @@ nest::BipartiteConnBuilder::single_connect_( size_t snode_id, Node& target, size
{
update_param_dict_( snode_id, target, target_thread, rng, synapse_indx );
- if ( default_weight_and_delay_[ synapse_indx ] )
+ double delay = numerics::nan;
+ double dendritic_delay = numerics::nan;
+ double axonal_delay = numerics::nan;
+ double weight = numerics::nan;
+
+ if ( not default_delay_[ synapse_indx ] )
{
- kernel().connection_manager.connect( snode_id,
- &target,
- target_thread,
- synapse_model_id_[ synapse_indx ],
- param_dicts_[ synapse_indx ][ target_thread ] );
+ delay = delays_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target );
}
- else if ( default_weight_[ synapse_indx ] )
+ if ( not default_dendritic_delay_[ synapse_indx ] )
{
- kernel().connection_manager.connect( snode_id,
- &target,
- target_thread,
- synapse_model_id_[ synapse_indx ],
- param_dicts_[ synapse_indx ][ target_thread ],
- delays_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target ) );
+ dendritic_delay = dendritic_delays_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target );
}
- else if ( default_delay_[ synapse_indx ] )
+ if ( not default_axonal_delay_[ synapse_indx ] )
{
- kernel().connection_manager.connect( snode_id,
- &target,
- target_thread,
- synapse_model_id_[ synapse_indx ],
- param_dicts_[ synapse_indx ][ target_thread ],
- numerics::nan,
- weights_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target ) );
+ axonal_delay = axonal_delays_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target );
}
- else
+ if ( not default_weight_[ synapse_indx ] )
{
- const double delay = delays_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target );
- const double weight = weights_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target );
- kernel().connection_manager.connect( snode_id,
- &target,
- target_thread,
- synapse_model_id_[ synapse_indx ],
- param_dicts_[ synapse_indx ][ target_thread ],
- delay,
- weight );
+ weight = weights_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target );
}
+
+ kernel().connection_manager.connect( snode_id,
+ &target,
+ target_thread,
+ synapse_model_id_[ synapse_indx ],
+ param_dicts_[ synapse_indx ][ target_thread ],
+ delay,
+ dendritic_delay,
+ axonal_delay,
+ weight );
}
// We connect third-party only once per source-target pair, not per collocated synapse type
@@ -480,6 +496,22 @@ nest::BipartiteConnBuilder::all_parameters_scalar_() const
}
}
+ for ( auto delay : dendritic_delays_ )
+ {
+ if ( delay )
+ {
+ all_scalar = all_scalar and delay->is_scalar();
+ }
+ }
+
+ for ( auto delay : axonal_delays_ )
+ {
+ if ( delay )
+ {
+ all_scalar = all_scalar and delay->is_scalar();
+ }
+ }
+
for ( auto params : synapse_params_ )
{
for ( auto synapse_parameter : params )
@@ -517,22 +549,24 @@ nest::BipartiteConnBuilder::set_synapse_model_( DictionaryDatum syn_params, size
}
void
-nest::BipartiteConnBuilder::set_default_weight_or_delay_( DictionaryDatum syn_params, size_t synapse_indx )
+nest::BipartiteConnBuilder::set_default_weight_or_delays_( DictionaryDatum syn_params, size_t synapse_indx )
{
DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id_[ synapse_indx ] );
- // All synapse models have the possibility to set the delay (see SynIdDelay), but some have
+ // All synapse models have the possibility to set the delay, but some have
// homogeneous weights, hence it should be possible to set the delay without the weight.
default_weight_[ synapse_indx ] = not syn_params->known( names::weight );
- default_delay_[ synapse_indx ] = not syn_params->known( names::delay );
+ // Based on the synapse type, it must not be allowed to specify either the total delay or axonal or dendritic delay.
+ kernel().model_manager.check_valid_default_delay_parameters( synapse_model_id_[ synapse_indx ], syn_params );
- // If neither weight nor delay are given in the dict, we handle this separately. Important for
- // hom_w synapses, on which weight cannot be set. However, we use default weight and delay for
- // _all_ types of synapses.
- default_weight_and_delay_[ synapse_indx ] = ( default_weight_[ synapse_indx ] and default_delay_[ synapse_indx ] );
+ default_delay_[ synapse_indx ] = not syn_params->known( names::delay );
+ default_dendritic_delay_[ synapse_indx ] = not syn_params->known( names::dendritic_delay );
+ default_axonal_delay_[ synapse_indx ] = not syn_params->known( names::axonal_delay );
- if ( not default_weight_and_delay_[ synapse_indx ] )
+ // If neither weight nor delay are given in the dict, we handle this separately. Important for hom_w synapses, on
+ // which weight cannot be set. However, we use default weight and delay for _all_ types of synapses.
+ if ( not( default_weight_[ synapse_indx ] and default_delay_[ synapse_indx ] ) )
{
weights_[ synapse_indx ] = syn_params->known( names::weight )
? ConnParameter::create( ( *syn_params )[ names::weight ], kernel().vp_manager.get_num_threads() )
@@ -550,6 +584,22 @@ nest::BipartiteConnBuilder::set_default_weight_or_delay_( DictionaryDatum syn_pa
: ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel().vp_manager.get_num_threads() );
}
register_parameters_requiring_skipping_( *delays_[ synapse_indx ] );
+
+ if ( not default_dendritic_delay_[ synapse_indx ] )
+ {
+ dendritic_delays_[ synapse_indx ] = syn_params->known( names::dendritic_delay )
+ ? ConnParameter::create( ( *syn_params )[ names::dendritic_delay ], kernel().vp_manager.get_num_threads() )
+ : ConnParameter::create( ( *syn_defaults )[ names::dendritic_delay ], kernel().vp_manager.get_num_threads() );
+ register_parameters_requiring_skipping_( *dendritic_delays_[ synapse_indx ] );
+ }
+
+ if ( not default_axonal_delay_[ synapse_indx ] )
+ {
+ axonal_delays_[ synapse_indx ] = syn_params->known( names::axonal_delay )
+ ? ConnParameter::create( ( *syn_params )[ names::axonal_delay ], kernel().vp_manager.get_num_threads() )
+ : ConnParameter::create( ( *syn_defaults )[ names::axonal_delay ], kernel().vp_manager.get_num_threads() );
+ register_parameters_requiring_skipping_( *axonal_delays_[ synapse_indx ] );
+ }
}
void
@@ -650,6 +700,30 @@ nest::BipartiteConnBuilder::reset_delays_()
}
}
+void
+nest::BipartiteConnBuilder::reset_dendritic_delays_()
+{
+ for ( auto delay : dendritic_delays_ )
+ {
+ if ( delay )
+ {
+ delay->reset();
+ }
+ }
+}
+
+void
+nest::BipartiteConnBuilder::reset_axonal_delays_()
+{
+ for ( auto delay : axonal_delays_ )
+ {
+ if ( delay )
+ {
+ delay->reset();
+ }
+ }
+}
+
nest::ThirdInBuilder::ThirdInBuilder( NodeCollectionPTR sources,
NodeCollectionPTR third,
const DictionaryDatum& third_conn_spec,
@@ -1031,8 +1105,7 @@ nest::OneToOneBuilder::connect_()
}
catch ( std::exception& err )
{
- // We must create a new exception here, err's lifetime ends at
- // the end of the catch block.
+ // We must create a new exception here, err's lifetime ends at the end of the catch block.
exceptions_raised_.at( tid ) = std::shared_ptr< WrappedThreadException >( new WrappedThreadException( err ) );
}
}
diff --git a/nestkernel/conn_builder.h b/nestkernel/conn_builder.h
index 801d4bb355..7d24afc728 100644
--- a/nestkernel/conn_builder.h
+++ b/nestkernel/conn_builder.h
@@ -113,6 +113,26 @@ class BipartiteConnBuilder
return default_delay_[ 0 ];
}
+ bool
+ get_default_dendritic_delay() const
+ {
+ if ( synapse_model_id_.size() > 1 )
+ {
+ throw KernelException( "Can only retrieve default dendritic delay when one synapse per connection is used." );
+ }
+ return default_dendritic_delay_[ 0 ];
+ }
+
+ bool
+ get_default_axonal_delay() const
+ {
+ if ( synapse_model_id_.size() > 1 )
+ {
+ throw KernelException( "Can only retrieve default axonal delay when one synapse per connection is used." );
+ }
+ return default_axonal_delay_[ 0 ];
+ }
+
void set_synaptic_element_names( const std::string& pre_name, const std::string& post_name );
/**
@@ -252,18 +272,23 @@ class BipartiteConnBuilder
private:
typedef std::map< Name, ConnParameter* > ConnParameterMap;
- //! indicate that weight and delay should not be set per synapse
- std::vector< bool > default_weight_and_delay_;
-
//! indicate that weight should not be set per synapse
std::vector< bool > default_weight_;
- //! indicate that delay should not be set per synapse
+ //! indicate that total delay should not be set per synapse
std::vector< bool > default_delay_;
+ //! indicate that dendritic delay should not be set per synapse
+ std::vector< bool > default_dendritic_delay_;
+
+ //! indicate that axonal delay should not be set per synapse
+ std::vector< bool > default_axonal_delay_;
+
// null-pointer indicates that default be used
std::vector< ConnParameter* > weights_;
std::vector< ConnParameter* > delays_;
+ std::vector< ConnParameter* > dendritic_delays_;
+ std::vector< ConnParameter* > axonal_delays_;
//! all other parameters, mapping name to value representation
std::vector< ConnParameterMap > synapse_params_;
@@ -284,7 +309,7 @@ class BipartiteConnBuilder
* Set synapse specific parameters.
*/
void set_synapse_model_( DictionaryDatum syn_params, size_t indx );
- void set_default_weight_or_delay_( DictionaryDatum syn_params, size_t indx );
+ void set_default_weight_or_delays_( DictionaryDatum syn_params, size_t indx );
void set_synapse_params( DictionaryDatum syn_defaults, DictionaryDatum syn_params, size_t indx );
/**
@@ -309,6 +334,8 @@ class BipartiteConnBuilder
*/
void reset_weights_();
void reset_delays_();
+ void reset_dendritic_delays_();
+ void reset_axonal_delays_();
};
diff --git a/nestkernel/conn_builder_conngen.cpp b/nestkernel/conn_builder_conngen.cpp
index 7c0547ab34..ebc7297162 100644
--- a/nestkernel/conn_builder_conngen.cpp
+++ b/nestkernel/conn_builder_conngen.cpp
@@ -130,6 +130,8 @@ ConnectionGeneratorBuilder::connect_()
synapse_model_id_[ 0 ],
param_dicts_[ 0 ][ target_thread ],
params[ d_idx ],
+ numerics::nan,
+ numerics::nan,
params[ w_idx ] );
}
}
diff --git a/nestkernel/connection.h b/nestkernel/connection.h
index 4a90eb2f0f..65d6564777 100644
--- a/nestkernel/connection.h
+++ b/nestkernel/connection.h
@@ -28,6 +28,7 @@
#include "connection_label.h"
#include "connector_base_impl.h"
#include "delay_checker.h"
+#include "delay_types.h"
#include "event.h"
#include "kernel_manager.h"
#include "nest.h"
@@ -37,7 +38,7 @@
#include "nest_types.h"
#include "node.h"
#include "spikecounter.h"
-#include "syn_id_delay.h"
+#include "target_identifier.h"
// Includes from sli:
#include "arraydatum.h"
@@ -76,7 +77,7 @@ class ConnTestDummyNodeBase : public Node
{
}
void
- update( const nest::Time&, long, long ) override
+ update( const nest::Time&, const long, const long ) override
{
}
void
@@ -111,7 +112,7 @@ class ConnTestDummyNodeBase : public Node
* or if needs to be changed, everything has to be reset after sending
* (i.e. after Event::operator() has been called).
*/
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
class Connection
{
@@ -121,12 +122,15 @@ class Connection
Connection()
: target_()
- , syn_id_delay_( 1.0 )
+ , more_targets_( false )
+ , disabled_( false )
+ , delay_( 1.0 )
{
+ delay_.set_delay_ms( 1.0 );
}
- Connection( const Connection< targetidentifierT >& rhs ) = default;
- Connection& operator=( const Connection< targetidentifierT >& rhs ) = default;
+ Connection( const Connection< targetidentifierT, DelayTypeT >& rhs ) = default;
+ Connection& operator=( const Connection< targetidentifierT, DelayTypeT >& rhs ) = default;
/**
* Get a pointer to an instance of a SecondaryEvent if this connection supports secondary events.
@@ -169,57 +173,122 @@ class Connection
void calibrate( const TimeConverter& );
/**
- * Return the delay of the connection in ms
+ * Framework for STDP with predominantly axonal delays:
+ * Correct this synapse and the corresponding previously sent spike
+ * taking into account a new post-synaptic spike.
+ */
+ void correct_synapse_stdp_ax_delay( const size_t tid,
+ const double t_last_pre_spike,
+ double& weight_revert,
+ const double t_post_spike,
+ const CommonSynapseProperties& );
+
+ /**
+ * Return the proportion of the transmission delay attributed to the dendrite.
*/
double
- get_delay() const
+ get_dendritic_delay_ms() const
{
- return syn_id_delay_.get_delay_ms();
+ return delay_.get_dendritic_delay_ms();
}
/**
- * Return the delay of the connection in steps
+ * Return the proportion of the transmission delay attributed to the dendrite.
*/
long
- get_delay_steps() const
+ get_dendritic_delay_steps() const
{
- return syn_id_delay_.delay;
+ return delay_.get_dendritic_delay_steps();
}
/**
- * Set the delay of the connection
+ * Set the proportion of the transmission delay attributed to the dendrite.
*/
void
- set_delay( const double delay )
+ set_dendritic_delay_ms( const double d )
{
- syn_id_delay_.set_delay_ms( delay );
+ delay_.set_dendritic_delay_ms( d );
}
/**
- * Set the delay of the connection in steps
+ * Set the proportion of the transmission delay attributed to the dendrite.
+ */
+ void
+ set_dendritic_delay_steps( const long d )
+ {
+ delay_.set_dendritic_delay_steps( d );
+ }
+
+ /**
+ * Set the proportion of the transmission delay attributed to the axon.
*/
void
- set_delay_steps( const long delay )
+ set_axonal_delay_ms( const double d )
+ {
+ delay_.set_axonal_delay_ms( d );
+ }
+
+ /**
+ * Get the proportion of the transmission delay attributed to the axon.
+ */
+ double
+ get_axonal_delay_ms() const
{
- syn_id_delay_.delay = delay;
+ return delay_.get_axonal_delay_ms();
}
/**
- * Set the synapse id of the connection
+ * Set the proportion of the transmission delay attributed to the axon.
*/
void
- set_syn_id( synindex syn_id )
+ set_axonal_delay_steps( const long d )
+ {
+ delay_.set_axonal_delay_steps( d );
+ }
+
+ /**
+ * Get the proportion of the transmission delay attributed to the axon.
+ */
+ double
+ get_axonal_delay_steps() const
{
- syn_id_delay_.syn_id = syn_id;
+ return delay_.get_axonal_delay_steps();
}
/**
- * Get the synapse id of the connection
+ * Return the delay of the connection in ms
*/
- synindex
- get_syn_id() const
+ double
+ get_delay_ms() const
{
- return syn_id_delay_.syn_id;
+ return delay_.get_delay_ms();
+ }
+
+ /**
+ * Return the delay of the connection in steps
+ */
+ long
+ get_delay_steps() const
+ {
+ return delay_.get_delay_steps();
+ }
+
+ /**
+ * Set the delay of the connection
+ */
+ void
+ set_delay_ms( const double d )
+ {
+ delay_.set_delay_ms( d );
+ }
+
+ /**
+ * Set the delay of the connection in steps
+ */
+ void
+ set_delay_steps( const long d )
+ {
+ delay_.set_delay_steps( d );
}
long
@@ -258,7 +327,7 @@ class Connection
void
set_source_has_more_targets( const bool more_targets )
{
- syn_id_delay_.set_source_has_more_targets( more_targets );
+ more_targets_ = more_targets;
}
/**
@@ -270,29 +339,29 @@ class Connection
bool
source_has_more_targets() const
{
- return syn_id_delay_.source_has_more_targets();
+ return more_targets_;
}
/**
- * Disables the connection.
+ * Disables the synapse.
*
* @see is_disabled
*/
void
disable()
{
- syn_id_delay_.disable();
+ disabled_ = true;
}
/**
- * Returns a flag denoting if the connection is disabled.
+ * Returns a flag denoting if the synapse is disabled.
*
* @see disable
*/
bool
is_disabled() const
{
- return syn_id_delay_.is_disabled();
+ return disabled_;
}
protected:
@@ -305,39 +374,50 @@ class Connection
* \param the last spike produced by the presynaptic neuron (for STDP and
* maturing connections)
*/
- void check_connection_( Node& dummy_target, Node& source, Node& target, const size_t receptor_type );
+ void check_connection_( Node& dummy_target,
+ Node& source,
+ Node& target,
+ const synindex syn_id,
+ const size_t receptor_type );
- // The order of the members below is critical as it influcences the size of the object.
- // Please leave unchanged!
targetidentifierT target_;
- // syn_id (9 bit), delay (21 bit) in timesteps of this connection and more_targets and disabled flags (each 1 bit)
- SynIdDelay syn_id_delay_;
+ bool more_targets_ : 1;
+ bool disabled_ : 1;
+ DelayTypeT delay_;
+ // There are still 14 bits to spare here. If more bits are required, the sizes of the delays in the delay struct could
+ // be reduced even more as well.
};
-template < typename targetidentifierT >
-constexpr ConnectionModelProperties Connection< targetidentifierT >::properties;
+using success_connection_target_ptr_size =
+ StaticAssert< sizeof( Connection< TargetIdentifierPtrRport, TotalDelay > ) == 24 >::success;
+using success_connection_target_idx_size =
+ StaticAssert< sizeof( Connection< TargetIdentifierIndex, TotalDelay > ) == 8 >::success;
+using success_connection_target_ptr_size =
+ StaticAssert< sizeof( Connection< TargetIdentifierPtrRport, AxonalDendriticDelay > ) == 24 >::success;
+using success_connection_target_idx_size =
+ StaticAssert< sizeof( Connection< TargetIdentifierIndex, AxonalDendriticDelay > ) == 8 >::success;
+
+template < typename targetidentifierT, typename DelayTypeT >
+constexpr ConnectionModelProperties Connection< targetidentifierT, DelayTypeT >::properties;
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
inline void
-Connection< targetidentifierT >::check_connection_( Node& dummy_target,
+Connection< targetidentifierT, DelayTypeT >::check_connection_( Node& dummy_target,
Node& source,
Node& target,
+ const synindex syn_id,
const size_t receptor_type )
{
- // 1. does this connection support the event type sent by source
- // try to send event from source to dummy_target
- // this line might throw an exception
- source.send_test_event( dummy_target, receptor_type, get_syn_id(), true );
+ // 1. does this connection support the event type sent by source try to send event from source to dummy_target this
+ // line might throw an exception
+ source.send_test_event( dummy_target, receptor_type, syn_id, true );
- // 2. does the target accept the event type sent by source
- // try to send event from source to target
- // this returns the port of the incoming connection
- // p must be stored in the base class connection
+ // 2. does the target accept the event type sent by source try to send event from source to target
+ // this returns the port of the incoming connection p must be stored in the base class connection
// this line might throw an exception
- target_.set_rport( source.send_test_event( target, receptor_type, get_syn_id(), false ) );
+ target_.set_rport( source.send_test_event( target, receptor_type, syn_id, false ) );
- // 3. do the events sent by source mean the same thing as they are
- // interpreted in target?
+ // 3. do the events sent by source mean the same thing as they are interpreted in target?
// note that we here use a bitwise and operation (&), because we interpret
// each bit in the signal type as a collection of individual flags
if ( not( source.sends_signal() & target.receives_signal() ) )
@@ -348,49 +428,49 @@ Connection< targetidentifierT >::check_connection_( Node& dummy_target,
target_.set_target( &target );
}
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
inline void
-Connection< targetidentifierT >::get_status( DictionaryDatum& d ) const
+Connection< targetidentifierT, DelayTypeT >::get_status( DictionaryDatum& d ) const
{
- def< double >( d, names::delay, syn_id_delay_.get_delay_ms() );
+ delay_.get_status( d );
target_.get_status( d );
}
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
inline void
-Connection< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& )
+Connection< targetidentifierT, DelayTypeT >::set_status( const DictionaryDatum& d, ConnectorModel& cm )
{
- double delay;
- if ( updateValue< double >( d, names::delay, delay ) )
- {
- kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay );
- syn_id_delay_.set_delay_ms( delay );
- }
+ delay_.set_status( d, cm );
// no call to target_.set_status() because target and rport cannot be changed
}
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
inline void
-Connection< targetidentifierT >::check_synapse_params( const DictionaryDatum& ) const
+Connection< targetidentifierT, DelayTypeT >::check_synapse_params( const DictionaryDatum& ) const
{
}
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
inline void
-Connection< targetidentifierT >::calibrate( const TimeConverter& tc )
+Connection< targetidentifierT, DelayTypeT >::calibrate( const TimeConverter& tc )
{
- Time t = tc.from_old_steps( syn_id_delay_.delay );
- syn_id_delay_.delay = t.get_steps();
+ delay_.calibrate( tc );
+}
- if ( syn_id_delay_.delay == 0 )
- {
- syn_id_delay_.delay = 1;
- }
+template < typename targetidentifierT, typename DelayTypeT >
+inline void
+Connection< targetidentifierT, DelayTypeT >::correct_synapse_stdp_ax_delay( const size_t,
+ const double,
+ double&,
+ const double,
+ const CommonSynapseProperties& )
+{
+ throw IllegalConnection( "Connection does not support correction in case of STDP with predominantly axonal delays." );
}
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
inline void
-Connection< targetidentifierT >::trigger_update_weight( const size_t,
+Connection< targetidentifierT, DelayTypeT >::trigger_update_weight( const size_t,
const std::vector< spikecounter >&,
const double,
const CommonSynapseProperties& )
@@ -398,9 +478,9 @@ Connection< targetidentifierT >::trigger_update_weight( const size_t,
throw IllegalConnection( "Connection does not support updates that are triggered by a volume transmitter." );
}
-template < typename targetidentifierT >
+template < typename targetidentifierT, typename DelayTypeT >
SecondaryEvent*
-Connection< targetidentifierT >::get_secondary_event()
+Connection< targetidentifierT, DelayTypeT >::get_secondary_event()
{
assert( false and "Non-primary connections have to provide get_secondary_event()" );
return nullptr;
diff --git a/nestkernel/connection_creator.cpp b/nestkernel/connection_creator.cpp
index 21b94e3153..10684ed854 100644
--- a/nestkernel/connection_creator.cpp
+++ b/nestkernel/connection_creator.cpp
@@ -36,6 +36,8 @@ ConnectionCreator::ConnectionCreator( DictionaryDatum dict )
, synapse_model_()
, weight_()
, delay_()
+ , dendritic_delay_()
+ , axonal_delay_()
{
Name connection_type;
@@ -111,9 +113,50 @@ ConnectionCreator::ConnectionCreator( DictionaryDatum dict )
{
weight_ = { NestModule::create_parameter( ( *syn_defaults )[ names::weight ] ) };
}
+
+ // In case the synapse type uses split axonal and dendritic delays, the synapse default dict will contain values for
+ // the dendritic delay, the axonal delay, and also the total delay. But we only want to use the delay value if we are
+ // not explicitly using axonal and dendritic delays, so we only set the delay here if those are not provided.
+ bool axonal_or_dendritic_delay_set = false;
+ if ( dendritic_delay_.empty() )
+ {
+ if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] )
+ or not syn_defaults->known( names::dendritic_delay ) )
+ {
+ dendritic_delay_ = { NestModule::create_parameter( numerics::nan ) };
+ }
+ else
+ {
+ dendritic_delay_ = { NestModule::create_parameter( ( *syn_defaults )[ names::dendritic_delay ] ) };
+ axonal_or_dendritic_delay_set = true;
+ }
+ }
+ else
+ {
+ axonal_or_dendritic_delay_set = true;
+ }
+ if ( axonal_delay_.empty() )
+ {
+ if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] )
+ or not syn_defaults->known( names::axonal_delay ) )
+ {
+ axonal_delay_ = { NestModule::create_parameter( numerics::nan ) };
+ }
+ else
+ {
+ axonal_delay_ = { NestModule::create_parameter( ( *syn_defaults )[ names::axonal_delay ] ) };
+ axonal_or_dendritic_delay_set = true;
+ }
+ }
+ else
+ {
+ axonal_or_dendritic_delay_set = true;
+ }
+
if ( delay_.empty() )
{
- if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] ) )
+ if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] ) or not syn_defaults->known( names::delay )
+ or axonal_or_dendritic_delay_set )
{
delay_ = { NestModule::create_parameter( numerics::nan ) };
}
@@ -183,10 +226,54 @@ ConnectionCreator::extract_params_( const DictionaryDatum& dict_datum, std::vect
if ( dict_datum->known( names::delay ) )
{
delay_.push_back( NestModule::create_parameter( ( *dict_datum )[ names::delay ] ) );
+ dendritic_delay_.push_back( NestModule::create_parameter( numerics::nan ) );
+ axonal_delay_.push_back( NestModule::create_parameter( numerics::nan ) );
}
else
{
- if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] ) )
+ // In case the synapse type uses split axonal and dendritic delays, the synapse default dict will contain values for
+ // the dendritic delay, the axonal delay, and also the total delay. But we only want to use the delay value if we
+ // are not explicitly using axonal and dendritic delays, so we only set the delay here if those are not provided.
+ bool axonal_or_dendritic_delay_set = false;
+ if ( dict_datum->known( names::dendritic_delay ) )
+ {
+ dendritic_delay_.push_back( NestModule::create_parameter( ( *dict_datum )[ names::dendritic_delay ] ) );
+ axonal_or_dendritic_delay_set = true;
+ }
+ else
+ {
+ if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] )
+ or not syn_defaults->known( names::dendritic_delay ) )
+ {
+ dendritic_delay_.push_back( NestModule::create_parameter( numerics::nan ) );
+ }
+ else
+ {
+ dendritic_delay_.push_back( NestModule::create_parameter( ( *syn_defaults )[ names::dendritic_delay ] ) );
+ axonal_or_dendritic_delay_set = true;
+ }
+ }
+ if ( dict_datum->known( names::axonal_delay ) )
+ {
+ axonal_delay_.push_back( NestModule::create_parameter( ( *dict_datum )[ names::axonal_delay ] ) );
+ axonal_or_dendritic_delay_set = true;
+ }
+ else
+ {
+ if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] )
+ or not syn_defaults->known( names::axonal_delay ) )
+ {
+ axonal_delay_.push_back( NestModule::create_parameter( numerics::nan ) );
+ }
+ else
+ {
+ axonal_delay_.push_back( NestModule::create_parameter( ( *syn_defaults )[ names::axonal_delay ] ) );
+ axonal_or_dendritic_delay_set = true;
+ }
+ }
+
+ if ( not getValue< bool >( ( *syn_defaults )[ names::has_delay ] ) or not syn_defaults->known( names::delay )
+ or axonal_or_dendritic_delay_set )
{
delay_.push_back( NestModule::create_parameter( numerics::nan ) );
}
diff --git a/nestkernel/connection_creator.h b/nestkernel/connection_creator.h
index 62d2671344..44e034eb41 100644
--- a/nestkernel/connection_creator.h
+++ b/nestkernel/connection_creator.h
@@ -186,6 +186,8 @@ class ConnectionCreator
std::vector< std::vector< DictionaryDatum > > param_dicts_;
std::vector< std::shared_ptr< Parameter > > weight_;
std::vector< std::shared_ptr< Parameter > > delay_;
+ std::vector< std::shared_ptr< Parameter > > dendritic_delay_;
+ std::vector< std::shared_ptr< Parameter > > axonal_delay_;
};
} // namespace nest
diff --git a/nestkernel/connection_creator_impl.h b/nestkernel/connection_creator_impl.h
index e094ab59d5..a8fba1cea2 100644
--- a/nestkernel/connection_creator_impl.h
+++ b/nestkernel/connection_creator_impl.h
@@ -108,6 +108,8 @@ ConnectionCreator::connect_to_target_( Iterator from,
synapse_model_[ indx ],
param_dicts_[ indx ][ tgt_thread ],
delay_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ),
+ dendritic_delay_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ),
+ axonal_delay_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ),
weight_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ) );
}
}
@@ -153,6 +155,8 @@ ConnectionCreator::connect_to_target_poisson_( Iterator from,
synapse_model_[ indx ],
param_dicts_[ indx ][ tgt_thread ],
delay_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ),
+ dendritic_delay_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ),
+ axonal_delay_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ),
weight_[ indx ]->value( rng, source_pos, target_pos, source, tgt_ptr ) );
}
}
@@ -258,7 +262,7 @@ ConnectionCreator::pairwise_bernoulli_on_source_( Layer< D >& source,
NodeCollection::const_iterator target_begin = target_nc->begin();
NodeCollection::const_iterator target_end = target_nc->end();
- for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it )
+ for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it != target_end; ++tgt_it )
{
Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id, thread_id );
@@ -342,7 +346,7 @@ ConnectionCreator::pairwise_bernoulli_on_target_( Layer< D >& source,
NodeCollection::const_iterator target_begin = target_nc->thread_local_begin();
NodeCollection::const_iterator target_end = target_nc->end();
- for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it )
+ for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it != target_end; ++tgt_it )
{
Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id, thread_id );
@@ -483,7 +487,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
// protect against connecting to devices without proxies
// we need to do this before creating the first connection to leave
// the network untouched if any target does not have proxies
- for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it )
+ for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it != target_end; ++tgt_it )
{
Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id );
@@ -497,7 +501,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
std::vector< std::pair< Position< D >, size_t > > positions;
- for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it )
+ for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it != target_end; ++tgt_it )
{
size_t target_id = ( *tgt_it ).node_id;
Node* const tgt = kernel().node_manager.get_node_or_proxy( target_id );
@@ -574,9 +578,20 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
for ( size_t indx = 0; indx < synapse_model_.size(); ++indx )
{
const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- kernel().connection_manager.connect(
- source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w );
+ const double delay = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double dend_delay =
+ dendritic_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double ax_delay =
+ axonal_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ kernel().connection_manager.connect( source_id,
+ tgt,
+ target_thread,
+ synapse_model_[ indx ],
+ param_dicts_[ indx ][ target_thread ],
+ delay,
+ dend_delay,
+ ax_delay,
+ w );
}
is_selected[ random_id ] = true;
@@ -613,9 +628,20 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
for ( size_t indx = 0; indx < synapse_model_.size(); ++indx )
{
const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- kernel().connection_manager.connect(
- source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w );
+ const double delay = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double dend_delay =
+ dendritic_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double ax_delay =
+ axonal_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ kernel().connection_manager.connect( source_id,
+ tgt,
+ target_thread,
+ synapse_model_[ indx ],
+ param_dicts_[ indx ][ target_thread ],
+ delay,
+ dend_delay,
+ ax_delay,
+ w );
}
is_selected[ random_id ] = true;
@@ -631,7 +657,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
// Get (position,node ID) pairs for all nodes in source layer
std::vector< std::pair< Position< D >, size_t > >* positions = source.get_global_positions_vector( source_nc );
- for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it )
+ for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it != target_end; ++tgt_it )
{
size_t target_id = ( *tgt_it ).node_id;
Node* const tgt = kernel().node_manager.get_node_or_proxy( target_id );
@@ -700,9 +726,20 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
for ( size_t indx = 0; indx < synapse_model_.size(); ++indx )
{
const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- kernel().connection_manager.connect(
- source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w );
+ const double delay = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double dend_delay =
+ dendritic_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double ax_delay =
+ axonal_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ kernel().connection_manager.connect( source_id,
+ tgt,
+ target_thread,
+ synapse_model_[ indx ],
+ param_dicts_[ indx ][ target_thread ],
+ delay,
+ dend_delay,
+ ax_delay,
+ w );
}
is_selected[ random_id ] = true;
@@ -737,9 +774,20 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source,
for ( size_t indx = 0; indx < synapse_model_.size(); ++indx )
{
const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
- kernel().connection_manager.connect(
- source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w );
+ const double delay = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double dend_delay =
+ dendritic_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ const double ax_delay =
+ axonal_delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt );
+ kernel().connection_manager.connect( source_id,
+ tgt,
+ target_thread,
+ synapse_model_[ indx ],
+ param_dicts_[ indx ][ target_thread ],
+ delay,
+ dend_delay,
+ ax_delay,
+ w );
}
is_selected[ random_id ] = true;
@@ -772,7 +820,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source,
NodeCollection::const_iterator target_begin = target_nc->rank_local_begin();
NodeCollection::const_iterator target_end = target_nc->end();
- for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it )
+ for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it != target_end; ++tgt_it )
{
Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id );
@@ -869,11 +917,17 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source,
std::vector< double > rng_weight_vec;
std::vector< double > rng_delay_vec;
+ std::vector< double > rng_dendritic_delay_vec;
+ std::vector< double > rng_axonal_delay_vec;
for ( size_t indx = 0; indx < weight_.size(); ++indx )
{
const auto tgt = kernel().node_manager.get_node_or_proxy( target_pos_node_id_pairs[ indx ].second );
rng_weight_vec.push_back( weight_[ indx ]->value( grng, source_pos_vector, target_pos_vector, target, tgt ) );
rng_delay_vec.push_back( delay_[ indx ]->value( grng, source_pos_vector, target_pos_vector, target, tgt ) );
+ rng_dendritic_delay_vec.push_back(
+ dendritic_delay_[ indx ]->value( grng, source_pos_vector, target_pos_vector, target, tgt ) );
+ rng_axonal_delay_vec.push_back(
+ axonal_delay_[ indx ]->value( grng, source_pos_vector, target_pos_vector, target, tgt ) );
}
// Each VP has now decided to create this connection and drawn any random parameter values
@@ -896,6 +950,8 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source,
synapse_model_[ indx ],
param_dicts_[ indx ][ target_thread ],
rng_delay_vec[ indx ],
+ rng_dendritic_delay_vec[ indx ],
+ rng_axonal_delay_vec[ indx ],
rng_weight_vec[ indx ] );
}
}
diff --git a/nestkernel/connection_manager.cpp b/nestkernel/connection_manager.cpp
index 7228915296..7476810647 100644
--- a/nestkernel/connection_manager.cpp
+++ b/nestkernel/connection_manager.cpp
@@ -22,13 +22,9 @@
#include "connection_manager.h"
-// Generated includes:
-#include "config.h"
-
// C++ includes:
#include
#include
-#include
#include
#include
#include
@@ -53,7 +49,6 @@
#include "eprop_archiving_node_recurrent.h"
#include "exceptions.h"
#include "kernel_manager.h"
-#include "mpi_manager_impl.h"
#include "nest_names.h"
#include "node.h"
#include "sonata_connector.h"
@@ -68,7 +63,10 @@
#include "tokenutils.h"
-nest::ConnectionManager::ConnectionManager()
+namespace nest
+{
+
+ConnectionManager::ConnectionManager()
: connruledict_( new Dictionary() )
, connbuilder_factories_()
, thirdconnruledict_( new Dictionary() )
@@ -84,10 +82,11 @@ nest::ConnectionManager::ConnectionManager()
, secondary_connections_exist_( false )
, check_secondary_connections_()
, stdp_eps_( 1.0e-6 )
+ , num_corrections_( 0 )
{
}
-nest::ConnectionManager::~ConnectionManager()
+ConnectionManager::~ConnectionManager()
{
// Memory leak on purpose!
// The ConnectionManager is deleted, when the network is deleted, and
@@ -98,7 +97,7 @@ nest::ConnectionManager::~ConnectionManager()
}
void
-nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_only )
+ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_only )
{
if ( not adjust_number_of_threads_or_rng_only )
{
@@ -129,6 +128,7 @@ nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_
connections_.resize( num_threads );
secondary_recv_buffer_pos_.resize( num_threads );
compressed_spike_data_.resize( 0 );
+ have_nonzero_axonal_delays_.resize( num_threads, false );
has_primary_connections_ = false;
check_primary_connections_.initialize( num_threads, false );
@@ -158,7 +158,7 @@ nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_
}
void
-nest::ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_only )
+ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_only )
{
source_table_.finalize();
target_table_.finalize();
@@ -167,6 +167,8 @@ nest::ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_on
std::vector< std::vector< ConnectorBase* > >().swap( connections_ );
std::vector< std::vector< std::vector< size_t > > >().swap( secondary_recv_buffer_pos_ );
compressed_spike_data_.clear();
+ num_corrections_ = 0;
+ have_nonzero_axonal_delays_.clear();
if ( not adjust_number_of_threads_or_rng_only )
{
@@ -187,7 +189,7 @@ nest::ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_on
}
void
-nest::ConnectionManager::set_status( const DictionaryDatum& d )
+ConnectionManager::set_status( const DictionaryDatum& d )
{
for ( size_t i = 0; i < delay_checkers_.size(); ++i )
{
@@ -211,14 +213,14 @@ nest::ConnectionManager::set_status( const DictionaryDatum& d )
}
}
-nest::DelayChecker&
-nest::ConnectionManager::get_delay_checker()
+DelayChecker&
+ConnectionManager::get_delay_checker()
{
return delay_checkers_[ kernel().vp_manager.get_thread_id() ];
}
void
-nest::ConnectionManager::get_status( DictionaryDatum& dict )
+ConnectionManager::get_status( DictionaryDatum& dict )
{
update_delay_extrema_();
def< double >( dict, names::min_delay, Time( Time::step( min_delay_ ) ).get_ms() );
@@ -229,6 +231,8 @@ nest::ConnectionManager::get_status( DictionaryDatum& dict )
def< bool >( dict, names::keep_source_table, keep_source_table_ );
def< bool >( dict, names::use_compressed_spikes, use_compressed_spikes_ );
+ def< size_t >( dict, names::num_corrections, num_corrections_ );
+
sw_construction_connect.get_status( dict, names::time_construction_connect, names::time_construction_connect_cpu );
ArrayDatum connection_rules;
@@ -240,7 +244,7 @@ nest::ConnectionManager::get_status( DictionaryDatum& dict )
}
DictionaryDatum
-nest::ConnectionManager::get_synapse_status( const size_t source_node_id,
+ConnectionManager::get_synapse_status( const size_t source_node_id,
const size_t target_node_id,
const size_t tid,
const synindex syn_id,
@@ -285,7 +289,7 @@ nest::ConnectionManager::get_synapse_status( const size_t source_node_id,
}
void
-nest::ConnectionManager::set_synapse_status( const size_t source_node_id,
+ConnectionManager::set_synapse_status( const size_t source_node_id,
const size_t target_node_id,
const size_t tid,
const synindex syn_id,
@@ -335,7 +339,7 @@ nest::ConnectionManager::set_synapse_status( const size_t source_node_id,
}
void
-nest::ConnectionManager::delete_connections_()
+ConnectionManager::delete_connections_()
{
for ( size_t tid = 0; tid < connections_.size(); ++tid )
{
@@ -346,8 +350,8 @@ nest::ConnectionManager::delete_connections_()
}
}
-const nest::Time
-nest::ConnectionManager::get_min_delay_time_() const
+const Time
+ConnectionManager::get_min_delay_time_() const
{
Time min_delay = Time::pos_inf();
@@ -360,8 +364,8 @@ nest::ConnectionManager::get_min_delay_time_() const
return min_delay;
}
-const nest::Time
-nest::ConnectionManager::get_max_delay_time_() const
+const Time
+ConnectionManager::get_max_delay_time_() const
{
Time max_delay = Time::get_resolution();
@@ -375,7 +379,7 @@ nest::ConnectionManager::get_max_delay_time_() const
}
bool
-nest::ConnectionManager::get_user_set_delay_extrema() const
+ConnectionManager::get_user_set_delay_extrema() const
{
bool user_set_delay_extrema = false;
@@ -388,8 +392,8 @@ nest::ConnectionManager::get_user_set_delay_extrema() const
return user_set_delay_extrema;
}
-nest::BipartiteConnBuilder*
-nest::ConnectionManager::get_conn_builder( const std::string& name,
+BipartiteConnBuilder*
+ConnectionManager::get_conn_builder( const std::string& name,
NodeCollectionPTR sources,
NodeCollectionPTR targets,
ThirdOutBuilder* third_out,
@@ -429,7 +433,7 @@ nest::ConnectionManager::get_third_conn_builder( const std::string& name,
}
void
-nest::ConnectionManager::calibrate( const TimeConverter& tc )
+ConnectionManager::calibrate( const TimeConverter& tc )
{
for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid )
{
@@ -438,7 +442,7 @@ nest::ConnectionManager::calibrate( const TimeConverter& tc )
}
void
-nest::ConnectionManager::connect( NodeCollectionPTR sources,
+ConnectionManager::connect( NodeCollectionPTR sources,
NodeCollectionPTR targets,
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs )
@@ -487,7 +491,7 @@ nest::ConnectionManager::connect( NodeCollectionPTR sources,
void
-nest::ConnectionManager::connect( TokenArray sources, TokenArray targets, const DictionaryDatum& syn_spec )
+ConnectionManager::connect( TokenArray sources, TokenArray targets, const DictionaryDatum& syn_spec )
{
// Get synapse id
size_t syn_id = 0;
@@ -513,7 +517,7 @@ nest::ConnectionManager::connect( TokenArray sources, TokenArray targets, const
void
-nest::ConnectionManager::update_delay_extrema_()
+ConnectionManager::update_delay_extrema_()
{
if ( kernel().simulation_manager.has_been_simulated() )
{
@@ -533,9 +537,9 @@ nest::ConnectionManager::update_delay_extrema_()
max_delay_ = std::max( max_delay_, kernel().sp_manager.builder_max_delay() );
}
- // If the user explicitly set min/max_delay, this happend on all MPI ranks,
+ // If the user explicitly set min/max_delay, this happened on all MPI ranks,
// so all ranks are up to date already. Also, once the user has set min/max_delay
- // explicitly, Connect() cannot induce new extrema. Thuse, we only need to communicate
+ // explicitly, Connect() cannot induce new extrema. Thus, we only need to communicate
// with other ranks if the user has not set the extrema and connections may have
// been created.
if ( not kernel().connection_manager.get_user_set_delay_extrema()
@@ -560,12 +564,14 @@ nest::ConnectionManager::update_delay_extrema_()
// node ID node thread syn_id dict delay weight
void
-nest::ConnectionManager::connect( const size_t snode_id,
+ConnectionManager::connect( const size_t snode_id,
Node* target,
size_t target_thread,
const synindex syn_id,
const DictionaryDatum& params,
const double delay,
+ const double dendritic_delay,
+ const double axonal_delay,
const double weight )
{
kernel().model_manager.assert_valid_syn_id( syn_id, kernel().vp_manager.get_thread_id() );
@@ -577,7 +583,7 @@ nest::ConnectionManager::connect( const size_t snode_id,
switch ( connection_type )
{
case CONNECT:
- connect_( *source, *target, snode_id, target_thread, syn_id, params, delay, weight );
+ connect_( *source, *target, snode_id, target_thread, syn_id, params, delay, dendritic_delay, axonal_delay, weight );
break;
case CONNECT_FROM_DEVICE:
connect_from_device_( *source, *target, target_thread, syn_id, params, delay, weight );
@@ -592,7 +598,7 @@ nest::ConnectionManager::connect( const size_t snode_id,
// node_id node_id dict syn_id
bool
-nest::ConnectionManager::connect( const size_t snode_id,
+ConnectionManager::connect( const size_t snode_id,
const size_t tnode_id,
const DictionaryDatum& params,
const synindex syn_id )
@@ -633,10 +639,12 @@ nest::ConnectionManager::connect( const size_t snode_id,
}
void
-nest::ConnectionManager::connect_arrays( long* sources,
+ConnectionManager::connect_arrays( long* sources,
long* targets,
double* weights,
double* delays,
+ double* dendritic_delays,
+ double* axonal_delays,
std::vector< std::string >& p_keys,
double* p_values,
size_t n,
@@ -692,7 +700,10 @@ nest::ConnectionManager::connect_arrays( long* sources,
}
// Increments pointers to weight and delay, if they are specified.
- auto increment_wd = [ weights, delays ]( decltype( weights ) & w, decltype( delays ) & d )
+ auto increment_wd = [ weights, delays, dendritic_delays, axonal_delays ]( decltype( weights ) & w,
+ decltype( delays ) & d,
+ decltype( dendritic_delays ) & dend,
+ decltype( axonal_delays ) & axonal )
{
if ( weights )
{
@@ -702,6 +713,14 @@ nest::ConnectionManager::connect_arrays( long* sources,
{
++d;
}
+ if ( dendritic_delays )
+ {
+ ++dend;
+ }
+ if ( axonal_delays )
+ {
+ ++axonal;
+ }
};
// Set flag before entering parallel section in case we have fewer connections than ranks.
@@ -719,8 +738,12 @@ nest::ConnectionManager::connect_arrays( long* sources,
auto t = targets;
auto w = weights;
auto d = delays;
+ auto dend = dendritic_delays;
+ auto axonal = axonal_delays;
double weight_buffer = numerics::nan;
double delay_buffer = numerics::nan;
+ double dendritic_delay_buffer = numerics::nan;
+ double axonal_delay_buffer = numerics::nan;
int index_counter = 0; // Index of the current connection, for connection parameters
for ( ; s != sources + n; ++s, ++t, ++index_counter )
@@ -736,7 +759,7 @@ nest::ConnectionManager::connect_arrays( long* sources,
auto target_node = kernel().node_manager.get_node_or_proxy( *t, tid );
if ( target_node->is_proxy() )
{
- increment_wd( w, d );
+ increment_wd( w, d, dend, axonal );
continue;
}
@@ -750,6 +773,14 @@ nest::ConnectionManager::connect_arrays( long* sources,
{
delay_buffer = *d;
}
+ if ( dendritic_delays )
+ {
+ dendritic_delay_buffer = *dend;
+ }
+ if ( axonal_delays )
+ {
+ axonal_delay_buffer = *axonal;
+ }
// Store the key-value pair of each parameter in the Dictionary.
for ( auto& param_pointer_pair : param_pointers )
@@ -782,11 +813,19 @@ nest::ConnectionManager::connect_arrays( long* sources,
}
}
- connect( *s, target_node, tid, synapse_model_id, param_dicts[ tid ], delay_buffer, weight_buffer );
+ connect( *s,
+ target_node,
+ tid,
+ synapse_model_id,
+ param_dicts[ tid ],
+ delay_buffer,
+ dendritic_delay_buffer,
+ axonal_delay_buffer,
+ weight_buffer );
ALL_ENTRIES_ACCESSED( *param_dicts[ tid ], "connect_arrays", "Unread dictionary entries: " );
- increment_wd( w, d );
+ increment_wd( w, d, dend, axonal );
}
}
catch ( std::exception& err )
@@ -891,6 +930,8 @@ nest::ConnectionManager::connect_( Node& source,
const synindex syn_id,
const DictionaryDatum& params,
const double delay,
+ const double dendritic_delay,
+ const double axonal_delay,
const double weight )
{
ConnectorModel& conn_model = kernel().model_manager.get_connection_model( syn_id, tid );
@@ -918,11 +959,14 @@ nest::ConnectionManager::connect_( Node& source,
}
const bool is_primary = conn_model.has_property( ConnectionModelProperties::IS_PRIMARY );
- conn_model.add_connection( source, target, connections_[ tid ], syn_id, params, delay, weight );
+ conn_model.add_connection(
+ source, target, connections_[ tid ], syn_id, params, delay, dendritic_delay, axonal_delay, weight );
source_table_.add_source( tid, syn_id, s_node_id, is_primary );
increase_connection_count( tid, syn_id );
+ have_nonzero_axonal_delays_[ tid ] = have_nonzero_axonal_delays_[ tid ] or ( axonal_delay > 0. );
+
// We do not check has_primary_connections_ and secondary_connections_exist_
// directly as this led to worse performance on the supercomputer Piz Daint.
if ( check_primary_connections_[ tid ].is_false() and is_primary )
@@ -940,7 +984,7 @@ nest::ConnectionManager::connect_( Node& source,
}
void
-nest::ConnectionManager::connect_to_device_( Node& source,
+ConnectionManager::connect_to_device_( Node& source,
Node& target,
const size_t s_node_id,
const size_t tid,
@@ -956,7 +1000,7 @@ nest::ConnectionManager::connect_to_device_( Node& source,
}
void
-nest::ConnectionManager::connect_from_device_( Node& source,
+ConnectionManager::connect_from_device_( Node& source,
Node& target,
const size_t tid,
const synindex syn_id,
@@ -971,7 +1015,7 @@ nest::ConnectionManager::connect_from_device_( Node& source,
}
void
-nest::ConnectionManager::increase_connection_count( const size_t tid, const synindex syn_id )
+ConnectionManager::increase_connection_count( const size_t tid, const synindex syn_id )
{
if ( num_connections_[ tid ].size() <= syn_id )
{
@@ -989,7 +1033,7 @@ nest::ConnectionManager::increase_connection_count( const size_t tid, const syni
}
size_t
-nest::ConnectionManager::find_connection( const size_t tid,
+ConnectionManager::find_connection( const size_t tid,
const synindex syn_id,
const size_t snode_id,
const size_t tnode_id )
@@ -1014,10 +1058,7 @@ nest::ConnectionManager::find_connection( const size_t tid,
}
void
-nest::ConnectionManager::disconnect( const size_t tid,
- const synindex syn_id,
- const size_t snode_id,
- const size_t tnode_id )
+ConnectionManager::disconnect( const size_t tid, const synindex syn_id, const size_t snode_id, const size_t tnode_id )
{
assert( syn_id != invalid_synindex );
@@ -1036,7 +1077,7 @@ nest::ConnectionManager::disconnect( const size_t tid,
}
void
-nest::ConnectionManager::trigger_update_weight( const long vt_id,
+ConnectionManager::trigger_update_weight( const long vt_id,
const std::vector< spikecounter >& dopa_spikes,
const double t_trig )
{
@@ -1054,7 +1095,7 @@ nest::ConnectionManager::trigger_update_weight( const long vt_id,
}
size_t
-nest::ConnectionManager::get_num_target_data( const size_t tid ) const
+ConnectionManager::get_num_target_data( const size_t tid ) const
{
size_t num_connections = 0;
for ( synindex syn_id = 0; syn_id < connections_[ tid ].size(); ++syn_id )
@@ -1068,7 +1109,7 @@ nest::ConnectionManager::get_num_target_data( const size_t tid ) const
}
size_t
-nest::ConnectionManager::get_num_connections() const
+ConnectionManager::get_num_connections() const
{
size_t num_connections = 0;
for ( size_t t = 0; t < num_connections_.size(); ++t )
@@ -1083,7 +1124,7 @@ nest::ConnectionManager::get_num_connections() const
}
size_t
-nest::ConnectionManager::get_num_connections( const synindex syn_id ) const
+ConnectionManager::get_num_connections( const synindex syn_id ) const
{
size_t num_connections = 0;
for ( size_t t = 0; t < num_connections_.size(); ++t )
@@ -1098,7 +1139,7 @@ nest::ConnectionManager::get_num_connections( const synindex syn_id ) const
}
ArrayDatum
-nest::ConnectionManager::get_connections( const DictionaryDatum& params )
+ConnectionManager::get_connections( const DictionaryDatum& params )
{
std::deque< ConnectionID > connectome;
const Token& source_t = params->lookup( names::source );
@@ -1180,8 +1221,8 @@ nest::ConnectionManager::get_connections( const DictionaryDatum& params )
// Helper method which removes ConnectionIDs from input deque and
// appends them to output deque.
-static inline std::deque< nest::ConnectionID >&
-extend_connectome( std::deque< nest::ConnectionID >& out, std::deque< nest::ConnectionID >& in )
+static inline std::deque< ConnectionID >&
+extend_connectome( std::deque< ConnectionID >& out, std::deque< ConnectionID >& in )
{
while ( not in.empty() )
{
@@ -1193,7 +1234,7 @@ extend_connectome( std::deque< nest::ConnectionID >& out, std::deque< nest::Conn
}
void
-nest::ConnectionManager::split_to_neuron_device_vectors_( const size_t tid,
+ConnectionManager::split_to_neuron_device_vectors_( const size_t tid,
NodeCollectionPTR nodecollection,
std::vector< size_t >& neuron_node_ids,
std::vector< size_t >& device_node_ids ) const
@@ -1218,7 +1259,7 @@ nest::ConnectionManager::split_to_neuron_device_vectors_( const size_t tid,
}
void
-nest::ConnectionManager::get_connections( std::deque< ConnectionID >& connectome,
+ConnectionManager::get_connections( std::deque< ConnectionID >& connectome,
NodeCollectionPTR source,
NodeCollectionPTR target,
synindex syn_id,
@@ -1403,7 +1444,7 @@ nest::ConnectionManager::get_connections( std::deque< ConnectionID >& connectome
}
void
-nest::ConnectionManager::get_source_node_ids_( const size_t tid,
+ConnectionManager::get_source_node_ids_( const size_t tid,
const synindex syn_id,
const size_t tnode_id,
std::vector< size_t >& sources )
@@ -1417,7 +1458,7 @@ nest::ConnectionManager::get_source_node_ids_( const size_t tid,
}
void
-nest::ConnectionManager::get_sources( const std::vector< size_t >& targets,
+ConnectionManager::get_sources( const std::vector< size_t >& targets,
const size_t syn_id,
std::vector< std::vector< size_t > >& sources )
{
@@ -1437,7 +1478,7 @@ nest::ConnectionManager::get_sources( const std::vector< size_t >& targets,
}
void
-nest::ConnectionManager::get_targets( const std::vector< size_t >& sources,
+ConnectionManager::get_targets( const std::vector< size_t >& sources,
const size_t syn_id,
const std::string& post_synaptic_element,
std::vector< std::vector< size_t > >& targets )
@@ -1462,7 +1503,7 @@ nest::ConnectionManager::get_targets( const std::vector< size_t >& sources,
}
void
-nest::ConnectionManager::sort_connections( const size_t tid )
+ConnectionManager::sort_connections( const size_t tid )
{
assert( not source_table_.is_cleared() );
if ( use_compressed_spikes_ )
@@ -1479,7 +1520,7 @@ nest::ConnectionManager::sort_connections( const size_t tid )
}
void
-nest::ConnectionManager::compute_target_data_buffer_size()
+ConnectionManager::compute_target_data_buffer_size()
{
// Determine number of target data on this rank. Since each thread
// has its own data structures, we need to count connections on every
@@ -1505,7 +1546,7 @@ nest::ConnectionManager::compute_target_data_buffer_size()
}
void
-nest::ConnectionManager::compute_compressed_secondary_recv_buffer_positions( const size_t tid )
+ConnectionManager::compute_compressed_secondary_recv_buffer_positions( const size_t tid )
{
#pragma omp single
{
@@ -1547,8 +1588,8 @@ nest::ConnectionManager::compute_compressed_secondary_recv_buffer_positions( con
}
}
-nest::ConnectionManager::ConnectionType
-nest::ConnectionManager::connection_required( Node*& source, Node*& target, size_t tid )
+ConnectionManager::ConnectionType
+ConnectionManager::connection_required( Node*& source, Node*& target, size_t tid )
{
// The caller has to check and guarantee that the target is not a
// proxy and that it is on thread tid.
@@ -1640,9 +1681,9 @@ nest::ConnectionManager::connection_required( Node*& source, Node*& target, size
}
void
-nest::ConnectionManager::set_stdp_eps( const double stdp_eps )
+ConnectionManager::set_stdp_eps( const double stdp_eps )
{
- if ( not( stdp_eps < Time::get_resolution().get_ms() ) )
+ if ( stdp_eps >= Time::get_resolution().get_ms() )
{
throw KernelException(
"The epsilon used for spike-time comparison in STDP must be less "
@@ -1669,7 +1710,7 @@ nest::ConnectionManager::set_stdp_eps( const double stdp_eps )
// recv_buffer can not be a const reference as iterators used in
// secondary events must not be const
bool
-nest::ConnectionManager::deliver_secondary_events( const size_t tid,
+ConnectionManager::deliver_secondary_events( const size_t tid,
const bool called_from_wfr_update,
std::vector< unsigned int >& recv_buffer )
{
@@ -1717,13 +1758,13 @@ nest::ConnectionManager::deliver_secondary_events( const size_t tid,
}
void
-nest::ConnectionManager::compress_secondary_send_buffer_pos( const size_t tid )
+ConnectionManager::compress_secondary_send_buffer_pos( const size_t tid )
{
target_table_.compress_secondary_send_buffer_pos( tid );
}
void
-nest::ConnectionManager::remove_disabled_connections( const size_t tid )
+ConnectionManager::remove_disabled_connections( const size_t tid )
{
std::vector< ConnectorBase* >& connectors = connections_[ tid ];
@@ -1747,7 +1788,7 @@ nest::ConnectionManager::remove_disabled_connections( const size_t tid )
}
void
-nest::ConnectionManager::resize_connections()
+ConnectionManager::resize_connections()
{
kernel().vp_manager.assert_thread_parallel();
@@ -1758,19 +1799,19 @@ nest::ConnectionManager::resize_connections()
}
void
-nest::ConnectionManager::sync_has_primary_connections()
+ConnectionManager::sync_has_primary_connections()
{
has_primary_connections_ = kernel().mpi_manager.any_true( has_primary_connections_ );
}
void
-nest::ConnectionManager::check_secondary_connections_exist()
+ConnectionManager::check_secondary_connections_exist()
{
secondary_connections_exist_ = kernel().mpi_manager.any_true( secondary_connections_exist_ );
}
void
-nest::ConnectionManager::set_connections_have_changed()
+ConnectionManager::set_connections_have_changed()
{
assert( kernel().vp_manager.get_thread_id() == 0 );
@@ -1787,14 +1828,14 @@ nest::ConnectionManager::set_connections_have_changed()
}
void
-nest::ConnectionManager::unset_connections_have_changed()
+ConnectionManager::unset_connections_have_changed()
{
connections_have_changed_ = false;
}
void
-nest::ConnectionManager::collect_compressed_spike_data( const size_t tid )
+ConnectionManager::collect_compressed_spike_data( const size_t tid )
{
if ( use_compressed_spikes_ )
{
@@ -1946,3 +1987,5 @@ nest::ConnectionManager::initialize_iteration_state()
iteration_state_.push_back( std::pair< size_t, std::map< size_t, CSDMapEntry >::const_iterator >( 0, begin ) );
}
}
+
+}
diff --git a/nestkernel/connection_manager.h b/nestkernel/connection_manager.h
index 49a8a8ca39..6c707e9abb 100644
--- a/nestkernel/connection_manager.h
+++ b/nestkernel/connection_manager.h
@@ -145,7 +145,9 @@ class ConnectionManager : public ManagerInterface
* \param target_thread Thread that hosts the target node.
* \param syn_id The synapse model to use.
* \param params Parameter dictionary to configure the synapse.
- * \param delay Delay of the connection (in ms).
+ * \param delay Total delay of the connection (in ms).
+ * \param dendritic_delay Dendritic delay of the connection (in ms).
+ * \param axonal_delay Axonal delay of the connection (in ms).
* \param weight Weight of the connection.
*/
void connect( const size_t snode_id,
@@ -154,6 +156,8 @@ class ConnectionManager : public ManagerInterface
const synindex syn_id,
const DictionaryDatum& params,
const double delay = numerics::nan,
+ const double dendritic_delay = numerics::nan,
+ const double axonal_delay = numerics::nan,
const double weight = numerics::nan );
/**
@@ -174,6 +178,8 @@ class ConnectionManager : public ManagerInterface
long* targets,
double* weights,
double* delays,
+ double* dendritic_delays,
+ double* axonal_delays,
std::vector< std::string >& p_keys,
double* p_values,
size_t n,
@@ -307,6 +313,26 @@ class ConnectionManager : public ManagerInterface
const std::vector< ConnectorModel* >& cm,
Event& e );
+ /**
+ * On occurrence of a post-synaptic spike, correct the weight update of a previous pre-synaptic spike which was
+ * processed before the current post-synaptic spike, but had to be processed after it, if it was known at this point
+ * in time.
+ *
+ * @param tid The thread storing the synapse.
+ * @param syn_id Synapse type.
+ * @param lcid Local index of the synapse in the array of connections of the same type for this thread.
+ * @param t_last_pre_spike Time of the last pre-synaptic spike before the pre-synaptic spike which needs a correction.
+ * @param weight_revert The synaptic weight before depression after facilitation as baseline for potential later
+ * correction.
+ * @param t_post_spike Time of the current post-synaptic spike.
+ */
+ void correct_synapse_stdp_ax_delay( const size_t tid,
+ const synindex syn_id,
+ const size_t lcid,
+ const double t_last_pre_spike,
+ double& weight_revert,
+ const double t_post_spike );
+
/**
* Send event e to all device targets of source source_node_id
*/
@@ -318,11 +344,6 @@ class ConnectionManager : public ManagerInterface
*/
void send_from_device( const size_t tid, const size_t ldid, Event& e );
- /**
- * Send event e to all targets of node source on thread t
- */
- void send_local( size_t t, Node& source, Event& e );
-
/**
* Resize the structures for the Connector objects if necessary.
*
@@ -396,31 +417,28 @@ class ConnectionManager : public ManagerInterface
void remove_disabled_connections( const size_t tid );
/**
- * Returns true if connection information needs to be
- * communicated. False otherwise.
+ * Returns true if connection information needs to be communicated. False otherwise.
*/
bool connections_have_changed() const;
/**
- * Sets flag indicating whether connection information needs to be
- * communicated to true.
+ * Sets flag indicating whether connection information needs to be communicated to true.
*/
void set_connections_have_changed();
/**
- * Sets flag indicating whether connection information needs to be
- * communicated to false.
+ * Sets flag indicating whether connection information needs to be communicated to false.
*/
void unset_connections_have_changed();
+ bool have_nonzero_axonal_delays() const;
+
/**
- * Deletes TargetTable and resets processed flags of
- * SourceTable.
+ * Deletes TargetTable and resets processed flags of SourceTable.
*
- * This function must be called if connections are
- * created after connections have been communicated previously. It
- * basically restores the connection infrastructure to a state where
- * all information only exists on the postsynaptic side.
+ * This function must be called if connections are created after connections have been communicated previously. It
+ * basically restores the connection infrastructure to a state where all information only exists on the postsynaptic
+ * side.
*/
void restructure_connection_tables( const size_t tid );
@@ -527,7 +545,9 @@ class ConnectionManager : public ManagerInterface
* \param tid The thread of the target node.
* \param syn_id The synapse model to use.
* \param params The parameters for the connection.
- * \param delay The delay of the connection (optional).
+ * \param delay Total delay of the connection (in ms).
+ * \param dendritic_delay Dendritic delay of the connection (in ms).
+ * \param axonal_delay Axonal delay of the connection (in ms).
* \param weight The weight of the connection (optional).
*/
void connect_( Node& source,
@@ -537,6 +557,8 @@ class ConnectionManager : public ManagerInterface
const synindex syn_id,
const DictionaryDatum& params,
const double delay = numerics::nan,
+ const double dendritic_delay = numerics::nan,
+ const double axonal_delay = numerics::nan,
const double weight = numerics::nan );
/**
@@ -563,17 +585,17 @@ class ConnectionManager : public ManagerInterface
const size_t tid,
const synindex syn_id,
const DictionaryDatum& params,
- const double delay = NAN,
- const double weight = NAN );
+ const double delay = numerics::nan,
+ const double weight = numerics::nan );
/**
* connect_from_device_ is used to establish a connection between a sender and
* receiving node if the sender does not have proxies.
*
- * The parameters delay and weight have the default value NAN.
- * NAN is a special value in cmath, which describes double values that
+ * The parameters delay and weight have the default value numerics::nan.
+ * numerics::nan is a special value in C++, which describes double values that
* are not a number. If delay or weight is omitted in an connect call,
- * NAN indicates this and weight/delay are set only, if they are valid.
+ * numerics::nan indicates this and weight/delay are set only, if they are valid.
*
* \param source A reference to the sending Node.
* \param target A reference to the receiving Node.
@@ -589,8 +611,8 @@ class ConnectionManager : public ManagerInterface
const size_t tid,
const synindex syn_id,
const DictionaryDatum& params,
- const double delay = NAN,
- const double weight = NAN );
+ const double delay = numerics::nan,
+ const double weight = numerics::nan );
/**
* Increases the connection count.
@@ -665,6 +687,9 @@ class ConnectionManager : public ManagerInterface
//! simulate.
bool connections_have_changed_;
+ //! True if any connection uses axonal delays on given thread.
+ std::vector< bool > have_nonzero_axonal_delays_;
+
//! true if GetConnections has been called.
bool get_connections_has_been_called_;
@@ -697,6 +722,9 @@ class ConnectionManager : public ManagerInterface
//! For each thread, store (syn_id, compressed_spike_data_map_::iterator) pair for next iteration while filling target
//! buffers
std::vector< std::pair< size_t, std::map< size_t, CSDMapEntry >::const_iterator > > iteration_state_;
+
+ //! Number of weight corrections required for STDP synapses with predominant axonal delays during the whole simulation
+ size_t num_corrections_;
};
inline bool
@@ -807,6 +835,13 @@ ConnectionManager::connections_have_changed() const
return connections_have_changed_;
}
+inline bool
+ConnectionManager::have_nonzero_axonal_delays() const
+{
+ return std::any_of(
+ have_nonzero_axonal_delays_.cbegin(), have_nonzero_axonal_delays_.cend(), []( const bool b ) { return b; } );
+}
+
inline void
ConnectionManager::add_target( const size_t tid, const size_t target_rank, const TargetData& target_data )
{
@@ -897,6 +932,19 @@ ConnectionManager::send( const size_t tid,
connections_[ tid ][ syn_id ]->send( tid, lcid, cm, e );
}
+inline void
+ConnectionManager::correct_synapse_stdp_ax_delay( const size_t tid,
+ const synindex syn_id,
+ const size_t lcid,
+ const double t_last_pre_spike,
+ double& weight_revert,
+ const double t_post_spike )
+{
+ ++num_corrections_;
+ connections_[ tid ][ syn_id ]->correct_synapse_stdp_ax_delay(
+ tid, syn_id, lcid, t_last_pre_spike, weight_revert, t_post_spike );
+}
+
inline void
ConnectionManager::restructure_connection_tables( const size_t tid )
{
diff --git a/nestkernel/connector_base.h b/nestkernel/connector_base.h
index 7cdd91b1e8..712978bb13 100644
--- a/nestkernel/connector_base.h
+++ b/nestkernel/connector_base.h
@@ -54,12 +54,12 @@ namespace nest
{
/**
- * Base class to allow storing Connectors for different synapse types
- * in vectors. We define the interface here to avoid casting.
+ * Base class to allow storing Connectors for different synapse types in vectors. We define the interface here to avoid
+ * casting.
*
- * @note If any member functions need to do something special for a given connection type,
- * declare specializations in the corresponding header file and define them in the corresponding
- * source file. For an example, see `eprop_synapse_bsshslm_2020`.
+ * @note If any member functions need to do something special for a given connection type, declare specializations in
+ * the corresponding header file and define them in the corresponding source file. For an example, see
+ * `eprop_synapse_bsshslm_2020`.
*/
class ConnectorBase
{
@@ -71,8 +71,7 @@ class ConnectorBase
virtual ~ConnectorBase() {};
/**
- * Return syn_id_ of the synapse type of this Connector (index in
- * list of synapse prototypes).
+ * Return syn_id_ of the synapse type of this Connector (index in list of synapse prototypes).
*/
virtual synindex get_syn_id() const = 0;
@@ -82,21 +81,18 @@ class ConnectorBase
virtual size_t size() const = 0;
/**
- * Write status of the connection at position lcid to the dictionary
- * dict.
+ * Write status of the connection at position lcid to the dictionary dict.
*/
virtual void get_synapse_status( const size_t tid, const size_t lcid, DictionaryDatum& dict ) const = 0;
/**
- * Set status of the connection at position lcid according to the
- * dictionary dict.
+ * Set status of the connection at position lcid according to the dictionary dict.
*/
virtual void set_synapse_status( const size_t lcid, const DictionaryDatum& dict, ConnectorModel& cm ) = 0;
/**
- * Add ConnectionID with given source_node_id and lcid to conns. If
- * target_node_id is given, only add connection if target_node_id matches
- * the node_id of the target of the connection.
+ * Add ConnectionID with given source_node_id and lcid to conns. If target_node_id is given, only add connection if
+ * target_node_id matches the node_id of the target of the connection.
*/
virtual void get_connection( const size_t source_node_id,
const size_t target_node_id,
@@ -106,9 +102,8 @@ class ConnectorBase
std::deque< ConnectionID >& conns ) const = 0;
/**
- * Add ConnectionID with given source_node_id and lcid to conns. If
- * target_neuron_node_ids is given, only add connection if
- * target_neuron_node_ids contains the node ID of the target of the connection.
+ * Add ConnectionID with given source_node_id and lcid to conns. If target_neuron_node_ids is given, only add
+ * connection if target_neuron_node_ids contains the node ID of the target of the connection.
*/
virtual void get_connection_with_specified_targets( const size_t source_node_id,
const std::vector< size_t >& target_neuron_node_ids,
@@ -118,9 +113,8 @@ class ConnectorBase
std::deque< ConnectionID >& conns ) const = 0;
/**
- * Add ConnectionIDs with given source_node_id to conns, looping over
- * all lcids. If target_node_id is given, only add connection if
- * target_node_id matches the node ID of the target of the connection.
+ * Add ConnectionIDs with given source_node_id to conns, looping over all lcids. If target_node_id is given, only add
+ * connection if target_node_id matches the node ID of the target of the connection.
*/
virtual void get_all_connections( const size_t source_node_id,
const size_t target_node_id,
@@ -129,15 +123,13 @@ class ConnectorBase
std::deque< ConnectionID >& conns ) const = 0;
/**
- * For a given target_node_id add lcids of all connections with matching
- * node ID of target to source_lcids.
+ * For a given target_node_id add lcids of all connections with matching node ID of target to source_lcids.
*/
virtual void
get_source_lcids( const size_t tid, const size_t target_node_id, std::vector< size_t >& source_lcids ) const = 0;
/**
- * For a given start_lcid add node IDs of all targets that belong to the
- * same source to target_node_ids.
+ * For a given start_lcid add node IDs of all targets that belong to the same source to target_node_ids.
*/
virtual void get_target_node_ids( const size_t tid,
const size_t start_lcid,
@@ -155,12 +147,31 @@ class ConnectorBase
virtual void send_to_all( const size_t tid, const std::vector< ConnectorModel* >& cm, Event& e ) = 0;
/**
- * Send the event e to the connection at position lcid. Return bool
- * indicating whether the following connection belongs to the same
- * source.
+ * Send the event e to the connection at position lcid. Return bool indicating whether the following connection
+ * belongs to the same source.
*/
virtual size_t send( const size_t tid, const size_t lcid, const std::vector< ConnectorModel* >& cm, Event& e ) = 0;
+ /**
+ * On occurrence of a post-synaptic spike, correct the weight update of a previous pre-synaptic spike which was
+ * processed before the current post-synaptic spike, but had to be processed after it, if it was known at this point
+ * in time.
+ *
+ * @param tid The thread storing the synapse.
+ * @param syn_id Synapse type.
+ * @param lcid Local index of the synapse in the array of connections of the same type for this thread.
+ * @param t_last_pre_spike Time of the last pre-synaptic spike before the pre-synaptic spike which needs a correction.
+ * @param weight_revert The synaptic weight before depression after facilitation as baseline for potential later
+ * correction.
+ * @param t_post_spike Time of the current post-synaptic spike.
+ */
+ virtual void correct_synapse_stdp_ax_delay( const size_t tid,
+ const synindex syn_id,
+ const size_t lcid,
+ const double t_last_pre_spike,
+ double& weight_revert,
+ const double t_post_spike ) = 0;
+
virtual void
send_weight_event( const size_t tid, const unsigned int lcid, Event& e, const CommonSynapseProperties& cp ) = 0;
@@ -179,31 +190,26 @@ class ConnectorBase
virtual void sort_connections( BlockVector< Source >& ) = 0;
/**
- * Set a flag in the connection indicating whether the following
- * connection belongs to the same source.
+ * Set a flag in the connection indicating whether the following connection belongs to the same source.
*/
virtual void set_source_has_more_targets( const size_t lcid, const bool has_more_targets ) = 0;
/**
- * Return lcid of the first connection after start_lcid (inclusive)
- * where the node_id of the target matches target_node_id. If there are no matches,
- * the function returns invalid_index.
+ * Return lcid of the first connection after start_lcid (inclusive) where the node_id of the target matches
+ * target_node_id. If there are no matches, the function returns invalid_index.
*/
virtual size_t find_first_target( const size_t tid, const size_t start_lcid, const size_t target_node_id ) const = 0;
/**
- * Return lcid of first connection where the node ID of the target
- * matches target_node_id; consider only the connections with lcids
- * given in matching_lcids. If there is no match, the function returns
- * invalid_index.
+ * Return lcid of first connection where the node ID of the target matches target_node_id; consider only the
+ * connections with lcids given in matching_lcids. If there is no match, the function returns invalid_index.
*/
virtual size_t find_matching_target( const size_t tid,
const std::vector< size_t >& matching_lcids,
const size_t target_node_id ) const = 0;
/**
- * Disable the transfer of events through the connection at position
- * lcid.
+ * Disable the transfer of events through the connection at position lcid.
*/
virtual void disable_connection( const size_t lcid ) = 0;
@@ -408,6 +414,9 @@ class Connector : public ConnectorBase
e.set_port( lcid + lcid_offset );
if ( not conn.is_disabled() )
{
+ // non-local sender -> receiver retrieves ID of sender Node from SourceTable based on tid, syn_id, lcid
+ // only if needed, as this is computationally costly
+ e.set_sender_node_id_info( tid, syn_id_, lcid + lcid_offset );
// Some synapses, e.g., bernoulli_synapse, may not send an event after all
const bool event_sent = conn.send( e, tid, cp );
if ( event_sent )
@@ -425,6 +434,13 @@ class Connector : public ConnectorBase
return 1 + lcid_offset; // event was delivered to at least one target
}
+ void correct_synapse_stdp_ax_delay( const size_t tid,
+ const synindex syn_id,
+ const size_t lcid,
+ const double t_last_pre_spike,
+ double& weight_revert,
+ const double t_post_spike ) override;
+
// Implemented in connector_base_impl.h
void
send_weight_event( const size_t tid, const unsigned int lcid, Event& e, const CommonSynapseProperties& cp ) override;
diff --git a/nestkernel/connector_base_impl.h b/nestkernel/connector_base_impl.h
index 1c1b77a28f..fd61453293 100644
--- a/nestkernel/connector_base_impl.h
+++ b/nestkernel/connector_base_impl.h
@@ -61,6 +61,21 @@ Connector< ConnectionT >::send_weight_event( const size_t tid,
}
}
+template < typename ConnectionT >
+void
+Connector< ConnectionT >::correct_synapse_stdp_ax_delay( const size_t tid,
+ const synindex syn_id,
+ const size_t lcid,
+ const double t_last_pre_spike,
+ double& weight_revert,
+ const double t_post_spike )
+{
+ typename ConnectionT::CommonPropertiesType const& cp = static_cast< GenericConnectorModel< ConnectionT >* >(
+ kernel().model_manager.get_connection_models( tid )[ syn_id ] )
+ ->get_common_properties();
+ C_[ lcid ].correct_synapse_stdp_ax_delay( tid, t_last_pre_spike, weight_revert, t_post_spike, cp );
+}
+
} // of namespace nest
#endif
diff --git a/nestkernel/connector_model.h b/nestkernel/connector_model.h
index 0a7f83ce8e..c92d6184b9 100644
--- a/nestkernel/connector_model.h
+++ b/nestkernel/connector_model.h
@@ -98,8 +98,10 @@ class ConnectorModel
std::vector< ConnectorBase* >& hetconn,
const synindex syn_id,
const DictionaryDatum& d,
- const double delay = NAN,
- const double weight = NAN ) = 0;
+ const double delay = numerics::nan,
+ const double dendritic_delay = numerics::nan,
+ const double axonal_delay = numerics::nan,
+ const double weight = numerics::nan ) = 0;
virtual ConnectorModel* clone( std::string, synindex syn_id ) const = 0;
@@ -119,6 +121,8 @@ class ConnectorModel
*/
virtual void check_synapse_params( const DictionaryDatum& ) const = 0;
+ virtual void check_valid_default_delay_parameters( DictionaryDatum syn_params ) const = 0;
+
virtual SecondaryEvent* get_secondary_event() = 0;
virtual size_t get_syn_id() const = 0;
@@ -157,11 +161,13 @@ class GenericConnectorModel : public ConnectorModel
ConnectionT default_connection_;
size_t receptor_type_;
+ synindex syn_id_;
public:
GenericConnectorModel( const std::string name )
: ConnectorModel( name, ConnectionT::properties )
, receptor_type_( 0 )
+ , syn_id_( invalid_synindex )
{
}
@@ -170,6 +176,7 @@ class GenericConnectorModel : public ConnectorModel
, cp_( cm.cp_ )
, default_connection_( cm.default_connection_ )
, receptor_type_( cm.receptor_type_ )
+ , syn_id_( cm.syn_id_ )
{
}
@@ -179,6 +186,8 @@ class GenericConnectorModel : public ConnectorModel
const synindex syn_id,
const DictionaryDatum& d,
const double delay,
+ const double dendritic_delay,
+ const double axonal_delay,
const double weight ) override;
ConnectorModel* clone( std::string, synindex ) const override;
@@ -199,6 +208,8 @@ class GenericConnectorModel : public ConnectorModel
void check_synapse_params( const DictionaryDatum& syn_spec ) const override;
+ void check_valid_default_delay_parameters( DictionaryDatum syn_params ) const override;
+
SecondaryEvent*
get_secondary_event() override
{
@@ -213,15 +224,7 @@ class GenericConnectorModel : public ConnectorModel
private:
void used_default_delay();
-
- void add_connection_( Node& src,
- Node& tgt,
- std::vector< ConnectorBase* >& hetconn,
- const synindex syn_id,
- ConnectionT& c,
- const size_t receptor_type );
-
-}; // GenericConnectorModel
+};
} // namespace nest
diff --git a/nestkernel/connector_model_impl.h b/nestkernel/connector_model_impl.h
index fc831cb916..22888b0bc7 100644
--- a/nestkernel/connector_model_impl.h
+++ b/nestkernel/connector_model_impl.h
@@ -33,8 +33,10 @@
#include "enum_bitfield.h"
// Includes from nestkernel:
+#include "connection.h"
#include "connector_base.h"
#include "delay_checker.h"
+#include "delay_types.h"
#include "kernel_manager.h"
#include "nest_time.h"
#include "nest_timeconverter.h"
@@ -46,22 +48,6 @@
namespace nest
{
-// standard implementation to obtain the default delay
-// synapse types with homogeneous delays must provide a specialization
-// that returns the default delay from CommonProperties (or from else where)
-// template
-// double get_default_delay(const GenericConnectorModel &cm)
-// {
-// //std::cout << "standard implementation of get_default_delay" << std::endl;
-// return cm.get_default_connection().get_delay();
-// }
-
-// template
-// SynIdDelay & syn_id_delay(const GenericConnectorModel &cm)
-// {
-// return cm.get_default_connection().get_syn_id_delay();
-// }
-
template < typename ConnectionT >
ConnectorModel*
GenericConnectorModel< ConnectionT >::clone( std::string name, synindex syn_id ) const
@@ -129,12 +115,12 @@ GenericConnectorModel< ConnectionT >::set_status( const DictionaryDatum& d )
kernel().connection_manager.get_delay_checker().freeze_delay_update();
cp_.set_status( d, *this );
+
default_connection_.set_status( d, *this );
kernel().connection_manager.get_delay_checker().enable_delay_update();
- // we've possibly just got a new default delay. So enforce checking next time
- // it is used
+ // we've possibly just got a new default delay. So enforce checking next time it is used
default_delay_needs_check_ = true;
}
@@ -175,7 +161,7 @@ GenericConnectorModel< ConnectionT >::used_default_delay()
{
if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
{
- const double d = default_connection_.get_delay();
+ const double d = default_connection_.get_delay_ms();
kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( d );
}
// Let connections without delay contribute to the delay extrema with
@@ -192,9 +178,8 @@ GenericConnectorModel< ConnectionT >::used_default_delay()
}
catch ( BadDelay& e )
{
- throw BadDelay( default_connection_.get_delay(),
- String::compose( "Default delay of '%1' must be between min_delay %2 "
- "and max_delay %3.",
+ throw BadDelay( default_connection_.get_delay_ms(),
+ String::compose( "Default delay of '%1' must be between min_delay %2 and max_delay %3.",
get_name(),
Time::delay_steps_to_ms( kernel().connection_manager.get_min_delay() ),
Time::delay_steps_to_ms( kernel().connection_manager.get_max_delay() ) ) );
@@ -207,14 +192,39 @@ template < typename ConnectionT >
size_t
GenericConnectorModel< ConnectionT >::get_syn_id() const
{
- return default_connection_.get_syn_id();
+ return syn_id_;
}
template < typename ConnectionT >
void
GenericConnectorModel< ConnectionT >::set_syn_id( synindex syn_id )
{
- default_connection_.set_syn_id( syn_id );
+ syn_id_ = syn_id;
+}
+
+template < typename ConnectionT >
+void
+GenericConnectorModel< ConnectionT >::check_valid_default_delay_parameters( DictionaryDatum syn_params ) const
+{
+ if constexpr ( std::is_base_of< Connection< TargetIdentifierPtrRport, AxonalDendriticDelay >, ConnectionT >::value
+ or std::is_base_of< Connection< TargetIdentifierIndex, AxonalDendriticDelay >, ConnectionT >::value )
+ {
+ if ( syn_params->known( names::delay ) )
+ {
+ throw BadParameter( "Synapse type does not support explicitly setting total transmission delay." );
+ }
+ }
+ else
+ {
+ if ( syn_params->known( names::dendritic_delay ) )
+ {
+ throw BadParameter( "Synapse type does not support explicitly setting dendritic delay." );
+ }
+ if ( syn_params->known( names::axonal_delay ) )
+ {
+ throw BadParameter( "Synapse type does not support explicitly setting axonal delay." );
+ }
+ }
}
template < typename ConnectionT >
@@ -225,58 +235,105 @@ GenericConnectorModel< ConnectionT >::add_connection( Node& src,
const synindex syn_id,
const DictionaryDatum& p,
const double delay,
+ const double dendritic_delay,
+ const double axonal_delay,
const double weight )
{
- if ( not numerics::is_nan( delay ) )
+ // create a new instance of the default connection
+ ConnectionT connection = ConnectionT( default_connection_ );
+
+ bool default_delay_used = true;
+
+ if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
{
- if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
+ if constexpr ( std::is_base_of< Connection< TargetIdentifierPtrRport, AxonalDendriticDelay >, ConnectionT >::value
+ or std::is_base_of< Connection< TargetIdentifierIndex, AxonalDendriticDelay >, ConnectionT >::value )
{
- kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay );
- }
+ if ( not numerics::is_nan( delay ) or p->known( names::delay ) )
+ {
+ throw BadProperty( "Setting the total transmission delay via the parameter '" + names::delay.toString()
+ + "' is not allowed for synapse types which use both dendritic and axonal delays, because of ambiguity." );
+ }
- if ( p->known( names::delay ) )
- {
- throw BadParameter(
- "Parameter dictionary must not contain delay if delay is given "
- "explicitly." );
- }
- }
- else
- {
- // check delay
- double delay = 0.0;
+ if ( not numerics::is_nan( dendritic_delay ) and p->known( names::dendritic_delay ) )
+ {
+ throw BadParameter(
+ "Parameter dictionary must not contain dendritic delay if dendritic delay is given explicitly." );
+ }
- if ( updateValue< double >( p, names::delay, delay ) )
- {
- if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
+ if ( not numerics::is_nan( axonal_delay ) and p->known( names::axonal_delay ) )
+ {
+ throw BadParameter( "Parameter dictionary must not contain axonal delay if axonal delay is given explicitly." );
+ }
+
+ double actual_dendritic_delay = dendritic_delay;
+ double actual_axonal_delay = axonal_delay;
+ if ( not numerics::is_nan( dendritic_delay )
+ or updateValue< double >( p, names::dendritic_delay, actual_dendritic_delay ) )
{
- kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay );
+ connection.set_dendritic_delay_ms( actual_dendritic_delay );
+ }
+ if ( not numerics::is_nan( axonal_delay )
+ or updateValue< double >( p, names::axonal_delay, actual_axonal_delay ) )
+ {
+ connection.set_axonal_delay_ms( axonal_delay );
+ }
+ if ( not numerics::is_nan( actual_dendritic_delay ) or not numerics::is_nan( actual_axonal_delay ) )
+ {
+ default_delay_used = false;
}
}
else
{
- used_default_delay();
+ if ( not numerics::is_nan( dendritic_delay ) or p->known( names::dendritic_delay ) )
+ {
+ throw BadParameter( "Synapse type does not support explicitly setting dendritic delay." );
+ }
+
+ if ( not numerics::is_nan( axonal_delay ) or p->known( names::axonal_delay ) )
+ {
+ throw BadParameter( "Synapse type does not support explicitly setting axonal delay." );
+ }
+
+ if ( not numerics::is_nan( delay ) and ( p->known( names::delay ) or p->known( names::dendritic_delay ) ) )
+ {
+ throw BadParameter( "Parameter dictionary must not contain delay if delay is given explicitly." );
+ }
+
+ double actual_delay = delay;
+ if ( updateValue< double >( p, names::delay, actual_delay ) or not numerics::is_nan( delay ) )
+ {
+ connection.set_delay_ms( actual_delay );
+ default_delay_used = false;
+ }
}
}
-
- // create a new instance of the default connection
- ConnectionT connection = ConnectionT( default_connection_ );
+ else if ( p->known( names::delay ) or p->known( names::dendritic_delay ) or p->known( names::axonal_delay )
+ or not numerics::is_nan( delay ) or not numerics::is_nan( dendritic_delay )
+ or not numerics::is_nan( axonal_delay ) )
+ {
+ throw BadProperty( "Delay specified for a connection type which doesn't use delays." );
+ }
if ( not numerics::is_nan( weight ) )
{
connection.set_weight( weight );
}
- if ( not numerics::is_nan( delay ) )
+ if ( not p->empty() )
{
- connection.set_delay( delay );
+ // Reference to connector model needed here to check delay (maybe this could be done one level above?).
+ connection.set_status( p, *this );
}
- if ( not p->empty() )
+ if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
{
- // Reference to connector model needed here to check delay (maybe this could
- // be done one level above?).
- connection.set_status( p, *this );
+ kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( connection.get_delay_ms() );
+ }
+
+ if ( default_delay_used )
+ {
+ used_default_delay();
}
// We must use a local variable here to hold the actual value of the
@@ -288,20 +345,6 @@ GenericConnectorModel< ConnectionT >::add_connection( Node& src,
updateValue< long >( p, names::music_channel, actual_receptor_type );
#endif
updateValue< long >( p, names::receptor_type, actual_receptor_type );
-
- add_connection_( src, tgt, thread_local_connectors, syn_id, connection, actual_receptor_type );
-}
-
-
-template < typename ConnectionT >
-void
-GenericConnectorModel< ConnectionT >::add_connection_( Node& src,
- Node& tgt,
- std::vector< ConnectorBase* >& thread_local_connectors,
- const synindex syn_id,
- ConnectionT& connection,
- const size_t receptor_type )
-{
assert( syn_id != invalid_synindex );
if ( not thread_local_connectors[ syn_id ] )
@@ -313,7 +356,7 @@ GenericConnectorModel< ConnectionT >::add_connection_( Node& src,
ConnectorBase* connector = thread_local_connectors[ syn_id ];
// The following line will throw an exception, if it does not work.
- connection.check_connection( src, tgt, receptor_type, get_common_properties() );
+ connection.check_connection( src, tgt, actual_receptor_type, syn_id, get_common_properties() );
assert( connector );
diff --git a/nestkernel/delay_checker.cpp b/nestkernel/delay_checker.cpp
index 8a1776c98e..ff6268337c 100644
--- a/nestkernel/delay_checker.cpp
+++ b/nestkernel/delay_checker.cpp
@@ -161,9 +161,7 @@ nest::DelayChecker::assert_valid_delay_ms( double requested_new_delay )
const bool bad_max_delay = new_delay > kernel().connection_manager.get_max_delay();
if ( bad_min_delay or bad_max_delay )
{
- throw BadDelay( new_delay_ms,
- "Minimum and maximum delay cannot be changed "
- "after Simulate has been called." );
+ throw BadDelay( new_delay_ms, "Minimum and maximum delay cannot be changed after Simulate has been called." );
}
}
@@ -175,8 +173,7 @@ nest::DelayChecker::assert_valid_delay_ms( double requested_new_delay )
if ( user_set_delay_extrema_ )
{
throw BadDelay( new_delay_ms,
- "Delay must be greater than or equal to min_delay. "
- "You may set min_delay before creating connections." );
+ "Delay must be greater than or equal to min_delay. You may set min_delay before creating connections." );
}
else
{
@@ -192,8 +189,7 @@ nest::DelayChecker::assert_valid_delay_ms( double requested_new_delay )
if ( user_set_delay_extrema_ )
{
throw BadDelay( new_delay_ms,
- "Delay must be smaller than or equal to max_delay. "
- "You may set min_delay before creating connections." );
+ "Delay must be smaller than or equal to max_delay. You may set min_delay before creating connections." );
}
else
{
@@ -240,8 +236,7 @@ nest::DelayChecker::assert_two_valid_delays_steps( long new_delay1, long new_del
if ( user_set_delay_extrema_ )
{
throw BadDelay( Time::delay_steps_to_ms( ldelay ),
- "Delay must be greater than or equal to min_delay. "
- "You may set min_delay before creating connections." );
+ "Delay must be greater than or equal to min_delay. You may set min_delay before creating connections." );
}
else
{
@@ -257,8 +252,7 @@ nest::DelayChecker::assert_two_valid_delays_steps( long new_delay1, long new_del
if ( user_set_delay_extrema_ )
{
throw BadDelay( Time::delay_steps_to_ms( hdelay ),
- "Delay must be smaller than or equal to max_delay. "
- "You may set max_delay before creating connections." );
+ "Delay must be smaller than or equal to max_delay. You may set max_delay before creating connections." );
}
else
{
diff --git a/nestkernel/delay_types.h b/nestkernel/delay_types.h
new file mode 100644
index 0000000000..903a1bd541
--- /dev/null
+++ b/nestkernel/delay_types.h
@@ -0,0 +1,373 @@
+/*
+ * delay_types.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 .
+ *
+ */
+
+#ifndef DELAY_TYPES_H
+#define DELAY_TYPES_H
+
+// Includes from nestkernel:
+#include "kernel_manager.h"
+#include "nest_time.h"
+#include "nest_types.h"
+
+namespace nest
+{
+
+
+/**
+ * Container for a single delay value which is interpreted as total transmission delay or purely dendritic delay by some
+ * models. Implies an axonal delay of 0.
+ */
+struct TotalDelay
+{
+ uint32_t delay_;
+
+ explicit TotalDelay( double d )
+ {
+ set_delay_ms( d );
+ }
+
+ /**
+ * Return the dendritic delay of the connection in steps
+ */
+ long
+ get_dendritic_delay_steps() const
+ {
+ throw BadProperty( "Trying to get dendritic delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Set the dendritic delay of the connection specified in ms
+ */
+ void
+ set_dendritic_delay_steps( const double )
+ {
+ throw BadProperty( "Trying to set dendritic delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Return the dendritic delay of the connection in ms
+ */
+ double
+ get_dendritic_delay_ms() const
+ {
+ throw BadProperty( "Trying to get dendritic delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Set the dendritic delay of the connection specified in ms
+ */
+ void
+ set_dendritic_delay_ms( const double )
+ {
+ throw BadProperty( "Trying to set dendritic delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Return the axonal delay of the connection in steps
+ */
+ long
+ get_axonal_delay_steps() const
+ {
+ throw BadProperty( "Trying to get axonal delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Set the axonal delay of the connection specified in ms
+ */
+ void
+ set_axonal_delay_steps( const double )
+ {
+ throw BadProperty( "Trying to set axonal delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Return the axonal delay of the connection in ms
+ */
+ double
+ get_axonal_delay_ms() const
+ {
+ throw BadProperty( "Trying to get axonal delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Set the axonal delay of the connection specified in ms
+ */
+ void
+ set_axonal_delay_ms( const double )
+ {
+ throw BadProperty( "Trying to set axonal delay on a synapse which only stores the total transmission delay." );
+ }
+
+ /**
+ * Return the delay of the connection in steps
+ */
+ long
+ get_delay_steps() const
+ {
+ return delay_;
+ }
+
+ /**
+ * Set the delay of the connection specified in ms
+ */
+ void
+ set_delay_steps( const long d )
+ {
+ delay_ = d;
+ }
+
+ /**
+ * Return the delay of the connection in ms
+ */
+ double
+ get_delay_ms() const
+ {
+ return Time::delay_steps_to_ms( delay_ );
+ }
+
+ /**
+ * Set the delay of the connection specified in ms
+ */
+ void
+ set_delay_ms( const double d )
+ {
+ delay_ = Time::delay_ms_to_steps( d );
+ }
+
+ void
+ calibrate( const TimeConverter& tc )
+ {
+ Time t = tc.from_old_steps( delay_ );
+ delay_ = t.get_steps();
+
+ if ( delay_ == 0 )
+ {
+ delay_ = 1;
+ }
+ }
+
+ void
+ get_status( DictionaryDatum& d ) const
+ {
+ def< double >( d, names::delay, Time::delay_steps_to_ms( delay_ ) );
+ }
+
+ void
+ set_status( const DictionaryDatum& d, ConnectorModel& )
+ {
+ // Check for allowed combinations. See PR #2989 for more details.
+ if ( d->known( names::dendritic_delay ) or d->known( names::axonal_delay ) )
+ {
+ throw BadParameter( "Synapse type does not support explicitly setting axonal and dendritic delays." );
+ }
+
+ // Update delay values
+ double delay;
+ if ( updateValue< double >( d, names::delay, delay ) )
+ {
+ set_delay_ms( delay );
+ }
+
+ kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( get_delay_ms() );
+ }
+};
+
+//! check legal size
+using success_total_transmission_delay_data_size = StaticAssert< sizeof( TotalDelay ) == 4 >::success;
+
+/**
+ * Container for explicit dendritic and axonal delay values.
+ */
+struct AxonalDendriticDelay
+{
+ uint32_t dendritic_delay_ : NUM_BITS_DENDRITIC_DELAY;
+ uint32_t axonal_delay_ : NUM_BITS_AXONAL_DELAY;
+
+ explicit AxonalDendriticDelay( double d )
+ : axonal_delay_( 0 )
+ {
+ set_dendritic_delay_ms( d );
+ }
+
+ /**
+ * Return the dendritic delay of the connection in steps
+ */
+ long
+ get_dendritic_delay_steps() const
+ {
+ return dendritic_delay_;
+ }
+
+ /**
+ * Set the dendritic delay of the connection specified in ms
+ */
+ void
+ set_dendritic_delay_steps( const long d )
+ {
+ dendritic_delay_ = d;
+ }
+
+ /**
+ * Return the dendritic delay of the connection in ms
+ */
+ double
+ get_dendritic_delay_ms() const
+ {
+ return Time::delay_steps_to_ms( dendritic_delay_ );
+ }
+
+ /**
+ * Set the dendritic delay of the connection specified in ms
+ */
+ void
+ set_dendritic_delay_ms( const double d )
+ {
+ dendritic_delay_ = Time::delay_ms_to_steps( d );
+ }
+
+ /**
+ * Return the axonal delay of the connection in steps
+ */
+ long
+ get_axonal_delay_steps() const
+ {
+ return axonal_delay_;
+ }
+
+ /**
+ * Set the axonal delay of the connection specified in ms
+ */
+ void
+ set_axonal_delay_steps( const long d )
+ {
+ axonal_delay_ = d;
+ }
+
+ /**
+ * Return the axonal delay of the connection in ms
+ */
+ double
+ get_axonal_delay_ms() const
+ {
+ return Time::delay_steps_to_ms( axonal_delay_ );
+ }
+
+ /**
+ * Set the axonal delay of the connection specified in ms
+ */
+ void
+ set_axonal_delay_ms( const double d )
+ {
+ axonal_delay_ = Time::delay_ms_to_steps( d );
+ }
+
+ /**
+ * Return the delay of the connection in steps
+ */
+ long
+ get_delay_steps() const
+ {
+ return dendritic_delay_ + axonal_delay_;
+ }
+
+ /**
+ * Set the delay of the connection specified in ms
+ */
+ void
+ set_delay_steps( const long d )
+ {
+ dendritic_delay_ = d;
+ axonal_delay_ = 0;
+ }
+
+ /**
+ * Return the delay of the connection in ms
+ */
+ double
+ get_delay_ms() const
+ {
+ return Time::delay_steps_to_ms( get_delay_steps() );
+ }
+
+ /**
+ * Set the delay of the connection specified in ms
+ */
+ void
+ set_delay_ms( const double d )
+ {
+ dendritic_delay_ = Time::delay_ms_to_steps( d );
+ axonal_delay_ = 0;
+ }
+
+ void
+ calibrate( const TimeConverter& tc )
+ {
+ Time ax_delay_t = tc.from_old_steps( axonal_delay_ );
+ Time dend_delay_t = tc.from_old_steps( dendritic_delay_ );
+ axonal_delay_ = ax_delay_t.get_steps();
+ dendritic_delay_ = dend_delay_t.get_steps();
+
+ if ( dendritic_delay_ == 0 )
+ {
+ dendritic_delay_ = 1;
+ }
+ }
+
+ void
+ get_status( DictionaryDatum& d ) const
+ {
+ def< double >( d, names::dendritic_delay, Time::delay_steps_to_ms( dendritic_delay_ ) );
+ def< double >( d, names::axonal_delay, Time::delay_steps_to_ms( axonal_delay_ ) );
+ def< double >( d, names::delay, Time::delay_steps_to_ms( axonal_delay_ + dendritic_delay_ ) );
+ }
+
+ void
+ set_status( const DictionaryDatum& d, ConnectorModel& )
+ {
+ if ( d->known( names::delay ) )
+ {
+ throw BadParameter( "Setting the total transmission delay via the parameter '" + names::delay.toString()
+ + "' is not allowed for synapse types which use both dendritic and axonal delays, because of ambiguity." );
+ }
+
+ // Update delay values
+ double dendritic_delay = get_dendritic_delay_ms();
+ if ( updateValue< double >( d, names::dendritic_delay, dendritic_delay ) )
+ {
+ set_dendritic_delay_ms( dendritic_delay );
+ }
+ double axonal_delay = get_axonal_delay_ms();
+ if ( updateValue< double >( d, names::axonal_delay, axonal_delay ) )
+ {
+ set_axonal_delay_ms( axonal_delay );
+ }
+
+ kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( get_delay_ms() );
+ }
+};
+
+//! check legal size
+using success_axonal_dendritic_delay_data_size = StaticAssert< sizeof( AxonalDendriticDelay ) == 4 >::success;
+
+}
+
+#endif
diff --git a/nestkernel/event.cpp b/nestkernel/event.cpp
index 6d33a5f615..ec3ee12f24 100644
--- a/nestkernel/event.cpp
+++ b/nestkernel/event.cpp
@@ -73,6 +73,12 @@ SpikeEvent::operator()()
receiver_->handle( *this );
}
+void
+CorrectionSpikeEvent::operator()()
+{
+ receiver_->handle( *this );
+}
+
void
WeightRecorderEvent::operator()()
{
diff --git a/nestkernel/event.h b/nestkernel/event.h
index 13860bd88a..dee2ef9c9f 100644
--- a/nestkernel/event.h
+++ b/nestkernel/event.h
@@ -322,6 +322,12 @@ class Event
*/
void set_stamp( Time const& );
+ /**
+ * Returns the sender_spike_data_
+ * The sender_spike_data_ is a SpikeData object
+ */
+ SpikeData get_sender_spike_data() const;
+
protected:
size_t sender_node_id_; //!< node ID of sender or 0
SpikeData sender_spike_data_; //!< spike data of sender node, in some cases required to retrieve node ID
@@ -443,6 +449,43 @@ SpikeEvent::get_multiplicity() const
return multiplicity_;
}
+class CorrectionSpikeEvent : public SpikeEvent
+{
+public:
+ CorrectionSpikeEvent();
+ void operator()() override;
+ CorrectionSpikeEvent* clone() const override;
+
+ void set_new_weight( double );
+ double get_new_weight() const;
+
+protected:
+ double new_weight_;
+};
+
+inline CorrectionSpikeEvent::CorrectionSpikeEvent()
+ : new_weight_( 0. )
+{
+}
+
+inline CorrectionSpikeEvent*
+CorrectionSpikeEvent::clone() const
+{
+ return new CorrectionSpikeEvent( *this );
+}
+
+inline void
+CorrectionSpikeEvent::set_new_weight( double new_weight )
+{
+ new_weight_ = new_weight;
+}
+
+inline double
+CorrectionSpikeEvent::get_new_weight() const
+{
+ return new_weight_;
+}
+
/**
* Event for recording the weight of a spike.
@@ -1031,6 +1074,12 @@ Event::set_rport( size_t rp )
{
rp_ = rp;
}
+
+inline SpikeData
+Event::get_sender_spike_data() const
+{
+ return sender_spike_data_;
+}
}
#endif /* EVENT_H */
diff --git a/nestkernel/event_delivery_manager.cpp b/nestkernel/event_delivery_manager.cpp
index 8ba790b740..ca65d63970 100644
--- a/nestkernel/event_delivery_manager.cpp
+++ b/nestkernel/event_delivery_manager.cpp
@@ -663,7 +663,6 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik
tid_batch[ j ] = spike_data.get_tid();
syn_id_batch[ j ] = spike_data.get_syn_id();
lcid_batch[ j ] = spike_data.get_lcid();
- se_batch[ j ].set_sender_node_id_info( tid_batch[ j ], syn_id_batch[ j ], lcid_batch[ j ] );
}
for ( size_t j = 0; j < SPIKES_PER_BATCH; ++j )
{
@@ -684,7 +683,6 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik
tid_batch[ j ] = spike_data.get_tid();
syn_id_batch[ j ] = spike_data.get_syn_id();
lcid_batch[ j ] = spike_data.get_lcid();
- se_batch[ j ].set_sender_node_id_info( tid_batch[ j ], syn_id_batch[ j ], lcid_batch[ j ] );
}
for ( size_t j = 0; j < num_remaining_entries; ++j )
{
@@ -718,15 +716,6 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik
lcid_batch[ j ] = compressed_spike_data[ tid ].get_lcid();
}
for ( size_t j = 0; j < SPIKES_PER_BATCH; ++j )
- {
- if ( lcid_batch[ j ] != invalid_lcid )
- {
- // non-local sender -> receiver retrieves ID of sender Node from SourceTable based on tid, syn_id, lcid
- // only if needed, as this is computationally costly
- se_batch[ j ].set_sender_node_id_info( tid, syn_id_batch[ j ], lcid_batch[ j ] );
- }
- }
- for ( size_t j = 0; j < SPIKES_PER_BATCH; ++j )
{
if ( lcid_batch[ j ] != invalid_lcid )
{
@@ -755,15 +744,6 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik
lcid_batch[ j ] = compressed_spike_data[ tid ].get_lcid();
}
for ( size_t j = 0; j < num_remaining_entries; ++j )
- {
- if ( lcid_batch[ j ] != invalid_lcid )
- {
- // non-local sender -> receiver retrieves ID of sender Node from SourceTable based on tid, syn_id, lcid
- // only if needed, as this is computationally costly
- se_batch[ j ].set_sender_node_id_info( tid, syn_id_batch[ j ], lcid_batch[ j ] );
- }
- }
- for ( size_t j = 0; j < num_remaining_entries; ++j )
{
if ( lcid_batch[ j ] != invalid_lcid )
{
diff --git a/nestkernel/event_delivery_manager.h b/nestkernel/event_delivery_manager.h
index dbdbe1483b..bf99e3d24b 100644
--- a/nestkernel/event_delivery_manager.h
+++ b/nestkernel/event_delivery_manager.h
@@ -314,22 +314,18 @@ class EventDeliveryManager : public ManagerInterface
/**
- * Reads spikes from MPI buffers and delivers them to ringbuffer of
- * nodes.
+ * Reads spikes from MPI buffers and delivers them to ringbuffer of nodes.
*/
template < typename SpikeDataT >
void deliver_events_( const size_t tid, const std::vector< SpikeDataT >& recv_buffer );
/**
- * Deletes all spikes from spike registers and resets spike
- * counters.
+ * Deletes all spikes from spike registers and resets spike counters.
*/
void reset_spike_register_( const size_t tid );
/**
- * Returns true if spike has been moved to MPI buffer, such that it
- * can be removed by clean_spike_register. Required static function
- * by std::remove_if.
+ * Resizes spike registers according minimal delay so it can accommodate all possible lags.
*/
static bool is_marked_for_removal_( const Target& target );
@@ -347,22 +343,19 @@ class EventDeliveryManager : public ManagerInterface
TargetSendBufferPosition& send_buffer_position );
/**
- * Sets marker in MPI buffer that signals end of communication
- * across MPI ranks.
+ * Sets marker in MPI buffer that signals end of communication across MPI ranks.
*/
void set_complete_marker_target_data_( const AssignedRanks& assigned_ranks,
const TargetSendBufferPosition& send_buffer_position );
/**
- * Reads TargetData objects from MPI buffers and creates Target
- * objects on TargetTable (presynaptic part of connection
- * infrastructure).
+ * Reads TargetData objects from MPI buffers and creates Target objects on TargetTable (presynaptic part of
+ * connection infrastructure).
*/
bool distribute_target_data_buffers_( const size_t tid );
/**
- * Sends event e to all targets of node source. Delivers events from
- * devices directly to targets.
+ * Sends event e to all targets of node source. Delivers events from devices directly to targets.
*/
template < class EventT >
void send_local_( Node& source, EventT& e, const long lag );
@@ -370,8 +363,7 @@ class EventDeliveryManager : public ManagerInterface
//--------------------------------------------------//
- bool off_grid_spiking_; //!< indicates whether spikes are not constrained to
- //!< the grid
+ bool off_grid_spiking_; //!< indicates whether spikes are not constrained to the grid
/**
* Table of pre-computed modulos.
diff --git a/nestkernel/model_manager.cpp b/nestkernel/model_manager.cpp
index a656285f13..2bdd50260b 100644
--- a/nestkernel/model_manager.cpp
+++ b/nestkernel/model_manager.cpp
@@ -476,4 +476,11 @@ ModelManager::create_proxynode_( size_t t, int model_id )
return proxy;
}
+void
+ModelManager::check_valid_default_delay_parameters( const synindex syn_id, DictionaryDatum syn_params )
+{
+ get_connection_model( syn_id, kernel().vp_manager.get_thread_id() )
+ .check_valid_default_delay_parameters( syn_params );
+}
+
} // namespace nest
diff --git a/nestkernel/model_manager.h b/nestkernel/model_manager.h
index 924535a780..71efd20f06 100644
--- a/nestkernel/model_manager.h
+++ b/nestkernel/model_manager.h
@@ -114,7 +114,7 @@ class ModelManager : public ManagerInterface
*
* @param name The name under which the ConnectorModel will be registered.
*/
- template < template < typename targetidentifierT > class ConnectionT >
+ template < template < typename > class ConnectionT >
void register_connection_model( const std::string& name );
/**
@@ -176,6 +176,8 @@ class ModelManager : public ManagerInterface
SecondaryEvent& get_secondary_event_prototype( const synindex syn_id, const size_t tid );
+ void check_valid_default_delay_parameters( const synindex syn_id, DictionaryDatum syn_params );
+
private:
/**
* Delete all models and clear the modeldict
@@ -190,7 +192,7 @@ class ModelManager : public ManagerInterface
size_t register_node_model_( Model* model );
- template < typename CompleteConnecionT >
+ template < typename CompleteConnectionT >
void register_specific_connection_model_( const std::string& name );
/**
diff --git a/nestkernel/nest.cpp b/nestkernel/nest.cpp
index 2add49bcb6..33db13f202 100644
--- a/nestkernel/nest.cpp
+++ b/nestkernel/nest.cpp
@@ -198,12 +198,15 @@ connect_arrays( long* sources,
long* targets,
double* weights,
double* delays,
+ double* dendritic_delay,
+ double* axonal_delays,
std::vector< std::string >& p_keys,
double* p_values,
size_t n,
std::string syn_model )
{
- kernel().connection_manager.connect_arrays( sources, targets, weights, delays, p_keys, p_values, n, syn_model );
+ kernel().connection_manager.connect_arrays(
+ sources, targets, weights, delays, dendritic_delay, axonal_delays, p_keys, p_values, n, syn_model );
}
ArrayDatum
diff --git a/nestkernel/nest.h b/nestkernel/nest.h
index e49c7dcb5e..3525956031 100644
--- a/nestkernel/nest.h
+++ b/nestkernel/nest.h
@@ -123,6 +123,8 @@ void connect_arrays( long* sources,
long* targets,
double* weights,
double* delays,
+ double* dendritic_delays,
+ double* axonal_delays,
std::vector< std::string >& p_keys,
double* p_values,
size_t n,
diff --git a/nestkernel/nest_names.cpp b/nestkernel/nest_names.cpp
index 2b1d98435e..25cb92a8d3 100644
--- a/nestkernel/nest_names.cpp
+++ b/nestkernel/nest_names.cpp
@@ -75,6 +75,7 @@ const Name asc_init( "asc_init" );
const Name asc_r( "asc_r" );
const Name available( "available" );
const Name average_gradient( "average_gradient" );
+const Name axonal_delay( "axonal_delay" );
const Name azimuth_angle( "azimuth_angle" );
const Name b( "b" );
@@ -134,6 +135,7 @@ const Name delta_IP3( "delta_IP3" );
const Name delta_P( "delta_P" );
const Name delta_tau( "delta_tau" );
const Name dendritic_curr( "dendritic_curr" );
+const Name dendritic_delay( "dendritic_delay" );
const Name dendritic_exc( "dendritic_exc" );
const Name dendritic_inh( "dendritic_inh" );
const Name dg( "dg" );
@@ -356,6 +358,7 @@ const Name node_uses_wfr( "node_uses_wfr" );
const Name noise( "noise" );
const Name noisy_rate( "noisy_rate" );
const Name num_connections( "num_connections" );
+const Name num_corrections( "num_corrections" );
const Name num_processes( "num_processes" );
const Name number_of_connections( "number_of_connections" );
diff --git a/nestkernel/nest_names.h b/nestkernel/nest_names.h
index 44a75f62d0..34e6c84009 100644
--- a/nestkernel/nest_names.h
+++ b/nestkernel/nest_names.h
@@ -101,6 +101,7 @@ extern const Name asc_init;
extern const Name asc_r;
extern const Name available;
extern const Name average_gradient;
+extern const Name axonal_delay;
extern const Name azimuth_angle;
extern const Name b;
@@ -161,6 +162,7 @@ extern const Name delta_IP3;
extern const Name delta_P;
extern const Name delta_tau;
extern const Name dendritic_curr;
+extern const Name dendritic_delay;
extern const Name dendritic_exc;
extern const Name dendritic_inh;
extern const Name dg;
@@ -384,6 +386,7 @@ extern const Name node_uses_wfr;
extern const Name noise;
extern const Name noisy_rate;
extern const Name num_connections;
+extern const Name num_corrections;
extern const Name num_processes;
extern const Name number_of_connections;
diff --git a/nestkernel/nest_time.cpp b/nestkernel/nest_time.cpp
index 93b7e6f79f..35dd29af84 100644
--- a/nestkernel/nest_time.cpp
+++ b/nestkernel/nest_time.cpp
@@ -36,6 +36,9 @@
#include "integerdatum.h"
#include "token.h"
+// Includes from nestkernel:
+#include "exceptions.h"
+
using namespace nest;
const double Time::Range::TICS_PER_MS_DEFAULT = CONFIG_TICS_PER_MS;
@@ -205,3 +208,23 @@ operator<<( std::ostream& strm, const Time& t )
return strm;
}
+
+double
+Time::delay_steps_to_ms( long steps )
+{
+ if ( steps < 0 )
+ {
+ throw BadDelay( steps * Range::MS_PER_STEP, "Delay value must be greater than or equal to zero." );
+ }
+ return steps * Range::MS_PER_STEP;
+}
+
+long
+Time::delay_ms_to_steps( double ms )
+{
+ if ( ms < 0 )
+ {
+ throw BadDelay( ms, "Delay value must be greater than or equal to zero." );
+ }
+ return ld_round( ms * Range::STEPS_PER_MS );
+}
diff --git a/nestkernel/nest_time.h b/nestkernel/nest_time.h
index f579af5659..56237965bb 100644
--- a/nestkernel/nest_time.h
+++ b/nestkernel/nest_time.h
@@ -535,17 +535,9 @@ class Time
* ld_round, which is different from ms_stamp --> Time mapping, which rounds
* up. See #903.
*/
- static double
- delay_steps_to_ms( long steps )
- {
- return steps * Range::MS_PER_STEP;
- }
+ static double delay_steps_to_ms( long steps );
- static long
- delay_ms_to_steps( double ms )
- {
- return ld_round( ms * Range::STEPS_PER_MS );
- }
+ static long delay_ms_to_steps( double ms );
};
/////////////////////////////////////////////////////////////
diff --git a/nestkernel/node.cpp b/nestkernel/node.cpp
index 6f54cc1075..3de045f0e1 100644
--- a/nestkernel/node.cpp
+++ b/nestkernel/node.cpp
@@ -143,6 +143,12 @@ Node::get_local_device_id() const
return invalid_index;
}
+void
+Node::add_correction_entry_stdp_ax_delay( SpikeEvent&, const double, const double, const double )
+{
+ throw UnexpectedEvent( "Node does not support framework for STDP synapses with predominantly axonal delays." );
+}
+
DictionaryDatum
Node::get_status_base()
{
@@ -204,7 +210,7 @@ size_t
Node::send_test_event( Node&, size_t, synindex, bool )
{
throw IllegalConnection(
- "Source node does not send output.\n"
+ "Source node does not send output."
" Note that recorders must be connected as Connect(neuron, recorder)." );
}
@@ -213,7 +219,7 @@ Node::send_test_event( Node&, size_t, synindex, bool )
* throws IllegalConnection
*/
void
-Node::register_stdp_connection( double, double )
+Node::register_stdp_connection( double, double, double )
{
throw IllegalConnection( "The target node does not support STDP synapses." );
}
@@ -259,12 +265,25 @@ Node::handle( SpikeEvent& )
{
throw UnexpectedEvent( "The target node does not handle spike input." );
}
+void
+Node::handle( CorrectionSpikeEvent& )
+{
+ throw UnexpectedEvent( "The target node does not handle spike input." );
+}
size_t
Node::handles_test_event( SpikeEvent&, size_t )
{
throw IllegalConnection(
- "The target node or synapse model does not support spike input.\n"
+ "The target node or synapse model does not support spike input."
+ " Note that volt/multimeters must be connected as Connect(meter, neuron)." );
+}
+
+size_t
+Node::handles_test_event( CorrectionSpikeEvent&, size_t )
+{
+ throw IllegalConnection(
+ "The target node or synapse model does not support spike input with axonal delays."
" Note that volt/multimeters must be connected as Connect(meter, neuron)." );
}
diff --git a/nestkernel/node.h b/nestkernel/node.h
index 5c41113f43..90ca9aef9b 100644
--- a/nestkernel/node.h
+++ b/nestkernel/node.h
@@ -400,6 +400,7 @@ class Node
* @throws IllegalConnection
*/
virtual size_t handles_test_event( SpikeEvent&, size_t receptor_type );
+ virtual size_t handles_test_event( CorrectionSpikeEvent&, size_t receptor_type );
virtual size_t handles_test_event( WeightRecorderEvent&, size_t receptor_type );
virtual size_t handles_test_event( RateEvent&, size_t receptor_type );
virtual size_t handles_test_event( DataLoggingRequest&, size_t receptor_type );
@@ -481,7 +482,7 @@ class Node
* @throws IllegalConnection
*
*/
- virtual void register_stdp_connection( double, double );
+ virtual void register_stdp_connection( double, double, double );
/**
* @brief Registers an eprop synapse and initializes the update history.
@@ -557,6 +558,7 @@ class Node
* @ingroup event_interface
*/
virtual void handle( SpikeEvent& e );
+ virtual void handle( CorrectionSpikeEvent& );
/**
* Handle incoming weight recording events.
@@ -1010,6 +1012,21 @@ class Node
*/
virtual size_t get_local_device_id() const;
+ /**
+ * Framework for STDP with predominantly axonal delays: Buffer a correction entry for a short time window.
+ *
+ * @param spike_event Incoming pre-synaptic spike which could potentially need a correction after the next
+ * post-synaptic spike.
+ * @param t_last_pre_spike The time of the last pre-synaptic spike that was processed before the current one.
+ * @param weight_revert The synaptic weight before depression after facilitation as baseline for potential later
+ * correction.
+ * @param time_while_critical The number of time steps until the spike no longer needs to be corrected.
+ */
+ void add_correction_entry_stdp_ax_delay( SpikeEvent& spike_event,
+ const double t_last_pre_spike,
+ const double weight_revert,
+ const double time_while_critical );
+
/**
* Member of DeprecationWarning class to be used by models if parameters are
* deprecated.
diff --git a/nestkernel/node_manager.cpp b/nestkernel/node_manager.cpp
index ca5f28ed98..974ade9031 100644
--- a/nestkernel/node_manager.cpp
+++ b/nestkernel/node_manager.cpp
@@ -619,8 +619,7 @@ NodeManager::set_status_single_node_( Node& target, const DictionaryDatum& d, bo
}
target.set_status_base( d );
- // TODO: Not sure this check should be at single neuron level; advantage is
- // it stops after first failure.
+ // TODO: Not sure this check should be at single neuron level; advantage is it stops after first failure.
ALL_ENTRIES_ACCESSED( *d, "NodeManager::set_status", "Unread dictionary entries: " );
}
}
diff --git a/nestkernel/recording_backend_ascii.cpp b/nestkernel/recording_backend_ascii.cpp
index 773aa36a82..bfafc150ac 100644
--- a/nestkernel/recording_backend_ascii.cpp
+++ b/nestkernel/recording_backend_ascii.cpp
@@ -32,31 +32,34 @@
#include "recording_backend_ascii.h"
-const unsigned int nest::RecordingBackendASCII::ASCII_REC_BACKEND_VERSION = 2;
+namespace nest
+{
+
+const unsigned int RecordingBackendASCII::ASCII_REC_BACKEND_VERSION = 2;
-nest::RecordingBackendASCII::RecordingBackendASCII()
+RecordingBackendASCII::RecordingBackendASCII()
{
}
-nest::RecordingBackendASCII::~RecordingBackendASCII() throw()
+RecordingBackendASCII::~RecordingBackendASCII() throw()
{
}
void
-nest::RecordingBackendASCII::initialize()
+RecordingBackendASCII::initialize()
{
data_map tmp( kernel().vp_manager.get_num_threads() );
device_data_.swap( tmp );
}
void
-nest::RecordingBackendASCII::finalize()
+RecordingBackendASCII::finalize()
{
// nothing to do
}
void
-nest::RecordingBackendASCII::enroll( const RecordingDevice& device, const DictionaryDatum& params )
+RecordingBackendASCII::enroll( const RecordingDevice& device, const DictionaryDatum& params )
{
const size_t t = device.get_thread();
const size_t node_id = device.get_node_id();
@@ -74,7 +77,7 @@ nest::RecordingBackendASCII::enroll( const RecordingDevice& device, const Dictio
}
void
-nest::RecordingBackendASCII::disenroll( const RecordingDevice& device )
+RecordingBackendASCII::disenroll( const RecordingDevice& device )
{
const size_t t = device.get_thread();
const size_t node_id = device.get_node_id();
@@ -87,7 +90,7 @@ nest::RecordingBackendASCII::disenroll( const RecordingDevice& device )
}
void
-nest::RecordingBackendASCII::set_value_names( const RecordingDevice& device,
+RecordingBackendASCII::set_value_names( const RecordingDevice& device,
const std::vector< Name >& double_value_names,
const std::vector< Name >& long_value_names )
{
@@ -100,13 +103,13 @@ nest::RecordingBackendASCII::set_value_names( const RecordingDevice& device,
}
void
-nest::RecordingBackendASCII::pre_run_hook()
+RecordingBackendASCII::pre_run_hook()
{
// nothing to do
}
void
-nest::RecordingBackendASCII::post_run_hook()
+RecordingBackendASCII::post_run_hook()
{
for ( auto& inner : device_data_ )
{
@@ -118,13 +121,13 @@ nest::RecordingBackendASCII::post_run_hook()
}
void
-nest::RecordingBackendASCII::post_step_hook()
+RecordingBackendASCII::post_step_hook()
{
// nothing to do
}
void
-nest::RecordingBackendASCII::cleanup()
+RecordingBackendASCII::cleanup()
{
for ( auto& inner : device_data_ )
{
@@ -136,7 +139,7 @@ nest::RecordingBackendASCII::cleanup()
}
void
-nest::RecordingBackendASCII::write( const RecordingDevice& device,
+RecordingBackendASCII::write( const RecordingDevice& device,
const Event& event,
const std::vector< double >& double_values,
const std::vector< long >& long_values )
@@ -154,7 +157,7 @@ nest::RecordingBackendASCII::write( const RecordingDevice& device,
}
const std::string
-nest::RecordingBackendASCII::compute_vp_node_id_string_( const RecordingDevice& device ) const
+RecordingBackendASCII::compute_vp_node_id_string_( const RecordingDevice& device ) const
{
const double num_vps = kernel().vp_manager.get_num_virtual_processes();
const double num_nodes = kernel().node_manager.size();
@@ -169,7 +172,7 @@ nest::RecordingBackendASCII::compute_vp_node_id_string_( const RecordingDevice&
}
void
-nest::RecordingBackendASCII::prepare()
+RecordingBackendASCII::prepare()
{
for ( auto& inner : device_data_ )
{
@@ -181,33 +184,33 @@ nest::RecordingBackendASCII::prepare()
}
void
-nest::RecordingBackendASCII::set_status( const DictionaryDatum& )
+RecordingBackendASCII::set_status( const DictionaryDatum& )
{
// nothing to do
}
void
-nest::RecordingBackendASCII::get_status( DictionaryDatum& ) const
+RecordingBackendASCII::get_status( DictionaryDatum& ) const
{
// nothing to do
}
void
-nest::RecordingBackendASCII::check_device_status( const DictionaryDatum& params ) const
+RecordingBackendASCII::check_device_status( const DictionaryDatum& params ) const
{
DeviceData dd( "", "" );
dd.set_status( params ); // throws if params contains invalid entries
}
void
-nest::RecordingBackendASCII::get_device_defaults( DictionaryDatum& params ) const
+RecordingBackendASCII::get_device_defaults( DictionaryDatum& params ) const
{
DeviceData dd( "", "" );
dd.get_status( params );
}
void
-nest::RecordingBackendASCII::get_device_status( const nest::RecordingDevice& device, DictionaryDatum& d ) const
+RecordingBackendASCII::get_device_status( const RecordingDevice& device, DictionaryDatum& d ) const
{
const size_t t = device.get_thread();
const size_t node_id = device.get_node_id();
@@ -221,7 +224,7 @@ nest::RecordingBackendASCII::get_device_status( const nest::RecordingDevice& dev
/* ******************* Device meta data class DeviceData ******************* */
-nest::RecordingBackendASCII::DeviceData::DeviceData( std::string modelname, std::string vp_node_id_string )
+RecordingBackendASCII::DeviceData::DeviceData( std::string modelname, std::string vp_node_id_string )
: precision_( 3 )
, time_in_steps_( false )
, modelname_( modelname )
@@ -232,7 +235,7 @@ nest::RecordingBackendASCII::DeviceData::DeviceData( std::string modelname, std:
}
void
-nest::RecordingBackendASCII::DeviceData::set_value_names( const std::vector< Name >& double_value_names,
+RecordingBackendASCII::DeviceData::set_value_names( const std::vector< Name >& double_value_names,
const std::vector< Name >& long_value_names )
{
double_value_names_ = double_value_names;
@@ -240,13 +243,13 @@ nest::RecordingBackendASCII::DeviceData::set_value_names( const std::vector< Nam
}
void
-nest::RecordingBackendASCII::DeviceData::flush_file()
+RecordingBackendASCII::DeviceData::flush_file()
{
file_.flush();
}
void
-nest::RecordingBackendASCII::DeviceData::open_file()
+RecordingBackendASCII::DeviceData::open_file()
{
std::string filename = compute_filename_();
@@ -289,13 +292,13 @@ nest::RecordingBackendASCII::DeviceData::open_file()
}
void
-nest::RecordingBackendASCII::DeviceData::close_file()
+RecordingBackendASCII::DeviceData::close_file()
{
file_.close();
}
void
-nest::RecordingBackendASCII::DeviceData::write( const Event& event,
+RecordingBackendASCII::DeviceData::write( const Event& event,
const std::vector< double >& double_values,
const std::vector< long >& long_values )
{
@@ -323,7 +326,7 @@ nest::RecordingBackendASCII::DeviceData::write( const Event& event,
}
void
-nest::RecordingBackendASCII::DeviceData::get_status( DictionaryDatum& d ) const
+RecordingBackendASCII::DeviceData::get_status( DictionaryDatum& d ) const
{
( *d )[ names::file_extension ] = file_extension_;
( *d )[ names::precision ] = precision_;
@@ -335,7 +338,7 @@ nest::RecordingBackendASCII::DeviceData::get_status( DictionaryDatum& d ) const
}
void
-nest::RecordingBackendASCII::DeviceData::set_status( const DictionaryDatum& d )
+RecordingBackendASCII::DeviceData::set_status( const DictionaryDatum& d )
{
updateValue< std::string >( d, names::file_extension, file_extension_ );
updateValue< long >( d, names::precision, precision_ );
@@ -354,7 +357,7 @@ nest::RecordingBackendASCII::DeviceData::set_status( const DictionaryDatum& d )
}
std::string
-nest::RecordingBackendASCII::DeviceData::compute_filename_() const
+RecordingBackendASCII::DeviceData::compute_filename_() const
{
std::string data_path = kernel().io_manager.get_data_path();
if ( not data_path.empty() and not( data_path[ data_path.size() - 1 ] == '/' ) )
@@ -372,3 +375,5 @@ nest::RecordingBackendASCII::DeviceData::compute_filename_() const
return data_path + data_prefix + label + vp_node_id_string_ + "." + file_extension_;
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/nestkernel/recording_backend_memory.cpp b/nestkernel/recording_backend_memory.cpp
index 3ff816c685..b98b8adce0 100644
--- a/nestkernel/recording_backend_memory.cpp
+++ b/nestkernel/recording_backend_memory.cpp
@@ -26,28 +26,31 @@
#include "recording_backend_memory.h"
-nest::RecordingBackendMemory::RecordingBackendMemory()
+namespace nest
+{
+
+RecordingBackendMemory::RecordingBackendMemory()
{
}
-nest::RecordingBackendMemory::~RecordingBackendMemory() throw()
+RecordingBackendMemory::~RecordingBackendMemory() throw()
{
}
void
-nest::RecordingBackendMemory::initialize()
+RecordingBackendMemory::initialize()
{
device_data_map tmp( kernel().vp_manager.get_num_threads() );
device_data_.swap( tmp );
}
void
-nest::RecordingBackendMemory::finalize()
+RecordingBackendMemory::finalize()
{
}
void
-nest::RecordingBackendMemory::enroll( const RecordingDevice& device, const DictionaryDatum& params )
+RecordingBackendMemory::enroll( const RecordingDevice& device, const DictionaryDatum& params )
{
size_t t = device.get_thread();
size_t node_id = device.get_node_id();
@@ -63,7 +66,7 @@ nest::RecordingBackendMemory::enroll( const RecordingDevice& device, const Dicti
}
void
-nest::RecordingBackendMemory::disenroll( const RecordingDevice& device )
+RecordingBackendMemory::disenroll( const RecordingDevice& device )
{
size_t t = device.get_thread();
size_t node_id = device.get_node_id();
@@ -76,7 +79,7 @@ nest::RecordingBackendMemory::disenroll( const RecordingDevice& device )
}
void
-nest::RecordingBackendMemory::set_value_names( const RecordingDevice& device,
+RecordingBackendMemory::set_value_names( const RecordingDevice& device,
const std::vector< Name >& double_value_names,
const std::vector< Name >& long_value_names )
{
@@ -89,19 +92,19 @@ nest::RecordingBackendMemory::set_value_names( const RecordingDevice& device,
}
void
-nest::RecordingBackendMemory::pre_run_hook()
+RecordingBackendMemory::pre_run_hook()
{
// nothing to do
}
void
-nest::RecordingBackendMemory::cleanup()
+RecordingBackendMemory::cleanup()
{
// nothing to do
}
void
-nest::RecordingBackendMemory::write( const RecordingDevice& device,
+RecordingBackendMemory::write( const RecordingDevice& device,
const Event& event,
const std::vector< double >& double_values,
const std::vector< long >& long_values )
@@ -113,21 +116,21 @@ nest::RecordingBackendMemory::write( const RecordingDevice& device,
}
void
-nest::RecordingBackendMemory::check_device_status( const DictionaryDatum& params ) const
+RecordingBackendMemory::check_device_status( const DictionaryDatum& params ) const
{
DeviceData dd;
dd.set_status( params ); // throws if params contains invalid entries
}
void
-nest::RecordingBackendMemory::get_device_defaults( DictionaryDatum& params ) const
+RecordingBackendMemory::get_device_defaults( DictionaryDatum& params ) const
{
DeviceData dd;
dd.get_status( params );
}
void
-nest::RecordingBackendMemory::get_device_status( const RecordingDevice& device, DictionaryDatum& d ) const
+RecordingBackendMemory::get_device_status( const RecordingDevice& device, DictionaryDatum& d ) const
{
const size_t t = device.get_thread();
const size_t node_id = device.get_node_id();
@@ -140,44 +143,44 @@ nest::RecordingBackendMemory::get_device_status( const RecordingDevice& device,
}
void
-nest::RecordingBackendMemory::post_run_hook()
+RecordingBackendMemory::post_run_hook()
{
// nothing to do
}
void
-nest::RecordingBackendMemory::post_step_hook()
+RecordingBackendMemory::post_step_hook()
{
// nothing to do
}
void
-nest::RecordingBackendMemory::get_status( lockPTRDatum< Dictionary, &SLIInterpreter::Dictionarytype >& ) const
+RecordingBackendMemory::get_status( lockPTRDatum< Dictionary, &SLIInterpreter::Dictionarytype >& ) const
{
// nothing to do
}
void
-nest::RecordingBackendMemory::set_status( lockPTRDatum< Dictionary, &SLIInterpreter::Dictionarytype > const& )
+RecordingBackendMemory::set_status( lockPTRDatum< Dictionary, &SLIInterpreter::Dictionarytype > const& )
{
// nothing to do
}
void
-nest::RecordingBackendMemory::prepare()
+RecordingBackendMemory::prepare()
{
// nothing to do
}
/* ******************* Device meta data class DeviceInfo ******************* */
-nest::RecordingBackendMemory::DeviceData::DeviceData()
+RecordingBackendMemory::DeviceData::DeviceData()
: time_in_steps_( false )
{
}
void
-nest::RecordingBackendMemory::DeviceData::set_value_names( const std::vector< Name >& double_value_names,
+RecordingBackendMemory::DeviceData::set_value_names( const std::vector< Name >& double_value_names,
const std::vector< Name >& long_value_names )
{
double_value_names_ = double_value_names;
@@ -188,7 +191,7 @@ nest::RecordingBackendMemory::DeviceData::set_value_names( const std::vector< Na
}
void
-nest::RecordingBackendMemory::DeviceData::push_back( const Event& event,
+RecordingBackendMemory::DeviceData::push_back( const Event& event,
const std::vector< double >& double_values,
const std::vector< long >& long_values )
{
@@ -215,7 +218,7 @@ nest::RecordingBackendMemory::DeviceData::push_back( const Event& event,
}
void
-nest::RecordingBackendMemory::DeviceData::get_status( DictionaryDatum& d ) const
+RecordingBackendMemory::DeviceData::get_status( DictionaryDatum& d ) const
{
DictionaryDatum events;
@@ -261,7 +264,7 @@ nest::RecordingBackendMemory::DeviceData::get_status( DictionaryDatum& d ) const
}
void
-nest::RecordingBackendMemory::DeviceData::set_status( const DictionaryDatum& d )
+RecordingBackendMemory::DeviceData::set_status( const DictionaryDatum& d )
{
bool time_in_steps = false;
if ( updateValue< bool >( d, names::time_in_steps, time_in_steps ) )
@@ -282,7 +285,7 @@ nest::RecordingBackendMemory::DeviceData::set_status( const DictionaryDatum& d )
}
void
-nest::RecordingBackendMemory::DeviceData::clear()
+RecordingBackendMemory::DeviceData::clear()
{
senders_.clear();
times_ms_.clear();
@@ -298,3 +301,5 @@ nest::RecordingBackendMemory::DeviceData::clear()
long_values_[ i ].clear();
}
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/nestkernel/recording_backend_mpi.cpp b/nestkernel/recording_backend_mpi.cpp
index 3c048211a0..ddcede1043 100644
--- a/nestkernel/recording_backend_mpi.cpp
+++ b/nestkernel/recording_backend_mpi.cpp
@@ -29,6 +29,9 @@
#include "recording_backend_mpi.h"
#include "recording_device.h"
+namespace nest
+{
+
nest::RecordingBackendMPI::RecordingBackendMPI()
: enrolled_( false )
, prepared_( false )
@@ -423,3 +426,5 @@ nest::RecordingBackendMPI::send_data( const MPI_Comm* comm, const double data[],
// Receive the data ( for the moment only spike time )
MPI_Send( data, shape, MPI_DOUBLE, 0, 0, *comm );
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/nestkernel/recording_backend_screen.cpp b/nestkernel/recording_backend_screen.cpp
index 9b31ea6f57..21065f483e 100644
--- a/nestkernel/recording_backend_screen.cpp
+++ b/nestkernel/recording_backend_screen.cpp
@@ -28,20 +28,23 @@
#include "recording_backend_screen.h"
+namespace nest
+{
+
void
-nest::RecordingBackendScreen::initialize()
+RecordingBackendScreen::initialize()
{
device_data_map tmp( kernel().vp_manager.get_num_threads() );
device_data_.swap( tmp );
}
void
-nest::RecordingBackendScreen::finalize()
+RecordingBackendScreen::finalize()
{
}
void
-nest::RecordingBackendScreen::enroll( const RecordingDevice& device, const DictionaryDatum& params )
+RecordingBackendScreen::enroll( const RecordingDevice& device, const DictionaryDatum& params )
{
const size_t node_id = device.get_node_id();
const size_t t = device.get_thread();
@@ -57,7 +60,7 @@ nest::RecordingBackendScreen::enroll( const RecordingDevice& device, const Dicti
}
void
-nest::RecordingBackendScreen::disenroll( const RecordingDevice& device )
+RecordingBackendScreen::disenroll( const RecordingDevice& device )
{
const size_t node_id = device.get_node_id();
const size_t t = device.get_thread();
@@ -70,7 +73,7 @@ nest::RecordingBackendScreen::disenroll( const RecordingDevice& device )
}
void
-nest::RecordingBackendScreen::set_value_names( const RecordingDevice&,
+RecordingBackendScreen::set_value_names( const RecordingDevice&,
const std::vector< Name >&,
const std::vector< Name >& )
{
@@ -78,19 +81,19 @@ nest::RecordingBackendScreen::set_value_names( const RecordingDevice&,
}
void
-nest::RecordingBackendScreen::pre_run_hook()
+RecordingBackendScreen::pre_run_hook()
{
// nothing to do
}
void
-nest::RecordingBackendScreen::cleanup()
+RecordingBackendScreen::cleanup()
{
// nothing to do
}
void
-nest::RecordingBackendScreen::write( const RecordingDevice& device,
+RecordingBackendScreen::write( const RecordingDevice& device,
const Event& event,
const std::vector< double >& double_values,
const std::vector< long >& long_values )
@@ -107,21 +110,21 @@ nest::RecordingBackendScreen::write( const RecordingDevice& device,
}
void
-nest::RecordingBackendScreen::check_device_status( const DictionaryDatum& params ) const
+RecordingBackendScreen::check_device_status( const DictionaryDatum& params ) const
{
DeviceData dd;
dd.set_status( params ); // throws if params contains invalid entries
}
void
-nest::RecordingBackendScreen::get_device_defaults( DictionaryDatum& params ) const
+RecordingBackendScreen::get_device_defaults( DictionaryDatum& params ) const
{
DeviceData dd;
dd.get_status( params );
}
void
-nest::RecordingBackendScreen::get_device_status( const nest::RecordingDevice& device, DictionaryDatum& d ) const
+RecordingBackendScreen::get_device_status( const RecordingDevice& device, DictionaryDatum& d ) const
{
const size_t t = device.get_thread();
const size_t node_id = device.get_node_id();
@@ -135,59 +138,59 @@ nest::RecordingBackendScreen::get_device_status( const nest::RecordingDevice& de
void
-nest::RecordingBackendScreen::prepare()
+RecordingBackendScreen::prepare()
{
// nothing to do
}
void
-nest::RecordingBackendScreen::post_run_hook()
+RecordingBackendScreen::post_run_hook()
{
// nothing to do
}
void
-nest::RecordingBackendScreen::post_step_hook()
+RecordingBackendScreen::post_step_hook()
{
// nothing to do
}
void
-nest::RecordingBackendScreen::set_status( const DictionaryDatum& )
+RecordingBackendScreen::set_status( const DictionaryDatum& )
{
// nothing to do
}
void
-nest::RecordingBackendScreen::get_status( DictionaryDatum& ) const
+RecordingBackendScreen::get_status( DictionaryDatum& ) const
{
// nothing to do
}
/* ******************* Device meta data class DeviceInfo ******************* */
-nest::RecordingBackendScreen::DeviceData::DeviceData()
+RecordingBackendScreen::DeviceData::DeviceData()
: precision_( 3 )
, time_in_steps_( false )
{
}
void
-nest::RecordingBackendScreen::DeviceData::get_status( DictionaryDatum& d ) const
+RecordingBackendScreen::DeviceData::get_status( DictionaryDatum& d ) const
{
( *d )[ names::precision ] = precision_;
( *d )[ names::time_in_steps ] = time_in_steps_;
}
void
-nest::RecordingBackendScreen::DeviceData::set_status( const DictionaryDatum& d )
+RecordingBackendScreen::DeviceData::set_status( const DictionaryDatum& d )
{
updateValue< long >( d, names::precision, precision_ );
updateValue< bool >( d, names::time_in_steps, time_in_steps_ );
}
void
-nest::RecordingBackendScreen::DeviceData::write( const Event& event,
+RecordingBackendScreen::DeviceData::write( const Event& event,
const std::vector< double >& double_values,
const std::vector< long >& long_values )
{
@@ -221,15 +224,17 @@ nest::RecordingBackendScreen::DeviceData::write( const Event& event,
}
void
-nest::RecordingBackendScreen::DeviceData::prepare_cout_()
+RecordingBackendScreen::DeviceData::prepare_cout_()
{
old_fmtflags_ = std::cout.flags( std::ios::fixed );
old_precision_ = std::cout.precision( precision_ );
}
void
-nest::RecordingBackendScreen::DeviceData::restore_cout_()
+RecordingBackendScreen::DeviceData::restore_cout_()
{
std::cout.flags( old_fmtflags_ );
std::cout.precision( old_precision_ );
}
+
+}
\ No newline at end of file
diff --git a/nestkernel/recording_backend_sionlib.cpp b/nestkernel/recording_backend_sionlib.cpp
index 5aabb26ebc..517b0c9249 100644
--- a/nestkernel/recording_backend_sionlib.cpp
+++ b/nestkernel/recording_backend_sionlib.cpp
@@ -41,6 +41,9 @@
#include "recording_backend_sionlib.h"
+namespace nest
+{
+
const unsigned int nest::RecordingBackendSIONlib::SIONLIB_REC_BACKEND_VERSION = 2;
const unsigned int nest::RecordingBackendSIONlib::DEV_NAME_BUFFERSIZE = 32;
const unsigned int nest::RecordingBackendSIONlib::DEV_LABEL_BUFFERSIZE = 32;
@@ -703,3 +706,5 @@ nest::RecordingBackendSIONlib::get_device_status( const nest::RecordingDevice&,
{
// nothing to do
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/nestkernel/simulation_manager.cpp b/nestkernel/simulation_manager.cpp
index 9f23d7f89b..ad5dde3d61 100644
--- a/nestkernel/simulation_manager.cpp
+++ b/nestkernel/simulation_manager.cpp
@@ -34,7 +34,6 @@
#include "numerics.h"
// Includes from nestkernel:
-#include "connection_manager_impl.h"
#include "event_delivery_manager.h"
#include "kernel_manager.h"
#include "stopwatch_impl.h"
@@ -539,11 +538,25 @@ nest::SimulationManager::prepare()
}
prepared_ = true;
- // check whether waveform relaxation is used on any MPI process;
- // needs to be called before update_connection_intrastructure_since
- // it resizes coefficient arrays for secondary events
+ // check whether waveform relaxation is used on any MPI process; needs to be called before
+ // update_connection_infrastructure() since it resizes coefficient arrays for secondary events
kernel().node_manager.check_wfr_use();
+ // If we simulated already and we use axonal delays, we have to make sure connectivity didn't change, as this would
+ // invalidate the correction entries in the neurons that are required for connections with predominant axonal delays.
+ if ( simulated_ and kernel().connection_manager.have_nonzero_axonal_delays()
+ and kernel().connection_manager.connections_have_changed() )
+ {
+ throw KernelException(
+ "Connections have changed during simulation, which is not allowed when using axonal delays!" );
+ }
+
+ if ( kernel().connection_manager.have_nonzero_axonal_delays()
+ and kernel().sp_manager.is_structural_plasticity_enabled() )
+ {
+ throw KernelException( "Structural plasticity is not compatible with axonal delays!" );
+ }
+
if ( kernel().node_manager.have_nodes_changed() or kernel().connection_manager.connections_have_changed() )
{
#pragma omp parallel
@@ -909,7 +922,7 @@ nest::SimulationManager::update_()
#endif
} // if from_step == 0
- // preliminary update of nodes that use waveform relaxtion, only
+ // preliminary update of nodes that use waveform relaxation, only
// necessary if secondary connections exist and any node uses
// wfr
if ( kernel().connection_manager.secondary_connections_exist() and kernel().node_manager.wfr_is_used() )
diff --git a/nestkernel/sonata_connector.cpp b/nestkernel/sonata_connector.cpp
index b44ae89640..4e9420a149 100644
--- a/nestkernel/sonata_connector.cpp
+++ b/nestkernel/sonata_connector.cpp
@@ -476,6 +476,8 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off
edge_type_id_2_syn_model_.at( edge_type_id ),
edge_type_id_2_param_dicts_.at( edge_type_id ).at( tid ),
delay,
+ numerics::nan,
+ numerics::nan,
weight );
} // end for
diff --git a/nestkernel/sp_manager.cpp b/nestkernel/sp_manager.cpp
index 4705b7de64..d9b039573b 100644
--- a/nestkernel/sp_manager.cpp
+++ b/nestkernel/sp_manager.cpp
@@ -156,8 +156,8 @@ SPManager::set_status( const DictionaryDatum& d )
SPBuilder* conn_builder = new SPBuilder( sources, targets, /* third_out */ nullptr, conn_spec, { syn_spec } );
conn_builder->set_name( i->first.toString() );
- // check that the user defined the min and max delay properly, if the
- // default delay is not used.
+ // TODO: Consider axonal delays here
+ // check that the user defined the min and max delay properly, if the default delay is not used.
if ( not conn_builder->get_default_delay() and not kernel().connection_manager.get_user_set_delay_extrema() )
{
throw BadProperty(
@@ -171,6 +171,7 @@ SPManager::set_status( const DictionaryDatum& d )
long
SPManager::builder_min_delay() const
{
+ // TODO: Consider axonal delays here
long min_delay = Time::pos_inf().get_steps();
long builder_delay = Time::pos_inf().get_steps();
@@ -185,6 +186,7 @@ SPManager::builder_min_delay() const
long
SPManager::builder_max_delay() const
{
+ // TODO: Consider axonal delays here
long max_delay = Time::neg_inf().get_steps();
long builder_delay = Time::neg_inf().get_steps();
diff --git a/nestkernel/spike_data.h b/nestkernel/spike_data.h
index 87b1205ba0..d2271f4372 100644
--- a/nestkernel/spike_data.h
+++ b/nestkernel/spike_data.h
@@ -86,8 +86,7 @@ enum enum_status_spike_data_id
};
/**
- * Used to communicate spikes. These are the elements of the MPI
- * buffers.
+ * Used to communicate spikes. These are the elements of the MPI buffers.
*
* @see TargetData
*/
diff --git a/nestkernel/stimulation_device.cpp b/nestkernel/stimulation_device.cpp
index ab3c800c9b..de7bbaca7f 100644
--- a/nestkernel/stimulation_device.cpp
+++ b/nestkernel/stimulation_device.cpp
@@ -25,8 +25,10 @@
#include "stimulation_device.h"
#include "kernel_manager.h"
+namespace nest
+{
-nest::StimulationDevice::StimulationDevice()
+StimulationDevice::StimulationDevice()
: DeviceNode()
, Device()
, first_syn_id_( invalid_synindex )
@@ -34,7 +36,7 @@ nest::StimulationDevice::StimulationDevice()
{
}
-nest::StimulationDevice::StimulationDevice( StimulationDevice const& sd )
+StimulationDevice::StimulationDevice( StimulationDevice const& sd )
: DeviceNode( sd )
, Device( sd )
, P_( sd.P_ )
@@ -44,7 +46,7 @@ nest::StimulationDevice::StimulationDevice( StimulationDevice const& sd )
}
bool
-nest::StimulationDevice::is_active( const Time& T ) const
+StimulationDevice::is_active( const Time& T ) const
{
long step = T.get_steps();
if ( get_type() == StimulationDevice::Type::CURRENT_GENERATOR
@@ -57,7 +59,7 @@ nest::StimulationDevice::is_active( const Time& T ) const
}
void
-nest::StimulationDevice::enforce_single_syn_type( synindex syn_id )
+StimulationDevice::enforce_single_syn_type( synindex syn_id )
{
if ( first_syn_id_ == invalid_synindex )
{
@@ -70,39 +72,39 @@ nest::StimulationDevice::enforce_single_syn_type( synindex syn_id )
}
void
-nest::StimulationDevice::pre_run_hook()
+StimulationDevice::pre_run_hook()
{
Device::pre_run_hook();
}
void
-nest::StimulationDevice::set_initialized_()
+StimulationDevice::set_initialized_()
{
kernel().io_manager.enroll_stimulator( P_.stimulus_source_, *this, backend_params_ );
}
const std::string&
-nest::StimulationDevice::get_label() const
+StimulationDevice::get_label() const
{
return P_.label_;
}
-nest::StimulationDevice::Parameters_::Parameters_()
+StimulationDevice::Parameters_::Parameters_()
: label_()
, stimulus_source_( Name() )
{
}
void
-nest::StimulationDevice::Parameters_::get( DictionaryDatum& d ) const
+StimulationDevice::Parameters_::get( DictionaryDatum& d ) const
{
( *d )[ names::label ] = label_;
( *d )[ names::stimulus_source ] = LiteralDatum( stimulus_source_ );
}
void
-nest::StimulationDevice::Parameters_::set( const DictionaryDatum& d )
+StimulationDevice::Parameters_::set( const DictionaryDatum& d )
{
updateValue< std::string >( d, names::label, label_ );
@@ -120,7 +122,7 @@ nest::StimulationDevice::Parameters_::set( const DictionaryDatum& d )
}
void
-nest::StimulationDevice::set_status( const DictionaryDatum& d )
+StimulationDevice::set_status( const DictionaryDatum& d )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
@@ -163,7 +165,7 @@ nest::StimulationDevice::set_status( const DictionaryDatum& d )
void
-nest::StimulationDevice::get_status( DictionaryDatum& d ) const
+StimulationDevice::get_status( DictionaryDatum& d ) const
{
P_.get( d );
@@ -180,3 +182,5 @@ nest::StimulationDevice::get_status( DictionaryDatum& d ) const
}
}
}
+
+} // namespace nest
\ No newline at end of file
diff --git a/nestkernel/structural_plasticity_node.cpp b/nestkernel/structural_plasticity_node.cpp
index 07a3af88e4..b46c7b5334 100644
--- a/nestkernel/structural_plasticity_node.cpp
+++ b/nestkernel/structural_plasticity_node.cpp
@@ -31,7 +31,7 @@
namespace nest
{
-nest::StructuralPlasticityNode::StructuralPlasticityNode()
+StructuralPlasticityNode::StructuralPlasticityNode()
: Ca_t_( 0.0 )
, Ca_minus_( 0.0 )
, tau_Ca_( 10000.0 )
@@ -40,7 +40,7 @@ nest::StructuralPlasticityNode::StructuralPlasticityNode()
{
}
-nest::StructuralPlasticityNode::StructuralPlasticityNode( const StructuralPlasticityNode& n )
+StructuralPlasticityNode::StructuralPlasticityNode( const StructuralPlasticityNode& n )
: Node( n )
, Ca_t_( n.Ca_t_ )
, Ca_minus_( n.Ca_minus_ )
@@ -51,7 +51,7 @@ nest::StructuralPlasticityNode::StructuralPlasticityNode( const StructuralPlasti
}
void
-nest::StructuralPlasticityNode::get_status( DictionaryDatum& d ) const
+StructuralPlasticityNode::get_status( DictionaryDatum& d ) const
{
DictionaryDatum synaptic_elements_d;
DictionaryDatum synaptic_element_d;
@@ -73,7 +73,7 @@ nest::StructuralPlasticityNode::get_status( DictionaryDatum& d ) const
}
void
-nest::StructuralPlasticityNode::set_status( const DictionaryDatum& d )
+StructuralPlasticityNode::set_status( const DictionaryDatum& d )
{
// We need to preserve values in case invalid values are set
double new_Ca_ = Ca_minus_;
@@ -145,14 +145,14 @@ nest::StructuralPlasticityNode::set_status( const DictionaryDatum& d )
}
void
-nest::StructuralPlasticityNode::clear_history()
+StructuralPlasticityNode::clear_history()
{
Ca_minus_ = 0.0;
Ca_t_ = 0.0;
}
double
-nest::StructuralPlasticityNode::get_synaptic_elements( Name n ) const
+StructuralPlasticityNode::get_synaptic_elements( Name n ) const
{
std::map< Name, SynapticElement >::const_iterator se_it;
se_it = synaptic_elements_map_.find( n );
@@ -177,7 +177,7 @@ nest::StructuralPlasticityNode::get_synaptic_elements( Name n ) const
}
int
-nest::StructuralPlasticityNode::get_synaptic_elements_vacant( Name n ) const
+StructuralPlasticityNode::get_synaptic_elements_vacant( Name n ) const
{
std::map< Name, SynapticElement >::const_iterator se_it;
se_it = synaptic_elements_map_.find( n );
@@ -193,7 +193,7 @@ nest::StructuralPlasticityNode::get_synaptic_elements_vacant( Name n ) const
}
int
-nest::StructuralPlasticityNode::get_synaptic_elements_connected( Name n ) const
+StructuralPlasticityNode::get_synaptic_elements_connected( Name n ) const
{
std::map< Name, SynapticElement >::const_iterator se_it;
se_it = synaptic_elements_map_.find( n );
@@ -209,7 +209,7 @@ nest::StructuralPlasticityNode::get_synaptic_elements_connected( Name n ) const
}
std::map< Name, double >
-nest::StructuralPlasticityNode::get_synaptic_elements() const
+StructuralPlasticityNode::get_synaptic_elements() const
{
std::map< Name, double > n_map;
@@ -223,7 +223,7 @@ nest::StructuralPlasticityNode::get_synaptic_elements() const
}
void
-nest::StructuralPlasticityNode::update_synaptic_elements( double t )
+StructuralPlasticityNode::update_synaptic_elements( double t )
{
assert( t >= Ca_t_ );
@@ -239,7 +239,7 @@ nest::StructuralPlasticityNode::update_synaptic_elements( double t )
}
void
-nest::StructuralPlasticityNode::decay_synaptic_elements_vacant()
+StructuralPlasticityNode::decay_synaptic_elements_vacant()
{
for ( std::map< Name, SynapticElement >::iterator it = synaptic_elements_map_.begin();
it != synaptic_elements_map_.end();
@@ -250,7 +250,7 @@ nest::StructuralPlasticityNode::decay_synaptic_elements_vacant()
}
void
-nest::StructuralPlasticityNode::connect_synaptic_element( Name name, int n )
+StructuralPlasticityNode::connect_synaptic_element( Name name, int n )
{
std::map< Name, SynapticElement >::iterator se_it;
se_it = synaptic_elements_map_.find( name );
@@ -262,7 +262,7 @@ nest::StructuralPlasticityNode::connect_synaptic_element( Name name, int n )
}
void
-nest::StructuralPlasticityNode::set_spiketime( Time const& t_sp, double offset )
+StructuralPlasticityNode::set_spiketime( Time const& t_sp, double offset )
{
const double t_sp_ms = t_sp.get_ms() - offset;
update_synaptic_elements( t_sp_ms );
diff --git a/nestkernel/structural_plasticity_node.h b/nestkernel/structural_plasticity_node.h
index ffaf0c9f67..d545d255d2 100644
--- a/nestkernel/structural_plasticity_node.h
+++ b/nestkernel/structural_plasticity_node.h
@@ -72,8 +72,7 @@ class StructuralPlasticityNode : public Node
int get_synaptic_elements_vacant( Name n ) const override;
/**
- * Get the number of synaptic element of type n which are currently
- * connected
+ * Get the number of synaptic element of type n which are currently connected
*/
int get_synaptic_elements_connected( Name n ) const override;
@@ -89,8 +88,7 @@ class StructuralPlasticityNode : public Node
void update_synaptic_elements( double t ) override;
/**
- * Delete a certain portion of the vacant synaptic elements which are not
- * in use
+ * Delete a certain portion of the vacant synaptic elements which are not in use
*/
void decay_synaptic_elements_vacant() override;
diff --git a/nestkernel/syn_id_delay.h b/nestkernel/syn_id_delay.h
deleted file mode 100644
index c3693137ce..0000000000
--- a/nestkernel/syn_id_delay.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * syn_id_delay.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 .
- *
- */
-
-#ifndef SYN_ID_DELAY_H
-#define SYN_ID_DELAY_H
-
-// Includes from nestkernel:
-#include "nest_time.h"
-#include "nest_types.h"
-
-namespace nest
-{
-
-struct SynIdDelay
-{
- unsigned int delay : NUM_BITS_DELAY;
- unsigned int syn_id : NUM_BITS_SYN_ID;
- bool more_targets : 1;
- bool disabled : 1;
-
- explicit SynIdDelay( double d )
- : syn_id( invalid_synindex )
- , more_targets( false )
- , disabled( false )
- {
- set_delay_ms( d );
- }
-
- SynIdDelay( const SynIdDelay& s ) = default;
- SynIdDelay& operator=( const SynIdDelay& s ) = default;
-
- /**
- * Return the delay of the connection in ms
- */
- double
- get_delay_ms() const
- {
- return Time::delay_steps_to_ms( delay );
- }
-
- /**
- * Set the delay of the connection specified in ms
- */
- void
- set_delay_ms( const double d )
- {
- delay = Time::delay_ms_to_steps( d );
- }
-
- void
- set_source_has_more_targets( const bool more_targets )
- {
- this->more_targets = more_targets;
- }
-
- bool
- source_has_more_targets() const
- {
- return more_targets;
- }
-
- /**
- * Disables the synapse.
- *
- * @see is_disabled
- */
- void
- disable()
- {
- disabled = true;
- }
-
- /**
- * Returns a flag denoting if the synapse is disabled.
- *
- * @see disable
- */
- bool
- is_disabled() const
- {
- return disabled;
- }
-};
-
-//! check legal size
-using success_syn_id_delay_data_size = StaticAssert< sizeof( SynIdDelay ) == 4 >::success;
-}
-
-#endif
diff --git a/nestkernel/target_table_devices_impl.h b/nestkernel/target_table_devices_impl.h
index 26a4668fb1..28a64834ec 100644
--- a/nestkernel/target_table_devices_impl.h
+++ b/nestkernel/target_table_devices_impl.h
@@ -47,7 +47,7 @@ nest::TargetTableDevices::add_connection_to_device( Node& source,
kernel()
.model_manager.get_connection_model( syn_id, tid )
- .add_connection( source, target, target_to_devices_[ tid ][ lid ], syn_id, p, d, w );
+ .add_connection( source, target, target_to_devices_[ tid ][ lid ], syn_id, p, d, numerics::nan, numerics::nan, w );
}
inline void
@@ -66,7 +66,8 @@ nest::TargetTableDevices::add_connection_from_device( Node& source,
kernel()
.model_manager.get_connection_model( syn_id, tid )
- .add_connection( source, target, target_from_devices_[ tid ][ ldid ], syn_id, p, d, w );
+ .add_connection(
+ source, target, target_from_devices_[ tid ][ ldid ], syn_id, p, d, numerics::nan, numerics::nan, w );
// store node ID of sending device
sending_devices_node_ids_[ tid ][ ldid ] = source.get_node_id();
diff --git a/pynest/examples/axonal_delays.py b/pynest/examples/axonal_delays.py
new file mode 100644
index 0000000000..7eb8fba4ec
--- /dev/null
+++ b/pynest/examples/axonal_delays.py
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+#
+# axonal_delays.py
+#
+# 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 .
+
+"""
+Example of using axonal delays in NEST
+--------------------------------------
+
+This script demonstrates the use of axonal delays, by comparing neuronal simulations with
+and without axonal delays (i.e., only dendritic delays). It analyzes the impact of axonal delays
+on synaptic weight distributions using the Jensen-Shannon divergence
+and the number of corrections required for different fractions of axonal delays.
+It uses the synapse model ``stdp_pl_synapse_hom_ax_delay``, which supports the
+use of axonal delays.
+
+For more information see :ref:`delays`.
+"""
+
+
+########################################
+# First, we import all necessary modules
+
+import os.path
+
+import matplotlib.pyplot as plt
+import nest
+import numpy as np
+import seaborn as sns
+from scipy.spatial.distance import jensenshannon
+
+########################################
+# Next we set the parameters
+
+
+tau_syn = 0.32582722403722841
+neuron_params = {
+ "E_L": 0.0,
+ "C_m": 250.0,
+ "tau_m": 10.0,
+ "t_ref": 0.5,
+ "V_th": 20.0,
+ "V_reset": 0.0,
+ "tau_syn_ex": tau_syn,
+ "tau_syn_in": tau_syn,
+ "tau_minus": 30.0,
+ "V_m": 5.7,
+}
+
+stdp_params = {"alpha": 0.0513, "mu": 0.4, "tau_plus": 15.0, "weight": 45.0}
+
+NE = 9000
+eta = 4.92
+
+single_column_in = 3.348
+
+
+#################################################################################
+# And then we set up the simulation
+
+
+def run(T, axonal_delay, dendritic_delay, enable_stdp, use_ax_delay):
+ # Enable or disable STDP
+ if enable_stdp:
+ stdp_params["lambda"] = 1.0
+ else:
+ stdp_params["lambda"] = 0.0
+ # Reset the NEST kernel and set simulation parameters
+ nest.ResetKernel()
+ nest.local_num_threads = 8
+ nest.resolution = 0.1
+ nest.rng_seed = 42
+ nest.set_verbosity("M_ERROR")
+
+ # Create devices and neurons
+ E_ext = nest.Create("poisson_generator", 1, {"rate": eta * 1000.0})
+ E_pg = nest.Create("poisson_generator", 1, params={"rate": 10.0})
+ I_pg = nest.Create("poisson_generator", 1, params={"rate": 10.0 * NE / 5})
+ E_neurons = nest.Create("parrot_neuron", NE)
+ I_neurons = nest.Create("parrot_neuron", 1)
+ post_neuron = nest.Create("iaf_psc_alpha", 1, params=neuron_params)
+ sr = nest.Create("spike_recorder")
+
+ # Set synapse parameters with axonal and dendritic delays
+ syn_params_copy = stdp_params.copy()
+ if use_ax_delay:
+ syn_params_copy["dendritic_delay"] = dendritic_delay
+ syn_params_copy["axonal_delay"] = axonal_delay
+ # Use the new synapse model with axonal delays
+ syn_model = "stdp_pl_synapse_hom_ax_delay"
+ else:
+ syn_params_copy["delay"] = dendritic_delay + axonal_delay
+ syn_model = "stdp_pl_synapse_hom"
+
+ nest.SetDefaults(syn_model, syn_params_copy)
+
+ # Connect neurons and devices
+ nest.Connect(E_pg, E_neurons)
+ nest.Connect(I_pg, I_neurons)
+ nest.Connect(E_neurons, post_neuron, syn_spec={"synapse_model": syn_model})
+ nest.Connect(I_neurons, post_neuron, syn_spec={"weight": 45.0 * -5})
+ nest.Connect(E_ext, post_neuron, syn_spec={"weight": 45.0})
+ nest.Connect(post_neuron, sr)
+
+ # Run the simulation
+ nest.Simulate(T)
+
+ return sr, post_neuron
+
+
+#####################################################################
+# Set the font sizes for graph
+
+
+def set_font_sizes(small=8, medium=10, large=12, family="Arial"):
+ # plt.rc('text', usetex=True)
+ plt.rc("font", size=small) # controls default text sizes
+ plt.rc("axes", titlesize=small) # fontsize of the axes title
+ plt.rc("axes", labelsize=medium) # fontsize of the x and y labels
+ plt.rc("xtick", labelsize=small) # fontsize of the tick labels
+ plt.rc("ytick", labelsize=small) # fontsize of the tick labels
+ plt.rc("legend", fontsize=small) # legend fontsize
+ plt.rc("figure", titlesize=large) # fontsize of the figure title
+ plt.rc("font", family=family)
+
+
+#####################################################################
+# Measure the similarity between two probability distributions using
+# Jensen-Shannon divergence
+
+
+def jensen_shannon_divergence(weights_correction, weights_no_correction):
+ p = np.histogram(weights_correction, bins=100000, density=True)[0]
+ q = np.histogram(weights_no_correction, bins=100000, density=True)[0]
+ return round(jensenshannon(p, q) ** 2, 3)
+
+
+####################################################################################
+# Get different weight distributions of purely dendritic and axonal+dendritic delays
+
+
+_, post_neuron = run(10000.0, 5.0, 0.0, enable_stdp=True, use_ax_delay=True)
+weights_correction = nest.GetConnections(target=post_neuron, synapse_model="stdp_pl_synapse_hom_ax_delay").get("weight")
+_, post_neuron = run(10000.0, 5.0, 0.0, enable_stdp=True, use_ax_delay=False)
+weights_no_correction = nest.GetConnections(target=post_neuron, synapse_model="stdp_pl_synapse_hom").get("weight")
+
+print(
+ "Jensen-Shannon divergence of weight distributions:",
+ jensen_shannon_divergence(weights_correction, weights_no_correction),
+)
+
+#########################################################################
+# Plot the weight distributions
+
+fig, ax = plt.subplots(figsize=(single_column_in, 3.5))
+set_font_sizes()
+sns.distplot(
+ weights_correction,
+ hist=False,
+ kde=True,
+ kde_kws={"fill": True, "linewidth": 3},
+ label="axonal delay and correction",
+ ax=ax,
+)
+sns.distplot(
+ weights_no_correction,
+ hist=False,
+ kde=True,
+ kde_kws={"fill": True, "linewidth": 3},
+ label="purely dendritic delay",
+ ax=ax,
+)
+plt.setp(ax.spines.values(), linewidth=2)
+ax.set_xlabel("Synaptic weight [pA]")
+ax.tick_params(width=2)
+plt.legend()
+fig.tight_layout()
+plt.show()
+
+
+#########################################################################
+# Measure number of corrections for increasing fractions of axonal delays
+
+
+ax_perc = np.arange(0.0, 1.01, 0.01, dtype=np.float32)
+num_corrections = np.empty(101, dtype=np.int32)
+for i, p in enumerate(ax_perc):
+ run(500.0, 5.0 * p, 5.0 * (1 - p), enable_stdp=False, use_ax_delay=True)
+ num_corrections[i] = nest.kernel_status["num_corrections"]
+
+##########################################################################
+# Plot the number of corrections
+
+fig, ax = plt.subplots(figsize=(single_column_in, 3.5))
+set_font_sizes()
+plt.plot(ax_perc, num_corrections, color="black")
+plt.setp(ax.spines.values(), linewidth=2)
+ax.set_xlabel("Fraction of axonal delay")
+ax.set_ylabel("Number of corrections") # average per neuron
+ax.tick_params(width=2)
+fig.tight_layout()
+plt.show()
diff --git a/pynest/nest/lib/hl_api_connection_helpers.py b/pynest/nest/lib/hl_api_connection_helpers.py
index e9fe89b7be..c8cc47baf9 100644
--- a/pynest/nest/lib/hl_api_connection_helpers.py
+++ b/pynest/nest/lib/hl_api_connection_helpers.py
@@ -173,7 +173,15 @@ def _process_spatial_projections(conn_spec, syn_spec):
"use_on_source",
"allow_oversized_mask",
]
- allowed_syn_spec_keys = ["weight", "delay", "synapse_model", "synapse_label", "receptor_type"]
+ allowed_syn_spec_keys = [
+ "weight",
+ "delay",
+ "dendritic_delay",
+ "axonal_delay",
+ "synapse_model",
+ "synapse_label",
+ "receptor_type",
+ ]
for key in conn_spec.keys():
if key not in allowed_conn_spec_keys:
raise ValueError("'{}' is not allowed in conn_spec when connecting with mask or kernel".format(key))
diff --git a/pynest/nest/lib/hl_api_connections.py b/pynest/nest/lib/hl_api_connections.py
index aef9dd0674..e1c902af65 100644
--- a/pynest/nest/lib/hl_api_connections.py
+++ b/pynest/nest/lib/hl_api_connections.py
@@ -232,9 +232,19 @@ def Connect(pre, post, conn_spec=None, syn_spec=None, return_synapsecollection=F
raise ValueError("To specify weights, use 'weight' in syn_spec.")
if "delays" in processed_syn_spec:
raise ValueError("To specify delays, use 'delay' in syn_spec.")
+ if "dendritic_delays" in processed_syn_spec:
+ raise ValueError("To specify dendritic delays, use 'dendritic_delay' in syn_spec.")
+ if "axonal_delays" in processed_syn_spec:
+ raise ValueError("To specify axonal delays, use 'axonal_delay' in syn_spec.")
weights = numpy.array(processed_syn_spec["weight"]) if "weight" in processed_syn_spec else None
delays = numpy.array(processed_syn_spec["delay"]) if "delay" in processed_syn_spec else None
+ dendritic_delays = (
+ numpy.array(processed_syn_spec["dendritic_delay"]) if "dendritic_delay" in processed_syn_spec else None
+ )
+ axonal_delays = (
+ numpy.array(processed_syn_spec["axonal_delay"]) if "axonal_delay" in processed_syn_spec else None
+ )
try:
synapse_model = processed_syn_spec["synapse_model"]
@@ -247,7 +257,9 @@ def Connect(pre, post, conn_spec=None, syn_spec=None, return_synapsecollection=F
# Split remaining syn_spec entries to key and value arrays
reduced_processed_syn_spec = {
k: processed_syn_spec[k]
- for k in set(processed_syn_spec.keys()).difference(set(("weight", "delay", "synapse_model")))
+ for k in set(processed_syn_spec.keys()).difference(
+ set(("weight", "delay", "axonal_delay", "synapse_model"))
+ )
}
if len(reduced_processed_syn_spec) > 0:
@@ -257,7 +269,17 @@ def Connect(pre, post, conn_spec=None, syn_spec=None, return_synapsecollection=F
else:
syn_param_values = None
- connect_arrays(pre, post, weights, delays, synapse_model, reduced_processed_syn_spec.keys(), syn_param_values)
+ connect_arrays(
+ pre,
+ post,
+ weights,
+ delays,
+ dendritic_delays,
+ axonal_delays,
+ synapse_model,
+ reduced_processed_syn_spec.keys(),
+ syn_param_values,
+ )
return
diff --git a/pynest/pynestkernel.pxd b/pynest/pynestkernel.pxd
index 7a766f4696..36391166fb 100644
--- a/pynest/pynestkernel.pxd
+++ b/pynest/pynestkernel.pxd
@@ -148,7 +148,7 @@ cdef extern from "neststartup.h":
cdef extern from "nest.h" namespace "nest":
Datum* node_collection_array_index(const Datum* node_collection, const long* array, unsigned long n) except +
Datum* node_collection_array_index(const Datum* node_collection, const cbool* array, unsigned long n) except +
- void connect_arrays( long* sources, long* targets, double* weights, double* delays, vector[string]& p_keys, double* p_values, size_t n, string syn_model ) except +
+ void connect_arrays( long* sources, long* targets, double* weights, double* delays, double* dendritic_delays, double* axonal_delays, vector[string]& p_keys, double* p_values, size_t n, string syn_model ) except +
cdef extern from *:
diff --git a/pynest/pynestkernel.pyx b/pynest/pynestkernel.pyx
index 1fdf7fa537..97446de66e 100644
--- a/pynest/pynestkernel.pyx
+++ b/pynest/pynestkernel.pyx
@@ -281,7 +281,7 @@ cdef class NESTEngine:
exceptionCls = getattr(NESTErrors, str(e))
raise exceptionCls('take_array_index', '') from None
- def connect_arrays(self, sources, targets, weights, delays, synapse_model, syn_param_keys, syn_param_values):
+ def connect_arrays(self, sources, targets, weights, delays, dendritic_delays, axonal_delays, synapse_model, syn_param_keys, syn_param_values):
"""Calls connect_arrays function, bypassing SLI to expose pointers to the NumPy arrays"""
if self.pEngine is NULL:
raise NESTErrors.PyNESTError("engine uninitialized")
@@ -296,6 +296,8 @@ cdef class NESTEngine:
raise TypeError('weights must be a 1-dimensional NumPy array')
if delays is not None and not (isinstance(delays, numpy.ndarray) and delays.ndim == 1):
raise TypeError('delays must be a 1-dimensional NumPy array')
+ if axonal_delays is not None and not (isinstance(axonal_delays, numpy.ndarray) and axonal_delays.ndim == 1):
+ raise TypeError('axonal_delays must be a 1-dimensional NumPy array')
if syn_param_values is not None and not ((isinstance(syn_param_values, numpy.ndarray) and syn_param_values.ndim == 2)):
raise TypeError('syn_param_values must be a 2-dimensional NumPy array')
@@ -305,6 +307,9 @@ cdef class NESTEngine:
raise ValueError('weights must be an array of the same length as sources and targets.')
if delays is not None and len(sources) != len(delays):
raise ValueError('delays must be an array of the same length as sources and targets.')
+ if axonal_delays is not None:
+ if not len(sources) == len(axonal_delays):
+ raise ValueError('axonal_delays must be an array of the same length as sources and targets.')
if syn_param_values is not None:
if not len(syn_param_keys) == syn_param_values.shape[0]:
raise ValueError('syn_param_values must be a matrix with one array per key in syn_param_keys.')
@@ -330,6 +335,18 @@ cdef class NESTEngine:
delays_mv = numpy.ascontiguousarray(delays, dtype=numpy.double)
delays_ptr = &delays_mv[0]
+ cdef double[::1] dendritic_delays_mv
+ cdef double* dendritic_delays_ptr = NULL
+ if dendritic_delays is not None:
+ dendritic_delays_mv = numpy.ascontiguousarray(dendritic_delays, dtype=numpy.double)
+ dendritic_delays_ptr = &dendritic_delays_mv[0]
+
+ cdef double[::1] axonal_delays_mv
+ cdef double* axonal_delays_ptr = NULL
+ if axonal_delays is not None:
+ axonal_delays_mv = numpy.ascontiguousarray(axonal_delays, dtype=numpy.double)
+ axonal_delays_ptr = &axonal_delays_mv[0]
+
# Storing parameter keys in a vector of strings
cdef vector[string] param_keys_ptr
if syn_param_keys is not None:
@@ -345,7 +362,7 @@ cdef class NESTEngine:
cdef string syn_model_string = synapse_model.encode('UTF-8')
try:
- connect_arrays( sources_ptr, targets_ptr, weights_ptr, delays_ptr, param_keys_ptr, param_values_ptr, len(sources), syn_model_string )
+ connect_arrays( sources_ptr, targets_ptr, weights_ptr, delays_ptr, dendritic_delays_ptr, axonal_delays_ptr, param_keys_ptr, param_values_ptr, len(sources), syn_model_string )
except RuntimeError as e:
exceptionCls = getattr(NESTErrors, str(e))
raise exceptionCls('connect_arrays', '') from None
diff --git a/sli/dictstack.h b/sli/dictstack.h
index e4b05e0118..ca8d957fc1 100644
--- a/sli/dictstack.h
+++ b/sli/dictstack.h
@@ -144,7 +144,7 @@ class DictionaryStack
/** Clear the entire cache.
- * This should be called whenever a dictionary is pushed or poped.
+ * This should be called whenever a dictionary is pushed or popped.
* Alternative, one could just clear the names from the moved dictionary.
*/
void
diff --git a/testsuite/pytests/connect_test_base.py b/testsuite/pytests/connect_test_base.py
index 12124080ba..0643313116 100644
--- a/testsuite/pytests/connect_test_base.py
+++ b/testsuite/pytests/connect_test_base.py
@@ -63,8 +63,7 @@ class ConnectTestBase(unittest.TestCase):
# number of threads
nr_threads = 2
- # for now only tests if a multi-thread connect is successful, not whether
- # the the threading is actually used
+ # for now only tests if a multi-thread connect is successful, not whether the threading is actually used
def setUp(self):
nest.ResetKernel()
nest.local_num_threads = self.nr_threads
diff --git a/testsuite/pytests/sli2py_connect/test_gap_junction.py b/testsuite/pytests/sli2py_connect/test_gap_junction.py
index dcc94d7893..8ec5f00e3f 100644
--- a/testsuite/pytests/sli2py_connect/test_gap_junction.py
+++ b/testsuite/pytests/sli2py_connect/test_gap_junction.py
@@ -72,7 +72,7 @@ def test_neuron_gap_connect_with_delay_fails(conn_spec):
leads to an error.
"""
syn_spec = {"synapse_model": "gap_junction", "delay": 2.0}
- with pytest.raises(nest.kernel.NESTError, match="gap_junction connection has no delay"):
+ with pytest.raises(nest.kernel.NESTError, match="Delay specified for a connection type which doesn't use delays."):
nest.Connect(pytest.neuron_gap, pytest.neuron_gap, conn_spec=conn_spec, syn_spec=syn_spec)
diff --git a/testsuite/pytests/sli2py_recording/test_compare_delta.py b/testsuite/pytests/sli2py_recording/test_compare_delta.py
index 7af5f8f5ec..60b7eba672 100644
--- a/testsuite/pytests/sli2py_recording/test_compare_delta.py
+++ b/testsuite/pytests/sli2py_recording/test_compare_delta.py
@@ -63,5 +63,5 @@ def test_simulation_completes():
spike_recs = spike_recorder.get("events", ["senders", "times"])
- assert np.all(np.in1d(np.array([1, 2]), spike_recs["senders"].T[:2]))
+ assert np.all(np.isin(np.array([1, 2]), spike_recs["senders"].T[:2]))
assert np.all(spike_recs["times"].T[:2] == pytest.approx(4.1))
diff --git a/testsuite/pytests/sli2py_regressions/test_ticket_941.py b/testsuite/pytests/sli2py_regressions/test_ticket_941.py
index 7c8d33cd60..18aa71f450 100644
--- a/testsuite/pytests/sli2py_regressions/test_ticket_941.py
+++ b/testsuite/pytests/sli2py_regressions/test_ticket_941.py
@@ -95,4 +95,4 @@ def test_different_connections():
synapses = nest.GetConnections(source=pn1, target=pn2).get("synapse_model")
expected_synapses = ["static_synapse", "static_synapse", "static_synapse_hom_w"]
- assert np.all(np.in1d(expected_synapses, synapses))
+ assert np.all(np.isin(expected_synapses, synapses))
diff --git a/testsuite/pytests/test_axonal_delay_connectivity_changed.py b/testsuite/pytests/test_axonal_delay_connectivity_changed.py
new file mode 100644
index 0000000000..1dfdf8c9c2
--- /dev/null
+++ b/testsuite/pytests/test_axonal_delay_connectivity_changed.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+#
+# test_axonal_delay_connectivity_changed.py
+#
+# 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 .
+
+import nest
+import pytest
+
+
+@pytest.mark.parametrize("conn1, conn2", [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
+def test_axonal_delay_connectivity_changed(conn1, conn2):
+ """
+ Test that changing connectivity during simulation throws an exception when using axonal delays.
+ """
+ nest.ResetKernel()
+
+ nest.SetKernelStatus({"min_delay": 1.0, "max_delay": 2.0})
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay", "axonal_delay": conn1})
+
+ nest.Simulate(nest.resolution)
+
+ nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay", "axonal_delay": conn2})
+
+ if conn1 > 0.0 or conn2 > 0.0:
+ with pytest.raises(nest.kernel.NESTError):
+ nest.Simulate(nest.resolution)
+ else:
+ nest.Simulate(nest.resolution)
diff --git a/testsuite/pytests/test_axonal_delay_user_interface.py b/testsuite/pytests/test_axonal_delay_user_interface.py
new file mode 100644
index 0000000000..4a7ce7f8a4
--- /dev/null
+++ b/testsuite/pytests/test_axonal_delay_user_interface.py
@@ -0,0 +1,251 @@
+# -*- coding: utf-8 -*-
+#
+# test_axonal_delay_user_interface.py
+#
+# 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 .
+
+import nest
+import pytest
+
+
+def test_total_delay_user_interface_connect_success():
+ """
+ Make sure that one can only set the total delay and not just the axonal or dendritic delay for synapses which only
+ support a total transmission delay in the Connect call.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom", "delay": 1.0}, return_synapsecollection=True
+ )
+ assert nest.GetStatus(conn)[0]["delay"] == 1.0
+
+
+def test_total_delay_user_interface_set_status_success():
+ """
+ Make sure that one can only set the total delay and not just the axonal or dendritic delay for synapses which only
+ support a total transmission delay when using SetStatus.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom"}, return_synapsecollection=True
+ )
+ nest.SetStatus(conn, {"delay": 1.0})
+ assert nest.GetStatus(conn)[0]["delay"] == 1.0
+
+
+def test_total_delay_user_interface_set_defaults_success():
+ """
+ Make sure that one can only set the total delay and not just the axonal or dendritic delay for synapses which only
+ support a total transmission delay when using SetDefaults.
+ """
+ nest.ResetKernel()
+
+ nest.SetDefaults("stdp_pl_synapse_hom", {"delay": 1.0})
+ assert nest.GetDefaults("stdp_pl_synapse_hom")["delay"] == 1.0
+
+
+@pytest.mark.parametrize("ax_delay, dend_delay", [[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
+def test_split_delay_user_interface_connect_success(ax_delay, dend_delay):
+ """
+ Make sure that one can only set the axonal or dendritic delay for synapses which support split axonal and dendritic
+ delays and setting the total transmission delay via the "delay" parameter name must fail because of ambiguity.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron,
+ neuron,
+ syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay", "axonal_delay": 1.0},
+ return_synapsecollection=True,
+ )
+ assert nest.GetStatus(conn)[0]["axonal_delay"] == 1.0
+ conn = nest.Connect(
+ neuron,
+ neuron,
+ syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay", "dendritic_delay": 1.0},
+ return_synapsecollection=True,
+ )
+ assert nest.GetStatus(conn)[0]["dendritic_delay"] == 1.0
+
+
+@pytest.mark.parametrize("ax_delay, dend_delay", [[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
+def test_split_delay_user_interface_set_status_success(ax_delay, dend_delay):
+ """
+ Make sure that one can only set the axonal or dendritic delay for synapses which support split axonal and dendritic
+ delays and setting the total transmission delay via the "delay" parameter name must fail because of ambiguity.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay"}, return_synapsecollection=True
+ )
+ nest.SetStatus(conn, {"axonal_delay": 1.0})
+ nest.SetStatus(conn, {"dendritic_delay": 1.0})
+ assert nest.GetStatus(conn)[0]["axonal_delay"] == 1.0
+ assert nest.GetStatus(conn)[0]["dendritic_delay"] == 1.0
+
+
+@pytest.mark.parametrize("ax_delay, dend_delay", [[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
+def test_split_delay_user_interface_set_defaults_success(ax_delay, dend_delay):
+ """
+ Make sure that one can set the axonal or dendritic delay for synapses which support split axonal and dendritic
+ delays and setting the total transmission delay via the "delay" parameter name must fail because of ambiguity.
+ """
+ nest.ResetKernel()
+
+ nest.SetDefaults("stdp_pl_synapse_hom_ax_delay", {"axonal_delay": 1.0})
+ nest.SetDefaults("stdp_pl_synapse_hom_ax_delay", {"dendritic_delay": 1.0})
+ assert nest.GetDefaults("stdp_pl_synapse_hom_ax_delay")["axonal_delay"] == 1.0
+ assert nest.GetDefaults("stdp_pl_synapse_hom_ax_delay")["dendritic_delay"] == 1.0
+
+
+def test_total_delay_user_interface_connect_failure():
+ """
+ Make sure that one can only set the total delay and not just the axonal or dendritic delay for synapses which only
+ support a total transmission delay in the Connect call.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ with pytest.raises(nest.kernel.NESTError):
+ nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom", "axonal_delay": 1.0})
+ with pytest.raises(nest.kernel.NESTError):
+ nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom", "dendritic_delay": 1.0})
+
+
+def test_total_delay_user_interface_set_status_failure():
+ """
+ Make sure that one can only set the total delay and not just the axonal or dendritic delay for synapses which only
+ support a total transmission delay when using SetStatus.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom"}, return_synapsecollection=True
+ )
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetStatus(conn, {"dendritic_delay": 1.0})
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetStatus(conn, {"axonal_delay": 1.0})
+
+
+def test_total_delay_user_interface_set_defaults_failure():
+ """
+ Make sure that one can only set the total delay and not just the axonal or dendritic delay for synapses which only
+ support a total transmission delay when using SetDefaults.
+ """
+ nest.ResetKernel()
+
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetDefaults("stdp_pl_synapse_hom", {"axonal_delay": 1.0})
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetDefaults("stdp_pl_synapse_hom", {"dendritic_delay": 1.0})
+
+
+def test_split_delay_user_interface_connect_failure():
+ """
+ Make sure that setting the total transmission delay via the "delay" parameter name in Connect fails because of
+ ambiguity.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ with pytest.raises(nest.kernel.NESTError):
+ nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay", "delay": 1.0})
+
+
+def test_split_delay_user_interface_set_status_failure():
+ """
+ Make sure that setting the total transmission delay via the "delay" parameter name in SetStatus fails because of
+ ambiguity.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay"}, return_synapsecollection=True
+ )
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetStatus(conn, {"delay": 1.0})
+
+
+def test_split_delay_user_interface_set_defaults_failure():
+ """
+ Make sure that setting the total transmission delay via the "delay" parameter name in SetDefaults fails because of
+ ambiguity.
+ """
+ nest.ResetKernel()
+
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetDefaults("stdp_pl_synapse_hom_ax_delay", {"delay": 1.0})
+
+
+def test_split_delay_user_interface_connect_zero_delay_failure():
+ """
+ Make sure that either the dendritic or axonal delay is non-zero.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ with pytest.raises(nest.kernel.NESTError):
+ nest.Connect(
+ neuron,
+ neuron,
+ syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay", "dendritic_delay": 0.0, "axonal_delay": 0.0},
+ )
+
+
+def test_split_delay_user_interface_set_status_zero_delay_failure():
+ """
+ Make sure that either the dendritic or axonal delay is non-zero.
+ """
+ nest.ResetKernel()
+
+ neuron = nest.Create("iaf_psc_alpha")
+
+ conn = nest.Connect(
+ neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay"}, return_synapsecollection=True
+ )
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetStatus(conn, {"dendritic_delay": 0.0, "axonal_delay": 0.0})
+
+
+def test_split_delay_user_interface_set_defaults_zero_delay_failure():
+ """
+ Make sure that either the dendritic or axonal delay is non-zero.
+ """
+ nest.ResetKernel()
+
+ with pytest.raises(nest.kernel.NESTError):
+ nest.SetDefaults("stdp_pl_synapse_hom_ax_delay", {"dendritic_delay": 0.0, "axonal_delay": 0.0})
diff --git a/testsuite/pytests/test_labeled_synapses.py b/testsuite/pytests/test_labeled_synapses.py
index 0ff60ceec7..ae0e430edb 100644
--- a/testsuite/pytests/test_labeled_synapses.py
+++ b/testsuite/pytests/test_labeled_synapses.py
@@ -55,6 +55,12 @@ def default_network(self, syn_model):
self.clopath_synapses = ["clopath_synapse", "clopath_synapse_lbl", "clopath_synapse_hpc"]
+ self.axonal_delay_synapses = [
+ "stdp_pl_synapse_hom_ax_delay",
+ "stdp_pl_synapse_hom_ax_delay_lbl",
+ "stdp_pl_synapse_hom_ax_delay_hpc",
+ ]
+
self.urbanczik_synapses = ["urbanczik_synapse", "urbanczik_synapse_lbl", "urbanczik_synapse_hpc"]
self.eprop_synapses_bsshslm_2020 = ["eprop_synapse_bsshslm_2020", "eprop_synapse_bsshslm_2020_hpc"]
@@ -88,6 +94,10 @@ def default_network(self, syn_model):
if syn_model in self.clopath_synapses:
neurons = nest.Create("hh_psc_alpha_clopath", 5)
+ # in case of synapses with axonal delays use a supported model instead
+ if syn_model in self.axonal_delay_synapses:
+ neurons = nest.Create("iaf_psc_alpha", 5)
+
r_type = 0
# in case of the urbanczik synapse use a supported model instead
if syn_model in self.urbanczik_synapses:
diff --git a/testsuite/pytests/test_sp/test_disconnect_multiple.py b/testsuite/pytests/test_sp/test_disconnect_multiple.py
index a3eeebf0ed..95b313f5be 100644
--- a/testsuite/pytests/test_sp/test_disconnect_multiple.py
+++ b/testsuite/pytests/test_sp/test_disconnect_multiple.py
@@ -35,6 +35,10 @@ def setUp(self):
"stdp_dopamine_synapse_lbl",
"stdp_dopamine_synapse_hpc",
"stdp_dopamine_synapse_hpc_lbl",
+ "stdp_pl_synapse_hom_ax_delay",
+ "stdp_pl_synapse_hom_ax_delay_lbl",
+ "stdp_pl_synapse_hom_ax_delay_hpc",
+ "stdp_pl_synapse_hom_ax_delay_hpc_lbl",
"gap_junction",
"gap_junction_lbl",
"diffusion_connection",
@@ -66,7 +70,6 @@ def test_multiple_synapse_deletion_all_to_all(self):
for syn_model in nest.synapse_models:
if syn_model not in self.exclude_synapse_model:
nest.ResetKernel()
- nest.CopyModel("static_synapse", "my_static_synapse")
nest.SetDefaults(syn_model, {"delay": 0.5})
syn_dict = {"synapse_model": syn_model, "pre_synaptic_element": "SE1", "post_synaptic_element": "SE2"}
# For co-dependent properties, we use `set()` instead of kernel attributes
@@ -113,7 +116,6 @@ def test_multiple_synapse_deletion_one_to_one(self):
for syn_model in nest.synapse_models:
if syn_model not in self.exclude_synapse_model:
nest.ResetKernel()
- nest.CopyModel("static_synapse", "my_static_synapse")
nest.SetDefaults(syn_model, {"delay": 0.5})
syn_dict = {"synapse_model": syn_model, "pre_synaptic_element": "SE1", "post_synaptic_element": "SE2"}
# For co-dependent properties, we use `set()` instead of kernel attributes
@@ -160,7 +162,6 @@ def test_multiple_synapse_deletion_one_to_one_no_sp(self):
for syn_model in nest.synapse_models:
if syn_model not in self.exclude_synapse_model:
nest.ResetKernel()
- nest.CopyModel("static_synapse", "my_static_synapse")
neurons = nest.Create("iaf_psc_alpha", 10)
syn_dict = {"synapse_model": syn_model}
nest.Connect(neurons, neurons, "all_to_all", syn_dict)
diff --git a/testsuite/pytests/test_sp/test_sp_manager.py b/testsuite/pytests/test_sp/test_sp_manager.py
index 4631b613ab..f1334c37c9 100644
--- a/testsuite/pytests/test_sp/test_sp_manager.py
+++ b/testsuite/pytests/test_sp/test_sp_manager.py
@@ -39,6 +39,10 @@ def setUp(self):
"stdp_dopamine_synapse_lbl",
"stdp_dopamine_synapse_hpc",
"stdp_dopamine_synapse_hpc_lbl",
+ "stdp_pl_synapse_hom_ax_delay",
+ "stdp_pl_synapse_hom_ax_delay_lbl",
+ "stdp_pl_synapse_hom_ax_delay_hpc",
+ "stdp_pl_synapse_hom_ax_delay_hpc_lbl",
"gap_junction",
"gap_junction_lbl",
"diffusion_connection",
diff --git a/testsuite/pytests/test_spatial/test_axonal_delay.py b/testsuite/pytests/test_spatial/test_axonal_delay.py
new file mode 100644
index 0000000000..ee7c9cad16
--- /dev/null
+++ b/testsuite/pytests/test_spatial/test_axonal_delay.py
@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*-
+#
+# test_axonal_delay.py
+#
+# 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 .
+
+"""
+Test setting axonal and dendritic delays for models supporting this and those that don't, which must throw an exception.
+
+The test checks that weights and delays in a spatial network can be set to arbitrary values within the limits set by
+resolution. The test creates a layer with a single row and uses linear functions for weights and delays. Expected
+combined dendritic and axonal delays with resolution 0.04 are 1.0 0.96 0.96 0.92 0.92 0.88 0.84. One model supports
+setting dendritic and axonal delays and one does not, which is expected to throw an exception.
+"""
+
+import nest
+import numpy as np
+import pytest
+
+
+def build_network(synapse_model):
+ """Build spatial network."""
+
+ nest.ResetKernel()
+ nest.resolution = 0.04
+ nest.use_compressed_spikes = False
+
+ p1 = nest.CreateParameter("constant", {"value": 0.5})
+ p2 = nest.CreateParameter("constant", {"value": -0.01})
+ p3 = nest.CreateParameter("distance", {})
+ linear_parameter = p1 + p2 * p3
+
+ syn_spec = {
+ "synapse_model": synapse_model,
+ "weight": linear_parameter,
+ "dendritic_delay": linear_parameter,
+ "axonal_delay": linear_parameter,
+ }
+ pos = nest.spatial.grid(
+ shape=[10, 1],
+ extent=[10.0, 1.0],
+ center=[0.0, 0.0],
+ edge_wrap=True,
+ )
+ conn_spec = {
+ "rule": "pairwise_bernoulli",
+ "use_on_source": False,
+ "mask": {"grid": {"shape": [10, 1]}, "anchor": [0, 0]},
+ }
+
+ src_layer = nest.Create("iaf_psc_alpha", positions=pos)
+ tgt_layer = nest.Create("iaf_psc_alpha", positions=pos)
+
+ nest.Connect(src_layer, tgt_layer, conn_spec=conn_spec, syn_spec=syn_spec)
+
+ return src_layer, tgt_layer
+
+
+def test_layer_connections_dump_success(tmp_path, expected_conn_dump):
+ """Test that layer connections dump matches expectation."""
+
+ synapse_model = "stdp_pl_synapse_hom_ax_delay"
+ src_layer, tgt_layer = build_network(synapse_model)
+
+ fname = tmp_path / "layer_conns.txt"
+ nest.DumpLayerConnections(src_layer, tgt_layer, synapse_model, fname)
+
+ # We need to sort results to be invariant against implementation-dependent output order
+ actual_conn_dump = fname.read_text().splitlines()
+ assert actual_conn_dump.sort() == expected_conn_dump.sort()
+
+
+def test_layer_connections_dump_failure():
+ """Test that this synapse model is not compatible with the layer parameters."""
+
+ with pytest.raises(nest.kernel.NESTError):
+ build_network("static_synapse")
+
+
+@pytest.fixture(scope="module")
+def expected_conn_dump():
+ expected_conn_dump = [
+ "1 11 1 1 0 0",
+ "1 12 0.98 1 1 0",
+ "1 13 0.96 0.96 2 0",
+ "1 14 0.94 0.96 3 0",
+ "1 15 0.92 0.92 4 0",
+ "1 16 0.9 0.92 -5 0",
+ "1 17 0.92 0.92 -4 0",
+ "1 18 0.94 0.96 -3 0",
+ "1 19 0.96 0.96 -2 0",
+ "1 20 0.98 1 -1 0",
+ "2 11 0.98 1 -1 0",
+ "2 12 1 1 0 0",
+ "2 13 0.98 1 1 0",
+ "2 14 0.96 0.96 2 0",
+ "2 15 0.94 0.96 3 0",
+ "2 16 0.92 0.92 4 0",
+ "2 17 0.9 0.92 -5 0",
+ "2 18 0.92 0.92 -4 0",
+ "2 19 0.94 0.96 -3 0",
+ "2 20 0.96 0.96 -2 0",
+ "3 11 0.96 0.96 -2 0",
+ "3 12 0.98 1 -1 0",
+ "3 13 1 1 0 0",
+ "3 14 0.98 1 1 0",
+ "3 15 0.96 0.96 2 0",
+ "3 16 0.94 0.96 3 0",
+ "3 17 0.92 0.92 4 0",
+ "3 18 0.9 0.92 -5 0",
+ "3 19 0.92 0.92 -4 0",
+ "3 20 0.94 0.96 -3 0",
+ "4 11 0.94 0.96 -3 0",
+ "4 12 0.96 0.96 -2 0",
+ "4 13 0.98 1 -1 0",
+ "4 14 1 1 0 0",
+ "4 15 0.98 1 1 0",
+ "4 16 0.96 0.96 2 0",
+ "4 17 0.94 0.96 3 0",
+ "4 18 0.92 0.92 4 0",
+ "4 19 0.9 0.92 -5 0",
+ "4 20 0.92 0.92 -4 0",
+ "5 11 0.92 0.92 -4 0",
+ "5 12 0.94 0.96 -3 0",
+ "5 13 0.96 0.96 -2 0",
+ "5 14 0.98 1 -1 0",
+ "5 15 1 1 0 0",
+ "5 16 0.98 1 1 0",
+ "5 17 0.96 0.96 2 0",
+ "5 18 0.94 0.96 3 0",
+ "5 19 0.92 0.92 4 0",
+ "5 20 0.9 0.92 -5 0",
+ "6 11 0.9 0.92 -5 0",
+ "6 12 0.92 0.92 -4 0",
+ "6 13 0.94 0.96 -3 0",
+ "6 14 0.96 0.96 -2 0",
+ "6 15 0.98 1 -1 0",
+ "6 16 1 1 0 0",
+ "6 17 0.98 1 1 0",
+ "6 18 0.96 0.96 2 0",
+ "6 19 0.94 0.96 3 0",
+ "6 20 0.92 0.92 4 0",
+ "7 11 0.92 0.92 4 0",
+ "7 12 0.9 0.92 -5 0",
+ "7 13 0.92 0.92 -4 0",
+ "7 14 0.94 0.96 -3 0",
+ "7 15 0.96 0.96 -2 0",
+ "7 16 0.98 1 -1 0",
+ "7 17 1 1 0 0",
+ "7 18 0.98 1 1 0",
+ "7 19 0.96 0.96 2 0",
+ "7 20 0.94 0.96 3 0",
+ "8 11 0.94 0.96 3 0",
+ "8 12 0.92 0.92 4 0",
+ "8 13 0.9 0.92 -5 0",
+ "8 14 0.92 0.92 -4 0",
+ "8 15 0.94 0.96 -3 0",
+ "8 16 0.96 0.96 -2 0",
+ "8 17 0.98 1 -1 0",
+ "8 18 1 1 0 0",
+ "8 19 0.98 1 1 0",
+ "8 20 0.96 0.96 2 0",
+ "9 11 0.96 0.96 2 0",
+ "9 12 0.94 0.96 3 0",
+ "9 13 0.92 0.92 4 0",
+ "9 14 0.9 0.92 -5 0",
+ "9 15 0.92 0.92 -4 0",
+ "9 16 0.94 0.96 -3 0",
+ "9 17 0.96 0.96 -2 0",
+ "9 18 0.98 1 -1 0",
+ "9 19 1 1 0 0",
+ "9 20 0.98 1 1 0",
+ "10 11 0.98 1 1 0",
+ "10 12 0.96 0.96 2 0",
+ "10 13 0.94 0.96 3 0",
+ "10 14 0.92 0.92 4 0",
+ "10 15 0.9 0.92 -5 0",
+ "10 16 0.92 0.92 -4 0",
+ "10 17 0.94 0.96 -3 0",
+ "10 18 0.96 0.96 -2 0",
+ "10 19 0.98 1 -1 0",
+ "10 20 1 1 0 0",
+ ]
+ return expected_conn_dump
diff --git a/testsuite/pytests/test_spatial/test_weight_delay.py b/testsuite/pytests/test_spatial/test_weight_delay.py
index f0569d80b0..bb126fdaff 100644
--- a/testsuite/pytests/test_spatial/test_weight_delay.py
+++ b/testsuite/pytests/test_spatial/test_weight_delay.py
@@ -85,7 +85,7 @@ def build_network(layer_type):
@pytest.mark.parametrize("layer_type", ["grid", "free"])
def test_source_layer_nodes_dump(tmp_path, expected_source_nodes_dump, layer_type):
- """Test that source layer nodes dump mathces expectation."""
+ """Test that source layer nodes dump matches expectation."""
src_layer, _ = build_network(layer_type)
@@ -98,7 +98,7 @@ def test_source_layer_nodes_dump(tmp_path, expected_source_nodes_dump, layer_typ
@pytest.mark.parametrize("layer_type", ["grid", "free"])
def test_target_layer_nodes_dump(tmp_path, expected_target_nodes_dump, layer_type):
- """Test that target layer nodes dump mathces expectation."""
+ """Test that target layer nodes dump matches expectation."""
_, tgt_layer = build_network(layer_type)
@@ -111,7 +111,7 @@ def test_target_layer_nodes_dump(tmp_path, expected_target_nodes_dump, layer_typ
@pytest.mark.parametrize("layer_type", ["grid", "free"])
def test_layer_connections_dump(tmp_path, expected_conn_dump, layer_type):
- """Test that layer connections dump mathces expectation."""
+ """Test that layer connections dump matches expectation."""
src_layer, tgt_layer = build_network(layer_type)
diff --git a/testsuite/pytests/test_stdp_pl_synapse_hom.py b/testsuite/pytests/test_stdp_pl_synapse_hom.py
index 4243ccc004..a635380882 100644
--- a/testsuite/pytests/test_stdp_pl_synapse_hom.py
+++ b/testsuite/pytests/test_stdp_pl_synapse_hom.py
@@ -36,6 +36,9 @@
except Exception:
DEBUG_PLOTS = False
+# Defined here so we can use it in init_params() and in parametrization
+RESOLUTION = 0.1 # [ms]
+
@nest.ll_api.check_stack
class TestSTDPPlSynapse:
@@ -47,9 +50,8 @@ class TestSTDPPlSynapse:
"""
def init_params(self):
- self.resolution = 0.1 # [ms]
- self.simulation_duration = 1e3 # [ms]
- self.synapse_model = "stdp_pl_synapse_hom"
+ self.simulation_duration = 1e2 # [ms]
+ self.synapse_model = "stdp_pl_synapse_hom_ax_delay"
self.presynaptic_firing_rate = 100.0 # [ms^-1]
self.postsynaptic_firing_rate = 100.0 # [ms^-1]
self.tau_pre = 20.0
@@ -85,23 +87,27 @@ def do_nest_simulation_and_compare_to_reproduced_weight(self, fname_snip):
weight_reproduced_independently,
Kpre_log,
Kpost_log,
+ allowed_to_deviate,
) = self.reproduce_weight_drift(pre_spikes, post_spikes, self.init_weight, fname_snip=fname_snip)
# ``weight_by_nest`` contains only weight values at pre spike times, ``weight_reproduced_independently``
# contains the weight at pre *and* post times: check that weights are equal only for pre spike times
assert len(weight_by_nest) > 0
- difference_matrix = t_weight_by_nest[t_weight_by_nest < self.simulation_duration].reshape(
- 1, -1
- ) - t_weight_reproduced_independently.reshape(-1, 1)
+ difference_matrix = (
+ t_weight_by_nest[t_weight_by_nest < self.simulation_duration].reshape(1, -1)
+ + self.axonal_delay
+ - t_weight_reproduced_independently.reshape(-1, 1)
+ )
pre_spike_reproduced_indices = np.abs(difference_matrix).argmin(axis=0)
time_differences = np.diagonal(difference_matrix[pre_spike_reproduced_indices])
# make sure all spike times are equal
np.testing.assert_allclose(time_differences, 0, atol=1e-07)
+ weights_to_consider = ~allowed_to_deviate[pre_spike_reproduced_indices]
# make sure the weights after the pre_spikes times are equal
np.testing.assert_allclose(
- weight_by_nest[t_weight_by_nest < self.simulation_duration],
- weight_reproduced_independently[pre_spike_reproduced_indices],
+ weight_by_nest[t_weight_by_nest < self.simulation_duration][weights_to_consider],
+ weight_reproduced_independently[pre_spike_reproduced_indices][weights_to_consider],
)
if DEBUG_PLOTS:
@@ -133,13 +139,7 @@ def do_the_nest_simulation(self):
"""
nest.set_verbosity("M_WARNING")
nest.ResetKernel()
- nest.SetKernelStatus(
- {
- "resolution": self.resolution,
- "min_delay": min(self.min_delay, self.dendritic_delay),
- "max_delay": max(self.max_delay, self.dendritic_delay),
- }
- )
+ nest.SetKernelStatus({"resolution": RESOLUTION, "min_delay": self.min_delay, "max_delay": self.max_delay})
presynaptic_neuron, postsynaptic_neuron = nest.Create(self.nest_neuron_model, 2, params=self.neuron_parameters)
@@ -171,6 +171,7 @@ def do_the_nest_simulation(self):
{"spike_times": self.hardcoded_post_times + self.simulation_duration - self.hardcoded_trains_length},
),
)
+
pre_spike_generator = spike_senders[0]
post_spike_generator = spike_senders[1]
@@ -234,19 +235,20 @@ def depress(w, Kminus):
w_log = []
Kplus_log = []
Kminus_log = []
+ allowed_to_deviate = []
# Make sure only spikes that were relevant for simulation are actually considered in the test
# For pre-spikes that will be all spikes with: t_pre < sim_duration
- pre_spikes = pre_spikes[pre_spikes + eps < self.simulation_duration]
- # For post-spikes that will be all spikes with: t_post + d_dend <= latest_pre_spike
- post_spikes = post_spikes[post_spikes + self.dendritic_delay <= pre_spikes[-1] + eps]
+ pre_spikes_delayed = pre_spikes[pre_spikes + eps < self.simulation_duration] + self.axonal_delay
+ # For post-spikes that will be all spikes with: t_post + d_dend <= latest_pre_spike + d_axon
post_spikes_delayed = post_spikes + self.dendritic_delay
+ post_spikes_delayed = post_spikes_delayed[post_spikes_delayed <= pre_spikes_delayed[-1] + eps]
- while idx_next_pre_spike < len(pre_spikes) or idx_next_post_spike < len(post_spikes_delayed):
- if idx_next_pre_spike >= pre_spikes.size:
+ while idx_next_pre_spike < len(pre_spikes_delayed) or idx_next_post_spike < len(post_spikes_delayed):
+ if idx_next_pre_spike >= pre_spikes_delayed.size:
t_next_pre_spike = -1
else:
- t_next_pre_spike = pre_spikes[idx_next_pre_spike]
+ t_next_pre_spike = pre_spikes_delayed[idx_next_pre_spike]
if idx_next_post_spike >= post_spikes_delayed.size:
t_next_post_spike = -1
@@ -288,11 +290,36 @@ def depress(w, Kminus):
if not handle_pre_spike or abs(t_next_post_spike - t_last_post_spike) > eps:
if abs(t_next_post_spike - t_last_pre_spike) > eps:
weight = facilitate(weight, Kplus)
+ # if time when next pre-synaptic spike is being communicated is before post-synaptic spike
+ # occurs, a correction will be required in NEST
+ if (
+ t_next_pre_spike - RESOLUTION - self.axonal_delay + self.min_delay
+ ) // self.min_delay * self.min_delay < t_next_post_spike:
+ allowed_to_deviate.append(True)
+ else:
+ allowed_to_deviate.append(False)
if handle_pre_spike:
if not handle_post_spike or abs(t_next_pre_spike - t_last_pre_spike) > eps:
if abs(t_next_pre_spike - t_last_post_spike) > eps:
weight = depress(weight, Kminus)
+ # if the next post-synaptic spike occurs after the pre-synaptic is being communicated, but
+ # before the pre-synaptic spike arrives at the synapse, a correction will be required in NEST
+ if (
+ abs(t_next_post_spike - t_next_pre_spike) < eps
+ and (t_next_pre_spike - RESOLUTION - self.axonal_delay + self.min_delay)
+ // self.min_delay
+ * self.min_delay
+ < t_next_post_spike - self.dendritic_delay
+ ):
+ pass
+ elif (
+ t_next_pre_spike - RESOLUTION - self.axonal_delay + self.min_delay
+ ) // self.min_delay * self.min_delay < t_last_post_spike:
+ allowed_to_deviate.append(True)
+ else:
+ allowed_to_deviate.append(False)
+
t_last_pre_spike = t_next_pre_spike
Kplus += 1.0
@@ -318,7 +345,7 @@ def depress(w, Kminus):
title_snip="Reference",
)
- return np.array(t_log), np.array(w_log), Kplus_log, Kminus_log
+ return np.array(t_log), np.array(w_log), Kplus_log, Kminus_log, np.array(allowed_to_deviate)
def plot_weight_evolution(
self,
@@ -368,17 +395,23 @@ def plot_weight_evolution(
fig.savefig("./tmp/nest_stdp_pl_synapse_hom_test" + fname_snip + ".png", dpi=300)
plt.close(fig)
- def test_stdp_synapse(self):
+ @pytest.mark.parametrize(
+ ["dend_delay", "ax_delay"], ((1.0, 0.0), (0.5, 0.5), (0.0, 1.0), (RESOLUTION, 0.0), (0.0, RESOLUTION))
+ )
+ @pytest.mark.parametrize("model", ("iaf_psc_alpha",))
+ @pytest.mark.parametrize("min_delay", (1.0, 0.4, RESOLUTION))
+ @pytest.mark.parametrize("max_delay", (1.0, 3.0))
+ @pytest.mark.parametrize("t_ref", (RESOLUTION, 0.5, 1.0, 1.1, 2.5))
+ def test_stdp_synapse(self, dend_delay, ax_delay, model, min_delay, max_delay, t_ref):
self.init_params()
- for self.dendritic_delay in (1.0, 0.5, self.resolution):
- self.synapse_parameters["delay"] = self.dendritic_delay
- for self.min_delay in (1.0, 0.4, self.resolution):
- for self.max_delay in (3.0, 1.0):
- self.min_delay = min(self.min_delay, self.max_delay)
- self.max_delay = max(self.min_delay, self.max_delay)
- for self.nest_neuron_model in ("iaf_psc_exp", "iaf_cond_exp"):
- for self.neuron_parameters["t_ref"] in (self.resolution, 0.5, 1.0, 1.1, 2.5):
- fname_snip = "_[nest_neuron_mdl=" + self.nest_neuron_model + "]"
- fname_snip += "_[dend_delay=" + str(self.dendritic_delay) + "]"
- fname_snip += "_[t_ref=" + str(self.neuron_parameters["t_ref"]) + "]"
- self.do_nest_simulation_and_compare_to_reproduced_weight(fname_snip=fname_snip)
+ self.synapse_parameters["dendritic_delay"] = self.dendritic_delay = dend_delay
+ self.synapse_parameters["axonal_delay"] = self.axonal_delay = ax_delay
+ self.nest_neuron_model = model
+ self.min_delay = min(min_delay, max_delay, self.dendritic_delay + self.axonal_delay)
+ self.max_delay = max(min_delay, max_delay, self.dendritic_delay + self.axonal_delay)
+ self.neuron_parameters["t_ref"] = t_ref
+
+ fname_snip = "_[nest_neuron_mdl=" + self.nest_neuron_model + "]"
+ fname_snip += "_[dend_delay=" + str(self.dendritic_delay) + "]"
+ fname_snip += "_[t_ref=" + str(self.neuron_parameters["t_ref"]) + "]"
+ self.do_nest_simulation_and_compare_to_reproduced_weight(fname_snip=fname_snip)
diff --git a/testsuite/pytests/test_stdp_synapse.py b/testsuite/pytests/test_stdp_synapse.py
index ccd0981c6d..1ff69c9e4c 100644
--- a/testsuite/pytests/test_stdp_synapse.py
+++ b/testsuite/pytests/test_stdp_synapse.py
@@ -51,7 +51,6 @@ class TestSTDPSynapse:
"""
def init_params(self):
- self.resolution = RESOLUTION # [ms]
self.simulation_duration = 1000 # [ms]
self.synapse_model = "stdp_synapse"
self.presynaptic_firing_rate = 100.0 # [ms^-1]
@@ -71,9 +70,7 @@ def init_params(self):
"Wmax": 15.0,
"weight": self.init_weight,
}
- self.neuron_parameters = {
- "tau_minus": self.tau_post,
- }
+ self.neuron_parameters = {"tau_minus": self.tau_post}
# While the random sequences, fairly long, would supposedly reveal small differences in the weight change
# between NEST and ours, some low-probability events (say, coinciding spikes) can well not have occurred.
@@ -154,7 +151,7 @@ def do_the_nest_simulation(self):
nest.ResetKernel()
nest.SetKernelStatus(
{
- "resolution": self.resolution,
+ "resolution": RESOLUTION,
"min_delay": min(self.min_delay, self.dendritic_delay),
"max_delay": max(self.max_delay, self.dendritic_delay),
}
@@ -399,7 +396,7 @@ def plot_weight_evolution(
_ax.set_xlim(0.0, self.simulation_duration)
fig.suptitle(title_snip)
- fig.savefig("/tmp/nest_stdp_synapse_test" + fname_snip + ".png", dpi=300)
+ fig.savefig("./tmp/nest_stdp_synapse_test" + fname_snip + ".png", dpi=300)
plt.close(fig)
@pytest.mark.parametrize("dend_delay", [RESOLUTION, 1.0])
@@ -409,12 +406,11 @@ def plot_weight_evolution(
@pytest.mark.parametrize("t_ref", (RESOLUTION, 0.5, 1.0, 1.1, 2.5))
def test_stdp_synapse(self, dend_delay, model, min_delay, max_delay, t_ref):
self.init_params()
- self.dendritic_delay = dend_delay
+ self.synapse_parameters["delay"] = self.dendritic_delay = dend_delay
self.nest_neuron_model = model
- self.min_delay = min(min_delay, max_delay)
- self.max_delay = max(min_delay, max_delay)
+ self.min_delay = min(min_delay, max_delay, self.dendritic_delay)
+ self.max_delay = max(min_delay, max_delay, self.dendritic_delay)
self.neuron_parameters["t_ref"] = t_ref
- self.synapse_parameters["delay"] = self.dendritic_delay
fname_snip = "_[nest_neuron_mdl=" + self.nest_neuron_model + "]"
fname_snip += "_[dend_delay=" + str(self.dendritic_delay) + "]"
diff --git a/testsuite/pytests/test_synapsecollection.py b/testsuite/pytests/test_synapsecollection.py
index 67a590d4d8..55116c1b4a 100644
--- a/testsuite/pytests/test_synapsecollection.py
+++ b/testsuite/pytests/test_synapsecollection.py
@@ -117,7 +117,11 @@ def test_get(self):
expected_syn_id = nest.GetDefaults("static_synapse", "synapse_modelid")
target_ref = [1, 2, 1, 2]
- dpw_ref = {"delay": [1.0, 1.0, 1.0, 1.0], "port": [0, 1, 2, 3], "weight": [1.0, 1.0, 1.0, 1.0]}
+ dpw_ref = {
+ "delay": [1.0, 1.0, 1.0, 1.0],
+ "port": [0, 1, 2, 3],
+ "weight": [1.0, 1.0, 1.0, 1.0],
+ }
all_ref = {
"delay": [1.0, 1.0, 1.0, 1.0],
"port": [0, 1, 2, 3],
diff --git a/testsuite/pytests/test_urbanczik_synapse.py b/testsuite/pytests/test_urbanczik_synapse.py
index 0b057fdd0a..0dfef42904 100644
--- a/testsuite/pytests/test_urbanczik_synapse.py
+++ b/testsuite/pytests/test_urbanczik_synapse.py
@@ -229,7 +229,7 @@ def test_SynapseDepressionFacilitation(self):
if len(spike_times_soma) > 0:
t = np.around(t, 4)
spike_times_soma = np.around(spike_times_soma + 0.2, 4)
- idx = np.nonzero(np.in1d(t, spike_times_soma))[0]
+ idx = np.nonzero(np.isin(t, spike_times_soma))[0]
rate[idx] -= 1.0 / resolution
w_change_raw = -15.0 * C_m_prox * rate * h * alpha_response
@@ -247,7 +247,7 @@ def test_SynapseDepressionFacilitation(self):
comparison between Nest and python implementation
"""
# extract the weight computed in python at the times of the presynaptic spikes
- idx = np.nonzero(np.in1d(np.around(t, 4), np.around(pre_syn_spike_times + resolution, 4)))[0]
+ idx = np.nonzero(np.isin(np.around(t, 4), np.around(pre_syn_spike_times + resolution, 4)))[0]
syn_w_comp_at_spike_times = syn_weight_comp[idx]
realtive_error = (weights[-1] - syn_w_comp_at_spike_times[-1]) / (weights[-1] - init_w)