Unverified Commit 1179600b authored by Jesse Mapel's avatar Jesse Mapel Committed by GitHub
Browse files

Changed line scan sensor model to new ISD spec (#149)

* Changed line scan sensor model to new ISD spec

* Updated LS to the proper spec

* Changed model_name to name_model

* Updated tests to use new name_ format in ISD

* Updated LS test data to new spec

* Fixed typo in ls test ISD

* Moved framer to new ISD format. Added bad debug statements.

* Updated LS to new spec

* Fixed focal length epsilon name
parent b81522bc
Loading
Loading
Loading
Loading
+55 −58
Original line number Diff line number Diff line
@@ -808,84 +808,84 @@ std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string&


    try {
      state["m_modelName"] = isd.at("model_name");
      state["m_modelName"] = isd.at("name_model");
      std::cerr << "Model Name Parsed!" << std::endl;

      state["m_startingDetectorSample"] = isd.at("starting_detector_sample");
      state["m_startingDetectorLine"] = isd.at("starting_detector_line");

      std::cerr << "Detector Starting Pixel Parsed!" << std::endl;

      // get focal length
      {
        json jayson = isd.at("focal_length_model");
        json focal_length = jayson.at("focal_length");
        json epsilon = jayson.at("epsilon");
        json epsilon = jayson.at("focal_epsilon");

        state["m_focalLength"] = focal_length;
        state["m_focalLengthEpsilon"] = epsilon;

        std::cerr << "Focal Length Parsed!" << std::endl;
      }

      // get sensor_location
      // get sensor_position
      {
        json jayson = isd.at("sensor_location");
        json x = jayson.at("x");
        json y = jayson.at("y");
        json z = jayson.at("z");
        json jayson = isd.at("sensor_position");
        json positions = jayson.at("positions")[0];
        json velocities = jayson.at("velocities")[0];
        json unit = jayson.at("unit");

        state["m_currentParameterValue"] = json();
        state["m_currentParameterValue"][0] = x;
        state["m_currentParameterValue"][1] = y;
        state["m_currentParameterValue"][2] = z;

        unit = unit.get<std::string>();
        state["m_currentParameterValue"][0] = metric_conversion(state["m_currentParameterValue"][0].get<double>(), unit);
        state["m_currentParameterValue"][1] = metric_conversion(state["m_currentParameterValue"][1].get<double>(), unit);
        state["m_currentParameterValue"][2] = metric_conversion(state["m_currentParameterValue"][2].get<double>(), unit);
      }

      // get  sensor_velocity
      {
        json jayson = isd.at("sensor_velocity");
        json x = jayson.at("x");
        json y = jayson.at("y");
        json z = jayson.at("z");
        state["m_currentParameterValue"] = json();
        state["m_currentParameterValue"][0] = metric_conversion(positions[0].get<double>(), unit);
        state["m_currentParameterValue"][1] = metric_conversion(positions[1].get<double>(), unit);
        state["m_currentParameterValue"][2] = metric_conversion(positions[2].get<double>(), unit);
        state["m_spacecraftVelocity"] = velocities;

        state["m_spacecraftVelocity"] = json();
        state["m_spacecraftVelocity"][0] = x;
        state["m_spacecraftVelocity"][1] = y;
        state["m_spacecraftVelocity"][2] = z;
        std::cerr << "Sensor Location Parsed!" << std::endl;
      }

      // get sun_position
      // sun position is not strictly necessary, but is required for getIlluminationDirection.
      {
        json jayson = isd.at("sun_position");
        json x = jayson.at("x");
        json y = jayson.at("y");
        json z = jayson.at("z");
        json positions = jayson.at("positions")[0];
        json unit = jayson.at("unit");

        unit = unit.get<std::string>();
        state["m_sunPosition"] = json();
        state["m_sunPosition"][0] = metric_conversion(positions[0].get<double>(), unit);
        state["m_sunPosition"][1] = metric_conversion(positions[1].get<double>(), unit);
        state["m_sunPosition"][2] = metric_conversion(positions[2].get<double>(), unit);

        state["m_sunPosition"][0] = x;
        state["m_sunPosition"][1] = y;
        state["m_sunPosition"][2] = z;
        std::cerr << "Sun Position Parsed!" << std::endl;
      }

      // get sun_position
      // sun position is not strictly necessary, but is required for getIlluminationDirection.
      // get sensor_orientation quaternion
      {
        state["m_currentParameterValue"][3] = isd.at("sensor_orientation").at(0);
        state["m_currentParameterValue"][4] = isd.at("sensor_orientation").at(1);
        state["m_currentParameterValue"][5] = isd.at("sensor_orientation").at(2);
        state["m_currentParameterValue"][6] = isd.at("sensor_orientation").at(3);
        json jayson = isd.at("sensor_orientation");
        json quaternion = jayson.at("quaternions")[0];

        state["m_currentParameterValue"][3] = quaternion[0];
        state["m_currentParameterValue"][4] = quaternion[1];
        state["m_currentParameterValue"][5] = quaternion[2];
        state["m_currentParameterValue"][6] = quaternion[3];

        std::cerr << "Sensor Orientation Parsed!" << std::endl;
      }

      // get optical_distortion
      {
        json jayson = isd.at("optical_distortion");
        std::vector<double> xDistortion = jayson.at("x");
        std::vector<double> yDistortion = jayson.at("y");
        std::vector<double> xDistortion = jayson.at("transverse").at("x");
        std::vector<double> yDistortion = jayson.at("transverse").at("y");
        xDistortion.resize(10, 0.0);
        yDistortion.resize(10, 0.0);

        state["m_odtX"] = xDistortion;
        state["m_odtY"] = yDistortion;

        std::cerr << "Distortion Parsed!" << std::endl;
      }

      // get detector_center
@@ -896,6 +896,8 @@ std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string&

        state["m_ccdCenter"][0] = line;
        state["m_ccdCenter"][1] = sample;

        std::cerr << "Detector Center Parsed!" << std::endl;
      }

      // get radii
@@ -905,13 +907,11 @@ std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string&
        json semimajor = jayson.at("semimajor");
        json unit = jayson.at("unit");

        state["m_minorAxis"] = semiminor;
        state["m_majorAxis"] = semimajor;


        unit = unit.get<std::string>();
        state["m_minorAxis"] = metric_conversion(state["m_minorAxis"].get<double>(), unit);
        state["m_majorAxis"] = metric_conversion(state["m_majorAxis"].get<double>(), unit);
        state["m_minorAxis"] = metric_conversion(semiminor.get<double>(), unit);
        state["m_majorAxis"] = metric_conversion(semimajor.get<double>(), unit);

        std::cerr << "Target Radii Parsed!" << std::endl;
      }

      // get reference_height
