Commit af80ce26 authored by Jeannie Backer's avatar Jeannie Backer
Browse files

Added feature in pixel2map for using an FOV based on the full range of the...

Added feature in pixel2map for using an FOV based on the full range of the exposure time. Fixes #4476. Fixed bug in VariableLineScanCameraDetectorMap that was calculating values on the middle of the line instead of the top. Fixes #4508.

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@7207 41f8697f-d340-4b68-9986-7bafba869bb8
parent d64e0c1d
Loading
Loading
Loading
Loading
+72 −57
Original line number Original line Diff line number Diff line
@@ -12,7 +12,7 @@
#include "CubeAttribute.h"
#include "CubeAttribute.h"
#include "FileList.h"
#include "FileList.h"
#include "IException.h"
#include "IException.h"
#include "PixelIfov.h"
#include "PixelFOV.h"
#include "ProcessByBrick.h"
#include "ProcessByBrick.h"
#include "ProcessGroundPolygons.h"
#include "ProcessGroundPolygons.h"
#include "ProcessRubberSheet.h"
#include "ProcessRubberSheet.h"
@@ -28,7 +28,6 @@ using namespace Isis;


void PrintMap();
void PrintMap();
void rasterizePixel(Isis::Buffer &in);
void rasterizePixel(Isis::Buffer &in);
std::vector<double> dns;


