1 /*
2  *  recording_backend_screen.cpp
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 // C++ includes:
24 #include <iostream>
25 
26 // Includes from nestkernel:
27 #include "recording_device.h"
28 
29 #include "recording_backend_screen.h"
30 
31 void
initialize()32 nest::RecordingBackendScreen::initialize()
33 {
34   device_data_map tmp( kernel().vp_manager.get_num_threads() );
35   device_data_.swap( tmp );
36 }
37 
38 void
finalize()39 nest::RecordingBackendScreen::finalize()
40 {
41 }
42 
43 void
enroll(const RecordingDevice & device,const DictionaryDatum & params)44 nest::RecordingBackendScreen::enroll( const RecordingDevice& device, const DictionaryDatum& params )
45 {
46   const index node_id = device.get_node_id();
47   const thread t = device.get_thread();
48 
49   device_data_map::value_type::iterator device_data = device_data_[ t ].find( node_id );
50   if ( device_data == device_data_[ t ].end() )
51   {
52     auto p = device_data_[ t ].insert( std::make_pair( node_id, DeviceData() ) );
53     device_data = p.first;
54   }
55 
56   device_data->second.set_status( params );
57 }
58 
59 void
disenroll(const RecordingDevice & device)60 nest::RecordingBackendScreen::disenroll( const RecordingDevice& device )
61 {
62   const index node_id = device.get_node_id();
63   const thread t = device.get_thread();
64 
65   device_data_map::value_type::iterator device_data = device_data_[ t ].find( node_id );
66   if ( device_data != device_data_[ t ].end() )
67   {
68     device_data_[ t ].erase( device_data );
69   }
70 }
71 
72 void
set_value_names(const RecordingDevice &,const std::vector<Name> &,const std::vector<Name> &)73 nest::RecordingBackendScreen::set_value_names( const RecordingDevice&,
74   const std::vector< Name >&,
75   const std::vector< Name >& )
76 {
77   // nothing to do
78 }
79 
80 void
pre_run_hook()81 nest::RecordingBackendScreen::pre_run_hook()
82 {
83   // nothing to do
84 }
85 
86 void
cleanup()87 nest::RecordingBackendScreen::cleanup()
88 {
89   // nothing to do
90 }
91 
92 void
write(const RecordingDevice & device,const Event & event,const std::vector<double> & double_values,const std::vector<long> & long_values)93 nest::RecordingBackendScreen::write( const RecordingDevice& device,
94   const Event& event,
95   const std::vector< double >& double_values,
96   const std::vector< long >& long_values )
97 {
98   const thread t = device.get_thread();
99   const index node_id = device.get_node_id();
100 
101   if ( device_data_[ t ].find( node_id ) == device_data_[ t ].end() )
102   {
103     return;
104   }
105 
106   device_data_[ t ][ node_id ].write( event, double_values, long_values );
107 }
108 
109 void
check_device_status(const DictionaryDatum & params) const110 nest::RecordingBackendScreen::check_device_status( const DictionaryDatum& params ) const
111 {
112   DeviceData dd;
113   dd.set_status( params ); // throws if params contains invalid entries
114 }
115 
116 void
get_device_defaults(DictionaryDatum & params) const117 nest::RecordingBackendScreen::get_device_defaults( DictionaryDatum& params ) const
118 {
119   DeviceData dd;
120   dd.get_status( params );
121 }
122 
123 void
get_device_status(const nest::RecordingDevice & device,DictionaryDatum & d) const124 nest::RecordingBackendScreen::get_device_status( const nest::RecordingDevice& device, DictionaryDatum& d ) const
125 {
126   const thread t = device.get_thread();
127   const index node_id = device.get_node_id();
128 
129   device_data_map::value_type::const_iterator device_data = device_data_[ t ].find( node_id );
130   if ( device_data != device_data_[ t ].end() )
131   {
132     device_data->second.get_status( d );
133   }
134 }
135 
136 
137 void
prepare()138 nest::RecordingBackendScreen::prepare()
139 {
140   // nothing to do
141 }
142 
143 void
post_run_hook()144 nest::RecordingBackendScreen::post_run_hook()
145 {
146   // nothing to do
147 }
148 
149 void
post_step_hook()150 nest::RecordingBackendScreen::post_step_hook()
151 {
152   // nothing to do
153 }
154 
155 void
set_status(const DictionaryDatum &)156 nest::RecordingBackendScreen::set_status( const DictionaryDatum& )
157 {
158   // nothing to do
159 }
160 
161 void
get_status(DictionaryDatum &) const162 nest::RecordingBackendScreen::get_status( DictionaryDatum& ) const
163 {
164   // nothing to do
165 }
166 
167 /* ******************* Device meta data class DeviceInfo ******************* */
168 
DeviceData()169 nest::RecordingBackendScreen::DeviceData::DeviceData()
170   : precision_( 3 )
171   , time_in_steps_( false )
172 {
173 }
174 
175 void
get_status(DictionaryDatum & d) const176 nest::RecordingBackendScreen::DeviceData::get_status( DictionaryDatum& d ) const
177 {
178   ( *d )[ names::precision ] = precision_;
179   ( *d )[ names::time_in_steps ] = time_in_steps_;
180 }
181 
182 void
set_status(const DictionaryDatum & d)183 nest::RecordingBackendScreen::DeviceData::set_status( const DictionaryDatum& d )
184 {
185   updateValue< long >( d, names::precision, precision_ );
186   updateValue< bool >( d, names::time_in_steps, time_in_steps_ );
187 }
188 
189 void
write(const Event & event,const std::vector<double> & double_values,const std::vector<long> & long_values)190 nest::RecordingBackendScreen::DeviceData::write( const Event& event,
191   const std::vector< double >& double_values,
192   const std::vector< long >& long_values )
193 {
194 #pragma omp critical
195   {
196     prepare_cout_();
197 
198     std::cout << event.get_sender_node_id() << "\t";
199 
200     if ( time_in_steps_ )
201     {
202       std::cout << event.get_stamp().get_steps() << "\t" << event.get_offset();
203     }
204     else
205     {
206       std::cout << event.get_stamp().get_ms() - event.get_offset();
207     }
208 
209     for ( auto& val : double_values )
210     {
211       std::cout << "\t" << val;
212     }
213     for ( auto& val : long_values )
214     {
215       std::cout << "\t" << val;
216     }
217     std::cout << std::endl;
218 
219     restore_cout_();
220   }
221 }
222 
223 void
prepare_cout_()224 nest::RecordingBackendScreen::DeviceData::prepare_cout_()
225 {
226   old_fmtflags_ = std::cout.flags( std::ios::fixed );
227   old_precision_ = std::cout.precision( precision_ );
228 }
229 
230 void
restore_cout_()231 nest::RecordingBackendScreen::DeviceData::restore_cout_()
232 {
233   std::cout.flags( old_fmtflags_ );
234   std::cout.precision( old_precision_ );
235 }
236