NEST main@caf0ae8
 
Loading...
Searching...
No Matches
connector_model_impl.h
Go to the documentation of this file.
1/*
2 * connector_model_impl.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef CONNECTOR_MODEL_IMPL_H
24#define CONNECTOR_MODEL_IMPL_H
25
26#include "connector_model.h"
27
28// Generated includes:
29#include "config.h"
30
31// Includes from libnestutil:
32#include "compose.hpp"
33#include "enum_bitfield.h"
34
35// Includes from nestkernel:
36#include "connector_base.h"
37#include "delay_checker.h"
38#include "kernel_manager.h"
39#include "nest_time.h"
40#include "nest_timeconverter.h"
42
43
44namespace nest
45{
46
47// standard implementation to obtain the default delay
48// synapse types with homogeneous delays must provide a specialization
49// that returns the default delay from CommonProperties (or from elsewhere)
50// template<typename ConnectionT>
51// double get_default_delay(const GenericConnectorModel<ConnectionT> &cm)
52// {
53// //std::cout << "standard implementation of get_default_delay" << std::endl;
54// return cm.get_default_connection().get_delay();
55// }
56
57// template<typename ConnectionT>
58// SynIdDelay & syn_id_delay(const GenericConnectorModel<ConnectionT> &cm)
59// {
60// return cm.get_default_connection().get_syn_id_delay();
61// }
62
63template < typename ConnectionT >
64ConnectorModel*
66{
67 ConnectorModel* new_cm = new GenericConnectorModel( *this, name ); // calls copy construtor
68 new_cm->set_syn_id( syn_id );
69
70 const bool is_primary = new_cm->has_property( ConnectionModelProperties::IS_PRIMARY );
71 if ( not is_primary )
72 {
73 new_cm->get_secondary_event()->add_syn_id( syn_id );
74 }
75
76 return new_cm;
77}
78
79template < typename ConnectionT >
80void
82{
83 // calibrate the delay of the default properties here
84 default_connection_.calibrate( tc );
85
86 // Calibrate will be called after a change in resolution, when there are no
87 // network elements present.
88
89 // calibrate any time objects that might reside in CommonProperties
90 cp_.calibrate( tc );
91}
92
93template < typename ConnectionT >
94void
96{
97 // first get properties common to all synapses
98 // these are stored only once (not within each Connection)
99 cp_.get_status( d );
100
101 // then get default properties for individual synapses
102 default_connection_.get_status( d );
103
104 d[ names::receptor_type ] = static_cast< long >( receptor_type_ );
105 d[ names::synapse_model ] = name_;
106 d[ names::synapse_modelid ] = static_cast< long >( kernel().model_manager.get_synapse_model_id( name_ ) );
109}
110
111template < typename ConnectionT >
112void
114{
115 d.update_integer_value( names::receptor_type, receptor_type_ );
116#ifdef HAVE_MUSIC
117 // We allow music_channel as alias for receptor_type during connection setup
118 d.update_integer_value( names::music_channel, receptor_type_ );
119#endif
120
121 // If the parameter dict d contains /delay, this should set the delay
122 // on the default connection, but not affect the actual min/max_delay
123 // until a connection with that default delay is created. Since the
124 // set_status calls on common properties and default connection may
125 // modify min/max delay, we need to freeze the min/max_delay checking.
126
128
129 cp_.set_status( d, *this );
130 default_connection_.set_status( d, *this );
131
133
134 // we've possibly just got a new default delay. So enforce checking next time
135 // it is used
136 default_delay_needs_check_ = true;
137}
138
139template < typename ConnectionT >
140void
142{
143 // This is called just once per Connect() call, so we need not worry much about performance.
144 // We get a dictionary with synapse default values and check if any of its keys are in syn_spec.
145 Dictionary dummy;
146 cp_.get_status( dummy );
147
148 for ( [[maybe_unused]] const auto& [ key, val ] : syn_spec )
149 {
150 if ( dummy.known( key ) )
151 {
152 throw NotImplemented(
153 String::compose( "Synapse parameter \"%1\" can only be set via SetDefaults() or CopyModel().", key ) );
154 }
155 }
156
157 default_connection_.check_synapse_params( syn_spec );
158}
159
160
161template < typename ConnectionT >
162void
164{
165 // if not used before, check now. Solves bug #138, MH 08-01-08
166 // replaces whole delay checking for the default delay, see bug #217
167 // MH 08-04-24
168 // get_default_delay_ must be overridden by derived class to return the
169 // correct default delay (either from commonprops or default connection)
170 if ( default_delay_needs_check_ )
171 {
172 try
173 {
174 if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
175 {
176 const double d = default_connection_.get_delay();
178 }
179 // Let connections without delay contribute to the delay extrema with
180 // wfr_comm_interval. For those connections the min_delay is important
181 // as it determines the length of the global communication interval.
182 // The call to assert_valid_delay_ms needs to happen only once
183 // (either here or in add_connection()) when the first connection
184 // without delay is created.
185 else
186 {
187 const double wfr_comm_interval = kernel().simulation_manager.get_wfr_comm_interval();
189 }
190 }
191 catch ( BadDelay& e )
192 {
193 throw BadDelay( default_connection_.get_delay(),
194 String::compose( "Default delay of '%1' must be between min_delay %2 "
195 "and max_delay %3.",
196 get_name(),
197 Time::delay_steps_to_ms( kernel().connection_manager.get_min_delay() ),
198 Time::delay_steps_to_ms( kernel().connection_manager.get_max_delay() ) ) );
199 }
200 default_delay_needs_check_ = false;
201 }
202}
203
204template < typename ConnectionT >
205size_t
207{
208 return default_connection_.get_syn_id();
209}
210
211template < typename ConnectionT >
212void
214{
215 default_connection_.set_syn_id( syn_id );
216}
217
218template < typename ConnectionT >
219void
221 Node& tgt,
222 std::vector< ConnectorBase* >& thread_local_connectors,
223 const synindex syn_id,
224 const Dictionary& p,
225 const double delay,
226 const double weight )
227{
228 if ( not numerics::is_nan( delay ) )
229 {
230 if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
231 {
233 }
234
235 if ( p.known( names::delay ) )
236 {
237 throw BadParameter(
238 "Parameter dictionary must not contain delay if delay is given "
239 "explicitly." );
240 }
241 }
242 else
243 {
244 // check delay
245 double delay = 0.0;
246
247 if ( p.update_value( names::delay, delay ) )
248 {
249 if ( has_property( ConnectionModelProperties::HAS_DELAY ) )
250 {
252 }
253 }
254 else
255 {
256 used_default_delay();
257 }
258 }
259
260 // create a new instance of the default connection
261 ConnectionT connection = ConnectionT( default_connection_ );
262
263 if ( not numerics::is_nan( weight ) )
264 {
265 connection.set_weight( weight );
266 }
267
268 if ( not numerics::is_nan( delay ) )
269 {
270 connection.set_delay( delay );
271 }
272
273 if ( not p.empty() )
274 {
275 // Reference to connector model needed here to check delay (maybe this could
276 // be done one level above?).
277 connection.set_status( p, *this );
278 }
279
280 // We must use a local variable here to hold the actual value of the
281 // receptor type. We must not change the receptor_type_ data member, because
282 // that represents the *default* value. See #921.
283 size_t actual_receptor_type = receptor_type_;
284#ifdef HAVE_MUSIC
285 // We allow music_channel as alias for receptor_type during connection setup
286 p.update_integer_value( names::music_channel, actual_receptor_type );
287#endif
288 p.update_integer_value( names::receptor_type, actual_receptor_type );
289
290 add_connection_( src, tgt, thread_local_connectors, syn_id, connection, actual_receptor_type );
291}
292
293
294template < typename ConnectionT >
295void
297 Node& tgt,
298 std::vector< ConnectorBase* >& thread_local_connectors,
299 const synindex syn_id,
300 ConnectionT& connection,
301 const size_t receptor_type )
302{
303 assert( syn_id != invalid_synindex );
304
305 if ( not thread_local_connectors[ syn_id ] )
306 {
307 // No homogeneous Connector with this syn_id exists, we need to create a new
308 // homogeneous Connector.
309 thread_local_connectors[ syn_id ] = new Connector< ConnectionT >( syn_id );
310 }
311
312 ConnectorBase* connector = thread_local_connectors[ syn_id ];
313 // The following line will throw an exception, if it does not work.
314 connection.check_connection( src, tgt, receptor_type, get_common_properties() );
315
316 assert( connector );
317
318 Connector< ConnectionT >* vc = static_cast< Connector< ConnectionT >* >( connector );
319 vc->push_back( std::move( connection ) );
320}
321
322} // namespace nest
323
324#endif
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
bool known(const std::string &key) const
Check whether there exists a value with specified key in the dictionary.
Definition dictionary.h:677
Exception to be thrown if an invalid delay is used in a connection.
Definition exceptions.h:583
Exception to be thrown if a parameter cannot be set.
Definition exceptions.h:717
DelayChecker & get_delay_checker()
Returns the delay checker for the current thread.
Definition connection_manager.cpp:207
Base class to allow storing Connectors for different synapse types in vectors.
Definition connector_base.h:63
Definition connector_model.h:69
bool has_property(const ConnectionModelProperties &property) const
Definition connector_model.h:132
virtual void calibrate(const TimeConverter &tc)=0
virtual void set_syn_id(synindex syn_id)=0
virtual std::unique_ptr< SecondaryEvent > get_secondary_event()=0
Homogeneous connector, contains synapses of one particular type (syn_id_).
Definition connector_base.h:221
void push_back(const ConnectionT &c)
Definition connector_base.h:270
void assert_valid_delay_ms(double)
Raise exception if delay value in milliseconds is invalid.
Definition delay_checker.cpp:149
void enable_delay_update()
This method enables the min/ max delay update in SetDefaults of connections method.
Definition delay_checker.h:127
void freeze_delay_update()
This method freezes the min/ max delay update in SetDefaults of connections method.
Definition delay_checker.h:121
Definition connector_model.h:152
void add_connection(Node &src, Node &tgt, std::vector< ConnectorBase * > &hetconn, const synindex syn_id, const Dictionary &d, const double delay, const double weight) override
Adds a connection.
Definition connector_model_impl.h:220
void used_default_delay()
Definition connector_model_impl.h:163
size_t get_syn_id() const override
Definition connector_model_impl.h:206
void add_connection_(Node &src, Node &tgt, std::vector< ConnectorBase * > &hetconn, const synindex syn_id, ConnectionT &c, const size_t receptor_type)
Definition connector_model_impl.h:296
void set_syn_id(synindex syn_id) override
Definition connector_model_impl.h:213
void calibrate(const TimeConverter &tc) override
Definition connector_model_impl.h:81
ConnectorModel * clone(std::string, synindex) const override
Definition connector_model_impl.h:65
void check_synapse_params(const Dictionary &syn_spec) const override
Checks to see if illegal parameters are given in syn_spec.
Definition connector_model_impl.h:141
void get_status(Dictionary &) const override
Definition connector_model_impl.h:95
void set_status(const Dictionary &) override
Definition connector_model_impl.h:113
size_t get_synapse_model_id(std::string model_name)
Definition model_manager.cpp:321
Base class for all NEST network objects.
Definition node.h:99
Exception to be thrown if a feature is unavailable.
Definition exceptions.h:108
double get_wfr_comm_interval() const
Get the desired communication interval for the waveform relaxation.
Definition simulation_manager.h:325
Class to convert times from one representation to another.
Definition nest_timeconverter.h:42
static double delay_steps_to_ms(long steps)
Convert between delays given in steps and milliseconds.
Definition nest_time.h:529
ConnectionManager connection_manager
Definition kernel_manager.h:239
ModelManager model_manager
Definition kernel_manager.h:243
SimulationManager simulation_manager
Definition kernel_manager.h:237
const std::string delay("delay")
const std::string receptor_type("receptor_type")
const std::string has_delay("has_delay")
const std::string synapse_modelid("synapse_modelid")
const std::string requires_symmetric("requires_symmetric")
const std::string synapse_model("synapse_model")
const std::string music_channel("music_channel")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
constexpr synindex invalid_synindex
Definition nest_types.h:116
KernelManager & kernel()
Definition kernel_manager.h:311
size_t synindex
For enumerations of synapse types.
Definition nest_types.h:115
bool is_nan(T f)
Definition numerics.h:51