Unverified Commit f1d32bfd authored by Jesse Mapel's avatar Jesse Mapel Committed by GitHub
Browse files

Merge pull request #368 from SgStapleton/tracking

Added new tracking table object for Mosaic tracking Fixes #971
parents c95d3233 abb268ac
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
ifeq ($(ISISROOT), $(BLANK))
.SILENT:
error:
	echo "Please set ISISROOT";
else
	include $(ISISROOT)/make/isismake.objs
endif
 No newline at end of file
+166 −0
Original line number Diff line number Diff line
/**
 * @file
 * $Revision: 1.4 $
 * $Date: 2010/05/14 19:17:09 $
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are public
 *   domain. See individual third-party library and package descriptions for
 *   intellectual property information,user agreements, and related information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or implied,
 *   is made by the USGS as to the accuracy and functioning of such software
 *   and related material nor shall the fact of distribution constitute any such
 *   warranty, and no responsibility is assumed by the USGS in connection
 *   therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html in a browser or see
 *   the Privacy & Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */

#include "TrackingTable.h"

#include <QList>
#include <QString>

#include "FileName.h"
#include "IException.h"
#include "Pvl.h"
#include "Table.h"
#include "TableField.h"
#include "TableRecord.h"

using namespace std;
namespace Isis {


  /**
  * Default constructor
  */
  TrackingTable::TrackingTable() {
    
  }
  
  
  /**
  * Constructs a TrackingTable given a Table object. The Table is used to populate 
  *         m_fileList.
  *
  * @param table The Table object to pull the filenames and serial numbers from
  */
  TrackingTable::TrackingTable(Table table) {
    
    for (int i=0; i < table.Records(); i++) {
      TableRecord record = table[i];
      QString nameField = QString(record["FileName"]);
      QString extension(FileName(nameField).extension());
      int found = nameField.lastIndexOf(extension);
      if (found != -1) {
        // clear the packing characters - get only the file name
        nameField.remove(found + 3);
      }
      FileName fileName(nameField);
      QString serialNumber = QString(record["SerialNumber"]);
      m_fileList.append(QPair<FileName, QString>(fileName, serialNumber));
    }
  }
  
  
  /**
  * Destroys the TrackingTable object
  */
  TrackingTable::~TrackingTable() {
    
  }
  
  
  /**
  * Constrcts and returns a Table object based on values in m_fileList.
  *
  * @return Table The constructed table to be returned
  */
  Table TrackingTable::toTable() {
    
    // Begin by establishing the length of the fields within the table. This would be the longest 
    // length that is needed to be stored.
    int fieldLength = 0;
    
    for (int i=0; i < m_fileList.size(); i++) {
      if (m_fileList[i].first.name().length() > fieldLength) {
        fieldLength = m_fileList[i].first.name().length();
      }
      if (m_fileList[i].second.length() > fieldLength) {
        fieldLength = m_fileList[i].second.length();
      }
    }
    
    // This record is never being used. It is simply to construct the Table object.
    TableRecord dummyRecord;
    TableField fileNameField("FileName", TableField::Text, fieldLength);
    TableField serialNumberField("SerialNumber", TableField::Text, fieldLength);
    TableField indexField("Index", TableField::Integer);
    dummyRecord += fileNameField;
    dummyRecord += serialNumberField;
    dummyRecord += indexField;
    Table table(trackingTableName, dummyRecord);
    
    // Loop through m_fileList and add records to the table with the proper information.
    for (int i=0; i < m_fileList.size(); i++) {
      
      fileNameField = m_fileList[i].first.name();
      serialNumberField = m_fileList[i].second;
      indexField = i;
        
      TableRecord record;
      record += fileNameField;
      record += serialNumberField;
      record += indexField;
      
      table += record;
      
    }
    
    return table;
  }
  
  
  /**
  * Returns the FileName at the given index within m_fileList.
  *
  * @param index The index to find the filename for
  * @returns FileName The FileName at the index specified
  */
  FileName TrackingTable::indexToFileName(unsigned int index) {
    if (index >= (unsigned int)m_fileList.size()) {
      QString msg = "Cannot convert index [" + toString(index)
                  + "] to a filename, index is out of bounds.";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }
    
    return m_fileList[index].first;
  }
  
  
  /**
  * Returns the index of the filename/serialnumber combination.
  *
  * @param file The FileName within m_fileList to find the index of
  * @param serialNumber The QString of the serial number within m_fileList to find the index of
  * @return unsighned int The index of the filename/serialnumber combination
  */
  unsigned int TrackingTable::fileNameToIndex(FileName file, QString serialNumber) {
    for (int i = 0; i < m_fileList.size(); i++) {
      if (m_fileList[i].first == file) {
        return i;
      }
    }
    
    // At this point, the file is not in the internal file list so append it
    // and return its new index.
    m_fileList.append(QPair<FileName, QString>(file, serialNumber));
    return m_fileList.size() - 1;
  }

}
+72 −0
Original line number Diff line number Diff line
#ifndef TrackingTable_h
#define TrackingTable_h
/**
 * @file
 * $Revision: 1.3 $
 * $Date: 2010/05/14 19:17:09 $
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are public
 *   domain. See individual third-party library and package descriptions for
 *   intellectual property information,user agreements, and related information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or implied,
 *   is made by the USGS as to the accuracy and functioning of such software
 *   and related material nor shall the fact of distribution constitute any such
 *   warranty, and no responsibility is assumed by the USGS in connection
 *   therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html in a browser or see
 *   the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */

