Skip to content

Commit

Permalink
vikcal tests added (#4332)
Browse files Browse the repository at this point in the history
* vikcal tests added

* removed old tests

* addressing comments

* removed coeff comparisons
  • Loading branch information
Kelvin Rodriguez authored Mar 8, 2021
1 parent e00da61 commit 8d591c1
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 13 deletions.
4 changes: 0 additions & 4 deletions isis/src/viking/apps/vikcal/tsts/Makefile

This file was deleted.

9 changes: 0 additions & 9 deletions isis/src/viking/apps/vikcal/tsts/default/Makefile

This file was deleted.

141 changes: 141 additions & 0 deletions isis/src/viking/apps/vikcal/vikcal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/** 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 "SpecialPixel.h"
#include "ProcessByLine.h"
#include "UserInterface.h"
#include "Pvl.h"
#include "CalParameters.h"

#include "vikcal.h"

using namespace std;

namespace Isis {

static void cal(vector<Buffer *> &in,
vector<Buffer *> &out);

static CalParameters *calParam;
static bool linear;

void vikcal(UserInterface &ui) {
const QString in = ui.GetFileName("FROM");

// Open the input cube
Cube icube(in, "r");

vikcal(&icube, ui);
}


void vikcal(Cube *icube, UserInterface &ui) {
// We will be processing by line
ProcessByLine p;

// The linear option can never be true in Isis2, if it is needed, comment out
// the following line, and uncomment the line below it. Also, add the code
// segment found in the CalParameters documentation to the vikcal.xml file
linear = false;

// linear = ui.GetBoolean("LINEAR");
const QString in = icube->fileName();

// Open the input cube
calParam = new CalParameters(in, icube);
Progress prog;

// If the file has already been calibrated, throw an error
if(icube->hasGroup("Radiometry")) {
QString msg = "The Viking image [" + icube->fileName() + "] has already "
"been radiometrically calibrated";
throw IException(IException::User, msg, _FILEINFO_);
}

CubeAttributeInput dcf;
CubeAttributeInput fff;
const QString gainFile = (QString)FileName(calParam->GainFile()).expanded();
const QString offsetFile = (QString)FileName(calParam->OffsetFile()).expanded();

// Setup the input cubes
p.SetInputCube(icube);
p.SetInputCube(offsetFile, dcf);
p.SetInputCube(gainFile, fff);

// Setup the output cube
Cube *ocube = p.SetOutputCubeStretch("TO", &ui);

// Set up and add the radiometry group to the output cube label
PvlGroup calgrp("Radiometry");

calgrp.addComment("Calibration equation in vikcal");
calgrp.addComment("DI(l,s) = (1.0/(exp*w1))*G(l,s)*(gain*DR(l,s)+DC(l,s)+offt+offc)");
calgrp.addComment("with w1 = w0*((dist0*dist0) / (dist1*dist1))");
calgrp.addComment("and offt(l,s) = A*l + B*l*l + C*s + D*l*s + E");
calgrp += PvlKeyword("offc", toString(calParam->Offset()));
calgrp += PvlKeyword("exp", toString(calParam->Exposure()));
calgrp += PvlKeyword("gain", toString(calParam->Gain()));
calgrp += PvlKeyword("DR", in);
calgrp += PvlKeyword("DC", calParam->OffsetFile());
calgrp += PvlKeyword("G", calParam->GainFile());

calgrp += PvlKeyword("w0", toString(calParam->Omega0()));
calgrp += PvlKeyword("w1", toString(calParam->Omega1()));
calgrp += PvlKeyword("dist0", toString(calParam->Distance()));
calgrp += PvlKeyword("dist1", toString(calParam->Dist1()));
calgrp += PvlKeyword("1.0/exp*w1", toString(1.0 / (calParam->Exposure() * calParam->Omega1())));

calgrp += PvlKeyword("Acoeff", toString(calParam->Acoeff()));
calgrp += PvlKeyword("Bcoeff", toString(calParam->Bcoeff()));
calgrp += PvlKeyword("Ccoeff", toString(calParam->Ccoeff()));
calgrp += PvlKeyword("Dcoeff", toString(calParam->Dcoeff()));
calgrp += PvlKeyword("Ecoeff", toString(calParam->Ecoeff()));

ocube->putGroup(calgrp);

// Start the calibration process
p.StartProcess(cal);
p.EndProcess();
}

void cal(vector<Buffer *> &in, vector<Buffer *> &out) {

Buffer &inp = *in[0]; // Input Cube
Buffer &dcf = *in[1]; // Dark Current File
Buffer &fff = *in[2]; // Flat Field File
Buffer &outp = *out[0]; // Output Cube

// Loop for each pixel in the line.
for(int i = 0; i < inp.size(); i++) {
if(IsSpecial(inp[i])) {
outp[i] = inp[i];
}
else if(IsSpecial(fff[i]) || IsSpecial(dcf[i])) {
outp[i] = Isis::Null;
}
else {
double offc = calParam->TimeBasedOffset(inp.Line(), i + 1);
double dnraw = (inp[i] * calParam->Gain()) + dcf[i] + offc;

// The linear option can never be true in isis2, and therefore, this
// section of the code has not been tested.
if(linear == true) {
double temp = (dnraw / calParam->NormalizingPower());
for(int i = 1; i < calParam->LinearityPower(); i++) {
temp *= (dnraw / calParam->NormalizingPower());
}
dnraw = calParam->Acoeff() * dnraw + calParam->Bcoeff() * temp;
}

double xmlt = 1.0 / (calParam->Exposure() * calParam->Omega1());
outp[i] = xmlt * fff[i] * dnraw;
}
}

}
}
12 changes: 12 additions & 0 deletions isis/src/viking/apps/vikcal/vikcal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef vikcal_h // Change this to your app name in all lower case suffixed with _h (e.g. campt_h, cam2map_h etc.)
#define vikcal_h

#include "Cube.h"
#include "UserInterface.h"

namespace Isis{
extern void vikcal(Cube *cube, UserInterface &ui);
extern void vikcal(UserInterface &ui);
}

#endif
90 changes: 90 additions & 0 deletions isis/tests/FunctionalTestsVikcal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "Fixtures.h"
#include "Pvl.h"
#include "PvlGroup.h"
#include "TestUtilities.h"
#include "Histogram.h"

#include "vikcal.h"

#include "gtest/gtest.h"

using namespace Isis;

static QString APP_XML = FileName("$ISISROOT/bin/xml/vikcal.xml").expanded();

TEST_F(DefaultCube, FunctionalTestVikcalDefault) {
// Note: DefaultCube is a viking image

QString outCubeFileName = tempDir.path() + "/outTemp.cub";
QVector<QString> args = {"to="+outCubeFileName};

UserInterface options(APP_XML, args);
try {
vikcal(testCube, options);
}
catch (IException &e) {
FAIL() << "Unable to open image: " << e.what() << std::endl;
}

Cube oCube(outCubeFileName, "r");

PvlGroup radGroup = oCube.label()->findObject("IsisCube").findGroup("Radiometry");

EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("offc"), 0);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("exp"), 7.73);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("gain"), 1.0);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("w0"), 90.36);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("w1"), 119.84873964656);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("dist0"), 243840000.0);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("dist1"), 211727039.58284);
EXPECT_DOUBLE_EQ((double)radGroup.findKeyword("1.0/exp*w1"), 0.0010794114853583);

Histogram *oCubeStats = oCube.histogram();

EXPECT_DOUBLE_EQ(oCubeStats->Average(), 0.14601107854966053);
EXPECT_DOUBLE_EQ(oCubeStats->Sum(), 184914.12430735352);
EXPECT_DOUBLE_EQ(oCubeStats->ValidPixels(), 1266439);
EXPECT_DOUBLE_EQ(oCubeStats->StandardDeviation(), 0.07892281197170499);
}


TEST_F(DefaultCube, FunctionalTestCtxcalCameraComparison) {
// Note: DefaultCube is a viking image

QString outCubeFileNameCam = tempDir.path() + "/outTemp.cub";
QVector<QString> args = {"to="+outCubeFileNameCam};

UserInterface options(APP_XML, args);

try {
vikcal(testCube, options);
}
catch (IException &e) {
FAIL() << "Unable to open image: " << e.what() << std::endl;
}

// force camera to not construct
Pvl *lab = testCube->label();
lab->deleteObject("NaifKeywords");

QString outCubeFileNameNoCam = tempDir.path() + "/outTempNoCam.cub";
args = {"to="+outCubeFileNameNoCam};

try {
vikcal(testCube, options);
}
catch (IException &e) {
FAIL() << "Unable to open image: " << e.what() << std::endl;
}

Cube oNoCamCube(outCubeFileNameCam, "r");
Cube oCamCube(outCubeFileNameCam, "r");

Pvl *noCamLab = oNoCamCube.label();
Pvl *camLab = oCamCube.label();

EXPECT_DOUBLE_EQ((double)noCamLab->findObject("IsisCube").findGroup("Radiometry").findKeyword("dist1"),
(double)camLab->findObject("IsisCube").findGroup("Radiometry").findKeyword("dist1"));

EXPECT_DOUBLE_EQ((double)noCamLab->findObject("IsisCube").findGroup("Radiometry").findKeyword("dist1"), 211727039.58284);
}

0 comments on commit 8d591c1

Please sign in to comment.