Isis 3 Programmer Reference
CSVReader.cpp
Go to the documentation of this file.
1 
23 #include <string>
24 #include <vector>
25 #include <numeric>
26 #include <iostream>
27 #include <sstream>
28 #include "IString.h"
29 #include "CSVReader.h"
30 #include "CollectorMap.h"
31 #include "IException.h"
32 
33 using namespace std;
34 
35 namespace Isis {
36 
51  CSVReader::CSVReader() : _header(false), _skip(0),
52  _delimiter(','), _keepParts(true), _lines(),
53  _ignoreComments(true) { }
54 
81  CSVReader::CSVReader(const QString &csvfile, bool header, int skip,
82  const char &delimiter, const bool keepEmptyParts,
83  const bool ignoreComments) :
84  _header(header), _skip(skip), _delimiter(delimiter),
85  _keepParts(keepEmptyParts), _lines(),
86  _ignoreComments(ignoreComments) {
87 
88  read(csvfile);
89  }
90 
91 
113  int CSVReader::columns() const {
114  return ((rows() > 0) ? columns(getTable()) : 0);
115  }
116 
133  int CSVReader::columns(const CSVReader::CSVTable &table) const {
134  CSVColumnSummary summary = getColumnSummary(table);
135  return ((summary.size() > 0) ? summary.key(0) : 0);
136  }
137 
138 
156  void CSVReader::read(const QString &csvfile) {
157  ifstream ifile(csvfile.toLatin1().data(), ios::in);
158  if(!ifile) {
159  QString mess = "Unable to open file [" + csvfile + "]";
160  throw IException(IException::User, mess, _FILEINFO_);
161  }
162 
163  _lines.clear();
164  load(ifile);
165  ifile.close();
166  }
167 
185  // Return an empty header if we don't have one
186  if((!_header) || (_skip >= rows())) {
187  return (CSVAxis(0));
188  }
189  return (Parser(_lines[_skip], _delimiter, _keepParts).result());
190  }
191 
205  // Return an empty header if we don't have one
206  if((index < 0) || (index >= rows())) {
207  return (CSVAxis(0));
208  }
209  return (Parser(_lines[index+firstRowIndex()], _delimiter, _keepParts).result());
210  }
211 
212 
235  // Return an empty header if we don't have one
236  if(index < 0) {
237  return (CSVAxis(0));
238  }
239 
240  int nrows(rows());
241  int nbad(0);
242  CSVAxis column(nrows);
243  Parser parser;
244  for(int i = 0 ; i < nrows ; i++) {
246  if(parser.size() <= index) {
247 // column[i] = Parser::TokenType("");
248  nbad++;
249  }
250  else {
251  column[i] = parser(index);
252  }
253  }
254 
255  // If we had no good columns (index is invalid) return an empty column
256  return ((nbad == nrows) ? CSVAxis(0) : column);
257  }
258 
279  CSVReader::CSVAxis CSVReader::getColumn(const QString &hname) const {
280  // Get the header
281  CSVAxis header(getHeader());
282  QString head = hname.trimmed();
283  for(int i = 0 ; i < header.dim() ; i++) {
284  if(head.toLower() == header[i].trimmed().toLower()) {
285  return (getColumn(i));
286  }
287  }
288 
289  // If we reach here, we did not find the column name
290  return (CSVAxis(0));
291  }
292 
293 
319  CSVTable table(rows());
320  int nrows(rows());
321  Parser parser;
322  for(int row = 0 ; row < nrows ; row++) {
324  table[row] = parser.result();
325  }
326  return (table);
327  }
328 
361  const {
362  CSVColumnSummary summary;
363  for(int row = 0 ; row < table.dim() ; row++) {
364  int n(table[row].dim());
365  if(summary.exists(n)) {
366  int &count = summary.get(n);
367  count++;
368  }
369  else {
370  summary.add(n, 1);
371  }
372  }
373 
374  return (summary);
375  }
376 
388  bool CSVReader::isTableValid(const CSVReader::CSVTable &table) const {
389  CSVColumnSummary summary = getColumnSummary(table);
390  return (summary.size() <= 1);
391  }
392 
418  std::istream &CSVReader::load(std::istream &ifile) {
419 
420  std::string iline;
421  int nlines(0);
422  while(getline(ifile, iline)) {
423  if(!iline.empty()) {
424  if(!(_ignoreComments && (iline[0] == '#'))) {
425  _lines.push_back(iline.c_str());
426  nlines++;
427  }
428  }
429  }
430 
431  if(!ifile.eof()) {
432  ostringstream mess;
433  mess << "Error reading line [" << (nlines + 1) << "]" << ends;
434  throw IException(IException::User, mess.str(), _FILEINFO_);
435  }
436 
437  return (ifile);
438  }
439 
463  std::istream &operator>>(std::istream &is, CSVReader &csv) {
464  return (csv.load(is));
465  }
466 
467 }
std::istream & load(std::istream &ifile)
Reads all lines from the input stream until an EOF is encoutered.
Definition: CSVReader.cpp:418
CSVList _lines
List of lines from file.
Definition: CSVReader.h:494
CSVTable getTable() const
Parse and return all rows and columns in a table array.
Definition: CSVReader.cpp:318
CSV Parser seperates fields (tokens) from a string with a delimeter.
Definition: CSVReader.h:85
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:583
CSVColumnSummary getColumnSummary(const CSVTable &table) const
Computes a row summary of the number of distinct columns in table.
Definition: CSVReader.cpp:360
void read(const QString &fname)
Reads the entire contents of a file for subsequent parsing.
Definition: CSVReader.cpp:156
TokenList result() const
Returns the list of tokens.
Definition: CSVReader.h:172
int firstRowIndex() const
Computes the index of the first data.
Definition: CSVReader.h:506
int _skip
Number of lines to skip.
Definition: CSVReader.h:491
int parse(const QString &str, const char &delimiter=',', bool keepEmptyParts=true)
Parser method accepting string, delimiter and multiple token handling.
Definition: CSVReader.h:153
CSVParser< QString > Parser
Defines single line parser.
Definition: CSVReader.h:258
Namespace for the standard library.
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:528
bool _keepParts
Keep empty parts between delimiter.
Definition: CSVReader.h:493
bool _header
Indicates presences of header.
Definition: CSVReader.h:490
char _delimiter
Separator of values.
Definition: CSVReader.h:492
const K & key(int nth) const
Returns the nth key in the collection.
Definition: CollectorMap.h:689
int rows() const
Reports the number of rows in the table.
Definition: CSVReader.h:301
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:567
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:556
std::istream & operator>>(std::istream &is, CSVReader &csv)
Input read operator for input stream sources.
Definition: CSVReader.cpp:463
int size() const
Returns the number of tokens in the parsed string.
Definition: CSVReader.h:117
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
CSVAxis getRow(int index) const
Parse and return the requested row by index.
Definition: CSVReader.cpp:204
CSVAxis getColumn(int index) const
Parse and return a column specified by index order.
Definition: CSVReader.cpp:234
Parser::TokenList CSVAxis
Row/Column token list.
Definition: CSVReader.h:263
Reads strings and parses them into tokens separated by a delimiter character.
Definition: CSVReader.h:255
int columns() const
Determine the number of columns in the input source.
Definition: CSVReader.cpp:113
Collector/container for arbitrary items.
Definition: CollectorMap.h:435
bool isTableValid(const CSVTable &table) const
Indicates if all rows have the same number of columns.
Definition: CSVReader.cpp:388
CSVReader()
Default constructor for CSV reader.
Definition: CSVReader.cpp:51
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
TNT::Array1D< CSVAxis > CSVTable
Table of all rows/columns.
Definition: CSVReader.h:264
CSVAxis getHeader() const
Retrieve the header from the input source if it exists.
Definition: CSVReader.cpp:184
bool _ignoreComments
Ignore comments on read.
Definition: CSVReader.h:495