Unverified Commit 809981ad authored by acpaquette's avatar acpaquette Committed by GitHub
Browse files

Autoseed, Footprintinit, and 1/2 of Findimageoverlaps (#3688)

* Initial stab at converting autoseed which includes findimageoverlaps and footprintinit (eventually)

* Finished autoseed test and added footprintinit test

* Finished autoseed and footprintinit tests

* Updated autoseed, and tests and addressed PR feedback

* Updated footprintinit from feedback

* Updated findimageoverlaps based on feedback

* Moved enum into the namespace

* Adding overlaps list file to data, fixtures, and tests

* Fixed path pointing to the wrong file

* Finished last autoseed test

* Updated autoseed test

* Removed unnecessary temp file and renamed footprintinit test
parent f33e9bf6
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
#include "findimageoverlaps.h"

#include "Application.h"
#include "FileList.h"
#include "ImageOverlapSet.h"
#include "Pvl.h"
#include "SerialNumber.h"
#include "SerialNumberList.h"

using namespace std;

namespace Isis {

  void findimageoverlaps(UserInterface &ui, Pvl *log) {
    FileList images(ui.GetFileName("FROMLIST"));

    findimageoverlaps(images, ui, log);
  }

  void findimageoverlaps(FileList &images, UserInterface &ui, Pvl *log) {
    // list of sns/filenames sorted by serial number
    SerialNumberList serialNumbers(true);

    vector< pair<QString, QString> > sortedList;

    if (images.size() == 1) {
      throw IException(IException::User, "The list [" + ui.GetFileName("FROMLIST") +
                       "] only contains one image.", _FILEINFO_);
    }

    // We want to sort the input data by serial number so that the same
    //   results are produced every time this program is run with the same
    //   images. This is a modified insertion sort.
    for (int image = 0; image < images.size(); image++) {
      unsigned int insertPos = 0;
      QString sn = SerialNumber::Compose(images[image].toString());
      for (insertPos = 0; insertPos < sortedList.size(); insertPos++) {
        if (sn.compare(sortedList[insertPos].first) < 0) break;
      }
      pair<QString, QString> newPair = pair<QString, QString>(sn, images[image].toString());
      sortedList.insert(sortedList.begin() + insertPos, newPair);
    }

    // Add the serial numbers in sorted order now
    for (unsigned int i = 0; i < sortedList.size(); i++) {
      serialNumbers.add(sortedList[i].second);
    }

    // Now we want the ImageOverlapSet to calculate our overlaps
    ImageOverlapSet overlaps(true);

    // Use multi-threading to create the overlaps
    overlaps.FindImageOverlaps(serialNumbers,
                               FileName(ui.GetFileName("OVERLAPLIST")).expanded());

    // This will only occur when "CONTINUE" is true, so we can assume "ERRORS" was
    //   an entered parameter.
    if (overlaps.Errors().size() != 0 && ui.WasEntered("ERRORS")) {
      Pvl outFile;

      bool filenamesOnly = !ui.GetBoolean("DETAILED");

      vector<PvlGroup> errorList = overlaps.Errors();

      for (unsigned int err = 0; err < errorList.size(); err++) {
        if (!filenamesOnly) {
          outFile += errorList[err];
        }
        else if (errorList[err].hasKeyword("FileNames")) {
          PvlGroup origError = errorList[err];
          PvlGroup err("ImageOverlapError");

          for (int keyword = 0; keyword < origError.keywords(); keyword++) {
            if (origError[keyword].name() == "FileNames") {
              err += origError[keyword];
            }
          }

          outFile += err;
        }
      }

      outFile.write(FileName(ui.GetFileName("ERRORS")).expanded());
    }

    PvlGroup results("Results");
    results += PvlKeyword("ErrorCount", toString((BigInt)overlaps.Errors().size()));

    if (log) {
      log->addGroup(results);
    }
  }
}
+14 −0
Original line number Diff line number Diff line
#ifndef findimageoverlaps_h
#define findimageoverlaps_h

#include "FileList.h"
#include "Pvl.h"
#include "UserInterface.h"

namespace Isis {
  extern void findimageoverlaps(UserInterface &ui, Pvl *log=nullptr);

  extern void findimageoverlaps(FileList &images, UserInterface &ui, Pvl *log=nullptr);
}

#endif
+13 −69
Original line number Diff line number Diff line
#include "Isis.h"

#include "FileList.h"
#include "ImageOverlapSet.h"
#include "SerialNumber.h"
#include "SerialNumberList.h"
#include "findimageoverlaps.h"

#include "UserInterface.h"

using namespace std;
using namespace Isis;

void IsisMain() {
  UserInterface &ui = Application::GetUserInterface();
  SerialNumberList serialNumbers(true);

  FileList images(ui.GetFileName("FROMLIST"));
  // list of sns/filenames sorted by serial number

  vector< pair<QString, QString> > sortedList;
  
  if (images.size() == 1) {
    throw IException(IException::User, "The list [" + ui.GetFileName("FROMLIST") +
                     "] only contains one image.", _FILEINFO_);
  }

  // We want to sort the input data by serial number so that the same
  //   results are produced every time this program is run with the same
  //   images. This is a modified insertion sort.
  for (int image = 0; image < images.size(); image++) {
    unsigned int insertPos = 0;
    QString sn = SerialNumber::Compose(images[image].toString());
    for (insertPos = 0; insertPos < sortedList.size(); insertPos++) {
      if (sn.compare(sortedList[insertPos].first) < 0) break;
    }
    pair<QString, QString> newPair = pair<QString, QString>(sn, images[image].toString());
    sortedList.insert(sortedList.begin() + insertPos, newPair);
  }
  
  // Add the serial numbers in sorted order now
  for (unsigned int i = 0; i < sortedList.size(); i++) {
    serialNumbers.add(sortedList[i].second);
  }
  Pvl appLog;
  
  // Now we want the ImageOverlapSet to calculate our overlaps
  ImageOverlapSet overlaps(true);
  
  // Use multi-threading to create the overlaps
  overlaps.FindImageOverlaps(serialNumbers, 
                             FileName(ui.GetFileName("OVERLAPLIST")).expanded());
  
  // This will only occur when "CONTINUE" is true, so we can assume "ERRORS" was
  //   an entered parameter.
  if (overlaps.Errors().size() != 0 && ui.WasEntered("ERRORS")) {
    Pvl outFile;

    bool filenamesOnly = !ui.GetBoolean("DETAILED");

    vector<PvlGroup> errorList = overlaps.Errors();

    for (unsigned int err = 0; err < errorList.size(); err++) {
      if (!filenamesOnly) {
        outFile += errorList[err];
  try {
    findimageoverlaps(ui, &appLog);
  }
      else if (errorList[err].hasKeyword("FileNames")) {
        PvlGroup origError = errorList[err];
        PvlGroup err("ImageOverlapError");

        for (int keyword = 0; keyword < origError.keywords(); keyword++) {
          if (origError[keyword].name() == "FileNames") {
            err += origError[keyword];
  catch (...) {
    for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) {
      Application::Log(*grpIt);
    }
    throw;
  }

        outFile += err;
      }
  for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) {
    Application::Log(*grpIt);
  }

    outFile.write(FileName(ui.GetFileName("ERRORS")).expanded());
  }

  PvlGroup results("Results");
  results += PvlKeyword("ErrorCount", toString((BigInt)overlaps.Errors().size()));
  Application::Log(results);
}
+157 −0
Original line number Diff line number Diff line
#include "footprintinit.h"

#include "Application.h"
#include "IException.h"
#include "ImagePolygon.h"
#include "PolygonTools.h"
#include "Process.h"
#include "Progress.h"
#include "PvlGroup.h"
#include "SerialNumber.h"
#include "Target.h"
#include "TProjection.h"


using namespace std;

namespace Isis {

  void footprintinit(UserInterface &ui, Pvl *log) {
    Cube cube;
    cube.open(ui.GetFileName("FROM"), "rw");

    footprintinit(&cube, ui, log);
    cube.close();
  }

  void footprintinit(Cube *cube, UserInterface &ui, Pvl *log) {
    bool testXY = ui.GetBoolean("TESTXY");

    // Make sure cube has been run through spiceinit
    try {
      cube->camera();
    }
    catch (IException &e) {
      if (!cube->projection()) {
        string msg = "Spiceinit must be run before initializing the polygon";
        throw IException(e, IException::User, msg, _FILEINFO_);
      }
      testXY = false;
    }

    Progress prog;
    prog.SetMaximumSteps(1);
    prog.CheckStatus();

    QString sn = SerialNumber::Compose(*cube);

    ImagePolygon poly;
    if (ui.WasEntered("MAXEMISSION")) {
      poly.Emission(ui.GetDouble("MAXEMISSION"));
    }
    if (ui.WasEntered("MAXINCIDENCE")) {
      poly.Incidence(ui.GetDouble("MAXINCIDENCE"));
    }
    if (ui.GetString("LIMBTEST") == "ELLIPSOID") {
      poly.EllipsoidLimb(true);
    }

    int sinc = 1;
    int linc = 1;
    IString incType = ui.GetString("INCTYPE");
    if (incType.UpCase() == "VERTICES") {
      poly.initCube(*cube);
      sinc = linc = (int)(0.5 + (((poly.validSampleDim() * 2) +
                         (poly.validLineDim() * 2) - 3.0) /
                         ui.GetInteger("NUMVERTICES")));
      if (sinc < 1.0 || linc < 1.0)
        sinc = linc = 1.0;
    }
    else if (incType.UpCase() == "LINCSINC"){
      sinc = ui.GetInteger("SINC");
      linc = ui.GetInteger("LINC");
    }
    else {
      string msg = "Invalid INCTYPE option[" + incType + "]";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    bool precision = ui.GetBoolean("INCREASEPRECISION");
    try {
      poly.Create(*cube, sinc, linc, 1, 1, 0, 0, 1, precision);
    }
    catch (IException &e) {
      QString msg = "Cannot generate polygon for [" + ui.GetFileName("FROM") + "]";
      throw IException(e, IException::User, msg, _FILEINFO_);
    }

    if (testXY) {
      Pvl map(ui.GetFileName("MAP"));
      PvlGroup &mapGroup = map.findGroup("MAPPING");

      Pvl cubeLab(ui.GetFileName("FROM"));
      // This call adds TargetName, EquatorialRadius and PolarRadius to mapGroup
      mapGroup = Target::radiiGroup(cubeLab, mapGroup);
      // add/replace the rest of the keywords
      mapGroup.addKeyword( PvlKeyword("LatitudeType", "Planetocentric"),
                           PvlContainer::Replace );
      mapGroup.addKeyword( PvlKeyword("LongitudeDirection", "PositiveEast"),
                           PvlContainer::Replace );
      mapGroup.addKeyword( PvlKeyword("LongitudeDomain", "360"),
                           PvlContainer::Replace );
      mapGroup.addKeyword( PvlKeyword("CenterLatitude", "0.0"),
                           PvlContainer::Replace );
      mapGroup.addKeyword( PvlKeyword("CenterLongitude", "0.0"),
                           PvlContainer::Replace);

      sinc = poly.getSinc();
      linc = poly.getLinc();
      bool polygonGenerated = false;
      while (!polygonGenerated) {
        TProjection *proj = NULL;
        geos::geom::MultiPolygon *xyPoly = NULL;

        try {
          proj = (TProjection *) ProjectionFactory::Create(map, true);
          xyPoly = PolygonTools::LatLonToXY(*poly.Polys(), proj);

          polygonGenerated = true;
        }
        catch (IException &e) {
          if (precision && sinc > 1 && linc > 1) {
            sinc = sinc * 2 / 3;
            linc = linc * 2 / 3;
            poly.Create(*cube, sinc, linc);
          }
          else {
            delete proj;
            delete xyPoly;
            e.print(); // This should be a NAIF error
            QString msg = "Cannot calculate XY for [";
            msg += ui.GetFileName("FROM") + "]";
            throw IException(e, IException::User, msg, _FILEINFO_);
          }
        }

        delete proj;
        delete xyPoly;
      }
    }

    cube->deleteBlob("Polygon", sn);
    cube->write(poly);

    if (precision) {
      PvlGroup results("Results");
      results.addKeyword(PvlKeyword("SINC", toString(sinc)));
      results.addKeyword(PvlKeyword("LINC", toString(linc)));
      log->addGroup(results);
    }

    Process p;
    p.SetInputCube(cube);
    p.WriteHistory(*cube);

    prog.CheckStatus();
  }
}
+9 −0
Original line number Diff line number Diff line
#include "Cube.h"
#include "Pvl.h"
#include "UserInterface.h"

namespace Isis {
  extern void footprintinit(UserInterface &ui, Pvl *log=nullptr);

  extern void footprintinit(Cube *cube, UserInterface &ui, Pvl *log=nullptr);
}
Loading