Isis 3 Programmer Reference
CSVReader.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include <string>
8 #include <vector>
9 #include <numeric>
10 #include <iostream>
11 #include <sstream>
12 #include "IString.h"
13 #include "CSVReader.h"
14 #include "CollectorMap.h"
15 #include "IException.h"
16 
17 using namespace std;
18 
19 namespace Isis {
20 
35  CSVReader::CSVReader() : _header(false), _skip(0),
36  _delimiter(','), _keepParts(true), _lines(),
37  _ignoreComments(true) { }
38 
65  CSVReader::CSVReader(const QString &csvfile, bool header, int skip,
66  const char &delimiter, const bool keepEmptyParts,
67  const bool ignoreComments) :
68  _header(header), _skip(skip), _delimiter(delimiter),
69  _keepParts(keepEmptyParts), _lines(),
70  _ignoreComments(ignoreComments) {
71 
72  read(csvfile);
73  }
74 
75 
97  int CSVReader::columns() const {
98  return ((rows() > 0) ? columns(getTable()) : 0);
99  }
100 
117  int CSVReader::columns(const CSVReader::CSVTable &table) const {
118  CSVColumnSummary summary = getColumnSummary(table);
119  return ((summary.size() > 0) ? summary.key(0) : 0);
120  }
121 
122 
140  void CSVReader::read(const QString &csvfile) {
141  ifstream ifile(csvfile.toLatin1().data(), ios::in);
142  if(!ifile) {
143  QString mess = "Unable to open file [" + csvfile + "]";
144  throw IException(IException::User, mess, _FILEINFO_);
145  }
146 
147  _lines.clear();
148  load(ifile);
149  ifile.close();
150  }
151 
169  // Return an empty header if we don't have one
170  if((!_header) || (_skip >= rows())) {
171  return (CSVAxis(0));
172  }
173  return (Parser(_lines[_skip], _delimiter, _keepParts).result());
174  }
175 
189  // Return an empty header if we don't have one
190  if((index < 0) || (index >= rows())) {
191  return (CSVAxis(0));
192  }
193  return (Parser(_lines[index+firstRowIndex()], _delimiter, _keepParts).result());
194  }
195 
196 
219  // Return an empty header if we don't have one
220  if(index < 0) {
221  return (CSVAxis(0));
222  }
223 
224  int nrows(rows());
225  int nbad(0);
226  CSVAxis column(nrows);
227  Parser parser;
228  for(int i = 0 ; i < nrows ; i++) {
230  if(parser.size() <= index) {
231 // column[i] = Parser::TokenType("");
232  nbad++;
233  }
234  else {
235  column[i] = parser(index);
236  }
237  }
238 
239  // If we had no good columns (index is invalid) return an empty column
240  return ((nbad == nrows) ? CSVAxis(0) : column);
241  }
242 
263  CSVReader::CSVAxis CSVReader::getColumn(const QString &hname) const {
264  // Get the header
265  CSVAxis header(getHeader());
266  QString head = hname.trimmed();
267  for(int i = 0 ; i < header.dim() ; i++) {
268  if(head.toLower() == header[i].trimmed().toLower()) {
269  return (getColumn(i));
270  }
271  }
272 
273  // If we reach here, we did not find the column name
274  return (CSVAxis(0));
275  }
276 
277 
303  CSVTable table(rows());
304  int nrows(rows());
305  Parser parser;
306  for(int row = 0 ; row < nrows ; row++) {
308  table[row] = parser.result();
309  }
310  return (table);
311  }
312 
345  const {
346  CSVColumnSummary summary;
347  for(int row = 0 ; row < table.dim() ; row++) {
348  int n(table[row].dim());
349  if(summary.exists(n)) {
350  int &count = summary.get(n);
351  count++;
352  }
353  else {
354  summary.add(n, 1);
355  }
356  }
357 
358  return (summary);
359  }
360 
372  bool CSVReader::isTableValid(const CSVReader::CSVTable &table) const {
373  CSVColumnSummary summary = getColumnSummary(table);
374  return (summary.size() <= 1);
375  }
376 
402  std::istream &CSVReader::load(std::istream &ifile) {
403 
404  std::string iline;
405  int nlines(0);
406  while(getline(ifile, iline)) {
407  if(!iline.empty()) {
408  if(!(_ignoreComments && (iline[0] == '#'))) {
409  _lines.push_back(iline.c_str());
410  nlines++;
411  }
412  }
413  }
414 
415  if(!ifile.eof()) {
416  ostringstream mess;
417  mess << "Error reading line [" << (nlines + 1) << "]" << ends;
418  throw IException(IException::User, mess.str(), _FILEINFO_);
419  }
420 
421  return (ifile);
422  }
423 
447  std::istream &operator>>(std::istream &is, CSVReader &csv) {
448  return (csv.load(is));
449  }
450 
451 }
Isis::CSVReader::getColumn
CSVAxis getColumn(int index) const
Parse and return a column specified by index order.
Definition: CSVReader.cpp:218
Isis::CSVReader::CSVAxis
Parser::TokenList CSVAxis
Row/Column token list.
Definition: CSVReader.h:247
Isis::CSVReader::columns
int columns() const
Determine the number of columns in the input source.
Definition: CSVReader.cpp:97
Isis::CSVReader::isTableValid
bool isTableValid(const CSVTable &table) const
Indicates if all rows have the same number of columns.
Definition: CSVReader.cpp:372
Isis::CSVReader
Reads strings and parses them into tokens separated by a delimiter character.
Definition: CSVReader.h:239
Isis::CSVReader::getRow
CSVAxis getRow(int index) const
Parse and return the requested row by index.
Definition: CSVReader.cpp:188
Isis::CollectorMap::get
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:567
Isis::CSVReader::CSVReader
CSVReader()
Default constructor for CSV reader.
Definition: CSVReader.cpp:35
Isis::CollectorMap::size
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:512
Isis::CSVReader::getHeader
CSVAxis getHeader() const
Retrieve the header from the input source if it exists.
Definition: CSVReader.cpp:168
Isis::CSVReader::CSVTable
TNT::Array1D< CSVAxis > CSVTable
Table of all rows/columns.
Definition: CSVReader.h:248
Isis::CSVReader::_ignoreComments
bool _ignoreComments
Ignore comments on read.
Definition: CSVReader.h:479
Isis::CSVReader::load
std::istream & load(std::istream &ifile)
Reads all lines from the input stream until an EOF is encoutered.
Definition: CSVReader.cpp:402
Isis::CSVParser::result
TokenList result() const
Returns the list of tokens.
Definition: CSVReader.h:156
Isis::CollectorMap::exists
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:551
Isis::CollectorMap::key
const K & key(int nth) const
Returns the nth key in the collection.
Definition: CollectorMap.h:673
Isis::CSVReader::getTable
CSVTable getTable() const
Parse and return all rows and columns in a table array.
Definition: CSVReader.cpp:302
Isis::CSVReader::_skip
int _skip
Number of lines to skip.
Definition: CSVReader.h:475
Isis::CSVReader::_lines
CSVList _lines
List of lines from file.
Definition: CSVReader.h:478
Isis::CSVReader::firstRowIndex
int firstRowIndex() const
Computes the index of the first data.
Definition: CSVReader.h:490
Isis::CSVReader::read
void read(const QString &fname)
Reads the entire contents of a file for subsequent parsing.
Definition: CSVReader.cpp:140
Isis::CSVReader::getColumnSummary
CSVColumnSummary getColumnSummary(const CSVTable &table) const
Computes a row summary of the number of distinct columns in table.
Definition: CSVReader.cpp:344
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::CollectorMap::add
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:540
std
Namespace for the standard library.
Isis::CollectorMap
Collector/container for arbitrary items.
Definition: CollectorMap.h:419
Isis::CSVReader::_keepParts
bool _keepParts
Keep empty parts between delimiter.
Definition: CSVReader.h:477
Isis::CSVReader::_header
bool _header
Indicates presences of header.
Definition: CSVReader.h:474
Isis::CSVReader::Parser
CSVParser< QString > Parser
Defines single line parser.
Definition: CSVReader.h:242
Isis::CSVParser
CSV Parser seperates fields (tokens) from a string with a delimeter.
Definition: CSVReader.h:69
Isis::CSVReader::_delimiter
char _delimiter
Separator of values.
Definition: CSVReader.h:476
Isis::CSVParser::parse
int parse(const QString &str, const char &delimiter=',', bool keepEmptyParts=true)
Parser method accepting string, delimiter and multiple token handling.
Definition: CSVReader.h:137
Isis::operator>>
std::istream & operator>>(std::istream &is, CSVReader &csv)
Input read operator for input stream sources.
Definition: CSVReader.cpp:447
Isis::CSVParser::size
int size() const
Returns the number of tokens in the parsed string.
Definition: CSVReader.h:101
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::CSVReader::rows
int rows() const
Reports the number of rows in the table.
Definition: CSVReader.h:285
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126