NEST main@caf0ae8
 
Loading...
Searching...
No Matches
sinusoidal_gamma_generator.h
Go to the documentation of this file.
1/*
2 * sinusoidal_gamma_generator.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 SINUSOIDAL_GAMMA_GENERATOR_H
24#define SINUSOIDAL_GAMMA_GENERATOR_H
25
26// Generated includes:
27#include "config.h"
28
29#ifdef HAVE_GSL
30
31// C++ includes:
32#include <vector>
33
34// Includes from nestkernel:
35#include "connection.h"
36#include "device_node.h"
37#include "event.h"
38#include "nest_types.h"
39#include "stimulation_device.h"
41
42namespace nest
43{
44
45/* BeginUserDocs: device, generator
46
47Short description
48+++++++++++++++++
49
50Generates sinusoidally modulated gamma spike trains
51
52Description
53+++++++++++
54
55``sinusoidal_gamma_generator`` generates sinusoidally modulated gamma spike
56trains. By default, each target of the generator will receive a different
57spike train.
58
59The instantaneous rate of the process is given by
60
61.. math::
62
63 f(t) = \mathrm{rate} + \mathrm{amplitude} \cdot \sin \left(
64 2 \pi \cdot \mathrm{frequency} \cdot t + \mathrm{phase} \cdot
65 \frac{\pi}{180} \right)
66
67.. note::
68
69 - The gamma generator requires
70 :math:`0 \leq \mathrm{amplitude} \leq \mathrm{rate}`.
71 - The state of the generator is reset on calibration.
72 - The generator does not support precise spike timing.
73 - You can use the multimeter to sample the rate of the generator.
74 - The generator will create different trains if run at different
75 temporal resolutions.
76
77By default, the generator sends a different spike train to each of its
78targets. If ``individual_spike_trains`` is set to ``False`` using either
79:py:func:`.SetDefaults` or :py:func:`.CopyModel` before a generator node
80is created, the generator will send the same spike train to all of its targets.
81
82.. include:: ../models/stimulation_device.rst
83
84rate
85 Mean firing rate in spikes/second. Default: ``0.0``.
86
87amplitude
88 Firing rate modulation amplitude in spikes/second. Default: ``0.0``.
89
90frequency
91 Modulation frequency in Hz. Default: ``0.0``.
92
93phase
94 Modulation phase in degree [0-360]. Default: ``0.0``.
95
96order
97 Gamma order (>= 1). Default: ``1``.
98
99individual_spike_trains
100 See note above. Default: ``True``.
101
102See also :footcite:p:`Barbieri2001`.
103
104Setting parameters from a stimulation backend
105~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106
107The parameters in this stimulation device can be updated with input
108coming from a stimulation backend. The data structure used for the
109update holds one value for each of the parameters mentioned above.
110The indexing is as follows:
111
112 0. frequency
113 1. phase
114 2. order
115 3. rate
116 4. amplitude
117 5. individual_spike_trains
118
119Receives
120++++++++
121
122DataLoggingRequest
123
124Sends
125+++++
126
127SpikeEvent
128
129References
130++++++++++
131
132.. footbibliography::
133
134See also
135++++++++
136
137sinusoidal_poisson_generator, gamma_sup_generator
138
139
140Examples using this model
141+++++++++++++++++++++++++
142
143.. listexamples:: sinusoidal_gamma_generator
144
145EndUserDocs */
146
194void register_sinusoidal_gamma_generator( const std::string& name );
195
196class sinusoidal_gamma_generator : public StimulationDevice
197{
198
199public:
200 sinusoidal_gamma_generator();
201 sinusoidal_gamma_generator( const sinusoidal_gamma_generator& );
202
203 size_t send_test_event( Node&, size_t, synindex, bool ) override;
204
210 using Node::event_hook;
211 using Node::handle;
212 using Node::handles_test_event;
213
214 void handle( DataLoggingRequest& ) override;
215
216 size_t handles_test_event( DataLoggingRequest&, size_t ) override;
217
218 void get_status( Dictionary& ) const override;
219 void set_status( const Dictionary& ) override;
220
222 bool has_proxies() const override;
223
225 bool local_receiver() const override;
226
227 StimulationDevice::Type get_type() const override;
228 void set_data_from_stimulation_backend( std::vector< double >& input_param ) override;
229
230private:
231 void init_state_() override;
232 void init_buffers_() override;
233 void pre_run_hook() override;
234 void event_hook( DSSpikeEvent& ) override;
235
236 void update( Time const&, const long, const long ) override;
237
238 struct Parameters_
239 {
241 double om_;
242
244 double phi_;
245
247 double order_;
248
250 double rate_;
251
253 double amplitude_;
254
256 bool individual_spike_trains_;
257
267 size_t num_trains_;
268
269 Parameters_();
270 Parameters_( const Parameters_& );
271 Parameters_& operator=( const Parameters_& p );
272
273 void get( Dictionary& ) const;
274
280 void set( const Dictionary&, const sinusoidal_gamma_generator&, Node* );
281 };
282
283 struct State_
284 {
285 double rate_;
286
287 State_();
288 };
289
290 // ------------------------------------------------------------
291
292 // The next two classes need to be friends to access the State_ class/member.
293 friend class RecordablesMap< sinusoidal_gamma_generator >;
294 friend class UniversalDataLogger< sinusoidal_gamma_generator >;
295
296 // ----------------------------------------------------------------
297
301 struct Buffers_
302 {
303 Buffers_( sinusoidal_gamma_generator& );
304 Buffers_( const Buffers_&, sinusoidal_gamma_generator& );
305 UniversalDataLogger< sinusoidal_gamma_generator > logger_;
306
315 std::vector< double > t0_ms_;
316
321 std::vector< double > Lambda_t0_;
322
323 Parameters_ P_prev_;
324 };
325
326 // ------------------------------------------------------------
327
328 struct Variables_
329 {
330 double h_;
331 double t_ms_;
333 long t_steps_;
334 RngPtr rng_;
335 };
336
337 double
338 get_rate_() const
339 {
340 return 1000.0 * S_.rate_;
341 }
342
344 double deltaLambda_( const Parameters_&, double, double ) const;
345
347 double hazard_( size_t ) const;
348
349 static RecordablesMap< sinusoidal_gamma_generator > recordablesMap_;
350
351 Parameters_ P_;
352 State_ S_;
353 Variables_ V_;
354 Buffers_ B_;
355};
356
357inline size_t
358sinusoidal_gamma_generator::send_test_event( Node& target, size_t receptor_type, synindex syn_id, bool dummy_target )
359{
361
362 // to ensure correct overloading resolution, we need explicit event types
363 // therefore, we need to duplicate the code here
364 if ( P_.individual_spike_trains_ )
365 {
366 if ( dummy_target )
367 {
368 DSSpikeEvent e;
369 e.set_sender( *this );
370 return target.handles_test_event( e, receptor_type );
371 }
372 else
373 {
374 SpikeEvent e;
375 e.set_sender( *this );
376 const size_t r = target.handles_test_event( e, receptor_type );
377 if ( r != invalid_port and not is_model_prototype() )
378 {
379 ++P_.num_trains_;
380 }
381 return r;
382 }
383 }
384 else
385 {
386 // We do not count targets here, since connections may be created through
387 // proxies. Instead, we set P_.num_trains_ to 1 in Parameters_::set().
388 SpikeEvent e;
389 e.set_sender( *this );
390 return target.handles_test_event( e, receptor_type );
391 }
392}
393
394inline size_t
395sinusoidal_gamma_generator::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type )
396{
397 if ( receptor_type != 0 )
398 {
399 throw UnknownReceptorType( receptor_type, get_name() );
400 }
401 return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
402}
403
404inline void
405sinusoidal_gamma_generator::get_status( Dictionary& d ) const
406{
407 P_.get( d );
409 d[ names::recordables ] = recordablesMap_.get_list();
410}
411
412inline void
413sinusoidal_gamma_generator::set_status( const Dictionary& d )
414{
415 Parameters_ ptmp = P_; // temporary copy in case of errors
416
417 ptmp.set( d, *this, this ); // throws if BadProperty
418 // We now know that ptmp is consistent. We do not write it back
419 // to P_ before we are also sure that the properties to be set
420 // in the parent class are internally consistent.
422
423 // if we get here, temporaries contain consistent set of properties
424 P_ = ptmp;
425}
426
428inline bool
429sinusoidal_gamma_generator::has_proxies() const
430{
431 return not P_.individual_spike_trains_;
432}
433
435inline bool
436sinusoidal_gamma_generator::local_receiver() const
437{
438 return true;
439}
440
442sinusoidal_gamma_generator::get_type() const
443{
445}
446
447} // namespace
448
449#endif // SINUSOIDAL_GAMMA_GENERATOR_H
450
451#endif // HAVE_GSL
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
void enforce_single_syn_type(synindex)
Throws IllegalConnection if synapse id differs from initial synapse id.
Definition stimulation_device.cpp:62
Type
Device type.
Definition stimulation_device.h:187
@ SPIKE_GENERATOR
Definition stimulation_device.h:189
void set_status(const Dictionary &) override
Change properties of the node according to the entries in the dictionary.
Definition stimulation_device.cpp:125
void get_status(Dictionary &d) const override
Export properties of the node by setting entries in the status dictionary.
Definition stimulation_device.cpp:168
const std::string recordables("recordables")
const std::string d("d")
const std::string target("target")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
BaseRandomGenerator * RngPtr
Definition random_generators.h:50
constexpr size_t invalid_port
Value for invalid connection port number.
Definition nest_types.h:141
size_t synindex
For enumerations of synapse types.
Definition nest_types.h:115
const double e
Definition numerics.cpp:32