#include "FileName.h"
#include "Pvl.h"
#include "Table.h"

#include <QList>
#include <QString>


namespace Isis {
  
  const QString trackingTableName = "InputImages";

  /**
   * Table to store tracking information for a mosaic.
   *
   * This table will currently be stored in the label of a separate cube. This tracking cube will
   * also contain a single tracking band. The DN values stored in this band will correlate to the
   * indices in this table. Each record within this table will contain the filename of an
   * associated cube, that cube's serial number, and the DN value associated with this cube within
   * the tracking band (which should also be its index in the table).
   *
   * @author 2018-07-19 Jesse Mapel & Summer Stapleton
   *
   * @internal
   */
  class TrackingTable{
    
    public:
            
      TrackingTable();
      
      TrackingTable(Table table);
      
      ~TrackingTable();
      
      Table toTable();
            
      FileName indexToFileName(unsigned int index);
      
      unsigned int fileNameToIndex(FileName file, QString serialNumber);
      
    private:
      
      QList< QPair< FileName, QString > > m_fileList;   //!< The list to keep track of images
  };
};

#endif
 No newline at end of file
+40 −0
Original line number Diff line number Diff line
Unit test for TrackingTable


Testing default constructor ...
Record added: fileName1.cub, 1

Testing constructor with a Table object ...
Constructing Table ...
First record : fileName1.cub, 1234567890
Second record: fileName2.cub, 123
Third record : fileName3.dat, 456789
TrackingTable object created

Testing the indexToFileName method ...
FileName at index 0: fileName1.cub
FileName at index 1: fileName2.cub
FileName at index 2: fileName3.dat
FileName at index 3 does not exist and an exception is thrown.
**PROGRAMMER ERROR** Cannot convert index [3] to a filename, index is out of bounds.

Testing the fileNameToIndex method ...
Index of FileName fileName1.cub: 0
Index of FileName fileName2.cub: 1
Index of FileName fileName3.cub: 2
Index of the non-existent FileName fileName4.cub (demonstrating its addition): 3

Testing the toTable method ...
First record : fileName1.cub, 1234567890
Second record: fileName2.cub, 123
Third record : fileName3.dat, 456789
Fourth record: fileName4.cub, 12345678901234567890

Creating a new TrackingTable object with the table returned from toTable method ...
New TrackingTable object created

Testing that the Table returned from toTable on new TrackingTable matches ...
First record : fileName1.cub, 1234567890
Second record: fileName2.cub, 123
Third record : fileName3.dat, 456789
Fourth record: fileName4.cub, 12345678901234567890
+137 −0
Original line number Diff line number Diff line
#include <iostream>

#include "IException.h"
#include "Preference.h"
#include "Table.h"
#include "TableField.h"
#include "TableRecord.h"
#include "TrackingTable.h"

using namespace Isis;
using namespace std;

