poisson_dbl_exp_neuron.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: poisson_dbl_exp_neuron.h
22  * Author: Hsieh, Kappel
23  *
24  * This file is based on pp_psc_delta.h which is part of NEST
25  * (Copyright (C) 2004 The NEST Initiative).
26  * See: http://nest-initiative.org/
27  */
28 
29 #ifndef POISSON_DBL_EXP_NEURON_H
30 #define POISSON_DBL_EXP_NEURON_H
31 
32 #include "nest.h"
33 #include "event.h"
34 #include "ring_buffer.h"
35 #include "poisson_randomdev.h"
36 #include "gamma_randomdev.h"
37 #include "universal_data_logger.h"
38 
39 #include "tracing_node.h"
40 
41 
42 namespace spore
43 {
44 
162 {
163 public:
164 
167 
172  using nest::Node::handle;
173  using nest::Node::handles_test_event;
174 
175  nest::port send_test_event(nest::Node&, nest::rport, nest::synindex, bool);
176 
177  void handle(nest::SpikeEvent &);
178  void handle(nest::CurrentEvent &);
179  void handle(nest::DataLoggingRequest &);
180 
181  nest::port handles_test_event(nest::SpikeEvent&, nest::rport);
182  nest::port handles_test_event(nest::CurrentEvent&, nest::rport);
183  nest::port handles_test_event(nest::DataLoggingRequest&, nest::rport);
184 
185  void get_status(DictionaryDatum &) const;
186  void set_status(const DictionaryDatum &);
187 
188 private:
189 
190  void init_state_(const nest::Node& proto);
191  void init_buffers_();
192  void calibrate();
193 
194  void update(nest::Time const &, const long, const long);
195 
196  // The next two classes need to be friends to access the State_ class/member
197  friend class nest::RecordablesMap<PoissonDblExpNeuron>;
198  friend class nest::UniversalDataLogger<PoissonDblExpNeuron>;
199 
200  // ----------------------------------------------------------------
201 
205  struct Parameters_
206  {
208  double tau_rise_exc_;
209 
211  double tau_fall_exc_;
212 
214  double tau_rise_inh_;
215 
217  double tau_fall_inh_;
218 
220  double input_conductance_;
221 
223  double dead_time_;
224 
226  bool dead_time_random_;
227 
229  long dead_time_shape_;
230 
232  bool with_reset_;
233 
235  double c_1_;
236 
238  double c_2_;
239 
241  double c_3_;
242 
244  double I_e_;
245 
247  double t_ref_remaining_;
248 
250  double target_rate_;
251 
253  double target_adaptation_speed_;
254 
255  Parameters_();
256 
257  void get(DictionaryDatum&) const;
258  void set(const DictionaryDatum&);
259  };
260 
264  struct State_
265  {
266  double u_rise_exc_;
267  double u_fall_exc_;
268  double u_rise_inh_;
269  double u_fall_inh_;
270  double u_membrane_;
271  double input_current_;
272  double adaptive_threshold_;
273  int r_;
274 
275  State_();
276 
277  void get(DictionaryDatum&, const Parameters_&) const;
278  void set(const DictionaryDatum&, const Parameters_&);
279  };
280 
284  struct Buffers_
285  {
286  Buffers_(PoissonDblExpNeuron &);
287  Buffers_(const Buffers_ &, PoissonDblExpNeuron &);
288 
290  nest::RingBuffer exc_spikes_;
291  nest::RingBuffer inh_spikes_;
292  nest::RingBuffer currents_;
293 
295  nest::UniversalDataLogger<PoissonDblExpNeuron> logger_;
296  };
297 
301  struct Variables_
302  {
303  double decay_rise_exc_;
304  double decay_fall_exc_;
305  double decay_rise_inh_;
306  double decay_fall_inh_;
307  double norm_exc_;
308  double norm_inh_;
309  double h_;
310  double dt_rate_;
311 
312  librandom::RngPtr rng_; // random number generator of my own thread
313  librandom::PoissonRandomDev poisson_dev_; // random deviate generator
314  librandom::GammaRandomDev gamma_dev_; // random deviate generator
315 
316  int DeadTimeCounts_;
317 
318  };
319 
320  // Access functions for UniversalDataLogger
321 
323 
324  double get_V_m_() const
325  {
326  return S_.u_membrane_;
327  }
328 
330 
331  double get_E_sfa_() const
332  {
333  return S_.adaptive_threshold_;
334  }
335 
342  Parameters_ P_;
343  State_ S_;
344  Variables_ V_;
345  Buffers_ B_;
348  static nest::RecordablesMap<PoissonDblExpNeuron> recordablesMap_;
350 };
351 
355 inline
356 nest::port PoissonDblExpNeuron::send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool)
357 {
358  nest::SpikeEvent e;
359  e.set_sender(*this);
360 
361  return target.handles_test_event(e, receptor_type);
362 }
363 
367 inline
368 nest::port PoissonDblExpNeuron::handles_test_event(nest::SpikeEvent&, nest::rport receptor_type)
369 {
370  if ((receptor_type != 0) && (receptor_type != 1))
371  {
372  throw nest::UnknownReceptorType(receptor_type, get_name());
373  }
374 
375  return receptor_type;
376 }
377 
381 inline
382 nest::port PoissonDblExpNeuron::handles_test_event(nest::CurrentEvent&, nest::rport receptor_type)
383 {
384  if (receptor_type != 0)
385  {
386  throw nest::UnknownReceptorType(receptor_type, get_name());
387  }
388 
389  return 0;
390 }
391 
395 inline
396 nest::port PoissonDblExpNeuron::handles_test_event(nest::DataLoggingRequest &dlr,
397  nest::rport receptor_type)
398 {
399  if (receptor_type != 0)
400  {
401  throw nest::UnknownReceptorType(receptor_type, get_name());
402  }
403 
404  return B_.logger_.connect_logging_device(dlr, recordablesMap_);
405 }
406 
410 inline
411 void PoissonDblExpNeuron::get_status(DictionaryDatum &d) const
412 {
413  P_.get(d);
414  S_.get(d, P_);
415 
416  (*d)[nest::names::recordables] = recordablesMap_.get_list();
417 }
418 
422 inline
423 void PoissonDblExpNeuron::set_status(const DictionaryDatum &d)
424 {
425  Parameters_ ptmp = P_; // temporary copy in case of errors
426  ptmp.set(d); // throws if BadProperty
427  State_ stmp = S_; // temporary copy in case of errors
428  stmp.set(d, ptmp); // throws if BadProperty
429 
430  // We now know that (ptmp, stmp) are consistent. We do not
431  // write them back to (P_, S_) before we are also sure that
432  // the properties to be set in the parent class are internally
433  // consistent.
434  //Archiving_Node::set_status(d);
435 
436  // if we get here, temporaries contain consistent set of properties
437  P_ = ptmp;
438  S_ = stmp;
439 }
440 
441 }
442 
443 #endif
nest::port send_test_event(nest::Node &, nest::rport, nest::synindex, bool)
Definition: poisson_dbl_exp_neuron.h:356
Base class to all nodes that record traces.
Definition: tracing_node.h:52
void handle(nest::SpikeEvent &)
Definition: poisson_dbl_exp_neuron.cpp:399
void set_status(const DictionaryDatum &)
Definition: poisson_dbl_exp_neuron.h:423
nest::port handles_test_event(nest::SpikeEvent &, nest::rport)
Definition: poisson_dbl_exp_neuron.h:368
void get_status(DictionaryDatum &) const
Definition: poisson_dbl_exp_neuron.h:411
Global namespace holding all classes of the SPORE NEST module.
Definition: circular_buffer.h:31
PoissonDblExpNeuron()
Definition: poisson_dbl_exp_neuron.cpp:188
Point process neuron with double-exponential shaped PSCs.
Definition: poisson_dbl_exp_neuron.h:161