From d1b146c423f312dd4d8d600f4ff3948f6bf2af0e Mon Sep 17 00:00:00 2001 From: Tim Giroux Date: Wed, 9 Dec 2020 14:50:50 -0700 Subject: [PATCH 1/7] basic app conversion --- isis/src/control/apps/pointreg/main.cpp | 835 +------------------ isis/src/control/apps/pointreg/pointreg.cpp | 839 ++++++++++++++++++++ isis/src/control/apps/pointreg/pointreg.h | 13 + isis/tests/FunctionalTestsPointreg.cpp | 42 + 4 files changed, 906 insertions(+), 823 deletions(-) create mode 100644 isis/src/control/apps/pointreg/pointreg.cpp create mode 100644 isis/src/control/apps/pointreg/pointreg.h create mode 100644 isis/tests/FunctionalTestsPointreg.cpp diff --git a/isis/src/control/apps/pointreg/main.cpp b/isis/src/control/apps/pointreg/main.cpp index 1126a1c43c..d9bdff1659 100644 --- a/isis/src/control/apps/pointreg/main.cpp +++ b/isis/src/control/apps/pointreg/main.cpp @@ -1,839 +1,28 @@ -#define GUIHELPERS - #include "Isis.h" -#include - -#include "AutoReg.h" -#include "AutoRegFactory.h" -#include "Camera.h" -#include "Chip.h" -#include "ControlMeasure.h" -#include "ControlMeasureLogData.h" -#include "ControlNet.h" -#include "ControlPoint.h" -#include "Cube.h" -#include "CubeManager.h" -#include "Pixel.h" -#include "Progress.h" -#include "SerialNumberList.h" +#include "Application.h" +#include "Process.h" #include "UserInterface.h" -#include "IException.h" -#include "iTime.h" - -using namespace std; -using namespace Isis; - - -AutoReg *ar; -AutoReg *validator; -CubeManager *cubeMgr; -SerialNumberList *files; -QList *falsePositives; - -int ignored; -int locked; -int registered; -int notintersected; -int unregistered; - -bool logFalsePositives; -bool revertFalsePositives; -int expansion; -double resTolerance; - -/** - * @author 2012-04-06 Travis Addair - * - * @internal - */ -class Validation { - public: - enum Result { - Untested, - Success, - Failure, - Skipped - }; - - Validation(QString test, ControlMeasure *held, ControlMeasure *registered, - double tolerance) { - - m_test = test; - m_pointId = registered->Parent()->GetId(); - m_heldId = FileName( - files->fileName(held->GetCubeSerialNumber())).baseName(); - m_registeredId = FileName( - files->fileName(registered->GetCubeSerialNumber())).baseName(); - - m_aprioriSample = registered->GetSample(); - m_aprioriLine = registered->GetLine(); - m_shiftSample = 0.0; - m_shiftLine = 0.0; - - m_resDiff = 0.0; - m_resTolerance = 0.0; - - m_shift = 0.0; - m_shiftTolerance = tolerance; - m_result = Untested; - } - - ~Validation() {} - - bool untested() const { - return m_result == Untested; - } - - bool succeeded() const { - return m_result == Success; - } - - bool failed() const { - return m_result == Failure; - } - - bool skipped() const { - return m_result == Skipped; - } - - QString resultString() const { - switch (m_result) { - case Untested: return "Untested"; - case Success: return "Success"; - case Failure: return "Failure"; - case Skipped: return "Skipped"; - default: throw IException(IException::Programmer, - "Unknown value for m_result", _FILEINFO_); - } - } - - void setValidity(bool valid) { - m_result = valid ? Success : Failure; - } - - void skip(QString testFailure) { - m_test = testFailure; - m_result = Skipped; - } - - void compareResolutions(double heldResolution, double registeredResolution, - double tolerance) { - - m_resDiff = fabs(heldResolution - registeredResolution); - m_resTolerance = tolerance; - - if (m_resDiff > m_resTolerance) skip("Resolution Tolerance"); - } - - void compare(double shiftSample, double shiftLine) { - m_shiftSample = shiftSample; - m_shiftLine = shiftLine; - - double sampleShift = shiftSample - m_aprioriSample; - double lineShift = shiftLine - m_aprioriLine; - - m_shift = sqrt(pow(sampleShift, 2) + pow(lineShift, 2)); - setValidity(m_shift <= m_shiftTolerance); - } - - static QString getHeader() { - return "Result,Test,PointID,HeldID,RegisteredID," - "Sample,Line,ShiftedSample,ShiftedLine," - "ResolutionDifference,ResolutionTolerance," - "Shift,ShiftTolerance"; - } - - QString toString() { - stringstream stream; - stream << - resultString() << "," << m_test << "," << m_pointId << "," << - m_heldId << "," << m_registeredId << "," << - m_aprioriSample << "," << m_aprioriLine << "," << - m_shiftSample << "," << m_shiftLine << "," << - m_resDiff << "," << m_resTolerance << "," << - m_shift << "," << m_shiftTolerance; - return stream.str().c_str(); - } - - private: - QString m_test; - QString m_pointId; - QString m_heldId; - QString m_registeredId; - - double m_aprioriSample; - double m_aprioriLine; - double m_shiftSample; - double m_shiftLine; - - double m_resDiff; - double m_resTolerance; - - double m_shift; - double m_shiftTolerance; - - Result m_result; -}; - - -void registerPoint(ControlPoint *outPoint, ControlMeasure *patternCM, - QString registerMeasures, bool outputFailed); -void validatePoint(ControlPoint *point, ControlMeasure *reference, - double shiftTolerance); -Validation backRegister(ControlMeasure *measure, ControlMeasure *reference, - double shiftTolerance); - -double getResolution(Cube &cube, ControlMeasure &measure); -void verifyCube(Cube & cube); -bool outputValue(ofstream &os, double value); -int calcGoodMeasureCount(const ControlPoint *point); -void printTemp(); - -map GuiHelpers() { - map helper; - helper["PrintTemp"] = (void *) printTemp; - return helper; -} +#include "pointreg.h" +using namespace Isis; void IsisMain() { - // Initialize variables - ar = NULL; - validator = NULL; - cubeMgr = NULL; - files = NULL; - falsePositives = NULL; - - ignored = 0; - locked = 0; - registered = 0; - notintersected = 0; - unregistered = 0; - - logFalsePositives = false; - revertFalsePositives = false; - // Get user interface UserInterface &ui = Application::GetUserInterface(); - - if (ui.WasEntered("FALSEPOSITIVES")) { - logFalsePositives = true; - falsePositives = new QList; - } - - // Determine which points/measures to register - QString registerPoints = ui.GetString("POINTS"); - QString registerMeasures = ui.GetString("MEASURES"); - - bool outputFailed = ui.GetBoolean("OUTPUTFAILED"); - bool outputIgnored = ui.GetBoolean("OUTPUTIGNORED"); - - // Open the files list in a SerialNumberList for - // reference by SerialNumber - files = new SerialNumberList(ui.GetFileName("FROMLIST")); - - // Create the output ControlNet from the input file - ControlNet outNet(ui.GetFileName("CNET")); - - if (outNet.GetNumPoints() <= 0) { - QString msg = "Control network [" + ui.GetFileName("CNET") + "] "; - msg += "contains no points"; - throw IException(IException::User, msg, _FILEINFO_); - } - - outNet.SetUserName(Application::UserName()); - - // Create an AutoReg from the template file - Pvl pvl(ui.GetFileName("DEFFILE")); - ar = AutoRegFactory::Create(pvl); - - Progress progress; - progress.SetText("Registering Points"); - progress.SetMaximumSteps(outNet.GetNumPoints()); - progress.CheckStatus(); - - // Get the maximum allowable number of open files - struct rlimit limit; - if (getrlimit(RLIMIT_NOFILE, &limit) != 0) { - QString msg = "Cannot read the maximum allowable open files from system resources."; - throw IException(IException::Programmer, msg, _FILEINFO_); - } - // Allow for library files, etc - unsigned int maxOpenFiles = limit.rlim_cur * .60; - - cubeMgr = new CubeManager; - cubeMgr->SetNumOpenCubes(maxOpenFiles); - - QString validate = ui.GetString("VALIDATE"); - if (validate != "SKIP") { - validator = AutoRegFactory::Create(pvl); - - validator->SetTolerance(validator->MostLenientTolerance()); - validator->SetPatternZScoreMinimum(DBL_MIN); - validator->SetPatternValidPercent(DBL_MIN); - validator->SetSubsearchValidPercent(DBL_MIN); - - validator->SetSurfaceModelDistanceTolerance(validator->WindowSize()); - - expansion = ui.WasEntered("SEARCH") ? - ui.GetInteger("SEARCH") : validator->WindowSize(); - expansion *= 2; - - int patternSamples = validator->PatternChip()->Samples(); - int patternLines = validator->PatternChip()->Lines(); - validator->SearchChip()->SetSize( - patternSamples + expansion, patternLines + expansion); - - revertFalsePositives = ui.GetBoolean("REVERT"); - resTolerance = ui.GetDouble("RESTOLERANCE"); - } - - // Register the points and create a new - // ControlNet containing the refined measurements - int i = 0; - while (i < outNet.GetNumPoints()) { - progress.CheckStatus(); - - ControlPoint * outPoint = outNet.GetPoint(i); - - // Establish whether or not we want to attempt to register this point. - bool wantToRegister = true; - if (outPoint->IsIgnored()) { - if (registerPoints == "NONIGNORED") wantToRegister = false; - } - else { - if (registerPoints == "IGNORED") wantToRegister = false; - } - - // Check if this is a point we wish to disregard. - if (!wantToRegister) { - // Keep track of how many ignored points we didn't register. - if (outPoint->IsIgnored()) { - ignored++; - - // If the point is ignored and the user doesn't want them, delete it - if (!outputIgnored) { - outNet.DeletePoint(i); - continue; - } - } - } - else { // "Ignore" or "valid" point to be registered - if (outPoint->IsIgnored()) { - outPoint->SetIgnored(false); - } - - ControlMeasure * patternCM = outPoint->GetRefMeasure(); - - // In case this is an implicit reference, make it explicit since we'll be - // registering measures to it - outPoint->SetRefMeasure(patternCM); - - if (validate != "ONLY") { - registerPoint(outPoint, patternCM, registerMeasures, outputFailed); - } - if (validate != "SKIP") { - validatePoint(outPoint, patternCM, ui.GetDouble("SHIFT")); - } - - // Check to see if the control point has now been assigned - // to "ignore". If not, add it to the network. If so, only - // add it to the output if the OUTPUTIGNORED parameter is selected - // 2008-11-14 Jeannie Walldren - if (outPoint->IsIgnored()) { - ignored++; - if (!outputIgnored) { - outNet.DeletePoint(i); - continue; - } - } - } - - // The point wasn't deleted, so the network size is the same and we should - // increment our index. - i++; - } - - // If flatfile was entered, create the flatfile - // The flatfile is comma seperated and can be imported into an excel - // spreadsheet - if (ui.WasEntered("FLATFILE")) { - QString fFile = FileName(ui.GetFileName("FLATFILE")).expanded(); - - ofstream os; - os.open(fFile.toLatin1().data(), ios::out); - os << - "PointId,Filename,MeasureType,Reference,EditLock,Ignore,Registered," << - "OriginalMeasurementSample,OriginalMeasurementLine," << - "RegisteredMeasurementSample,RegisteredMeasurementLine,SampleShift," << - "LineShift,PixelShift,ZScoreMin,ZScoreMax,GoodnessOfFit" << endl; - os << Null << endl; - - // Create a ControlNet from the original input file - ControlNet inNet(ui.GetFileName("CNET")); - - for (int i = 0; i < outNet.GetNumPoints(); i++) { - - // get point from output control net and its - // corresponding point from input control net - const ControlPoint * outPoint = outNet.GetPoint(i); - QString outPointId = outPoint->GetId(); - const ControlPoint * inPoint = inNet.GetPoint(outPointId); - - if (!outPoint->IsIgnored()) { - for (int i = 0; i < outPoint->GetNumMeasures(); i++) { - - // Get measure and find its corresponding measure from input net - const ControlMeasure * cmTrans = outPoint->GetMeasure(i); - const ControlMeasure * cmOrig = - inPoint->GetMeasure((QString) cmTrans->GetCubeSerialNumber()); - - QString pointId = outPoint->GetId(); - - QString fullName = files->fileName(cmTrans->GetCubeSerialNumber()); - QString filename = FileName(fullName).baseName(); - - QString measureType = cmTrans->MeasureTypeToString( - cmTrans->GetType()); - QString reference = outPoint->GetRefMeasure() == cmTrans ? - "true" : "false"; - QString editLock = cmTrans->IsEditLocked() ? "true" : "false"; - QString ignore = cmTrans->IsIgnored() ? "true" : "false"; - QString registered = - !cmOrig->IsRegistered() && cmTrans->IsRegistered() ? - "true" : "false"; - - double inSamp = cmOrig->GetSample(); - double inLine = cmOrig->GetLine(); - - double outSamp = cmTrans->GetSample(); - double outLine = cmTrans->GetLine(); - - os << - pointId << "," << - filename << "," << - measureType << "," << - reference << "," << - editLock << "," << - ignore << "," << - registered << "," << - inSamp << "," << - inLine << "," << - outSamp << "," << - outLine; - - double sampleShift = cmTrans->GetSampleShift(); - double lineShift = cmTrans->GetLineShift(); - double pixelShift = cmTrans->GetPixelShift(); - - outputValue(os, sampleShift); - outputValue(os, lineShift); - outputValue(os, pixelShift); - - double zScoreMin = cmTrans->GetLogData( - ControlMeasureLogData::MinimumPixelZScore).GetNumericalValue(); - double zScoreMax = cmTrans->GetLogData( - ControlMeasureLogData::MaximumPixelZScore).GetNumericalValue(); - double goodnessOfFit = cmTrans->GetLogData( - ControlMeasureLogData::GoodnessOfFit).GetNumericalValue(); - - outputValue(os, zScoreMin); - outputValue(os, zScoreMax); - outputValue(os, goodnessOfFit); - - os << endl; - } - } - } - } - - if (logFalsePositives) { - QString filename = FileName(ui.GetFileName("FALSEPOSITIVES")).expanded(); - ofstream os; - os.open(filename.toLatin1().data(), ios::out); - - os << Validation::getHeader() << endl; - for (int i = 0; i < falsePositives->size(); i++) { - os << (*falsePositives)[i].toStdString() << endl; - } - - os.close(); - } - - PvlGroup pLog("Points"); - pLog += PvlKeyword("Total", toString(outNet.GetNumPoints())); - pLog += PvlKeyword("Ignored", toString(ignored)); - Application::Log(pLog); - - PvlGroup mLog("Measures"); - mLog += PvlKeyword("Locked", toString(locked)); - mLog += PvlKeyword("Registered", toString(registered)); - mLog += PvlKeyword("NotIntersected", toString(notintersected)); - mLog += PvlKeyword("Unregistered", toString(unregistered)); - Application::Log(mLog); - - // Log Registration Statistics - Pvl arPvl = ar->RegistrationStatistics(); - - for (int i = 0; i < arPvl.groups(); i++) { - Application::Log(arPvl.group(i)); - } - - // add the auto registration information to print.prt - PvlGroup autoRegTemplate = ar->RegTemplate(); - Application::Log(autoRegTemplate); - - if (validator) { - PvlGroup validationGroup("ValidationStatistics"); - - Pvl validationPvl = validator->RegistrationStatistics(); - for (int g = 0; g < validationPvl.groups(); g++) { - PvlGroup &group = validationPvl.group(g); - if (group.keywords() > 0) { - group[0].addComment(group.name()); - for (int k = 0; k < group.keywords(); k++) - validationGroup.addKeyword(group[k]); - } - } - - Application::Log(validationGroup); - - PvlGroup validationTemplate = validator->UpdatedTemplate(); - validationTemplate.setName("ValidationTemplate"); - Application::Log(validationTemplate); - } - - outNet.Write(ui.GetFileName("ONET")); - - delete ar; - ar = NULL; - - delete validator; - validator = NULL; - - delete cubeMgr; - cubeMgr = NULL; - - delete files; - files = NULL; - - delete falsePositives; - falsePositives = NULL; -} - - -void registerPoint(ControlPoint *outPoint, ControlMeasure *patternCM, - QString registerMeasures, bool outputFailed) { - - Cube &patternCube = *cubeMgr->OpenCube( - files->fileName(patternCM->GetCubeSerialNumber())); - - ar->PatternChip()->TackCube(patternCM->GetSample(), patternCM->GetLine()); - ar->PatternChip()->Load(patternCube); - - if (patternCM->IsEditLocked()) { - locked++; - } - - if (outPoint->GetRefMeasure() != patternCM) { - outPoint->SetRefMeasure(patternCM); - } - - // Register all the unlocked measurements - int j = 0; - while (j < outPoint->GetNumMeasures()) { - if (j != outPoint->IndexOfRefMeasure()) { - - ControlMeasure * measure = outPoint->GetMeasure(j); - if (measure->IsEditLocked()) { - // If the measurement is locked, keep it as is and go to next measure - locked++; - } - else if (!measure->IsMeasured() || registerMeasures != "CANDIDATES") { - - // refresh pattern cube pointer to ensure it stays valid - Cube &patternCube = *cubeMgr->OpenCube(files->fileName( - patternCM->GetCubeSerialNumber())); - Cube &searchCube = *cubeMgr->OpenCube(files->fileName( - measure->GetCubeSerialNumber())); - - ar->SearchChip()->TackCube(measure->GetSample(), measure->GetLine()); - - verifyCube(patternCube); - verifyCube(searchCube); - - try { - ar->SearchChip()->Load(searchCube, *(ar->PatternChip()), patternCube); - - // If the measurements were correctly registered - // Write them to the new ControlNet - AutoReg::RegisterStatus res = ar->Register(); - searchCube.clearIoCache(); - patternCube.clearIoCache(); - - double score1, score2; - ar->ZScores(score1, score2); - - // Set the minimum and maximum z-score values for the measure - measure->SetLogData(ControlMeasureLogData( - ControlMeasureLogData::MinimumPixelZScore, score1)); - measure->SetLogData(ControlMeasureLogData( - ControlMeasureLogData::MaximumPixelZScore, score2)); - - if (ar->Success()) { - // Check to make sure the newly calculated measure position is on - // the surface of the planet - Camera *cam = searchCube.camera(); - bool foundLatLon = cam->SetImage(ar->CubeSample(), ar->CubeLine()); - - if (foundLatLon) { - registered++; - - if (res == AutoReg::SuccessSubPixel) { - measure->SetType(ControlMeasure::RegisteredSubPixel); - } - else { - measure->SetType(ControlMeasure::RegisteredPixel); - } - - measure->SetLogData(ControlMeasureLogData( - ControlMeasureLogData::GoodnessOfFit, - ar->GoodnessOfFit())); - - measure->SetAprioriSample(measure->GetSample()); - measure->SetAprioriLine(measure->GetLine()); - measure->SetCoordinate(ar->CubeSample(), ar->CubeLine()); - measure->SetIgnored(false); - - // We successfully registered the current measure to the - // reference, and since we set the current measure to be - // unignored, it follows that its reference should also be made - // unignored. - patternCM->SetIgnored(false); - } - else { - notintersected++; - - if (outputFailed) { - measure->SetType(ControlMeasure::Candidate); - measure->SetIgnored(true); - } - else { - outPoint->Delete(j); - continue; - } - } - } - // Else use the original marked as "Candidate" - else { - unregistered++; - - if (outputFailed) { - measure->SetType(ControlMeasure::Candidate); - - if (res == AutoReg::FitChipToleranceNotMet) { - measure->SetLogData(ControlMeasureLogData( - ControlMeasureLogData::GoodnessOfFit, - ar->GoodnessOfFit())); - } - measure->SetIgnored(true); - } - else { - outPoint->Delete(j); - continue; - } - } - } - catch (IException &e) { - unregistered++; - - if (outputFailed) { - measure->SetType(ControlMeasure::Candidate); - measure->SetIgnored(true); - } - else { - outPoint->Delete(j); - continue; - } - } - } - } - - // If we made it here (without continuing on to the next measure), - // then the measure wasn't deleted and we should therefore increment - // the index of the measure we're looking at. - j++; - } - - // Jeff Anderson put in this test (Dec 2, 2008) to allow for control - // points to be good so long as at least two measure could be - // registered. When a measure can't be registered to the reference then - // that measure is set to be ignored where in the past the whole point - // was ignored - if (calcGoodMeasureCount(outPoint) < 2 && - outPoint->GetType() != ControlPoint::Fixed) { - outPoint->SetIgnored(true); - } - - // Otherwise, ignore=false. This is already set at the beginning of the - // registration process -} - - -void validatePoint(ControlPoint *point, ControlMeasure *reference, - double shiftTolerance) { - - for (int i = 0; i < point->GetNumMeasures(); i++) { - if (i != point->IndexOfRefMeasure()) { - ControlMeasure *measure = point->GetMeasure(i); - if (measure->IsMeasured() && !measure->IsEditLocked()) { - Validation validation = backRegister( - reference, measure, shiftTolerance); - - // If the validation failed, or we were unable to perform the validation - // due to registration errors, we consider this registration to be a - // false positive - if (validation.failed() || validation.untested()) { - if (revertFalsePositives) { - measure->SetType(ControlMeasure::Candidate); - measure->SetCoordinate( - measure->GetAprioriSample(), measure->GetAprioriLine()); - measure->SetIgnored(true); - // TODO remove log data here - } - } - - // If the registration did not succeed for whatever reason (untested, - // failed, or skipped due to incompatible data), log the result - if (logFalsePositives) { - if (!validation.succeeded()) { - falsePositives->append( - validation.toString()); - } - } - } - } - } -} - - -Validation backRegister(ControlMeasure *reference, ControlMeasure *measure, - double shiftTolerance) { - - Validation validation( - "Back-Registration", measure, reference, shiftTolerance); - - Cube &patternCube = *cubeMgr->OpenCube(files->fileName( - measure->GetCubeSerialNumber())); - Cube &searchCube = *cubeMgr->OpenCube(files->fileName( - reference->GetCubeSerialNumber())); - - double patternRes = getResolution(patternCube, *measure); - double searchRes = getResolution(searchCube, *reference); - validation.compareResolutions(patternRes, searchRes, resTolerance); - - if (validation.skipped()) - return validation; - - validator->SearchChip()->TackCube( - reference->GetSample(), reference->GetLine()); - validator->PatternChip()->TackCube(measure->GetSample(), measure->GetLine()); - validator->PatternChip()->Load(patternCube); - - verifyCube(patternCube); - verifyCube(searchCube); - - try { - validator->SearchChip()->Load( - searchCube, *(validator->PatternChip()), patternCube); - - // If the measurements were correctly registered - // Write them to the new ControlNet - validator->Register(); - searchCube.clearIoCache(); - patternCube.clearIoCache(); - - if (validator->Success()) { - // Check to make sure the newly calculated measure position is on - // the surface of the planet - Camera *cam = searchCube.camera(); - bool foundLatLon = cam->SetImage( - validator->CubeSample(), validator->CubeLine()); - - if (foundLatLon) { - validation.compare( - validator->CubeSample(), validator->CubeLine()); - } - } - } - catch (IException &e) { - } - - return validation; -} - - -double getResolution(Cube &cube, ControlMeasure &measure) { - // TODO retrieve for projection - Camera *camera = cube.camera(); - camera->SetImage(measure.GetSample(), measure.GetLine()); - return camera->PixelResolution(); -} - - -// Verify a cube has either a Camera or a Projection, throw an exception if not -void verifyCube(Cube & cube) { + Pvl appLog; try { - cube.camera(); + pointreg(ui, &appLog); } - catch (IException &camError) { - try { - cube.projection(); - } - catch (IException &projError) { - projError.append(camError); - throw projError; + catch (...) { + for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) { + Application::Log(*grpIt); } + throw; } -} - - -bool outputValue(ofstream &os, double value) { - os << ","; - if (fabs(value) > DBL_EPSILON && value != Null) { - os << value; - return true; - } - else { - os << "NA"; - return false; + for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) { + Application::Log(*grpIt); } } - - -int calcGoodMeasureCount(const ControlPoint *point) { - int goodMeasureCount = 0; - for (int i = 0; i < point->GetNumMeasures(); i++) { - const ControlMeasure *measure = point->GetMeasure(i); - if (!measure->IsIgnored()) goodMeasureCount++; - } - - return goodMeasureCount; -} - - -// Helper function to print out template to session log -void printTemp() { - UserInterface &ui = Application::GetUserInterface(); - - // Get template pvl - Pvl userTemp; - userTemp.read(ui.GetFileName("DEFFILE")); - - //Write template file out to the log - Isis::Application::GuiLog(userTemp); -} - diff --git a/isis/src/control/apps/pointreg/pointreg.cpp b/isis/src/control/apps/pointreg/pointreg.cpp new file mode 100644 index 0000000000..62cb24adc9 --- /dev/null +++ b/isis/src/control/apps/pointreg/pointreg.cpp @@ -0,0 +1,839 @@ +#define GUIHELPERS + +#include "Isis.h" + +#include + +#include "pointreg.h" + +#include "AutoReg.h" +#include "AutoRegFactory.h" +#include "Camera.h" +#include "Chip.h" +#include "ControlMeasure.h" +#include "ControlMeasureLogData.h" +#include "ControlNet.h" +#include "ControlPoint.h" +#include "Cube.h" +#include "CubeManager.h" +#include "Pixel.h" +#include "Progress.h" +#include "SerialNumberList.h" +#include "UserInterface.h" +#include "IException.h" +#include "iTime.h" + +using namespace std; +namespace Isis { + + AutoReg *ar; + AutoReg *validator; + CubeManager *cubeMgr; + SerialNumberList *files; + QList *falsePositives; + + int ignored; + int locked; + int registered; + int notintersected; + int unregistered; + + bool logFalsePositives; + bool revertFalsePositives; + int expansion; + double resTolerance; + + /** + * @author 2012-04-06 Travis Addair + * + * @internal + */ + class Validation { + public: + enum Result { + Untested, + Success, + Failure, + Skipped + }; + + Validation(QString test, ControlMeasure *held, ControlMeasure *registered, + double tolerance) { + + m_test = test; + m_pointId = registered->Parent()->GetId(); + m_heldId = FileName( + files->fileName(held->GetCubeSerialNumber())).baseName(); + m_registeredId = FileName( + files->fileName(registered->GetCubeSerialNumber())).baseName(); + + m_aprioriSample = registered->GetSample(); + m_aprioriLine = registered->GetLine(); + m_shiftSample = 0.0; + m_shiftLine = 0.0; + + m_resDiff = 0.0; + m_resTolerance = 0.0; + + m_shift = 0.0; + m_shiftTolerance = tolerance; + + m_result = Untested; + } + + ~Validation() {} + + bool untested() const { + return m_result == Untested; + } + + bool succeeded() const { + return m_result == Success; + } + + bool failed() const { + return m_result == Failure; + } + + bool skipped() const { + return m_result == Skipped; + } + + QString resultString() const { + switch (m_result) { + case Untested: return "Untested"; + case Success: return "Success"; + case Failure: return "Failure"; + case Skipped: return "Skipped"; + default: throw IException(IException::Programmer, + "Unknown value for m_result", _FILEINFO_); + } + } + + void setValidity(bool valid) { + m_result = valid ? Success : Failure; + } + + void skip(QString testFailure) { + m_test = testFailure; + m_result = Skipped; + } + + void compareResolutions(double heldResolution, double registeredResolution, + double tolerance) { + + m_resDiff = fabs(heldResolution - registeredResolution); + m_resTolerance = tolerance; + + if (m_resDiff > m_resTolerance) skip("Resolution Tolerance"); + } + + void compare(double shiftSample, double shiftLine) { + m_shiftSample = shiftSample; + m_shiftLine = shiftLine; + + double sampleShift = shiftSample - m_aprioriSample; + double lineShift = shiftLine - m_aprioriLine; + + m_shift = sqrt(pow(sampleShift, 2) + pow(lineShift, 2)); + setValidity(m_shift <= m_shiftTolerance); + } + + static QString getHeader() { + return "Result,Test,PointID,HeldID,RegisteredID," + "Sample,Line,ShiftedSample,ShiftedLine," + "ResolutionDifference,ResolutionTolerance," + "Shift,ShiftTolerance"; + } + + QString toString() { + stringstream stream; + stream << + resultString() << "," << m_test << "," << m_pointId << "," << + m_heldId << "," << m_registeredId << "," << + m_aprioriSample << "," << m_aprioriLine << "," << + m_shiftSample << "," << m_shiftLine << "," << + m_resDiff << "," << m_resTolerance << "," << + m_shift << "," << m_shiftTolerance; + return stream.str().c_str(); + } + + private: + QString m_test; + QString m_pointId; + QString m_heldId; + QString m_registeredId; + + double m_aprioriSample; + double m_aprioriLine; + double m_shiftSample; + double m_shiftLine; + + double m_resDiff; + double m_resTolerance; + + double m_shift; + double m_shiftTolerance; + + Result m_result; + }; + + + void registerPoint(ControlPoint *outPoint, ControlMeasure *patternCM, + QString registerMeasures, bool outputFailed); + void validatePoint(ControlPoint *point, ControlMeasure *reference, + double shiftTolerance); + Validation backRegister(ControlMeasure *measure, ControlMeasure *reference, + double shiftTolerance); + + double getResolution(Cube &cube, ControlMeasure &measure); + void verifyCube(Cube & cube); + bool outputValue(ofstream &os, double value); + int calcGoodMeasureCount(const ControlPoint *point); + void printTemp(); + + map GuiHelpers() { + map helper; + helper["PrintTemp"] = (void *) printTemp; + return helper; + } + + + void pointreg(UserInterface &ui, Pvl *appLog) { + ControlNet inNet(ui.GetFileName("CNET")); + pointreg(inNet, ui, appLog); + } + + void pointreg(ControlNet inNet, UserInterface &ui, Pvl *appLog) { + // Initialize variables + ar = NULL; + validator = NULL; + cubeMgr = NULL; + files = NULL; + falsePositives = NULL; + + ignored = 0; + locked = 0; + registered = 0; + notintersected = 0; + unregistered = 0; + + logFalsePositives = false; + revertFalsePositives = false; + + if (ui.WasEntered("FALSEPOSITIVES")) { + logFalsePositives = true; + falsePositives = new QList; + } + + // Determine which points/measures to register + QString registerPoints = ui.GetString("POINTS"); + QString registerMeasures = ui.GetString("MEASURES"); + + bool outputFailed = ui.GetBoolean("OUTPUTFAILED"); + bool outputIgnored = ui.GetBoolean("OUTPUTIGNORED"); + + // Open the files list in a SerialNumberList for + // reference by SerialNumber + files = new SerialNumberList(ui.GetFileName("FROMLIST")); + + // Create the output ControlNet from the input file + ControlNet outNet(ui.GetFileName("CNET")); + + if (outNet.GetNumPoints() <= 0) { + QString msg = "Control network [" + ui.GetFileName("CNET") + "] "; + msg += "contains no points"; + throw IException(IException::User, msg, _FILEINFO_); + } + + outNet.SetUserName(Application::UserName()); + + // Create an AutoReg from the template file + Pvl pvl(ui.GetFileName("DEFFILE")); + ar = AutoRegFactory::Create(pvl); + + Progress progress; + progress.SetText("Registering Points"); + progress.SetMaximumSteps(outNet.GetNumPoints()); + progress.CheckStatus(); + + // Get the maximum allowable number of open files + struct rlimit limit; + if (getrlimit(RLIMIT_NOFILE, &limit) != 0) { + QString msg = "Cannot read the maximum allowable open files from system resources."; + throw IException(IException::Programmer, msg, _FILEINFO_); + } + // Allow for library files, etc + unsigned int maxOpenFiles = limit.rlim_cur * .60; + + cubeMgr = new CubeManager; + cubeMgr->SetNumOpenCubes(maxOpenFiles); + + QString validate = ui.GetString("VALIDATE"); + if (validate != "SKIP") { + validator = AutoRegFactory::Create(pvl); + + validator->SetTolerance(validator->MostLenientTolerance()); + validator->SetPatternZScoreMinimum(DBL_MIN); + validator->SetPatternValidPercent(DBL_MIN); + validator->SetSubsearchValidPercent(DBL_MIN); + + validator->SetSurfaceModelDistanceTolerance(validator->WindowSize()); + + expansion = ui.WasEntered("SEARCH") ? + ui.GetInteger("SEARCH") : validator->WindowSize(); + expansion *= 2; + + int patternSamples = validator->PatternChip()->Samples(); + int patternLines = validator->PatternChip()->Lines(); + validator->SearchChip()->SetSize( + patternSamples + expansion, patternLines + expansion); + + revertFalsePositives = ui.GetBoolean("REVERT"); + resTolerance = ui.GetDouble("RESTOLERANCE"); + } + + // Register the points and create a new + // ControlNet containing the refined measurements + int i = 0; + while (i < outNet.GetNumPoints()) { + progress.CheckStatus(); + + ControlPoint * outPoint = outNet.GetPoint(i); + + // Establish whether or not we want to attempt to register this point. + bool wantToRegister = true; + if (outPoint->IsIgnored()) { + if (registerPoints == "NONIGNORED") wantToRegister = false; + } + else { + if (registerPoints == "IGNORED") wantToRegister = false; + } + + // Check if this is a point we wish to disregard. + if (!wantToRegister) { + // Keep track of how many ignored points we didn't register. + if (outPoint->IsIgnored()) { + ignored++; + + // If the point is ignored and the user doesn't want them, delete it + if (!outputIgnored) { + outNet.DeletePoint(i); + continue; + } + } + } + else { // "Ignore" or "valid" point to be registered + if (outPoint->IsIgnored()) { + outPoint->SetIgnored(false); + } + + ControlMeasure * patternCM = outPoint->GetRefMeasure(); + + // In case this is an implicit reference, make it explicit since we'll be + // registering measures to it + outPoint->SetRefMeasure(patternCM); + + if (validate != "ONLY") { + registerPoint(outPoint, patternCM, registerMeasures, outputFailed); + } + if (validate != "SKIP") { + validatePoint(outPoint, patternCM, ui.GetDouble("SHIFT")); + } + + // Check to see if the control point has now been assigned + // to "ignore". If not, add it to the network. If so, only + // add it to the output if the OUTPUTIGNORED parameter is selected + // 2008-11-14 Jeannie Walldren + if (outPoint->IsIgnored()) { + ignored++; + if (!outputIgnored) { + outNet.DeletePoint(i); + continue; + } + } + } + + // The point wasn't deleted, so the network size is the same and we should + // increment our index. + i++; + } + + // If flatfile was entered, create the flatfile + // The flatfile is comma seperated and can be imported into an excel + // spreadsheet + if (ui.WasEntered("FLATFILE")) { + QString fFile = FileName(ui.GetFileName("FLATFILE")).expanded(); + + ofstream os; + os.open(fFile.toLatin1().data(), ios::out); + os << + "PointId,Filename,MeasureType,Reference,EditLock,Ignore,Registered," << + "OriginalMeasurementSample,OriginalMeasurementLine," << + "RegisteredMeasurementSample,RegisteredMeasurementLine,SampleShift," << + "LineShift,PixelShift,ZScoreMin,ZScoreMax,GoodnessOfFit" << endl; + os << Null << endl; + + for (int i = 0; i < outNet.GetNumPoints(); i++) { + + // get point from output control net and its + // corresponding point from input control net + const ControlPoint * outPoint = outNet.GetPoint(i); + QString outPointId = outPoint->GetId(); + const ControlPoint * inPoint = inNet.GetPoint(outPointId); + + if (!outPoint->IsIgnored()) { + for (int i = 0; i < outPoint->GetNumMeasures(); i++) { + + // Get measure and find its corresponding measure from input net + const ControlMeasure * cmTrans = outPoint->GetMeasure(i); + const ControlMeasure * cmOrig = + inPoint->GetMeasure((QString) cmTrans->GetCubeSerialNumber()); + + QString pointId = outPoint->GetId(); + + QString fullName = files->fileName(cmTrans->GetCubeSerialNumber()); + QString filename = FileName(fullName).baseName(); + + QString measureType = cmTrans->MeasureTypeToString( + cmTrans->GetType()); + QString reference = outPoint->GetRefMeasure() == cmTrans ? + "true" : "false"; + QString editLock = cmTrans->IsEditLocked() ? "true" : "false"; + QString ignore = cmTrans->IsIgnored() ? "true" : "false"; + QString registered = + !cmOrig->IsRegistered() && cmTrans->IsRegistered() ? + "true" : "false"; + + double inSamp = cmOrig->GetSample(); + double inLine = cmOrig->GetLine(); + + double outSamp = cmTrans->GetSample(); + double outLine = cmTrans->GetLine(); + + os << + pointId << "," << + filename << "," << + measureType << "," << + reference << "," << + editLock << "," << + ignore << "," << + registered << "," << + inSamp << "," << + inLine << "," << + outSamp << "," << + outLine; + + double sampleShift = cmTrans->GetSampleShift(); + double lineShift = cmTrans->GetLineShift(); + double pixelShift = cmTrans->GetPixelShift(); + + outputValue(os, sampleShift); + outputValue(os, lineShift); + outputValue(os, pixelShift); + + double zScoreMin = cmTrans->GetLogData( + ControlMeasureLogData::MinimumPixelZScore).GetNumericalValue(); + double zScoreMax = cmTrans->GetLogData( + ControlMeasureLogData::MaximumPixelZScore).GetNumericalValue(); + double goodnessOfFit = cmTrans->GetLogData( + ControlMeasureLogData::GoodnessOfFit).GetNumericalValue(); + + outputValue(os, zScoreMin); + outputValue(os, zScoreMax); + outputValue(os, goodnessOfFit); + + os << endl; + } + } + } + } + + if (logFalsePositives) { + QString filename = FileName(ui.GetFileName("FALSEPOSITIVES")).expanded(); + ofstream os; + os.open(filename.toLatin1().data(), ios::out); + + os << Validation::getHeader() << endl; + for (int i = 0; i < falsePositives->size(); i++) { + os << (*falsePositives)[i].toStdString() << endl; + } + + os.close(); + } + + PvlGroup pLog("Points"); + pLog += PvlKeyword("Total", toString(outNet.GetNumPoints())); + pLog += PvlKeyword("Ignored", toString(ignored)); + appLog->addGroup(pLog); + + PvlGroup mLog("Measures"); + mLog += PvlKeyword("Locked", toString(locked)); + mLog += PvlKeyword("Registered", toString(registered)); + mLog += PvlKeyword("NotIntersected", toString(notintersected)); + mLog += PvlKeyword("Unregistered", toString(unregistered)); + appLog->addGroup(mLog); + + // Log Registration Statistics + Pvl arPvl = ar->RegistrationStatistics(); + + for (int i = 0; i < arPvl.groups(); i++) { + appLog->addGroup(arPvl.group(i)); + } + + // add the auto registration information to print.prt + PvlGroup autoRegTemplate = ar->RegTemplate(); + appLog->addGroup(autoRegTemplate); + + if (validator) { + PvlGroup validationGroup("ValidationStatistics"); + + Pvl validationPvl = validator->RegistrationStatistics(); + for (int g = 0; g < validationPvl.groups(); g++) { + PvlGroup &group = validationPvl.group(g); + if (group.keywords() > 0) { + group[0].addComment(group.name()); + for (int k = 0; k < group.keywords(); k++) + validationGroup.addKeyword(group[k]); + } + } + + appLog->addGroup(validationGroup); + + PvlGroup validationTemplate = validator->UpdatedTemplate(); + validationTemplate.setName("ValidationTemplate"); + appLog->addGroup(validationTemplate); + } + + outNet.Write(ui.GetFileName("ONET")); + + delete ar; + ar = NULL; + + delete validator; + validator = NULL; + + delete cubeMgr; + cubeMgr = NULL; + + delete files; + files = NULL; + + delete falsePositives; + falsePositives = NULL; + } + + + void registerPoint(ControlPoint *outPoint, ControlMeasure *patternCM, + QString registerMeasures, bool outputFailed) { + + Cube &patternCube = *cubeMgr->OpenCube( + files->fileName(patternCM->GetCubeSerialNumber())); + + ar->PatternChip()->TackCube(patternCM->GetSample(), patternCM->GetLine()); + ar->PatternChip()->Load(patternCube); + + if (patternCM->IsEditLocked()) { + locked++; + } + + if (outPoint->GetRefMeasure() != patternCM) { + outPoint->SetRefMeasure(patternCM); + } + + // Register all the unlocked measurements + int j = 0; + while (j < outPoint->GetNumMeasures()) { + if (j != outPoint->IndexOfRefMeasure()) { + + ControlMeasure * measure = outPoint->GetMeasure(j); + if (measure->IsEditLocked()) { + // If the measurement is locked, keep it as is and go to next measure + locked++; + } + else if (!measure->IsMeasured() || registerMeasures != "CANDIDATES") { + + // refresh pattern cube pointer to ensure it stays valid + Cube &patternCube = *cubeMgr->OpenCube(files->fileName( + patternCM->GetCubeSerialNumber())); + Cube &searchCube = *cubeMgr->OpenCube(files->fileName( + measure->GetCubeSerialNumber())); + + ar->SearchChip()->TackCube(measure->GetSample(), measure->GetLine()); + + verifyCube(patternCube); + verifyCube(searchCube); + + try { + ar->SearchChip()->Load(searchCube, *(ar->PatternChip()), patternCube); + + // If the measurements were correctly registered + // Write them to the new ControlNet + AutoReg::RegisterStatus res = ar->Register(); + searchCube.clearIoCache(); + patternCube.clearIoCache(); + + double score1, score2; + ar->ZScores(score1, score2); + + // Set the minimum and maximum z-score values for the measure + measure->SetLogData(ControlMeasureLogData( + ControlMeasureLogData::MinimumPixelZScore, score1)); + measure->SetLogData(ControlMeasureLogData( + ControlMeasureLogData::MaximumPixelZScore, score2)); + + if (ar->Success()) { + // Check to make sure the newly calculated measure position is on + // the surface of the planet + Camera *cam = searchCube.camera(); + bool foundLatLon = cam->SetImage(ar->CubeSample(), ar->CubeLine()); + + if (foundLatLon) { + registered++; + + if (res == AutoReg::SuccessSubPixel) { + measure->SetType(ControlMeasure::RegisteredSubPixel); + } + else { + measure->SetType(ControlMeasure::RegisteredPixel); + } + + measure->SetLogData(ControlMeasureLogData( + ControlMeasureLogData::GoodnessOfFit, + ar->GoodnessOfFit())); + + measure->SetAprioriSample(measure->GetSample()); + measure->SetAprioriLine(measure->GetLine()); + measure->SetCoordinate(ar->CubeSample(), ar->CubeLine()); + measure->SetIgnored(false); + + // We successfully registered the current measure to the + // reference, and since we set the current measure to be + // unignored, it follows that its reference should also be made + // unignored. + patternCM->SetIgnored(false); + } + else { + notintersected++; + + if (outputFailed) { + measure->SetType(ControlMeasure::Candidate); + measure->SetIgnored(true); + } + else { + outPoint->Delete(j); + continue; + } + } + } + // Else use the original marked as "Candidate" + else { + unregistered++; + + if (outputFailed) { + measure->SetType(ControlMeasure::Candidate); + + if (res == AutoReg::FitChipToleranceNotMet) { + measure->SetLogData(ControlMeasureLogData( + ControlMeasureLogData::GoodnessOfFit, + ar->GoodnessOfFit())); + } + measure->SetIgnored(true); + } + else { + outPoint->Delete(j); + continue; + } + } + } + catch (IException &e) { + unregistered++; + + if (outputFailed) { + measure->SetType(ControlMeasure::Candidate); + measure->SetIgnored(true); + } + else { + outPoint->Delete(j); + continue; + } + } + } + } + + // If we made it here (without continuing on to the next measure), + // then the measure wasn't deleted and we should therefore increment + // the index of the measure we're looking at. + j++; + } + + // Jeff Anderson put in this test (Dec 2, 2008) to allow for control + // points to be good so long as at least two measure could be + // registered. When a measure can't be registered to the reference then + // that measure is set to be ignored where in the past the whole point + // was ignored + if (calcGoodMeasureCount(outPoint) < 2 && + outPoint->GetType() != ControlPoint::Fixed) { + outPoint->SetIgnored(true); + } + + // Otherwise, ignore=false. This is already set at the beginning of the + // registration process + } + + + void validatePoint(ControlPoint *point, ControlMeasure *reference, + double shiftTolerance) { + + for (int i = 0; i < point->GetNumMeasures(); i++) { + if (i != point->IndexOfRefMeasure()) { + ControlMeasure *measure = point->GetMeasure(i); + if (measure->IsMeasured() && !measure->IsEditLocked()) { + Validation validation = backRegister( + reference, measure, shiftTolerance); + + // If the validation failed, or we were unable to perform the validation + // due to registration errors, we consider this registration to be a + // false positive + if (validation.failed() || validation.untested()) { + if (revertFalsePositives) { + measure->SetType(ControlMeasure::Candidate); + measure->SetCoordinate( + measure->GetAprioriSample(), measure->GetAprioriLine()); + measure->SetIgnored(true); + // TODO remove log data here + } + } + + // If the registration did not succeed for whatever reason (untested, + // failed, or skipped due to incompatible data), log the result + if (logFalsePositives) { + if (!validation.succeeded()) { + falsePositives->append( + validation.toString()); + } + } + } + } + } + } + + + Validation backRegister(ControlMeasure *reference, ControlMeasure *measure, + double shiftTolerance) { + + Validation validation( + "Back-Registration", measure, reference, shiftTolerance); + + Cube &patternCube = *cubeMgr->OpenCube(files->fileName( + measure->GetCubeSerialNumber())); + Cube &searchCube = *cubeMgr->OpenCube(files->fileName( + reference->GetCubeSerialNumber())); + + double patternRes = getResolution(patternCube, *measure); + double searchRes = getResolution(searchCube, *reference); + validation.compareResolutions(patternRes, searchRes, resTolerance); + + if (validation.skipped()) + return validation; + + validator->SearchChip()->TackCube( + reference->GetSample(), reference->GetLine()); + validator->PatternChip()->TackCube(measure->GetSample(), measure->GetLine()); + validator->PatternChip()->Load(patternCube); + + verifyCube(patternCube); + verifyCube(searchCube); + + try { + validator->SearchChip()->Load( + searchCube, *(validator->PatternChip()), patternCube); + + // If the measurements were correctly registered + // Write them to the new ControlNet + validator->Register(); + searchCube.clearIoCache(); + patternCube.clearIoCache(); + + if (validator->Success()) { + // Check to make sure the newly calculated measure position is on + // the surface of the planet + Camera *cam = searchCube.camera(); + bool foundLatLon = cam->SetImage( + validator->CubeSample(), validator->CubeLine()); + + if (foundLatLon) { + validation.compare( + validator->CubeSample(), validator->CubeLine()); + } + } + } + catch (IException &e) { + } + + return validation; + } + + + double getResolution(Cube &cube, ControlMeasure &measure) { + // TODO retrieve for projection + Camera *camera = cube.camera(); + camera->SetImage(measure.GetSample(), measure.GetLine()); + return camera->PixelResolution(); + } + + + // Verify a cube has either a Camera or a Projection, throw an exception if not + void verifyCube(Cube & cube) { + try { + cube.camera(); + } + catch (IException &camError) { + try { + cube.projection(); + } + catch (IException &projError) { + projError.append(camError); + throw projError; + } + } + } + + + bool outputValue(ofstream &os, double value) { + os << ","; + + if (fabs(value) > DBL_EPSILON && value != Null) { + os << value; + return true; + } + else { + os << "NA"; + return false; + } + } + + + int calcGoodMeasureCount(const ControlPoint *point) { + int goodMeasureCount = 0; + for (int i = 0; i < point->GetNumMeasures(); i++) { + const ControlMeasure *measure = point->GetMeasure(i); + if (!measure->IsIgnored()) goodMeasureCount++; + } + + return goodMeasureCount; + } + + + // Helper function to print out template to session log + void printTemp() { + UserInterface &ui = Application::GetUserInterface(); + + // Get template pvl + Pvl userTemp; + userTemp.read(ui.GetFileName("DEFFILE")); + + //Write template file out to the log + Isis::Application::GuiLog(userTemp); + } +} diff --git a/isis/src/control/apps/pointreg/pointreg.h b/isis/src/control/apps/pointreg/pointreg.h new file mode 100644 index 0000000000..3e78506e1b --- /dev/null +++ b/isis/src/control/apps/pointreg/pointreg.h @@ -0,0 +1,13 @@ +#ifndef pointreg_h +#define pointreg_h + +#include "ControlNet.h" +#include "UserInterface.h" +#include "Pvl.h" + +namespace Isis{ + extern void pointreg(ControlNet inNet, UserInterface &ui, Pvl *appLog); + extern void pointreg(UserInterface &ui, Pvl *appLog); +} + +#endif diff --git a/isis/tests/FunctionalTestsPointreg.cpp b/isis/tests/FunctionalTestsPointreg.cpp new file mode 100644 index 0000000000..e52ab81eb3 --- /dev/null +++ b/isis/tests/FunctionalTestsPointreg.cpp @@ -0,0 +1,42 @@ +#include "pointreg.h" + +#include "Fixtures.h" +#include "TestUtilities.h" +#include "UserInterface.h" +#include "Histogram.h" + +#include "gmock/gmock.h" + +using namespace Isis; + +static QString APP_XML = FileName("$ISISROOT/bin/xml/pointreg.xml").expanded(); + +TEST_F(ThreeImageNetwork, FunctionalTestPointRegDefault) { + // Setup def file + QTemporaryFile defFile("XXXXXX.def"); + ASSERT_TRUE(defFile.open()); + + std::ofstream ofstream; + ofstream.open(defFile.fileName().toStdString()); + ofstream << "Object = Filters\n\tGroup = Cube_NumPoints\n\t\tGreaterThan = 15\n\tEndGroup\nEndObject"; + ofstream.close(); + + // Setup output flat file + QTemporaryFile flatFile; + ASSERT_TRUE(flatFile.open()); + + Pvl *log; + QTemporaryDir prefix; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector args = { "fromlist=" + cubeList->fileName(), + "deffile=" + defFile->fileName(), + "flatfile=" + flatFile->fileName(), + "onet=" + outNetPath}; + UserInterface options(APP_XML, args); + try { + pointreg(network, options, &log); + } + catch (IException &e) { + FAIL() << "Unable to register " << e.toString().toStdString().c_str() << std::endl; + } +} From 9eea0283d10ef920d612709d6712fbc40dc739ed Mon Sep 17 00:00:00 2001 From: Tim Giroux Date: Wed, 16 Dec 2020 16:02:35 -0700 Subject: [PATCH 2/7] add test cases --- isis/src/control/apps/pointreg/pointreg.cpp | 15 +- isis/src/control/apps/pointreg/pointreg.h | 2 - isis/src/control/apps/pointreg/tsts/Makefile | 4 - .../apps/pointreg/tsts/case01/Makefile | 15 - .../pointreg/tsts/failureOptions/Makefile | 29 -- .../apps/pointreg/tsts/outputOptions/Makefile | 59 --- .../pointreg/tsts/registerOptions/Makefile | 30 -- .../apps/pointreg/tsts/validation/Makefile | 44 --- isis/tests/FunctionalTestsPointreg.cpp | 373 +++++++++++++++++- .../threeImageNetwork/autoRegTemplate.def | 19 + 10 files changed, 379 insertions(+), 211 deletions(-) delete mode 100644 isis/src/control/apps/pointreg/tsts/Makefile delete mode 100644 isis/src/control/apps/pointreg/tsts/case01/Makefile delete mode 100644 isis/src/control/apps/pointreg/tsts/failureOptions/Makefile delete mode 100644 isis/src/control/apps/pointreg/tsts/outputOptions/Makefile delete mode 100644 isis/src/control/apps/pointreg/tsts/registerOptions/Makefile delete mode 100644 isis/src/control/apps/pointreg/tsts/validation/Makefile create mode 100644 isis/tests/data/threeImageNetwork/autoRegTemplate.def diff --git a/isis/src/control/apps/pointreg/pointreg.cpp b/isis/src/control/apps/pointreg/pointreg.cpp index 62cb24adc9..63cd2cf2dc 100644 --- a/isis/src/control/apps/pointreg/pointreg.cpp +++ b/isis/src/control/apps/pointreg/pointreg.cpp @@ -1,6 +1,3 @@ -#define GUIHELPERS - -#include "Isis.h" #include @@ -20,6 +17,7 @@ #include "Progress.h" #include "SerialNumberList.h" #include "UserInterface.h" +#include "Application.h" #include "IException.h" #include "iTime.h" @@ -200,16 +198,10 @@ namespace Isis { void pointreg(UserInterface &ui, Pvl *appLog) { - ControlNet inNet(ui.GetFileName("CNET")); - pointreg(inNet, ui, appLog); - } - - void pointreg(ControlNet inNet, UserInterface &ui, Pvl *appLog) { // Initialize variables ar = NULL; validator = NULL; cubeMgr = NULL; - files = NULL; falsePositives = NULL; ignored = 0; @@ -266,6 +258,7 @@ namespace Isis { // Allow for library files, etc unsigned int maxOpenFiles = limit.rlim_cur * .60; + cubeMgr = new CubeManager; cubeMgr->SetNumOpenCubes(maxOpenFiles); @@ -297,6 +290,7 @@ namespace Isis { // ControlNet containing the refined measurements int i = 0; while (i < outNet.GetNumPoints()) { + progress.CheckStatus(); ControlPoint * outPoint = outNet.GetPoint(i); @@ -374,6 +368,9 @@ namespace Isis { "LineShift,PixelShift,ZScoreMin,ZScoreMax,GoodnessOfFit" << endl; os << Null << endl; + // Create a ControlNet from the original input file + ControlNet inNet(ui.GetFileName("CNET")); + for (int i = 0; i < outNet.GetNumPoints(); i++) { // get point from output control net and its diff --git a/isis/src/control/apps/pointreg/pointreg.h b/isis/src/control/apps/pointreg/pointreg.h index 3e78506e1b..70fa85b9af 100644 --- a/isis/src/control/apps/pointreg/pointreg.h +++ b/isis/src/control/apps/pointreg/pointreg.h @@ -1,12 +1,10 @@ #ifndef pointreg_h #define pointreg_h -#include "ControlNet.h" #include "UserInterface.h" #include "Pvl.h" namespace Isis{ - extern void pointreg(ControlNet inNet, UserInterface &ui, Pvl *appLog); extern void pointreg(UserInterface &ui, Pvl *appLog); } diff --git a/isis/src/control/apps/pointreg/tsts/Makefile b/isis/src/control/apps/pointreg/tsts/Makefile deleted file mode 100644 index 46d84c74c2..0000000000 --- a/isis/src/control/apps/pointreg/tsts/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -BLANKS = "%-6s" -LENGTH = "%-40s" - -include $(ISISROOT)/make/isismake.tststree diff --git a/isis/src/control/apps/pointreg/tsts/case01/Makefile b/isis/src/control/apps/pointreg/tsts/case01/Makefile deleted file mode 100644 index 84734bf8ae..0000000000 --- a/isis/src/control/apps/pointreg/tsts/case01/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -APPNAME = pointreg - -redPointregLog.txt.IGNORELINES = Processed - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/cub.lis; - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/redOutputCnet.net \ - flatfile=$(OUTPUT)/redFlatFile.csv \ - points=nonignored > $(OUTPUT)/redPointregLog.txt; - $(RM) $(OUTPUT)/cub.lis; diff --git a/isis/src/control/apps/pointreg/tsts/failureOptions/Makefile b/isis/src/control/apps/pointreg/tsts/failureOptions/Makefile deleted file mode 100644 index d3143ce6be..0000000000 --- a/isis/src/control/apps/pointreg/tsts/failureOptions/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -APPNAME = pointreg - -logKeep.txt.IGNORELINES = Processed -logRemove.txt.IGNORELINES = Processed - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/cub.lis; - - # Keep Failures - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/input.net \ - deffile=$(INPUT)/definitions.def \ - onet=$(OUTPUT)/outputKeep.net \ - flatfile=$(OUTPUT)/flatKeep.txt \ - outputignored=no \ - points=all measures=all > $(OUTPUT)/logKeep.txt; - - # Remove Failures - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/input.net \ - deffile=$(INPUT)/definitions.def \ - onet=$(OUTPUT)/outputRemove.net \ - flatfile=$(OUTPUT)/flatRemove.txt \ - outputignored=no outputfailed=no \ - points=all measures=all > $(OUTPUT)/logRemove.txt; - - $(RM) $(OUTPUT)/cub.lis; diff --git a/isis/src/control/apps/pointreg/tsts/outputOptions/Makefile b/isis/src/control/apps/pointreg/tsts/outputOptions/Makefile deleted file mode 100644 index c99d87dd3b..0000000000 --- a/isis/src/control/apps/pointreg/tsts/outputOptions/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -APPNAME = pointreg - -log.a.txt.IGNORELINES = Processed -log.b.txt.IGNORELINES = Processed -log.c.txt.IGNORELINES = Processed -log.d.txt.IGNORELINES = Processed -log.e.txt.IGNORELINES = Processed - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/cub.lis; - - # A. Output Ignored, Register Ignored - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.a.net \ - flatfile=$(OUTPUT)/flatfile.a.txt \ - outputfailed=no \ - points=ignored > $(OUTPUT)/log.a.txt; - - # B. Output Ignored, Unmeasured, Register Ignored - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.b.net \ - flatfile=$(OUTPUT)/flatfile.b.txt \ - points=ignored \ - measures=candidates > $(OUTPUT)/log.b.txt; - - # C. Output Ignored Only - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.c.net \ - flatfile=$(OUTPUT)/flatfile.c.txt \ - outputfailed=no \ - points=nonignored > $(OUTPUT)/log.c.txt; - - # D. Output Unmeasured Only - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.d.net \ - flatfile=$(OUTPUT)/flatfile.d.txt \ - outputignored=no \ - points=nonignored > $(OUTPUT)/log.d.txt; - - # E. Output Unmeasured, Register Ignored - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.e.net \ - flatfile=$(OUTPUT)/flatfile.e.txt \ - outputignored=no \ - points=ignored > $(OUTPUT)/log.e.txt; - - $(RM) $(OUTPUT)/cub.lis; diff --git a/isis/src/control/apps/pointreg/tsts/registerOptions/Makefile b/isis/src/control/apps/pointreg/tsts/registerOptions/Makefile deleted file mode 100644 index 3c39d73009..0000000000 --- a/isis/src/control/apps/pointreg/tsts/registerOptions/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -APPNAME = pointreg - -log.ignored.txt.IGNORELINES = Processed -log.valid.txt.IGNORELINES = Processed - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/cub.lis; - - # Register Ignored Only - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.ignored.net \ - flatfile=$(OUTPUT)/flatfile.ignored.txt \ - outputignored=no \ - outputfailed=no \ - points=ignored > $(OUTPUT)/log.ignored.txt; - - # Register Valid Only - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/outnet.valid.net \ - flatfile=$(OUTPUT)/flatfile.valid.txt \ - outputignored=no \ - outputfailed=no > $(OUTPUT)/log.valid.txt; - - $(RM) $(OUTPUT)/cub.lis; diff --git a/isis/src/control/apps/pointreg/tsts/validation/Makefile b/isis/src/control/apps/pointreg/tsts/validation/Makefile deleted file mode 100644 index 7d4b943593..0000000000 --- a/isis/src/control/apps/pointreg/tsts/validation/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -APPNAME = pointreg - -log.default.txt.IGNORELINES = Processed -log.revert.txt.IGNORELINES = Processed -log.skipped.txt.IGNORELINES = Processed - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(LS) $(INPUT)/*.cub > $(OUTPUT)/cub.lis; - - # Test the validation without reverting failed registration - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(INPUT)/red.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/cnet.default.net \ - flatfile=$(OUTPUT)/flatfile.default.csv \ - validate=after falsepositives=$(OUTPUT)/falsepos.default.csv \ - revert=no shift=0.1 \ - points=nonignored > $(OUTPUT)/log.default.txt; - - # Test the validation with reverting failed registration - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(OUTPUT)/cnet.default.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/cnet.revert.net \ - flatfile=$(OUTPUT)/flatfile.revert.csv \ - validate=only falsepositives=$(OUTPUT)/falsepos.revert.csv \ - shift=0.1 search=7 \ - points=nonignored > $(OUTPUT)/log.revert.txt; - - # Test the validation with everything being skipped due to an absurdly strict - # RESTOLERANCE of 0.0 (i.e., nothing should be reverted, even though we enable - # reverting as an option) - $(APPNAME) fromlist=$(OUTPUT)/cub.lis \ - cnet=$(OUTPUT)/cnet.default.net \ - deffile=$(INPUT)/autoRegTemplate.def \ - onet=$(OUTPUT)/cnet.skipped.net \ - flatfile=$(OUTPUT)/flatfile.skipped.csv \ - validate=only falsepositives=$(OUTPUT)/falsepos.skipped.csv \ - restolerance=0.0 shift=0.1 search=7 \ - points=nonignored > $(OUTPUT)/log.skipped.txt; - - $(RM) $(OUTPUT)/cub.lis; diff --git a/isis/tests/FunctionalTestsPointreg.cpp b/isis/tests/FunctionalTestsPointreg.cpp index e52ab81eb3..6f91d06d31 100644 --- a/isis/tests/FunctionalTestsPointreg.cpp +++ b/isis/tests/FunctionalTestsPointreg.cpp @@ -3,7 +3,8 @@ #include "Fixtures.h" #include "TestUtilities.h" #include "UserInterface.h" -#include "Histogram.h" +#include "ControlNet.h" +#include "LineManager.h" #include "gmock/gmock.h" @@ -11,32 +12,366 @@ using namespace Isis; static QString APP_XML = FileName("$ISISROOT/bin/xml/pointreg.xml").expanded(); -TEST_F(ThreeImageNetwork, FunctionalTestPointRegDefault) { - // Setup def file - QTemporaryFile defFile("XXXXXX.def"); - ASSERT_TRUE(defFile.open()); +TEST_F(ThreeImageNetwork, FunctionalTestPointregDefault) { + // Populate cubes + LineManager line(*cube1); + double pixelValue = 0.0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = pixelValue++; + } + cube1->write(line); + cube2->write(line); + cube3->write(line); + } + cube1->close(); + cube2->close(); + cube3->close(); - std::ofstream ofstream; - ofstream.open(defFile.fileName().toStdString()); - ofstream << "Object = Filters\n\tGroup = Cube_NumPoints\n\t\tGreaterThan = 15\n\tEndGroup\nEndObject"; - ofstream.close(); + Pvl log; + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector args = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath }; + UserInterface options(APP_XML, args); - // Setup output flat file - QTemporaryFile flatFile; - ASSERT_TRUE(flatFile.open()); + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } - Pvl *log; + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + ASSERT_EQ(int(points["Total"]), 16); + ASSERT_EQ(int(measures["Registered"]), 24); + + // Check flatFile + QFile flatFile(flatFilePath); + ASSERT_TRUE(flatFile.size() > 0) ; + + // Check output control network + ControlNet outNet(outNetPath); + ASSERT_EQ(int(outNet.GetNumPoints()), 16); + ASSERT_EQ(int(outNet.GetNumMeasures()), 41); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregFailOptions) { + // Populate cubes + LineManager line(*cube1); + double pixelValue = 0.0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = pixelValue++; + } + cube1->write(line); + cube2->write(line); + cube3->write(line); + } + cube1->close(); + cube2->close(); + cube3->close(); + + Pvl log; QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; QString outNetPath = prefix.path() + "/outNet.net"; - QVector args = { "fromlist=" + cubeList->fileName(), - "deffile=" + defFile->fileName(), - "flatfile=" + flatFile->fileName(), - "onet=" + outNetPath}; + QVector args = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputignored=no", + "outputfailed=no", + "points=all", + "measures=all" }; UserInterface options(APP_XML, args); + + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + ASSERT_EQ(int(points["Total"]), 15); + ASSERT_EQ(int(measures["Registered"]), 24); + + // Check flatFile + QFile flatFile(flatFilePath); + ASSERT_TRUE(flatFile.size() > 0) ; + + // Check output control network + ControlNet outNet(outNetPath); + ASSERT_EQ(int(outNet.GetNumPoints()), 15); + ASSERT_EQ(int(outNet.GetNumMeasures()), 39); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptions) { + // Populate cubes + LineManager line(*cube1); + double pixelValue = 0.0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = pixelValue++; + } + cube1->write(line); + cube2->write(line); + cube3->write(line); + } + cube1->close(); + cube2->close(); + cube3->close(); + + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector argsA = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputfailed=no", + "points=ignored" }; + QVector argsB = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "measures=candidates", + "points=ignored" }; + QVector argsC = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputfailed=no", + "points=nonignored" }; + QVector argsD = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputignored=no", + "points=nonignored" }; + QVector argsE = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputignored=no", + "points=ignored" }; + UserInterface optionsA(APP_XML, argsA); // Output ignored, register ignored + UserInterface optionsB(APP_XML, argsB); // Output ignored, unmeasured, register ignored + UserInterface optionsC(APP_XML, argsC); // Output ignored only + UserInterface optionsD(APP_XML, argsD); // Output unmeasured only + UserInterface optionsE(APP_XML, argsE); // Output unmeasured, register ignored + Pvl logA, logB, logC, logD, logE; + try { - pointreg(network, options, &log); + pointreg(optionsA, &logA); + pointreg(optionsB, &logB); + pointreg(optionsC, &logC); + pointreg(optionsD, &logD); + pointreg(optionsE, &logE); } catch (IException &e) { - FAIL() << "Unable to register " << e.toString().toStdString().c_str() << std::endl; + FAIL() << e.toString().toStdString().c_str() << std::endl; } + + // Check app log + PvlGroup pointsA = logA.findGroup("Points"); + PvlGroup pointsB = logB.findGroup("Points"); + PvlGroup pointsC = logC.findGroup("Points"); + PvlGroup pointsD = logD.findGroup("Points"); + PvlGroup pointsE = logE.findGroup("Points"); + PvlGroup measuresA = logA.findGroup("Measures"); + PvlGroup measuresB = logB.findGroup("Measures"); + PvlGroup measuresC = logC.findGroup("Measures"); + PvlGroup measuresD = logD.findGroup("Measures"); + PvlGroup measuresE = logE.findGroup("Measures"); + PvlGroup surfaceA= logA.findGroup("SurfaceModelFailures"); + PvlGroup surfaceB= logB.findGroup("SurfaceModelFailures"); + PvlGroup surfaceC= logC.findGroup("SurfaceModelFailures"); + PvlGroup surfaceD= logD.findGroup("SurfaceModelFailures"); + PvlGroup surfaceE= logE.findGroup("SurfaceModelFailures"); + + ASSERT_EQ(int(pointsA["Total"]), 16); + ASSERT_EQ(int(pointsB["Total"]), 16); + ASSERT_EQ(int(pointsC["Total"]), 16); + ASSERT_EQ(int(pointsD["Total"]), 15); + ASSERT_EQ(int(pointsE["Total"]), 16); + ASSERT_EQ(int(measuresA["Registered"]), 0); + ASSERT_EQ(int(measuresB["Registered"]), 0); + ASSERT_EQ(int(measuresC["Registered"]), 24); + ASSERT_EQ(int(measuresD["Registered"]), 24); + ASSERT_EQ(int(measuresE["Registered"]), 0); + ASSERT_EQ(int(surfaceA["SurfaceModelNotEnoughValidData"]), 0); + ASSERT_EQ(int(surfaceB["SurfaceModelNotEnoughValidData"]), 0); + ASSERT_EQ(int(surfaceC["SurfaceModelNotEnoughValidData"]), 1); + ASSERT_EQ(int(surfaceD["SurfaceModelNotEnoughValidData"]), 1); + ASSERT_EQ(int(surfaceE["SurfaceModelNotEnoughValidData"]), 0); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregRegisterOptions) { + // Populate cubes + LineManager line(*cube1); + double pixelValue = 0.0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = pixelValue++; + } + cube1->write(line); + cube2->write(line); + cube3->write(line); + } + cube1->close(); + cube2->close(); + cube3->close(); + + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector argsA = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputfailed=no", + "outputignored=no", + "points=ignored" }; + QVector argsB = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "outputfailed=no", + "outputignored=no" }; + + UserInterface optionsA(APP_XML, argsA); // Register ignored only + UserInterface optionsB(APP_XML, argsB); // Register valid only + Pvl logA, logB; + + try { + pointreg(optionsA, &logA); + pointreg(optionsB, &logB); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup pointsA = logA.findGroup("Points"); + PvlGroup pointsB = logB.findGroup("Points"); + PvlGroup measuresA = logA.findGroup("Measures"); + PvlGroup measuresB = logB.findGroup("Measures"); + + ASSERT_EQ(int(pointsA["Total"]), 16); + ASSERT_EQ(int(pointsB["Total"]), 15); + ASSERT_EQ(int(measuresA["Registered"]), 0); + ASSERT_EQ(int(measuresB["Registered"]), 24); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregValidation) { + // Populate cubes + LineManager line(*cube1); + double pixelValue = 0.0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = pixelValue++; + } + cube1->write(line); + cube2->write(line); + cube3->write(line); + } + cube1->close(); + cube2->close(); + cube3->close(); + + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + + QString falsePosPathA = prefix.path() + "/falsePosA.csv"; + QString falsePosPathB = prefix.path() + "/falsePosB.csv"; + QString falsePosPathC = prefix.path() + "/falsePosC.csv"; + + QVector argsA = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "validate=after", + "falsepositives=" + falsePosPathA, + "revert=no", "shift=0.1", + "points=nonignored" }; + QVector argsB = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "validate=only", + "falsepositives=" + falsePosPathB, + "search=7", "shift=0.1", + "points=nonignored" }; + QVector argsC = { "fromlist=" + cubeListFile, + "cnet=data/threeImageNetwork/controlnetwork.net", + "deffile=data/threeImageNetwork/autoRegTemplate.def", + "flatfile=" + flatFilePath, + "onet=" + outNetPath, + "validate=only", + "falsepositives=" + falsePosPathC, + "search=7", "shift=0.1", "restolerance=0.0", + "points=nonignored" }; + UserInterface optionsA(APP_XML, argsA); // Test the validation without reverting failed registration + UserInterface optionsB(APP_XML, argsB); // Test the validation with reverting failed registration + // Test the validation with everything being skipped due restolerance=0.0 + UserInterface optionsC(APP_XML, argsC); + Pvl logA, logB, logC; + + try { + pointreg(optionsA, &logA); + pointreg(optionsB, &logB); + pointreg(optionsC, &logC); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup pointsA = logA.findGroup("Points"); + PvlGroup pointsB = logB.findGroup("Points"); + PvlGroup pointsC = logC.findGroup("Points"); + PvlGroup measuresA = logA.findGroup("Measures"); + PvlGroup measuresB = logB.findGroup("Measures"); + PvlGroup measuresC = logC.findGroup("Measures"); + PvlGroup validA= logA.findGroup("ValidationStatistics"); + PvlGroup validB= logB.findGroup("ValidationStatistics"); + PvlGroup validC= logC.findGroup("ValidationStatistics"); + + ASSERT_EQ(int(pointsA["Total"]), 16); + ASSERT_EQ(int(pointsB["Total"]), 16); + ASSERT_EQ(int(pointsC["Total"]), 16); + ASSERT_EQ(int(measuresA["Registered"]), 24); + ASSERT_EQ(int(measuresB["Registered"]), 0); + ASSERT_EQ(int(measuresC["Registered"]), 0); + ASSERT_EQ(int(validA["Total"]), 24); + ASSERT_EQ(int(validB["Total"]), 0); + ASSERT_EQ(int(validC["Total"]), 0); + + QFile falsePosA(falsePosPathA); // Should be populated + QFile falsePosB(falsePosPathB); // Should be empty + QFile falsePosC(falsePosPathC); // Should be empty + + ASSERT_TRUE(falsePosA.size() > falsePosB.size()); + ASSERT_EQ(falsePosB.size(), falsePosC.size()); } diff --git a/isis/tests/data/threeImageNetwork/autoRegTemplate.def b/isis/tests/data/threeImageNetwork/autoRegTemplate.def new file mode 100644 index 0000000000..d2348d3c71 --- /dev/null +++ b/isis/tests/data/threeImageNetwork/autoRegTemplate.def @@ -0,0 +1,19 @@ + Object = AutoRegistration + Group = Algorithm + Name = MaximumCorrelation + Tolerance = 0.9 + EndGroup + + Group = PatternChip + Samples = 15 + Lines = 15 + MinimumZScore = 1.5 + ValidPercent = 80 + EndGroup + + Group = SearchChip + Samples = 25 + Lines = 25 + EndGroup + EndObject + From f26c933ef3364cd9c88cae3a0cffcdd67a6d3508 Mon Sep 17 00:00:00 2001 From: Tim Giroux Date: Thu, 17 Dec 2020 16:15:27 -0700 Subject: [PATCH 3/7] split test cases and address PR review --- isis/tests/Fixtures.cpp | 19 +- isis/tests/Fixtures.h | 1 + isis/tests/FunctionalTestsPointreg.cpp | 437 +++++++++++++------------ 3 files changed, 243 insertions(+), 214 deletions(-) diff --git a/isis/tests/Fixtures.cpp b/isis/tests/Fixtures.cpp index 75507d321a..5ec8f11a8f 100644 --- a/isis/tests/Fixtures.cpp +++ b/isis/tests/Fixtures.cpp @@ -312,6 +312,21 @@ namespace Isis { cube3 = new Cube(); cube3->fromIsd(tempDir.path() + "/cube3.cub", labelPath3, *isdPath3, "rw"); + // Populate cubes + LineManager line(*cube1); + double pixelValue = 0.0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = pixelValue++; + } + cube1->write(line); + cube2->write(line); + cube3->write(line); + } + cube1->reopen("rw"); + cube2->reopen("rw"); + cube3->reopen("rw"); + cubeList = new FileList(); cubeList->append(cube1->fileName()); cubeList->append(cube2->fileName()); @@ -320,8 +335,10 @@ namespace Isis { cubeListFile = tempDir.path() + "/cubes.lis"; cubeList->write(cubeListFile); + networkFile = "data/threeImageNetwork/controlnetwork.net"; + network = new ControlNet(); - network->ReadControl("data/threeImageNetwork/controlnetwork.net"); + network->ReadControl(networkFile); } diff --git a/isis/tests/Fixtures.h b/isis/tests/Fixtures.h index 74002e1157..2e2ff79ee7 100644 --- a/isis/tests/Fixtures.h +++ b/isis/tests/Fixtures.h @@ -101,6 +101,7 @@ namespace Isis { protected: ControlNet *network; + QString networkFile; Cube *cube1; Cube *cube2; diff --git a/isis/tests/FunctionalTestsPointreg.cpp b/isis/tests/FunctionalTestsPointreg.cpp index 6f91d06d31..3bbc7a9810 100644 --- a/isis/tests/FunctionalTestsPointreg.cpp +++ b/isis/tests/FunctionalTestsPointreg.cpp @@ -13,27 +13,12 @@ using namespace Isis; static QString APP_XML = FileName("$ISISROOT/bin/xml/pointreg.xml").expanded(); TEST_F(ThreeImageNetwork, FunctionalTestPointregDefault) { - // Populate cubes - LineManager line(*cube1); - double pixelValue = 0.0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = pixelValue++; - } - cube1->write(line); - cube2->write(line); - cube3->write(line); - } - cube1->close(); - cube2->close(); - cube3->close(); - Pvl log; QTemporaryDir prefix; QString flatFilePath = prefix.path() + "/flatfile.csv"; QString outNetPath = prefix.path() + "/outNet.net"; QVector args = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath }; @@ -49,41 +34,26 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregDefault) { // Check app log PvlGroup points = log.findGroup("Points"); PvlGroup measures = log.findGroup("Measures"); - ASSERT_EQ(int(points["Total"]), 16); - ASSERT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 24); // Check flatFile QFile flatFile(flatFilePath); - ASSERT_TRUE(flatFile.size() > 0) ; + EXPECT_TRUE(flatFile.size() > 0) ; // Check output control network ControlNet outNet(outNetPath); - ASSERT_EQ(int(outNet.GetNumPoints()), 16); - ASSERT_EQ(int(outNet.GetNumMeasures()), 41); + EXPECT_EQ(int(outNet.GetNumPoints()), 16); + EXPECT_EQ(int(outNet.GetNumMeasures()), 41); } TEST_F(ThreeImageNetwork, FunctionalTestPointregFailOptions) { - // Populate cubes - LineManager line(*cube1); - double pixelValue = 0.0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = pixelValue++; - } - cube1->write(line); - cube2->write(line); - cube3->write(line); - } - cube1->close(); - cube2->close(); - cube3->close(); - Pvl log; QTemporaryDir prefix; QString flatFilePath = prefix.path() + "/flatfile.csv"; QString outNetPath = prefix.path() + "/outNet.net"; QVector args = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, @@ -103,275 +73,316 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregFailOptions) { // Check app log PvlGroup points = log.findGroup("Points"); PvlGroup measures = log.findGroup("Measures"); - ASSERT_EQ(int(points["Total"]), 15); - ASSERT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(points["Total"]), 15); + EXPECT_EQ(int(measures["Registered"]), 24); // Check flatFile QFile flatFile(flatFilePath); - ASSERT_TRUE(flatFile.size() > 0) ; + EXPECT_TRUE(flatFile.size() > 0) ; // Check output control network ControlNet outNet(outNetPath); - ASSERT_EQ(int(outNet.GetNumPoints()), 15); - ASSERT_EQ(int(outNet.GetNumMeasures()), 39); + EXPECT_EQ(int(outNet.GetNumPoints()), 15); + EXPECT_EQ(int(outNet.GetNumMeasures()), 39); } -TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptions) { - // Populate cubes - LineManager line(*cube1); - double pixelValue = 0.0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = pixelValue++; - } - cube1->write(line); - cube2->write(line); - cube3->write(line); - } - cube1->close(); - cube2->close(); - cube3->close(); - +TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsA) { + // Output ignored, register ignored + Pvl log; QTemporaryDir prefix; QString flatFilePath = prefix.path() + "/flatfile.csv"; QString outNetPath = prefix.path() + "/outNet.net"; - QVector argsA = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "outputfailed=no", "points=ignored" }; - QVector argsB = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", - "deffile=data/threeImageNetwork/autoRegTemplate.def", - "flatfile=" + flatFilePath, - "onet=" + outNetPath, - "measures=candidates", - "points=ignored" }; - QVector argsC = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + UserInterface options(APP_XML, args); + + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + PvlGroup surface= log.findGroup("SurfaceModelFailures"); + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 0); + EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 0); + + // Check flatFile + QFile flatFile(flatFilePath); + EXPECT_TRUE(flatFile.size() > 0) ; + + // Check output control network + ControlNet outNet(outNetPath); + EXPECT_EQ(int(outNet.GetNumPoints()), 16); + EXPECT_EQ(int(outNet.GetNumMeasures()), 41); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsB) { + // Output ignored only + Pvl log; + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "outputfailed=no", "points=nonignored" }; - QVector argsD = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + UserInterface options(APP_XML, args); + + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + PvlGroup surface= log.findGroup("SurfaceModelFailures"); + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 1); + + // Check flatFile + QFile flatFile(flatFilePath); + EXPECT_TRUE(flatFile.size() > 0) ; + + // Check output control network + ControlNet outNet(outNetPath); + EXPECT_EQ(int(outNet.GetNumPoints()), 16); + EXPECT_EQ(int(outNet.GetNumMeasures()), 40); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsC) { + // Output Unmeasured Only + Pvl log; + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "outputignored=no", "points=nonignored" }; - QVector argsE = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", - "deffile=data/threeImageNetwork/autoRegTemplate.def", - "flatfile=" + flatFilePath, - "onet=" + outNetPath, - "outputignored=no", - "points=ignored" }; - UserInterface optionsA(APP_XML, argsA); // Output ignored, register ignored - UserInterface optionsB(APP_XML, argsB); // Output ignored, unmeasured, register ignored - UserInterface optionsC(APP_XML, argsC); // Output ignored only - UserInterface optionsD(APP_XML, argsD); // Output unmeasured only - UserInterface optionsE(APP_XML, argsE); // Output unmeasured, register ignored - Pvl logA, logB, logC, logD, logE; + UserInterface options(APP_XML, args); try { - pointreg(optionsA, &logA); - pointreg(optionsB, &logB); - pointreg(optionsC, &logC); - pointreg(optionsD, &logD); - pointreg(optionsE, &logE); + pointreg(options, &log); } catch (IException &e) { FAIL() << e.toString().toStdString().c_str() << std::endl; } // Check app log - PvlGroup pointsA = logA.findGroup("Points"); - PvlGroup pointsB = logB.findGroup("Points"); - PvlGroup pointsC = logC.findGroup("Points"); - PvlGroup pointsD = logD.findGroup("Points"); - PvlGroup pointsE = logE.findGroup("Points"); - PvlGroup measuresA = logA.findGroup("Measures"); - PvlGroup measuresB = logB.findGroup("Measures"); - PvlGroup measuresC = logC.findGroup("Measures"); - PvlGroup measuresD = logD.findGroup("Measures"); - PvlGroup measuresE = logE.findGroup("Measures"); - PvlGroup surfaceA= logA.findGroup("SurfaceModelFailures"); - PvlGroup surfaceB= logB.findGroup("SurfaceModelFailures"); - PvlGroup surfaceC= logC.findGroup("SurfaceModelFailures"); - PvlGroup surfaceD= logD.findGroup("SurfaceModelFailures"); - PvlGroup surfaceE= logE.findGroup("SurfaceModelFailures"); - - ASSERT_EQ(int(pointsA["Total"]), 16); - ASSERT_EQ(int(pointsB["Total"]), 16); - ASSERT_EQ(int(pointsC["Total"]), 16); - ASSERT_EQ(int(pointsD["Total"]), 15); - ASSERT_EQ(int(pointsE["Total"]), 16); - ASSERT_EQ(int(measuresA["Registered"]), 0); - ASSERT_EQ(int(measuresB["Registered"]), 0); - ASSERT_EQ(int(measuresC["Registered"]), 24); - ASSERT_EQ(int(measuresD["Registered"]), 24); - ASSERT_EQ(int(measuresE["Registered"]), 0); - ASSERT_EQ(int(surfaceA["SurfaceModelNotEnoughValidData"]), 0); - ASSERT_EQ(int(surfaceB["SurfaceModelNotEnoughValidData"]), 0); - ASSERT_EQ(int(surfaceC["SurfaceModelNotEnoughValidData"]), 1); - ASSERT_EQ(int(surfaceD["SurfaceModelNotEnoughValidData"]), 1); - ASSERT_EQ(int(surfaceE["SurfaceModelNotEnoughValidData"]), 0); -} + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + PvlGroup surface= log.findGroup("SurfaceModelFailures"); + EXPECT_EQ(int(points["Total"]), 15); + EXPECT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 1); + + // Check flatFile + QFile flatFile(flatFilePath); + EXPECT_TRUE(flatFile.size() > 0) ; -TEST_F(ThreeImageNetwork, FunctionalTestPointregRegisterOptions) { - // Populate cubes - LineManager line(*cube1); - double pixelValue = 0.0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = pixelValue++; - } - cube1->write(line); - cube2->write(line); - cube3->write(line); - } - cube1->close(); - cube2->close(); - cube3->close(); + // Check output control network + ControlNet outNet(outNetPath); + EXPECT_EQ(int(outNet.GetNumPoints()), 15); + EXPECT_EQ(int(outNet.GetNumMeasures()), 39); +} +TEST_F(ThreeImageNetwork, FunctionalTestPointregRegisterOptionsIgnored) { QTemporaryDir prefix; QString flatFilePath = prefix.path() + "/flatfile.csv"; QString outNetPath = prefix.path() + "/outNet.net"; - QVector argsA = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "outputfailed=no", "outputignored=no", "points=ignored" }; - QVector argsB = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + UserInterface options(APP_XML, args); // Register ignored only + Pvl log; + + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 0); +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregRegisterOptionsValid) { + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "outputfailed=no", "outputignored=no" }; - - UserInterface optionsA(APP_XML, argsA); // Register ignored only - UserInterface optionsB(APP_XML, argsB); // Register valid only - Pvl logA, logB; + UserInterface options(APP_XML, args); // Register valid only + Pvl log; try { - pointreg(optionsA, &logA); - pointreg(optionsB, &logB); + pointreg(options, &log); } catch (IException &e) { FAIL() << e.toString().toStdString().c_str() << std::endl; } // Check app log - PvlGroup pointsA = logA.findGroup("Points"); - PvlGroup pointsB = logB.findGroup("Points"); - PvlGroup measuresA = logA.findGroup("Measures"); - PvlGroup measuresB = logB.findGroup("Measures"); - - ASSERT_EQ(int(pointsA["Total"]), 16); - ASSERT_EQ(int(pointsB["Total"]), 15); - ASSERT_EQ(int(measuresA["Registered"]), 0); - ASSERT_EQ(int(measuresB["Registered"]), 24); + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + + EXPECT_EQ(int(points["Total"]), 15); + EXPECT_EQ(int(measures["Registered"]), 24); } TEST_F(ThreeImageNetwork, FunctionalTestPointregValidation) { - // Populate cubes - LineManager line(*cube1); - double pixelValue = 0.0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = pixelValue++; - } - cube1->write(line); - cube2->write(line); - cube3->write(line); - } - cube1->close(); - cube2->close(); - cube3->close(); - QTemporaryDir prefix; QString flatFilePath = prefix.path() + "/flatfile.csv"; QString outNetPath = prefix.path() + "/outNet.net"; - QString falsePosPathA = prefix.path() + "/falsePosA.csv"; - QString falsePosPathB = prefix.path() + "/falsePosB.csv"; - QString falsePosPathC = prefix.path() + "/falsePosC.csv"; + QString falsePosPath = prefix.path() + "/falsePos.csv"; - QVector argsA = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "validate=after", - "falsepositives=" + falsePosPathA, + "falsepositives=" + falsePosPath, "revert=no", "shift=0.1", "points=nonignored" }; - QVector argsB = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + UserInterface options(APP_XML, args); // Test the validation without reverting failed registration + Pvl log; + + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + PvlGroup valid = log.findGroup("ValidationStatistics"); + + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(valid["Total"]), 24); + + QFile falsePos(falsePosPath); // Should be populated + + EXPECT_TRUE(falsePos.size() > 140); // 140 is the size of the empty table due to column names +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregValidationRevert) { + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + + QString falsePosPath = prefix.path() + "/falsePos.csv"; + + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "validate=only", - "falsepositives=" + falsePosPathB, + "falsepositives=" + falsePosPath, "search=7", "shift=0.1", "points=nonignored" }; - QVector argsC = { "fromlist=" + cubeListFile, - "cnet=data/threeImageNetwork/controlnetwork.net", + UserInterface options(APP_XML, args); // Test the validation with reverting failed registration + Pvl log; + + try { + pointreg(options, &log); + } + catch (IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // Check app log + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + PvlGroup valid = log.findGroup("ValidationStatistics"); + + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 0); + EXPECT_EQ(int(valid["Total"]), 0); + + QFile falsePos(falsePosPath); // Should be empty + + EXPECT_TRUE(falsePos.size() == 140); // 140 is the size of the empty table due to column names +} + +TEST_F(ThreeImageNetwork, FunctionalTestPointregValidationSkipped) { + QTemporaryDir prefix; + QString flatFilePath = prefix.path() + "/flatfile.csv"; + QString outNetPath = prefix.path() + "/outNet.net"; + + QString falsePosPath = prefix.path() + "/falsePos.csv"; + + QVector args = { "fromlist=" + cubeListFile, + "cnet=" + networkFile, "deffile=data/threeImageNetwork/autoRegTemplate.def", "flatfile=" + flatFilePath, "onet=" + outNetPath, "validate=only", - "falsepositives=" + falsePosPathC, + "falsepositives=" + falsePosPath, "search=7", "shift=0.1", "restolerance=0.0", "points=nonignored" }; - UserInterface optionsA(APP_XML, argsA); // Test the validation without reverting failed registration - UserInterface optionsB(APP_XML, argsB); // Test the validation with reverting failed registration // Test the validation with everything being skipped due restolerance=0.0 - UserInterface optionsC(APP_XML, argsC); - Pvl logA, logB, logC; + UserInterface options(APP_XML, args); + Pvl log; try { - pointreg(optionsA, &logA); - pointreg(optionsB, &logB); - pointreg(optionsC, &logC); + pointreg(options, &log); } catch (IException &e) { FAIL() << e.toString().toStdString().c_str() << std::endl; } // Check app log - PvlGroup pointsA = logA.findGroup("Points"); - PvlGroup pointsB = logB.findGroup("Points"); - PvlGroup pointsC = logC.findGroup("Points"); - PvlGroup measuresA = logA.findGroup("Measures"); - PvlGroup measuresB = logB.findGroup("Measures"); - PvlGroup measuresC = logC.findGroup("Measures"); - PvlGroup validA= logA.findGroup("ValidationStatistics"); - PvlGroup validB= logB.findGroup("ValidationStatistics"); - PvlGroup validC= logC.findGroup("ValidationStatistics"); - - ASSERT_EQ(int(pointsA["Total"]), 16); - ASSERT_EQ(int(pointsB["Total"]), 16); - ASSERT_EQ(int(pointsC["Total"]), 16); - ASSERT_EQ(int(measuresA["Registered"]), 24); - ASSERT_EQ(int(measuresB["Registered"]), 0); - ASSERT_EQ(int(measuresC["Registered"]), 0); - ASSERT_EQ(int(validA["Total"]), 24); - ASSERT_EQ(int(validB["Total"]), 0); - ASSERT_EQ(int(validC["Total"]), 0); + PvlGroup points = log.findGroup("Points"); + PvlGroup measures = log.findGroup("Measures"); + PvlGroup valid = log.findGroup("ValidationStatistics"); + + EXPECT_EQ(int(points["Total"]), 16); + EXPECT_EQ(int(measures["Registered"]), 0); + EXPECT_EQ(int(valid["Total"]), 0); - QFile falsePosA(falsePosPathA); // Should be populated - QFile falsePosB(falsePosPathB); // Should be empty - QFile falsePosC(falsePosPathC); // Should be empty + QFile falsePos(falsePosPath); // Should be empty - ASSERT_TRUE(falsePosA.size() > falsePosB.size()); - ASSERT_EQ(falsePosB.size(), falsePosC.size()); + EXPECT_TRUE(falsePos.size() == 140); // 140 is the size of the empty table due to column names } + From 58583f619eb2b46a246a2201205d8b5551ce6bd8 Mon Sep 17 00:00:00 2001 From: Tim Giroux Date: Thu, 17 Dec 2020 16:23:11 -0700 Subject: [PATCH 4/7] ThreeImageNetwork already has cube population upstream --- isis/tests/Fixtures.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/isis/tests/Fixtures.cpp b/isis/tests/Fixtures.cpp index 5ec8f11a8f..ed76b18f15 100644 --- a/isis/tests/Fixtures.cpp +++ b/isis/tests/Fixtures.cpp @@ -312,21 +312,6 @@ namespace Isis { cube3 = new Cube(); cube3->fromIsd(tempDir.path() + "/cube3.cub", labelPath3, *isdPath3, "rw"); - // Populate cubes - LineManager line(*cube1); - double pixelValue = 0.0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = pixelValue++; - } - cube1->write(line); - cube2->write(line); - cube3->write(line); - } - cube1->reopen("rw"); - cube2->reopen("rw"); - cube3->reopen("rw"); - cubeList = new FileList(); cubeList->append(cube1->fileName()); cubeList->append(cube2->fileName()); From 547af8ef458e9de439a9d05e8f26579f10a91e51 Mon Sep 17 00:00:00 2001 From: Tim Giroux Date: Thu, 17 Dec 2020 18:06:44 -0700 Subject: [PATCH 5/7] address Fixtures.cpp discrepancy --- isis/tests/Fixtures.cpp | 33 +++++++++++++++++++++-- isis/tests/FunctionalTestsPointreg.cpp | 36 +++++++++++++------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/isis/tests/Fixtures.cpp b/isis/tests/Fixtures.cpp index ed76b18f15..658055afde 100644 --- a/isis/tests/Fixtures.cpp +++ b/isis/tests/Fixtures.cpp @@ -295,7 +295,6 @@ namespace Isis { {30, 0}}; poly.Create(coords); cube1->write(poly); - cube1->reopen("rw"); cube2 = new Cube(); cube2->fromIsd(tempDir.path() + "/cube2.cub", labelPath2, *isdPath2, "rw"); @@ -307,11 +306,41 @@ namespace Isis { {31, 1}}; poly.Create(coords); cube2->write(poly); - cube2->reopen("rw"); cube3 = new Cube(); cube3->fromIsd(tempDir.path() + "/cube3.cub", labelPath3, *isdPath3, "rw"); + LineManager line(*cube1); + LineManager line2(*cube2); + LineManager line3(*cube3); + int pixelValue = 1; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = (double) (pixelValue %255); + pixelValue++; + } + cube1->write(line); + } + cube1->reopen("rw"); + + for(line2.begin(); !line2.end(); line2++) { + for(int i = 0; i < line.size(); i++) { + line2[i] = (double) (pixelValue %255); + pixelValue++; + } + cube2->write(line2); + } + cube2->reopen("rw"); + + for(line3.begin(); !line3.end(); line3++) { + for(int i = 0; i < line3.size(); i++) { + line3[i] = (double) (pixelValue %255); + pixelValue++; + } + cube3->write(line3); + } + cube3->reopen("rw"); + cubeList = new FileList(); cubeList->append(cube1->fileName()); cubeList->append(cube2->fileName()); diff --git a/isis/tests/FunctionalTestsPointreg.cpp b/isis/tests/FunctionalTestsPointreg.cpp index 3bbc7a9810..84e6f69b69 100644 --- a/isis/tests/FunctionalTestsPointreg.cpp +++ b/isis/tests/FunctionalTestsPointreg.cpp @@ -35,7 +35,7 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregDefault) { PvlGroup points = log.findGroup("Points"); PvlGroup measures = log.findGroup("Measures"); EXPECT_EQ(int(points["Total"]), 16); - EXPECT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(measures["Registered"]), 3); // Check flatFile QFile flatFile(flatFilePath); @@ -73,8 +73,8 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregFailOptions) { // Check app log PvlGroup points = log.findGroup("Points"); PvlGroup measures = log.findGroup("Measures"); - EXPECT_EQ(int(points["Total"]), 15); - EXPECT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(points["Total"]), 3); + EXPECT_EQ(int(measures["Registered"]), 3); // Check flatFile QFile flatFile(flatFilePath); @@ -82,8 +82,8 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregFailOptions) { // Check output control network ControlNet outNet(outNetPath); - EXPECT_EQ(int(outNet.GetNumPoints()), 15); - EXPECT_EQ(int(outNet.GetNumMeasures()), 39); + EXPECT_EQ(int(outNet.GetNumPoints()), 3); + EXPECT_EQ(int(outNet.GetNumMeasures()), 6); } TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsA) { @@ -153,8 +153,8 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsB) { PvlGroup measures = log.findGroup("Measures"); PvlGroup surface= log.findGroup("SurfaceModelFailures"); EXPECT_EQ(int(points["Total"]), 16); - EXPECT_EQ(int(measures["Registered"]), 24); - EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 1); + EXPECT_EQ(int(measures["Registered"]), 3); + EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 15); // Check flatFile QFile flatFile(flatFilePath); @@ -163,7 +163,7 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsB) { // Check output control network ControlNet outNet(outNetPath); EXPECT_EQ(int(outNet.GetNumPoints()), 16); - EXPECT_EQ(int(outNet.GetNumMeasures()), 40); + EXPECT_EQ(int(outNet.GetNumMeasures()), 19); } TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsC) { @@ -192,9 +192,9 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsC) { PvlGroup points = log.findGroup("Points"); PvlGroup measures = log.findGroup("Measures"); PvlGroup surface= log.findGroup("SurfaceModelFailures"); - EXPECT_EQ(int(points["Total"]), 15); - EXPECT_EQ(int(measures["Registered"]), 24); - EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 1); + EXPECT_EQ(int(points["Total"]), 3); + EXPECT_EQ(int(measures["Registered"]), 3); + EXPECT_EQ(int(surface["SurfaceModelNotEnoughValidData"]), 15); // Check flatFile QFile flatFile(flatFilePath); @@ -202,8 +202,8 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregOutputOptionsC) { // Check output control network ControlNet outNet(outNetPath); - EXPECT_EQ(int(outNet.GetNumPoints()), 15); - EXPECT_EQ(int(outNet.GetNumMeasures()), 39); + EXPECT_EQ(int(outNet.GetNumPoints()), 3); + EXPECT_EQ(int(outNet.GetNumMeasures()), 9); } TEST_F(ThreeImageNetwork, FunctionalTestPointregRegisterOptionsIgnored) { @@ -261,8 +261,8 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregRegisterOptionsValid) { PvlGroup points = log.findGroup("Points"); PvlGroup measures = log.findGroup("Measures"); - EXPECT_EQ(int(points["Total"]), 15); - EXPECT_EQ(int(measures["Registered"]), 24); + EXPECT_EQ(int(points["Total"]), 3); + EXPECT_EQ(int(measures["Registered"]), 3); } TEST_F(ThreeImageNetwork, FunctionalTestPointregValidation) { @@ -297,10 +297,10 @@ TEST_F(ThreeImageNetwork, FunctionalTestPointregValidation) { PvlGroup valid = log.findGroup("ValidationStatistics"); EXPECT_EQ(int(points["Total"]), 16); - EXPECT_EQ(int(measures["Registered"]), 24); - EXPECT_EQ(int(valid["Total"]), 24); + EXPECT_EQ(int(measures["Registered"]), 3); + EXPECT_EQ(int(valid["Total"]), 3); - QFile falsePos(falsePosPath); // Should be populated + QFile falsePos(falsePosPath); // Should be empty EXPECT_TRUE(falsePos.size() > 140); // 140 is the size of the empty table due to column names } From e494c081403586ce04407b130d0400d05efb50ad Mon Sep 17 00:00:00 2001 From: Tim Giroux Date: Thu, 17 Dec 2020 18:09:15 -0700 Subject: [PATCH 6/7] move cube reopens to match in merge conflict --- isis/tests/Fixtures.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/isis/tests/Fixtures.cpp b/isis/tests/Fixtures.cpp index 658055afde..2e5c46e9be 100644 --- a/isis/tests/Fixtures.cpp +++ b/isis/tests/Fixtures.cpp @@ -321,7 +321,6 @@ namespace Isis { } cube1->write(line); } - cube1->reopen("rw"); for(line2.begin(); !line2.end(); line2++) { for(int i = 0; i < line.size(); i++) { @@ -330,7 +329,6 @@ namespace Isis { } cube2->write(line2); } - cube2->reopen("rw"); for(line3.begin(); !line3.end(); line3++) { for(int i = 0; i < line3.size(); i++) { @@ -339,6 +337,9 @@ namespace Isis { } cube3->write(line3); } + + cube1->reopen("rw"); + cube2->reopen("rw"); cube3->reopen("rw"); cubeList = new FileList(); From dbf373e164453a9a4ffb014bef9498c42c43a94f Mon Sep 17 00:00:00 2001 From: Kelvin Date: Fri, 18 Dec 2020 18:29:21 -0700 Subject: [PATCH 7/7] added fixtures --- isis/tests/Fixtures.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/isis/tests/Fixtures.cpp b/isis/tests/Fixtures.cpp index 1799baafa1..b2b23136d7 100644 --- a/isis/tests/Fixtures.cpp +++ b/isis/tests/Fixtures.cpp @@ -365,8 +365,6 @@ namespace Isis { network = new ControlNet(); network->ReadControl(networkFile); - } - cube1map = new Cube(); cube2map = new Cube();