From e381affaa3dd1fae58c5bb710e6b0ec9f7979a06 Mon Sep 17 00:00:00 2001 From: kledmundson <6842706+kledmundson@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:28:29 -0700 Subject: [PATCH] The cnetdiff application has been refactored to be callable; Makefile tests have been removed and replaced by gtests. (#5323) * The cnetedit applciation has been refactored to be callable; Makefile tests have been removed and replace by gtests. Addresses #5322. * Moved CHANGELOG.md entry for cnetdiff changes from "Added" section to "Changed" section per reviewer suggestion. Addresses #5322. * Reverted back to original ControlNetDiff source and header files per reviewer suggestion. Addresses #5322. * Changes to cnetdiff.cpp and main.cpp to use the addLogGroup method to add PvlGroups to Pvl. Per reviewer suggestion. Addresses #5322. * Put back line erroneously removed in CHANGELOG.md, per review. Addresses #5322. --- CHANGELOG.md | 1 + isis/src/control/apps/cnetdiff/cnetdiff.cpp | 380 ++++++ isis/src/control/apps/cnetdiff/cnetdiff.h | 20 + isis/src/control/apps/cnetdiff/main.cpp | 318 +---- isis/src/control/apps/cnetdiff/tsts/Makefile | 4 - .../apps/cnetdiff/tsts/default/Makefile | 13 - .../control/apps/cnetdiff/tsts/full/Makefile | 20 - isis/tests/FunctionalTestsCnetdiff.cpp | 1023 +++++++++++++++++ 8 files changed, 1429 insertions(+), 350 deletions(-) create mode 100644 isis/src/control/apps/cnetdiff/cnetdiff.cpp create mode 100644 isis/src/control/apps/cnetdiff/cnetdiff.h delete mode 100644 isis/src/control/apps/cnetdiff/tsts/Makefile delete mode 100644 isis/src/control/apps/cnetdiff/tsts/default/Makefile delete mode 100644 isis/src/control/apps/cnetdiff/tsts/full/Makefile create mode 100644 isis/tests/FunctionalTestsCnetdiff.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e1993e125..b74577972d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ release. ### Changed +- Cnetedit has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5322](https://github.com/USGS-Astrogeology/ISIS3/issues/5322), - Changed cholmod 32 bit calls to 64 bit calls [#5173](https://github.com/DOI-USGS/ISIS3/issues/5173) and [#5176](https://github.com/DOI-USGS/ISIS3/issues/5176) - Removed the `.py` extention from the _isisdataeval_ tool `isisdata_mockup` for consistency and install it in $ISISROOT/bin; added the `--tojson` and `--hasher` option to _isisdata_mockup_ tool improve utility; updated the tool `README.md` documentation to reflect this change, removed help output and trimmed example results; fixed paths to test data in `make_isisdata_mockup.sh`. [#5163](https://github.com/DOI-USGS/ISIS3/pull/5163) - Significantly refactored FASTGEOM processing in findfeatures to accommodate stability and functionality. The scope of the algorithm was taken out of the ImageSource class and isolated to support this feature. [#4772](https://github.com/DOI-USGS/ISIS3/issues/4772) diff --git a/isis/src/control/apps/cnetdiff/cnetdiff.cpp b/isis/src/control/apps/cnetdiff/cnetdiff.cpp new file mode 100644 index 0000000000..3dd9c78660 --- /dev/null +++ b/isis/src/control/apps/cnetdiff/cnetdiff.cpp @@ -0,0 +1,380 @@ +/** This is free and unencumbered software released into the public domain. +The authors of ISIS do not claim copyright on the contents of this file. +For more details about the LICENSE terms and the AUTHORS, you will +find files of those names at the top level of this repository. **/ + +/* SPDX-License-Identifier: CC0-1.0 */ + +#include "cnetdiff.h" + +#include +#include + +#include +#include + +#include "ControlNet.h" +#include "ControlNetDiff.h" +#include "ControlNetVersioner.h" +#include "IException.h" +#include "PvlContainer.h" +#include "PvlGroup.h" + +using namespace std; + +namespace Isis { + + bool filesMatch; + QString differenceReason; + PvlGroup tolerances; + PvlGroup ignorekeys; + + void CompareKeywords(const PvlKeyword &pvl1, const PvlKeyword &pvl2); + void CompareGroups(const PvlContainer &pvl1, const PvlContainer &pvl2); + void Compare(const PvlObject &point1, const PvlObject &point2); + void Compare(ControlNetVersioner &net1, ControlNetVersioner &net2); + + /** + * Compare two control networks + * + * @param ui UserInterface object containing parameters + * @return Pvl results log file + */ + Pvl cnetdiff(UserInterface &ui) { + + // input control networks + ControlNet cnet1 = ControlNet(ui.GetFileName("FROM")); + ControlNet cnet2 = ControlNet(ui.GetFileName("FROM2")); + + if(ui.WasEntered("DIFF")) { + Pvl diffFile(ui.GetFileName("DIFF")); + return cnetdiff(cnet1, cnet2, ui, &diffFile); + } + + return cnetdiff(cnet1, cnet2, ui); + } + + + /** + * Compare two control networks + * + * @param ControlNet cnet1 1st control net for comparison + * @param ControlNet cnet2 2nd control net for comparison + * @return Pvl results log file + */ + Pvl cnetdiff(ControlNet &cnet1, ControlNet &cnet2, UserInterface &ui, + Pvl *diffFile) { + Pvl log; + + // create ControlNetVersioner objects for each net + ControlNetVersioner cnv1(&cnet1); + ControlNetVersioner cnv2(&cnet2); + + // report first difference only + if (ui.GetString("REPORT") == "FIRST") { + tolerances = PvlGroup(); + ignorekeys = PvlGroup(); + + differenceReason = ""; + filesMatch = true; + + if (diffFile != nullptr) { + if(diffFile->hasGroup("Tolerances")) { + tolerances = diffFile->findGroup("Tolerances"); + } + + if(diffFile->hasGroup("IgnoreKeys")) { + ignorekeys = diffFile->findGroup("IgnoreKeys"); + } + } + + // Don't want to consider the DateTime of a Point or Measure was set by + // default. + if(!ignorekeys.hasKeyword("DateTime")) { + ignorekeys += PvlKeyword("DateTime", "true"); + } + + // compare ControlNetVersioners + Compare(cnv1, cnv2); + + PvlGroup differences("Results"); + if (filesMatch) { + differences += PvlKeyword("Compare", "Identical"); + } + else { + differences += PvlKeyword("Compare", "Different"); + differences += PvlKeyword("Reason", differenceReason); + } + + log.addLogGroup(differences); + + if (ui.WasEntered("TO")) log.write(ui.GetFileName("TO")); + + differenceReason = ""; + + return log; + } + else { // do full report + FileName fileName1(ui.GetFileName("FROM")); + FileName fileName2(ui.GetFileName("FROM2")); + + ControlNetDiff differencer; + if (diffFile != nullptr) { + differencer.addTolerances(*diffFile); + } + + Pvl out = differencer.compare(fileName1, fileName2); + if (ui.WasEntered("TO")) out.write(ui.GetFileName("TO")); + + PvlGroup results("Results"); + + // Get a count of all the differences: just the keywords at the object level + // (network data) and the number of objects (different points). Ignore the + // FileName keyword as it's a superficial difference. + PvlObject &differences = out.findObject("Differences"); + int count = differences.objects() + differences.keywords(); + + if (differences.hasKeyword("Filename")) count--; + + results += PvlKeyword("Compare", count > 0 ? "Different" : "Identical"); + log.addLogGroup(results); + return log; + } + } + + + /** + * Compare two ControlNetVersioner objects + * + * @param ControlNetVersioner net1 + * @param ControlNetVersioner net2 + */ + void Compare(ControlNetVersioner &net1, ControlNetVersioner &net2) { + + Pvl net1Pvl(net1.toPvl()); + Pvl net2Pvl(net2.toPvl()); + + PvlObject &net1Obj = net1Pvl.findObject("ControlNetwork"); + PvlObject &net2Obj = net2Pvl.findObject("ControlNetwork"); + + BigInt net1NumPts = net1Obj.objects(); + BigInt net2NumPts = net2Obj.objects(); + + if (net1NumPts != net2NumPts) { + differenceReason = "The number of control points in the networks, [" + + toString(net1NumPts) + "] and [" + + toString(net2NumPts) + "], differ."; + filesMatch = false; + return; + } + + QString id1 = net1Obj["NetworkId"][0]; + QString id2 = net2Obj["NetworkId"][0]; + + if (id1 != id2) { + differenceReason = "The network IDs [" + + id1 + "] and [" + + id2 + "] differ."; + filesMatch = false; + return; + } + + QString target1 = net1Obj["TargetName"][0]; + QString target2 = net2Obj["TargetName"][0]; + + if (target1 != target2) { + differenceReason = "The TargetName values [" + + target1 + "] and [" + + target2 + "] differ."; + filesMatch = false; + return; + } + + for(int cpIndex = 0; cpIndex < net1NumPts; cpIndex ++) { + PvlObject &cp1 = net1Obj.object(cpIndex); + PvlObject &cp2 = net2Obj.object(cpIndex); + + Compare(cp1, cp2); + + if (!filesMatch) { + return; + } + } + } + + + /** + * Compare two point PvlObjects + * + * @param const PvlObject point1Pvl + * @param const PvlObject point2Pvl + */ + void Compare(const PvlObject &point1Pvl, const PvlObject &point2Pvl) { + // both names must be at least equal, should be named ControlPoint + if (point1Pvl.name() != point2Pvl.name()) { + QString msg = "The control points' CreatePvlOject method returned an " + "unexpected result."; + throw IException(IException::Programmer, msg, _FILEINFO_); + } + + if (point1Pvl.groups() != point2Pvl.groups()) { + filesMatch = false; + differenceReason = "The number of control measures, [" + + toString(point1Pvl.groups()) + "] and [" + + toString(point2Pvl.groups()) + "] does not match."; + } + + // Start by comparing top level control point keywords. + if (filesMatch) CompareGroups(point1Pvl, point2Pvl); + + // Now compare each measure + for(int cmIndex = 0; filesMatch && cmIndex < point1Pvl.groups(); cmIndex ++) { + const PvlGroup &measure1 = point1Pvl.group(cmIndex); + const PvlGroup &measure2 = point2Pvl.group(cmIndex); + + CompareGroups(measure1, measure2); + + if(!filesMatch) { + differenceReason = "Control Measure for Cube [" + + measure1["SerialNumber"][0] + "] " + differenceReason; + } + } + + if (!filesMatch) { + differenceReason = "Control Point [" + point1Pvl["PointId"][0] + + "] " + differenceReason; + } + } + + + /** + * Compare two PvlContainer objects + * + * @param const PvlContainer pvl1 + * @param const PvlContainer pvl2 + */ + void CompareGroups(const PvlContainer &pvl1, const PvlContainer &pvl2) { + // Create equivalent PvlGroups that can easily be compared to each other + PvlGroup point1FullKeys; + PvlGroup point2FullKeys; + + for(int keywordIndex = 0; keywordIndex < pvl1.keywords(); keywordIndex++) { + PvlKeyword thisKey = pvl1[keywordIndex]; + point1FullKeys += thisKey; + + if (!pvl2.hasKeyword(thisKey.name())) { + point2FullKeys += PvlKeyword(thisKey.name(), ""); + } + } + + for(int keywordIndex = 0; keywordIndex < pvl2.keywords(); keywordIndex++) { + PvlKeyword thisKey = pvl2[keywordIndex]; + point2FullKeys += thisKey; + + if (!pvl1.hasKeyword(thisKey.name())) { + point1FullKeys += PvlKeyword(thisKey.name(), ""); + } + } + + // Now compare the PvlGroups + for(int keywordIndex = 0; + keywordIndex < point1FullKeys.keywords(); + keywordIndex++) { + PvlKeyword key1 = point1FullKeys[keywordIndex]; + PvlKeyword key2 = point2FullKeys[key1.name()]; + CompareKeywords(key1, key2); + } + } + + + /** + * Compare two PvlKeyword objects + * + * @param const PvlKeyword pvl1 + * @param const PvlKeyword pvl2 + */ + void CompareKeywords(const PvlKeyword &pvl1, const PvlKeyword &pvl2) { + if (pvl1.name().compare(pvl2.name()) != 0) { + QString msg = "CompareKeywords should always be called with keywords that " + "have the same name."; + throw IException(IException::Programmer, msg, _FILEINFO_); + } + + if (pvl1.size() != pvl2.size()) { + filesMatch = false; + differenceReason = "Value '" + pvl1.name() + "' array size does not match."; + return; + } + + if (tolerances.hasKeyword(pvl1.name()) && + tolerances[pvl1.name()].size() > 1 && + pvl1.size() != tolerances[pvl1.name()].size()) { + QString msg = "Size of value '" + pvl1.name() + "' does not match with "; + msg += "its number of tolerances in the DIFF file."; + throw IException(IException::User, msg, _FILEINFO_); + } + + if (ignorekeys.hasKeyword(pvl1.name()) && + ignorekeys[pvl1.name()].size() > 1 && + pvl1.size() != ignorekeys[pvl1.name()].size()) { + QString msg = "Size of value '" + pvl1.name() + "' does not match with "; + msg += "its number of ignore keys in the DIFF file."; + throw IException(IException::User, msg, _FILEINFO_); + } + + for(int i = 0; i < pvl1.size() && filesMatch; i++) { + QString val1 = pvl1[i]; + QString val2 = pvl2[i]; + QString unit1 = pvl1.unit(i); + QString unit2 = pvl2.unit(i); + + int ignoreIndex = 0; + if (ignorekeys.hasKeyword(pvl1.name()) && ignorekeys[pvl1.name()].size() > 1) { + ignoreIndex = i; + } + + try { + if (!ignorekeys.hasKeyword(pvl1.name()) || + ignorekeys[pvl1.name()][ignoreIndex] == "false") { + + if (unit1.toLower() != unit2.toLower()) { + filesMatch = false; + differenceReason = "Value '" + pvl1.name() + "': units do not match."; + return; + } + + double tolerance = 0.0; + double difference = abs(toDouble(val1) - toDouble(val2)); + + if (tolerances.hasKeyword(pvl1.name())) { + tolerance = toDouble((tolerances[pvl1.name()].size() == 1) ? + tolerances[pvl1.name()][0] : tolerances[pvl1.name()][i]); + } + + if (difference > tolerance) { + filesMatch = false; + if (pvl1.size() == 1) { + differenceReason = "Value [" + pvl1.name() + "] difference is " + + toString(difference); + } + else { + differenceReason = "Value [" + pvl1.name() + "] at index " + + toString(i) + ": difference is " + toString(difference); + } + differenceReason += " (values are [" + val1 + "] and [" + + val2 + "], tolerance is [" + toString(tolerance) + "])"; + } + } + } + catch(IException &e) { + if (val1.toLower() != val2.toLower()) { + filesMatch = false; + differenceReason = "Value '" + pvl1.name() + "': values do not match."; + } + } + } + } + +} + + diff --git a/isis/src/control/apps/cnetdiff/cnetdiff.h b/isis/src/control/apps/cnetdiff/cnetdiff.h new file mode 100644 index 0000000000..e6229c3e83 --- /dev/null +++ b/isis/src/control/apps/cnetdiff/cnetdiff.h @@ -0,0 +1,20 @@ +/** This is free and unencumbered software released into the public domain. + +The authors of ISIS do not claim copyright on the contents of this file. +For more details about the LICENSE terms and the AUTHORS, you will +find files of those names at the top level of this repository. **/ + +/* SPDX-License-Identifier: CC0-1.0 */ +#ifndef cnetdiff_h +#define cnetdiff_h + +#include "ControlNet.h" +#include "UserInterface.h" + +namespace Isis{ + extern Pvl cnetdiff(UserInterface &ui); + extern Pvl cnetdiff(ControlNet &cnet1, ControlNet &cnet2, + UserInterface &ui, Pvl *diffFile=nullptr); +} + +#endif diff --git a/isis/src/control/apps/cnetdiff/main.cpp b/isis/src/control/apps/cnetdiff/main.cpp index c3ed771e64..1e07513a51 100644 --- a/isis/src/control/apps/cnetdiff/main.cpp +++ b/isis/src/control/apps/cnetdiff/main.cpp @@ -8,322 +8,14 @@ find files of those names at the top level of this repository. **/ #include "Isis.h" -#include -#include +#include "Application.h" +#include "Pvl.h" +#include "UserInterface.h" +#include "cnetdiff.h" -#include -#include - -#include "ControlMeasure.h" -#include "ControlNet.h" -#include "ControlNetDiff.h" -#include "ControlNetVersioner.h" -#include "ControlPoint.h" -#include "IException.h" -#include "PvlContainer.h" -#include "PvlGroup.h" - - -using namespace std; using namespace Isis; -bool filesMatch; -QString differenceReason; -PvlGroup tolerances; -PvlGroup ignorekeys; - -void CompareKeywords(const PvlKeyword &pvl1, const PvlKeyword &pvl2); -void CompareGroups(const PvlContainer &pvl1, const PvlContainer &pvl2); -void Compare(const PvlObject &point1, const PvlObject &point2); -void Compare(const QString net1Path, const QString net2Path); - void IsisMain() { UserInterface &ui = Application::GetUserInterface(); - - if (ui.GetString("REPORT") == "FIRST") { - tolerances = PvlGroup(); - ignorekeys = PvlGroup(); - - differenceReason = ""; - filesMatch = true; - - if(ui.WasEntered("DIFF")) { - Pvl diffFile(ui.GetFileName("DIFF")); - - if(diffFile.hasGroup("Tolerances")) { - tolerances = diffFile.findGroup("Tolerances"); - } - - if(diffFile.hasGroup("IgnoreKeys")) { - ignorekeys = diffFile.findGroup("IgnoreKeys"); - } - } - - // Don't want to consider the DateTime of a Point or Measure was set by - // default. - if(!ignorekeys.hasKeyword("DateTime")) { - ignorekeys += PvlKeyword("DateTime", "true"); - } - - Compare(ui.GetFileName("FROM"), ui.GetFileName("FROM2")); - - PvlGroup differences("Results"); - if(filesMatch) { - differences += PvlKeyword("Compare", "Identical"); - } - else { - differences += PvlKeyword("Compare", "Different"); - differences += PvlKeyword("Reason", differenceReason); - } - - Application::Log(differences); - - if(ui.WasEntered("TO")) { - Pvl out; - out.addGroup(differences); - out.write(ui.GetFileName("TO")); - } - - differenceReason = ""; - } - else { - FileName f1(ui.GetFileName("FROM")); - FileName f2(ui.GetFileName("FROM2")); - - ControlNetDiff differencer; - if (ui.WasEntered("DIFF")) { - Pvl diffFile(ui.GetFileName("DIFF")); - differencer.addTolerances(diffFile); - } - - Pvl results = differencer.compare(f1, f2); - if (ui.WasEntered("TO")) results.write(ui.GetFileName("TO")); - - PvlGroup log("Results"); - - // Get a count of all the differences: just the keywords at the object level - // (network data) and the number of objects (different points). Ignore the - // FileName keyword as it's a superficial difference. - PvlObject &differences = results.findObject("Differences"); - int count = differences.objects() + differences.keywords(); - if (differences.hasKeyword("Filename")) count--; - - log += PvlKeyword("Compare", count > 0 ? "Different" : "Identical"); - Application::Log(log); - } -} - -void Compare(QString net1Path, QString net2Path) { - ControlNetVersioner net1(net1Path); - ControlNetVersioner net2(net2Path); - - Pvl net1Pvl(net1.toPvl()); - Pvl net2Pvl(net2.toPvl()); - - PvlObject &net1Obj = net1Pvl.findObject("ControlNetwork"); - PvlObject &net2Obj = net2Pvl.findObject("ControlNetwork"); - - BigInt net1NumPts = net1Obj.objects(); - BigInt net2NumPts = net2Obj.objects(); - - if(net1NumPts != net2NumPts) { - differenceReason = "The number of control points in the networks, [" + - toString(net1NumPts) + "] and [" + - toString(net2NumPts) + "], differ."; - filesMatch = false; - return; - } - - QString id1 = net1Obj["NetworkId"][0]; - QString id2 = net2Obj["NetworkId"][0]; - - if(id1 != id2) { - differenceReason = "The network IDs [" + - id1 + "] and [" + - id2 + "] differ."; - filesMatch = false; - return; - } - - QString target1 = net1Obj["TargetName"][0]; - QString target2 = net2Obj["TargetName"][0]; - - if(target1 != target2) { - differenceReason = "The TargetName values [" + - target1 + "] and [" + - target2 + "] differ."; - filesMatch = false; - return; - } - -// QList net1Points = net1.GetPointIds(); -// QList net2Points = net2.GetPointIds(); -// qSort(net1Points); -// qSort(net2Points); - - for(int cpIndex = 0; cpIndex < net1NumPts; cpIndex ++) { - PvlObject &cp1 = net1Obj.object(cpIndex); - PvlObject &cp2 = net2Obj.object(cpIndex); - - Compare(cp1, cp2); - - if(!filesMatch) { - return; - } - } -} - -void Compare(const PvlObject &point1Pvl, const PvlObject &point2Pvl) { - // both names must be at least equal, should be named ControlPoint - if(point1Pvl.name() != point2Pvl.name()) { - QString msg = "The control points' CreatePvlOject method returned an " - "unexpected result."; - throw IException(IException::Programmer, msg, _FILEINFO_); - } - - if(point1Pvl.groups() != point2Pvl.groups()) { - filesMatch = false; - differenceReason = "The number of control measures, [" + - toString(point1Pvl.groups()) + "] and [" + - toString(point2Pvl.groups()) + "] does not match."; - } - - // Start by comparing top level control point keywords. - if(filesMatch) CompareGroups(point1Pvl, point2Pvl); - - // Now compare each measure - for(int cmIndex = 0; filesMatch && cmIndex < point1Pvl.groups(); cmIndex ++) { - const PvlGroup &measure1 = point1Pvl.group(cmIndex); - const PvlGroup &measure2 = point2Pvl.group(cmIndex); - - CompareGroups(measure1, measure2); - - if(!filesMatch) { - differenceReason = "Control Measure for Cube [" + - measure1["SerialNumber"][0] + "] " + differenceReason; - } - } - - if(!filesMatch) { - differenceReason = "Control Point [" + point1Pvl["PointId"][0] + - "] " + differenceReason; - } -} - - -void CompareGroups(const PvlContainer &pvl1, const PvlContainer &pvl2) { - // Create equivalent PvlGroups that can easily be compared to each other - PvlGroup point1FullKeys; - PvlGroup point2FullKeys; - - for(int keywordIndex = 0; keywordIndex < pvl1.keywords(); keywordIndex++) { - PvlKeyword thisKey = pvl1[keywordIndex]; - point1FullKeys += thisKey; - - if(!pvl2.hasKeyword(thisKey.name())) { - point2FullKeys += PvlKeyword(thisKey.name(), ""); - } - } - - for(int keywordIndex = 0; keywordIndex < pvl2.keywords(); keywordIndex++) { - PvlKeyword thisKey = pvl2[keywordIndex]; - point2FullKeys += thisKey; - - if(!pvl1.hasKeyword(thisKey.name())) { - point1FullKeys += PvlKeyword(thisKey.name(), ""); - } - } - - // Now compare the PvlGroups - for(int keywordIndex = 0; - keywordIndex < point1FullKeys.keywords(); - keywordIndex++) { - PvlKeyword key1 = point1FullKeys[keywordIndex]; - PvlKeyword key2 = point2FullKeys[key1.name()]; - CompareKeywords(key1, key2); - } -} - - - -void CompareKeywords(const PvlKeyword &pvl1, const PvlKeyword &pvl2) { - if(pvl1.name().compare(pvl2.name()) != 0) { - QString msg = "CompareKeywords should always be called with keywords that " - "have the same name."; - throw IException(IException::Programmer, msg, _FILEINFO_); - } - - if(pvl1.size() != pvl2.size()) { - filesMatch = false; - differenceReason = "Value '" + pvl1.name() + "' array size does not match."; - return; - } - - if(tolerances.hasKeyword(pvl1.name()) && - tolerances[pvl1.name()].size() > 1 && - pvl1.size() != tolerances[pvl1.name()].size()) { - QString msg = "Size of value '" + pvl1.name() + "' does not match with "; - msg += "its number of tolerances in the DIFF file."; - throw IException(IException::User, msg, _FILEINFO_); - } - - if(ignorekeys.hasKeyword(pvl1.name()) && - ignorekeys[pvl1.name()].size() > 1 && - pvl1.size() != ignorekeys[pvl1.name()].size()) { - QString msg = "Size of value '" + pvl1.name() + "' does not match with "; - msg += "its number of ignore keys in the DIFF file."; - throw IException(IException::User, msg, _FILEINFO_); - } - - for(int i = 0; i < pvl1.size() && filesMatch; i++) { - QString val1 = pvl1[i]; - QString val2 = pvl2[i]; - QString unit1 = pvl1.unit(i); - QString unit2 = pvl2.unit(i); - - int ignoreIndex = 0; - if(ignorekeys.hasKeyword(pvl1.name()) && ignorekeys[pvl1.name()].size() > 1) { - ignoreIndex = i; - } - - try { - if(!ignorekeys.hasKeyword(pvl1.name()) || - ignorekeys[pvl1.name()][ignoreIndex] == "false") { - - if(unit1.toLower() != unit2.toLower()) { - filesMatch = false; - differenceReason = "Value '" + pvl1.name() + "': units do not match."; - return; - } - - double tolerance = 0.0; - double difference = abs(toDouble(val1) - toDouble(val2)); - - if(tolerances.hasKeyword(pvl1.name())) { - tolerance = toDouble((tolerances[pvl1.name()].size() == 1) ? - tolerances[pvl1.name()][0] : tolerances[pvl1.name()][i]); - } - - if(difference > tolerance) { - filesMatch = false; - if(pvl1.size() == 1) { - differenceReason = "Value [" + pvl1.name() + "] difference is " + - toString(difference); - } - else { - differenceReason = "Value [" + pvl1.name() + "] at index " + - toString(i) + ": difference is " + toString(difference); - } - differenceReason += " (values are [" + val1 + "] and [" + - val2 + "], tolerance is [" + toString(tolerance) + "])"; - } - } - } - catch(IException &e) { - if(val1.toLower() != val2.toLower()) { - filesMatch = false; - differenceReason = "Value '" + pvl1.name() + "': values do not match."; - } - } - } + Pvl results = cnetdiff(ui); } diff --git a/isis/src/control/apps/cnetdiff/tsts/Makefile b/isis/src/control/apps/cnetdiff/tsts/Makefile deleted file mode 100644 index 46d84c74c2..0000000000 --- a/isis/src/control/apps/cnetdiff/tsts/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -BLANKS = "%-6s" -LENGTH = "%-40s" - -include $(ISISROOT)/make/isismake.tststree diff --git a/isis/src/control/apps/cnetdiff/tsts/default/Makefile b/isis/src/control/apps/cnetdiff/tsts/default/Makefile deleted file mode 100644 index 741df54876..0000000000 --- a/isis/src/control/apps/cnetdiff/tsts/default/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -APPNAME = cnetdiff - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(APPNAME) from=$(INPUT)/cnet.net from2=$(INPUT)/cnet.net \ - to=$(OUTPUT)/compareSame1.txt > /dev/null; - $(APPNAME) from=$(INPUT)/cnet2.net from2=$(INPUT)/cnet2.net \ - to=$(OUTPUT)/compareSame2.txt > /dev/null; - $(APPNAME) from=$(INPUT)/cnet.net from2=$(INPUT)/cnet2.net \ - to=$(OUTPUT)/compareDifferent.txt > /dev/null; - $(APPNAME) from=$(INPUT)/cnet.net from2=$(INPUT)/cnet2.net \ - to=$(OUTPUT)/compareDifferent2.txt DIFF=$(INPUT)/cnet.diff > /dev/null; diff --git a/isis/src/control/apps/cnetdiff/tsts/full/Makefile b/isis/src/control/apps/cnetdiff/tsts/full/Makefile deleted file mode 100644 index e81ce3ae4e..0000000000 --- a/isis/src/control/apps/cnetdiff/tsts/full/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -APPNAME = cnetdiff - -include $(ISISROOT)/make/isismake.tsts - -commands: - cnetpvl2bin from=$(INPUT)/cnet.pvl to=$(OUTPUT)/cnet.net > /dev/null; - cnetpvl2bin from=$(INPUT)/cnet2.pvl to=$(OUTPUT)/cnet2.net > /dev/null; - - $(APPNAME) from=$(OUTPUT)/cnet.net from2=$(OUTPUT)/cnet.net \ - to=$(OUTPUT)/compareSame1.txt report=full > /dev/null; - $(APPNAME) from=$(OUTPUT)/cnet2.net from2=$(OUTPUT)/cnet2.net \ - to=$(OUTPUT)/compareSame2.txt report=full > /dev/null; - $(APPNAME) from=$(OUTPUT)/cnet.net from2=$(OUTPUT)/cnet2.net \ - to=$(OUTPUT)/compareDifferent.txt report=full > /dev/null; - $(APPNAME) from=$(OUTPUT)/cnet.net from2=$(OUTPUT)/cnet2.net \ - to=$(OUTPUT)/compareDifferent2.txt DIFF=$(INPUT)/cnet.diff \ - report=full > /dev/null; - - rm $(OUTPUT)/cnet.net > /dev/null; - rm $(OUTPUT)/cnet2.net > /dev/null; diff --git a/isis/tests/FunctionalTestsCnetdiff.cpp b/isis/tests/FunctionalTestsCnetdiff.cpp new file mode 100644 index 0000000000..7ee007cf59 --- /dev/null +++ b/isis/tests/FunctionalTestsCnetdiff.cpp @@ -0,0 +1,1023 @@ +#include +#include +#include +#include + +#include "Progress.h" +#include "Pvl.h" +#include "PvlGroup.h" + +#include "cnetdiff.h" +#include "ControlMeasure.h" +#include "ControlPoint.h" +#include "ControlNet.h" +#include "SurfacePoint.h" +#include "TempFixtures.h" + +#include "gtest/gtest.h" + +using namespace Isis; + +static QString APP_XML = FileName("$ISISROOT/bin/xml/cnetdiff.xml").expanded(); + +class CompareNetsReportFirstDiff : public TempTestingFiles { + protected: + QString cnetFile1; + QString cnetFile2; + QString diffsFile; + + void SetUp() override { + TempTestingFiles::SetUp(); + + cnetFile1 = tempDir.path() + "/cnet1.net"; + cnetFile2 = tempDir.path() + "/cnet2.net"; + + diffsFile = tempDir.path() + "/diffs.txt"; + + // setup net1 + ControlNet net1; + + net1.SetNetworkId("Test"); + net1.SetTarget("Mars"); + net1.SetUserName("TSucharski"); + net1.SetCreatedDate("2010-07-10T12:50:15"); + net1.SetModifiedDate("2010-07-10T12:50:55"); + net1.SetDescription("UnitTest of ControlNetwork"); + + ControlPoint *cp1a = new ControlPoint("T0000"); + cp1a->SetType(ControlPoint::Fixed); + cp1a->SetChooserName("autoseed"); + cp1a->SetAprioriSurfacePointSource(ControlPoint::SurfacePointSource::Basemap); + cp1a->SetAprioriSurfacePointSourceFile("/work1/tsucharski/basemap.cub"); + cp1a->SetAprioriRadiusSource(ControlPoint::RadiusSource::DEM); + cp1a->SetAprioriRadiusSourceFile("$base/dems/molaMarsPlanetaryRadius0003.cub"); + + SurfacePoint surfacePt1(Displacement(-424.024048, Displacement::Meters), + Displacement(734.4311949, Displacement::Meters), + Displacement(529.919264, Displacement::Meters), + Distance(10, Distance::Meters), + Distance(50, Distance::Meters), + Distance(20, Distance::Meters)); + + // set apriori and adjusted surface points to the same values here + cp1a->SetAprioriSurfacePoint(surfacePt1); + cp1a->SetAdjustedSurfacePoint(surfacePt1); + + ControlMeasure *measure1aid0 = new ControlMeasure(); + measure1aid0->SetCubeSerialNumber("id0"); + measure1aid0->SetCoordinate(0.0, 0.0); + measure1aid0->SetType(ControlMeasure::Candidate); + measure1aid0->SetChooserName("cnetref"); + measure1aid0->SetDateTime("2010-08-27T17:10:06"); + measure1aid0->SetEditLock(true); + + ControlMeasure *measure1aid1 = new ControlMeasure(); + measure1aid1->SetCubeSerialNumber("id1"); + measure1aid1->SetCoordinate(1.0, 2.0); + measure1aid1->SetDiameter(15.0); + measure1aid1->SetType(ControlMeasure::Candidate); + measure1aid1->SetIgnored(true); + measure1aid1->SetAprioriSample(2.0); + measure1aid1->SetAprioriLine(5.0); + measure1aid1->SetSampleSigma(0.01); + measure1aid1->SetLineSigma(0.21); + measure1aid1->SetResidual(-3.0, 4.0); + measure1aid1->SetChooserName("autoseed"); + measure1aid1->SetDateTime("2010-08-27T17:10:06"); + + cp1a->Add(measure1aid0); + cp1a->Add(measure1aid1); + cp1a->SetDateTime("2010-08-27T17:10:06"); + cp1a->SetEditLock(true); + net1.AddPoint(cp1a); + + ControlPoint *cp1b = new ControlPoint("T0001"); + cp1b->SetType(ControlPoint::Free); + cp1b->SetChooserName("autoseed"); + cp1b->SetIgnored(true); + + ControlMeasure *measure1bid0 = new ControlMeasure(); + measure1bid0->SetCubeSerialNumber("id0"); + measure1bid0->SetCoordinate(0.0, 0.0); + measure1bid0->SetType(ControlMeasure::Candidate); + measure1bid0->SetChooserName("cnetref"); + measure1bid0->SetDateTime("2010-08-27T17:10:06"); + measure1bid0->SetEditLock(true); + + ControlMeasure *measure1bid1 = new ControlMeasure(); + measure1bid1->SetCubeSerialNumber("id1"); + measure1bid1->SetCoordinate(1.0, 2.0); + measure1bid1->SetDiameter(15.0); + measure1bid1->SetType(ControlMeasure::Candidate); + measure1bid1->SetIgnored(true); + measure1bid1->SetAprioriSample(2.0); + measure1bid1->SetAprioriLine(5.0); + measure1bid1->SetSampleSigma(0.01); + measure1bid1->SetLineSigma(0.21); + measure1bid1->SetResidual(-3.0, 4.0); + measure1bid1->SetChooserName("autoseed"); + measure1bid1->SetDateTime("2010-08-27T17:10:06"); + + cp1b->Add(measure1bid0); + cp1b->Add(measure1bid1); + cp1b->SetDateTime("2010-08-27T17:10:06"); + net1.AddPoint(cp1b); + + ControlPoint *cp1c = new ControlPoint("T0003"); + cp1c->SetType(ControlPoint::Free); + cp1c->SetChooserName("autoseed"); + + ControlMeasure *measure1cid0 = new ControlMeasure(); + measure1cid0->SetCubeSerialNumber("id0"); + measure1cid0->SetCoordinate(0.0, 0.0); + measure1cid0->SetType(ControlMeasure::Candidate); + measure1cid0->SetChooserName("cnetref"); + measure1cid0->SetDateTime("2010-08-27T17:10:06"); + measure1cid0->SetEditLock(true); + + ControlMeasure *measure1cid1 = new ControlMeasure(); + measure1cid1->SetCubeSerialNumber("id1"); + measure1cid1->SetCoordinate(1.0, 2.0); + measure1cid1->SetDiameter(15.0); + measure1cid1->SetType(ControlMeasure::Candidate); + measure1cid1->SetIgnored(true); + measure1cid1->SetAprioriSample(2.0); + measure1cid1->SetAprioriLine(5.0); + measure1cid1->SetSampleSigma(0.01); + measure1cid1->SetLineSigma(0.21); + measure1cid1->SetResidual(-3.0, 4.0); + measure1cid1->SetChooserName("autoseed"); + measure1cid1->SetDateTime("2010-08-27T17:10:06"); + + cp1c->Add(measure1cid0); + cp1c->Add(measure1cid1); + cp1c->SetDateTime("2010-08-27T17:10:06"); + net1.AddPoint(cp1c); + + ControlPoint *cp1d = new ControlPoint("T0004"); + cp1d->SetType(ControlPoint::Free); + cp1d->SetChooserName("autoseed"); + + ControlMeasure *measure1did0 = new ControlMeasure(); + measure1did0->SetCubeSerialNumber("id0"); + measure1did0->SetCoordinate(0.0, 0.0); + measure1did0->SetType(ControlMeasure::Candidate); + measure1did0->SetChooserName("cnetref"); + measure1did0->SetDateTime("2010-08-27T17:10:06"); + measure1did0->SetEditLock(true); + + ControlMeasure *measure1did1 = new ControlMeasure(); + measure1did1->SetCubeSerialNumber("id1"); + measure1did1->SetCoordinate(1.0, 2.0); + measure1did1->SetDiameter(15.0); + measure1did1->SetType(ControlMeasure::Candidate); + measure1did1->SetIgnored(true); + measure1did1->SetAprioriSample(2.0); + measure1did1->SetAprioriLine(5.0); + measure1did1->SetSampleSigma(0.01); + measure1did1->SetLineSigma(0.21); + measure1did1->SetResidual(-3.0, 4.0); + measure1did1->SetChooserName("autoseed"); + measure1did1->SetDateTime("2010-08-27T17:10:06"); + + cp1d->Add(measure1did0); + cp1d->Add(measure1did1); + cp1d->SetDateTime("2010-08-27T17:10:06"); + net1.AddPoint(cp1d); + + net1.Write(cnetFile1); + + // construct net2 from net1 and change some items + ControlNet net2(net1); + + ControlPoint *point2a = net2["T0000"]; + ControlMeasure* measure2aid1 = point2a->GetMeasure("id1"); + measure2aid1->SetResidual(-1.0, 4.0); + measure2aid1->SetChooserName("autoseed"); + measure2aid1->SetDateTime("2010-08-27T17:10:06"); + + ControlPoint *point2b = net2["T0001"]; + ControlMeasure* measure2bid1 = point2b->GetMeasure("id1"); + measure2bid1->SetResidual(-1.0, 4.0); + measure2bid1->SetChooserName("autoseed"); + measure2bid1->SetDateTime("2010-08-27T17:10:06"); + + ControlPoint *point2c = net2["T0003"]; + ControlMeasure* measure2cid1 = point2c->GetMeasure("id1"); + measure2cid1->SetResidual(-1.0, 4.0); + measure2cid1->SetChooserName("autoseed"); + measure2cid1->SetDateTime("2010-08-27T17:10:06"); + + ControlPoint *point2d = net2["T0004"]; + ControlMeasure* measure2did1 = point2d->GetMeasure("id1"); + measure2did1->SetResidual(-1.0, 4.0); + measure2did1->SetChooserName("autoseed"); + measure2did1->SetDateTime("2010-08-27T17:10:06"); + + net2.Write(cnetFile2); + + // set up pvl difference file + Pvl diffs; + PvlGroup toleranceGroup("Tolerances"); + toleranceGroup.addKeyword(PvlKeyword("SampleResidual", "1.5")); + diffs.addGroup(toleranceGroup); + diffs.write(diffsFile); + } +}; + +class CompareNetsReportFull : public TempTestingFiles { + protected: + QString cnetFile1; + QString cnetFile2; + + QString diffsFile; + + void SetUp() override { + TempTestingFiles::SetUp(); + + cnetFile1 = tempDir.path() + "/cnet1.net"; + cnetFile2 = tempDir.path() + "/cnet2.net"; + + diffsFile = tempDir.path() + "/diffs.txt"; + + // setup net1 + ControlNet net1; + + net1.SetNetworkId("Test"); + net1.SetTarget("Mars"); + net1.SetUserName("TSucharski"); + net1.SetCreatedDate("2010-07-10T12:50:15"); + net1.SetModifiedDate("2010-07-10T12:50:55"); + net1.SetDescription("UnitTest of ControlNetwork"); + + ControlPoint *cp3a = new ControlPoint("T0001"); + cp3a->SetType(ControlPoint::Free); + cp3a->SetChooserName("autoseed"); + cp3a->SetIgnored(true); + + ControlMeasure *measure3aid0 = new ControlMeasure(); + measure3aid0->SetCubeSerialNumber("id0"); + measure3aid0->SetCoordinate(0.0, 0.0); + measure3aid0->SetType(ControlMeasure::Candidate); + measure3aid0->SetChooserName("cnetref"); + measure3aid0->SetDateTime("2010-08-27T17:10:06"); + measure3aid0->SetEditLock(true); + + ControlMeasure *measure3aid1 = new ControlMeasure(); + measure3aid1->SetCubeSerialNumber("id1"); + measure3aid1->SetCoordinate(1.0, 2.0); + measure3aid1->SetDiameter(15.0); + measure3aid1->SetType(ControlMeasure::Candidate); + measure3aid1->SetIgnored(true); + measure3aid1->SetAprioriSample(2.0); + measure3aid1->SetAprioriLine(5.0); + measure3aid1->SetSampleSigma(0.01); + measure3aid1->SetLineSigma(0.21); + measure3aid1->SetResidual(-3.0, 4.0); + measure3aid1->SetChooserName("autoseed"); + measure3aid1->SetDateTime("2010-08-27T17:10:06"); + + cp3a->Add(measure3aid0); + cp3a->Add(measure3aid1); + cp3a->SetDateTime("2010-08-27T17:10:06"); + net1.AddPoint(cp3a); + + ControlPoint *cp3b = new ControlPoint("T0003"); + cp3b->SetType(ControlPoint::Free); + cp3b->SetChooserName("autoseed"); + cp3b->SetAprioriSurfacePointSource(ControlPoint::SurfacePointSource::Basemap); + cp3b->SetAprioriSurfacePointSourceFile("/work1/tsucharski/basemap.cub"); + cp3b->SetAprioriRadiusSource(ControlPoint::RadiusSource::DEM); + cp3b->SetAprioriRadiusSourceFile("$base/dems/molaMarsPlanetaryRadius0003.cub"); + + SurfacePoint surfacePt1(Displacement(-424.024048, Displacement::Meters), + Displacement(734.4311949, Displacement::Meters), + Displacement(529.919264, Displacement::Meters), + Distance(10, Distance::Meters), + Distance(50, Distance::Meters), + Distance(20, Distance::Meters)); + + cp3b->SetAprioriSurfacePoint(surfacePt1); + + SurfacePoint surfacePt2(Displacement(-423.024048, Displacement::Meters), + Displacement(754.4311949, Displacement::Meters), + Displacement(523.919264, Displacement::Meters), + Distance(10, Distance::Meters), + Distance(50, Distance::Meters), + Distance(20, Distance::Meters)); + + cp3b->SetAdjustedSurfacePoint(surfacePt2); + + ControlMeasure *measure3bid0 = new ControlMeasure(); + measure3bid0->SetCubeSerialNumber("id0"); + measure3bid0->SetCoordinate(0.0, 0.0); + measure3bid0->SetType(ControlMeasure::Candidate); + measure3bid0->SetChooserName("cnetref"); + measure3bid0->SetDateTime("2010-08-27T17:10:06"); + measure3bid0->SetEditLock(true); + + ControlMeasure *measure3bid1 = new ControlMeasure(); + measure3bid1->SetCubeSerialNumber("id1"); + measure3bid1->SetCoordinate(1.0, 2.0); + measure3bid1->SetDiameter(15.0); + measure3bid1->SetType(ControlMeasure::Candidate); + measure3bid1->SetIgnored(true); + measure3bid1->SetAprioriSample(2.0); + measure3bid1->SetAprioriLine(5.0); + measure3bid1->SetSampleSigma(0.01); + measure3bid1->SetLineSigma(0.21); + measure3bid1->SetResidual(-3.0, 4.0); + measure3bid1->SetChooserName("autoseed"); + measure3bid1->SetDateTime("2010-08-27T17:10:06"); + + cp3b->Add(measure3bid0); + cp3b->Add(measure3bid1); + cp3b->SetDateTime("2010-08-27T17:10:06"); + net1.AddPoint(cp3b); + + ControlPoint *cp3c = new ControlPoint("T0004"); + cp3c->SetType(ControlPoint::Free); + cp3c->SetChooserName("autoseed"); + cp3c->SetAprioriSurfacePoint(surfacePt1); + cp3c->SetAdjustedSurfacePoint(surfacePt1); + cp3c->SetAprioriRadiusSource(ControlPoint::RadiusSource::DEM); + cp3c->SetAprioriRadiusSourceFile("$base/dems/molaMarsPlanetaryRadius0003.cub"); + + ControlMeasure *measure3cid0 = new ControlMeasure(); + measure3cid0->SetCubeSerialNumber("id0"); + measure3cid0->SetCoordinate(4.0, 3.0); + measure3cid0->SetType(ControlMeasure::Candidate); + measure3cid0->SetResidual(1.0, -4.0); + measure3cid0->SetAprioriSample(10.0); + measure3cid0->SetAprioriLine(20.0); + measure3cid0->SetChooserName("cnetref"); + measure3cid0->SetDateTime("2010-08-27T17:10:06"); + measure3cid0->SetEditLock(true); + + ControlMeasure *measure3cid1 = new ControlMeasure(); + measure3cid1->SetCubeSerialNumber("id1"); + measure3cid1->SetCoordinate(1.0, 2.0); + measure3cid1->SetDiameter(15.0); + measure3cid1->SetType(ControlMeasure::Candidate); + measure3cid1->SetIgnored(true); + measure3cid1->SetAprioriSample(2.0); + measure3cid1->SetAprioriLine(5.0); + measure3cid1->SetSampleSigma(0.01); + measure3cid1->SetLineSigma(0.21); + measure3cid1->SetResidual(-3.0, 4.0); + measure3cid1->SetChooserName("autoseed"); + measure3cid1->SetDateTime("2010-08-27T17:10:06"); + + cp3c->Add(measure3cid0); + cp3c->Add(measure3cid1); + cp3c->SetDateTime("2010-08-27T17:10:06"); + cp3c->SetEditLock(true); + net1.AddPoint(cp3c); + + ControlPoint *cp3d = new ControlPoint("T0000"); + cp3d->SetType(ControlPoint::Fixed); + cp3d->SetChooserName("autoseed"); + + ControlMeasure *measure3did0 = new ControlMeasure(); + measure3did0->SetCubeSerialNumber("id0"); + measure3did0->SetCoordinate(2.0, 3.0); + measure3did0->SetType(ControlMeasure::Candidate); + measure3did0->SetChooserName("cnetref"); + measure3did0->SetDateTime("2010-08-27T17:10:06"); + measure3did0->SetEditLock(true); + + ControlMeasure *measure3did1 = new ControlMeasure(); + measure3did1->SetCubeSerialNumber("id1"); + measure3did1->SetCoordinate(1.0, 2.0); + measure3did1->SetDiameter(15.0); + measure3did1->SetType(ControlMeasure::Candidate); + measure3did1->SetIgnored(true); + measure3did1->SetAprioriSample(2.0); + measure3did1->SetAprioriLine(5.0); + measure3did1->SetSampleSigma(0.01); + measure3did1->SetLineSigma(0.21); + measure3did1->SetResidual(-3.0, 4.0); + measure3did1->SetChooserName("autoseed"); + measure3did1->SetDateTime("2010-08-27T17:10:06"); + + cp3d->Add(measure3did0); + cp3d->Add(measure3did1); + cp3d->SetDateTime("2010-08-27T17:10:06"); + cp3d->SetEditLock(true); + net1.AddPoint(cp3d); + + net1.Write(cnetFile1); + + // setup net2 + ControlNet net2; + + net2.SetNetworkId("Test2"); + net2.SetTarget("Moon"); + net2.SetUserName("TSucharski"); + net2.SetCreatedDate("2010-07-10T12:50:15"); + net2.SetModifiedDate("2010-07-10T12:50:55"); + net2.SetDescription("UnitTest of ControlNetwork"); + + ControlPoint *point4a = new ControlPoint("T0000"); + point4a->SetType(ControlPoint::Fixed); + point4a->SetChooserName("autoseed"); + + ControlMeasure *measure4aid0 = new ControlMeasure(); + measure4aid0->SetCubeSerialNumber("id0"); + measure4aid0->SetCoordinate(1.0, 2.0); + measure4aid0->SetType(ControlMeasure::Candidate); + measure4aid0->SetChooserName("cnetref"); + measure4aid0->SetDateTime("2010-08-27T17:10:06"); + measure4aid0->SetEditLock(true); + + ControlMeasure *measure4aid1 = new ControlMeasure(); + measure4aid1->SetCubeSerialNumber("id1"); + measure4aid1->SetCoordinate(1.0, 2.0); + measure4aid1->SetDiameter(15.0); + measure4aid1->SetType(ControlMeasure::Candidate); + measure4aid1->SetIgnored(true); + measure4aid1->SetAprioriSample(2.0); + measure4aid1->SetAprioriLine(5.0); + measure4aid1->SetSampleSigma(0.01); + measure4aid1->SetLineSigma(0.21); + measure4aid1->SetResidual(-1.0, 4.0); + measure4aid1->SetChooserName("autoseed"); + measure4aid1->SetDateTime("2010-08-27T17:10:06"); + + point4a->Add(measure4aid0); + point4a->Add(measure4aid1); + point4a->SetDateTime("2010-08-27T17:10:06"); + net2.AddPoint(point4a); + + ControlPoint *point4b = new ControlPoint("T0002"); + point4b->SetType(ControlPoint::Free); + point4b->SetChooserName("autoseed"); + point4b->SetIgnored(true); + + ControlMeasure *measure4bid0 = new ControlMeasure(); + measure4bid0->SetCubeSerialNumber("id0"); + measure4bid0->SetCoordinate(0.0, 0.0); + measure4bid0->SetType(ControlMeasure::Candidate); + measure4bid0->SetChooserName("cnetref"); + measure4bid0->SetDateTime("2010-08-27T17:10:06"); + measure4bid0->SetEditLock(true); + + ControlMeasure *measure4bid1 = new ControlMeasure(); + measure4bid1->SetCubeSerialNumber("id1"); + measure4bid1->SetCoordinate(1.0, 2.0); + measure4bid1->SetDiameter(15.0); + measure4bid1->SetType(ControlMeasure::Candidate); + measure4bid1->SetIgnored(true); + measure4bid1->SetAprioriSample(2.0); + measure4bid1->SetAprioriLine(5.0); + measure4bid1->SetSampleSigma(0.01); + measure4bid1->SetLineSigma(0.21); + measure4bid1->SetResidual(-1.0, 4.0); + measure4bid1->SetChooserName("autoseed"); + measure4bid1->SetDateTime("2010-08-27T17:10:06"); + + point4b->Add(measure4bid0); + point4b->Add(measure4bid1); + point4b->SetDateTime("2010-08-27T17:10:06"); + net2.AddPoint(point4b); + + ControlPoint *point4c = new ControlPoint("T0004"); + point4c->SetType(ControlPoint::Free); + point4c->SetAprioriSurfacePointSource(ControlPoint::SurfacePointSource::Basemap); + point4c->SetAprioriSurfacePointSourceFile("/work1/tsucharski/basemap.cub"); + point4c->SetAprioriRadiusSource(ControlPoint::RadiusSource::DEM); + point4c->SetAprioriRadiusSourceFile("$base/dems/molaMarsPlanetaryRadius0003.cub"); + point4c->SetAprioriSurfacePoint(surfacePt1); + point4c->SetAdjustedSurfacePoint(surfacePt2); + point4c->SetChooserName("autoseed"); + + ControlMeasure *measure4cid0 = new ControlMeasure(); + measure4cid0->SetCubeSerialNumber("id0"); + measure4cid0->SetCoordinate(1.0, 2.0); + measure4cid0->SetType(ControlMeasure::Candidate); + measure4cid0->SetResidual(1.0, -4.0); + measure4cid0->SetSampleSigma(0.01); + measure4cid0->SetLineSigma(0.21); + measure4cid0->SetResidual(-10.0, 4.0); + measure4cid0->SetChooserName("cnetref"); + measure4cid0->SetDateTime("2010-08-27T17:10:06"); + measure4cid0->SetEditLock(true); + + ControlMeasure *measure4cid2 = new ControlMeasure(); + measure4cid2->SetCubeSerialNumber("id2"); + measure4cid2->SetCoordinate(1.0, 2.0); + measure4cid2->SetDiameter(15.0); + measure4cid2->SetType(ControlMeasure::Candidate); + measure4cid2->SetIgnored(true); + measure4cid2->SetAprioriSample(2.0); + measure4cid2->SetAprioriLine(5.0); + measure4cid2->SetSampleSigma(0.01); + measure4cid2->SetLineSigma(0.21); + measure4cid2->SetResidual(-1.0, 4.0); + measure4cid2->SetChooserName("autoseed"); + measure4cid2->SetDateTime("2010-08-27T17:10:06"); + + ControlMeasure *measure4cid3 = new ControlMeasure(); + measure4cid3->SetCubeSerialNumber("id3"); + measure4cid3->SetCoordinate(1.0, 2.0); + measure4cid3->SetDiameter(15.0); + measure4cid3->SetType(ControlMeasure::Candidate); + measure4cid3->SetIgnored(true); + measure4cid3->SetAprioriSample(2.0); + measure4cid3->SetAprioriLine(5.0); + measure4cid3->SetSampleSigma(0.01); + measure4cid3->SetLineSigma(0.21); + measure4cid3->SetResidual(-1.0, 4.0); + measure4cid3->SetChooserName("autoseed"); + measure4cid3->SetDateTime("2010-08-27T17:10:06"); + + point4c->Add(measure4cid0); + point4c->Add(measure4cid2); + point4c->Add(measure4cid3); + point4c->SetDateTime("2010-08-27T17:10:06"); + net2.AddPoint(point4c); + + net2.Write(cnetFile2); + + // set up pvl difference file + Pvl diffs; + PvlGroup ignoreKeysGroup("IgnoreKeys"); + ignoreKeysGroup.addKeyword(PvlKeyword("AprioriSample", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("AprioriLine", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("SampleSigma", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("LineSigma", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("NetworkId", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("AprioriXYZSource", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("EditLock", "true")); + ignoreKeysGroup.addKeyword(PvlKeyword("AdjustedZ", "true")); + diffs.addGroup(ignoreKeysGroup); + + + PvlGroup toleranceGroup("Tolerances"); + toleranceGroup.addKeyword(PvlKeyword("Sample", "1")); + toleranceGroup.addKeyword(PvlKeyword("Line", "1")); + toleranceGroup.addKeyword(PvlKeyword("SampleResidual", "5")); + toleranceGroup.addKeyword(PvlKeyword("AdjustedX", "3")); + toleranceGroup.addKeyword(PvlKeyword("AdjustedY", "3")); + diffs.addGroup(toleranceGroup); + diffs.write(diffsFile); + } +}; + +/** + * CompareNetsReportFirst + * + * Runs 4 comparisons between binary control nets (reporting only + * the first difference)... + * a) cnet1 vs cnet1, should be identical + * b) cnet2 vs cnet2, should be identical + * c) cnet1 vs cnet2 + * d) cnet1 vs cnet2 with sample residual tolerance of 1.5 + * given in the input file diffs1.txt + */ +TEST_F(CompareNetsReportFirstDiff, FunctionalTestCnetdiffReportFirst) { + QVector args = {"from=" + cnetFile1, + "from2=" + cnetFile1, + "to=" + tempDir.path() + "/compareSame1.txt" + }; + + UserInterface ui1(APP_XML, args); + + Pvl log; + + try { + log = cnetdiff(ui1); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back CompareSame1 output file + Pvl comparePvlSame1; + try { + comparePvlSame1.read(tempDir.path()+ "/compareSame1.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + PvlGroup &results = comparePvlSame1.findGroup("Results", Pvl::Traverse); + EXPECT_EQ(results["Compare"][0].toStdString(), "Identical"); + + // cnet2 vs cnet2 + args = {"from=" + cnetFile2, + "from2=" + cnetFile2, + "to=" + tempDir.path() + "/compareSame2.txt" + }; + + UserInterface ui2(APP_XML, args); + + try { + log = cnetdiff(ui2); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back CompareSame2 output file + Pvl comparePvlSame2; + try { + comparePvlSame2.read(tempDir.path()+ "/compareSame2.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + results = comparePvlSame2.findGroup("Results", Pvl::Traverse); + EXPECT_EQ(results["Compare"][0].toStdString(), "Identical"); + + // cnet1 vs cnet2 + args = {"from=" + cnetFile1, + "from2=" + cnetFile2, + "to=" + tempDir.path() + "/compareDifferent.txt" + }; + + UserInterface ui3(APP_XML, args); + + try { + log = cnetdiff(ui3); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back CompareDifferent output file + Pvl comparePvlDifferent; + try { + comparePvlDifferent.read(tempDir.path()+ "/compareDifferent.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + results = comparePvlDifferent.findGroup("Results", Pvl::Traverse); + EXPECT_EQ(results["Compare"][0].toStdString(), "Different"); + EXPECT_EQ(results["Reason"][0].toStdString(), + "Control Point [T0000] Control Measure for Cube [id1] " + "Value [SampleResidual] difference is 2.0 (values are " + "[-3.0] and [-1.0], tolerance is [0.0])"); + + // cnet1 vs cnet2 with sample residual tolerance of 1.5 input in diffs file + args = {"from=" + cnetFile1, + "from2=" + cnetFile2, + "to=" + tempDir.path() + "/compareDifferent2.txt", + "diff=" + diffsFile + }; + + UserInterface ui4(APP_XML, args); + + try { + log = cnetdiff(ui4); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back CompareDifferent2 output file + Pvl comparePvlDifferent2; + try { + comparePvlDifferent2.read(tempDir.path()+ "/compareDifferent2.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + results = comparePvlDifferent2.findGroup("Results", Pvl::Traverse); + EXPECT_EQ(results["Compare"][0].toStdString(), "Different"); + EXPECT_EQ(results["Reason"][0].toStdString(), + "Control Point [T0000] Control Measure for Cube [id1] " + "Value [SampleResidual] difference is 2.0 (values are " + "[-3.0] and [-1.0], tolerance is [1.5])"); +} + +/** + * FunctionalTestCnetdiffReportFull + * + * 2) Runs 4 comparisons between binary control nets, generating full reports. + * a) cnet1 vs cnet1, should be identical + * b) cnet2 vs cnet2, should be identical + * c) cnet1 vs cnet2 + * d) cnet1 vs cnet2 using diffs2.txt containing... + * Group = IgnoreKeys + * AprioriSample = true + * AprioriLine = true + * SampleSigma = true + * LineSigma = true + * NetworkId = true + * AprioriXYZSource = true + * EditLock = true + * AdjustedZ = true + * EndGroup + * + * Group = Tolerances + * Sample = 1 + * Line = 1 + * SampleResidual = 5 + * AdjustedX = 3 + * AdjustedY = 3 + * EndGroup + */ +TEST_F(CompareNetsReportFull, FunctionalTestCnetdiffReportFull) { + + // compare cnet3 vs cnet3 + QVector args = {"from=" + cnetFile1, + "from2=" + cnetFile1, + "to=" + tempDir.path() + "/compareSame1.txt", + "report=full" + }; + + UserInterface ui1(APP_XML, args); + + Pvl log; + + try { + log = cnetdiff(ui1); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back compareSame1 output file + Pvl compareSame1; + try { + compareSame1.read(tempDir.path()+ "/compareSame1.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + // confirm there are no groups or objects in the difference + // object confirming cnet3 is identical to itself + ASSERT_TRUE(compareSame1.hasObject("Differences")); + PvlObject differences = compareSame1.findObject("Differences"); + EXPECT_EQ(differences.groups(), 0); + EXPECT_EQ(differences.objects(), 0); + + // compare cnet4 vs cnet4 + args = {"from=" + cnetFile2, + "from2=" + cnetFile2, + "to=" + tempDir.path() + "/compareSame2.txt", + "report=full" + }; + + UserInterface ui2(APP_XML, args); + + try { + log = cnetdiff(ui2); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back compareSame2 output file + Pvl compareSame2; + try { + compareSame2.read(tempDir.path()+ "/compareSame2.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + // confirm there are no groups or objects in the difference + // object confirming cnet4 is identical to itself + ASSERT_TRUE(compareSame2.hasObject("Differences")); + differences = compareSame2.findObject("Differences"); + EXPECT_EQ(differences.groups(), 0); + EXPECT_EQ(differences.objects(), 0); + + // compare cnet3 vs cnet4 + args = {"from=" + cnetFile1, + "from2=" + cnetFile2, + "to=" + tempDir.path() + "/compareDifferent1.txt", + "report=full" + }; + + UserInterface ui3(APP_XML, args); + + try { + log = cnetdiff(ui3); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back compareDifferent1 output file + Pvl compareDifferent1; + try { + compareDifferent1.read(tempDir.path() + "/compareDifferent1.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + PvlObject &DifferencesObject1 = compareDifferent1.findObject("Differences"); + EXPECT_EQ(DifferencesObject1.keywords(), 4); + EXPECT_EQ(DifferencesObject1.objects(), 5); + EXPECT_EQ(DifferencesObject1["Filename"][0].toStdString(), "cnet1.net"); + EXPECT_EQ(DifferencesObject1["Filename"][1].toStdString(), "cnet2.net"); + EXPECT_EQ(DifferencesObject1["Points"][0].toStdString(), "4"); + EXPECT_EQ(DifferencesObject1["Points"][1].toStdString(), "3"); + EXPECT_EQ(DifferencesObject1["NetworkId"][0].toStdString(), "Test"); + EXPECT_EQ(DifferencesObject1["NetworkId"][1].toStdString(), "Test2"); + EXPECT_EQ(DifferencesObject1["TargetName"][0].toStdString(), "Mars"); + EXPECT_EQ(DifferencesObject1["TargetName"][1].toStdString(), "Moon"); + + PvlObject &comp1P1 = DifferencesObject1.findObject("Point"); + EXPECT_EQ(comp1P1.keywords(), 2); + EXPECT_EQ(comp1P1.groups(), 2); + EXPECT_EQ(comp1P1["PointId"][0].toStdString(), "T0000"); + EXPECT_EQ(comp1P1["EditLock"][0].toStdString(), "True"); + EXPECT_EQ(comp1P1["EditLock"][1].toStdString(), "N/A"); + + PvlGroup &comp1P1M1 = comp1P1.findGroup("Measure"); + EXPECT_EQ(comp1P1M1.keywords(), 3); + EXPECT_EQ(comp1P1M1["SerialNumber"][0].toStdString(), "id0"); + EXPECT_EQ(comp1P1M1["Line"][0].toStdString(), "3.0"); + EXPECT_EQ(comp1P1M1["Line"][1].toStdString(), "2.0"); + EXPECT_EQ(comp1P1M1["Sample"][0].toStdString(), "2.0"); + EXPECT_EQ(comp1P1M1["Sample"][1].toStdString(), "1.0"); + comp1P1.deleteGroup("Measure"); + + PvlGroup &comp1P1M2 = comp1P1.findGroup("Measure"); + EXPECT_EQ(comp1P1M2.keywords(), 2); + EXPECT_EQ(comp1P1M2["SerialNumber"][0].toStdString(), "id1"); + EXPECT_EQ(comp1P1M2["SampleResidual"][0].toStdString(), "-3.0"); + EXPECT_EQ(comp1P1M2["SampleResidual"][1].toStdString(), "-1.0"); + DifferencesObject1.deleteObject("Point"); + + PvlObject &comp1P2 = DifferencesObject1.findObject("Point"); + EXPECT_EQ(comp1P2.keywords(), 1); + EXPECT_EQ(comp1P2["PointId"][0].toStdString(), "T0001"); + EXPECT_EQ(comp1P2["PointId"][1].toStdString(), "N/A"); + DifferencesObject1.deleteObject("Point"); + + PvlObject &comp1P3 = DifferencesObject1.findObject("Point"); + EXPECT_EQ(comp1P3.keywords(), 1); + EXPECT_EQ(comp1P3["PointId"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P3["PointId"][1].toStdString(), "T0002"); + DifferencesObject1.deleteObject("Point"); + + PvlObject &comp1P4 = DifferencesObject1.findObject("Point"); + EXPECT_EQ(comp1P4.keywords(), 1); + EXPECT_EQ(comp1P4["PointId"][0].toStdString(), "T0003"); + EXPECT_EQ(comp1P4["PointId"][1].toStdString(), "N/A"); + DifferencesObject1.deleteObject("Point"); + + PvlObject &comp1P5 = DifferencesObject1.findObject("Point"); + EXPECT_EQ(comp1P5.keywords(), 8); + EXPECT_EQ(comp1P5.groups(), 4); + EXPECT_EQ(comp1P5["PointId"][0].toStdString(), "T0004"); + EXPECT_EQ(comp1P5["Measures"][0].toStdString(), "2"); + EXPECT_EQ(comp1P5["Measures"][1].toStdString(), "3"); + EXPECT_EQ(comp1P5["AdjustedX"][0].toStdString(), "-424.024048"); + EXPECT_EQ(comp1P5["AdjustedX"][1].toStdString(), "-423.024048"); + EXPECT_EQ(comp1P5["AdjustedY"][0].toStdString(), "734.4311949"); + EXPECT_EQ(comp1P5["AdjustedY"][1].toStdString(), "754.4311949"); + EXPECT_EQ(comp1P5["AdjustedZ"][0].toStdString(), "529.919264"); + EXPECT_EQ(comp1P5["AdjustedZ"][1].toStdString(), "523.919264"); + EXPECT_EQ(comp1P5["AprioriXYZSource"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P5["AprioriXYZSource"][1].toStdString(), "Basemap"); + EXPECT_EQ(comp1P5["AprioriXYZSourceFile"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P5["AprioriXYZSourceFile"][1].toStdString(), "/work1/tsucharski/basemap.cub"); + EXPECT_EQ(comp1P5["EditLock"][0].toStdString(), "True"); + EXPECT_EQ(comp1P5["EditLock"][1].toStdString(), "N/A"); + + PvlGroup &comp1P5M1 = comp1P5.findGroup("Measure"); + EXPECT_EQ(comp1P5M1.keywords(), 9); + EXPECT_EQ(comp1P5M1["SerialNumber"][0].toStdString(), "id0"); + EXPECT_EQ(comp1P5M1["AprioriLine"][0].toStdString(), "20.0"); + EXPECT_EQ(comp1P5M1["AprioriLine"][1].toStdString(), "N/A"); + EXPECT_EQ(comp1P5M1["AprioriSample"][0].toStdString(), "10.0"); + EXPECT_EQ(comp1P5M1["AprioriSample"][1].toStdString(), "N/A"); + EXPECT_EQ(comp1P5M1["Line"][0].toStdString(), "3.0"); + EXPECT_EQ(comp1P5M1["Line"][1].toStdString(), "2.0"); + EXPECT_EQ(comp1P5M1["LineResidual"][0].toStdString(), "-4.0"); + EXPECT_EQ(comp1P5M1["LineResidual"][1].toStdString(), "4.0"); + EXPECT_EQ(comp1P5M1["LineSigma"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P5M1["LineSigma"][1].toStdString(), "0.21"); + EXPECT_EQ(comp1P5M1["Sample"][0].toStdString(), "4.0"); + EXPECT_EQ(comp1P5M1["Sample"][1].toStdString(), "1.0"); + EXPECT_EQ(comp1P5M1["SampleResidual"][0].toStdString(), "1.0"); + EXPECT_EQ(comp1P5M1["SampleResidual"][1].toStdString(), "-10.0"); + EXPECT_EQ(comp1P5M1["SampleSigma"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P5M1["SampleSigma"][1].toStdString(), "0.01"); + comp1P5.deleteGroup("Measure"); + + PvlGroup &comp1P5M2 = comp1P5.findGroup("Measure"); + EXPECT_EQ(comp1P5M2.keywords(), 1); + EXPECT_EQ(comp1P5M2["SerialNumber"][0].toStdString(), "id1"); + EXPECT_EQ(comp1P5M2["SerialNumber"][1].toStdString(), "N/A"); + comp1P5.deleteGroup("Measure"); + + PvlGroup &comp1P5M3 = comp1P5.findGroup("Measure"); + EXPECT_EQ(comp1P5M3.keywords(), 1); + EXPECT_EQ(comp1P5M3["SerialNumber"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P5M3["SerialNumber"][1].toStdString(), "id2"); + comp1P5.deleteGroup("Measure"); + + PvlGroup &comp1P5M4 = comp1P5.findGroup("Measure"); + EXPECT_EQ(comp1P5M4.keywords(), 1); + EXPECT_EQ(comp1P5M4["SerialNumber"][0].toStdString(), "N/A"); + EXPECT_EQ(comp1P5M4["SerialNumber"][1].toStdString(), "id3"); + + // cnet3 vs cnet4 with diffsFile + args = {"from=" + cnetFile1, + "from2=" + cnetFile2, + "to=" + tempDir.path() + "/compareDifferent2.txt", + "diff=" + diffsFile, + "report=full" + }; + + UserInterface ui4(APP_XML, args); + + try { + log = cnetdiff(ui4); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // read back compareDifferent2 output file + Pvl compareDifferent2; + try { + compareDifferent2.read(tempDir.path() + "/compareDifferent2.txt"); + } + catch (IException &e) { + FAIL() << "Unable to open error log pvl file: " << e.what() << std::endl; + } + + PvlObject &DifferencesObject2 = compareDifferent2.findObject("Differences"); + EXPECT_EQ(DifferencesObject2.keywords(), 3); + EXPECT_EQ(DifferencesObject2.objects(), 4); + EXPECT_EQ(DifferencesObject2["Filename"][0].toStdString(), "cnet1.net"); + EXPECT_EQ(DifferencesObject2["Filename"][1].toStdString(), "cnet2.net"); + EXPECT_EQ(DifferencesObject2["Points"][0].toStdString(), "4"); + EXPECT_EQ(DifferencesObject2["Points"][1].toStdString(), "3"); + EXPECT_EQ(DifferencesObject2["TargetName"][0].toStdString(), "Mars"); + EXPECT_EQ(DifferencesObject2["TargetName"][1].toStdString(), "Moon"); + + PvlObject &comp2P1 = DifferencesObject2.findObject("Point"); + EXPECT_EQ(comp2P1.keywords(), 1); + EXPECT_EQ(comp2P1["PointId"][0].toStdString(), "T0001"); + EXPECT_EQ(comp2P1["PointId"][1].toStdString(), "N/A"); + DifferencesObject2.deleteObject("Point"); + + PvlObject &comp2P2 = DifferencesObject2.findObject("Point"); + EXPECT_EQ(comp2P2.keywords(), 1); + EXPECT_EQ(comp2P2["PointId"][0].toStdString(), "N/A"); + EXPECT_EQ(comp2P2["PointId"][1].toStdString(), "T0002"); + DifferencesObject2.deleteObject("Point"); + + PvlObject &comp2P3 = DifferencesObject2.findObject("Point"); + EXPECT_EQ(comp2P3.keywords(), 1); + EXPECT_EQ(comp2P3["PointId"][0].toStdString(), "T0003"); + EXPECT_EQ(comp2P3["PointId"][1].toStdString(), "N/A"); + DifferencesObject2.deleteObject("Point"); + + PvlObject &comp2P4 = DifferencesObject2.findObject("Point"); + EXPECT_EQ(comp2P4.keywords(), 4); + EXPECT_EQ(comp2P4.groups(), 4); + EXPECT_EQ(comp2P4["PointId"][0].toStdString(), "T0004"); + EXPECT_EQ(comp2P4["Measures"][0].toStdString(), "2"); + EXPECT_EQ(comp2P4["Measures"][1].toStdString(), "3"); + EXPECT_EQ(comp2P4["AdjustedY"][0].toStdString(), "734.4311949"); + EXPECT_EQ(comp2P4["AdjustedY"][1].toStdString(), "754.4311949"); + EXPECT_EQ(comp2P4["AdjustedY"][2].toStdString(), "3.0"); + EXPECT_EQ(comp2P4["AprioriXYZSourceFile"][0].toStdString(), "N/A"); + EXPECT_EQ(comp2P4["AprioriXYZSourceFile"][1].toStdString(), "/work1/tsucharski/basemap.cub"); + + PvlGroup &comp2P4M1 = comp2P4.findGroup("Measure"); + EXPECT_EQ(comp2P4M1.keywords(), 4); + EXPECT_EQ(comp2P4M1["SerialNumber"][0].toStdString(), "id0"); + EXPECT_EQ(comp2P4M1["LineResidual"][0].toStdString(), "-4.0"); + EXPECT_EQ(comp2P4M1["LineResidual"][1].toStdString(), "4.0"); + EXPECT_EQ(comp2P4M1["Sample"][0].toStdString(), "4.0"); + EXPECT_EQ(comp2P4M1["Sample"][1].toStdString(), "1.0"); + EXPECT_EQ(comp2P4M1["Sample"][2].toStdString(), "1.0"); + EXPECT_EQ(comp2P4M1["SampleResidual"][0].toStdString(), "1.0"); + EXPECT_EQ(comp2P4M1["SampleResidual"][1].toStdString(), "-10.0"); + EXPECT_EQ(comp2P4M1["SampleResidual"][2].toStdString(), "5.0"); + comp2P4.deleteGroup("Measure"); + + PvlGroup &comp2P4M2 = comp2P4.findGroup("Measure"); + EXPECT_EQ(comp2P4M2.keywords(), 1); + EXPECT_EQ(comp2P4M2["SerialNumber"][0].toStdString(), "id1"); + EXPECT_EQ(comp2P4M2["SerialNumber"][1].toStdString(), "N/A"); + comp2P4.deleteGroup("Measure"); + + PvlGroup &comp2P4M3 = comp2P4.findGroup("Measure"); + EXPECT_EQ(comp2P4M3.keywords(), 1); + EXPECT_EQ(comp2P4M3["SerialNumber"][0].toStdString(), "N/A"); + EXPECT_EQ(comp2P4M3["SerialNumber"][1].toStdString(), "id2"); + comp2P4.deleteGroup("Measure"); + + PvlGroup &comp2P4M4 = comp2P4.findGroup("Measure"); + EXPECT_EQ(comp2P4M4.keywords(), 1); + EXPECT_EQ(comp2P4M4["SerialNumber"][0].toStdString(), "N/A"); + EXPECT_EQ(comp2P4M4["SerialNumber"][1].toStdString(), "id3"); +} -- GitLab