map <QString, void *> GuiHelpers() {
map <QString, void *> GuiHelpers() {
  map <QString, void *> helper;
  map <QString, void *> helper;
@@ -37,16 +36,14 @@ map <QString, void *> GuiHelpers() {
}
}


// Global variables
// Global variables
ProcessGroundPolygons g_pgp;
ProcessGroundPolygons g_processGroundPolygons;
UniversalGroundMap *g_groundMap;
Camera *g_incam;
int g_bands;
int g_numIFOVs = 0;
Camera *incam;
PixelIfov *g_pifov;


void IsisMain() {
void IsisMain() {


  ProcessRubberSheet p;
  ProcessRubberSheet processRubberSheet;
  incam = NULL;
  g_incam = NULL;
  Cube *icube;
  Cube *icube;


  // Get the map projection file provided by the user
  // Get the map projection file provided by the user
@@ -67,6 +64,12 @@ void IsisMain() {
                  "does not contain any data";
                  "does not contain any data";
    throw IException(IException::User, msg, _FILEINFO_);
    throw IException(IException::User, msg, _FILEINFO_);
  }
  }
  if (ui.GetString("FOVRANGE") == "INSTANTANEOUS") {
    g_numIFOVs = 1;
  }
  else {
    g_numIFOVs = 3;
  }


  double newminlat, newmaxlat, newminlon, newmaxlon;
  double newminlat, newmaxlat, newminlon, newmaxlon;
  double minlat = 90;
  double minlat = 90;
@@ -78,15 +81,16 @@ void IsisMain() {
  QString lastBandString;
  QString lastBandString;


  // Get the combined lat/lon range for all input cubes
  // Get the combined lat/lon range for all input cubes
  int bands;
  for (int i = 0; i < list.size(); i++) {
  for (int i = 0; i < list.size(); i++) {
    // Open the input cube and get the camera
    // Open the input cube and get the camera
    CubeAttributeInput atts0(list[i]);
    CubeAttributeInput atts0(list[i]);
    icube = p.SetInputCube(list[i].toString(), atts0);
    icube = processRubberSheet.SetInputCube(list[i].toString(), atts0);
    g_bands = icube->bandCount();
    bands = icube->bandCount();
    incam = icube->camera();
    g_incam = icube->camera();


    // Make sure it is not the sky
    // Make sure it is not the sky
    if (incam->target()->isSky()) {
    if (g_incam->target()->isSky()) {
      QString msg = "The image [" + list[i].toString() +
      QString msg = "The image [" + list[i].toString() +
                    "] is targeting the sky, use skymap instead.";
                    "] is targeting the sky, use skymap instead.";
      throw IException(IException::User, msg, _FILEINFO_);
      throw IException(IException::User, msg, _FILEINFO_);
@@ -103,14 +107,14 @@ void IsisMain() {


    // Get the mapping group and the BandBin group
    // Get the mapping group and the BandBin group
    Pvl camMap;
    Pvl camMap;
    incam->BasicMapping(camMap);
    g_incam->BasicMapping(camMap);
    camGrp = camMap.findGroup("Mapping");
    camGrp = camMap.findGroup("Mapping");
    if (icube->hasGroup("BandBin")) {
    if (icube->hasGroup("BandBin")) {
      bandBinGrp = icube->group("BandBin");
      bandBinGrp = icube->group("BandBin");


    }
    }


    incam->GroundRange(newminlat, newmaxlat, newminlon, newmaxlon, userMap);
    g_incam->GroundRange(newminlat, newmaxlat, newminlon, newmaxlon, userMap);
    //set min lat/lon
    //set min lat/lon
    if (newminlat < minlat) {
    if (newminlat < minlat) {
      minlat = newminlat;
      minlat = newminlat;
@@ -225,13 +229,13 @@ void IsisMain() {


  // See if the user want us to handle the longitude seam
  // See if the user want us to handle the longitude seam
  if (ui.GetString("DEFAULTRANGE") == "CAMERA" || ui.GetString("DEFAULTRANGE") == "MINIMIZE") {
  if (ui.GetString("DEFAULTRANGE") == "CAMERA" || ui.GetString("DEFAULTRANGE") == "MINIMIZE") {
// TODO: the incam below is left over from the for loop above. This must be fixed
  // TODO: the g_incam below is left over from the for loop above. This must be fixed
    if (incam->IntersectsLongitudeDomain(userMap)) {
    if (g_incam->IntersectsLongitudeDomain(userMap)) {
      if (ui.GetString("LONSEAM") == "AUTO") {
      if (ui.GetString("LONSEAM") == "AUTO") {
        if ((int) userGrp["LongitudeDomain"] == 360) {
        if ((int) userGrp["LongitudeDomain"] == 360) {
          userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(180)),
          userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(180)),
                             Pvl::Replace);
                             Pvl::Replace);
          if (incam->IntersectsLongitudeDomain(userMap)) {
          if (g_incam->IntersectsLongitudeDomain(userMap)) {
            // Its looks like a global image so switch back to the
            // Its looks like a global image so switch back to the
            // users preference
            // users preference
            userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(360)),
            userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(360)),
@@ -241,7 +245,7 @@ void IsisMain() {
        else {
        else {
          userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(360)),
          userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(360)),
                             Pvl::Replace);
                             Pvl::Replace);
          if (incam->IntersectsLongitudeDomain(userMap)) {
          if (g_incam->IntersectsLongitudeDomain(userMap)) {
            // Its looks like a global image so switch back to the
            // Its looks like a global image so switch back to the
            // users preference
            // users preference
            userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(180)),
            userGrp.addKeyword(PvlKeyword("LongitudeDomain", toString(180)),
@@ -250,7 +254,7 @@ void IsisMain() {
        }
        }
        // Make the target info match the new longitude domain
        // Make the target info match the new longitude domain
        double minlat, maxlat, minlon, maxlon;
        double minlat, maxlat, minlon, maxlon;
        incam->GroundRange(minlat, maxlat, minlon, maxlon, userMap);
        g_incam->GroundRange(minlat, maxlat, minlon, maxlon, userMap);
        if (!ui.WasEntered("MINLAT")) {
        if (!ui.WasEntered("MINLAT")) {
          userGrp.addKeyword(PvlKeyword("MinimumLatitude", toString(minlat)), Pvl::Replace);
          userGrp.addKeyword(PvlKeyword("MinimumLatitude", toString(minlat)), Pvl::Replace);
        }
        }
@@ -277,7 +281,7 @@ void IsisMain() {
  Pvl pvl;
  Pvl pvl;
  pvl.addGroup(userGrp);
  pvl.addGroup(userGrp);
  pvl.addGroup(bandBinGrp);
  pvl.addGroup(bandBinGrp);
  g_pgp.SetStatCubes("TO", pvl, g_bands);
  g_processGroundPolygons.SetStatCubes("TO", pvl, bands);
  bool useCenter = true;
  bool useCenter = true;
  if (ui.GetString("METHOD") == "CENTER") {
  if (ui.GetString("METHOD") == "CENTER") {
    useCenter = true;
    useCenter = true;
@@ -286,32 +290,36 @@ void IsisMain() {
    useCenter = false;
    useCenter = false;
  }
  }
 
 
  g_pgp.SetIntersectAlgorithm(useCenter);
  g_processGroundPolygons.SetIntersectAlgorithm(useCenter);


  UniversalGroundMap *groundMap;
  for (int f = 0; f < list.size(); f++) {
  for (int f = 0; f < list.size(); f++) {


    Cube cube(list[f].toString(), "r");
    Cube cube(list[f].toString(), "r");
    g_groundMap = new UniversalGroundMap(cube);
    groundMap = new UniversalGroundMap(cube);
    // Loop through the input cube and get the all pixels values for all bands
    // Loop through the input cube and get the all pixels values for all bands
    ProcessByBrick pbb;
    ProcessByBrick processBrick;
    pbb.Progress()->SetText("Working on file:  " + list[f].toString());
    processBrick.Progress()->SetText("Working on file:  " + list[f].toString());
    pbb.SetBrickSize(1, 1, g_bands);
    processBrick.SetBrickSize(1, 1, bands);
    CubeAttributeInput atts0(list[f].toString());
    CubeAttributeInput atts0(list[f].toString());
    icube = pbb.SetInputCube(list[f].toString(), atts0, 0);
    icube = processBrick.SetInputCube(list[f].toString(), atts0, 0);
    incam = icube->camera();
    g_incam = icube->camera();
    g_pifov = new PixelIfov();



    pbb.StartProcess(rasterizePixel);
    processBrick.StartProcess(rasterizePixel);
    pbb.EndProcess();
    processBrick.EndProcess();
  }
  }
  g_pgp.EndProcess();
  g_processGroundPolygons.EndProcess();


  // WARNING: rasterizePixel() method alters the current state of the camera.
  // If any code is added after this point, you must call setImage to return
  // to original camera state before rasterization.


}
}




// Helper function to print out mapfile to session log
/**
  * Helper function to print out mapfile to session log
  */
void PrintMap() {
void PrintMap() {
  UserInterface &ui = Application::GetUserInterface();
  UserInterface &ui = Application::GetUserInterface();


@@ -325,6 +333,12 @@ void PrintMap() {
}
}




/**
  * This method uses the ProcessGroundPolygons object to rasterize each 
  * pixel in the given buffer. 
  *  
  * @param in Input ProcessByBrick buffer. 
  */
void rasterizePixel(Isis::Buffer &in) {
void rasterizePixel(Isis::Buffer &in) {


  std::vector<double>lat, lon;
  std::vector<double>lat, lon;
@@ -337,25 +351,26 @@ void rasterizePixel(Isis::Buffer &in) {
  int l = in.Line();
  int l = in.Line();
  int s = in.Sample();
  int s = in.Sample();


// TODO: This needs to be done for each band for band dependant instrumets
  // TODO: This needs to be done for each band for band dependant instruments
  // Note: This can slow this down a lot
  // Note: This can slow this down a lot


  incam->SetImage(s, l);
  // Get the IFOVs in lat/lon space
  PixelFOV fov;
  QList< QList< QPointF > > fovVertices = fov.latLonVertices(*g_incam, l, s, g_numIFOVs);


  // Get the IFOV in lat/lon space
  // loop through each ifov list
  QList<QPointF> pIfovVertices = g_pifov->latLonVertices(*incam);
  for (int ifov = 0; ifov < fovVertices.size(); ifov++) {

    // we need at least 3 vertices for a polygon
  int numVertices = pIfovVertices.size();
    if (fovVertices[ifov].size() > 3) {
  if (numVertices > 3) {
      //  Get lat/lon for each vertex of the ifov
      //  Get lat/lon for each vertex of the ifov
    for (int j = 0; j < numVertices; j++) {
      for (int point = 0; point < fovVertices[ifov].size(); point++) {
      lat.push_back(pIfovVertices[j].x());
        lat.push_back(fovVertices[ifov][point].x());
      lon.push_back(pIfovVertices[j].y());
        lon.push_back(fovVertices[ifov][point].y());
      }
      }

      // rasterize this ifov and clear vectors for next ifov
    g_pgp.Rasterize(lat, lon, dns);
      g_processGroundPolygons.Rasterize(lat, lon, dns);

      lat.clear();
      lat.clear();
      lon.clear();
      lon.clear();
    }
    }
  }
  }
}
+41 −6
Original line number Original line Diff line number Diff line
@@ -6,12 +6,16 @@
  </brief>
  </brief>


  <description>
  <description>
    This specialized program projects an ISIS <def link="Level0">level0</def> or <def link="Level1">level1</def> 
    This specialized program projects an ISIS <def link="Level0">level0</def> or 
    <def link="Cube">cube</def> to a <def link="MAP">map</def> projected (ISIS <def link="Level2">level2</def>) cube.  
    <def link="Level1">level1</def> <def link="Cube">cube</def> to a 
    <def link="MAP">map</def> projected (ISIS <def link="Level2">level2</def>) cube.  
    <p>
    <p>
    The program, <i>cam2map</i>, also projects a cube, and is recommended for most mapping applications. Use
      The program, <i>cam2map</i> also projects a cube, and is recommended for most mapping 
    <i>pixel2map</i> to project cubes where pixels do not overlap, for instance in data from a point instrument such
      applications. Use <i>pixel2map</i> to project cubes where pixels do not overlap.
    as Cassini VIMS, or the Mars Reconnaissance Orbiter CRISM instrument where scan lines may not overlap.
      For instance, this program is used to project Cassini VIMS, a point instrument. It is
      also used for line scan instruments whose lines may not overlap, such as 
      Mars Reconnaissance Orbiter CRISM and Dawn VIR.
      
    </p>
    </p>
    <p>
    <p>
    Note: <i>pixel2map</i> cannot currently process the input <b>pixel</b> which contains either pole
    Note: <i>pixel2map</i> cannot currently process the input <b>pixel</b> which contains either pole
@@ -219,6 +223,10 @@
    <change name="Sasha Brownsberger" date="2015-01-19">
    <change name="Sasha Brownsberger" date="2015-01-19">
      Updated function calls to reflect changes to ProcessGroundPolygons object.
      Updated function calls to reflect changes to ProcessGroundPolygons object.
    </change>
    </change>
    <change name="Jeannie Backer" date="2016-10-24">
      Added feature to allow user to use full exposure duration to get polygons corresponding to
      real FOV. Improved coding standards. Fixes #4476.
    </change>
  </history>
  </history>


  <groups>
  <groups>
@@ -563,6 +571,33 @@
          longitude are not parallel to image lines and sample columns.
          longitude are not parallel to image lines and sample columns.
        </description>
        </description>
      </parameter>
      </parameter>
      <parameter name="FOVRANGE">
        <type>string</type>
        <brief>The time range to be used to determine the FOV.</brief>
        <default><item>INSTANTANEOUS</item></default>
        <description>
          The field of view for each pixel is determined by the time range specified.
        </description>
        <list>
           <option value="INSTANTANEOUS">
              <brief>Uses the IFOV corresponding to the center pixel time.</brief>
              <description>
                The instantaneous field of view (IFOV) at the center of the exposure will be used
                to map each pixel.
              </description>
            </option>
           <option value="FULLEXPOSURE">
              <brief>Uses the full FOV for the entire exposure time.</brief>
              <description>
                The full field of view will be used to map each pixel. This is determined by
                finding IFOVs at three times: beginning exposure, center exposure, 
                and end exposure. The maximum ground coverage area found by combining all
                three of these IFOVs is used as the full FOV.  <b>NOTE:</b> This option is
                currently not available for framing cameras.
              </description>
            </option>
        </list>
      </parameter>
    </group>
    </group>


    <group name="Longitude Seam Options">
    <group name="Longitude Seam Options">
@@ -605,8 +640,8 @@
               </description>
               </description>
             </option>
             </option>
        </list>
        </list>

      </parameter>
      </parameter>
    </group>
    </group>

  </groups>
  </groups>
</application>
</application>
+4 −3
Original line number Original line Diff line number Diff line
@@ -6,4 +6,5 @@ commands:
	$(APPNAME) from=$(INPUT)/crism.cub \
	$(APPNAME) from=$(INPUT)/crism.cub \
	           to=$(OUTPUT)/crismequi.cub \
	           to=$(OUTPUT)/crismequi.cub \
	           map=$(ISIS3DATA)/base/templates/maps/equirectangular.map \
	           map=$(ISIS3DATA)/base/templates/maps/equirectangular.map \
	method=wholepixel > /dev/null;
	           method=wholepixel \
			   > /dev/null;
+12 −0
Original line number Original line Diff line number Diff line
APPNAME = pixel2map

include $(ISISROOT)/make/isismake.tsts

commands:
	$(APPNAME) from=$(INPUT)/VIR_IR_1B_1_506266095_refl_1.b75.l1.cub \
               to=$(OUTPUT)/p2m-VIR_IR_1B_1_506266095_refl_1.b75.l2.full.cub \
	           map=$(INPUT)/equirectangular.map \
			   pixres=mpp \
			   resolution=100 \
			   fovrange=fullexp \
			   > /dev/null;
+5 −3
Original line number Original line Diff line number Diff line
@@ -4,5 +4,7 @@ include $(ISISROOT)/make/isismake.tsts


commands:
commands:
	$(APPNAME) from=$(INPUT)/C1621694254_1.ir.band248.cub \
	$(APPNAME) from=$(INPUT)/C1621694254_1.ir.band248.cub \
        to=$(OUTPUT)/C1621694254_1.ir.equi.cub lonseam=continue \
               to=$(OUTPUT)/C1621694254_1.ir.equi.cub \
	map=$(ISIS3DATA)/base/templates/maps/equirectangular.map > /dev/null;
			   lonseam=continue \
			   map=$(ISIS3DATA)/base/templates/maps/equirectangular.map \
			   > /dev/null;
Loading