Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heldimage + MEstimation tests for jigsaw #4099

Merged
merged 15 commits into from
Nov 2, 2020
4 changes: 2 additions & 2 deletions isis/tests/Fixtures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,9 @@ namespace Isis {
cubeListFile = tempDir.path() + "/cubes.lis";
cubeList->write(cubeListFile);

ControlNet inputNet("data/apolloNetwork/apolloNet.pvl");
network = new ControlNet("data/apolloNetwork/apolloNet.pvl");
controlNetPath = tempDir.path() + "/apolloNet.net";
inputNet.Write(controlNetPath);
network->Write(controlNetPath);
}

void ApolloNetwork::TearDown() {
Expand Down
32 changes: 17 additions & 15 deletions isis/tests/Fixtures.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,7 @@ namespace Isis {
void SetUp() override;
void TearDown() override;
};

class ApolloNetwork: public TempTestingFiles {
protected:
Cube *cube1, *cube2, *cube3, *cube4, *cube5, *cube6, *cube7;
FileName *isdFile1, *isdFile2, *isdFile3, *isdFile4, *isdFile5, *isdFile6, *isdFile7,
*cubeLabel, *label1, *label2, *label3, *label4, *label5, *label6, *label7;

FileList *cubeList;
QString cubeListFile;
QString controlNetPath;

void SetUp() override;
void TearDown() override;
};


class ObservationPair : public TempTestingFiles {
protected:

Expand All @@ -152,6 +138,22 @@ namespace Isis {

ControlNet *network;
QString cnetPath;

void SetUp() override;
void TearDown() override;
};

class ApolloNetwork: public TempTestingFiles {
protected:
Cube *cube1, *cube2, *cube3, *cube4, *cube5, *cube6, *cube7;
FileName *isdFile1, *isdFile2, *isdFile3, *isdFile4, *isdFile5, *isdFile6, *isdFile7,
*cubeLabel, *label1, *label2, *label3, *label4, *label5, *label6, *label7;

FileList *cubeList;
QString cubeListFile;

ControlNet *network;
QString controlNetPath;

void SetUp() override;
void TearDown() override;
Expand Down
167 changes: 144 additions & 23 deletions isis/tests/FunctionalTestsJigsaw.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
#include <iostream>
#include <QtMath>

#include <QFile>
#include <QHash>
#include <QSet>
#include <QString>
#include <QStringList>
#include <QTextStream>

#include "jigsaw.h"
#include "Angle.h"
#include "ControlNet.h"
#include "ControlPoint.h"
#include "ControlMeasure.h"
#include "Distance.h"
#include "FileName.h"
#include "Latitude.h"
#include "Longitude.h"
#include "SurfacePoint.h"
#include "gmock/gmock.h"
#include "UserInterface.h"
#include "CSVReader.h"
#include "Pvl.h"
#include "PvlGroup.h"
#include "Statistics.h"
#include "CSVReader.h"
#include "Latitude.h"
#include "Longitude.h"
#include "ControlPoint.h"

#include "jigsaw.h"

Expand Down Expand Up @@ -211,7 +197,7 @@ TEST_F(ApolloNetwork, FunctionalTestJigsawApollo) {

for (int i=0; i < inputPoints.length(); i++) {
ControlPoint* inputPoint = inputPoints[i];
ControlPoint* outputPoint;
ControlPoint* outputPoint = nullptr;
EXPECT_NO_THROW({
outputPoint = outputNet.GetPoint(inputPoint->GetId());
}
Expand Down Expand Up @@ -354,16 +340,151 @@ TEST_F(ObservationPair, FunctionalTestJigsawCamSolveAll) {
EXPECT_NEAR(elems.at(56).toDouble(), 0.365717165, 0.00001);
}

TEST_F(ObservationPair, FunctionalTestJigsawErrorNoSolve) {

TEST_F(ApolloNetwork, FunctionalTestJigsawHeldList) {
QTemporaryDir prefix;

QString heldlistpath = prefix.path() + "/heldlist.lis";
FileList heldList;
heldList.append(cube6->fileName());
heldList.write(heldlistpath);

QString outCnetFileName = prefix.path() + "/outTemp.net";
QVector<QString> args = {"fromlist="+cubeListFile, "cnet="+cnetPath, "onet="+outCnetFileName,
"camsolve=None", "spsolve=None"};
QVector<QString> args = {"fromlist="+cubeListFile, "cnet="+controlNetPath, "onet="+outCnetFileName, "heldlist="+heldlistpath,
"radius=yes", "errorpropagation=yes", "spsolve=position", "Spacecraft_position_sigma=1000",
"Residuals_csv=off", "Camsolve=angles", "Twist=yes", "Camera_angles_sigma=2",
"Output_csv=off", "imagescsv=on", "file_prefix="+prefix.path()+"/"};

UserInterface options(APP_XML, args);

Pvl log;

try {
jigsaw(options, &log);
}
catch (IException &e) {
FAIL() << "Unable to bundle: " << e.what() << std::endl;
}

CSVReader::CSVAxis csvLine;
CSVReader header = CSVReader(prefix.path()+"/bundleout_images.csv",
false, 0, ',', false, true);

csvLine = header.getRow(7);

// assert corrections are very small
// X Correction
EXPECT_LE(std::abs(csvLine[5].toDouble()), 1e-10);
// Y Correction
EXPECT_LE(std::abs(csvLine[10].toDouble()), 1e-10);
// Z Correction
EXPECT_LE(std::abs(csvLine[15].toDouble()), 1e-10);
// RA Correction
EXPECT_LE(std::abs(csvLine[20].toDouble()), 1e-10);
// DEC Correction
EXPECT_LE(std::abs(csvLine[25].toDouble()), 1e-10);
// TWIST Correction
EXPECT_LE(std::abs(csvLine[30].toDouble()), 1e-10);
}


TEST_F(ApolloNetwork, FunctionalTestJigsawMEstimator) {
QTemporaryDir prefix;
QString newNetworkPath = prefix.path()+"/badMeasures.net";

QVector<QString> pid = {"AS15_000031985",
"AS15_000033079",
"AS15_SocetPAN_03",
"AS15_Tie03"};

QVector<QString> mid = {"APOLLO15/METRIC/1971-07-31T14:01:40.346",
"APOLLO15/METRIC/1971-07-31T14:02:27.179",
"APOLLO15/METRIC/1971-07-31T14:02:03.751",
"APOLLO15/METRIC/1971-07-31T14:00:53.547"};

for (int i = 0; i < pid.size(); i++) {
// grab random points and add error to a single measure
ControlPoint *point = network->GetPoint(pid[i]);
ControlMeasure *measure = point->GetMeasure(mid[i]);
measure->SetCoordinate(measure->GetLine()+50, measure->GetLine()+50);
}

network->Write(newNetworkPath);

QString outCnetFileName = prefix.path() + "/outTemp.net";
QVector<QString> args = {"fromlist="+cubeListFile, "cnet="+newNetworkPath, "onet="+outCnetFileName,
"Radius=yes", "Errorpropagation=yes", "Spsolve=position","Spacecraft_position_sigma=1000.0",
"Camsolve=angles", "twist=yes", "Camera_angles_sigma=2",
"Model1=huber", "Max_model1_c_quantile=0.6", "Model2=chen", "Max_model2_c_quantile=0.98", "Sigma0=1e-3",
"bundleout_txt=yes", "Output_csv=on", "imagescsv=on", "file_prefix="+prefix.path()+"/"};

UserInterface options(APP_XML, args);

Pvl log;
try {
jigsaw(options, &log);
}
catch (IException &e) {
FAIL() << "Unable to bundle: " << e.what() << std::endl;
}

CSVReader::CSVAxis csvLine;
CSVReader header = CSVReader(prefix.path()+"/bundleout_images.csv",
false, 0, ',', false, true);

ControlNet onet;
onet.ReadControl(outCnetFileName);

QVector<double> presiduals = {};
QVector<QVector<double>> mresiduals = {{1.27975, 1.54281, 1.8778, 1.30159},
{2.25115, 2.33559, 0.547574, 3.16777},
{1.15396, 0.69243, 1.03005, 0.848934},
{2.24641, 4.39168, 0.560941, 2.844}};

for (int i = 0; i < pid.size(); i++) {
ControlPoint *point = network->GetPoint(pid[i]);
QList<ControlMeasure*> measures = point->getMeasures();
for (int j = 0; j < measures.size(); j++ ) {
EXPECT_NEAR(measures.at(j)->GetResidualMagnitude(), mresiduals[i][j], 0.0001);
}
}

QFile bo(prefix.path()+"/bundleout.txt");
QString contents;
if (bo.open(QIODevice::ReadOnly)) {
contents = bo.read(bo.size());
}
else {
FAIL() << "Failed to open bundleout.txt" << std::endl;
}

QStringList lines = contents.split("\n");

EXPECT_THAT(lines[31].toStdString(), HasSubstr("Tier 0 Enabled: TRUE"));
EXPECT_THAT(lines[32].toStdString(), HasSubstr("Maximum Likelihood Model: Huber"));
EXPECT_THAT(lines[33].toStdString(), HasSubstr("Quantile used for tweaking constant: 0.6"));
EXPECT_THAT(lines[34].toStdString(), HasSubstr("Quantile weighted R^2 Residual value: 0.207"));
EXPECT_THAT(lines[35].toStdString(), HasSubstr("Approx. weighted Residual cutoff: N/A"));

EXPECT_THAT(lines[37].toStdString(), HasSubstr("Tier 1 Enabled: TRUE"));
EXPECT_THAT(lines[38].toStdString(), HasSubstr("Maximum Likelihood Model: Chen"));
EXPECT_THAT(lines[39].toStdString(), HasSubstr("Quantile used for tweaking constant: 0.98"));
EXPECT_THAT(lines[40].toStdString(), HasSubstr("Quantile weighted R^2 Residual value: 1.0"));
EXPECT_THAT(lines[41].toStdString(), HasSubstr("Approx. weighted Residual cutoff: 1.0"));

EXPECT_THAT(lines[43].toStdString(), HasSubstr(" Tier 2 Enabled: FALSE"));
}


TEST_F(ObservationPair, FunctionalTestJigsawErrorNoSolve) {
QTemporaryDir prefix;
QString outCnetFileName = prefix.path() + "/outTemp.net";
QVector<QString> args = {"fromlist="+cubeListFile, "cnet="+cnetPath, "onet="+outCnetFileName,
"camsolve=None", "spsolve=None"};

UserInterface options(APP_XML, args);
Pvl log;

try {
jigsaw(options, &log);
FAIL() << "Should throw" << std::endl;
Expand Down