Commit af63544c authored by Jesse Mapel's avatar Jesse Mapel Committed by jlaura
Browse files

Fixed Line Scan construction and condensed plugin tests (#145)

* First pass at test LS ISD

* Initial LS plugin test base

* fixed a test in frame plugin tests

* Initial LS plugin test suite

* Moved to single plugin test file

* Added some new plugin tests

* Fixed LS construction

* Re-updated submodules

* Reverted gtest
parent 3405ccc6
Loading
Loading
Loading
Loading
+35 −64
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ void UsgsAstroLsSensorModel::replaceModelState(const std::string &stateString )
   m_offsetSamples = j["m_offsetSamples"];
   m_platformFlag = j["m_platformFlag"];
   m_aberrFlag = j["m_aberrFlag"];
   m_atmRefFlag = j["m_atmrefFlag"];
   m_atmRefFlag = j["m_atmRefFlag"];
   m_intTimeLines = j["m_intTimeLines"].get<std::vector<double>>();
   m_intTimeStartTimes = j["m_intTimeStartTimes"].get<std::vector<double>>();
   m_intTimes = j["m_intTimes"].get<std::vector<double>>();
@@ -208,6 +208,21 @@ void UsgsAstroLsSensorModel::replaceModelState(const std::string &stateString )
     }
    }
   }

   // If computed state values are still default, then compute them
   if (m_gsd == 1.0  && m_flyingHeight == 1000.0)
   {
     updateState();
   }

   try
   {
     setLinearApproximation();
   }
   catch (...)
   {
     _linear = false;
   }
}

std::string UsgsAstroLsSensorModel::getModelNameFromModelState(
@@ -392,22 +407,6 @@ void UsgsAstroLsSensorModel::reset()
    m_covariance[i * NUM_PARAMETERS + i] = 1.0;
  }
  m_imageFlipFlag = 0;                     // 53

  // If needed set state data elements that need a sensor model to compute
  // Update if still using default settings
  if (m_gsd == 1.0  && m_flyingHeight == 1000.0)
  {
    updateState();
  }

  try
  {
    setLinearApproximation();
  }
  catch (...)
  {
    _linear = false;
  }
}


@@ -477,49 +476,6 @@ void UsgsAstroLsSensorModel::updateState()
   {
      m_covariance[i * num_params + i] = variance;
   }

   // Set flag for flipping image along horizontal axis
   int index = int((m_numEphem - 1) / 2.0) * 3;
   double xs, ys, zs;    // mid sensor position
   xs = m_ephemPts[index];
   ys = m_ephemPts[index + 1];
   zs = m_ephemPts[index + 2];
   double xv, yv, zv;    // mid sensor velocity
   xv = m_ephemRates[index];
   yv = m_ephemRates[index + 1];
   zv = m_ephemRates[index + 2];
   double xm, ym, zm;    // mid line position (mid sample)
   xm = m_referencePointXyz.x;
   ym = m_referencePointXyz.y;
   zm = m_referencePointXyz.z;
   // mid line position (first sample)
   csm::EcefCoord posf = imageToGround(csm::ImageCoord(lineCtr, 0.0), refHeight);
   // mid line position (last sample)
   csm::EcefCoord posl = imageToGround(csm::ImageCoord(lineCtr, m_totalSamples - 1), refHeight);
   double xd, yd, zd;    // unit vector normal to image footprint
   xd = posl.x - posf.x;
   yd = posl.y - posf.y;
   zd = posl.z - posf.z;
   double xn, yn, zn;
   xn = yv*zd - zv*yd;
   yn = zv*xd - xv*zd;
   zn = xv*yd - yv*xd;
   double nmag = sqrt(xn*xn + yn*yn + zn*zn);
   xn /= nmag;
   yn /= nmag;
   zn /= nmag;
   double xo, yo, zo;   // unit vector ground-to_satellite
   xo = xs - xm;
   yo = ys - ym;
   zo = zs - zm;
   double omag = sqrt(xo*xo + yo*yo + zo*zo);
   xo /= omag;
   yo /= omag;
   zo /= omag;
   double triple_product = xn*xo + yn*yo + zn*zo;
   m_imageFlipFlag = 0;
   if (triple_product > 0.0)
      m_imageFlipFlag = 1;
}


