MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TableBase.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 <fstream>
12 #include "../utility/strutil.h"
13 #include "TableBase.h"
14 
16 {
18  // Field Definitions
21  "vector",
22  "vector with all table entries",
25  );
26 
27  static ValueFinfo< TableBase, string > plotDump(
28  "plotDump",
29  "'File plotname' for dumpling an xplot, as a workaround for an error in the xplot python interface. Note separator is a space. The return value is a dummy.",
32  );
33 
34  static ReadOnlyValueFinfo< TableBase, double > outputValue(
35  "outputValue",
36  "Output value holding current table entry or output of a calculation",
38  );
39 
41  "size",
42  "size of table. Note that this is the number of x divisions +1"
43  "since it must represent the largest value as well as the"
44  "smallest",
46  );
47 
49  "y",
50  "Value of table at specified index",
52  );
53 
55  // MsgDest Definitions
57 
58  static DestFinfo linearTransform( "linearTransform",
59  "Linearly scales and offsets data. Scale first, then offset.",
61 
62  static DestFinfo xplot( "xplot",
63  "Dumps table contents to xplot-format file. "
64  "Argument 1 is filename, argument 2 is plotname",
66 
67  static DestFinfo plainPlot( "plainPlot",
68  "Dumps table contents to single-column ascii file. "
69  "Uses scientific notation. "
70  "Argument 1 is filename",
72 
73  static DestFinfo loadCSV( "loadCSV",
74  "Reads a single column from a CSV file. "
75  "Arguments: filename, column#, starting row#, separator",
77  &TableBase::loadCSV ) );
78 
79  static DestFinfo loadXplot( "loadXplot",
80  "Reads a single plot from an xplot file. "
81  "Arguments: filename, plotname"
82  "When the file has 2 columns, the 2nd column is loaded.",
85 
86  static DestFinfo loadXplotRange( "loadXplotRange",
87  "Reads a single plot from an xplot file, and selects a "
88  "subset of points from it. "
89  "Arguments: filename, plotname, startindex, endindex"
90  "Uses C convention: startindex included, endindex not included."
91  "When the file has 2 columns, the 2nd column is loaded.",
94 
95  static DestFinfo compareXplot( "compareXplot",
96  "Reads a plot from an xplot file and compares with contents of TableBase."
97  "Result is put in 'output' field of table."
98  "If the comparison fails (e.g., due to zero entries), the "
99  "return value is -1."
100  "Arguments: filename, plotname, comparison_operation"
101  "Operations: rmsd (for RMSDifference), rmsr (RMSratio ), "
102  "dotp (Dot product, not yet implemented).",
105 
106  static DestFinfo compareVec( "compareVec",
107  "Compares contents of TableBase with a vector of doubles."
108  "Result is put in 'output' field of table."
109  "If the comparison fails (e.g., due to zero entries), the "
110  "return value is -1."
111  "Arguments: Other vector, comparison_operation"
112  "Operations: rmsd (for RMSDifference), rmsr (RMSratio ), "
113  "dotp (Dot product, not yet implemented).",
114  new OpFunc2< TableBase, vector< double >, string >(
116 
117  static DestFinfo clearVec(
118  "clearVec",
119  "Handles request to clear the data vector",
121 
122 
123  static Finfo* tableBaseFinfos[] = {
124  &vec, // Value
125  &plotDump, // Value, used for debugging xplot function.
126  &outputValue, // ReadOnlyValue
127  &size, // ReadOnlyValue
128  &y, // ReadOnlyLookupValue
129  &linearTransform, // DestFinfo
130  &xplot, // DestFinfo
131  &plainPlot, // DestFinfo
132  &loadCSV, // DestFinfo
133  &loadXplot, // DestFinfo
134  &loadXplotRange, // DestFinfo
135  &compareXplot, // DestFinfo
136  &compareVec, // DestFinfo
137  &clearVec,
138  };
139 
140  static Dinfo< TableBase > dinfo;
141  static Cinfo tableCinfo (
142  "TableBase",
144  tableBaseFinfos,
145  sizeof( tableBaseFinfos ) / sizeof ( Finfo* ),
146  &dinfo
147  );
148 
149  return &tableCinfo;
150 }
151 
153 // Basic class Definitions
155 
157 
158 TableBase::TableBase() : output_( 0 )
159 {
160 }
161 
163 // MsgDest Definitions
165 
166 void TableBase::linearTransform( double scale, double offset )
167 {
168  for ( vector< double >::iterator i = vec_.begin(); i != vec_.end(); ++i)
169  *i = *i * scale + offset;
170 }
171 
172 void TableBase::plainPlot( string fname )
173 {
174  ofstream fout( fname.c_str(), ios_base::out );
175  fout.precision( 18 );
176  fout.setf( ios::scientific, ios::floatfield );
177  for ( vector< double >::iterator i = vec_.begin(); i != vec_.end(); ++i)
178  fout << *i << endl;
179  fout << "\n";
180 }
181 
182 void TableBase::xplot( string fname, string plotname )
183 {
184  ofstream fout( fname.c_str(), ios_base::app );
185  fout << "/newplot\n";
186  fout << "/plotname " << plotname << "\n";
187  for ( vector< double >::iterator i = vec_.begin(); i != vec_.end(); ++i)
188  fout << *i << endl;
189  fout << "\n";
190 }
191 
192 bool isNamedPlot( const string& line, const string& plotname )
193 {
194  static const unsigned int len = strlen( "/plotname" ) ;
195  if ( line.size() < len + 2 )
196  return 0;
197  if ( line[0] == '/' && line[1] == 'p' ) {
198  string name = line.substr( strlen( "/plotname" ) );
199  string::size_type pos = name.find_first_not_of( " " );
200  if ( pos == string::npos ) {
201  cout << "TableBase::loadXplot: Malformed plotname line '" <<
202  line << "'\n";
203  return 0;
204  }
205  name = name.substr( pos );
206  if ( plotname == name )
207  return 1;
208  }
209  return 0;
210 }
211 
212 /*
213 bool lineHasExactlyTwoNumericalColumns( const string& line )
214 {
215  istringstream sstream( line );
216  double y;
217 
218  if ( sstream >> y ) {
219  if ( sstream >> y ) {
220  if ( sstream >> y ) {
221  return 0;
222  } else {
223  return 1;
224  }
225  }
226  }
227  return 0;
228 }
229 */
230 
231 double getYcolumn( const string& line )
232 {
233  istringstream sstream( line );
234  double y1 = 0.0;
235  double y2;
236  double y3;
237 
238  if ( sstream >> y1 ) {
239  if ( sstream >> y2 ) {
240  if ( sstream >> y3 ) {
241  return y1;
242  } else {
243  return y2;
244  }
245  }
246  }
247  return y1;
248 }
249 
250 bool innerLoadXplot( string fname, string plotname, vector< double >& v )
251 {
252  ifstream fin( fname.c_str() );
253  if ( !fin.good() ) {
254  cout << "TableBase::innerLoadXplot: Failed to open file " << fname <<endl;
255  return 0;
256  }
257 
258  string line;
259  // Here we advance to the first numerical line.
260  if ( plotname == "" ) // Just load starting from the 1st numerical line.
261  {
262  while ( fin.good() ) { // Break out of this loop if we find a number
263  getline( fin, line );
264  line = moose::trim(line);
265  if ( isdigit( line[0] ) )
266  break;;
267  if ( line[0] == '-' && line.length() > 1 && isdigit( line[1] ) )
268  break;
269  }
270  } else { // Find plotname and then begin loading.
271  while ( fin.good() ) {
272  getline( fin, line );
273  line = moose::trim(line);
274  if ( isNamedPlot ( line, plotname ) ) {
275  if ( !getline ( fin, line ) )
276  return 0;
277  break;
278  }
279  }
280  }
281 
282  v.resize( 0 );
283  do {
284  if ( line.length() == 0 || line == "/newplot" || line == "/plotname" )
285  break;
286  v.push_back( getYcolumn( line ) );
287  getline( fin, line );
288  line = moose::trim(line);
289  } while ( fin.good() );
290 
291  return ( v.size() > 0 );
292 }
293 
294 void TableBase::loadXplot( string fname, string plotname )
295 {
296  if ( !innerLoadXplot( fname, plotname, vec_ ) ) {
297  cout << "TableBase::loadXplot: unable to load data from file " << fname <<endl;
298  return;
299  }
300 }
301 
302 void TableBase::loadXplotRange( string fname, string plotname,
303  unsigned int start, unsigned int end )
304 {
305  vector< double > temp;
306  if ( !innerLoadXplot( fname, plotname, temp ) ) {
307  cout << "TableBase::loadXplot: unable to load data from file " << fname <<endl;
308  return;
309  }
310  if ( start > end || end > temp.size() ) {
311  cout << "TableBase::loadXplotRange: Bad range (" << start <<
312  ", " << end << "] for table of size " << temp.size() <<
313  " from file " << fname << endl;
314  return;
315  }
316  vec_.clear();
317  vec_.insert( vec_.end(), temp.begin() + start, temp.begin() + end );
318 }
319 
321  string fname, int startLine, int colNum, char separator )
322 {
323  cout << "TODO: Not implemented yet" << endl;
324 }
325 
326 double getRMSDiff( const vector< double >& v1, const vector< double >& v2 )
327 {
328  unsigned int size = ( v1.size() < v2.size() ) ? v1.size() : v2.size();
329  if ( size == 0 )
330  return -1;
331 
332  double sumsq = 0;
333  for ( unsigned int i = 0; i < size; ++i ) {
334  double temp = v1[i] - v2[i];
335  sumsq += temp * temp;
336  }
337  return sqrt( sumsq / size );
338 }
339 
340 double getRMS( const vector< double >& v )
341 {
342  double sumsq = 0;
343  unsigned int size = v.size();
344  if ( size == 0 )
345  return -1;
346  for ( vector< double >::const_iterator i = v.begin(); i != v.end(); ++i)
347  sumsq += *i * *i;
348 
349  return sqrt( sumsq / size );
350 }
351 
352 double getRMSRatio( const vector< double >& v1, const vector< double >& v2 )
353 {
354  double r1 = getRMS( v1 );
355  double r2 = getRMS( v2 );
356  if ( v1.size() == 0 || v2.size() == 0 )
357  return -1;
358  if ( r1 + r2 > 1e-20 )
359  return getRMSDiff( v1, v2 ) / (r1 + r2);
360  return -1;
361 }
362 
363 string headop( const string& op )
364 {
365  const unsigned int len = 5;
366  char temp[len];
367  unsigned int i = 0;
368  for ( i = 0; i < op.length() && i < len-1 ; ++i )
369  temp[i] = tolower( op[i] );
370  temp[i] = '\0';
371  return string( temp );
372 }
373 
374 void TableBase::compareXplot( string fname, string plotname, string op )
375 {
376  vector< double > temp;
377  if ( !innerLoadXplot( fname, plotname, temp ) ) {
378  cout << "TableBase::compareXplot: unable to load data from file " << fname <<endl;
379  }
380 
381  string hop = headop( op );
382 
383  if ( hop == "rmsd" ) { // RMSDifference
384  output_ = getRMSDiff( vec_, temp );
385  }
386 
387  if ( hop == "rmsr" ) { // RMS ratio
388  output_ = getRMSRatio( vec_, temp );
389  }
390 
391  if ( hop == "dotp" )
392  cout << "TableBase::compareXplot: DotProduct not yet done\n";
393 }
394 
395 void TableBase::compareVec( vector< double > temp, string op )
396 {
397  // Note that this line below is illegal: it causes a race condition
398  // vector< double > temp = Field< vector< double > >::get( other, "vec" );
399 
400  string hop = headop( op );
401 
402  if ( hop == "rmsd" ) { // RMSDifference
403  output_ = getRMSDiff( vec_, temp );
404  }
405 
406  if ( hop == "rmsr" ) { // RMS ratio
407  output_ = getRMSRatio( vec_, temp );
408  }
409 
410  if ( hop == "dotp" )
411  cout << "TableBase::compareVec: DotProduct not yet done\n";
412 }
413 
415 {
416  vec_.resize( 0 );
417 }
418 
420 // Field Definitions
422 
424 {
425  return output_;
426 }
427 
429 {
430  output_ = v;
431 }
432 
433 double TableBase::getY( unsigned int index ) const
434 {
435  if ( index < vec_.size() )
436  return ( vec_[index] );
437  return 0;
438 }
439 
440 double TableBase::interpolate( double xmin, double xmax, double input )
441  const
442 {
443  if ( vec_.size() == 0 )
444  return 0;
445  if ( vec_.size() == 1 || input < xmin || xmin >= xmax )
446  return vec_[0];
447  if ( input > xmax )
448  return ( vec_.back() );
449 
450  unsigned int xdivs = vec_.size() - 1;
451 
452  double fraction = ( input - xmin ) / ( xmax - xmin );
453  if ( fraction < 0 )
454  return vec_[0];
455 
456  unsigned int j = xdivs * fraction;
457  if ( j >= ( vec_.size() - 1 ) )
458  return vec_.back();
459 
460  double dx = (xmax - xmin ) / xdivs;
461  double lowerBound = xmin + j * dx;
462  double subFraction = ( input - lowerBound ) / dx;
463 
464  double y = vec_[j] + ( vec_[j + 1] - vec_[j] ) * subFraction;
465  return y;
466 }
467 
469 // Element Field Definitions
471 
472 void TableBase::setVecSize( unsigned int num )
473 {
474  vec_.resize( num );
475 }
476 
477 unsigned int TableBase::getVecSize() const
478 {
479  return vec_.size();
480 }
481 
482 vector< double > TableBase::getVec() const
483 {
484  return vec_;
485 }
486 
487 void TableBase::setVec( vector< double > val )
488 {
489  vec_ = val;
490 }
491 
492 vector< double >& TableBase::vec()
493 {
494  return vec_;
495 }
496 
497 // Fetch the const copy of table. Used in Streamer class.
498 const vector< double >& TableBase::data( )
499 {
500  return vec_;
501 }
502 
504 {
505  static string ret = "plot.Dump";
506  return ret;
507 }
508 
509 void TableBase::setPlotDump( string v )
510 {
511 
512  std::size_t pos = v.rfind(" ");
513  string fname = v.substr( 0, pos );
514  string plotname = "plot";
515  if ( pos != string::npos )
516  plotname = v.substr( pos );
517  // cout << "setPlotDump( " << fname << ", " << plotname << " ), " << v << "\n";
518  xplot( fname, plotname );
519 }
double getRMSDiff(const vector< double > &v1, const vector< double > &v2)
Definition: TableBase.cpp:326
void xplot(string file, string plotname)
Definition: TableBase.cpp:182
double getOutputValue() const
Definition: TableBase.cpp:423
bool isNamedPlot(const string &line, const string &plotname)
Definition: TableBase.cpp:192
vector< double > & vec()
Definition: TableBase.cpp:492
static double op(double x)
void linearTransform(double scale, double offset)
Definition: TableBase.cpp:166
void setVec(vector< double > val)
Definition: TableBase.cpp:487
vector< double > vec_
Definition: TableBase.h:73
string headop(const string &op)
Definition: TableBase.cpp:363
Definition: Dinfo.h:60
Definition: OpFunc.h:56
vector< double > getVec() const
Definition: TableBase.cpp:482
double interpolate(double x, double xmin, double xmax) const
Definition: TableBase.cpp:440
void setPlotDump(string v)
Definition: TableBase.cpp:509
void clearVec()
Definition: TableBase.cpp:414
double getRMSRatio(const vector< double > &v1, const vector< double > &v2)
Definition: TableBase.cpp:352
Definition: OpFunc.h:40
static const Cinfo * tableBaseCinfo
Definition: TableBase.cpp:156
void setOutputValue(double val)
Definition: TableBase.cpp:428
double getYcolumn(const string &line)
Definition: TableBase.cpp:231
const vector< double > & data()
Definition: TableBase.cpp:498
unsigned int getVecSize() const
Definition: TableBase.cpp:477
static const Cinfo * initCinfo()
Definition: TableBase.cpp:15
void loadCSV(string fname, int startLine, int colNum, char separator)
Definition: TableBase.cpp:320
void loadXplotRange(string fname, string plotname, unsigned int start, unsigned int end)
Definition: TableBase.cpp:302
Definition: OpFunc.h:27
void compareXplot(string fname, string plotname, string op)
Definition: TableBase.cpp:374
void plainPlot(string file)
Definition: TableBase.cpp:172
static const Cinfo * tableCinfo
Definition: Table.cpp:211
double getY(unsigned int index) const
Definition: TableBase.cpp:433
static char name[]
Definition: mfield.cpp:401
bool innerLoadXplot(string fname, string plotname, vector< double > &v)
Definition: TableBase.cpp:250
double getRMS(const vector< double > &v)
Definition: TableBase.cpp:340
Definition: OpFunc.h:13
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
std::string trim(const std::string myString, const string &delimiters)
Definition: strutil.cpp:53
void setVecSize(unsigned int num)
Definition: TableBase.cpp:472
Definition: Cinfo.h:18
Definition: OpFunc.h:70
void loadXplot(string fname, string plotname)
Definition: TableBase.cpp:294
void compareVec(vector< double > other, string op)
Definition: TableBase.cpp:395
Definition: Finfo.h:12
string getPlotDump() const
Definition: TableBase.cpp:503
double output_
Definition: TableBase.h:72