1 /*
2 * spin_detector.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 SPIN_DETECTOR_H
24 #define SPIN_DETECTOR_H
25
26
27 // C++ includes:
28 #include <vector>
29
30 // Includes from nestkernel:
31 #include "device_node.h"
32 #include "event.h"
33 #include "exceptions.h"
34 #include "nest_types.h"
35 #include "recording_device.h"
36 #include "nest_timeconverter.h"
37
38 namespace nest
39 {
40
41 /* BeginUserDocs: device, detector
42
43 Short description
44 +++++++++++++++++
45
46 Device for detecting binary states in neurons
47
48 Description
49 +++++++++++
50
51 The spin_detector is a recording device. It is used to decode and
52 record binary states from spiking activity from a single neuron, or
53 from multiple neurons at once. A single spike signals the 0 state, two
54 spikes at the same time signal the 1 state. If a neuron is in the 0 or
55 1 state and emits the spiking activity corresponding to the same
56 state, the same state is recorded again. Therefore, it is not only
57 the transitions that are recorded. Data is recorded in memory or to
58 file as for all RecordingDevices. By default, node ID, time, and binary
59 state (0 or 1) for each decoded state is recorded. The state can be
60 accessed from ['events']['weight'].
61
62 The spin_detector will record binary state times with full
63 precision from neurons emitting precisely timed spikes.
64
65 Any node from which binary states are to be recorded, must be
66 connected to the spin_detector using the Connect command. Any
67 connection weight and delay will be ignored for that connection.
68
69 Simulations progress in cycles defined by the minimum delay. During
70 each cycle, the spin_detector records (stores in memory or writes to
71 screen/file) the states during the previous cycle. As a consequence,
72 any state information that was decoded during the cycle immediately
73 preceding the end of the simulation time will not be recorded. Setting
74 the /stop parameter to at the latest one min_delay period before the
75 end of the simulation time ensures that all binary states desired to
76 be recorded, are recorded.
77
78 states are not necessarily written to file in chronological order.
79
80 Receives
81 ++++++++
82
83 SpikeEvent
84
85 EndUserDocs */
86
87 /**
88 * Spin detector class.
89 *
90 * This class decodes binary states based on incoming spikes. It receives
91 * spikes via its handle(SpikeEvent&) method, decodes the state, and
92 * stores them via its RecordingDevice.
93 *
94 */
95 class spin_detector : public RecordingDevice
96 {
97
98 public:
99 spin_detector();
100 spin_detector( const spin_detector& );
101
102 bool
has_proxies()103 has_proxies() const
104 {
105 return false;
106 }
107 bool
local_receiver()108 local_receiver() const
109 {
110 return true;
111 }
112
113 Name
get_element_type()114 get_element_type() const
115 {
116 return names::recorder;
117 }
118
119 /**
120 * Import sets of overloaded virtual functions.
121 * @see Technical Issues / Virtual Functions: Overriding, Overloading, and
122 * Hiding
123 */
124 using Node::handle;
125 using Node::handles_test_event;
126 using Node::receives_signal;
127
128 void handle( SpikeEvent& );
129
130 port handles_test_event( SpikeEvent&, rport );
131
132 Type get_type() const;
133 SignalType receives_signal() const;
134
135 void get_status( DictionaryDatum& ) const;
136 void set_status( const DictionaryDatum& );
137
138 void calibrate_time( const TimeConverter& tc );
139
140 private:
141 void init_buffers_();
142 void calibrate();
143
144 /**
145 * Update detector by recording spikes.
146 *
147 * All spikes in the read_toggle() half of the spike buffer are
148 * used to detect binary states.
149 *
150 * @see RecordingDevice
151 */
152 void update( Time const&, const long, const long );
153
154 index last_in_node_id_;
155 SpikeEvent last_event_;
156 Time t_last_in_spike_;
157 };
158
159 inline port
handles_test_event(SpikeEvent &,rport receptor_type)160 spin_detector::handles_test_event( SpikeEvent&, rport receptor_type )
161 {
162 if ( receptor_type != 0 )
163 {
164 throw UnknownReceptorType( receptor_type, get_name() );
165 }
166 return 0;
167 }
168
169 inline SignalType
receives_signal()170 spin_detector::receives_signal() const
171 {
172 return BINARY;
173 }
174
175 inline void
calibrate_time(const TimeConverter & tc)176 nest::spin_detector::calibrate_time( const TimeConverter& tc )
177 {
178 t_last_in_spike_ = tc.from_old_tics( t_last_in_spike_.get_tics() );
179 }
180
181 } // namespace
182
183 #endif /* #ifndef SPIN_DETECTOR_H */
184