Commit 48b1e9b0 authored by Tyler Wilson's avatar Tyler Wilson
Browse files

PROG: Forgot to do svn add before committing the new classes. References #4018

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@6805 41f8697f-d340-4b68-9986-7bafba869bb8
parent feab4a12
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------

*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash

# qtcreator generated files
*.pro.user*

# xemacs temporary files
*.flc

# Vim temporary files
.*.swp

# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*

# MinGW generated files
*.Debug
*.Release

# Python byte code
*.pyc

# Binaries
# --------
*.dll
*.exe

+563 −0
Original line number Diff line number Diff line
#include "CorrelationMatrix.h"

#include <QDataStream>
#include <QDebug>
#include <QFile>
#include <QList>
#include <QString>
#include <QStringList>
#include <QtCore/qmath.h>

#include "IException.h"
#include "Pvl.h"
#include "PvlObject.h"
#include "SparseBlockMatrix.h"

namespace Isis {
  /**
   * Default Constructor
   */
  CorrelationMatrix::CorrelationMatrix() {
    m_covarianceFileName = new FileName(""); 
    m_correlationFileName = new FileName(""); 
    m_visibleBlocks = new QList<SparseBlockColumnMatrix>();
    m_imagesAndParameters = new QMap<QString, QStringList>();
    m_diagonals = new QList<double>();
  }


