MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Table.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2010 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #include "global.h"
12 #include <fstream>
13 
14 #include "TableBase.h"
15 #include "Table.h"
16 #include "Clock.h"
17 #include "StreamerBase.h"
18 
19 // Write to numpy arrays.
20 #include "../utility/cnpy.hpp"
21 
22 
24 {
26  "requestOut",
27  "Sends request for a field to target object"
28  );
29  return &requestOut;
30 }
31 
33 {
34  static DestFinfo input(
35  "input",
36  "Fills data into table. Also handles data sent back following request",
38  );
39  return &input;
40 }
41 
43 {
45  // Field Definitions
47  static ValueFinfo< Table, double > threshold(
48  "threshold"
49  , "threshold used when Table acts as a buffer for spikes"
52  );
53 
54  static ValueFinfo< Table, bool > useStreamer(
55  "useStreamer"
56  , "When set to true, write to a file instead writing in memory."
57  " If `outfile` is not set, streamer writes to default path."
60  );
61 
62  static ValueFinfo< Table, bool > useSpikeMode(
63  "useSpikeMode"
64  , "When set to true, look for spikes in a time-series."
65  " Normally used for monitoring Vm for action potentials."
66  " Could be used for any thresholded event. Default is False."
69  );
70 
71  static ValueFinfo< Table, string > outfile(
72  "outfile"
73  , "Set the name of file to which data is written to. If set, "
74  " streaming support is automatically enabled."
77  );
78 
79  static ValueFinfo< Table, string > format(
80  "format"
81  , "Data format for table: default csv"
84  );
85 
86  // relevant for Streamer class. When data is written to a datafile, this is
87  // used to create column name.
88  static ValueFinfo< Table, string > columnName(
89  "columnName"
90  , "Name of the table written in header of data file."
93  );
94 
96  // MsgDest Definitions
98 
99  static DestFinfo spike(
100  "spike",
101  "Fills spike timings into the Table. Signal has to exceed thresh",
103  );
104 
105  static DestFinfo process(
106  "process",
107  "Handles process call, updates internal time stamp.",
109  );
110 
111  static DestFinfo reinit(
112  "reinit",
113  "Handles reinit call.",
115  );
116 
118  // SharedMsg Definitions
120  static Finfo* procShared[] =
121  {
122  &process, &reinit
123  };
124 
125  static SharedFinfo proc(
126  "proc"
127  , "Shared message for process and reinit"
128  , procShared, sizeof( procShared ) / sizeof( const Finfo* )
129  );
130 
132  // Field Element for the vector data
133  // Use a limit of 2^20 entries for the tables, about 1 million.
135 
136  static Finfo* tableFinfos[] =
137  {
138  &threshold, // Value
139  &format, // Value
140  &columnName, // Value
141  &outfile, // Value
142  &useStreamer, // Value
143  &useSpikeMode, // Value
144  handleInput(), // DestFinfo
145  &spike, // DestFinfo
146  requestOut(), // SrcFinfo
147  &proc, // SharedFinfo
148  };
149 
150  static string doc[] =
151  {
152  "Name", "Table",
153  "Author", "Upi Bhalla",
154  "Description",
155  "Table for accumulating data values, or spike timings. "
156  "Can either receive incoming doubles, or can explicitly "
157  "request values from fields provided they are doubles. "
158  "The latter mode of use is preferable if you wish to have "
159  "independent control of how often you sample from the output "
160  "variable. \n"
161  "Typically used for storing simulation output into memory, or to file"
162  " when stream is set to True \n"
163  "There are two functionally identical variants of the Table "
164  "class: Table and Table2. Their only difference is that the "
165  "default scheduling of the Table (Clock Tick 8, dt = 0.1 ms ) "
166  "makes it suitable for "
167  "tracking electrical compartmental models of neurons and "
168  "networks. \n"
169  "Table2 (Clock Tick 18, dt = 1.0 s) is good for tracking "
170  "biochemical signaling pathway outputs. \n"
171  "These are just the default values and Tables can be assigned"
172  " to any Clock Tick and timestep in the usual manner.",
173  };
174 
175  static Dinfo< Table > dinfo;
176 
177  static Cinfo tableCinfo (
178  "Table",
180  tableFinfos,
181  sizeof( tableFinfos ) / sizeof ( Finfo* ),
182  &dinfo,
183  doc,
184  sizeof( doc ) / sizeof( string )
185  );
186 
187  static string doc2[] =
188  {
189  doc[0], "Table2", doc[2], doc[3], doc[4], doc[5]
190  };
191 
192  doc2[1] = "Table2";
193 
194  static Cinfo table2Cinfo (
195  "Table2",
197  tableFinfos,
198  sizeof( tableFinfos ) / sizeof ( Finfo* ),
199  &dinfo,
200  doc2,
201  sizeof( doc2 ) / sizeof( string )
202  );
203 
204  return &tableCinfo;
205 }
206 
208 // Basic class Definitions
210 
212 
214  threshold_( 0.0 ) ,
215  lastTime_( 0.0 ) ,
216  input_( 0.0 ),
217  fired_(false),
218  useSpikeMode_(false),
219  dt_( 0.0 )
220 {
221  // Initialize the directory to which each table should stream.
222  rootdir_ = "_tables";
223  useStreamer_ = false;
224  format_ = "csv";
225  outfileIsSet_ = false;
226 }
227 
229 {
230  // Make sure to write to rest of the entries to file before closing down.
231  if( useStreamer_ )
232  {
235  clearVec();
236  data_.clear();
237  }
238 }
239 
241 {
242  return *this;
243 }
244 
245 
247 // MsgDest Definitions
249 
250 void Table::process( const Eref& e, ProcPtr p )
251 {
252  lastTime_ = p->currTime;
253 
254  // Copy incoming data to ret and insert into vector.
255  vector< double > ret;
256  requestOut()->send( e, &ret );
257  if (useSpikeMode_) {
258  for ( vector< double >::const_iterator
259  i = ret.begin(); i != ret.end(); ++i )
260  spike( *i );
261  } else {
262  vec().insert( vec().end(), ret.begin(), ret.end() );
263  }
264 
265  /* If we are streaming to a file, let's write to a file. And clean the
266  * vector.
267  * Write at every 5 seconds or whenever size of vector is more than 10k.
268  */
269  if( useStreamer_ )
270  {
271  if( fmod(lastTime_, 5.0) == 0.0 or getVecSize() >= 10000 )
272  {
275  data_.clear();
276  clearVec();
277  }
278  }
279 }
280 
287 void Table::reinit( const Eref& e, ProcPtr p )
288 {
289  tablePath_ = e.id().path();
290  unsigned int numTick = e.element()->getTick();
291  Clock* clk = reinterpret_cast<Clock*>(Id(1).eref().data());
292  dt_ = clk->getTickDt( numTick );
293  fired_ = false;
294 
296  if( useStreamer_ )
297  {
298  // The first column is variable time.
299  columns_.push_back( "time" );
300  // And the second column name is the name of the table.
302 
303  // If user has not set the filepath, then use the table path prefixed
304  // with rootdit as path.
305  if( ! outfileIsSet_ )
308  );
309  }
310 
311  input_ = 0.0;
312  vec().resize( 0 );
313  lastTime_ = 0;
314  vector< double > ret;
315  requestOut()->send( e, &ret );
316  if (useSpikeMode_) {
317  for ( vector< double >::const_iterator
318  i = ret.begin(); i != ret.end(); ++i )
319  spike( *i );
320  } else {
321  vec().insert( vec().end(), ret.begin(), ret.end() );
322  }
323 
324  if( useStreamer_ )
325  {
328  clearVec();
329  data_.clear();
330  clearVec();
331  }
332 }
333 
335 // Used to handle direct messages into the table, or
336 // returned plot data from queried objects.
338 void Table::input( double v )
339 {
340  vec().push_back( v );
341 }
342 
343 void Table::spike( double v )
344 {
345  if ( fired_ ) { // Wait for it to go below threshold
346  if ( v < threshold_ )
347  fired_ = false;
348  } else {
349  if ( v > threshold_ ) { // wait for it to go above threshold.
350  fired_ = true;
351  vec().push_back( lastTime_ );
352  }
353  }
354 }
355 
357 // Field Definitions
359 
360 void Table::setThreshold( double v )
361 {
362  threshold_ = v;
363 }
364 
365 double Table::getThreshold() const
366 {
367  return threshold_;
368 }
369 
370 // Set the format of table to which its data should be written.
371 void Table::setFormat( string format )
372 {
373  if( format == "csv" or format == "npy" )
374  format_ = format;
375  else
377  , "Unsupported format " << format
378  << " only npy and csv are supported"
379  );
380 }
381 
382 // Get the format of table to which it has to be written.
383 string Table::getFormat( void ) const
384 {
385  return format_;
386 }
387 
388 /* User defined column name for streamer */
389 string Table::getColumnName( void ) const
390 {
391  return tableColumnName_;
392 }
393 
394 void Table::setColumnName( const string colname )
395 {
396  tableColumnName_ = colname ;
397 }
398 
399 /* Enable/disable streamer support. */
400 void Table::setUseStreamer( bool useStreamer )
401 {
402  useStreamer_ = useStreamer;
403 }
404 
405 bool Table::getUseStreamer( void ) const
406 {
407  return useStreamer_;
408 }
409 
410 /* Enable/disable spike mode. */
411 void Table::setUseSpikeMode( bool useSpikeMode )
412 {
413  useSpikeMode_ = useSpikeMode;
414 }
415 
416 bool Table::getUseSpikeMode( void ) const
417 {
418  return useSpikeMode_;
419 }
420 
421 
422 /* set/get outfile_ */
423 void Table::setOutfile( string outpath )
424 {
425  outfile_ = moose::createMOOSEPath( outpath );
428 
429  outfileIsSet_ = true;
430  setUseStreamer( true );
431 
432  // If possible get the format of file as well.
434  if( format_.size() == 0 )
435  format_ = "csv";
436 }
437 
438 string Table::getOutfile( void ) const
439 {
440  return outfile_;
441 }
442 
443 // Get the dt_ of this table
444 double Table::getDt( void ) const
445 {
446  return dt_;
447 }
448 
453 void Table::zipWithTime( const vector<double>& v
454  , vector<double>& tvec
455  , const double& currTime
456  )
457 {
458  size_t N = v.size();
459  for (size_t i = 0; i < N; i++)
460  {
461  tvec.push_back( currTime - (N - i - 1 ) * dt_ );
462  tvec.push_back( v[i] );
463  }
464 }
Id id() const
Definition: Eref.cpp:62
char * data() const
Definition: Eref.cpp:41
bool getUseStreamer(void) const
Definition: Table.cpp:405
Table()
Definition: Table.cpp:213
double input_
Definition: Table.h:76
vector< double > & vec()
Definition: TableBase.cpp:492
Definition: Clock.h:25
void setUseStreamer(bool status)
Definition: Table.cpp:400
double currTime
Definition: ProcInfo.h:19
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
Definition: Dinfo.h:60
double lastTime_
Definition: Table.h:75
bool createParentDirs(const string &path)
Create directories recursively needed to open the given file p.
Definition: global.cpp:122
void clearVec()
Definition: TableBase.cpp:414
void reinit(const Eref &e, ProcPtr p)
Reinitialize.
Definition: Table.cpp:287
string format_
format of data. Default to csv.
Definition: Table.h:119
double getTickDt(unsigned int i) const
Definition: Clock.cpp:621
Eref eref() const
Definition: Id.cpp:125
Element * element() const
Definition: Eref.h:42
bool outfileIsSet_
Wheather or not outfile path is set by user.
Definition: Table.h:114
string getExtension(const string &path, bool without_dot)
Get the extension of a given filepath.
Definition: global.cpp:170
static const Cinfo * initCinfo()
Definition: Table.cpp:42
double getDt(void) const
Definition: Table.cpp:444
string moosePathToUserPath(string path)
When user gives a path /a/b/c, moose creates a path /a[0]/b[0]/c[0]. This is helpful in cases where o...
Definition: global.cpp:189
void setOutfile(string outfilepath)
Definition: Table.cpp:423
string getFormat() const
Definition: Table.cpp:383
int getTick() const
Definition: Element.cpp:186
string outfile_
Definition: Table.h:109
string tableColumnName_
Column name of this table. Use it when writing data to a datafile.
Definition: Table.h:93
bool fired_
Definition: Table.h:77
unsigned int getVecSize() const
Definition: TableBase.cpp:477
void zipWithTime(const vector< double > &yvec, vector< double > &tvec, const double &lasttime)
Take the vector from table and timestamp it. It must only be called when packing the data for writing...
Definition: Table.cpp:453
static const Cinfo * initCinfo()
Definition: TableBase.cpp:15
double dt_
dt of its clock. Needed for creating time co-ordinates,
Definition: Table.h:129
~Table()
Definition: Table.cpp:228
void process(const Eref &e, ProcPtr p)
Definition: Table.cpp:250
static DestFinfo * handleInput()
Definition: Table.cpp:32
void setColumnName(const string colname)
Definition: Table.cpp:394
void setThreshold(double v)
Definition: Table.cpp:360
Definition: OpFunc.h:27
Definition: Eref.h:26
string rootdir_
Table directory into which dump the stream data.
Definition: Table.h:105
static SrcFinfo1< vector< double > * > * requestOut()
Definition: Table.cpp:23
string getColumnName() const
Definition: Table.cpp:389
static const Cinfo * tableCinfo
Definition: Table.cpp:211
string toFilename(const string &path)
Replace all directory sepearator with _. This creates a filepath which can be created in current dire...
Definition: global.cpp:161
string createMOOSEPath(const string &path)
Create a POSIX compatible path from a given string. Remove/replace bad characters.
Definition: global.cpp:105
bool useSpikeMode_
Definition: Table.h:78
bool useStreamer_
If stream is set to true, then stream to outfile_. Default value of outfile_ is table path starting f...
Definition: Table.h:100
double threshold_
Definition: Table.h:74
double getThreshold() const
Definition: Table.cpp:365
string tablePath_
Definition: Table.h:87
Definition: Id.h:17
vector< string > columns_
Definition: Table.h:85
string getOutfile(void) const
Definition: Table.cpp:438
bool getUseSpikeMode(void) const
Definition: Table.cpp:416
Definition: Table.h:18
vector< double > data_
Keep the data, each entry is preceeded by time value. t0, v0, t1, v1, t2, v2 etc. ...
Definition: Table.h:84
Table & operator=(const Table &tab)
Definition: Table.cpp:240
void setUseSpikeMode(bool status)
Definition: Table.cpp:411
static void writeToOutFile(const string &filepath, const string &format, const string &openmode, const vector< double > &data, const vector< string > &columns)
Write to a output file in given format.
void spike(double v)
Definition: Table.cpp:343
void input(double v)
Definition: Table.cpp:338
Definition: Cinfo.h:18
void setFormat(const string format)
Definition: Table.cpp:371
Definition: Finfo.h:12