Commit 1394dedd authored by Tracie Sucharski's avatar Tracie Sucharski
Browse files

Update ecub labels after bundle adjust,allow ecub in results project tree node...

Update ecub labels after bundle adjust,allow ecub in results project tree node to point to dn file in image project tree node using relative paths so that projects can be re-located. Save the BundleSolutionInfo files when executing a 'Save As' operation and serialize using relative paths. Fixes #4804, #4849, #5104, #5210, #5276, #5289.

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/branches/ipce@8338 41f8697f-d340-4b68-9986-7bafba869bb8
parent a5b1dc94
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <unistd.h>

#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QMutex>
@@ -551,6 +552,7 @@ namespace Isis {
    // Figure out the name of the data file
    try {
      PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
      // Detached labels
      if (core.hasKeyword("^Core")) {
        FileName temp(core["^Core"][0]);

@@ -566,6 +568,7 @@ namespace Isis {

        m_dataFile = new QFile(realDataFileName().expanded());
      }
      // External cube files (ecub), ecub contains all labels and SPICE blobs, history
      else if (core.hasKeyword("^DnFile")) {
        FileName dataFileName(core["^DnFile"][0]);

@@ -578,9 +581,10 @@ namespace Isis {

        m_attached = true;
        m_storesDnData = false;

        *m_dataFileName = FileName(realDataFileName().expanded());
        m_dataFile = new QFile(realDataFileName().expanded());
      }
      // Typical cube containing labels, SPICE, history and dn data
      else {
        m_dataFileName = new FileName(*m_labelFileName);
        m_attached = true;
@@ -1840,7 +1844,16 @@ namespace Isis {
    else if (!m_storesDnData) {
      ASSERT(m_dataFileName);
      FileName guess = *m_dataFileName;
      QDir dir(guess.toString());

      // If path is relative and there is a labelFileName, start in directory of the ecub, then
      // cd to the directory containing the DnFile, since it is relative to the location of the ecub.
      // We need to turn the relative path into an absolute path.
      if (dir.isRelative() && m_labelFileName) {
        QDir dir2(m_labelFileName->originalPath());
        dir2.cd(guess.path());
        guess = dir2.absolutePath() + "/" + guess.name();
      }
      do {
        Pvl guessLabel(guess.expanded());

@@ -2079,7 +2092,7 @@ namespace Isis {

        FileName temp((*core)["^DnFile"][0]);
        if (!temp.expanded().startsWith("/")) {
          temp = FileName(FileName(label.fileName()).path() + "/" + temp.original());
          temp = realDataFileName();
        }

        label = Pvl(temp.toString());
+5 −0
Original line number Diff line number Diff line
@@ -157,6 +157,11 @@ namespace Isis {
   *   @history 2017-06-08 Chris Combs - Made "Failed to create" error messages more descriptive.
   *                           Fixes #833.
   *   @history 2017-09-22 Cole Neubauer - Fixed documentation. References #4807
   *   @history 2018-01-04 Tracie Sucharski - Allow relative paths that are not "." in the DnFile
   *                           keyword for ecubs. Changes to ::open to set m_dataFileName for ecubs,
   *                           and changed ::realDataFileName() to return the absolute path if it is
   *                           relative. Changed ::realDataFileLabel to call realDataFileName to
   *                           make sure we get absolute path.  Fixes #5276.
   */
  class Cube {
    public:
+145 −33
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

#include <QDataStream>
#include <QDebug>
#include <QFile>
#include <QList>
#include <QString>
#include <QStringList>
@@ -50,6 +51,8 @@ namespace Isis {
    m_statisticsResults = new BundleResults(outputStatistics);

    m_images = new QList<ImageList *>(imgList);

    m_adjustedImages = new QList<ImageList *>;
  }


@@ -71,6 +74,7 @@ namespace Isis {
    m_statisticsResults = NULL;
    // what about the rest of the member data ? should we set defaults ??? CREATE INITIALIZE METHOD
    m_images = new QList<ImageList *>;
    m_adjustedImages = new QList<ImageList *>;

    xmlReader->setErrorHandler(new XmlHandler(this, project));
    xmlReader->pushContentHandler(new XmlHandler(this, project));
@@ -90,6 +94,7 @@ namespace Isis {
        m_settings(new BundleSettings(*src.m_settings)),
        m_statisticsResults(new BundleResults(*src.m_statisticsResults)),
        m_images(new QList<ImageList *>(*src.m_images)),
        m_adjustedImages(new QList<ImageList *>(*src.m_adjustedImages)),
        m_csvSavedImagesFilename(src.m_csvSavedImagesFilename),
        m_csvSavedPointsFilename(src.m_csvSavedPointsFilename),
        m_csvSavedResidualsFilename(src.m_csvSavedResidualsFilename) {
@@ -112,6 +117,13 @@ namespace Isis {
      delete m_images;
      m_images = NULL;
    }

    // if (m_adjustedImages != NULL) {
    //   qDeleteAll(*m_adjustedImages);
    //   m_adjustedImages->clear();
    //   delete m_adjustedImages;
    //   m_adjustedImages = NULL;
    // }
  }


@@ -148,6 +160,9 @@ namespace Isis {

      delete m_images;
      m_images = new QList<ImageList *>(*src.m_images);

      delete m_adjustedImages;
      m_adjustedImages = new QList<ImageList *>(*src.m_adjustedImages);
    }
    return *this;
  }
@@ -164,6 +179,17 @@ namespace Isis {
    return m_csvSavedResidualsFilename;
  }


  /**
   * Adds a list of images that were adjusted (their labels were updated).
   *
   * @param ImageList *images The list of images to add that had their labels updated.
   */
  void BundleSolutionInfo::addAdjustedImages(ImageList *images) {
    m_adjustedImages->append(images);
  }


  /**
   * Sets the stat results.
   *
@@ -197,6 +223,17 @@ namespace Isis {
  }


  /**
   * Returns the list of images that were adjusted after a bundle. This can potentially be an
   * empty QList if no image labels were updated.
   *
   * @return QList<ImageList*> Returns the adjusted images (images with updated labels).
   */
  QList<ImageList *> BundleSolutionInfo::adjustedImages() const {
    return *m_adjustedImages;
  }


  /**
   * Get a unique, identifying string associated with this BundleSolutionInfo object.
   *
@@ -1460,21 +1497,85 @@ namespace Isis {
   *
   * @param stream The stream to which the BundleSolutionInfo will be saved
   * @param project The project to which this BundleSolutionInfo will be saved
   * @param newProjectRoot The location of the project root directory. This is not used.
   * @param newProjectRoot The location of the project root directory.
   */
  void BundleSolutionInfo::save(QXmlStreamWriter &stream, const Project *project,
                                FileName newProjectRoot) const {

    // This is done for unitTest which has no Project
    QString relativeBundlePath;
    FileName bundleSolutionInfoRoot;

    if (project) {
      bundleSolutionInfoRoot = FileName(Project::bundleSolutionInfoRoot(newProjectRoot.expanded()) +
                                      "/" + runTime());
      QString oldPath = project->bundleSolutionInfoRoot(project->projectRoot()) + "/" + runTime();
      QString newPath = project->bundleSolutionInfoRoot(newProjectRoot.toString()) + "/" + runTime();
      //  If project is being saved to new area, create directory and copy files
      if (oldPath != newPath) {
        //  Create project folder for BundleSolutionInfo
        QDir bundleDir(newPath);
        if (!bundleDir.mkpath(bundleDir.path())) {
          throw IException(IException::Io,
                           QString("Failed to create directory [%1]")
                             .arg(bundleSolutionInfoRoot.path()),
                           _FILEINFO_);
        }
        QString oldFile = oldPath + "/" + m_controlNetworkFileName->name();
        QString newFile = newPath + "/" + m_controlNetworkFileName->name();
        //QString outputControlFile = m_statisticsResults->outputControlNet()->
        if (!QFile::copy(oldFile, newFile)) {
          throw IException(IException::Io,
                           QString("Failed to copy file [%1] to new file [%2]")
                             .arg(m_controlNetworkFileName->name()).arg(newFile),
                           _FILEINFO_);        
        }
        newFile = newPath + "/" + FileName(m_csvSavedImagesFilename).name();
        if (!QFile::copy(m_csvSavedImagesFilename, newFile)) {
          throw IException(IException::Io,
                           QString("Failed to copy file [%1] to new file [%2]")
                             .arg(m_csvSavedImagesFilename).arg(newFile),
                           _FILEINFO_);        
        }
        newFile = newPath + "/" + FileName(m_csvSavedPointsFilename).name();
        if (!QFile::copy(m_csvSavedPointsFilename, newFile)) {
          throw IException(IException::Io,
                           QString("Failed to copy file [%1] to new file [%2]")
                             .arg(m_csvSavedPointsFilename).arg(newFile),
                           _FILEINFO_);        
        }
        newFile = newPath + "/" + FileName(m_csvSavedResidualsFilename).name();
        if (!QFile::copy(m_csvSavedResidualsFilename, newFile)) {
          throw IException(IException::Io,
                           QString("Failed to copy file [%1] to new file [%2]")
                             .arg(m_csvSavedResidualsFilename).arg(newFile),
                           _FILEINFO_);        
        }
      }

      // Create relative path for bundleSolutionInfo
      relativeBundlePath = newPath.remove(project->newProjectRoot());
      // Get rid of any preceding "/" , but add on ending "/"
      if (relativeBundlePath.startsWith("/")) {
        relativeBundlePath.remove(0,1);
      }
      relativeBundlePath += "/";
    }

    stream.writeStartElement("bundleSolutionInfo");
    // save ID, cnet file name, and run time to stream
    stream.writeStartElement("generalAttributes");
    stream.writeTextElement("id", m_id->toString());
    stream.writeTextElement("name", m_name);
    stream.writeTextElement("runTime", runTime());
    stream.writeTextElement("fileName", m_controlNetworkFileName->expanded());
    stream.writeTextElement("imagesCSV", m_csvSavedImagesFilename);
    stream.writeTextElement("pointsCSV", m_csvSavedPointsFilename);
    stream.writeTextElement("residualsCSV", m_csvSavedResidualsFilename);
    stream.writeTextElement("fileName",
                            relativeBundlePath + m_controlNetworkFileName->name());
    stream.writeTextElement("imagesCSV",
                            relativeBundlePath + FileName(m_csvSavedImagesFilename).name());
    stream.writeTextElement("pointsCSV",
                            relativeBundlePath + FileName(m_csvSavedPointsFilename).name());
    stream.writeTextElement("residualsCSV",
                            relativeBundlePath + FileName(m_csvSavedResidualsFilename).name());
    stream.writeEndElement(); // end general attributes

    // save settings to stream
@@ -1483,18 +1584,16 @@ namespace Isis {
    // save statistics to stream
    m_statisticsResults->save(stream, project);

    // save image lists to stream
    if ( !m_images->isEmpty() ) {
    if (project) {
      // save adjusted images lists to stream
      if (!m_adjustedImages->isEmpty()) {
        stream.writeStartElement("imageLists");

      FileName newResultsRoot(Project::bundleSolutionInfoRoot(newProjectRoot.expanded()) +
                              "/" + runTime());
      for (int i = 0; i < m_images->count(); i++) {
        m_images->at(i)->save(stream, project, newResultsRoot);
        for (int i = 0; i < m_adjustedImages->count(); i++) {
          m_adjustedImages->at(i)->save(stream, project, bundleSolutionInfoRoot);
        }

        stream.writeEndElement();
      }
    }
    stream.writeEndElement(); //end bundleSolutionInfo
  }

@@ -1557,10 +1656,13 @@ namespace Isis {
            BundleSettingsQsp(new BundleSettings(m_xmlHandlerProject, reader()));
      }
      else if (localName == "bundleResults") {
        m_xmlHandlerBundleSolutionInfo->m_statisticsResults = new BundleResults(m_xmlHandlerProject, reader());
        m_xmlHandlerBundleSolutionInfo->m_statisticsResults = new BundleResults(m_xmlHandlerProject,
                                                                                reader());
      }
      else if (localName == "imageList") {
        m_xmlHandlerBundleSolutionInfo->m_images->append(new ImageList(m_xmlHandlerProject, reader()));
        // m_xmlHandlerBundleSolutionInfo->m_images->append(new ImageList(m_xmlHandlerProject, reader()));
        m_xmlHandlerBundleSolutionInfo->m_adjustedImages->append(
            new ImageList(m_xmlHandlerProject, reader()));
      }
    }
    return true;
@@ -1579,6 +1681,12 @@ namespace Isis {
  bool BundleSolutionInfo::XmlHandler::endElement(const QString &namespaceURI,
                                                  const QString &localName,
                                                  const QString &qName) {
    // This is done for unitTest which has no Project
    QString projectRoot;
    if (m_xmlHandlerProject) {
      projectRoot = m_xmlHandlerProject->projectRoot() + "/";
    }

    if (localName == "id") {
      // all constructors assign a Uuid - we need to give it a one from the XML
      assert(m_xmlHandlerBundleSolutionInfo->m_id);
@@ -1593,16 +1701,20 @@ namespace Isis {
    }
    else if (localName == "fileName") {
      assert(m_xmlHandlerBundleSolutionInfo->m_controlNetworkFileName == NULL);
      m_xmlHandlerBundleSolutionInfo->m_controlNetworkFileName = new FileName(m_xmlHandlerCharacters);
      m_xmlHandlerBundleSolutionInfo->m_controlNetworkFileName = new FileName(
        projectRoot + m_xmlHandlerCharacters);
    }
    else if (localName == "imagesCSV") {
      m_xmlHandlerBundleSolutionInfo->m_csvSavedImagesFilename = m_xmlHandlerCharacters;
      m_xmlHandlerBundleSolutionInfo->m_csvSavedImagesFilename = 
        projectRoot + m_xmlHandlerCharacters;
    }
    else if (localName == "pointsCSV") {
      m_xmlHandlerBundleSolutionInfo->m_csvSavedPointsFilename = m_xmlHandlerCharacters;
      m_xmlHandlerBundleSolutionInfo->m_csvSavedPointsFilename =
        projectRoot + m_xmlHandlerCharacters;
    }
    else if (localName == "residualsCSV") {
      m_xmlHandlerBundleSolutionInfo->m_csvSavedResidualsFilename = m_xmlHandlerCharacters;
      m_xmlHandlerBundleSolutionInfo->m_csvSavedResidualsFilename =
        projectRoot + m_xmlHandlerCharacters;
    }

    m_xmlHandlerCharacters = "";
+14 −1
Original line number Diff line number Diff line
@@ -106,6 +106,16 @@ namespace Isis {
   *                           Fixes #4804, #4837.
   *   @history 2017-07-11 Makayla Shepherd - Added bundle naming capabilities. Fixes #4855.
   *   @history 2017-07-28 Makayla Shepherd - Fixed the default naming tag. Fixes #5069.
   *   @history 2017-08-09 Ian Humphrey - Added m_adjustedImages with setters and getters so the
   *                           BundleSolutionInfo can know which images have been adjusted (Updated
   *                           labels). References #4849.
   *   @history 2017-10-30 Tracie Sucharski - In ::save method, if the newProjectRoot is different
   *                           from the current projectRoot, save the cnet and csv files and
   *                           create the directory structure.
   *   @history 2017-12-20 Tracie Sucharski - Fixed bug which was saving the bundle adjust input
   *                           control net rather than the output control net.  References #4804.
   *   @history 2017-01-03 Tracie Sucharski - Changed serialization to use relative paths.
   *                           Fixes #5104.
   */
  class BundleSolutionInfo : public QObject {
    Q_OBJECT
@@ -126,10 +136,12 @@ namespace Isis {
      QString savedPointsFilename();
      QString savedResidualsFilename();

      void addAdjustedImages(ImageList *images);
      void setOutputStatistics(BundleResults statisticsResults);
      void setRunTime(QString runTime);
      void setName(QString name);

      QList<ImageList *> adjustedImages() const;
      QString id() const;
      QString controlNetworkFileName() const;
      BundleSettingsQsp bundleSettings();
@@ -193,7 +205,8 @@ namespace Isis {
      FileName           *m_controlNetworkFileName; //!< The name of the control network
      BundleSettingsQsp   m_settings; //!< The settings from the bundle adjust
      BundleResults      *m_statisticsResults; //!< The results of the bundle adjust
      QList<ImageList *> *m_images; //!< The list of images that were adjusted
      QList<ImageList *> *m_images; //!< The list of images as input to the bundle
      QList<ImageList *> *m_adjustedImages; //!< The list of images that were adjsuted

      // In theory the path in the BundlesSettings can change while running.  So we save the
      // filenames actually used when the most recent save of the file was done.
+9 −7
Original line number Diff line number Diff line
@@ -658,15 +658,16 @@ namespace Isis {

      //If the currently open project is a project that has been saved and is not within the current
      //list of recently open projects, then remove the oldest project from the list.
      if (!project->projectPath().contains("tmpProject") && !projectPaths.contains(project->projectPath()) ) {
      if (!project->projectRoot().contains("tmpProject") &&
          !projectPaths.contains(project->projectRoot()) ) {
        QString s=keys.first();
        recentProjects.remove( s );
      }

      //If the currently open project is already contained within the list,
      //then remove the earlier reference.
      if (projectPaths.contains(project->projectPath())) {
        QString key = recentProjects.key(project->projectPath());
      if (projectPaths.contains(project->projectRoot())) {
        QString key = recentProjects.key(project->projectRoot());
        recentProjects.remove(key);

      }
@@ -685,8 +686,8 @@ namespace Isis {
      QString t0String=QString::number(t0);

      //Save the project location
      if (!project->projectPath().contains("tmpProject") ) {
              globalSettings.setValue(t0String+"%%%%%"+projName,project->projectPath());
      if (!project->projectRoot().contains("tmpProject") ) {
              globalSettings.setValue(t0String+"%%%%%"+projName,project->projectRoot());
      }
    }

@@ -697,8 +698,9 @@ namespace Isis {
      QString projName = project->name();
      QString t0String=QString::number(t0);

      if (!project->projectPath().contains("tmpProject") && !projectPaths.contains( project->projectPath() ) ) {
        globalSettings.setValue(t0String+"%%%%%"+projName,project->projectPath());
      if (!project->projectRoot().contains("tmpProject") &&
          !projectPaths.contains( project->projectRoot())) {
        globalSettings.setValue(t0String+"%%%%%"+projName,project->projectRoot());
      }
    }
    globalSettings.endGroup();
Loading