@@ -921,25 +921,20 @@ std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string&
        json minheight = reference_height.at("minheight");
        json unit = reference_height.at("unit");

        state["m_minElevation"] = minheight;
        state["m_maxElevation"] = maxheight;

        unit = unit.get<std::string>();
        state["m_minElevation"] = metric_conversion(state["m_minElevation"].get<double>(), unit);
        state["m_maxElevation"] = metric_conversion(state["m_minElevation"].get<double>(), unit);
        state["m_minElevation"] = metric_conversion(minheight.get<double>(), unit);
        state["m_maxElevation"] = metric_conversion(maxheight.get<double>(), unit);

        std::cerr << "Reference Height Parsed!" << std::endl;
      }

      state["m_ephemerisTime"] = isd.at("center_ephemeris_time");
      state["m_nLines"] = isd.at("image_lines");
      state["m_nSamples"] = isd.at("image_samples");

      state["m_iTransL"][0] = isd.at("focal2pixel_lines").at(0);
      state["m_iTransL"][1] = isd.at("focal2pixel_lines").at(1);
      state["m_iTransL"][2] = isd.at("focal2pixel_lines").at(2);
      state["m_iTransL"] = isd.at("focal2pixel_lines");

      state["m_iTransS"][0] = isd.at("focal2pixel_samples").at(0);
      state["m_iTransS"][1] = isd.at("focal2pixel_samples").at(1);
      state["m_iTransS"][2] = isd.at("focal2pixel_samples").at(2);
      state["m_iTransS"] = isd.at("focal2pixel_samples");

      // We don't pass the pixel to focal plane transformation so invert the
      // focal plane to pixel transformation