int main(int argc, char *argv[]) {

  Preference::Preferences(true);
  
  try{
    cout << "Unit test for TrackingTable\n" << endl;
    
    cout << endl;
    
    
    cout << "Testing default constructor ..." << endl;
    
    TrackingTable trackingTable1;
    
    trackingTable1.fileNameToIndex("fileName1.cub", "1");
    
    Table tableOut1 = trackingTable1.toTable();
    
    cout << "Record added: " << QString(tableOut1[0][0]) << ", " << QString(tableOut1[0][1]) << endl;
    
    cout << endl;
    
    
    cout << "Testing constructor with a Table object ..." << endl;
    
    cout << "Constructing Table ..." << endl;
    
    TableField fileNameField("FileName", TableField::Text, 50);
    TableField serialNumberField("SerialNumber", TableField::Text, 50);
    
    TableRecord record;
    record += fileNameField;
    record += serialNumberField;
    Table tableIn("TestingTable", record);
    
    record[0] = "fileName1.cub";
    record[1] = "1234567890";
    tableIn += record;
    
    record[0] = "fileName2.cub";
    record[1] = "123";
    tableIn += record;
    
    record[0] = "fileName3.dat";
    record[1] = "456789";
    tableIn += record;
    
    cout << "First record : " << QString(tableIn[0][0]) << ", " << QString(tableIn[0][1]) << endl;
    cout << "Second record: " << QString(tableIn[1][0]) << ", " << QString(tableIn[1][1]) << endl;
    cout << "Third record : " << QString(tableIn[2][0]) << ", " << QString(tableIn[2][1]) << endl;
    
    TrackingTable trackingTable2(tableIn);
    
    cout << "TrackingTable object created" << endl;
    
    cout << endl;
    
    
    cout << "Testing the indexToFileName method ..." << endl;
    
    for (int i = 0; i < 4; i++) {
      try {
        cout << "FileName at index " << i << ": " << trackingTable2.indexToFileName(i).name() << endl;
      }
      catch (IException e) {
        cout << "FileName at index " << i << " does not exist and an exception is thrown." << endl;
        e.print();
      }
    }

    cout << endl;
    

    cout << "Testing the fileNameToIndex method ..." << endl;
    
    cout << "Index of FileName fileName1.cub: " 
           << trackingTable2.fileNameToIndex("fileName1.cub", "1234567890") << endl;
    cout << "Index of FileName fileName2.cub: " 
           << trackingTable2.fileNameToIndex("fileName2.cub", "123") << endl;
    cout << "Index of FileName fileName3.cub: " 
           << trackingTable2.fileNameToIndex("fileName3.dat", "456789") << endl;
    cout << "Index of the non-existent FileName fileName4.cub (demonstrating its addition): " 
           << trackingTable2.fileNameToIndex("fileName4.cub", "12345678901234567890") << endl;
           
    cout << endl;
    

    cout << "Testing the toTable method ..." << endl;
    
    Table tableOut2 = trackingTable2.toTable();
    
    cout << "First record : " << QString(tableOut2[0][0]) << ", " << QString(tableOut2[0][1]) << endl;
    cout << "Second record: " << QString(tableOut2[1][0]) << ", " << QString(tableOut2[1][1]) << endl;
    cout << "Third record : " << QString(tableOut2[2][0]) << ", " << QString(tableOut2[2][1]) << endl;
    cout << "Fourth record: " << QString(tableOut2[3][0]) << ", " << QString(tableOut2[3][1]) << endl;
    
    cout << endl;
    
    
    cout << "Creating a new TrackingTable object with the table returned from toTable method ..." << endl;
    
    TrackingTable trackingTable3(tableOut2);
    
    cout << "New TrackingTable object created" << endl;
    
    cout << endl;
    
    
    cout << "Testing that the Table returned from toTable on new TrackingTable matches ..." << endl;
             
    Table tableOut3 = trackingTable3.toTable();
             
    cout << "First record : " << QString(tableOut3[0][0]) << ", " << QString(tableOut3[0][1]) << endl;
    cout << "Second record: " << QString(tableOut3[1][0]) << ", " << QString(tableOut3[1][1]) << endl;
    cout << "Third record : " << QString(tableOut3[2][0]) << ", " << QString(tableOut3[2][1]) << endl;
    cout << "Fourth record: " << QString(tableOut3[3][0]) << ", " << QString(tableOut3[3][1]) << endl;
    
  }
  catch (IException &e) {
    cout << "Unit test failed." << endl;
    e.print();
  }
  
  
}