1 /*
2  *  connector_model.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_H
24 #define CONNECTOR_MODEL_H
25 
26 // C++ includes:
27 #include <cmath>
28 #include <string>
29 
30 // Includes from libnestutil:
31 #include "numerics.h"
32 
33 // Includes from nestkernel:
34 #include "event.h"
35 #include "nest_time.h"
36 #include "nest_types.h"
37 
38 // Includes from sli:
39 #include "dictutils.h"
40 
41 namespace nest
42 {
43 class ConnectorBase;
44 class CommonSynapseProperties;
45 class TimeConverter;
46 class Node;
47 
48 class ConnectorModel
49 {
50 
51 public:
52   ConnectorModel( const std::string,
53     const bool is_primary,
54     const bool has_delay,
55     const bool requires_symmetric,
56     const bool supports_wfr,
57     const bool requires_clopath_archiving,
58     const bool requires_urbanczik_archiving );
59   ConnectorModel( const ConnectorModel&, const std::string );
~ConnectorModel()60   virtual ~ConnectorModel()
61   {
62   }
63 
64   /**
65    * Adds a connection.
66    *
67    * @param src Source node
68    * @param tgt Target node
69    * @param hetconn Connector vector
70    * @param syn_id Synapse id
71    * @param d Parameter dictionary to configure the synapse
72    * @param delay Delay of the connection
73    * @param weight Weight of the connection
74    *
75    * Delay and weight have the default value NAN, a special value, which
76    * describes double values that are not a number. If delay or weight is
77    * omitted, NAN indicates this and weight/delay are set only if they are
78    * valid.
79    */
80   virtual void add_connection( Node& src,
81     Node& tgt,
82     std::vector< ConnectorBase* >& hetconn,
83     const synindex syn_id,
84     const DictionaryDatum& d,
85     const double delay = NAN,
86     const double weight = NAN ) = 0;
87 
88   virtual ConnectorModel* clone( std::string ) const = 0;
89 
90   virtual void calibrate( const TimeConverter& tc ) = 0;
91 
92   virtual void get_status( DictionaryDatum& ) const = 0;
93   virtual void set_status( const DictionaryDatum& ) = 0;
94 
95   virtual const CommonSynapseProperties& get_common_properties() const = 0;
96 
97   /**
98    * Checks to see if illegal parameters are given in syn_spec.
99    */
100   virtual void check_synapse_params( const DictionaryDatum& ) const = 0;
101 
102   virtual SecondaryEvent* get_event() const = 0;
103 
104   virtual void set_syn_id( synindex syn_id ) = 0;
105 
106   virtual std::vector< SecondaryEvent* > create_event( size_t n ) const = 0;
107 
108   std::string
get_name()109   get_name() const
110   {
111     return name_;
112   }
113 
114   bool
is_primary()115   is_primary() const
116   {
117     return is_primary_;
118   }
119 
120   bool
has_delay()121   has_delay() const
122   {
123     return has_delay_;
124   }
125 
126   bool
requires_symmetric()127   requires_symmetric() const
128   {
129     return requires_symmetric_;
130   }
131 
132   bool
requires_clopath_archiving()133   requires_clopath_archiving() const
134   {
135     return requires_clopath_archiving_;
136   }
137 
138   bool
requires_urbanczik_archiving()139   requires_urbanczik_archiving() const
140   {
141     return requires_urbanczik_archiving_;
142   }
143 
144   bool
supports_wfr()145   supports_wfr() const
146   {
147     return supports_wfr_;
148   }
149 
150 protected:
151   //! name of the ConnectorModel
152   std::string name_;
153   //! indicates whether the default delay must be checked
154   bool default_delay_needs_check_;
155   //! indicates whether this ConnectorModel belongs to a primary connection
156   bool is_primary_;
157   //! indicates whether ConnectorModel has a delay
158   bool has_delay_;
159   //! indicates that ConnectorModel requires symmetric connections
160   bool requires_symmetric_;
161   //! indicates whether connection can be used during wfr update
162   bool supports_wfr_;
163   //! indicates that ConnectorModel requires Clopath archiving
164   bool requires_clopath_archiving_;
165   //! indicates that ConnectorModel requires Urbanczik archiving
166   bool requires_urbanczik_archiving_;
167 
168 }; // ConnectorModel
169 
170 
171 template < typename ConnectionT >
172 class GenericConnectorModel : public ConnectorModel
173 {
174 private:
175   typename ConnectionT::CommonPropertiesType cp_;
176   //! used to create secondary events that belong to secondary connections
177   typename ConnectionT::EventType* pev_;
178 
179   ConnectionT default_connection_;
180   rport receptor_type_;
181 
182 public:
GenericConnectorModel(const std::string name,bool is_primary,bool has_delay,bool requires_symmetric,bool supports_wfr,bool requires_clopath_archiving,bool requires_urbanczik_archiving)183   GenericConnectorModel( const std::string name,
184     bool is_primary,
185     bool has_delay,
186     bool requires_symmetric,
187     bool supports_wfr,
188     bool requires_clopath_archiving,
189     bool requires_urbanczik_archiving )
190     : ConnectorModel( name,
191         is_primary,
192         has_delay,
193         requires_symmetric,
194         supports_wfr,
195         requires_clopath_archiving,
196         requires_urbanczik_archiving )
197     , receptor_type_( 0 )
198   {
199   }
200 
GenericConnectorModel(const GenericConnectorModel & cm,const std::string name)201   GenericConnectorModel( const GenericConnectorModel& cm, const std::string name )
202     : ConnectorModel( cm, name )
203     , cp_( cm.cp_ )
204     , pev_( cm.pev_ )
205     , default_connection_( cm.default_connection_ )
206     , receptor_type_( cm.receptor_type_ )
207   {
208   }
209 
210   void add_connection( Node& src,
211     Node& tgt,
212     std::vector< ConnectorBase* >& hetconn,
213     const synindex syn_id,
214     const DictionaryDatum& d,
215     const double delay,
216     const double weight );
217 
218   ConnectorModel* clone( std::string ) const;
219 
220   void calibrate( const TimeConverter& tc );
221 
222   void get_status( DictionaryDatum& ) const;
223   void set_status( const DictionaryDatum& );
224 
225   void
check_synapse_params(const DictionaryDatum & syn_spec)226   check_synapse_params( const DictionaryDatum& syn_spec ) const
227   {
228     default_connection_.check_synapse_params( syn_spec );
229   }
230 
231   typename ConnectionT::CommonPropertiesType const&
get_common_properties()232   get_common_properties() const
233   {
234     return cp_;
235   }
236 
237   void set_syn_id( synindex syn_id );
238 
239   virtual typename ConnectionT::EventType*
get_event()240   get_event() const
241   {
242     assert( false );
243     return 0;
244   }
245 
246   ConnectionT const&
get_default_connection()247   get_default_connection() const
248   {
249     return default_connection_;
250   }
251 
create_event(size_t)252   virtual std::vector< SecondaryEvent* > create_event( size_t ) const
253   {
254     // Should not be called for a ConnectorModel belonging to a primary
255     // connection. Only required for secondary connection types.
256     assert( false );
257     std::vector< SecondaryEvent* > prototype_events;
258     return prototype_events;
259   }
260 
261 private:
262   void used_default_delay();
263 
264   void add_connection_( Node& src,
265     Node& tgt,
266     std::vector< ConnectorBase* >& hetconn,
267     const synindex syn_id,
268     ConnectionT& c,
269     const rport receptor_type );
270 
271 }; // GenericConnectorModel
272 
273 template < typename ConnectionT >
274 class GenericSecondaryConnectorModel : public GenericConnectorModel< ConnectionT >
275 {
276 private:
277   //! used to create secondary events that belong to secondary connections
278   typename ConnectionT::EventType* pev_;
279 
280 public:
GenericSecondaryConnectorModel(const std::string name,const bool has_delay,const bool requires_symmetric,const bool supports_wfr)281   GenericSecondaryConnectorModel( const std::string name,
282     const bool has_delay,
283     const bool requires_symmetric,
284     const bool supports_wfr )
285     : GenericConnectorModel< ConnectionT >( name,
286         /*is _primary=*/false,
287         has_delay,
288         requires_symmetric,
289         supports_wfr,
290         /*requires_clopath_archiving=*/false,
291         /*requires_urbanczik_archiving=*/false )
292     , pev_( 0 )
293   {
294     pev_ = new typename ConnectionT::EventType();
295   }
296 
GenericSecondaryConnectorModel(const GenericSecondaryConnectorModel & cm,const std::string name)297   GenericSecondaryConnectorModel( const GenericSecondaryConnectorModel& cm, const std::string name )
298     : GenericConnectorModel< ConnectionT >( cm, name )
299   {
300     pev_ = new typename ConnectionT::EventType( *cm.pev_ );
301   }
302 
303 
304   ConnectorModel*
clone(std::string name)305   clone( std::string name ) const
306   {
307     return new GenericSecondaryConnectorModel( *this, name ); // calls copy construtor
308   }
309 
310   std::vector< SecondaryEvent* >
create_event(size_t n)311   create_event( size_t n ) const
312   {
313     std::vector< SecondaryEvent* > prototype_events( n, NULL );
314     for ( size_t i = 0; i < n; i++ )
315     {
316       prototype_events[ i ] = new typename ConnectionT::EventType();
317     }
318 
319     return prototype_events;
320   }
321 
322 
~GenericSecondaryConnectorModel()323   ~GenericSecondaryConnectorModel()
324   {
325     if ( pev_ != 0 )
326     {
327       delete pev_;
328     }
329   }
330 
331   typename ConnectionT::EventType*
get_event()332   get_event() const
333   {
334     return pev_;
335   }
336 };
337 
338 } // namespace nest
339 
340 #endif /* #ifndef CONNECTOR_MODEL_H */
341