Commit 47fb9e5a authored by Ian Humphrey's avatar Ian Humphrey
Browse files

fx's camera operators now work properly for band-dependent images. Fixes #1301.

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@7164 41f8697f-d340-4b68-9986-7bafba869bb8
parent 154a16b0
Loading
Loading
Loading
Loading
+31 −14
Original line number Diff line number Diff line
@@ -22,16 +22,13 @@

#include "Isis.h"

#include <string>

#include "IString.h"
#include "Camera.h"
#include "CubeCalculator.h"
#include "CubeInfixToPostfix.h"
#include "FileList.h"
#include "FileName.h"
#include "ProcessByLine.h"


using namespace std;
using namespace Isis;

@@ -45,14 +42,30 @@ void IsisMain() {
  ProcessByLine p;
  QVector<Cube *> cubes;
  Cube *outCube;
  Cube *inCube;
  int bands = 1;

  if (ui.GetString("MODE") == "CUBES") {
    // Require atleast one file to be specified
    cubes.push_back(p.SetInputCube("F1", Isis::AllMatchOrOne));
    if (ui.WasEntered("F2")) cubes.push_back(p.SetInputCube("F2", Isis::AllMatchOrOne));
    if (ui.WasEntered("F3")) cubes.push_back(p.SetInputCube("F3", Isis::AllMatchOrOne));
    if (ui.WasEntered("F4")) cubes.push_back(p.SetInputCube("F4", Isis::AllMatchOrOne));
    if (ui.WasEntered("F5")) cubes.push_back(p.SetInputCube("F5", Isis::AllMatchOrOne));
    inCube = p.SetInputCube("F1", Isis::AllMatchOrOne);
    cubes.push_back(inCube);
    if (ui.WasEntered("F2")){
        inCube = p.SetInputCube("F2", Isis::AllMatchOrOne);
        cubes.push_back(inCube);
    }
    if (ui.WasEntered("F3")){
        inCube = p.SetInputCube("F3", Isis::AllMatchOrOne);
        cubes.push_back(inCube);
    }
    if (ui.WasEntered("F4")){
        inCube = p.SetInputCube("F4", Isis::AllMatchOrOne);
        cubes.push_back(inCube);
    }
    if (ui.WasEntered("F5")){
        inCube = p.SetInputCube("F5", Isis::AllMatchOrOne);
        cubes.push_back(inCube);
    }
    bands = cubes[0]->bandCount();
    outCube = p.SetOutputCube("TO");
  }
  else if (ui.GetString("MODE") == "LIST") {
@@ -61,14 +74,16 @@ void IsisMain() {
    // Run through file list and set its entries as input cubes
    for (int i = 0; i < list.size(); i++) {
      CubeAttributeInput att(list[i].original());
      cubes.push_back(p.SetInputCube(list[i].original(), att, Isis::AllMatchOrOne));
      inCube = p.SetInputCube(list[i].original(), att, Isis::AllMatchOrOne);
      cubes.push_back(inCube);
    }
    bands = cubes[0]->bandCount();
    outCube = p.SetOutputCube("TO");
  }
  else {
    int lines = ui.GetInteger("LINES");
    int samples = ui.GetInteger("SAMPLES");
    int bands = ui.GetInteger("BANDS");
    bands = ui.GetInteger("BANDS");
    outCube = p.SetOutputCube("TO", samples, lines, bands);
  }

@@ -78,6 +93,7 @@ void IsisMain() {
  p.EndProcess();
}


/**
 * Take in the input buffer, apply the user-defined equation to
 * it, then write the results to the output buffer
@@ -111,3 +127,4 @@ void Evaluate(vector<Buffer *> &input, vector<Buffer *> &output) {
  }

}
+19 −18
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@

<application name="fx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd">
  <brief>
    Generalized arithmetic operations using multiple cube files
    Apply generalized arithmetic operations using multiple cube files
  </brief>

  <description>
@@ -15,7 +15,7 @@
    equation is applied to all the bands within the file.
    </p>
    <p>    
    Up to five files can be entered for parameters F1 to F5 under the "Input 
    Five files or fewer can be entered for parameters F1 to F5 under the "Input 
    Cube Files" section to specify the input data.  A second method to specify
    data is to include an arbitrary number of 
    files in a file list and enter the list name in the fromlist parameter that 
@@ -61,7 +61,7 @@
      </p>

      <p>   
	An escape chararter "\" has been added to differentiate a first parenthesis 
	An escape character "\" has been added to differentiate a first parenthesis 
	from the beginning of an array sequence.
      </p>

@@ -205,9 +205,10 @@
     </blockquote>
    </p>
    <p>
      In order to use the operators below, images must be processed through <i>
      In order to use the camera operators, images must be processed through <i>
      spiceinit</i> so that the NAIF camera model information is stored in the image 
      labels: 
      labels. <b>These operators calculate values on a band-by-band basis so that band-dependent
      images have correctly calculated camera-related values</b>.
    </p>
    <p>
     <blockquote>
@@ -517,13 +518,6 @@
        <td>emac(f1)</td>
      </tr>

      <tr>
        <td>1</td>
        <td>emal</td>
        <td><def>Local emission angle</def> on DTM</td>
        <td>emal(f1)</td>
      </tr>   

      <tr>
        <td>1</td>
        <td>rads</td>
@@ -700,6 +694,13 @@
      Fixed bug where the cube attributes on files in the fromlist were
      ignored.  Fixes #1926."
    </change>
    <change name="Moses Milazzo and Ian Humphrey" date="2016-10-13">
      Fixed bug where camera related operators produce incorrect calculations for band-dependent
      images. The camera operators now make calculations on a band-by-band basis, meaning
      band-dependent images are now supported with correct calculations. Fixes #1301.
      Backward Compatibility Issue: The changes made will impact any scripts that use the
      fx camera operators on band-dependent images, producing different output for each band.
    </change>
  </history>

  <groups>     
+87 −0
Original line number Diff line number Diff line
# This tests fx with a band-dependent cube when making calculations on camera
# properties. In this test, we use a band-dependent THEMIS-IR cube and use the
# various camera functions.
#
# 2016-10-13 Ian Humphrey - Original version. References #1301.
APPNAME = fx

include $(ISISROOT)/make/isismake.tsts

commands:
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/radiusTruth.cub \
	  equation=radius\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/phacTruth.cub \
          equation=phac\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/inacTruth.cub \
          equation=inac\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/emacTruth.cub \
          equation=emac\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/phaTruth.cub \
          equation=pha\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/inaTruth.cub \
          equation=ina\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/emaTruth.cub \
          equation=ema\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/phalTruth.cub \
          equation=phal\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/inalTruth.cub \
          equation=inal\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/emalTruth.cub \
          equation=emal\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/latTruth.cub \
          equation=lat\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/lonTruth.cub \
          equation=lon\(f1\) \
	  > /dev/null;
	$(APPNAME) \
	  f1=$(INPUT)/themisIR.crop20x20.cub \
	  to=$(OUTPUT)/resTruth.cub \
          equation=res\(f1\) \
	  > /dev/null;
	#$(APPNAME) \
	#  -batchlist=$(INPUT)/batchList.txt \
	#  f1=$(INPUT)/\$$\1.cub+\$$\2 \
	#  to=$(OUTPUT)/\$$\1_band\$$\2_temp.cub \
	#  equation=radius\(f1\) \
	#  > /dev/null;
	#$(LS) $(OUTPUT)/*temp.cub > $(OUTPUT)/cubeit_temp.txt;
	#cubeit \
	#  fromlist=$(INPUT)/cubeitList.txt \
	#  to=$(OUTPUT)/radiusTruth2.cub \
	#  > /dev/null;
	$(RM) $(OUTPUT)/*temp*;
+405 −125

File changed.

Preview size limit exceeded, changes collapsed.

+94 −106
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "Calculator.h"
#include "Cube.h"

class QString;
template<class T> class QVector;

namespace Isis {
@@ -62,6 +63,11 @@ namespace Isis {
   *                          ISIS coding standards
   *  @history 2015-01-30 Ian Humphrey - Removed unused variable m_data. Deallocated
   *                          unfreed dynamic memory. Added destructor. Fixes #2082.
   *  @history 2016-10-13 Ian Humphrey - Updated to correctly calculate center camera angles for
   *                          band-depedent images. Integrated Moses Milazzo's (moses@usgs.gov)
   *                          changes for correctly calculating camera angles for band-dependent
   *                          images. Quick documentation and coding standards review (moved
   *                          inline implementations to cpp). Fixes #1301.
   */
  class CubeCalculator : Calculator {
    public:
@@ -107,116 +113,88 @@ namespace Isis {
       */
      QVector<Calculations> *m_calculations;

      /**
       * This stores the addresses to the methods RunCalculations(...)
       * will call
       */
      //! This stores the addresses to the methods RunCalculations(...) will call.
      QVector<void (Calculator:: *)(void)> *m_methods;

      /**
       * This stores the addressed to the methods RunCalculations(...)
       * will push (constants), along with placeholders for simplicity to
       * keep synchronized with the data definitions.
       */
      // m_data is never used anywhere
//       QVector< QVector<double> > *m_data;

      /**
       * This defines what kind of data RunCalculations(...) will push
       * onto the calculator. Constants will be taken from p_data, which
       * is synchronized (index-wise) with this vector.
       */
      //! This defines what kind of data RunCalculations(...) will push onto the calculator.
      QVector<DataValue> *m_dataDefinitions;

      //! Stores the cube statistics for the input cubes. 
      QVector<Statistics *> *m_cubeStats;

      /**
       * This two are used for keeping cameras and camera buffers 
       * internalized for quick computations
       * Stores the cameras for the input cubes. This is synchronized with m_cameraBuffers
       * so that the camera buffers are loaded with data from the appropriate camera. 
       */
      QVector<Camera *> *m_cubeCameras;

      /**
       * Stores the camera buffers that are enabled for camera related calculations.
       * This is used for quickly computing camera related information.
       */
      QVector<CameraBuffers *> *m_cameraBuffers;

      int m_outputSamples;
      int m_outputSamples; //!< Number of samples in the output cube.
  };


  /**
   * This class is used to define what kind of data is being pushed onto the cube calculator
   * @author ????-??-?? Unknown
   *
   * @internal
   */
  class DataValue {
    public:
      /**
       * This is used to tell what kind of data to
       *   push onto the RPN calculator.
       */
      //! This is used to tell what kind of data to push onto the RPN calculator.
      enum DataValueType {
        Constant, //!< a single constant value
        Sample, //!< current sample number
        Line, //!< current line number
        Band, //!< current band number
        CubeData, //!< a brick of cube data
        InaData, //!< incidence camera data
        EmaData, //!< emission camera data
        PhaData, //!< phase camera data
        LatData, //!< Latitude camera data
        LonData, //!< Longitude camera data
        ResData, //!< Pixel resolution camera data
        RadiusData, //!< DEM radius
        InalData, //!< local incidence camera data
        EmalData, //!< local emission camera data
        PhalData //!< local phase camera data
        Constant, //!< A single constant value.
        Sample, //!< Current sample number.
        Line, //!< Current line number.
        Band, //!< Current band number.
        CubeData, //!< A brick of cube data.
        InaData, //!< Incidence camera data.
        EmaData, //!< Emission camera data.
        PhaData, //!< Phase camera data.
        LatData, //!< Latitude camera data.
        LonData, //!< Longitude camera data.
        ResData, //!< Pixel resolution camera data.
        RadiusData, //!< DEM radius.
        InalData, //!< Local incidence camera data.
        EmalData, //!< Local emission camera data.
        PhalData, //!< Local phase camera data.
        InacData, //!< Center incidence camera data.
        EmacData, //!< Center emission camera data.
        PhacData  //!< Center phase camera data.
      };

      DataValue() {
        m_type = (DataValueType) - 1;
        m_cubeIndex = -1;
        m_constantValue = 0.0;
      }

      DataValue(DataValueType type) {
        m_type = type;
        m_constantValue = 0.0;
        m_cubeIndex = -1;
      }

      DataValue(DataValueType type, int cubeIndex) {
        m_type = type;
        m_constantValue = 0.0;
        m_cubeIndex = cubeIndex;
      }

      DataValue(DataValueType type, double value) {
        m_type = type;
        m_cubeIndex = -1;

        if(type == Constant) {
          m_constantValue = value;
        }
      }
      DataValue();
      DataValue(DataValueType type);
      DataValue(DataValueType type, int cubeIndex);
      DataValue(DataValueType type, double value);

      DataValueType getType() {
        return m_type;
      }

      int getCubeIndex() {
        return m_cubeIndex;
      }

      double getConstant() {
        return m_constantValue;
      }
      DataValueType type();
      int cubeIndex();
      double constant();

    private:
      int m_cubeIndex;
      double m_constantValue;
      int m_cubeIndex;        //!< The index of the associated cube
      double m_constantValue; //!< Stored constant value

      DataValueType m_type;
      DataValueType m_type;   //!< Type of data stored.
  };


  /**
   * This class is used to manage buffers for calculating camera related information, such
   * as angles, radii, and resolution. It uses internal buffers for each of the camera related
   * operators that CubeCalculator recognizes as valid tokens. Each of the enableBuffer methods
   * can be used to dynamically allocate buffers for the camera operators that are being pushed
   * onto the CubeCalculator. Buffers can be loaded with appropriate camera data using the 
   * accessor methods.
   *
   * Note that memory is not allocated for buffers that are not enabled.
   *
   * @author 2012-02-02 Jeff Anderson
   *
   * @internal
@@ -236,35 +214,45 @@ namespace Isis {
       void enablePhalBuffer();
       void enableInalBuffer(); 
       void enableEmalBuffer(); 

       QVector<double> *getPhaBuffer (int currentLine, int ns);
       QVector<double> *getInaBuffer (int currentLine, int ns);
       QVector<double> *getEmaBuffer (int currentLine, int ns);
       QVector<double> *getLatBuffer (int currentLine, int ns);
       QVector<double> *getLonBuffer (int currentLine, int ns);
       QVector<double> *getResBuffer (int currentLine, int ns);
       QVector<double> *getRadiusBuffer (int currentLine, int ns);
       QVector<double> *getPhalBuffer (int currentLine, int ns);
       QVector<double> *getInalBuffer (int currentLine, int ns);
       QVector<double> *getEmalBuffer (int currentLine, int ns);
       void enablePhacBuffer();
       void enableInacBuffer();
       void enableEmacBuffer();

       // Accessors
       QVector<double> *phaBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *inaBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *emaBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *latBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *lonBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *resBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *radiusBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *phalBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *inalBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *emalBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *phacBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *inacBuffer(int currentLine, int ns, int currentBand);
       QVector<double> *emacBuffer(int currentLine, int ns, int currentBand);


    private:
      void loadBuffers (int currentLine, int ns);

      Camera *m_camera;
      int m_lastLine;

      QVector<double> *m_phaBuffer;
      QVector<double> *m_inaBuffer;
      QVector<double> *m_emaBuffer;
      QVector<double> *m_phalBuffer;
      QVector<double> *m_inalBuffer;
      QVector<double> *m_emalBuffer;
      QVector<double> *m_resBuffer;
      QVector<double> *m_latBuffer;
      QVector<double> *m_lonBuffer;
      QVector<double> *m_radiusBuffer;
      void loadBuffers(int currentLine, int ns, int currentBand);

      Camera *m_camera; //!< Camera to obtain camera-related information from.
      int m_lastLine; //!< The number of the last line loaded into the enabled camera buffers.

      QVector<double> *m_phaBuffer;    //!< Phase angle buffer.
      QVector<double> *m_inaBuffer;    //!< Incidence angle buffer.
      QVector<double> *m_emaBuffer;    //!< Emission angle buffer.
      QVector<double> *m_phalBuffer;   //!< Local phase angle buffer.
      QVector<double> *m_inalBuffer;   //!< Local incidence angle buffer.
      QVector<double> *m_emalBuffer;   //!< Local emission angle buffer.
      QVector<double> *m_phacBuffer;   //!< Center phase angle buffer.
      QVector<double> *m_inacBuffer;   //!< Center incidence angle buffer.
      QVector<double> *m_emacBuffer;   //!< Center emission angle buffer.
      QVector<double> *m_resBuffer;    //!< Resolution buffer.
      QVector<double> *m_latBuffer;    //!< Latitude buffer.
      QVector<double> *m_lonBuffer;    //!< Longitude buffer.
      QVector<double> *m_radiusBuffer; //!< Radius buffer.
  };
}
#endif