Unverified Commit 74dfafaa authored by Stuart Sides's avatar Stuart Sides Committed by GitHub
Browse files

Added ability to identify arrays in the csv and place those into table arrays (#4381)

* Added ability to identify arrays in the csv and place those into arrays in the table

* Added to change log

* Added to the documentation

* Update csv2table.xml

* Update main.cpp
parent d478869f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ release.

- Fixed hi2isis MRO:ADC_TIMING_SETTINGS label conversion issue [4290](https://github.com/USGS-Astrogeology/ISIS3/issues/4290)

- Changed csv2table to identify headers with arrays and create table fields as arrays instead of single fields for each element [3676](https://github.com/USGS-Astrogeology/ISIS3/issues/3676)

## [4.4.0] - 2021-02-11

### Added
+14 −1
Original line number Diff line number Diff line
@@ -6,10 +6,19 @@
  </brief>

  <description>
    This application converts a CSV file to a table and attaches it to a cube
    <p>
    This application converts a CSV file to a table and attaches it to a cube.
    The first row of the CSV will be used as the fieldnames for the table.
    The contents of the CSV file will be converted to floating point numbers
    before they are inserted into the table.
    </p>
    <p>
    A single table field with multiple values will be created for consecutive CSV columns
    with the same column name followed by an index inside parentheses.
    The index must start at zero and increase from left to right.
    For example a CSV header line like: "A, B(0), B(1), B(2), C", will create three
    table fields, A with size=1, B with size=3, and C with size=1.
    </p>
  </description>

  <category>
@@ -26,6 +35,10 @@
    <change name="Jesse Mapel" date="2018-09-04">
      Original version
    </change>
    <change name="Stuart Sides" date="2021-03-20">
      Added ability to convert CSV files with indicies into table field arrays
      instead of individual table fields.
    </change>
  </history>

  <groups>
+33 −7
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@

#include "Isis.h"

#include <vector>

#include <QRegularExpression>
#include <QString>

#include "Cube.h"
@@ -60,24 +63,48 @@ void IsisMain() {
  CSVReader::CSVAxis header = reader.getHeader();

  // Construct an empty table with the CSV header as field names
  // Collect identical field names together, including those with (###) at the end, so a single
  // table field with multiple values can be created.
  TableRecord tableRow;
  QRegularExpression rex(R"((?<name>\w+)(\((?<index>[0-9]*)\)|))");
  for (int columnIndex = 0; columnIndex < numColumns; columnIndex++) {
    TableField columnField(QString(header[columnIndex]), TableField::Double);
    QRegularExpressionMatch match = rex.match(header[columnIndex]);
    if (match.hasMatch()) {
      QString name = match.captured("name");
      QString index = match.captured("index");

      // If the next column header is different, create a field for this one
      QRegularExpressionMatch nextMatch = (columnIndex<numColumns-1)?rex.match(header[columnIndex+1]):QRegularExpressionMatch();
      if ((columnIndex == numColumns-1) || (nextMatch.hasMatch() && (name != nextMatch.captured("name")))) {
        TableField columnField(name, TableField::Double, (index.length()>0)?(index.toInt()+1):1);
        tableRow += columnField;
      }
    }
  }

  QString tableName = ui.GetString("tablename");
  Table table(tableName, tableRow);

  // Fill the table
  // Fill the table from the csv
  for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {
    CSVReader::CSVAxis csvRow = reader.getRow(rowIndex);
    for (int columnIndex = 0; columnIndex < numColumns; columnIndex++) {
      tableRow[columnIndex] = toDouble(csvRow[columnIndex]);
    for (int columnIndex = 0, fieldIndex = 0; columnIndex < numColumns; ) {
      if (tableRow[fieldIndex].size() == 1) {
        tableRow[fieldIndex] = toDouble(csvRow[columnIndex++]);
      }
      else {
        std::vector<double> dblVector;
        for (int arrayLen = 0; arrayLen < tableRow[fieldIndex].size(); arrayLen++) {
          dblVector.push_back(toDouble(csvRow[columnIndex++]));
        }
        tableRow[fieldIndex] = dblVector;
      }
      fieldIndex++;
    }
    table += tableRow;
  }

  // If a set of label keywords was passed add them to the table
  // If a set of additional label keywords was given then add them to the table's pvl description
  if (ui.WasEntered("label")) {
    QString labelPvlFilename = ui.GetFileName("label");
    Pvl labelPvl;
@@ -116,5 +143,4 @@ void IsisMain() {
  }

  outCube.close();

}
+6 −0
Original line number Diff line number Diff line
@@ -10,4 +10,10 @@ commands:
	tabledump from=$(OUTPUT)/isisTruth.cub \
	to=$(OUTPUT)/output.csv \
	NAME="TestTable" > /dev/null;
	$(APPNAME) csv=$(INPUT)/test_arrays.csv \
	tablename="TestTableArrays" \
	to=$(OUTPUT)/isisTruth.cub > /dev/null;
	tabledump from=$(OUTPUT)/isisTruth.cub \
	to=$(OUTPUT)/output_arrays.csv \
	NAME="TestTableArrays" > /dev/null;
	rm $(OUTPUT)/isisTruth.cub;