@@ -2721,10 +2677,10 @@ std::string UsgsAstroLsSensorModel::constructStateFromIsd(const std::string imag
   state["m_startingEphemerisTime"] = isd.at("STARTING_EPHEMERIS_TIME");
   state["m_centerEphemerisTime"] = isd.at("CENTER_EPHEMERIS_TIME");

   if (isd.at("NUMBER_OF_INT_TIMES").empty()) {
   if (isd.find("NUMBER_OF_INT_TIMES") == isd.end()) {
     state["m_intTimeLines"] = {0.5};
     state["m_intTimeStartTimes"] = {state["m_startingEphemerisTime"].get<double>() - state["m_centerEphemerisTime"].get<double>()};
     state["m_intTimes"] = {isd.at("INT_TIME")};
     state["m_intTimes"] = {isd.at("INT_TIME").get<double>()};
   }
   else {
     int numIntTimes = isd.at("NUMBER_OF_INT_TIMES");
@@ -2817,7 +2773,7 @@ std::string UsgsAstroLsSensorModel::constructStateFromIsd(const std::string imag
   state["m_collectionIdentifier"] = isd.at("COLL_ID");

   // Ground elevations
   state["m_refElevation"] = isd.at("REFERNCE_HEIGHT");
   state["m_refElevation"] = isd.at("REFERENCE_HEIGHT");
   state["m_minElevation"] = isd.at("MIN_VALID_HT");
   state["m_maxElevation"] = isd.at("MAX_VALID_HT");

@@ -2828,6 +2784,21 @@ std::string UsgsAstroLsSensorModel::constructStateFromIsd(const std::string imag
      state["m_ateterType"][i] = csm::param::REAL;
   }

   // Default to identity covariance
   state["m_covariance"] =
         std::vector<double>(NUM_PARAMETERS * NUM_PARAMETERS, 0.0);
   for (int i = 0; i < NUM_PARAMETERS; i++) {
     state["m_covariance"][i * NUM_PARAMETERS + i] = 1.0;
   }

   // Zero computed state values
   state["m_referencePointXyz"] = std::vector<double>(3, 0.0);
   state["m_gsd"] = 0.0;
   state["m_flyingHeight"] = 0.0;
   state["m_halfSwath"] = 0.0;
   state["m_halfTime"] = 0.0;
   state["m_imageFlipFlag"] = 0;

   // The state data will still be updated when a sensor model is created since
   // some state data is notin the ISD and requires a SM to compute them.
   return state.dump();
+19 −3
Original line number Diff line number Diff line
@@ -223,16 +223,32 @@ csm::Model *UsgsAstroPlugin::constructModelFromISD(const csm::Isd &imageSupportD

    if (modelName == UsgsAstroFrameSensorModel::_SENSOR_MODEL_NAME) {
      UsgsAstroFrameSensorModel *model =  new UsgsAstroFrameSensorModel();
      try {
        model->replaceModelState(model->constructStateFromIsd(stringIsd, warnings));
      }
      catch (...) {
        csm::Error::ErrorType aErrorType = csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE;
        std::string aMessage = "Invalid ISD for Model " + modelName + ": ";
        std::string aFunction = "UsgsAstroPlugin::constructModelFromISD()";
        throw csm::Error(aErrorType, aMessage, aFunction);
      }
      return model;
    }
    else if (modelName == UsgsAstroLsSensorModel::_SENSOR_MODEL_NAME) {
      UsgsAstroLsSensorModel *model =  new UsgsAstroLsSensorModel();
      try {
        model->replaceModelState(model->constructStateFromIsd(stringIsd, warnings));
      }
      catch (...) {
        csm::Error::ErrorType aErrorType = csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE;
        std::string aMessage = "Invalid ISD for Model " + modelName + ": ";
        std::string aFunction = "UsgsAstroPlugin::constructModelFromISD()";
        throw csm::Error(aErrorType, aMessage, aFunction);
      }
      return model;
    }
    else {
      csm::Error::ErrorType aErrorType = csm::Error::ISD_NOT_SUPPORTED;
      csm::Error::ErrorType aErrorType = csm::Error::SENSOR_MODEL_NOT_SUPPORTED;
      std::string aMessage = "Model" + modelName + " not supported: ";
      std::string aFunction = "UsgsAstroPlugin::constructModelFromISD()";
      throw csm::Error(aErrorType, aMessage, aFunction);
+3 −1
Original line number Diff line number Diff line
cmake_minimum_required(VERSION 3.10)

# Link runCSMCameraModelTests with what we want to test and the GTest and pthread library
add_executable(runCSMCameraModelTests FramePluginTests.cpp FrameCameraTests.cpp)
add_executable(runCSMCameraModelTests
               PluginTests.cpp
               FrameCameraTests.cpp)
if(WIN32)
  option(CMAKE_USE_WIN32_THREADS_INIT "using WIN32 threads" ON)
  option(gtest_disable_pthreads "Disable uses of pthreads in gtest." ON)
+14 −5
Original line number Diff line number Diff line
@@ -68,6 +68,15 @@ class FrameIsdTest : public ::testing::Test {
   }
};

class ConstVelLineScanIsdTest : public ::testing::Test {
   protected:
      csm::Isd isd;

   virtual void SetUp() {
      isd.setFilename("data/constVelocityLineScan.img");
   }
};

class FramerParameterizedTest : public ::testing::TestWithParam<csm::ImageCoord> {

protected:
+190 −0
Original line number Diff line number Diff line
#include "UsgsAstroPlugin.h"
#include "UsgsAstroFrameSensorModel.h"
#include "UsgsAstroLsSensorModel.h"

#include <sstream>
#include <fstream>
@@ -8,59 +9,70 @@

#include "Fixtures.h"

TEST(FramePluginTests, PluginName) {
TEST(PluginTests, PluginName) {
   UsgsAstroPlugin testPlugin;
   EXPECT_EQ("UsgsAstroPluginCSM", testPlugin.getPluginName());;
   EXPECT_EQ("UsgsAstroPluginCSM", testPlugin.getPluginName());
}

TEST(FramePluginTests, ManufacturerName) {
TEST(PluginTests, ManufacturerName) {
   UsgsAstroPlugin testPlugin;
   EXPECT_EQ("UsgsAstrogeology", testPlugin.getManufacturer());;
   EXPECT_EQ("UsgsAstrogeology", testPlugin.getManufacturer());
}

TEST(FramePluginTests, ReleaseDate) {
TEST(PluginTests, ReleaseDate) {
   UsgsAstroPlugin testPlugin;
   EXPECT_EQ("20170425", testPlugin.getReleaseDate());;
   EXPECT_EQ("20170425", testPlugin.getReleaseDate());
}

TEST(FramePluginTests, NumModels) {
TEST(PluginTests, NumModels) {
   UsgsAstroPlugin testPlugin;
   EXPECT_EQ(2, testPlugin.getNumModels());;
   EXPECT_EQ(2, testPlugin.getNumModels());
}

TEST(FramePluginTests, NoStateName) {
TEST(PluginTests, BadISDFile) {
   UsgsAstroPlugin testPlugin;
   csm::Isd badIsd("Not a file");
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromISD(
                badIsd,
                "USGS_ASTRO_FRAME_SENSOR_MODEL"));
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromISD(
                badIsd,
                "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL"));
}

TEST(FrameStateTests, NoStateName) {
   UsgsAstroPlugin testPlugin;
   std::string badState = "{\"not_a_name\":\"bad_name\"}";
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromState(
         "USGS_ASTRO_FRAME_SENSOR_MODEL",
         badState));;
         badState));
}

TEST(FramePluginTests, BadStateName) {
TEST(FrameStateTests, BadStateName) {
   UsgsAstroPlugin testPlugin;
   std::string badState = "{\"m_model_name\":\"bad_name\"}";
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromState(
         "USGS_ASTRO_FRAME_SENSOR_MODEL",
         badState));;
         badState));
}

TEST(FramePluginTests, BadStateValue) {
TEST(FrameStateTests, BadStateValue) {
   UsgsAstroPlugin testPlugin;
   std::string badState = "{"
         "\"m_model_name\":\"USGS_ASTRO_FRAME_SENSOR_MODEL\","
         "\"bad_param\":\"bad_value\"}";
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromState(
         "USGS_ASTRO_FRAME_SENSOR_MODEL",
         badState));;
         badState));
}

TEST(FramePluginTests, MissingStateValue) {
TEST(FrameStateTests, MissingStateValue) {
   UsgsAstroPlugin testPlugin;
   std::string badState = "{"
         "\"m_model_name\":\"USGS_ASTRO_FRAME_SENSOR_MODEL\"}";
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromState(
         "USGS_ASTRO_FRAME_SENSOR_MODEL",
         badState));;
         badState));
}

