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

Lronac2isis tests added (#4141)

* added new files

* added lronac2isis tests

* added data (important)

* static funcs
parent 9a7985de
Loading
Loading
Loading
Loading
+236 −0
Original line number Diff line number Diff line
#include "ProcessImportPds.h"
#include "UserInterface.h"
#include "FileName.h"
#include "IException.h"
#include "IString.h"
#include "Pvl.h"
#include "OriginalLabel.h"
#include "History.h"
#include "LineManager.h"
#include "Application.h"

#include <vector>

#include "lronac2isis.h"

#define MAX_INPUT_VALUE 4095

using namespace std;

namespace Isis {

  static void ResetGlobals();
  static void Import(Buffer &buf);
  static void TranslateLrocNacLabels(FileName &labelFile, Cube *ocube);
  
  // Global variables for processing functions
  Cube *g_ocube;
  std::vector< double> g_xterm, g_bterm, g_mterm;
  bool g_flip = false;
  
  void lronac2isis(UserInterface &ui) {
    // Initialize variables
    ResetGlobals();
    //Check that the file comes from the right camera
    FileName inFile = ui.GetFileName("FROM");
    QString id;
    try {
      Pvl lab(inFile.expanded());
      if(lab.hasKeyword("DATA_SET_ID"))
        id = (QString) lab.findKeyword("DATA_SET_ID");
      else {
        QString msg = "Unable to read [DATA_SET_ID] from input file [" + inFile.expanded() + "]";
        throw IException(IException::Unknown, msg, _FILEINFO_);
      }
      //Checks if in file is rdr
      bool projected = lab.hasObject("IMAGE_MAP_PROJECTION");
      if(projected) {
        QString msg = "[" + inFile.name() + "] appears to be an rdr file.";
        msg += " Use pds2isis.";
        throw IException(IException::User, msg, _FILEINFO_);
      }
      
      // Store the decompanding information
      PvlKeyword xtermKeyword = lab.findKeyword("LRO:XTERM"),
                 mtermKeyword = lab.findKeyword("LRO:MTERM"),
                 btermKeyword = lab.findKeyword("LRO:BTERM");

      if(mtermKeyword.size() != xtermKeyword.size() || btermKeyword.size() != xtermKeyword.size()) {
        QString msg = "The decompanding terms do not have the same dimensions";
        throw IException(IException::Io, msg, _FILEINFO_);
      }
      
      for(int i = 0; i < xtermKeyword.size(); i++) {
        g_xterm.push_back(toDouble(xtermKeyword[i]));
        g_mterm.push_back(toDouble(mtermKeyword[i]));
        g_bterm.push_back(toDouble(btermKeyword[i]));
      }
  
      double versionId = toDouble(lab.findKeyword("PRODUCT_VERSION_ID")[0].remove(QRegExp("^v")));
      if(lab.findKeyword("FRAME_ID")[0] == "RIGHT" && versionId < 1.30)
        g_flip = true;
      else
        g_flip = false;
    }
    catch(IException &e) {
      QString msg = "The PDS header is missing important keyword(s).";
      IException finalException(IException::Io, msg, _FILEINFO_);
      finalException.append(e);
      throw finalException;
    }
  
    id = id.simplified().trimmed();
    if(id.mid(13, 3) != "EDR") {
      QString msg = "Input file [" + inFile.expanded() + "] does not appear to be "
                   + "in LROC-NAC EDR format. DATA_SET_ID is [" + id + "]";
      throw IException(IException::Io, msg, _FILEINFO_);
    }
  
    //Process the file
    Pvl pdsLab;
    ProcessImportPds p;
    p.SetPdsFile(inFile.expanded(), "", pdsLab);
    // Set the output bit type to Real
    CubeAttributeOutput &outAtt = ui.GetOutputAttribute("TO");
  
    g_ocube = new Cube();
    g_ocube->setByteOrder(outAtt.byteOrder());
    g_ocube->setFormat(outAtt.fileFormat());
    g_ocube->setMinMax((double) VALID_MIN2, (double) VALID_MAX2);
    g_ocube->setLabelsAttached(outAtt.labelAttachment() == AttachedLabel);
    g_ocube->setDimensions(p.Samples(), p.Lines(), p.Bands());
    g_ocube->setPixelType(Isis::Real);
    g_ocube->create(ui.GetFileName("TO"));
    // Do 8 bit to 12 bit conversion
    // And if NAC-R, flip the frame
    p.StartProcess(Import);
  
    // Then translate the labels
    TranslateLrocNacLabels(inFile, g_ocube);
    p.EndProcess();

    // Add History
    if (iApp) { 
        History history("IsisCube");
        history.AddEntry();
        g_ocube->write(history);
    }

    // Add original label
    OriginalLabel origLabel(pdsLab);
    g_ocube->write(origLabel);
    g_ocube->close();
    delete g_ocube;
  }
  
  // The input buffer has a raw 16 bit buffer but the values are still 0 to 255.
  // See "Appendix B - NAC and WAC Companding Schemes" of the LROC_SOC_SPEC
  // document for reference.
  void Import(Buffer &in) {
    LineManager outLines(*g_ocube);
    outLines.SetLine(in.Line(), in.Band());
    Buffer buf(in.SampleDimension(), in.LineDimension(), in.BandDimension(),
               g_ocube->pixelType());
  
    // Do the decompanding
    for(int pixin = 0; pixin < in.size(); pixin++) {
  
      // if pixin < xtermo0, then it is in "segment 0"
      if(in[pixin] < g_xterm[0])
        buf[pixin] = (int) in[pixin];
  
      // otherwise, it is in segments 1 to 5
      else {
        unsigned int segment = 1;
        while(segment < g_xterm.size() && (in[pixin] - g_bterm[segment - 1]) / g_mterm[segment - 1] >= g_xterm[segment])
          segment++;
  
        // Compute the upper and lower bin values
        double upper = (in[pixin] + 1 - g_bterm[segment - 1]) / g_mterm[segment - 1] - 1;
        double lower = (in[pixin] - g_bterm[segment - 1]) / g_mterm[segment - 1];
  
        // Check if the bin is on the upper boundary of the last segment
        if(upper > MAX_INPUT_VALUE)
          upper = MAX_INPUT_VALUE;
        else if(segment < g_xterm.size() && upper >= g_xterm[segment]) {
          if((int)(g_bterm[segment] + g_mterm[segment]*upper) != in[pixin])
            upper = g_xterm[segment] - 1;
        }
  
        // Check if it is on the lower boundary of a segment
        if(lower < g_xterm[segment-1])
          lower = g_xterm[segment-1];
  
        // Output the middle bin value
        buf[pixin] = (upper + lower) / 2.0;
  
      }
    }
  
    // flip the NAC-R frame
    if(g_flip) {
      Buffer tmpbuf(buf);
      for(int i = 0; i < buf.size(); i++)
        buf[i] = tmpbuf[buf.size() - i - 1];
    }
    outLines.Copy(buf);
    g_ocube->write(outLines);
  }
  
  //Function to translate the labels
  void TranslateLrocNacLabels(FileName &labelFile, Cube *ocube) {
  
    //Pvl to store the labels
    Pvl outLabel;
    //Set up the directory where the translations are
    Pvl labelPvl(labelFile.expanded());
  
    //Translate the Instrument group
    FileName transFile("$ISISROOT/appdata/translations/LroNacInstrument.trn");
    PvlToPvlTranslationManager instrumentXlator(labelPvl, transFile.expanded());
    instrumentXlator.Auto(outLabel);
  
    //Translate the Archive group
    transFile = "$ISISROOT/appdata/translations/LroNacArchive.trn";
    PvlToPvlTranslationManager archiveXlater(labelPvl, transFile.expanded());
    archiveXlater.Auto(outLabel);
  
    //Translate the BandBin group
    transFile = "$ISISROOT/appdata/translations/LroNacBandBin.trn";
    PvlToPvlTranslationManager bandBinXlater(labelPvl, transFile.expanded());
    bandBinXlater.Auto(outLabel);
  
    Pvl lab(labelFile.expanded());
  
    //Set up the Kernels group
    PvlGroup kern("Kernels");
    if(lab.findKeyword("FRAME_ID")[0] == "LEFT")
      kern += PvlKeyword("NaifFrameCode", "-85600");
    else
      kern += PvlKeyword("NaifFrameCode", "-85610");
  
    PvlGroup inst = outLabel.findGroup("Instrument", Pvl::Traverse);
    if(lab.findKeyword("FRAME_ID")[0] == "LEFT") {
      inst.findKeyword("InstrumentId") = "NACL";
      inst.findKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA LEFT";
    }
    else {
      inst.findKeyword("InstrumentId") = "NACR";
      inst.findKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA RIGHT";
    }
  
    //Add all groups to the output cube
    ocube->putGroup(inst);
    ocube->putGroup(outLabel.findGroup("Archive", Pvl::Traverse));
    ocube->putGroup(outLabel.findGroup("BandBin", Pvl::Traverse));
    ocube->putGroup(kern);
  }
  
  void ResetGlobals() {
    g_ocube = NULL;
    g_xterm.clear();
    g_mterm.clear();
    g_bterm.clear();
    g_flip = false;
  }
}
+12 −0
Original line number Diff line number Diff line
#ifndef lronac2isis_h // Change this to your app name in all lower case suffixed with _h (e.g. campt_h, cam2map_h etc.)
#define lronac2isis_h

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

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

#endif
 No newline at end of file
+4 −230
Original line number Diff line number Diff line
#include "Isis.h"
#include "ProcessImportPds.h"
#include "UserInterface.h"
#include "FileName.h"
#include "IException.h"
#include "IString.h"
#include "Pvl.h"
#include "OriginalLabel.h"
#include "History.h"
#include "LineManager.h"
#include <vector>

#define MAX_INPUT_VALUE 4095
#include "Application.h"
#include "lronac2isis.h"

using namespace std;
using namespace Isis;

void ResetGlobals();
void Import(Buffer &buf);
void TranslateLrocNacLabels(FileName &labelFile, Cube *ocube);

// Global variables for processing functions
Cube *g_ocube;
std::vector< double> g_xterm, g_bterm, g_mterm;
bool g_flip = false;

void IsisMain() {
  // Initialize variables
  ResetGlobals();

  //Check that the file comes from the right camera
  UserInterface &ui = Application::GetUserInterface();
  FileName inFile = ui.GetFileName("FROM");
  QString id;
  try {
    Pvl lab(inFile.expanded());

    if(lab.hasKeyword("DATA_SET_ID"))
      id = (QString) lab.findKeyword("DATA_SET_ID");
    else {
      QString msg = "Unable to read [DATA_SET_ID] from input file [" + inFile.expanded() + "]";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }

    //Checks if in file is rdr
    bool projected = lab.hasObject("IMAGE_MAP_PROJECTION");
    if(projected) {
      QString msg = "[" + inFile.name() + "] appears to be an rdr file.";
      msg += " Use pds2isis.";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    // Store the decompanding information
    PvlKeyword xtermKeyword = lab.findKeyword("LRO:XTERM"),
               mtermKeyword = lab.findKeyword("LRO:MTERM"),
               btermKeyword = lab.findKeyword("LRO:BTERM");

    if(mtermKeyword.size() != xtermKeyword.size() || btermKeyword.size() != xtermKeyword.size()) {
      QString msg = "The decompanding terms do not have the same dimensions";
      throw IException(IException::Io, msg, _FILEINFO_);
    }

    for(int i = 0; i < xtermKeyword.size(); i++) {
      g_xterm.push_back(toDouble(xtermKeyword[i]));
      g_mterm.push_back(toDouble(mtermKeyword[i]));
      g_bterm.push_back(toDouble(btermKeyword[i]));
    }

    double versionId = toDouble(lab.findKeyword("PRODUCT_VERSION_ID")[0].remove(QRegExp("^v")));

    if(lab.findKeyword("FRAME_ID")[0] == "RIGHT" && versionId < 1.30)
      g_flip = true;
    else
      g_flip = false;
  }
  catch(IException &e) {
    QString msg = "The PDS header is missing important keyword(s).";
    IException finalException(IException::Io, msg, _FILEINFO_);
    finalException.append(e);
    throw finalException;
  }

  id = id.simplified().trimmed();
  if(id.mid(13, 3) != "EDR") {
    QString msg = "Input file [" + inFile.expanded() + "] does not appear to be "
                 + "in LROC-NAC EDR format. DATA_SET_ID is [" + id + "]";
    throw IException(IException::Io, msg, _FILEINFO_);
  }

  //Process the file
  Pvl pdsLab;
  ProcessImportPds p;
  p.SetPdsFile(inFile.expanded(), "", pdsLab);

  // Set the output bit type to Real
  CubeAttributeOutput &outAtt = ui.GetOutputAttribute("TO");

  g_ocube = new Cube();
  g_ocube->setByteOrder(outAtt.byteOrder());
  g_ocube->setFormat(outAtt.fileFormat());
  g_ocube->setMinMax((double) VALID_MIN2, (double) VALID_MAX2);
  g_ocube->setLabelsAttached(outAtt.labelAttachment() == AttachedLabel);
  g_ocube->setDimensions(p.Samples(), p.Lines(), p.Bands());
  g_ocube->setPixelType(Isis::Real);
  g_ocube->create(ui.GetFileName("TO"));

  // Do 8 bit to 12 bit conversion
  // And if NAC-R, flip the frame
  p.StartProcess(Import);

  // Then translate the labels
  TranslateLrocNacLabels(inFile, g_ocube);
  p.EndProcess();

  // Add History
  History history("IsisCube");
  history.AddEntry();
  g_ocube->write(history);

  // Add original label
  OriginalLabel origLabel(pdsLab);
  g_ocube->write(origLabel);

  g_ocube->close();
  delete g_ocube;
}

// The input buffer has a raw 16 bit buffer but the values are still 0 to 255.
// See "Appendix B - NAC and WAC Companding Schemes" of the LROC_SOC_SPEC
// document for reference.
void Import(Buffer &in) {
  LineManager outLines(*g_ocube);
  outLines.SetLine(in.Line(), in.Band());
  Buffer buf(in.SampleDimension(), in.LineDimension(), in.BandDimension(),
             g_ocube->pixelType());

  // Do the decompanding
  for(int pixin = 0; pixin < in.size(); pixin++) {

    // if pixin < xtermo0, then it is in "segment 0"
    if(in[pixin] < g_xterm[0])
      buf[pixin] = (int) in[pixin];

    // otherwise, it is in segments 1 to 5
    else {
      unsigned int segment = 1;
      while(segment < g_xterm.size() && (in[pixin] - g_bterm[segment - 1]) / g_mterm[segment - 1] >= g_xterm[segment])
        segment++;

      // Compute the upper and lower bin values
      double upper = (in[pixin] + 1 - g_bterm[segment - 1]) / g_mterm[segment - 1] - 1;
      double lower = (in[pixin] - g_bterm[segment - 1]) / g_mterm[segment - 1];

      // Check if the bin is on the upper boundary of the last segment
      if(upper > MAX_INPUT_VALUE)
        upper = MAX_INPUT_VALUE;
      else if(segment < g_xterm.size() && upper >= g_xterm[segment]) {
        if((int)(g_bterm[segment] + g_mterm[segment]*upper) != in[pixin])
          upper = g_xterm[segment] - 1;
      }

      // Check if it is on the lower boundary of a segment
      if(lower < g_xterm[segment-1])
        lower = g_xterm[segment-1];

      // Output the middle bin value
      buf[pixin] = (upper + lower) / 2.0;

    }
  }

  // flip the NAC-R frame
  if(g_flip) {
    Buffer tmpbuf(buf);
    for(int i = 0; i < buf.size(); i++)
      buf[i] = tmpbuf[buf.size() - i - 1];
  }
  outLines.Copy(buf);
  g_ocube->write(outLines);
}

//Function to translate the labels
void TranslateLrocNacLabels(FileName &labelFile, Cube *ocube) {

  //Pvl to store the labels
  Pvl outLabel;
  //Set up the directory where the translations are
  Pvl labelPvl(labelFile.expanded());

  //Translate the Instrument group
  FileName transFile("$ISISROOT/appdata/translations/LroNacInstrument.trn");
  PvlToPvlTranslationManager instrumentXlator(labelPvl, transFile.expanded());
  instrumentXlator.Auto(outLabel);

  //Translate the Archive group
  transFile = "$ISISROOT/appdata/translations/LroNacArchive.trn";
  PvlToPvlTranslationManager archiveXlater(labelPvl, transFile.expanded());
  archiveXlater.Auto(outLabel);

  //Translate the BandBin group
  transFile = "$ISISROOT/appdata/translations/LroNacBandBin.trn";
  PvlToPvlTranslationManager bandBinXlater(labelPvl, transFile.expanded());
  bandBinXlater.Auto(outLabel);

  Pvl lab(labelFile.expanded());

  //Set up the Kernels group
  PvlGroup kern("Kernels");
  if(lab.findKeyword("FRAME_ID")[0] == "LEFT")
    kern += PvlKeyword("NaifFrameCode", "-85600");
  else
    kern += PvlKeyword("NaifFrameCode", "-85610");

  PvlGroup inst = outLabel.findGroup("Instrument", Pvl::Traverse);
  if(lab.findKeyword("FRAME_ID")[0] == "LEFT") {
    inst.findKeyword("InstrumentId") = "NACL";
    inst.findKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA LEFT";
  }
  else {
    inst.findKeyword("InstrumentId") = "NACR";
    inst.findKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA RIGHT";
  }

  //Add all groups to the output cube
  ocube->putGroup(inst);
  ocube->putGroup(outLabel.findGroup("Archive", Pvl::Traverse));
  ocube->putGroup(outLabel.findGroup("BandBin", Pvl::Traverse));
  ocube->putGroup(kern);
}

void ResetGlobals() {
  g_ocube = NULL;
  g_xterm.clear();
  g_mterm.clear();
  g_bterm.clear();
  g_flip = false;
  lronac2isis(ui);
}
 No newline at end of file
+0 −4
Original line number Diff line number Diff line
BLANKS = "%-6s"    
LENGTH = "%-40s"

include $(ISISROOT)/make/isismake.tststree
+0 −12
Original line number Diff line number Diff line
APPNAME = lronac2isis
FILE=nacl00015d79Edit

include $(ISISROOT)/make/isismake.tsts

commands:
#    TEST A: Check that lronac2isis is returning the correct error messages
	if [ `$(APPNAME) from=$(INPUT)/$(FILE).img \
	  to=$(OUTPUT)/$(FILE).cub > /dev/null \
	  2>> $(OUTPUT)/error_message_temp.txt > /dev/null` ]; \
	  then true; \
	fi;
 No newline at end of file
Loading