  /**
   * This constructor will create a CorrelationMatrix object given a pvl.
   *
   * Object = CorrelationMatrix
   *
   *    CovarianceFileName = fileName.dat
   *    CorrelationFileName = fileName.dat
   *
   *    Group = ImagesAndParameters
   *       Image1 = "Parameter1", "Parameter2", "..."
   *       Image2 = "Parameter1", "Parameter2", "..."
   *       Image3 = "Parameter1", "Parameter2", "..."
   *    End_Group
   *
   * End_Object
   *
   * @param storedMatrixData  A PvlObject containing data about the
   * covariance/correlation matrix.
   *
   * @throws IException::User "This Pvl Object does not have the correct correlation information.
   * The Object you are looking for is called CorrelationMatrixData"
   *
   * @throws IException::User "Could not find the Covariance Matrix .dat file name."
   *
   * @throws IException::User "Could not find the Correlation Matrix .dat file name."
   *
   * @throws IException::User "Could not get Images and Parameters from ImagesAndParameters group."
   *
   */
  CorrelationMatrix::CorrelationMatrix(PvlObject storedMatrixData) {
    //m_imagesAndParameters = NULL;
    m_imagesAndParameters = new QMap<QString, QStringList>();
    m_covarianceFileName = new FileName("");
    m_correlationFileName = new FileName("");
    m_diagonals = NULL;
    m_visibleBlocks = NULL;

    if (storedMatrixData.name() != "CorrelationMatrixData") {
      QString msg = "This Pvl Object does not have the correct correlation information. The Object "
                    "you are looking for is called CorrelationMatrixData.";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    try {
      m_covarianceFileName =
          new FileName(storedMatrixData.findKeyword("CovarianceMatrixFileName")[0]);
    }
    catch (IException &e) {
      QString msg = "Could not find the Covariance Matrix .dat file name.";
      throw IException(e, IException::User, msg, _FILEINFO_);
    }
    
    try {
      QString corrFileName = storedMatrixData.findKeyword("CorrelationMatrixFileName")[0];
      if (corrFileName == "NULL") {
        m_correlationFileName = new FileName;
      }
      else {
        m_correlationFileName = new FileName(corrFileName);
      }
    }
    catch (IException &e) {
      QString msg = "Could not find the Correlation Matrix .dat file name.";
      throw IException(e, IException::User, msg, _FILEINFO_);
    }

    try {
      PvlObject::PvlKeywordIterator
          imgsIt = storedMatrixData.findGroup("ImagesAndParameters").begin();
      while ( imgsIt != storedMatrixData.findGroup("ImagesAndParameters").end() ) {
        QStringList params = (*imgsIt)[0].split(",");
        m_imagesAndParameters->insert(imgsIt->name(), params);
        imgsIt++;
      }
    }
    catch (IException &e) {
      QString msg = "Could not get Images and Parameters from ImagesAndParameters group.";
      throw IException(e, IException::User, msg, _FILEINFO_);
    }
  }


  /**
   * @brief Copy Constructor
   *
   * @param other The CorrelationMatrix to copy.
   */
  CorrelationMatrix::CorrelationMatrix(const CorrelationMatrix &other) {
    m_imagesAndParameters = new QMap<QString, QStringList>(*other.m_imagesAndParameters);
    m_covarianceFileName = new FileName(*other.m_covarianceFileName);
    m_correlationFileName = new FileName(*other.m_correlationFileName);
    m_diagonals = new QList<double>(*other.m_diagonals);
    m_visibleBlocks = new QList<SparseBlockColumnMatrix>(*other.m_visibleBlocks);
  }


  /**
   * Destructor
   */
  CorrelationMatrix::~CorrelationMatrix() {
    delete m_imagesAndParameters;
    m_imagesAndParameters = NULL;

    delete m_covarianceFileName;
    m_covarianceFileName = NULL;

    delete m_correlationFileName;
    m_correlationFileName = NULL;

    delete m_diagonals;
    m_diagonals = NULL;

    delete m_visibleBlocks;
    m_visibleBlocks = NULL;
  }


  /**
   * @brief Equal Operator
   *
   * Should this call the copy constructor???
   *
   * @param other The matrix to assign to this matrix.
   * @return @b CorrelationMatrix Returns the new matrix.
   */
  CorrelationMatrix &CorrelationMatrix::operator=(const CorrelationMatrix &other) {

    if (&other != this) {

      delete m_imagesAndParameters;
      m_imagesAndParameters = NULL;
      m_imagesAndParameters = new QMap<QString, QStringList>(*other.m_imagesAndParameters);
  
      delete m_covarianceFileName;
      m_covarianceFileName = NULL;
      m_covarianceFileName = new FileName(*other.m_covarianceFileName);
  
      delete m_correlationFileName;
      m_correlationFileName = NULL;
      m_correlationFileName = new FileName(*other.m_correlationFileName);
  
      delete m_diagonals;
      m_diagonals = NULL;
      m_diagonals = new QList<double>(*other.m_diagonals);
  
      delete m_visibleBlocks;
      m_visibleBlocks = NULL;
      m_visibleBlocks = new QList<SparseBlockColumnMatrix>(*other.m_visibleBlocks);

    }

    return *this;
  }


  /**
  * @description This method reads the covariance matrix in from a file,
  * one SparseBlockColumnMatrix at a time.  It then stores the diagonal values from that column
  * and computes the correlation values. The resulting SparseBlockMatrix is written to a
  * new file, one SparseBlockColumnMatrix at a time.
  *
  * @throws IException::Progammer  "Cannot compute correlation matrix without a specified
  * file name.  Use setCorrelationFileName(FileName) before calling computeCorrelationMatrix()."
  */
  void CorrelationMatrix::computeCorrelationMatrix() {

    if ( !isValid() ) {
      QString msg = "Cannot compute correlation matrix without a specified file name. Use "
                    "setCorrelationFileName(FileName) before calling computeCorrelationMatrix().";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }
    delete m_visibleBlocks;
    m_visibleBlocks = NULL;
    m_visibleBlocks = new QList<SparseBlockColumnMatrix>;

    // Create file handle
    QFile matrixInput( m_covarianceFileName->expanded() );
    QFile matrixOutput( m_correlationFileName->expanded() );

    // Open file to write to
    matrixInput.open(QIODevice::ReadOnly);
    matrixOutput.open(QIODevice::WriteOnly);

    // Open Stream
    QDataStream inStream(&matrixInput);
    QDataStream outStream(&matrixOutput);

    double firstParam1 = 0, //starting param for each iteration
            firstParam2 = 0;
    double param1 = 0, // current param for each iteration
            param2 = 0;
    // Read one column at a time
    SparseBlockColumnMatrix sbcm;
    while ( !inStream.atEnd() ) {
      inStream >> sbcm;

      // Store diagonal
      int numOfBlocks = sbcm.size();
      int lastBlock = numOfBlocks - 1;
      int numDiagonals = sbcm[lastBlock]->size1();

      // Get Diagonals
      for (int i = 0; i < numDiagonals; i++) {
        double val = ( *(sbcm[lastBlock]) )(i, i);
        m_diagonals->append(val);
      }

      // compute correlations
      QMapIterator<int, boost::numeric::ublas::matrix<double>*> block(sbcm);

      while ( block.hasNext() ) { // each block in the column
        block.next();
        for (int row = 0; row < (int)block.value()->size1(); row++) { // each row in the block
          for (int column = 0; column < (int)block.value()->size2(); column++) { // each column 
            // correlation = covariance / (variance1 * variance2)
            ( *block.value() )(row, column) = ( *block.value() )(row, column) /
                                              sqrt( (*m_diagonals)[param1] *
                                                    (*m_diagonals)[param2] );
            param2++;
          }
          param1++;
          param2 = firstParam2;
        }
        firstParam1 += block.value()->size1();
        param1 = firstParam1;
      }
      firstParam1 = 0;  // start each column at first element of diagonal list
      param1 = firstParam1;
      firstParam2 += block.value()->size2();
      param2 = firstParam2;

      outStream << sbcm;
      m_visibleBlocks->append(sbcm);
    }
    
    // close file
    matrixInput.close();
    matrixOutput.close();
  }



  /**
   * @description This method will open the correlation matrix file and read in the blocks that
   * apply to the requested area. It will populate m_visibleElements.
   *
   * @param x first coordinate of the location in the matrix that the user wants to see.
   * @param y second coordinate of the location in the matrix that the user wants to see.
   */
  void CorrelationMatrix::retrieveVisibleElements(int x, int y) {

//     if ( !correlationMatrixExists() ) {
      // call computeCorrelationMatrix
//     }
    // read the values we want from the correlation matrix file.

    // store values by column?
    // return list of values in m_visibleElements
  }



  /**
   * This is the public accessor for the list of elements that should be displayed in the current
   *   view.
   *
   * @return QList<MatrixElement*> The list of currently visible elements.
   *
   */
//   QList<MatrixElement*> CorrelationMatrix::visibleElements() {
//     return *m_visibleElements;
//   }



  /**
   * @brief See if the correlation matrix has already been calculated by checking to see if
   *   the correlation matrix file has been created.
   *
   * @return @b bool Returns True if the correlation matrix has already been set.
   */
  bool CorrelationMatrix::isValid() {

      return !(m_correlationFileName->name() == "" || m_covarianceFileName->name() == "");
  }


  /**
   * @description This is used to make sure the covariance matrix exists.
   * If it doesn't this class is not valid. If this file exists, we can compute the
   * correlation matrix.
   *
   * @return @b bool Returns True if the covariance matrix exists, and False if it does not.
   */
  bool CorrelationMatrix::hasCovMat() {
    return !(m_covarianceFileName->name() == "");
  }


  // Set Methods
  /**
   * @brief Set the qmap of images and parameters.
   * @param correlationFileName The FileName of the stored correlation matrix data.
   */
  void CorrelationMatrix::setCorrelationFileName(FileName correlationFileName) {
    if (m_correlationFileName == NULL) {
      m_correlationFileName = new FileName(correlationFileName);
    }
    else {
      *m_correlationFileName = correlationFileName;
    }
  }


  /**
   * @brief Set the qmap of images and parameters.
   * @param  covarianceFileName  The FileName of the stored covariance matrix data.
   */
  void CorrelationMatrix::setCovarianceFileName(FileName covarianceFileName) {
    if (m_covarianceFileName == NULL) {
      m_covarianceFileName = new FileName(covarianceFileName);
    }
    else {
      *m_covarianceFileName = covarianceFileName;
    }
    //Make the correlation matrix file name match the covariance matrix file name.
    if (!isValid()) {
      QString fName = covarianceFileName.expanded().replace( QString("inverse"),
                                                            QString("correlation") );
      setCorrelationFileName( FileName(fName) );
    }
  }


  /**
   * @brief Set the qmap of images and parameters.
   *
   * @param imagesAndParameters a QMap structure indexed by image keys, with an arbitrary set of
   * parameters for each image.
   */
  void CorrelationMatrix::setImagesAndParameters(QMap<QString, QStringList> imagesAndParameters) {
    if (m_imagesAndParameters == NULL) {
      m_imagesAndParameters = new QMap<QString, QStringList>(imagesAndParameters);
    }
    else {
      *m_imagesAndParameters = imagesAndParameters;
    }      
  }


  /**
   * @brief Public access for the correlation matrix file name.
   *
   * @return @b FileName  The FileName of the correlation matrix data file.
   */
  FileName CorrelationMatrix::correlationFileName() {
    return *m_correlationFileName;
  }


  /**
   * @brief Public access for the covariance matrix file name.
   *
   * @return @b FileName The FileName of the covariance data file.
   */
  FileName CorrelationMatrix::covarianceFileName() {
    return *m_covarianceFileName;
  }


  /**
   * @brief Public access for the qmap of images and parameters.
   *
   * @return  @b *QMap<QString,QStringList>  A pointer to the QMap structure containing a list
   * of images (the keys) and their associated parameter values.
   */
  QMap<QString, QStringList> *CorrelationMatrix::imagesAndParameters() {
    return m_imagesAndParameters;
  }


  /**
   * @description This method will read the matrix in from the file and hold on to the whole thing.
   * This will only be used when the matrix is small enough that this will be useful.
   *
   */
  void CorrelationMatrix::getWholeMatrix() {
//     SparseBlockColumnMatrix sbcm;
//     QFile matrixInput( m_correlationFileName->expanded() );
//     matrixInput.open(QIODevice::ReadOnly);
//     QDataStream inStream(&matrixInput);
//
//     while( !inStream.atEnd() ) {
//       inStream >> sbcm;
//       m_visibleBlocks->append(&sbcm);
//     }
  }


  /**
   * @description This method will be used when the matrix is too big to display the whole thing.
   * It will read in the block we want to see and the two blocks for the diagonals that belong to
   * the right images.
   */
  void CorrelationMatrix::getThreeVisibleBlocks() {
  }


  /**
   * @brief Get the visible part of the matrix.
   * @return @b QList Returns a list of the non-empty diagonal blocks of the correlation matrix.
   */
  QList<SparseBlockColumnMatrix> *CorrelationMatrix::visibleBlocks() {
    return m_visibleBlocks;
  }


  /**
   * @description This method creates a Pvl group with the information necessary to recreate
   * this correlation matrix.
   *
   * Object = CorrelationMatrixData
   *   CovarianceMatrixFileName = /location/covarianceTmpFileName.dat
   *   CorrelationMatrixFileName = /location/correlationTmpFileName.dat
   * 
   *   Group = ImagesAndParameters
   *     Image1Name = "Param1, Param2, ..., ParamN"
   *     ...
   *     ImageNName = "..."
   *   End_Group
   * End_Object
   * 
   * @return @b PvlGroup Returns the information needed to recreate this correlation matrix.
   */
  PvlObject CorrelationMatrix::pvlObject() {
    PvlObject corrMatInfo("CorrelationMatrixData");
    
    corrMatInfo += PvlKeyword( "CovarianceMatrixFileName", m_covarianceFileName->expanded() );
    corrMatInfo += PvlKeyword( "CorrelationMatrixFileName", m_correlationFileName->expanded() );

    PvlGroup imgsAndParams("ImagesAndParameters");
    QMapIterator<QString, QStringList> imgParamIt(*m_imagesAndParameters);
    while ( imgParamIt.hasNext() ) {
      imgParamIt.next();
      imgsAndParams += PvlKeyword( imgParamIt.key(), imgParamIt.value().join(",") );
    }
    corrMatInfo += imgsAndParams;
    
    return corrMatInfo;
  }


  /**
   * @brief Writes CorrelationMatrix data to the output stream and returns this stream
   * to the user.
   * @param stream  The input stream containing the data.
   * @return @b QDataStream Returns the output stream.
   */

  QDataStream &CorrelationMatrix::write(QDataStream &stream) const {
    // QMaps
    stream << *m_imagesAndParameters;
    // FileNames
    stream << m_covarianceFileName->expanded() << m_correlationFileName->expanded();
    // QLists
    stream << *m_diagonals << *m_visibleBlocks;
    return stream;
  }


  /**
   * @brief Reads CorrelationMatrix data from the input stream and places the data
   * in member variables.
   * @param stream  The input input stream containing the data.
   * @return @b QDataStream Returns the output data stream.
   */
    QDataStream &CorrelationMatrix::read(QDataStream &stream) {
    // QMaps
    QMap<QString, QStringList> imagesAndParameters;
    stream >> imagesAndParameters;
    delete m_imagesAndParameters;
    m_imagesAndParameters = NULL;
    m_imagesAndParameters = new QMap<QString, QStringList>(imagesAndParameters);

    // FileNames
    QString covarianceFileName;
    stream >> covarianceFileName;
    delete m_covarianceFileName;
    m_covarianceFileName = NULL;
    m_covarianceFileName  = new FileName(covarianceFileName);

    QString correlationFileName;
    stream >> correlationFileName;
    delete m_correlationFileName;
    m_correlationFileName = NULL;
    m_correlationFileName = new FileName(correlationFileName);

    // QLists
    QList<double> diagonals;
    stream >> diagonals;
    delete m_diagonals;
    m_diagonals = NULL;
    m_diagonals = new QList<double>(diagonals);

    QList<SparseBlockColumnMatrix> visibleBlocks;
    stream >> visibleBlocks;
    delete m_visibleBlocks;
    m_visibleBlocks = NULL;
    m_visibleBlocks = new QList<SparseBlockColumnMatrix>(visibleBlocks);

    return stream;
  }


  /**
   * @brief The operator <<  writes matrix data to a QDataStream.
   * @param stream The output stream upon which the matrix data is written.
   * @param matrix The CorrelationMatrix containing the data.
   * @return @b QDataStream Returns the output stream containing the matrix data.
   */
  QDataStream &operator<<(QDataStream &stream, const CorrelationMatrix &matrix) {
    return matrix.write(stream);
  }


  /**
   * @brief The operator >> reads matrix data from a QDataStream.
   * @param stream  The input stream containing the CorrelationMatrix data.
   * @param matrix  The matrix which is going to be overwritten by the input stream.
   * @return @b QDataStream Returns the output stream containing the matrix data.
   */
  QDataStream &operator>>(QDataStream &stream, CorrelationMatrix &matrix) {
    return matrix.read(stream);
  }
}
+137 −0
Original line number Diff line number Diff line
#ifndef CorrelationMatrix_h
#define CorrelationMatrix_h

/**
 * @file
 *   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 <QDebug>
#include <QList>
#include <QMap>
#include <QString>
#include <QStringList>

#include <boost/numeric/ublas/matrix_sparse.hpp>

template <typename A, typename B> class QMap;
template <typename A> class QList;

namespace Isis {
  class FileName;
  class MosaicSceneWidget;
  class PvlObject;
  class SparseBlockColumnMatrix;


  /**
   * @brief This is a container for the correlation matrix that comes from a bundle adjust
   *
   * The bundle adjust will output the covariance matrix to a file. This class will read that file
   * in and compute the correlation matrix. The entire correlation matrix will be written to a file
   * and values will be read/displayed on an as-needed basis.
   *
   * @ingroup Visualization Tools
   *
   * @author 2014-05-02 Kimberly Oyama
   *
   * @internal
   *   @history 2014-05-02 Kimberly Oyama - Original version.
   *   @history 2014-07-23 Jeannie Backer - Added QDataStream >> and << operators and read/write
   *                           methods. Created unitTest. Added new operators to assignments in
   *                           copy constructor and operator= methods.
   *   @history 2015-10-14 Jeffrey Covington - Declared CorrelationMatrix as a
   *                           Qt metatype for use with QVariant.
   *   @history 2016-06-06 Tyler Wilson - Fixed a problem with a PvlKeywordIterator not
   *                           being incremented in the constructor which accepts a PvlObject.
   *                           There was also an issue with a QMap data structure not being
   *                           initialized, resulting in a segmentation fault.  Also added
   *                           testing for exceptions being thrown in this constructor,
   *                           as well as the function computeCorrelationMatrix. Fixes #3997,3999.
   */
  class CorrelationMatrix {
    public:
      CorrelationMatrix();
      CorrelationMatrix(PvlObject storedMatrixData);
      CorrelationMatrix(const CorrelationMatrix &other);
      ~CorrelationMatrix();
      