TEST_F(FrameIsdTest, Constructible) {
@@ -72,7 +84,7 @@ TEST_F(FrameIsdTest, Constructible) {

TEST_F(FrameIsdTest, NotConstructible) {
   UsgsAstroPlugin testPlugin;
   isd.setFilename("Not a file");
   isd.setFilename("data/constVelocityLineScan.img");
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromISD(
                isd,
                "USGS_ASTRO_FRAME_SENSOR_MODEL"));
@@ -98,21 +110,74 @@ TEST_F(FrameIsdTest, ConstructValidCamera) {

TEST_F(FrameIsdTest, ConstructInValidCamera) {
   UsgsAstroPlugin testPlugin;
   // Remove the model_name keyword from the ISD to make it invalid
   isd.clearParams("model_name");
   isd.setFilename("data/constVelocityLineScan.img");
   csm::Model *cameraModel = NULL;
   try {
      testPlugin.constructModelFromISD(
            isd,
            "USGS_ASTRO_FRAME_SENSOR_MODEL",
            NULL);
      FAIL() << "Expected an error";
   }
   catch(csm::Error &e) {
      EXPECT_EQ(e.getError(), csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE);
   }
   catch(...) {
      FAIL() << "Expected csm SENSOR_MODEL_NOT_CONSTRUCTIBLE error";
   }
   if (cameraModel) {
      delete cameraModel;
   }
}

TEST_F(ConstVelLineScanIsdTest, Constructible) {
   UsgsAstroPlugin testPlugin;
   EXPECT_TRUE(testPlugin.canModelBeConstructedFromISD(
               isd,
               "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL"));
}

TEST_F(ConstVelLineScanIsdTest, NotConstructible) {
   UsgsAstroPlugin testPlugin;
   isd.setFilename("data/simpleFramerISD.img");
   EXPECT_FALSE(testPlugin.canModelBeConstructedFromISD(
               isd,
               "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL"));
}

TEST_F(ConstVelLineScanIsdTest, ConstructValidCamera) {
   UsgsAstroPlugin testPlugin;
   csm::Model *cameraModel = NULL;
   EXPECT_NO_THROW(
         cameraModel = testPlugin.constructModelFromISD(
               isd,
               "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL",
               NULL)
   );
   UsgsAstroLsSensorModel *frameModel = dynamic_cast<UsgsAstroLsSensorModel *>(cameraModel);
   EXPECT_NE(frameModel, nullptr);
   if (cameraModel) {
      delete cameraModel;
   }
}

TEST_F(ConstVelLineScanIsdTest, ConstructInValidCamera) {
   UsgsAstroPlugin testPlugin;
   isd.setFilename("data/simpleFramerISD.img");
   csm::Model *cameraModel = NULL;
   try {
      testPlugin.constructModelFromISD(
            isd,
            "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL",
            NULL);
      FAIL() << "Expected an error";

   }
   catch(csm::Error &e) {
      EXPECT_EQ(e.getError(), csm::Error::ISD_NOT_SUPPORTED);
      EXPECT_EQ(e.getError(), csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE);
   }
   catch(...) {
      FAIL() << "Expected csm ISD_NOT_SUPPORTED error";
      FAIL() << "Expected csm SENSOR_MODEL_NOT_CONSTRUCTIBLE error";
   }
   if (cameraModel) {
      delete cameraModel;
Loading