From 411d802f71156a5d9a4ecc071e2882a4c289938c Mon Sep 17 00:00:00 2001 From: acpaquette Date: Tue, 10 Nov 2020 21:25:01 -0700 Subject: [PATCH] Cnetextract App and Test Update (#4109) * Convert cnetextract and update tests * Adds a check for bad app inputs * Disabled old tests * Updated cnetextract BadInput test to be three different tests --- .../control/apps/cnetextract/cnetextract.cpp | 856 +++++++++++++++++ .../control/apps/cnetextract/cnetextract.h | 38 + isis/src/control/apps/cnetextract/main.cpp | 875 +----------------- .../apps/cnetextract/tsts/basic/Makefile | 34 - .../apps/cnetextract/tsts/cubes/Makefile | 42 - .../apps/cnetextract/tsts/latlon/Makefile | 25 - .../cnetextract/tsts/noOutputNet/Makefile | 28 - .../apps/cnetextract/tsts/nofromlist/Makefile | 20 - .../apps/cnetextract/tsts/pointlist/Makefile | 26 - .../apps/cnetextract/tsts/reference/Makefile | 21 - .../tsts/reportsNotCreated/Makefile | 98 -- .../apps/cnetextract/tsts/tolerance/Makefile | 24 - isis/tests/FunctionalTestsCnetextract.cpp | 442 +++++++++ 13 files changed, 1347 insertions(+), 1182 deletions(-) create mode 100644 isis/src/control/apps/cnetextract/cnetextract.cpp create mode 100644 isis/src/control/apps/cnetextract/cnetextract.h delete mode 100644 isis/src/control/apps/cnetextract/tsts/basic/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/cubes/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/latlon/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/noOutputNet/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/nofromlist/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/pointlist/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/reference/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/reportsNotCreated/Makefile delete mode 100644 isis/src/control/apps/cnetextract/tsts/tolerance/Makefile create mode 100644 isis/tests/FunctionalTestsCnetextract.cpp diff --git a/isis/src/control/apps/cnetextract/cnetextract.cpp b/isis/src/control/apps/cnetextract/cnetextract.cpp new file mode 100644 index 0000000000..249481a133 --- /dev/null +++ b/isis/src/control/apps/cnetextract/cnetextract.cpp @@ -0,0 +1,856 @@ +#include "cnetextract.h" + +using namespace std; + +namespace Isis { + void ExtractPointList(ControlNet &outNet, QVector &nonListedPoints, FileName pointListFile); + void ExtractLatLonRange(ControlNet &outNet, QVector &nonLatLonPoints, + QVector &cannotGenerateLatLonPoints, + QMap sn2filename, + UserInterface &ui); + bool NotInLatLonRange(SurfacePoint surfacePt, Latitude minlat, + Latitude maxlat, Longitude minlon, Longitude maxlon); + void WriteCubeOutList(ControlNet cnet, + QMap sn2file, + PvlGroup &summary, + FileName toList); + void WriteResults(QString filename, + QVector notExtracted, + PvlGroup &results); + void omit(ControlNet &cnet, int cp); + void omit(ControlPoint *point, int cm); + + void cnetextract(UserInterface &ui, Pvl *log) { + ControlNet outNet(ui.GetFileName("CNET")); + + cnetextract(outNet, ui, log); + } + + + // Main program + void cnetextract(ControlNet outNet, UserInterface &ui, Pvl *log) { + if(!ui.WasEntered("FROMLIST") && ui.WasEntered("TOLIST")) { + QString msg = "To create a [TOLIST] the [FROMLIST] parameter must be provided."; + throw IException(IException::User, msg, _FILEINFO_); + } + + bool noIgnore = ui.GetBoolean("NOIGNORE"); + bool noMeasureless = ui.GetBoolean("NOMEASURELESS"); + bool noSingleMeasure = ui.GetBoolean("NOSINGLEMEASURES"); + bool reference = ui.GetBoolean("REFERENCE"); + bool fixed = ui.GetBoolean("FIXED"); + bool constrained = ui.GetBoolean("CONSTRAINED"); + bool editLocked = ui.GetBoolean("EDITLOCKED"); + bool noTolerancePoints = ui.GetBoolean("TOLERANCE"); + bool pointsEntered = ui.WasEntered("POINTLIST"); + bool cubePoints = ui.GetBoolean("CUBES"); + bool cubeMeasures = ui.GetBoolean("CUBEMEASURES"); + bool retainReference = ui.GetBoolean("RETAIN_REFERENCE"); + bool latLon = ui.GetBoolean("LATLON"); + + if(!(noIgnore || noMeasureless || noSingleMeasure || editLocked || reference || fixed || + noTolerancePoints || pointsEntered || cubePoints || constrained || latLon)) { + QString msg = "At least one filter must be selected ["; + msg += "NOIGNORE,NOMEASURELESS,NOSINGLEMEASURE,REFERENCE,FIXED,CONSTRAINED,EDITLOCKED,TOLERANCE,"; + msg += "POINTLIST,CUBES,LATLON]"; + throw IException(IException::User, msg, _FILEINFO_); + } + + if(cubeMeasures || reference) { + noMeasureless = true; + } + + FileList inList; + if(ui.WasEntered("FROMLIST")) { + //inList = ui.GetFileName("FROMLIST"); + inList.read(ui.GetFileName("FROMLIST")); + } + + int inputPoints = outNet.GetNumPoints(); + int inputMeasures = 0; + for (int cp = 0; cp < outNet.GetNumPoints(); cp++) + inputMeasures += outNet.GetPoint(cp)->GetNumMeasures(); + + // Set up the Serial Number to FileName mapping + QMap sn2filename; + for(int cubeIndex = 0; cubeIndex < (int)inList.size(); cubeIndex ++) { + QString sn = SerialNumber::Compose(inList[cubeIndex].toString()); + sn2filename[sn] = inList[cubeIndex].toString(); + } + + + Progress progress; + progress.SetMaximumSteps(outNet.GetNumPoints()); + progress.CheckStatus(); + + // Set up vector records of how points/measures are removed + QVector ignoredPoints; + QVector ignoredMeasures; + QVector singleMeasurePoints; + QVector measurelessPoints; + QVector tolerancePoints; + QVector nonReferenceMeasures; + QVector nonFixedPoints; + QVector nonConstrainedPoints; + QVector nonEditLockedPoints; + QVector nonCubePoints; + QVector noCubeMeasures; + // This is commented out since this does not correspond to any filters or the + // documentation of this application. I did not delete the code in case we find + // that we need it later. J.Backer 2012-06-22 + // + // QVector noMeasurePoints; + QVector nonListedPoints; + QVector nonLatLonPoints; + QVector cannotGenerateLatLonPoints; + + // Set up comparison data + QVector serialNumbers; + if(cubePoints) { + FileList cubeList(ui.GetFileName("CUBELIST")); + for(int cubeIndex = 0; cubeIndex < (int)cubeList.size(); cubeIndex ++) { + QString sn = SerialNumber::Compose(cubeList[cubeIndex].toString()); + serialNumbers.push_back(sn); + } + } + + double tolerance = 0.0; + if(noTolerancePoints) { + tolerance = ui.GetDouble("PIXELTOLERANCE"); + } + + // Set up extracted network values + if(ui.WasEntered("NETWORKID")) + outNet.SetNetworkId(ui.GetString("NETWORKID")); + + outNet.SetUserName(Isis::Environment::userName()); + outNet.SetDescription(ui.GetString("DESCRIPTION")); + + for(int cp = outNet.GetNumPoints() - 1; cp >= 0; cp --) { + progress.CheckStatus(); + + ControlPoint *controlpt = outNet.GetPoint(cp); + + // Do preliminary exclusion checks + if(noIgnore && controlpt->IsIgnored()) { + ignoredPoints.append(controlpt->GetId()); + omit(outNet, cp); + continue; + } + if(fixed && !(controlpt->GetType() == ControlPoint::Fixed)) { + nonFixedPoints.append(controlpt->GetId()); + omit(outNet, cp); + continue; + } + if(constrained && !(controlpt->GetType() == ControlPoint::Constrained)) { + nonConstrainedPoints.append(controlpt->GetId()); + omit(outNet, cp); + continue; + } + + + if(noSingleMeasure) { + bool invalidPoint = false; + invalidPoint |= noIgnore && (controlpt->GetNumValidMeasures() < 2); + invalidPoint |= controlpt->GetNumMeasures() < 2 && (controlpt->GetType() != ControlPoint::Fixed); + + if(invalidPoint) { + singleMeasurePoints.append(controlpt->GetId()); + omit(outNet, cp); + continue; + } + } + if (editLocked && !(controlpt->IsEditLocked())){ + nonEditLockedPoints.append(controlpt->GetId()); + omit(outNet, cp); + continue; + } + + // Change the current point into a new point by manipulation of its control measures + ControlPoint *newPoint = outNet.GetPoint(cp); + bool replaceLock = false; + if (newPoint->IsEditLocked()) { + newPoint->SetEditLock(false); + replaceLock = true; + } + + for(int cm = newPoint->GetNumMeasures() - 1; cm >= 0; cm --) { + const ControlMeasure *newMeasure = newPoint->GetMeasure(cm); + + if(noIgnore && newMeasure->IsIgnored()) { + //New error with deleting Reference Measures + QString msg = newPoint->GetId() + "," + newMeasure->GetCubeSerialNumber(); + if(newPoint->GetRefMeasure() != newMeasure) { + omit(newPoint, cm); + } + else{ + msg += ", Ignored measure but extracted since it is Reference"; + } + ignoredMeasures.append(msg); + } + else if(reference && newPoint->GetRefMeasure() != newMeasure) { + nonReferenceMeasures.append(newPoint->GetId() + "," + newMeasure->GetCubeSerialNumber()); + omit(newPoint, cm); + } + else if(cubeMeasures) { + bool hasSerialNumber = false; + QString serialNum = newMeasure->GetCubeSerialNumber(); + for(int sn = 0; sn < serialNumbers.size(); sn ++) { + if(serialNumbers[sn] == serialNum) { + hasSerialNumber = true; + break; + } + } + + // doesn't have serial number if measure is not associated with cubelist + // we need to omit appropriate measures + if(!hasSerialNumber) { + QString msg = newPoint->GetId() + "," + newMeasure->GetCubeSerialNumber(); + // if this measure is not reference, omit it + // if this measure is a reference, but retainReference is off, omit it + if(newPoint->GetRefMeasure() != newMeasure || + (newPoint->GetRefMeasure() == newMeasure && !retainReference)) + omit(newPoint, cm); + else { + //this is unnecessary if statement. only other possibility for else... + // if(newPoint->GetRefMeasure() == newMeasure && retainReference) { + msg += ", Reference not in the cubelist but extracted since " + "RETAIN_REFERENCE=true"; + // } + } + noCubeMeasures.append(msg); + } + } + } + + if (replaceLock) + newPoint->SetEditLock(true); + + //outNet.UpdatePoint(newPoint); // Fixed by redesign + + // Check for line/sample errors above provided tolerance + if(noTolerancePoints) { + bool hasLowTolerance = true; + + for(int cm = 0; cm < newPoint->GetNumMeasures() && hasLowTolerance; cm ++) { + const ControlMeasure *newMeasure = newPoint->GetMeasure(cm); + if(newMeasure->GetSampleResidual() >= tolerance || + newMeasure->GetLineResidual() >= tolerance) { + hasLowTolerance = false; + } + } + + if(hasLowTolerance) { + tolerancePoints.append(newPoint->GetId()); + omit(outNet, cp); + continue; + } + } + + // Do not add outPoint if it has too few measures + if(noSingleMeasure) { + bool invalidPoint = false; + invalidPoint |= noIgnore && (newPoint->GetNumValidMeasures() < 2); + invalidPoint |= newPoint->GetNumMeasures() < 2 && newPoint->GetType() != ControlPoint::Fixed; + + if(invalidPoint) { + singleMeasurePoints.append(controlpt->GetId()); + omit(outNet, cp); + continue; + } + } + + // Do not add outPoint if it does not have a cube in CUBELIST as asked + if(cubePoints) { + bool hasSerialNumber = false; + + for(int cm = 0; cm < newPoint->GetNumMeasures() && !hasSerialNumber; cm ++) { + for(int sn = 0; sn < serialNumbers.size() && !hasSerialNumber; sn ++) { + if(serialNumbers[sn] == newPoint->GetMeasure(cm)->GetCubeSerialNumber()) + hasSerialNumber = true; + } + } + + if(!hasSerialNumber) { + nonCubePoints.append(newPoint->GetId()); + omit(outNet, cp); + continue; + } + } + + if(noMeasureless && newPoint->GetNumMeasures() == 0) { + measurelessPoints.append(newPoint->GetId()); + omit(outNet, cp); + continue; + } + } // Finished with simple comparisons + + // Use another pass to check for Ids + if(pointsEntered) { + ExtractPointList(outNet, nonListedPoints, ui.GetFileName("POINTLIST")); + } + + + // Use another pass on outNet, because this is by far the most time consuming + // process, and time could be saved by using the reduced size of outNet + if(latLon) { + ExtractLatLonRange(outNet, nonLatLonPoints, cannotGenerateLatLonPoints, sn2filename, ui); + } + + int outputPoints = outNet.GetNumPoints(); + int outputMeasures = 0; + for (int cp = 0; cp < outNet.GetNumPoints(); cp++){ + outputMeasures += outNet.GetPoint(cp)->GetNumMeasures(); + } + + // if the output control net is not empty, write it out. + Progress outProgress; + outProgress.SetMaximumSteps(3); + + + // Adds the remove history to the summary and results group + PvlGroup summary("ResultSummary"); + PvlGroup results("Results"); + + summary.addKeyword(PvlKeyword("InputPoints", toString(inputPoints))); + summary.addKeyword(PvlKeyword("InputMeasures", toString(inputMeasures))); + summary.addKeyword(PvlKeyword("OutputPoints", toString(outputPoints))); + summary.addKeyword(PvlKeyword("OutputMeasures", toString(outputMeasures))); + + if (outputPoints != 0) { + // Write the filenames associated with outNet + if (ui.WasEntered("TOLIST") ) { + WriteCubeOutList(outNet, sn2filename, summary, ui.GetFileName("TOLIST")); + } + + outProgress.SetText("Writing Control Network"); + outProgress.CheckStatus(); + + // Write the extracted Control Network + outNet.Write(ui.GetFileName("ONET")); + outProgress.CheckStatus(); + } + else { + summary.addComment("The output control network file, [" + + ui.GetFileName("ONET") + + "], was not created. " + "The provided filters have resulted in no points or " + "measures extracted."); + if (ui.WasEntered("TOLIST")) { + summary.addComment("The output cube list file, [" + + ui.GetFileName("TOLIST") + + "], was not created. " + "The provided filters have resulted in an empty" + "Control Network."); + } + } + + + if(noIgnore) { + summary.addKeyword(PvlKeyword("IgnoredPoints", toString((int)ignoredPoints.size()))); + summary.addKeyword(PvlKeyword("IgnoredMeasures", toString((int)ignoredMeasures.size()))); + } + if(noSingleMeasure) { + summary.addKeyword(PvlKeyword("SingleMeasurePoints", toString((int)singleMeasurePoints.size()))); + } + if(noMeasureless) { + summary.addKeyword(PvlKeyword("MeasurelessPoints", toString((int)measurelessPoints.size()))); + } + if(noTolerancePoints) { + summary.addKeyword(PvlKeyword("TolerancePoints", toString((int)tolerancePoints.size()))); + } + if(reference) { + summary.addKeyword(PvlKeyword("NonReferenceMeasures", toString((int)nonReferenceMeasures.size()))); + } + if(fixed) { + summary.addKeyword(PvlKeyword("NonFixedPoints", toString((int)nonFixedPoints.size()))); + } + if(cubePoints) { + summary.addKeyword(PvlKeyword("NonCubePoints", toString((int)nonCubePoints.size()))); + } + // This is commented out since this does not correspond to any filters or the + // documentation of this application. I did not delete the code in case we find + // that we need it later. J.Backer 2012-06-22 + // + // if(noMeasurePoints.size() != 0) { + // summary.addKeyword(PvlKeyword("NoCubeMeasure", toString((int)noMeasurePoints.size()))); + // } + if(cubeMeasures) { + summary.addKeyword(PvlKeyword("NonCubeMeasures", toString((int)noCubeMeasures.size()))); + } + if(pointsEntered) { + summary.addKeyword(PvlKeyword("NonListedPoints", toString((int)nonListedPoints.size()))); + } + if(latLon) { + summary.addKeyword(PvlKeyword("LatLonOutOfRange", toString((int)nonLatLonPoints.size()))); + summary.addKeyword(PvlKeyword("NoLatLonPoints", toString((int)cannotGenerateLatLonPoints.size()))); + } + + outProgress.CheckStatus(); + + // Log Control Net results + if (log){ + log->addGroup(summary); + } + + outProgress.CheckStatus(); + + Progress resultsProgress; + if(ui.WasEntered("PREFIX")) { + if (outputPoints == inputPoints && outputMeasures == inputMeasures) { + results.addComment("No filter reports were created since all points and " + "measures from the input control network were " + "extracted into the output control network."); + } + else { + resultsProgress.SetText("Writing Results"); + resultsProgress.SetMaximumSteps(11); + resultsProgress.CheckStatus(); + + QString prefix = ui.GetString("PREFIX"); + + if(noIgnore) { + QString namecp = FileName(prefix + "IgnoredPoints.txt").expanded(); + WriteResults(namecp, ignoredPoints, results); + QString namecm = FileName(prefix + "IgnoredMeasures.txt").expanded(); + WriteResults(namecm, ignoredMeasures, results); + } + + resultsProgress.CheckStatus(); + + if(noSingleMeasure) { + QString name = FileName(prefix + "SingleMeasurePoints.txt").expanded(); + WriteResults(name, singleMeasurePoints, results); + } + + resultsProgress.CheckStatus(); + + if(noMeasureless) { + QString name = FileName(prefix + "MeasurelessPoints.txt").expanded(); + WriteResults(name, measurelessPoints, results); + } + + resultsProgress.CheckStatus(); + + if(noTolerancePoints) { + QString name = FileName(prefix + "TolerancePoints.txt").expanded(); + WriteResults(name, tolerancePoints, results); + } + + resultsProgress.CheckStatus(); + + if(reference) { + QString name = FileName(prefix + "NonReferenceMeasures.txt").expanded(); + WriteResults(name, nonReferenceMeasures, results); + } + + resultsProgress.CheckStatus(); + + if(fixed) { + QString name = FileName(prefix + "NonFixedPoints.txt").expanded(); + WriteResults(name, nonFixedPoints, results); + } + + resultsProgress.CheckStatus(); + + if(cubePoints) { + QString name = FileName(prefix + "NonCubePoints.txt").expanded(); + WriteResults(name, nonCubePoints, results); + } + + resultsProgress.CheckStatus(); + + // This is commented out since this does not correspond to any filters or the + // documentation of this application. I did not delete the code in case we find + // that we need it later. J.Backer 2012-06-22 + // + // if(noMeasurePoints.size() != 0) { + // QString name = FileName(prefix + "NoMeasurePoints.txt").expanded(); + // WriteResults(name, noMeasurePoints); + // } + + resultsProgress.CheckStatus(); + + if(cubeMeasures) { + QString name = FileName(prefix + "NonCubeMeasures.txt").expanded(); + WriteResults(name, noCubeMeasures, results); + } + + resultsProgress.CheckStatus(); + + if(pointsEntered) { + QString name = FileName(prefix + "NonListedPoints.txt").expanded(); + WriteResults(name, nonListedPoints, results); + } + + resultsProgress.CheckStatus(); + + if(latLon) { + QString namenon = FileName(prefix + "LatLonOutOfRange.txt").expanded(); + WriteResults(namenon, nonLatLonPoints, results); + QString namegen = FileName(prefix + "NoLatLonPoints.txt").expanded(); + WriteResults(namegen, cannotGenerateLatLonPoints, results); + } + + results.addComment("Each keyword represents a filter parameter used. " + "Check the documentation for specific keyword descriptions."); + } + if(log) { + log->addGroup(results); + } + + resultsProgress.CheckStatus(); + } + + } + + + /** + * Removes control points not listed in POINTLIST + * + * @param outNet The output control net being removed from + * @param nonListedPoints The keyword recording all of the control points + * removed due to not being listed + * @history 2012-06-22 - Jeannie Backer - Changed nonListedPoints parameter to + * reference so that this information could be + * accessed in the main program. + */ + void ExtractPointList(ControlNet &outNet, QVector &nonListedPoints, FileName pointListFile) { + // Use the file list class for functionality + // (even though this is a list of point IDs) + FileList listedPoints(pointListFile); + + // loop through control point indices, backwards + for(int cp = outNet.GetNumPoints() - 1; cp >= 0; cp--) { + ControlPoint *controlpt = outNet.GetPoint(cp); + // flag to determine if this controlpoint is in the pointlist + bool isInList = false; + // loop through line numbers of POINTLIST until we find a point ID in the + // list that matches this control point's ID + for(int i = 0; i < (int)listedPoints.size() && !isInList; i++) { + QString pointId = listedPoints[i].toString(); + // isInList is true if these strings are equal + isInList = pointId.toLower() == controlpt->GetId().toLower(); + } + if(!isInList) { + nonListedPoints.append(controlpt->GetId()); + omit(outNet, cp); + } + } + return; + } + + + /** + * Removes control points not in the lat/lon range provided in the input + * parameters. + * + * @param outNet[in] The output control net being removed from + * @param noLanLonPoint[out] The keyword recording all of the control points removed + * due to the control point being out of the lat/lon range. + * @param cannotGenerateLatLonPoints[out] The keyword recording all of the control points removed + * due to the inability to find a cube to calculate the lat/lon for that point. + * @param sn2filename[in] QMap that maps the serial numbers to (input) file names. + * + * @internal + * @history 2016-09-29 Ian Humphrey - Reverted r6597, which had reveresed the logic for + * checking the reference measure and other measures (see lines 635,643). + * Modified the QVector parameters to be pass-by-reference OUT parameters, + * since the cnetextract main uses them for summary output. + */ + void ExtractLatLonRange(ControlNet &outNet, + QVector &nonLatLonPoints, + QVector &cannotGenerateLatLonPoints, + QMap sn2filename, + UserInterface &ui) { + if(outNet.GetNumPoints() == 0) { + return; + } + + // Get the lat/lon and fix the range for the internal 0/360 + Latitude minlat(ui.GetDouble("MINLAT"), Angle::Degrees); + Latitude maxlat(ui.GetDouble("MAXLAT"), Angle::Degrees); + Longitude minlon = Longitude(ui.GetDouble("MINLON"), Angle::Degrees); + Longitude maxlon = Longitude(ui.GetDouble("MAXLON"), Angle::Degrees); + + Progress progress; + progress.SetText("Calculating lat/lon"); + progress.SetMaximumSteps(outNet.GetNumPoints()); + progress.CheckStatus(); + + CubeManager manager; + manager.SetNumOpenCubes(50); //Should keep memory usage to around 1GB + + bool hasFromList = ui.WasEntered("FROMLIST"); + for(int cp = outNet.GetNumPoints() - 1; cp >= 0; cp --) { + progress.CheckStatus(); + const ControlPoint *controlPt = outNet.GetPoint(cp); + SurfacePoint surfacePt = controlPt->GetBestSurfacePoint(); + + // If the Contorl Network takes priority, use it + if(surfacePt.Valid()) { + if(NotInLatLonRange(surfacePt, minlat, maxlat, minlon, maxlon)) { + nonLatLonPoints.push_back(controlPt->GetId()); + omit(outNet, cp); + } + } + + /** + * If the lat/lon cannot be determined from the point, then we need to calculate + * lat/lon on our own + */ + else if(hasFromList) { + + // Find a cube in the Control Point to get the lat/lon from + int cm = 0; + QString sn = ""; + Latitude lat; + Longitude lon; + Distance radius; + + // First check the reference Measure + if(sn2filename[controlPt->GetReferenceSN()].length() != 0) { + sn = controlPt->GetReferenceSN(); + } + + // Search for other Control Measures if needed + if(sn.isEmpty()) { + // Find the Serial Number if it exists + for(int cm = 0; (cm < controlPt->GetNumMeasures()) && sn.isEmpty(); cm ++) { + if(sn2filename[controlPt->GetReferenceSN()].length() != 0) { + sn = controlPt->GetReferenceSN(); + } + } + } + + // Cannot find a cube to get the lat/lon from + if(sn.isEmpty()) { + cannotGenerateLatLonPoints.push_back(controlPt->GetId()); + omit(outNet, cp); + } + + // Calculate the lat/lon and check for validity + else { + bool remove = false; + + Cube *cube = manager.OpenCube(sn2filename[sn]); + Camera *camera = cube->camera(); + + if(camera == NULL) { + try { + TProjection *projection = + (TProjection *) ProjectionFactory::Create((*(cube->label()))); + + if(!projection->SetCoordinate(controlPt->GetMeasure(cm)->GetSample(), + controlPt->GetMeasure(cm)->GetLine())) { + nonLatLonPoints.push_back(controlPt->GetId()); + remove = true; + } + + lat = Latitude(projection->Latitude(), Angle::Degrees); + lon = Longitude(projection->Longitude(), Angle::Degrees); + radius = Distance(projection->LocalRadius(), Distance::Meters); + + delete projection; + projection = NULL; + } + catch(IException &) { + remove = true; + } + } + else { + if(!camera->SetImage(controlPt->GetMeasure(cm)->GetSample(), + controlPt->GetMeasure(cm)->GetLine())) { + nonLatLonPoints.push_back(controlPt->GetId()); + remove = true; + } + + lat = camera->GetLatitude(); + lon = camera->GetLongitude(); + radius = camera->LocalRadius(); + + camera = NULL; + } + + cube = NULL; + + bool notInRange = false; + bool validLatLonRadius = lat.isValid() && lon.isValid() && radius.isValid(); + if(validLatLonRadius) { + SurfacePoint sfpt(lat, lon, radius); + notInRange = NotInLatLonRange(sfpt, minlat, maxlat, minlon, maxlon); + } + + if(remove || notInRange) { + nonLatLonPoints.push_back(controlPt->GetId()); + omit(outNet, cp); + } + else if(validLatLonRadius) { // Add the reference lat/lon/radius to the Control Point + outNet.GetPoint(cp)->SetAprioriSurfacePoint(SurfacePoint(lat, lon, radius)); + } + } + } + else { + cannotGenerateLatLonPoints.push_back(controlPt->GetId()); + omit(outNet, cp); + } + + } + + manager.CleanCubes(); + } + + + /** + * Checks whether the given surface point is in the given lat/lon range, + * handling the meridian correctly + * + * @param lat The latitude to check + * @param lon The longitude to check + * @param minlat Minimum Latitude Minimum valid latitude + * @param maxlat Maximum Latitude Maximum valid latitude + * @param minlon Minimum Longitude Minimum valid longitude + * @param maxlon Maximum Longitude Maximum valid longitude + * + * @return bool True when the range is valid + */ + bool NotInLatLonRange(SurfacePoint surfacePtToTest, Latitude minlat, + Latitude maxlat, Longitude minlon, Longitude maxlon) { + Latitude lat = surfacePtToTest.GetLatitude(); + Longitude lon = surfacePtToTest.GetLongitude(); + + bool outRange = false; + try { + outRange = !lat.inRange(minlat, maxlat) || !lon.inRange(minlon, maxlon); + } + catch (IException &e) { + QString msg = "Cannot complete lat/lon range test with given filters"; + throw IException(e, IException::User, msg, _FILEINFO_); + } + + return outRange; + } + + + /** + * Creates the output list, [TOLIST], if the parameter is entered. This method + * finds all cubes contained within the given Control Network and lists the + * corresponding file names for these cubes in the [TOLIST] output file. + * + * @param cnet The Control Network from which the cube list will be found and + * created. + * @param sn2file The map for converting the Control Network's serial numbers + * to filenames. + */ + void WriteCubeOutList(ControlNet cnet, + QMap sn2file, + PvlGroup &summary, + FileName toList) { + Progress p; + p.SetText("Writing Cube List"); + try { + p.SetMaximumSteps(cnet.GetNumPoints()); + p.CheckStatus(); + } + catch(IException &e) { + QString msg = "Unable to write the output cube list, [TOLIST]."; + throw IException(e, IException::User, msg, _FILEINFO_); + } + + std::set outputsn; + for(int cp = 0; cp < cnet.GetNumPoints(); cp ++) { + for(int cm = 0; cm < cnet.GetPoint(cp)->GetNumMeasures(); cm ++) { + QString sn = cnet.GetPoint(cp)->GetMeasure(cm)->GetCubeSerialNumber(); + if (sn2file[sn].length() != 0) { + outputsn.insert(sn); + } + } + p.CheckStatus(); + } + // Don't create file if it will be empty + if (outputsn.size() == 0) { + summary.addComment("The output cube list file, [" + + toList.toString() + "], was not created. " + "The provided filters have resulted in an empty" + "Control Network."); + return; + } + + std::ofstream out_stream; + out_stream.open(toList.toString().toLatin1().data(), std::ios::out); + out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file + + for(std::set::iterator sn = outputsn.begin(); sn != outputsn.end(); sn ++) { + // moved the "if" statement to the previous for loop to prevent creating + // an empty file + //if(!sn2file[(*sn)].length() == 0) { + out_stream << sn2file[(*sn)] << std::endl; + //} + } + + out_stream.close(); + return; + } + + + /** + * Creates the results report using the given file name and vector of measures + * or points that were not extracted. + * + * @param filename The name of the report file to create. + * @param notExtracted A vector of points and/or measures to be listed in the + * report. + * @param results A reference to the results PvlGroup address. + */ + void WriteResults(QString filename, + QVector notExtracted, + PvlGroup &results) { + // if no points or measures are being extracted, + // we will not create the filter report. + if(notExtracted.size() == 0) { + results.addComment("The output report ["+ filename +"] was not created. " + "The corresponding filter found no points/measures that " + "would not be extracted."); + return; + } + + // Set up the output file for writing + std::ofstream out_stream; + out_stream.open(filename.toLatin1().data(), std::ios::out); + out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file + + out_stream << notExtracted[0]; + for(int index = 1; index < notExtracted.size(); index ++) { + out_stream << std::endl << notExtracted[index]; + } + + out_stream.close(); + results.addKeyword(PvlKeyword("ReportCreated", filename)); + return; + } + + /** + * This method removes the given control point from the given control network. + */ + void omit(ControlNet &cnet, int cp) { + ControlPoint *point = cnet.GetPoint(cp); + if (point->IsEditLocked()) point->SetEditLock(false); + cnet.DeletePoint(cp); + return; + } + + /** + * This method removes the given control measure from the given control point. + */ + void omit(ControlPoint *point, int cm) { + ControlMeasure *measure = point->GetMeasure(cm); + if (measure->IsEditLocked()) measure->SetEditLock(false); + point->Delete(cm); + return; + } + + + // Modified [PREFIX]IgnoredMeasures.txt output to exclude + // ignored reference measures since these measures will be extracted. + +} diff --git a/isis/src/control/apps/cnetextract/cnetextract.h b/isis/src/control/apps/cnetextract/cnetextract.h new file mode 100644 index 0000000000..3007023a14 --- /dev/null +++ b/isis/src/control/apps/cnetextract/cnetextract.h @@ -0,0 +1,38 @@ +#ifndef cnetextract_h +#define cnetextract_h + +#include +#include + +#include +#include +#include + +#include "Angle.h" +#include "Camera.h" +#include "ControlMeasure.h" +#include "ControlNet.h" +#include "ControlPoint.h" +#include "Cube.h" +#include "CubeManager.h" +#include "Environment.h" +#include "FileList.h" +#include "IException.h" +#include "IString.h" +#include "Longitude.h" +#include "Latitude.h" +#include "TProjection.h" +#include "Progress.h" +#include "ProjectionFactory.h" +#include "Pvl.h" +#include "SerialNumber.h" +#include "SurfacePoint.h" +#include "UserInterface.h" + +namespace Isis { + void cnetextract(UserInterface &ui, Pvl *log); + + void cnetextract(ControlNet outNet, UserInterface &ui, Pvl *log); +} + +#endif diff --git a/isis/src/control/apps/cnetextract/main.cpp b/isis/src/control/apps/cnetextract/main.cpp index db4f5bcdea..1c1eb0bd0e 100644 --- a/isis/src/control/apps/cnetextract/main.cpp +++ b/isis/src/control/apps/cnetextract/main.cpp @@ -1,880 +1,27 @@ #include "Isis.h" -#include -#include +#include "cnetextract.h" -#include -#include -#include - -#include "Angle.h" -#include "Camera.h" -#include "CameraFactory.h" -#include "ControlMeasure.h" -#include "ControlNet.h" -#include "ControlPoint.h" -#include "Cube.h" -#include "CubeManager.h" -#include "FileList.h" -#include "IException.h" -#include "IString.h" -#include "Longitude.h" -#include "Latitude.h" -#include "TProjection.h" -#include "Progress.h" -#include "ProjectionFactory.h" +#include "Application.h" #include "Pvl.h" -#include "SerialNumber.h" -#include "SurfacePoint.h" -#include "UserInterface.h" using namespace std; using namespace Isis; -void ExtractPointList(ControlNet &outNet, QVector &nonListedPoints); -void ExtractLatLonRange(ControlNet &outNet, QVector &nonLatLonPoints, - QVector &cannotGenerateLatLonPoints, - QMap sn2filename); -bool NotInLatLonRange(SurfacePoint surfacePt, Latitude minlat, - Latitude maxlat, Longitude minlon, Longitude maxlon); -void WriteCubeOutList(ControlNet cnet, - QMap sn2file, - PvlGroup &summary); -void WriteResults(QString filename, - QVector notExtracted, - PvlGroup &results); -void omit(ControlNet &cnet, int cp); -void omit(ControlPoint *point, int cm); - - -// Main program void IsisMain() { UserInterface &ui = Application::GetUserInterface(); - - if(!ui.WasEntered("FROMLIST") && ui.WasEntered("TOLIST")) { - QString msg = "To create a [TOLIST] the [FROMLIST] parameter must be provided."; - throw IException(IException::User, msg, _FILEINFO_); - } - - bool noIgnore = ui.GetBoolean("NOIGNORE"); - bool noMeasureless = ui.GetBoolean("NOMEASURELESS"); - bool noSingleMeasure = ui.GetBoolean("NOSINGLEMEASURES"); - bool reference = ui.GetBoolean("REFERENCE"); - bool fixed = ui.GetBoolean("FIXED"); - bool constrained = ui.GetBoolean("CONSTRAINED"); - bool editLocked = ui.GetBoolean("EDITLOCKED"); - bool noTolerancePoints = ui.GetBoolean("TOLERANCE"); - bool pointsEntered = ui.WasEntered("POINTLIST"); - bool cubePoints = ui.GetBoolean("CUBES"); - bool cubeMeasures = ui.GetBoolean("CUBEMEASURES"); - bool retainReference = ui.GetBoolean("RETAIN_REFERENCE"); - bool latLon = ui.GetBoolean("LATLON"); - - if(!(noIgnore || noMeasureless || noSingleMeasure || editLocked || reference || fixed || - noTolerancePoints || pointsEntered || cubePoints || constrained || latLon)) { - QString msg = "At least one filter must be selected ["; - msg += "NOIGNORE,NOMEASURELESS,NOSINGLEMEASURE,REFERENCE,FIXED,CONSTRAINED,EDITLOCKED,TOLERANCE,"; - msg += "POINTLIST,CUBES,LATLON]"; - throw IException(IException::User, msg, _FILEINFO_); - } - - if(cubeMeasures || reference) { - noMeasureless = true; - } - - // Gets the input parameters - ControlNet outNet(ui.GetFileName("CNET")); - FileList inList; - if(ui.WasEntered("FROMLIST")) { - //inList = ui.GetFileName("FROMLIST"); - inList.read(ui.GetFileName("FROMLIST")); - } - - int inputPoints = outNet.GetNumPoints(); - int inputMeasures = 0; - for (int cp = 0; cp < outNet.GetNumPoints(); cp++) - inputMeasures += outNet.GetPoint(cp)->GetNumMeasures(); - - // Set up the Serial Number to FileName mapping - QMap sn2filename; - for(int cubeIndex = 0; cubeIndex < (int)inList.size(); cubeIndex ++) { - QString sn = SerialNumber::Compose(inList[cubeIndex].toString()); - sn2filename[sn] = inList[cubeIndex].toString(); - } - - - Progress progress; - progress.SetMaximumSteps(outNet.GetNumPoints()); - progress.CheckStatus(); - - // Set up vector records of how points/measures are removed - QVector ignoredPoints; - QVector ignoredMeasures; - QVector singleMeasurePoints; - QVector measurelessPoints; - QVector tolerancePoints; - QVector nonReferenceMeasures; - QVector nonFixedPoints; - QVector nonConstrainedPoints; - QVector nonEditLockedPoints; - QVector nonCubePoints; - QVector noCubeMeasures; -// This is commented out since this does not correspond to any filters or the -// documentation of this application. I did not delete the code in case we find -// that we need it later. J.Backer 2012-06-22 -// -// QVector noMeasurePoints; - QVector nonListedPoints; - QVector nonLatLonPoints; - QVector cannotGenerateLatLonPoints; - - // Set up comparison data - QVector serialNumbers; - if(cubePoints) { - FileList cubeList(ui.GetFileName("CUBELIST")); - for(int cubeIndex = 0; cubeIndex < (int)cubeList.size(); cubeIndex ++) { - QString sn = SerialNumber::Compose(cubeList[cubeIndex].toString()); - serialNumbers.push_back(sn); - } - } - - double tolerance = 0.0; - if(noTolerancePoints) { - tolerance = ui.GetDouble("PIXELTOLERANCE"); - } - - // Set up extracted network values - if(ui.WasEntered("NETWORKID")) - outNet.SetNetworkId(ui.GetString("NETWORKID")); - - outNet.SetUserName(Isis::Application::UserName()); - outNet.SetDescription(ui.GetString("DESCRIPTION")); - - for(int cp = outNet.GetNumPoints() - 1; cp >= 0; cp --) { - progress.CheckStatus(); - - ControlPoint *controlpt = outNet.GetPoint(cp); - - // Do preliminary exclusion checks - if(noIgnore && controlpt->IsIgnored()) { - ignoredPoints.append(controlpt->GetId()); - omit(outNet, cp); - continue; - } - if(fixed && !(controlpt->GetType() == ControlPoint::Fixed)) { - nonFixedPoints.append(controlpt->GetId()); - omit(outNet, cp); - continue; - } - if(constrained && !(controlpt->GetType() == ControlPoint::Constrained)) { - nonConstrainedPoints.append(controlpt->GetId()); - omit(outNet, cp); - continue; - } - - - if(noSingleMeasure) { - bool invalidPoint = false; - invalidPoint |= noIgnore && (controlpt->GetNumValidMeasures() < 2); - invalidPoint |= controlpt->GetNumMeasures() < 2 && (controlpt->GetType() != ControlPoint::Fixed); - - if(invalidPoint) { - singleMeasurePoints.append(controlpt->GetId()); - omit(outNet, cp); - continue; - } - } - if (editLocked && !(controlpt->IsEditLocked())){ - nonEditLockedPoints.append(controlpt->GetId()); - omit(outNet, cp); - continue; - } - - // Change the current point into a new point by manipulation of its control measures - ControlPoint *newPoint = outNet.GetPoint(cp); - bool replaceLock = false; - if (newPoint->IsEditLocked()) { - newPoint->SetEditLock(false); - replaceLock = true; - } - - for(int cm = newPoint->GetNumMeasures() - 1; cm >= 0; cm --) { - const ControlMeasure *newMeasure = newPoint->GetMeasure(cm); - - if(noIgnore && newMeasure->IsIgnored()) { - //New error with deleting Reference Measures - QString msg = newPoint->GetId() + "," + newMeasure->GetCubeSerialNumber(); - if(newPoint->GetRefMeasure() != newMeasure) { - omit(newPoint, cm); - } - else{ - msg += ", Ignored measure but extracted since it is Reference"; - } - ignoredMeasures.append(msg); - } - else if(reference && newPoint->GetRefMeasure() != newMeasure) { - nonReferenceMeasures.append(newPoint->GetId() + "," + newMeasure->GetCubeSerialNumber()); - omit(newPoint, cm); - } - else if(cubeMeasures) { - bool hasSerialNumber = false; - QString serialNum = newMeasure->GetCubeSerialNumber(); - for(int sn = 0; sn < serialNumbers.size(); sn ++) { - if(serialNumbers[sn] == serialNum) { - hasSerialNumber = true; - break; - } - } - - // doesn't have serial number if measure is not associated with cubelist - // we need to omit appropriate measures - if(!hasSerialNumber) { - QString msg = newPoint->GetId() + "," + newMeasure->GetCubeSerialNumber(); - // if this measure is not reference, omit it - // if this measure is a reference, but retainReference is off, omit it - if(newPoint->GetRefMeasure() != newMeasure || - (newPoint->GetRefMeasure() == newMeasure && !retainReference)) - omit(newPoint, cm); - else { - //this is unnecessary if statement. only other possibility for else... - // if(newPoint->GetRefMeasure() == newMeasure && retainReference) { - msg += ", Reference not in the cubelist but extracted since " - "RETAIN_REFERENCE=true"; - // } - } - noCubeMeasures.append(msg); - } - } - } - - if (replaceLock) - newPoint->SetEditLock(true); - - //outNet.UpdatePoint(newPoint); // Fixed by redesign - - // Check for line/sample errors above provided tolerance - if(noTolerancePoints) { - bool hasLowTolerance = true; - - for(int cm = 0; cm < newPoint->GetNumMeasures() && hasLowTolerance; cm ++) { - const ControlMeasure *newMeasure = newPoint->GetMeasure(cm); - if(newMeasure->GetSampleResidual() >= tolerance || - newMeasure->GetLineResidual() >= tolerance) { - hasLowTolerance = false; - } - } - - if(hasLowTolerance) { - tolerancePoints.append(newPoint->GetId()); - omit(outNet, cp); - continue; - } - } - - // Do not add outPoint if it has too few measures - if(noSingleMeasure) { - bool invalidPoint = false; - invalidPoint |= noIgnore && (newPoint->GetNumValidMeasures() < 2); - invalidPoint |= newPoint->GetNumMeasures() < 2 && newPoint->GetType() != ControlPoint::Fixed; - - if(invalidPoint) { - singleMeasurePoints.append(controlpt->GetId()); - omit(outNet, cp); - continue; - } - } - - // Do not add outPoint if it does not have a cube in CUBELIST as asked - if(cubePoints) { - bool hasSerialNumber = false; - - for(int cm = 0; cm < newPoint->GetNumMeasures() && !hasSerialNumber; cm ++) { - for(int sn = 0; sn < serialNumbers.size() && !hasSerialNumber; sn ++) { - if(serialNumbers[sn] == newPoint->GetMeasure(cm)->GetCubeSerialNumber()) - hasSerialNumber = true; - } - } - - if(!hasSerialNumber) { - nonCubePoints.append(newPoint->GetId()); - omit(outNet, cp); - continue; - } - } - - if(noMeasureless && newPoint->GetNumMeasures() == 0) { - measurelessPoints.append(newPoint->GetId()); - omit(outNet, cp); - continue; - } - } // Finished with simple comparisons - - // Use another pass to check for Ids - if(pointsEntered) { - ExtractPointList(outNet, nonListedPoints); - } - - - // Use another pass on outNet, because this is by far the most time consuming - // process, and time could be saved by using the reduced size of outNet - if(latLon) { - ExtractLatLonRange(outNet, nonLatLonPoints, cannotGenerateLatLonPoints, sn2filename); - } - - int outputPoints = outNet.GetNumPoints(); - int outputMeasures = 0; - for (int cp = 0; cp < outNet.GetNumPoints(); cp++){ - outputMeasures += outNet.GetPoint(cp)->GetNumMeasures(); - } - - // if the output control net is not empty, write it out. - Progress outProgress; - outProgress.SetMaximumSteps(3); - - - // Adds the remove history to the summary and results group - PvlGroup summary("ResultSummary"); - PvlGroup results("Results"); - - summary.addKeyword(PvlKeyword("InputPoints", toString(inputPoints))); - summary.addKeyword(PvlKeyword("InputMeasures", toString(inputMeasures))); - summary.addKeyword(PvlKeyword("OutputPoints", toString(outputPoints))); - summary.addKeyword(PvlKeyword("OutputMeasures", toString(outputMeasures))); - - if (outputPoints != 0) { - // Write the filenames associated with outNet - if (ui.WasEntered("TOLIST") ) { - WriteCubeOutList(outNet, sn2filename, summary); - } - - outProgress.SetText("Writing Control Network"); - outProgress.CheckStatus(); - - // Write the extracted Control Network - outNet.Write(ui.GetFileName("ONET")); - outProgress.CheckStatus(); - } - else { - summary.addComment("The output control network file, [" - + ui.GetFileName("ONET") + - "], was not created. " - "The provided filters have resulted in no points or " - "measures extracted."); - if (ui.WasEntered("TOLIST")) { - summary.addComment("The output cube list file, [" - + ui.GetFileName("TOLIST") + - "], was not created. " - "The provided filters have resulted in an empty" - "Control Network."); - } - } - - - if(noIgnore) { - summary.addKeyword(PvlKeyword("IgnoredPoints", toString((int)ignoredPoints.size()))); - summary.addKeyword(PvlKeyword("IgnoredMeasures", toString((int)ignoredMeasures.size()))); - } - if(noSingleMeasure) { - summary.addKeyword(PvlKeyword("SingleMeasurePoints", toString((int)singleMeasurePoints.size()))); - } - if(noMeasureless) { - summary.addKeyword(PvlKeyword("MeasurelessPoints", toString((int)measurelessPoints.size()))); - } - if(noTolerancePoints) { - summary.addKeyword(PvlKeyword("TolerancePoints", toString((int)tolerancePoints.size()))); - } - if(reference) { - summary.addKeyword(PvlKeyword("NonReferenceMeasures", toString((int)nonReferenceMeasures.size()))); - } - if(fixed) { - summary.addKeyword(PvlKeyword("NonFixedPoints", toString((int)nonFixedPoints.size()))); - } - if(cubePoints) { - summary.addKeyword(PvlKeyword("NonCubePoints", toString((int)nonCubePoints.size()))); - } -// This is commented out since this does not correspond to any filters or the -// documentation of this application. I did not delete the code in case we find -// that we need it later. J.Backer 2012-06-22 -// -// if(noMeasurePoints.size() != 0) { -// summary.addKeyword(PvlKeyword("NoCubeMeasure", toString((int)noMeasurePoints.size()))); -// } - if(cubeMeasures) { - summary.addKeyword(PvlKeyword("NonCubeMeasures", toString((int)noCubeMeasures.size()))); - } - if(pointsEntered) { - summary.addKeyword(PvlKeyword("NonListedPoints", toString((int)nonListedPoints.size()))); - } - if(latLon) { - summary.addKeyword(PvlKeyword("LatLonOutOfRange", toString((int)nonLatLonPoints.size()))); - summary.addKeyword(PvlKeyword("NoLatLonPoints", toString((int)cannotGenerateLatLonPoints.size()))); - } - - outProgress.CheckStatus(); - - // Log Control Net results - Application::Log(summary); - - outProgress.CheckStatus(); - - Progress resultsProgress; - if(ui.WasEntered("PREFIX")) { - if (outputPoints == inputPoints && outputMeasures == inputMeasures) { - results.addComment("No filter reports were created since all points and " - "measures from the input control network were " - "extracted into the output control network."); - } - else { - resultsProgress.SetText("Writing Results"); - resultsProgress.SetMaximumSteps(11); - resultsProgress.CheckStatus(); - - QString prefix = ui.GetString("PREFIX"); - - if(noIgnore) { - QString namecp = FileName(prefix + "IgnoredPoints.txt").expanded(); - WriteResults(namecp, ignoredPoints, results); - QString namecm = FileName(prefix + "IgnoredMeasures.txt").expanded(); - WriteResults(namecm, ignoredMeasures, results); - } - - resultsProgress.CheckStatus(); - - if(noSingleMeasure) { - QString name = FileName(prefix + "SingleMeasurePoints.txt").expanded(); - WriteResults(name, singleMeasurePoints, results); - } - - resultsProgress.CheckStatus(); - - if(noMeasureless) { - QString name = FileName(prefix + "MeasurelessPoints.txt").expanded(); - WriteResults(name, measurelessPoints, results); - } - - resultsProgress.CheckStatus(); - - if(noTolerancePoints) { - QString name = FileName(prefix + "TolerancePoints.txt").expanded(); - WriteResults(name, tolerancePoints, results); - } - - resultsProgress.CheckStatus(); - - if(reference) { - QString name = FileName(prefix + "NonReferenceMeasures.txt").expanded(); - WriteResults(name, nonReferenceMeasures, results); - } - - resultsProgress.CheckStatus(); - - if(fixed) { - QString name = FileName(prefix + "NonFixedPoints.txt").expanded(); - WriteResults(name, nonFixedPoints, results); - } - - resultsProgress.CheckStatus(); - - if(cubePoints) { - QString name = FileName(prefix + "NonCubePoints.txt").expanded(); - WriteResults(name, nonCubePoints, results); - } - - resultsProgress.CheckStatus(); - -// This is commented out since this does not correspond to any filters or the -// documentation of this application. I did not delete the code in case we find -// that we need it later. J.Backer 2012-06-22 -// -// if(noMeasurePoints.size() != 0) { -// QString name = FileName(prefix + "NoMeasurePoints.txt").expanded(); -// WriteResults(name, noMeasurePoints); -// } - - resultsProgress.CheckStatus(); - - if(cubeMeasures) { - QString name = FileName(prefix + "NonCubeMeasures.txt").expanded(); - WriteResults(name, noCubeMeasures, results); - } - - resultsProgress.CheckStatus(); - - if(pointsEntered) { - QString name = FileName(prefix + "NonListedPoints.txt").expanded(); - WriteResults(name, nonListedPoints, results); - } - - resultsProgress.CheckStatus(); - - if(latLon) { - QString namenon = FileName(prefix + "LatLonOutOfRange.txt").expanded(); - WriteResults(namenon, nonLatLonPoints, results); - QString namegen = FileName(prefix + "NoLatLonPoints.txt").expanded(); - WriteResults(namegen, cannotGenerateLatLonPoints, results); - } - - results.addComment("Each keyword represents a filter parameter used. " - "Check the documentation for specific keyword descriptions."); - } - Application::Log(results); - - resultsProgress.CheckStatus(); - } - -} - - -/** - * Removes control points not listed in POINTLIST - * - * @param outNet The output control net being removed from - * @param nonListedPoints The keyword recording all of the control points - * removed due to not being listed - * @history 2012-06-22 - Jeannie Backer - Changed nonListedPoints parameter to - * reference so that this information could be - * accessed in the main program. - */ -void ExtractPointList(ControlNet &outNet, QVector &nonListedPoints) { - UserInterface &ui = Application::GetUserInterface(); - - // Use the file list class for functionality - // (even though this is a list of point IDs) - FileList listedPoints(ui.GetFileName("POINTLIST")); - - // loop through control point indices, backwards - for(int cp = outNet.GetNumPoints() - 1; cp >= 0; cp--) { - ControlPoint *controlpt = outNet.GetPoint(cp); - // flag to determine if this controlpoint is in the pointlist - bool isInList = false; - // loop through line numbers of POINTLIST until we find a point ID in the - // list that matches this control point's ID - for(int i = 0; i < (int)listedPoints.size() && !isInList; i++) { - QString pointId = listedPoints[i].toString(); - // isInList is true if these strings are equal - isInList = pointId.toLower() == controlpt->GetId().toLower(); - } - if(!isInList) { - nonListedPoints.append(controlpt->GetId()); - omit(outNet, cp); - } - } - return; -} - - -/** - * Removes control points not in the lat/lon range provided in the input - * parameters. - * - * @param outNet[in] The output control net being removed from - * @param noLanLonPoint[out] The keyword recording all of the control points removed - * due to the control point being out of the lat/lon range. - * @param cannotGenerateLatLonPoints[out] The keyword recording all of the control points removed - * due to the inability to find a cube to calculate the lat/lon for that point. - * @param sn2filename[in] QMap that maps the serial numbers to (input) file names. - * - * @internal - * @history 2016-09-29 Ian Humphrey - Reverted r6597, which had reveresed the logic for - * checking the reference measure and other measures (see lines 635,643). - * Modified the QVector parameters to be pass-by-reference OUT parameters, - * since the cnetextract main uses them for summary output. - */ -void ExtractLatLonRange(ControlNet &outNet, - QVector &nonLatLonPoints, - QVector &cannotGenerateLatLonPoints, - QMap sn2filename) { - if(outNet.GetNumPoints() == 0) { - return; - } - - UserInterface &ui = Application::GetUserInterface(); - - // Get the lat/lon and fix the range for the internal 0/360 - Latitude minlat(ui.GetDouble("MINLAT"), Angle::Degrees); - Latitude maxlat(ui.GetDouble("MAXLAT"), Angle::Degrees); - Longitude minlon = Longitude(ui.GetDouble("MINLON"), Angle::Degrees); - Longitude maxlon = Longitude(ui.GetDouble("MAXLON"), Angle::Degrees); - - Progress progress; - progress.SetText("Calculating lat/lon"); - progress.SetMaximumSteps(outNet.GetNumPoints()); - progress.CheckStatus(); - - CubeManager manager; - manager.SetNumOpenCubes(50); //Should keep memory usage to around 1GB - - bool hasFromList = ui.WasEntered("FROMLIST"); - for(int cp = outNet.GetNumPoints() - 1; cp >= 0; cp --) { - progress.CheckStatus(); - const ControlPoint *controlPt = outNet.GetPoint(cp); - SurfacePoint surfacePt = controlPt->GetBestSurfacePoint(); - - // If the Contorl Network takes priority, use it - if(surfacePt.Valid()) { - if(NotInLatLonRange(surfacePt, minlat, maxlat, minlon, maxlon)) { - nonLatLonPoints.push_back(controlPt->GetId()); - omit(outNet, cp); - } - } - - /** - * If the lat/lon cannot be determined from the point, then we need to calculate - * lat/lon on our own - */ - else if(hasFromList) { - - // Find a cube in the Control Point to get the lat/lon from - int cm = 0; - QString sn = ""; - Latitude lat; - Longitude lon; - Distance radius; - - // First check the reference Measure - if(sn2filename[controlPt->GetReferenceSN()].length() != 0) { - sn = controlPt->GetReferenceSN(); - } - - // Search for other Control Measures if needed - if(sn.isEmpty()) { - // Find the Serial Number if it exists - for(int cm = 0; (cm < controlPt->GetNumMeasures()) && sn.isEmpty(); cm ++) { - if(sn2filename[controlPt->GetReferenceSN()].length() != 0) { - sn = controlPt->GetReferenceSN(); - } - } - } - - // Cannot find a cube to get the lat/lon from - if(sn.isEmpty()) { - cannotGenerateLatLonPoints.push_back(controlPt->GetId()); - omit(outNet, cp); - } - - // Calculate the lat/lon and check for validity - else { - bool remove = false; - - Cube *cube = manager.OpenCube(sn2filename[sn]); - Camera *camera = cube->camera(); - - if(camera == NULL) { - try { - TProjection *projection = - (TProjection *) ProjectionFactory::Create((*(cube->label()))); - - if(!projection->SetCoordinate(controlPt->GetMeasure(cm)->GetSample(), - controlPt->GetMeasure(cm)->GetLine())) { - nonLatLonPoints.push_back(controlPt->GetId()); - remove = true; - } - - lat = Latitude(projection->Latitude(), Angle::Degrees); - lon = Longitude(projection->Longitude(), Angle::Degrees); - radius = Distance(projection->LocalRadius(), Distance::Meters); - - delete projection; - projection = NULL; - } - catch(IException &) { - remove = true; - } - } - else { - if(!camera->SetImage(controlPt->GetMeasure(cm)->GetSample(), - controlPt->GetMeasure(cm)->GetLine())) { - nonLatLonPoints.push_back(controlPt->GetId()); - remove = true; - } - - lat = camera->GetLatitude(); - lon = camera->GetLongitude(); - radius = camera->LocalRadius(); - - camera = NULL; - } - - cube = NULL; - - bool notInRange = false; - bool validLatLonRadius = lat.isValid() && lon.isValid() && radius.isValid(); - if(validLatLonRadius) { - SurfacePoint sfpt(lat, lon, radius); - notInRange = NotInLatLonRange(sfpt, minlat, maxlat, minlon, maxlon); - } - - if(remove || notInRange) { - nonLatLonPoints.push_back(controlPt->GetId()); - omit(outNet, cp); - } - else if(validLatLonRadius) { // Add the reference lat/lon/radius to the Control Point - outNet.GetPoint(cp)->SetAprioriSurfacePoint(SurfacePoint(lat, lon, radius)); - } - } - } - else { - cannotGenerateLatLonPoints.push_back(controlPt->GetId()); - omit(outNet, cp); - } - - } - - manager.CleanCubes(); -} - - -/** - * Checks whether the given surface point is in the given lat/lon range, - * handling the meridian correctly - * - * @param lat The latitude to check - * @param lon The longitude to check - * @param minlat Minimum Latitude Minimum valid latitude - * @param maxlat Maximum Latitude Maximum valid latitude - * @param minlon Minimum Longitude Minimum valid longitude - * @param maxlon Maximum Longitude Maximum valid longitude - * - * @return bool True when the range is valid - */ -bool NotInLatLonRange(SurfacePoint surfacePtToTest, Latitude minlat, - Latitude maxlat, Longitude minlon, Longitude maxlon) { - Latitude lat = surfacePtToTest.GetLatitude(); - Longitude lon = surfacePtToTest.GetLongitude(); - - bool outRange = false; - try { - outRange = !lat.inRange(minlat, maxlat) || !lon.inRange(minlon, maxlon); - } - catch (IException &e) { - QString msg = "Cannot complete lat/lon range test with given filters"; - throw IException(e, IException::User, msg, _FILEINFO_); - } - - return outRange; -} - - -/** - * Creates the output list, [TOLIST], if the parameter is entered. This method - * finds all cubes contained within the given Control Network and lists the - * corresponding file names for these cubes in the [TOLIST] output file. - * - * @param cnet The Control Network from which the cube list will be found and - * created. - * @param sn2file The map for converting the Control Network's serial numbers - * to filenames. - */ -void WriteCubeOutList(ControlNet cnet, - QMap sn2file, - PvlGroup &summary) { - UserInterface &ui = Application::GetUserInterface(); - - Progress p; - p.SetText("Writing Cube List"); + Pvl appLog; try { - p.SetMaximumSteps(cnet.GetNumPoints()); - p.CheckStatus(); - } - catch(IException &e) { - QString msg = "Unable to write the output cube list, [TOLIST]."; - throw IException(e, IException::User, msg, _FILEINFO_); - } - - std::set outputsn; - for(int cp = 0; cp < cnet.GetNumPoints(); cp ++) { - for(int cm = 0; cm < cnet.GetPoint(cp)->GetNumMeasures(); cm ++) { - QString sn = cnet.GetPoint(cp)->GetMeasure(cm)->GetCubeSerialNumber(); - if (sn2file[sn].length() != 0) { - outputsn.insert(sn); - } - } - p.CheckStatus(); - } - // Don't create file if it will be empty - if (outputsn.size() == 0) { - summary.addComment("The output cube list file, [" - + ui.GetFileName("TOLIST") + - "], was not created. " - "The provided filters have resulted in an empty" - "Control Network."); - return; - } - - QString toList = ui.GetFileName("TOLIST"); - std::ofstream out_stream; - out_stream.open(toList.toLatin1().data(), std::ios::out); - out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file - - for(std::set::iterator sn = outputsn.begin(); sn != outputsn.end(); sn ++) { - // moved the "if" statement to the previous for loop to prevent creating - // an empty file - //if(!sn2file[(*sn)].length() == 0) { - out_stream << sn2file[(*sn)] << std::endl; - //} + cnetextract(ui, &appLog); } - - out_stream.close(); - return; -} - - -/** - * Creates the results report using the given file name and vector of measures - * or points that were not extracted. - * - * @param filename The name of the report file to create. - * @param notExtracted A vector of points and/or measures to be listed in the - * report. - * @param results A reference to the results PvlGroup address. - */ -void WriteResults(QString filename, - QVector notExtracted, - PvlGroup &results) { - // if no points or measures are being extracted, - // we will not create the filter report. - if(notExtracted.size() == 0) { - results.addComment("The output report ["+ filename +"] was not created. " - "The corresponding filter found no points/measures that " - "would not be extracted."); - return; + catch (...) { + for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) { + Application::Log(*grpIt); + } + throw; } - // Set up the output file for writing - std::ofstream out_stream; - out_stream.open(filename.toLatin1().data(), std::ios::out); - out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file - - out_stream << notExtracted[0]; - for(int index = 1; index < notExtracted.size(); index ++) { - out_stream << std::endl << notExtracted[index]; + for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) { + Application::Log(*grpIt); } - - out_stream.close(); - results.addKeyword(PvlKeyword("ReportCreated", filename)); - return; } - -/** - * This method removes the given control point from the given control network. - */ -void omit(ControlNet &cnet, int cp) { - ControlPoint *point = cnet.GetPoint(cp); - if (point->IsEditLocked()) point->SetEditLock(false); - cnet.DeletePoint(cp); - return; -} - -/** - * This method removes the given control measure from the given control point. - */ -void omit(ControlPoint *point, int cm) { - ControlMeasure *measure = point->GetMeasure(cm); - if (measure->IsEditLocked()) measure->SetEditLock(false); - point->Delete(cm); - return; -} - - -// Modified [PREFIX]IgnoredMeasures.txt output to exclude -// ignored reference measures since these measures will be extracted. diff --git a/isis/src/control/apps/cnetextract/tsts/basic/Makefile b/isis/src/control/apps/cnetextract/tsts/basic/Makefile deleted file mode 100644 index 3e7883e396..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/basic/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# Basic cnetextract test using noignore, nosinglemeasure, and nomeasureless filters -# -# Since a prefix is given, with the given filters, this test will make the -# following reports: -# preIgnoredPoints.txt -# preIgnoredMeasures.txt -# preSingleMeasurePoints.txt -# preMeasurelessPoints.txt -# -# The following will be extracted -# --points that are not ignored, with at least two measures -# for each of these points the following measures will be extracted: -# --reference measures (ignored or not) -# --non-ignored measures -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/pre \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNet.net \ - networkid=new \ - description=new \ - noignore=true \ - nosinglemeasure=true \ - nomeasureless=true \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/newList.txt; - $(RM) $(OUTPUT)/newList.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/src/control/apps/cnetextract/tsts/cubes/Makefile b/isis/src/control/apps/cnetextract/tsts/cubes/Makefile deleted file mode 100644 index 4c5484119b..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/cubes/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# Tests cnetextract using CUBES filters -# -# (1) The first run is a basic test of the filter. It extracts -# --non-ignored points that have at least one measure in the cubelist -# for each of these points the following measures will be extracted: -# --reference measures (ignored or not) -# --non-ignored measures -# (2) The second run uses an extra filter to remove any measures that are not -# in the cubelist -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/point \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNetPoint.net \ - networkid=new \ - description=new \ - noignore=true \ - cubes=true \ - cubelist=$(OUTPUT)/list.lis \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/pointNewList.txt; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/measure \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNetMeasure.net \ - networkid=new \ - description=new \ - noignore=true \ - cubes=true cubelist=$(OUTPUT)/list.lis \ - cubemeasures=true \ - retain_reference=true \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/measureNewList.txt; - $(RM) $(OUTPUT)/newList.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/src/control/apps/cnetextract/tsts/latlon/Makefile b/isis/src/control/apps/cnetextract/tsts/latlon/Makefile deleted file mode 100644 index 948928d895..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/latlon/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Test cnetextract using latlon range filters -# The following will be extracted -# --any points within the given lat/lon range -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/out \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNet.net \ - networkid=new \ - description=new \ - latlon=true \ - minlat=15.0 \ - maxlat=28.0 \ - minlon=20.0 \ - maxlon=28.0 \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/newList.txt; - $(RM) $(OUTPUT)/newList.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/src/control/apps/cnetextract/tsts/noOutputNet/Makefile b/isis/src/control/apps/cnetextract/tsts/noOutputNet/Makefile deleted file mode 100644 index 704dc5974b..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/noOutputNet/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# Test cnetextract when no output control net is created. -# No points or measures are extracted. -# No TOLIST file will be created. -# -# The following reports will be created: -# outIgnoreMeasures.txt -# outIgnorePoints.txt (Notice every point in this file is in the given pointlist) -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/out \ - tolist=$(OUTPUT)/emptyOut.lis \ - onet=$(OUTPUT)/emptyOut.net \ - networkid=new \ - description=new \ - noignore=true \ - pointlist=$(INPUT)/points.lis \ - | $(SED) 's+.*% Processed.*#+#+' \ - | grep -v "Processed" \ - | grep -v "Working" \ - > $(OUTPUT)/resultsLog.pvl; - $(RM) $(OUTPUT)/list.lis; - diff --git a/isis/src/control/apps/cnetextract/tsts/nofromlist/Makefile b/isis/src/control/apps/cnetextract/tsts/nofromlist/Makefile deleted file mode 100644 index 315497123e..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/nofromlist/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Test cnetextract with no FROMLIST given using NOIGNORE and MEASURELESS filters -# NOTE -- since no FROMLIST is given, no TOLIST can be created -# The following will be extracted -# --every non-ignored point with at least one measure -# for each of these points the following measures will be extracted: -# --every non-ignored measure -# --every ignored reference measure -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(APPNAME) cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/out \ - onet=$(OUTPUT)/newNet.net \ - networkid=new \ - description=new \ - noignore=true \ - nomeasureless=true \ - > /dev/null; diff --git a/isis/src/control/apps/cnetextract/tsts/pointlist/Makefile b/isis/src/control/apps/cnetextract/tsts/pointlist/Makefile deleted file mode 100644 index 20ad04ca4c..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/pointlist/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# Test cnetextract using pointlist filter -# The following will be extracted -# --every non-ignored point in the point list with at least one measure -# for each of these points the following measures will be extracted: -# --every non-ignored measure -# --every ignored reference measure -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/out \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNet.net \ - networkid=new \ - description=new \ - noignore=true \ - nomeasureless=true \ - pointlist=$(INPUT)/points.lis \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/newList.txt; - $(RM) $(OUTPUT)/newList.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/src/control/apps/cnetextract/tsts/reference/Makefile b/isis/src/control/apps/cnetextract/tsts/reference/Makefile deleted file mode 100644 index 7326ada3fa..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/reference/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Test cnetextract using reference filter -# The following will be extracted -# --every point and it's reference, as long as it is not measureless -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/out \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNet.net \ - networkid=new \ - description=new \ - reference=true \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/newList.txt; - $(RM) $(OUTPUT)/newList.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/src/control/apps/cnetextract/tsts/reportsNotCreated/Makefile b/isis/src/control/apps/cnetextract/tsts/reportsNotCreated/Makefile deleted file mode 100644 index bf1bdfcd65..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/reportsNotCreated/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# Test cnetextract when particular reports are not created. -# Run 4 tests: -# -# TEST RESULTS: REPORT NOT CREATED: -# -# (1) All points or measures are extracted. None created -# -# (2) No ignored points exist, IgnoredPoints.txt -# No non-reference ignore measures exist IgnoredMeasures.txt -# No single measure points exist SingleMeasurePoints.txt -# No measureless points exist MeasurelessPoints.txt -# All points fit tolerance TolerancePoints.txt -# All points are in lat/lon range LatLonOutOfRange.txt -# All points have determinable lat and lon NoLatLonPoints.txt -# (no output net or toList created) -# -# (3) All measures are ref NonReferenceMeasures.txt -# All points are fixed NonFixedPoints.txt -# All points are in pointlist NonListedPoints.txt -# -# (4) All points have measures in cubelist NonCubePoints.txt -# All measures are in cubelist NonCubeMeasures.txt -# All measures are in cubelist or references NonCubeMeasures.txt -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/1_cnet.net \ - prefix=$(OUTPUT)/1_ \ - tolist=$(OUTPUT)/outlist.lis \ - onet=$(OUTPUT)/1_sameAsInput.net \ - networkid=test \ - description=test \ - pointlist=$(INPUT)/allPoints.lis \ - | $(SED) 's+.*% Processed.*Group+Group+' \ - | grep -v "Processed" \ - | grep -v "cnetextract:" \ - > $(OUTPUT)/1_resultsLog.pvl; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/outlist.lis > $(OUTPUT)/1_toList.txt; - $(RM) $(OUTPUT)/outlist.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/2_cnet.net \ - prefix=$(OUTPUT)/2_ \ - tolist=$(OUTPUT)/outlist.lis \ - onet=$(OUTPUT)/2_outputNet.net \ - networkid=test \ - description=test \ - noignore=true \ - nosingle=true \ - nomeasureless=true \ - fixed=true \ - tolerance=true \ - pixel=5 \ - latlon=true \ - minlat=-90.0 \ - maxlat=90.0 \ - minlon=0.0 \ - maxlon=360 \ - | $(SED) 's+.*% Processed.*#+#+' \ - | grep -v "Processed" \ - | grep -v "cnetextract:" \ - > $(OUTPUT)/2_resultsLog.pvl; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/3_cnet.net \ - prefix=$(OUTPUT)/3_ \ - tolist=$(OUTPUT)/outlist.lis \ - onet=$(OUTPUT)/3_outputNet.net \ - networkid=test \ - description=test \ - reference=true \ - fixed=true \ - pointlist=$(INPUT)/allPoints.lis \ - | $(SED) 's+.*% Processed.*#+#+' \ - | grep -v "Processed" \ - | grep -v "cnetextract:" \ - > $(OUTPUT)/3_resultsLog.pvl; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/4_cnet.net \ - prefix=$(OUTPUT)/4_ \ - tolist=$(OUTPUT)/outlist.lis \ - onet=$(OUTPUT)/4_outputNet.net \ - networkid=test \ - description=test \ - reference=true \ - cubes=true \ - cubelist=$(OUTPUT)/list.lis \ - cubemeasure=true \ - retain=true \ - | $(SED) 's+.*% Processed.*Group+Group+' \ - | grep -v "Processed" \ - | grep -v "cnetextract:" \ - > $(OUTPUT)/4_resultsLog.pvl; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/outlist.lis > $(OUTPUT)/4_toList.txt; - $(RM) $(OUTPUT)/outlist.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/src/control/apps/cnetextract/tsts/tolerance/Makefile b/isis/src/control/apps/cnetextract/tsts/tolerance/Makefile deleted file mode 100644 index e819f82063..0000000000 --- a/isis/src/control/apps/cnetextract/tsts/tolerance/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# Test cnetextract using nomeasureless and tolerance filters -# The following will be extracted -# --any points with at least one measure -# --any points with with line/sample residual greater than 8 -APPNAME = cnetextract - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/list.lis; - $(APPNAME) fromlist=$(OUTPUT)/list.lis \ - cnet=$(INPUT)/cnet.net \ - prefix=$(OUTPUT)/out \ - tolist=$(OUTPUT)/newList.lis \ - onet=$(OUTPUT)/newNet.net \ - networkid=new \ - description=new \ - nomeasureless=true \ - tolerance=true \ - pixel=8.0 \ - > /dev/null; - $(SED) 's+/.*/input/+input/+' $(OUTPUT)/newList.lis > $(OUTPUT)/newList.txt; - $(RM) $(OUTPUT)/newList.lis; - $(RM) $(OUTPUT)/list.lis; diff --git a/isis/tests/FunctionalTestsCnetextract.cpp b/isis/tests/FunctionalTestsCnetextract.cpp new file mode 100644 index 0000000000..302338777c --- /dev/null +++ b/isis/tests/FunctionalTestsCnetextract.cpp @@ -0,0 +1,442 @@ +#include +#include +#include + +#include "cnetextract.h" +#include "Fixtures.h" +#include "Pvl.h" +#include "PvlGroup.h" +#include "TestUtilities.h" + +#include "gmock/gmock.h" + +using namespace Isis; +using testing::HasSubstr; + +static QString APP_XML = FileName("$ISISROOT/bin/xml/cnetextract.xml").expanded(); + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractExclusiveNoFromlist) { + QVector args = {"prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "noignore=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + try { + cnetextract( *network, options, &appLog ); + FAIL() << "Should not have been able to extract a new network with no fromlist set" << std::endl; + } catch(IException &e) { + EXPECT_THAT(e.what(), HasSubstr("To create a [TOLIST] the [FROMLIST] parameter must be provided.")); + } +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractExclusiveNoOnet) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "noignore=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + try { + cnetextract( *network, options, &appLog ); + FAIL() << "Should not have been able to extract a new network with no onet set" << std::endl; + } catch(IException &e) { + EXPECT_THAT(e.what(), HasSubstr("Parameter [ONET] has no value.")); + } +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractExclusiveNoFilter) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + try { + cnetextract( *network, options, &appLog ); + FAIL() << "Should not have been able to extract a new network with no filter" << std::endl; + } catch(IException &e) { + EXPECT_THAT(e.what(), HasSubstr("At least one filter must be selected")); + } +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractExclusiveNoIgnore) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "noignore=true", + "networkid=new", + "description=new"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + points[0]->SetIgnored(true); + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(outputNet.GetNetworkId(), "new"); + ASSERT_EQ(outputNet.Description(), "new"); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["IgnoredPoints"]), 1); + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["IgnoredMeasures"]), 0); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 1); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 2); + + FileName ignoredPointsFile(options.GetAsString("prefix") + "IgnoredPoints.txt"); + EXPECT_TRUE(ignoredPointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractExclusiveNoSingleMeasure) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "nosinglemeasure=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + // Deletes one of the two meausres that would have been removed + for (auto measure : points[0]->getMeasures()) { + points[0]->Delete(measure); + break; + } + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["SingleMeasurePoints"]), 1); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 1); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 1); + + FileName measurePointsFile(options.GetAsString("prefix") + "SingleMeasurePoints.txt"); + EXPECT_TRUE(measurePointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractExclusiveNoMeasureless) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "nomeasureless=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + // Deletes both measures that would have been removed + for (auto measure : points[0]->getMeasures()) { + points[0]->Delete(measure); + } + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["MeasurelessPoints"]), 1); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 1); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 0); + + FileName measurelessPointsFile(options.GetAsString("prefix") + "MeasurelessPoints.txt"); + EXPECT_TRUE(measurelessPointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractInclusiveReference) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "reference=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonReferenceMeasures"]), 25); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 0); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 25); + + FileName referencePointsFile(options.GetAsString("prefix") + "NonReferenceMeasures.txt"); + EXPECT_TRUE(referencePointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractInclusiveFixed) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "fixed=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + points[0]->SetType(ControlPoint::PointType::Fixed); + points[1]->SetType(ControlPoint::PointType::Fixed); + points[2]->SetType(ControlPoint::PointType::Fixed); + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonFixedPoints"]), 13); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 13); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 35); + + FileName fixedPointsFile(options.GetAsString("prefix") + "NonFixedPoints.txt"); + EXPECT_TRUE(fixedPointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractInclusiveContrained) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/pre", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "constrained=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + points[0]->SetType(ControlPoint::PointType::Constrained); + points[1]->SetType(ControlPoint::PointType::Constrained); + points[2]->SetType(ControlPoint::PointType::Constrained); + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 13); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 35); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractInclusiveEditlock) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "editlock=true"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + points[0]->SetEditLock(true); + points[1]->SetEditLock(true); + points[2]->SetEditLock(true); + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 13); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 35); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractInclusivePixeltolerence) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "tolerance=true", + "pixeltolerance=9.0"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + for (int i = 0; i < points.size(); i++) { + points[i]->getMeasures()[0]->SetResidual(i, i); + } + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["TolerancePoints"]), 9); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 9); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 23); + + FileName tolerancePointsFile(options.GetAsString("prefix") + "TolerancePoints.txt"); + EXPECT_TRUE(tolerancePointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractInclusivePointlist) { + QString pointListFile = tempDir.path() + "/pointList.lis"; + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "pointlist=" + pointListFile}; + + FileList pointList; + pointList.append("test0001"); + pointList.append("test0002"); + pointList.append("test0003"); + pointList.append("test0004"); + pointList.append("test0005"); + pointList.write(pointListFile); + + UserInterface options(APP_XML, args); + Pvl appLog; + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonListedPoints"]), 11); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 11); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 30); + + FileName nonListedPointsFile(options.GetAsString("prefix") + "NonListedPoints.txt"); + EXPECT_TRUE(nonListedPointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractCubeCubelist) { + QString reducedCubeList = tempDir.path() + "reducedCubes.lis"; + cubeList->pop_back(); + cubeList->pop_back(); + cubeList->write(reducedCubeList); + + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "cubes=true", + "cubelist=" + reducedCubeList}; + + UserInterface options(APP_XML, args); + Pvl appLog; + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonCubePoints"]), 3); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 3); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 6); + + FileName nonCubePointsFile(options.GetAsString("prefix") + "NonCubePoints.txt"); + EXPECT_TRUE(nonCubePointsFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractCubeCubemeasures) { + QString reducedCubeList = tempDir.path() + "reducedCubes.lis"; + cubeList->pop_back(); + cubeList->pop_back(); + cubeList->write(reducedCubeList); + + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "cubes=true", + "cubelist=" + reducedCubeList, + "cubemeasures=true"}; + + UserInterface options(APP_XML, args); + Pvl appLog; + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonCubePoints"]), 3); + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonCubeMeasures"]), 28); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 3); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 28); + + FileName nonCubePointsFile(options.GetAsString("prefix") + "NonCubePoints.txt"); + EXPECT_TRUE(nonCubePointsFile.fileExists()); + + FileName nonCubeMeasuresFile(options.GetAsString("prefix") + "NonCubeMeasures.txt"); + EXPECT_TRUE(nonCubeMeasuresFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractCubeRetainreference) { + QString reducedCubeList = tempDir.path() + "reducedCubes.lis"; + cubeList->pop_back(); + cubeList->pop_back(); + cubeList->write(reducedCubeList); + + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "cubes=true", + "cubelist=" + reducedCubeList, + "cubemeasures=true", + "retain_reference=true"}; + + UserInterface options(APP_XML, args); + Pvl appLog; + + QList points = network->GetPoints(); + + points[0]->SetRefMeasure(points[0]->getMeasures()[1]); + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonCubePoints"]), 3); + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NonCubeMeasures"]), 28); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 3); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 27); + + FileName nonCubePointsFile(options.GetAsString("prefix") + "NonCubePoints.txt"); + EXPECT_TRUE(nonCubePointsFile.fileExists()); + + FileName nonCubeMeasuresFile(options.GetAsString("prefix") + "NonCubeMeasures.txt"); + EXPECT_TRUE(nonCubeMeasuresFile.fileExists()); +} + +TEST_F(ThreeImageNetwork, FunctionalTestCnetextractLatlon) { + QVector args = {"fromlist=" + cubeListFile, + "prefix=" + tempDir.path() + "/", + "tolist=" + tempDir.path() + "/newList.lis", + "onet=" + tempDir.path() + "/newNet.net", + "latlon=true", + "minlat=0", "maxlat=2", + "minlon=0", "maxlon=1"}; + + UserInterface options(APP_XML, args); + Pvl appLog; + + cnetextract( *network, options, &appLog ); + + ControlNet outputNet(options.GetFileName("ONET")); + + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["LatLonOutOfRange"]), 10); + ASSERT_EQ(int(appLog.findGroup("ResultSummary")["NoLatLonPoints"]), 0); + + ASSERT_EQ(network->GetNumPoints() - outputNet.GetNumPoints(), 10); + ASSERT_EQ(network->GetNumMeasures() - outputNet.GetNumMeasures(), 25); + + FileName outOfRangeFile(options.GetAsString("prefix") + "LatLonOutOfRange.txt"); + EXPECT_TRUE(outOfRangeFile.fileExists()); + + FileName noLatLonPointsFile(options.GetAsString("prefix") + "NoLatLonPoints.txt"); + EXPECT_FALSE(noLatLonPointsFile.fileExists()); +}