spore_test_connection.h
1 /*
2  * This file is part of SPORE.
3  *
4  * Copyright (C) 2016, the SPORE team (see AUTHORS).
5  *
6  * SPORE is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * SPORE is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with SPORE. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * For more information see: https://github.com/IGITUGraz/spore-nest-module
20  *
21  * File: spore_test_connection.h
22  * Author: Kappel
23  *
24  * Created on November 9, 2016, 4:03 PM
25  */
26 
27 #ifndef SPORE_TEST_CONNECTION
28 #define SPORE_TEST_CONNECTION
29 
30 #include <cmath>
31 #include "nest.h"
32 #include "connection.h"
33 #include "normal_randomdev.h"
34 #include "spikecounter.h"
35 
36 #include "tracing_node.h"
37 #include "spore_names.h"
38 
39 
40 namespace spore
41 {
42 
46 class SporeTestConnectionCommonProperties : public nest::CommonSynapseProperties
47 {
48 public:
49 
54  : nest::CommonSynapseProperties(),
55  weight_update_time_(100.0),
56  bap_trace_id_(0),
57  resolution_unit_(-1)
58  {
59  }
60 
65  {
66  }
67 
71  void get_status(DictionaryDatum& d) const
72  {
73  }
74 
78  void set_status(const DictionaryDatum& d, nest::ConnectorModel& cm)
79  {
80  updateValue<double>(d, names::weight_update_time, weight_update_time_);
81  updateValue<long>(d, names::bap_trace_id, bap_trace_id_);
82  }
83 
89  void calibrate(const nest::TimeConverter& tc)
90  {
91  resolution_unit_ = nest::Time::get_resolution().get_ms();
92  }
93 
97  void check_event(nest::SpikeEvent&)
98  {
99  }
100 
104  long get_vt_gid() const
105  {
106  return -1;
107  }
108 
112  nest::Node* get_node()
113  {
114  return nest::CommonSynapseProperties::get_node();
115  }
116 
117  double weight_update_time_;
118  TracingNode::trace_id bap_trace_id_;
119  double resolution_unit_;
120 };
121 
128 template<typename targetidentifierT>
129 class SporeTestConnection : public nest::Connection<targetidentifierT>
130 {
131 public:
132 
136 
139 
141  typedef nest::Connection<targetidentifierT> ConnectionBase;
142 
143  void check_connection(nest::Node& s, nest::Node& t,
144  nest::rport receptor_type, double t_lastspike, const CommonPropertiesType& cp)
145  {
146  if (!dynamic_cast<TracingNode*> (&t))
147  {
148  throw nest::IllegalConnection("This synapse only works with nodes exposing their firing probability trace (e.g. TracingNode-Subclass)!");
149  }
150 
151  ConnTestDummyNode dummy_target;
152  ConnectionBase::check_connection_(dummy_target, s, t, receptor_type);
153  }
154 
155  void get_status(DictionaryDatum& d) const;
156  void set_status(const DictionaryDatum& d, nest::ConnectorModel& cm);
157 
158  void send(nest::Event& e, nest::thread t, double t_lastspike, const CommonPropertiesType& cp);
159 
160  using ConnectionBase::get_delay_steps;
161  using ConnectionBase::get_delay;
162  using ConnectionBase::get_rport;
163  using ConnectionBase::get_target;
164 
165  void set_weight(double w)
166  {
167  weight_ = w;
168  }
169 
173  bool is_degenerated() const
174  {
175  return false;
176  }
177 
178 private:
179  double weight_;
180  double t_weight_;
181 
182  std::vector<double> recorder_times_;
183  std::vector<double> recorder_values_;
184 
185  void update_synapse_state(double t_to,
186  double t_last_update,
187  TracingNode::const_iterator &bap_trace,
188  const CommonPropertiesType& cp);
189 
190  void update_synapic_weight(double time,
191  nest::thread thread,
192  TracingNode* target,
193  const CommonPropertiesType& cp);
194 
195  class ConnTestDummyNode : public nest::ConnTestDummyNodeBase
196  {
197  public:
198  using nest::ConnTestDummyNodeBase::handles_test_event;
199 
200  nest::port handles_test_event(nest::SpikeEvent&, nest::rport)
201  {
202  return nest::invalid_port_;
203  }
204 
205  nest::port handles_test_event(nest::DSSpikeEvent&, nest::rport)
206  {
207  return nest::invalid_port_;
208  }
209  };
210 };
211 
212 
213 /* ----------------------------------------------------------------
214  * IMPLEMENTATION OF SYNAPSE
215  * ---------------------------------------------------------------- */
216 
217 /* ----------------------------------------------------------------
218  * Object lifecycle
219  * ---------------------------------------------------------------- */
220 
221 template <typename targetidentifierT>
223 : ConnectionBase(),
224 weight_(0.0),
225 t_weight_(0.0)
226 {
227 }
228 
229 template <typename targetidentifierT>
230 SporeTestConnection<targetidentifierT>::SporeTestConnection(const SporeTestConnection& rhs)
231 : ConnectionBase(rhs),
232 weight_(rhs.weight_),
233 t_weight_(rhs.t_weight_)
234 {
235 }
236 
237 template <typename targetidentifierT>
239 {
240 }
241 
242 /* ----------------------------------------------------------------
243  * Parameter and state extractions and manipulation functions
244  * ---------------------------------------------------------------- */
245 
246 template <typename targetidentifierT>
247 void SporeTestConnection<targetidentifierT>::get_status(DictionaryDatum& d) const
248 {
249  ConnectionBase::get_status(d);
250  (*d)[names::recorder_times] = recorder_times_;
251  (*d)[names::recorder_values] = recorder_values_;
252 }
253 
254 template <typename targetidentifierT>
255 void SporeTestConnection<targetidentifierT>::set_status(const DictionaryDatum& d, nest::ConnectorModel& cm)
256 {
257  ConnectionBase::set_status(d, cm);
258 }
259 
260 //
261 // Synapse event handling
262 //
263 
276 template <typename targetidentifierT>
278  nest::thread thread,
279  double t_last_spike,
280  const CommonPropertiesType& cp)
281 {
282  const double t_to = e.get_stamp().get_ms(); // ConnectionUpdateManager::instance()->get_origin().get_ms();
283  double t_from = t_last_spike;
284 
285  assert(cp.resolution_unit_ > 0.0);
286 
287  if (t_to > t_last_spike)
288  {
289  // prepare the pointer to the target neuron. We can safely static_cast
290  // since the connection is checked when established.
291  TracingNode* target = static_cast<TracingNode*> (get_target(thread));
292 
293  TracingNode::const_iterator bap_trace = target->get_trace(nest::delay(t_from / cp.resolution_unit_), cp.bap_trace_id_ + get_rport());
294 
295  for (double next_weight_time = t_weight_ + cp.weight_update_time_;
296  next_weight_time <= t_to;
297  next_weight_time += cp.weight_update_time_)
298  {
299  update_synapse_state(next_weight_time, t_from, bap_trace, cp);
300  update_synapic_weight(next_weight_time, thread, target, cp);
301  t_from = next_weight_time;
302  }
303 
304  if (t_to > t_from)
305  {
306  update_synapse_state(t_to, t_from, bap_trace, cp);
307  }
308  }
309 
310  if (e.get_rport() >= 0)
311  {
312  if (weight_ > 0.0)
313  {
314  e.set_weight(weight_);
315 
316  e.set_delay(get_delay_steps());
317  e.set_receiver(*get_target(thread));
318  e.set_rport(get_rport());
319  e();
320  }
321  }
322 }
323 
336 template <typename targetidentifierT>
338  double t_last_update,
339  TracingNode::const_iterator& bap_trace,
340  const CommonPropertiesType& cp)
341 {
342  t_to -= cp.resolution_unit_ / 2.0; // exclude the last time step.
343 
344  for (double time = t_last_update; time < t_to; time += cp.resolution_unit_)
345  {
346  assert(time >= ConnectionUpdateManager::instance()->get_horizon().get_ms() &&
347  time < ConnectionUpdateManager::instance()->get_origin().get_ms());
348 
349  recorder_times_.push_back(time);
350  recorder_values_.push_back(*bap_trace);
351  ++bap_trace;
352  }
353 }
354 
363 template <typename targetidentifierT>
365  nest::thread thread,
366  TracingNode* target,
367  const CommonPropertiesType& cp)
368 {
369  t_weight_ = time;
370 }
371 
372 }
373 
374 #endif
nest::Node * get_node()
Definition: spore_test_connection.h:112
nest::Connection< targetidentifierT > ConnectionBase
Shortcut for base class.
Definition: spore_test_connection.h:141
void get_status(DictionaryDatum &d) const
Definition: spore_test_connection.h:71
Base class to all nodes that record traces.
Definition: tracing_node.h:52
bool is_degenerated() const
Definition: spore_test_connection.h:173
Definition: poisson_dbl_exp_neuron.cpp:43
~SporeTestConnectionCommonProperties()
Definition: spore_test_connection.h:64
SporeTestConnectionCommonProperties CommonPropertiesType
Type to use for representing common synapse properties.
Definition: spore_test_connection.h:138
Class holding the common properties for all synapses of type SporeTestConnection. ...
Definition: spore_test_connection.h:46
Constant iterator class.
Definition: circular_buffer.h:49
void check_event(nest::SpikeEvent &)
Definition: spore_test_connection.h:97
void calibrate(const nest::TimeConverter &tc)
Definition: spore_test_connection.h:89
Connection for testing the spore module.
Definition: spore_test_connection.h:129
SporeTestConnectionCommonProperties()
Definition: spore_test_connection.h:53
static ConnectionUpdateManager * instance()
Definition: connection_updater.cpp:312
Global namespace holding all classes of the SPORE NEST module.
Definition: circular_buffer.h:31
void set_status(const DictionaryDatum &d, nest::ConnectorModel &cm)
Definition: spore_test_connection.h:78
long get_vt_gid() const
Definition: spore_test_connection.h:104
void send(nest::Event &e, nest::thread t, double t_lastspike, const CommonPropertiesType &cp)
Definition: spore_test_connection.h:277
const_iterator get_trace(nest::delay steps, trace_id id) const
Access the trace of id at time step step.
Definition: tracing_node.h:82