      CorrelationMatrix &operator=(const CorrelationMatrix &other);

      void computeCorrelationMatrix();
      void retrieveVisibleElements(int x, int y);

      bool isValid();
      bool hasCovMat();
     //const bool hasCovMat() const;

      void setCorrelationFileName(FileName correlationFileName);
      void setCovarianceFileName(FileName covarianceFileName);
      void setImagesAndParameters(QMap<QString, QStringList> imagesAndParameters);

      SparseBlockColumnMatrix correlationMatrixFromFile(QDataStream inStream);
      //might need something called deleteLater(), called from MatrixTreeWidgetItem constructor.

      //if cov filename is null we need to ask the user to find it.

      FileName correlationFileName();
      FileName covarianceFileName();
      QMap<QString, QStringList> *imagesAndParameters();

      void getWholeMatrix();
      void getThreeVisibleBlocks();

      // Need these for range used to pick colors....
      QList<SparseBlockColumnMatrix> *visibleBlocks();

      PvlObject pvlObject();

      QDataStream &write(QDataStream &stream) const;
      QDataStream &read(QDataStream &stream);

    private:
      //! This map holds the images used to create this matrix and their associated parameters.
      QMap<QString, QStringList> *m_imagesAndParameters;

      //! FileName of the covariance matrix calculated when the bundle was run.
      FileName *m_covarianceFileName;

      //! FileName of the correlation matrix
      FileName *m_correlationFileName;

      /**
       * List of the parameter values. Stored so we don't need to store all the SBCMs when
       * calculating the correlation values.
       */
      QList<double> *m_diagonals;

      /**
       * This will be the three blocks (or whole matrix depending on size) that apply to
       * the given area.
       */
      QList<SparseBlockColumnMatrix> *m_visibleBlocks;
  };
  // operators to read/write CorrelationMatrix to/from binary disk file
  QDataStream &operator<<(QDataStream &stream, const CorrelationMatrix &matrix);
  QDataStream &operator>>(QDataStream &stream, CorrelationMatrix &matrix);
};

Q_DECLARE_METATYPE(Isis::CorrelationMatrix);

#endif
+87 −0

File added.

Preview size limit exceeded, changes collapsed.

+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
Loading