Unverified Commit 8d591c18 authored by Kelvin Rodriguez's avatar Kelvin Rodriguez Committed by GitHub
Browse files

vikcal tests added (#4332)

* vikcal tests added

* removed old tests

* addressing comments

* removed coeff comparisons
parent e00da61f
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
BLANKS = "%-6s"    
LENGTH = "%-40s"

include $(ISISROOT)/make/isismake.tststree
+0 −9
Original line number Diff line number Diff line
APPNAME = vikcal

include $(ISISROOT)/make/isismake.tsts

commands:
	$(APPNAME) from=$(INPUT)/f387a06.cub \
	  to=$(OUTPUT)/vikcalTruth.cub > /dev/null;
	$(APPNAME) from=$(INPUT)/f319b18.cub \
	  to=$(OUTPUT)/vikcalCameraTruth.cub > /dev/null;
+141 −0
Original line number Diff line number Diff line
/** 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;
      }
    }
  
  }
}
 No newline at end of file
+12 −0
Original line number Diff line number Diff line
#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
 No newline at end of file
+90 −0
Original line number Diff line number Diff line
#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);
}
 No newline at end of file