@@ -956,6 +951,8 @@ std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string&
      state["m_transY"][0] = -(state["m_transY"][1].get<double>() * state["m_iTransL"][0].get<double>() +
                               state["m_transY"][2].get<double>() * state["m_iTransS"][0].get<double>());

      std::cerr << "Focal To Pixel Transformation Parsed!" << std::endl;

    }
    catch(std::out_of_range& e) {
      throw csm::Error(csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE,
+69 −90
Original line number Diff line number Diff line
@@ -401,11 +401,7 @@ void UsgsAstroLsSensorModel::reset()
  m_halfSwath = 1000.0;                    // 50
  m_halfTime = 10.0;                       // 51

  m_covariance.assign(NUM_PARAMETERS * NUM_PARAMETERS,0.0); // 52
  for (int i = 0; i < NUM_PARAMETERS; i++)
  {
    m_covariance[i * NUM_PARAMETERS + i] = 1.0;
  }
  m_covariance = std::vector<double>(NUM_PARAMETERS * NUM_PARAMETERS,0.0); // 52
  m_imageFlipFlag = 0;                     // 53
}

@@ -2664,57 +2660,43 @@ std::string UsgsAstroLsSensorModel::constructStateFromIsd(const std::string imag

   int num_params = NUM_PARAMETERS;

   state["m_imageIdentifier"] = isd.at("IMAGE_ID");
   state["m_sensorType"] = isd.at("SENSOR_TYPE");
   state["m_totalLines"] = isd.at("TOTAL_LINES");
   state["m_totalSamples"] = isd.at("TOTAL_SAMPLES");
   state["m_imageIdentifier"] = "UNKNOWN";
   state["m_sensorType"] = "LINE_SCAN";
   state["m_totalLines"] = isd.at("image_lines");
   state["m_totalSamples"] = isd.at("image_samples");
   state["m_offsetLines"] = 0.0;
   state["m_offsetSamples"] = 0.0;
   state["m_platformFlag"] = isd.at("PLATFORM");
   state["m_aberrFlag"] = isd.at("ABERR");
   state["m_atmRefFlag"] = isd.at("ATMREF");

   state["m_startingEphemerisTime"] = isd.at("STARTING_EPHEMERIS_TIME");
   state["m_centerEphemerisTime"] = isd.at("CENTER_EPHEMERIS_TIME");

   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").get<double>()};
   }
   else {
     int numIntTimes = isd.at("NUMBER_OF_INT_TIMES");
     for (int i = 0; i < numIntTimes; i++) {
       state["m_intTimeLines"].push_back(isd.at("INT_TIME").at(i*3));
       state["m_intTimeStartTimes"].push_back(isd.at("INT_TIME").at(i*3+1));
       state["m_intTimes"].push_back(isd.at("INT_TIME").at(i*3+2));
     }
   }

   state["m_centerEphemerisTime"] = isd.at("CENTER_EPHEMERIS_TIME");
   state["m_detectorSampleSumming"] = isd.at("DETECTOR_SAMPLE_SUMMING");
   state["m_startingSample"] = isd.at("STARTING_SAMPLE");
   state["m_ikCode"] = isd.at("IKCODE");
   state["m_focal"] = isd.at("FOCAL");
   state["m_isisZDirection"] = isd.at("ISIS_Z_DIRECTION");

   for (int i = 0; i < 3; i++)
   {
      state["m_opticalDistCoef"][i] = isd.at("OPTICAL_DIST_COEF").at(i);
      state["m_iTransS"][i] = isd.at("ITRANSS").at(i);
      state["m_iTransL"][i] = isd.at("ITRANSL").at(i);
   }

   state["m_detectorSampleOrigin"] = isd.at("DETECTOR_SAMPLE_ORIGIN");
   state["m_detectorLineOrigin"] = isd.at("DETECTOR_LINE_ORIGIN");
   state["m_detectorLineOffset"] = isd.at("DETECTOR_LINE_OFFSET");

   double cos_a = cos(isd.at("MOUNTING_ANGLES").at(0).get<double>());
   double sin_a = sin(isd.at("MOUNTING_ANGLES").at(0).get<double>());
   double cos_b = cos(isd.at("MOUNTING_ANGLES").at(1).get<double>());
   double sin_b = sin(isd.at("MOUNTING_ANGLES").at(1).get<double>());
   double cos_c = cos(isd.at("MOUNTING_ANGLES").at(2).get<double>());
   double sin_c = sin(isd.at("MOUNTING_ANGLES").at(2).get<double>());
   state["m_platformFlag"] = 1;
   state["m_aberrFlag"] = 0;
   state["m_atmRefFlag"] = 0;
   state["m_centerEphemerisTime"] = isd.at("center_ephemeris_time");
   state["m_startingEphemerisTime"] = isd.at("starting_ephemeris_time");

   for (auto& scanRate : isd.at("line_scan_rate")) {
     state["m_intTimeLines"].push_back(scanRate[0]);
     state["m_intTimeStartTimes"].push_back(scanRate[1]);
     state["m_intTimes"].push_back(scanRate[2]);
   }

   state["m_detectorSampleSumming"] = isd.at("detector_sample_summing");
   state["m_startingSample"] = isd.at("detector_line_summing");
   state["m_ikCode"] = 0;
   state["m_focal"] = isd.at("focal_length_model").at("focal_length");
   state["m_isisZDirection"] = 1;
   state["m_opticalDistCoef"] = isd.at("optical_distortion").at("radial").at("coefficients");
   state["m_iTransS"] = isd.at("focal2pixel_samples");
   state["m_iTransL"] = isd.at("focal2pixel_lines");

   state["m_detectorSampleOrigin"] = isd.at("detector_center").at("sample");
   state["m_detectorLineOrigin"] = isd.at("detector_center").at("line");
   state["m_detectorLineOffset"] = 0;

   double cos_a = cos(0);
   double sin_a = sin(0);
   double cos_b = cos(0);
   double sin_b = sin(0);
   double cos_c = cos(0);
   double sin_c = sin(0);

   state["m_mountingMatrix"] = json::array();
   state["m_mountingMatrix"][0] = cos_b * cos_c;
@@ -2727,60 +2709,57 @@ std::string UsgsAstroLsSensorModel::constructStateFromIsd(const std::string imag
   state["m_mountingMatrix"][7] = sin_a * cos_b;
   state["m_mountingMatrix"][8] = cos_a * cos_b;

   state["m_dtEphem"] = isd.at("DT_EPHEM");
   state["m_t0Ephem"] = isd.at("T0_EPHEM");
   state["m_dtQuat"] =  isd.at("DT_QUAT");
   state["m_t0Quat"] =  isd.at("T0_QUAT");
   state["m_dtEphem"] = isd.at("dt_ephemeris");
   state["m_t0Ephem"] = isd.at("t0_ephemeris");
   state["m_dtQuat"] =  isd.at("dt_quaternion");
   state["m_t0Quat"] =  isd.at("t0_quaternion");

   state["m_numEphem"] = isd.at("NUMBER_OF_EPHEM");
   state["m_numQuaternions"] = isd.at("NUMBER_OF_QUATERNIONS");
   state["m_numEphem"] = isd.at("sensor_position").at("positions").size();
   state["m_numQuaternions"] = isd.at("sensor_orientation").at("quaternions").size();

   int numEphem = isd.at("NUMBER_OF_EPHEM");
   for (int i=0;i < numEphem * 3; i++){
       state["m_ephemPts"].push_back(isd.at("EPHEM_PTS").at(i));
       state["m_ephemRates"].push_back(isd.at("EPHEM_RATES").at(i));
   for (auto& location : isd.at("sensor_position").at("positions")) {
     state["m_ephemPts"].push_back(location[0]);
     state["m_ephemPts"].push_back(location[1]);
     state["m_ephemPts"].push_back(location[2]);
   }

   int numQuat = isd.at("NUMBER_OF_QUATERNIONS");
   for (int i=0; i < numQuat * 4; i++){
       state["m_quaternions"].push_back(isd.at("QUATERNIONS").at(i));
   for (auto& velocity : isd.at("sensor_position").at("velocities")) {
     state["m_ephemRates"].push_back(velocity[0]);
     state["m_ephemRates"].push_back(velocity[1]);
     state["m_ephemRates"].push_back(velocity[2]);
   }

   //state["m_ephemPts"] = isd.m_ephem_pts;
   //state["m_ephemRates"] = isd.m_ephem_rates;
   //state["m_quaternions"] = isd.m_quaternions;
   state["m_parameterVals"] = json::array();
   for (int i=0; i < 18; i++){
       state["m_parameterVals"].push_back(isd.at("TRI_PARAMETERS").at(i));
   for (auto& quaternion : isd.at("sensor_orientation").at("quaternions")) {
     state["m_quaternions"].push_back(quaternion[0]);
     state["m_quaternions"].push_back(quaternion[1]);
     state["m_quaternions"].push_back(quaternion[2]);
     state["m_quaternions"].push_back(quaternion[3]);
    }
   //state["m_parameterVals"] = isd.m_tRI_PARAMETERS;
   double deltaF = state["m_parameterVals"][numQuat - 1].get<double>() - state["m_focal"].get<double>();
   if (fabs(deltaF) < 0.4 * state["m_focal"].get<double>())
      state["m_parameterVals"][numQuat - 1] = deltaF;


   state["m_parameterVals"] = std::vector<double>(NUM_PARAMETERS, 0.0);
   state["m_parameterVals"][15] = state["m_focal"].get<double>();

   // Set the ellipsoid
   state["m_semiMajorAxis"] = isd.at("SEMI_MAJOR_AXIS");
   state["m_semiMinorAxis"] =
        state["m_semiMajorAxis"].get<double>() * sqrt(1.0 - isd.at("ECCENTRICITY").get<double>() * isd.at("ECCENTRICITY").get<double>()) ;
   state["m_semiMajorAxis"] = isd.at("radii").at("semimajor");
   state["m_semiMinorAxis"] = isd.at("radii").at("semiminor");

   // Now finish setting the state data from the ISD read in

   // set identifiers
   state["m_referenceDateAndTime"] = isd.at("REF_DATE_TIME");
   state["m_platformIdentifier"]   = isd.at("PLATFORM_ID");
   state["m_sensorIdentifier"]     = isd.at("SENSOR_ID");
   state["m_trajectoryIdentifier"] = isd.at("TRAJ_ID");
   state["m_collectionIdentifier"] = isd.at("COLL_ID");
   state["m_referenceDateAndTime"] = "UNKNOWN";
   state["m_platformIdentifier"]   = isd.at("name_platform");
   state["m_sensorIdentifier"]     = isd.at("name_sensor");
   state["m_trajectoryIdentifier"] = "UNKNOWN";
   state["m_collectionIdentifier"] = "UNKNOWN";

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

   // Zero ateter values
   for (int i = 0; i < numQuat; i++)
   {
      state["m_parameterVals"][i] = 0.0;
   for (int i = 0; i < NUM_PARAMETERS; i++) {
      state["m_ateterType"][i] = csm::param::REAL;
   }

+3 −3
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ const int UsgsAstroPlugin::_NUM_ISD_KEYWORDS = 21;

const std::string UsgsAstroPlugin::_ISD_KEYWORD[] =
{
   "model_name",
   "name_model",
   "center_ephemeris_time",
   "dt_ephemeris",
   "focal2pixel_lines",
@@ -175,11 +175,11 @@ std::string UsgsAstroPlugin::getModelNameFromModelState(const std::string &model
                                                   csm::WarningList *warnings) const {
  auto state = json::parse(modelState);

  std::string name = state.value<std::string>("model_name", "");
  std::string name = state.value<std::string>("name_model", "");

  if (name == "") {
      csm::Error::ErrorType aErrorType = csm::Error::INVALID_SENSOR_MODEL_STATE;
      std::string aMessage = "No 'model_name' key in the model state object.";
      std::string aMessage = "No 'name_model' key in the model state object.";
      std::string aFunction = "UsgsAstroPlugin::getModelNameFromModelState";
      csm::Error csmErr(aErrorType, aMessage, aFunction);
      throw(csmErr);
+91 −109
Original line number Diff line number Diff line
{
   "DT_EPHEM": 0.2,
   "NUMBER_OF_EPHEM": 9,
   "T0_QUAT": -8.0,
   "MIN_VALID_HT": -10,
   "SEMI_MAJOR_AXIS": 10,
   "QUATERNIONS": [
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547,
     0.0, -0.707106781186547, 0.0, 0.707106781186547
  "name_model" : "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL",
  "name_platform" : "TEST_PLATFORM",
  "name_sensor" : "TEST_SENSOR",
  "center_ephemeris_time": 1000.0,
  "starting_ephemeris_time": 992.0,
  "line_scan_rate": [
    [0.5, 992.0, 0.1]
  ],
   "SENSOR_ID": "USGS_LINE_SCANNER",
   "SCAN_DURATION": 16.0,
   "ECCENTRICITY": 0.0,
   "STARTING_EPHEMERIS_TIME": 992.0,
   "STARTING_LINE": 1,
   "STARTING_SAMPLE": 0,
   "DETECTOR_SAMPLE_ORIGIN": 8.5,
   "IMAGE_ID": "UNKNOWN",
   "PLATFORM": 1,
   "TOTAL_LINES": 16,
   "EPHEM_RATES": [
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0,
     0.0, 0.0, -20.0
   ],
   "DT_QUAT": 0.2,
   "FOCAL": 50.0,
   "DETECTOR_LINE_ORIGIN": 0.5,
   "MOUNTING_ANGLES": [
     0,
     0,
     0
   ],
   "T0_EPHEM": -8.0,
   "DETECTOR_SAMPLE_SUMMING": 1,
   "REFERENCE_HEIGHT": 0,
   "ATMREF": 0,
   "SENSOR_TYPE": "USGSAstroLineScanner",
   "TOTAL_SAMPLES": 16,
   "ABERR": 0,
   "OPTICAL_DIST_COEF": [
     0.0,
     0.0,
     0.0
   ],
   "COLL_ID": "UNKNOWN",
   "DETECTOR_LINE_OFFSET": 0,
   "EPHEM_PTS": [
     1000.0, 0.0, 16.0,
     1000.0, 0.0, 12.0,
     1000.0, 0.0, 8.0,
     1000.0, 0.0, 4.0,
     1000.0, 0.0, 0.0,
     1000.0, 0.0, -4.0,
     1000.0, 0.0, -8.0,
     1000.0, 0.0, -12.0,
     1000.0, 0.0, -16.0
   ],
   "CENTER_EPHEMERIS_TIME": 1000.0,
   "INT_TIME": 0.1,
   "NUMBER_OF_QUATERNIONS": 9,
   "ITRANSS": [
     0,
     0,
     10.0
  "detector_sample_summing": 1,
  "detector_line_summing": 1,
  "t0_ephemeris": -8.0,
  "dt_ephemeris": 0.2,
  "t0_quaternion": -8.0,
  "dt_quaternion": 0.2,
  "focal2pixel_lines": [0.0, 10.0, 0.0],
  "focal2pixel_samples": [0.0, 0.0, 10.0],
  "focal_length_model": {
    "focal_length": 50,
    "focal_epsilon": 1.0
  },
  "image_lines": 16,
  "image_samples": 16,
  "detector_center" : {
    "line" : 0.5,
    "sample" : 7.5
  },
  "interpolation_method": "lagrange",
  "optical_distortion": {
    "radial": {
      "coefficients": [0.0, 0.0, 0.0]
    }
  },
  "radii": {
    "semimajor": 10,
    "semiminor": 10,
    "unit":"m"
  },
  "reference_height": {
    "maxheight": 1,
    "minheight": -1,
    "unit": "m"
  },
  "sensor_position": {
    "unit": "m",
    "positions": [
      [1000.0, 0.0, 16.0],
      [1000.0, 0.0, 12.0],
      [1000.0, 0.0, 8.0],
      [1000.0, 0.0, 4.0],
      [1000.0, 0.0, 0.0],
      [1000.0, 0.0, -4.0],
      [1000.0, 0.0, -8.0],
      [1000.0, 0.0, -12.0],
      [1000.0, 0.0, -16.0]
    ],
   "IKCODE": -99999,
   "PLATFORM_ID": "UNKNOWN",
   "ISIS_Z_DIRECTION": 1,
   "MAX_VALID_HT": 20,
   "TRI_PARAMETERS": [
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     50.0,
     0,
     0
    "velocities": [
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0],
      [0.0, 0.0, -20.0]
    ]
  },
  "sensor_orientation": {
    "quaternions": [
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547],
      [0.0, -0.707106781186547, 0.0, 0.707106781186547]
    ]
  },
  "starting_detector_line": 0,
  "starting_detector_sample": 0,
  "sun_position": {
    "positions": [
      [100.0, 100.0, 0.0]
    ],
   "TRAJ_ID": "UNKNOWN",
   "ITRANSL": [
     0,
     10.0,
     0
    "velocities": [
      [0.0, 0.0, 0.0]
    ],
   "REF_DATE_TIME": "UNKNOWN"
    "unit": "m"
  }
}
+24 −22
Original line number Diff line number Diff line
{
	"model_name" : "USGS_ASTRO_FRAME_SENSOR_MODEL",
	"name_model" : "USGS_ASTRO_FRAME_SENSOR_MODEL",
	"center_ephemeris_time": 50,
	"dt_ephemeris": 100,
  "focal2pixel_lines": [0.0, 0.0, 10.0],
  "focal2pixel_samples": [0.0, 10.0, 0.0],
	"focal_length_model": {
		"focal_length": 50,
		"epsilon": 1.0
		"focal_epsilon": 1.0
	},
	"image_lines": 15,
	"image_samples": 15,
@@ -17,8 +17,10 @@
	"interpolation_method": "lagrange",
	"number_of_ephemerides": 1,
	"optical_distortion": {
		"transverse": {
			"x": [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
			"y": [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
		}
	},
	"radii": {
		"semimajor": 0.01,
@@ -30,30 +32,30 @@
		"minheight": -1,
		"unit": "m"
	},
	"sensor_location": {
		"unit": "m",
		"x": 1000,
		"y": 0,
		"z": 0
	},
	"sensor_orientation": [0.0, -0.707106781186547, 0.0, 0.707106781186547],
	"sensor_velocity": {
	"sensor_position": {
		"unit": "m",
		"x": 0,
		"y": 0,
		"z": 0
		"positions": [
			[1000.0, 0.0, 0.0]
		],
		"velocities": [
			[0.0, 0.0, 0.0]
		]
	},
	"sensor_orientation": {
		"quaternions": [
			[0.0, -0.707106781186547, 0.0, 0.707106781186547]
		]
	},
	"starting_detector_line": 0,
	"starting_detector_sample": 0,
	"starting_ephemeris_time": 0,
	"sun_position": {
		"x": 100,
		"y": 100,
		"z": 0
	},
	"sun_velocity": {
		"x": 0,
		"y": 0,
		"z": 0
		"unit": "m",
		"positions": [
			[100.0, 100.0, 0.0]
		],
		"velocities": [
			[0.0, 0.0, 0.0]
		]
	}
}