diff --git a/include/usgscsm/Distortion.h b/include/usgscsm/Distortion.h
index 990f513617f0beda9ebd431719e9e02ce164477d..10c56691840b3a856255ee7727ac756786802d92 100644
--- a/include/usgscsm/Distortion.h
+++ b/include/usgscsm/Distortion.h
@@ -6,22 +6,24 @@
 #include <tuple>
 #include <vector>
 
-enum DistortionType { RADIAL, TRANSVERSE, KAGUYALISM, DAWNFC, LROLROCNAC, CAHVOR };
+// This should be synched with the enum in ale/Distortion.h
+enum DistortionType { RADIAL, TRANSVERSE, KAGUYALISM, DAWNFC, LROLROCNAC, CAHVOR, 
+                     LUNARORBITER, RADTAN };
 
-// Transverse Distortion
-void distortionJacobian(double x, double y, double *jacobian,
-                        const std::vector<double> opticalDistCoeffs);
+// Transverse distortion Jacobian
+void transverseDistortionJacobian(double x, double y, double *jacobian,
+                                  std::vector<double> const& opticalDistCoeffs);
 
 void computeTransverseDistortion(double ux, double uy, double &dx, double &dy,
-                                 const std::vector<double> opticalDistCoeffs);
+                                 std::vector<double> const& opticalDistCoeffs);
 
 void removeDistortion(double dx, double dy, double &ux, double &uy,
-                      const std::vector<double> opticalDistCoeffs,
+                      std::vector<double> const& opticalDistCoeffs,
                       DistortionType distortionType,
                       const double tolerance = 1.0E-6);
 
 void applyDistortion(double ux, double uy, double &dx, double &dy,
-                     const std::vector<double> opticalDistCoeffs,
+                     std::vector<double> const& opticalDistCoeffs,
                      DistortionType distortionType,
                      const double desiredPrecision = 1.0E-6,
                      const double tolerance = 1.0E-6);
diff --git a/include/usgscsm/Utilities.h b/include/usgscsm/Utilities.h
index f1106299a48f361967f5e81c213e2f2c37b5a229..7247560973806c7233592436e9a7450670a22004 100644
--- a/include/usgscsm/Utilities.h
+++ b/include/usgscsm/Utilities.h
@@ -65,6 +65,15 @@ void lagrangeInterp(const int &numTime, const double *valueArray,
 double brentRoot(double lowerBound, double upperBound,
                  std::function<double(double)> func, double epsilon = 1e-10);
 
+// Use the Newton-Raphson method undistort a pixel (dx, dy), producing (ux, uy).
+void newtonRaphson(double dx, double dy, double &ux, double &uy,
+                    std::vector<double> const& opticalDistCoeffs,
+                    DistortionType distortionType, const double tolerance,
+                    std::function<void(double, double, double &, double &,
+                                       std::vector<double> const&)> distortionFunction,
+                    std::function<void(double, double, double *, 
+                                       std::vector<double> const&)> distortionJacobian);
+
 // Evaluate a polynomial function.
 // Coefficients should be ordered least order to greatest I.E. {1, 2, 3} is 1 +
 // 2x + 3x^2
diff --git a/src/Distortion.cpp b/src/Distortion.cpp
index 9684822a0dc35ce04add4056036f4c1e601f6788..38f397ac7d45176f326e2587989ca3333b040abe 100644
--- a/src/Distortion.cpp
+++ b/src/Distortion.cpp
@@ -1,10 +1,12 @@
 #include "Distortion.h"
+#include "Utilities.h"
 
 #include <Error.h>
 #include <string>
 
-void distortionJacobian(double x, double y, double *jacobian,
-                        const std::vector<double> opticalDistCoeffs) {
+// Jacobian for Transverse distortion
+void transverseDistortionJacobian(double x, double y, double *jacobian,
+                                  std::vector<double> const& opticalDistCoeffs) {
   double d_dx[10];
   d_dx[0] = 0;
   d_dx[1] = 1;
@@ -57,7 +59,7 @@ void distortionJacobian(double x, double y, double *jacobian,
  * tuple
  */
 void computeTransverseDistortion(double ux, double uy, double &dx, double &dy,
-                                 const std::vector<double> opticalDistCoeffs) {
+                                 std::vector<double> const& opticalDistCoeffs) {
   double f[10];
   f[0] = 1;
   f[1] = ux;
@@ -82,8 +84,77 @@ void computeTransverseDistortion(double ux, double uy, double &dx, double &dy,
   }
 }
 
+// Compute distorted focal plane coordinates given undistorted coordinates. Use
+// the radial-tangential distortion model with 5 coefficients (k1, k2, k3 for
+// radial distortion, and p1, p2 for tangential distortion). This was tested to
+// give the same results as the OpenCV distortion model, by invoking the
+// function cv::projectPoints() (with zero rotation, zero translation, and
+// identity camera matrix). The parameters are stored in opticalDistCoeffs 
+// in the order: [k1, k2, p1, p2, k3]. 
+void computeRadTanDistortion(double ux, double uy, double &dx, double &dy,
+                             std::vector<double> const& opticalDistCoeffs) {
+
+  if (opticalDistCoeffs.size() != 5) {
+    csm::Error::ErrorType errorType = csm::Error::INDEX_OUT_OF_RANGE;
+    std::string message =
+        "Distortion coefficients for the radtan distortion model must be of size 5, "
+        "in the order k1, k2, p1, p2, k3. Got: " + std::to_string(opticalDistCoeffs.size());
+    std::string function = "computeRadTanDistortion";
+    throw csm::Error(errorType, message, function);
+  }
+  
+  // Shorten notation
+  double x = ux, y = uy; 
+  double k1 = opticalDistCoeffs[0];
+  double k2 = opticalDistCoeffs[1];
+  double p1 = opticalDistCoeffs[2];
+  double p2 = opticalDistCoeffs[3];
+  double k3 = opticalDistCoeffs[4];
+  
+  double r2 = (x * x) + (y * y);
+  
+  dx = x * (1.0 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2)
+     + (2.0 * p1 * x * y + p2 * (r2 + 2.0 * x * x));
+       
+  dy = y * (1.0 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2)
+     + (p1 * (r2 + 2.0 * y * y) + 2.0 * p2 * x * y);
+}
+
+// Compute the jacobian for radtan distortion
+void radTanDistortionJacobian(double x, double y, double *jacobian,
+                              std::vector<double> const& opticalDistCoeffs) {
+
+  double k1 = opticalDistCoeffs[0];
+  double k2 = opticalDistCoeffs[1];
+  double p1 = opticalDistCoeffs[2];
+  double p2 = opticalDistCoeffs[3];
+  double k3 = opticalDistCoeffs[4];
+  
+  double r2 = x * x + y * y;
+  double dr2dx = 2.0 * x;
+  double dr2dy = 2.0 * y;
+
+  // dfx / dx 
+  jacobian[0] = (1.0 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2)    
+              + x * (k1 * dr2dx + k2 * dr2dx * 2.0 * r2 + k3 * dr2dx * 3.0 * r2 * r2)
+              + 2.0 * p1 * y + p2 * (dr2dx + 4.0 * x);
+  
+  // dfx / dy
+  jacobian[1] = x * (k1 * dr2dy + k2 * dr2dy * 2.0 * r2 + k3 * dr2dy * 3.0 * r2 * r2)
+              + 2.0 * p1 * x  + p2 * dr2dy;
+              
+  // dfy / dx
+  jacobian[2] = y * (k1 * dr2dx + k2 * dr2dx * 2.0 * r2 + k3 * dr2dx * 3.0 * r2 * r2)
+              + (p1 * dr2dx + 2.0 * p2 * y);
+  
+  // dfy / dy
+  jacobian[3] = (1.0 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2)
+              + y * (k1 * dr2dy + k2 * dr2dy * 2.0 * r2 + k3 * dr2dy * 3.0 * r2 * r2)
+              + p1 * (dr2dy + 4.0 * y) + 2.0 * p2 * x;
+}
+
 void removeDistortion(double dx, double dy, double &ux, double &uy,
-                      const std::vector<double> opticalDistCoeffs,
+                      std::vector<double> const& opticalDistCoeffs,
                       DistortionType distortionType, const double tolerance) {
   ux = dx;
   uy = dy;
@@ -109,55 +180,8 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
       // Solve the distortion equation using the Newton-Raphson method.
       // Set the error tolerance to about one millionth of a NAC pixel.
       // The maximum number of iterations of the Newton-Raphson method.
-      const int maxTries = 20;
-
-      double x;
-      double y;
-      double fx;
-      double fy;
-      double jacobian[4];
-
-      // Initial guess at the root
-      x = dx;
-      y = dy;
-
-      computeTransverseDistortion(x, y, fx, fy, opticalDistCoeffs);
-
-      for (int count = 1;
-           ((fabs(fx) + fabs(fy)) > tolerance) && (count < maxTries); count++) {
-        computeTransverseDistortion(x, y, fx, fy, opticalDistCoeffs);
-
-        fx = dx - fx;
-        fy = dy - fy;
-
-        distortionJacobian(x, y, jacobian, opticalDistCoeffs);
-
-        // Jxx * Jyy - Jxy * Jyx
-        double determinant =
-            jacobian[0] * jacobian[3] - jacobian[1] * jacobian[2];
-        if (fabs(determinant) < 1E-6) {
-          ux = x;
-          uy = y;
-          //
-          // Near-zero determinant. Add error handling here.
-          //
-          //-- Just break out and return with no convergence
-          return;
-        }
-
-        x = x + (jacobian[3] * fx - jacobian[1] * fy) / determinant;
-        y = y + (jacobian[0] * fy - jacobian[2] * fx) / determinant;
-      }
-
-      if ((fabs(fx) + fabs(fy)) <= tolerance) {
-        // The method converged to a root.
-        ux = x;
-        uy = y;
-
-        return;
-      }
-      // Otherwise method did not converge to a root within the maximum
-      // number of iterations
+      newtonRaphson(dx, dy, ux, uy, opticalDistCoeffs, distortionType, tolerance, 
+                    computeTransverseDistortion, transverseDistortionJacobian);
     } break;
 
     case KAGUYALISM: {
@@ -314,11 +338,22 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
       }
     }
     break;
+    
+    // Compute undistorted focal plane coordinate given distorted coordinates
+    // with the radtan model. See computeRadTanDistortion() for more details.
+    case RADTAN:
+    {
+      newtonRaphson(dx, dy, ux, uy, opticalDistCoeffs, distortionType, tolerance, 
+                    computeRadTanDistortion, radTanDistortionJacobian);
+      
+    }
+    break;
+    
   }
 }
 
 void applyDistortion(double ux, double uy, double &dx, double &dy,
-                     const std::vector<double> opticalDistCoeffs,
+                     std::vector<double> const& opticalDistCoeffs,
                      DistortionType distortionType,
                      const double desiredPrecision, const double tolerance) {
   dx = ux;
@@ -451,9 +486,9 @@ void applyDistortion(double ux, double uy, double &dx, double &dy,
       }
     } break;
 
-    // The dawn distortion model is "reversed" from other distortion models so
-    // the apply function computes distorted coordinates as a
-    // fn(undistorted coordinates)
+    // The dawn distortion model is "reversed" from other distortion models. 
+    // The apply function computes distorted coordinates as a
+    // function of undistorted coordinates.
     case DAWNFC: {
       double r2;
 
@@ -594,5 +629,14 @@ void applyDistortion(double ux, double uy, double &dx, double &dy,
       }
     }
     break;
+    
+    // Compute distorted focal plane coordinate given undistorted coordinates
+    // with the RADTAN model. See computeRadTanDistortion() for more details.
+    case RADTAN:
+    {
+      computeRadTanDistortion(ux, uy, dx, dy, opticalDistCoeffs);  
+    }  
+    break;
+    
   }
 }
diff --git a/src/Utilities.cpp b/src/Utilities.cpp
index 46be2632bc17e161842817c755119dd3779073c5..035d46060f25e9e4ea55e7b4e916166ffee9cdf9 100644
--- a/src/Utilities.cpp
+++ b/src/Utilities.cpp
@@ -401,6 +401,57 @@ double brentRoot(double lowerBound, double upperBound,
   return nextPoint;
 }
 
+// Use the Newton-Raphson method undistort a pixel (dx, dy), producing (ux, uy).
+void newtonRaphson(double dx, double dy, double &ux, double &uy,
+                    std::vector<double> const& opticalDistCoeffs,
+                    DistortionType distortionType, const double tolerance,
+                    std::function<void(double, double, double &, double &,
+                                       std::vector<double> const&)> distortionFunction,
+                    std::function<void(double, double, double *, 
+                                       std::vector<double> const&)> distortionJacobian) {
+
+  const int maxTries = 20;
+
+  double x, y, fx, fy, jacobian[4];
+
+  // Initial guess for the root
+  x = dx;
+  y = dy;
+
+  distortionFunction(x, y, fx, fy, opticalDistCoeffs);
+
+  for (int count = 1;
+        ((fabs(fx) + fabs(fy)) > tolerance) && (count < maxTries); count++) {
+    distortionFunction(x, y, fx, fy, opticalDistCoeffs);
+
+    fx = dx - fx;
+    fy = dy - fy;
+
+    distortionJacobian(x, y, jacobian, opticalDistCoeffs);
+
+    // Jxx * Jyy - Jxy * Jyx
+    double determinant =
+        jacobian[0] * jacobian[3] - jacobian[1] * jacobian[2];
+    if (fabs(determinant) < 1e-6) {
+      ux = x;
+      uy = y;
+      // Near-zero determinant. Cannot continue. Return most recent result.
+      return;
+    }
+
+    x = x + (jacobian[3] * fx - jacobian[1] * fy) / determinant;
+    y = y + (jacobian[0] * fy - jacobian[2] * fx) / determinant;
+  }
+
+  if ((fabs(fx) + fabs(fy)) <= tolerance) {
+    // The method converged to a root.
+    ux = x;
+    uy = y;
+
+    return;
+  }
+}
+
 double evaluatePolynomial(const std::vector<double> &coeffs, double x) {
   if (coeffs.empty()) {
     throw std::invalid_argument("Polynomial coeffs must be non-empty.");
@@ -1009,9 +1060,9 @@ double getSemiMinorRadius(json isd, csm::WarningList *list) {
 // type. Defaults to transverse
 DistortionType getDistortionModel(json isd, csm::WarningList *list) {
   try {
-    json distoriton_subset = isd.at("optical_distortion");
+    json distortion_subset = isd.at("optical_distortion");
 
-    json::iterator it = distoriton_subset.begin();
+    json::iterator it = distortion_subset.begin();
 
     std::string distortion = (std::string)it.key();
 
@@ -1025,6 +1076,12 @@ DistortionType getDistortionModel(json isd, csm::WarningList *list) {
       return DistortionType::DAWNFC;
     } else if (distortion.compare("lrolrocnac") == 0) {
       return DistortionType::LROLROCNAC;
+    } else if (distortion.compare("cahvor") == 0) {
+      return DistortionType::CAHVOR;
+    } else if (distortion.compare("lunarorbiter") == 0) {
+      return DistortionType::LUNARORBITER;
+    } else if (distortion.compare("radtan") == 0) {
+      return DistortionType::RADTAN;
     }
   } catch (...) {
     if (list) {
@@ -1054,6 +1111,10 @@ DistortionType getDistortionModel(int aleDistortionModel,
       return DistortionType::LROLROCNAC;
     }else if (aleDistortionType == ale::DistortionType::CAHVOR) {
       return DistortionType::CAHVOR;
+    }else if (aleDistortionType == ale::DistortionType::LUNARORBITER) {
+      return DistortionType::LUNARORBITER;
+    }else if (aleDistortionType == ale::DistortionType::RADTAN) {
+      return DistortionType::RADTAN;
     }
   } catch (...) {
     if (list) {
@@ -1212,7 +1273,26 @@ std::vector<double> getDistortionCoeffs(json isd, csm::WarningList *list) {
         coefficients = std::vector<double>(6, 0.0);
       }
     } break;
+    case DistortionType::RADTAN: {
+      try {
+        coefficients = isd.at("optical_distortion")
+                           .at("radtan")
+                           .at("coefficients")
+                           .get<std::vector<double>>();
+
+        return coefficients;
+      } catch (...) {
+        if (list) {
+          list->push_back(csm::Warning(
+              csm::Warning::DATA_NOT_AVAILABLE,
+              "Could not parse the radtan distortion model coefficients.",
+              "Utilities::getDistortion()"));
+        }
+        coefficients = std::vector<double>(5, 0.0);
+      }
+    } break;
   }
+  
   if (list) {
     list->push_back(
         csm::Warning(csm::Warning::DATA_NOT_AVAILABLE,
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8922583af27f9c0071be37c0469f47aa16e08684..a60dfc7887207b60bfb19bba9fe1184787121bb9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -33,7 +33,6 @@ add_test(NAME test_usgscsm_cam_test_load_state
     COMMAND usgscsm_cam_test --model model_state.json --output-model-state model_state2.json
     WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
 
-
 # 3. Save model state from .sup file
 add_test(NAME test_usgscsm_cam_test_save_sup_state
     COMMAND usgscsm_cam_test --model data/gxp_model_file.sup --output-model-state gxp_model_state.json
@@ -43,4 +42,9 @@ add_test(NAME test_usgscsm_cam_test_load_sup_state
     COMMAND usgscsm_cam_test --model gxp_model_state.json --output-model-state gxp_model_state2.json
     WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
 
+# 5. Test the radtan model (this distortion model gets added to a DawnFC sensor)
+add_test(NAME test_usgscsm_cam_test_radtan
+    COMMAND usgscsm_cam_test --model data/dawnfc_radtan.json  --sample-rate 100 --output-model-state dawnfc_radtan_model_state.json
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
+    
 gtest_discover_tests(runCSMCameraModelTests WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
diff --git a/tests/DistortionTests.cpp b/tests/DistortionTests.cpp
index bfee70e4eb58e1a91f7466c911aa91f458f19dc1..bda373bd24c1e89c64e4347e8c431a34c9b15a62 100644
--- a/tests/DistortionTests.cpp
+++ b/tests/DistortionTests.cpp
@@ -19,8 +19,8 @@ TEST_P(ImageCoordParameterizedTest, JacobianTest) {
 
   csm::ImageCoord imagePt = GetParam();
   double jacobian[4];
-  distortionJacobian(imagePt.samp, imagePt.line, jacobian,
-                     transverseDistortionCoeffs);
+  transverseDistortionJacobian(imagePt.samp, imagePt.line, jacobian,
+                               transverseDistortionCoeffs);
 
   // Jxx * Jyy - Jxy * Jyx
   double determinant =
@@ -36,8 +36,8 @@ TEST(Transverse, Jacobian1) {
       0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0};
 
   double jacobian[4];
-  distortionJacobian(imagePt.samp, imagePt.line, jacobian,
-                     transverseDistortionCoeffs);
+  transverseDistortionJacobian(imagePt.samp, imagePt.line, jacobian,
+                               transverseDistortionCoeffs);
 
   EXPECT_NEAR(jacobian[0], 56.25, 1e-8);
   EXPECT_NEAR(jacobian[1], 112.5, 1e-8);
@@ -389,3 +389,28 @@ TEST_P(CoeffOffsetParameterizedTest, InverseOnesCoeffsCahvorTest)
   EXPECT_NEAR(dx, 4, 1e-8);
   EXPECT_NEAR(dy, 0, 1e-8);
 }
+
+INSTANTIATE_TEST_SUITE_P(RadTanInversionTest, RadTanTest,
+                         ::testing::Values(std::vector<double>(0, 0)));
+
+TEST_P(RadTanTest, RadTanInversionTest)
+{
+
+  // Initialize radtan distortion coefficients (k1, k2, p1, p2, k3)  
+  std::vector<double> distCoeffs= {0.000031, -0.000056, 1.3e-5, -1.7e-6, 2.9e-8};
+  
+  double ux = 5.0, uy = 6.0; 
+  
+  // Compute distortion 
+  double dx, dy;
+  applyDistortion(ux, uy, dx, dy, distCoeffs, DistortionType::RADTAN, 1e-8, 1e-8);
+  
+  // Remove distortion (undistort)
+  double ux2, uy2;
+  removeDistortion(dx, dy, ux2, uy2, distCoeffs, DistortionType::RADTAN, 1e-8);
+  
+  EXPECT_NEAR(dx, 4.0010785450000004, 1e-8);
+  EXPECT_NEAR(dy, 4.8022116940000013, 1e-8);
+  EXPECT_NEAR(ux2, ux, 1e-8);
+  EXPECT_NEAR(uy2, uy, 1e-8);
+}
diff --git a/tests/Fixtures.h b/tests/Fixtures.h
index 2b5b053c537467c052dab6d212a1bde8f3c6ed7f..36c5e0ad6d2fbcf7e5aa226bff70933174e95182 100644
--- a/tests/Fixtures.h
+++ b/tests/Fixtures.h
@@ -180,6 +180,9 @@ class ImageCoordParameterizedTest
 class CoeffOffsetParameterizedTest
     : public ::testing::TestWithParam<std::vector<double>> {};
 
+class RadTanTest
+    : public ::testing::TestWithParam<std::vector<double>> {};
+
 class FramerParameterizedTest
     : public ::testing::TestWithParam<csm::ImageCoord> {
  protected:
diff --git a/tests/data/dawnfc_radtan.json b/tests/data/dawnfc_radtan.json
new file mode 100644
index 0000000000000000000000000000000000000000..22a5d9f8e3bf12f059cd2fdb36310016a755a039
--- /dev/null
+++ b/tests/data/dawnfc_radtan.json
@@ -0,0 +1,272 @@
+{
+  "isis_camera_version": 2,
+  "image_lines": 1024,
+  "image_samples": 1024,
+  "name_platform": "DAWN",
+  "name_sensor": "FRAMING CAMERA 2",
+  "reference_height": {
+    "maxheight": 1000,
+    "minheight": -1000,
+    "unit": "m"
+  },
+  "name_model": "USGS_ASTRO_FRAME_SENSOR_MODEL",
+  "center_ephemeris_time": 366389046.66804266,
+  "radii": {
+    "semimajor": 289.0,
+    "semiminor": 229.0,
+    "unit": "km"
+  },
+  "body_rotation": {
+    "time_dependent_frames": [
+      2000004,
+      1
+    ],
+    "ck_table_start_time": 366389046.66804266,
+    "ck_table_end_time": 366389046.66804266,
+    "ck_table_original_size": 1,
+    "ephemeris_times": [
+      366389046.66804266
+    ],
+    "quaternions": [
+      [
+        -0.6516990183788688,
+        0.4029902779213469,
+        -0.03888879053873084,
+        0.641385131816547
+      ]
+    ],
+    "angular_velocities": [
+      [
+        0.00015233084023562592,
+        -0.00018790495501866476,
+        0.00021960595804307437
+      ]
+    ],
+    "reference_frame": 1
+  },
+  "instrument_pointing": {
+    "time_dependent_frames": [
+      -203120,
+      -203000,
+      1
+    ],
+    "ck_table_start_time": 366389046.66804266,
+    "ck_table_end_time": 366389046.66804266,
+    "ck_table_original_size": 1,
+    "ephemeris_times": [
+      366389046.66804266
+    ],
+    "quaternions": [
+      [
+        0.23666091236048983,
+        -0.2808008347085259,
+        -0.9120764329484655,
+        0.18237073298010004
+      ]
+    ],
+    "angular_velocities": [
+      [
+        -2.4291478000490343e-05,
+        -8.625645496100273e-06,
+        8.501230573671002e-06
+      ]
+    ],
+    "reference_frame": 1,
+    "constant_frames": [
+      -203121,
+      -203120
+    ],
+    "constant_rotation": [
+      1.0,
+      0.0,
+      0.0,
+      0.0,
+      1.0,
+      0.0,
+      0.0,
+      0.0,
+      1.0
+    ]
+  },
+  "naif_keywords": {
+    "BODY2000004_RADII": [
+      289.0,
+      280.0,
+      229.0
+    ],
+    "BODY_FRAME_CODE": 2000004,
+    "BODY_CODE": 2000004,
+    "FRAME_-203121_CLASS_ID": -203121.0,
+    "TKFRAME_-203121_ANGLES": [
+      0.0,
+      0.0,
+      0.0
+    ],
+    "INS-203121_PIXEL_SAMPLES": 1024.0,
+    "FRAME_-203121_CENTER": -203.0,
+    "INS-203121_FOV_ANGULAR_SIZE": [
+      0.09548,
+      0.09542
+    ],
+    "INS-203121_RAD_DIST_COEFF": 8.4e-06,
+    "INS-203121_FOV_ANGLE_UNITS": "DEGREES",
+    "TKFRAME_-203121_AXES": [
+      1.0,
+      2.0,
+      3.0
+    ],
+    "TKFRAME_-203121_SPEC": "ANGLES",
+    "INS-203121_IFOV": [
+      9.3242e-05,
+      9.3184e-05
+    ],
+    "FRAME_-203121_NAME": "DAWN_FC2_FILTER_1",
+    "INS-203121_F/RATIO": 7.5,
+    "INS-203121_EFF_WAVELENGTH": 732.0,
+    "INS-203121_PIXEL_SIZE": [
+      14.004,
+      13.995
+    ],
+    "INS-203121_BANDCENTER": 735.0,
+    "INS-203121_FOV_CLASS_SPEC": "ANGLES",
+    "FRAME_-203121_CLASS": 4.0,
+    "INS-203121_FOV_REF_VECTOR": [
+      1.0,
+      0.0,
+      0.0
+    ],
+    "INS-203121_FOV_CROSS_ANGLE": 2.7335816,
+    "INS-203121_FOV_REF_ANGLE": 2.7353005,
+    "INS-203121_BANDWIDTH": 682.0,
+    "INS-203121_CCD_CENTER": [
+      511.5,
+      511.5
+    ],
+    "TKFRAME_-203121_UNITS": "DEGREES",
+    "INS-203121_BORESIGHT": [
+      0.0,
+      0.0,
+      150.07
+    ],
+    "INS-203121_PIXEL_LINES": 1024.0,
+    "INS-203121_FOV_SHAPE": "RECTANGLE",
+    "INS-203121_FOCAL_LENGTH": 150.07,
+    "INS-203121_ITRANSL": [
+      0.0,
+      0.0,
+      71.42857142857143
+    ],
+    "INS-203121_TRANSX": [
+      0.0,
+      0.0140088,
+      0.0
+    ],
+    "INS-203121_TRANSY": [
+      0.0,
+      0.0,
+      0.014
+    ],
+    "INS-203121_ITRANSS": [
+      0.0,
+      71.38370167323397,
+      0.0
+    ],
+    "TKFRAME_-203121_RELATIVE": "DAWN_FC2",
+    "INS-203121_FOV_FRAME": "DAWN_FC2",
+    "BODY2000004_LONG_AXIS": 0.0,
+    "FRAME_2000004_CENTER": 2000004.0,
+    "FRAME_2000004_CLASS_ID": 2000004.0,
+    "BODY2000004_POLE_DEC": [
+      42.235,
+      0.0,
+      0.0
+    ],
+    "BODY2000004_PM": [
+      285.39,
+      1617.3329428,
+      0.0
+    ],
+    "BODY2000004_POLE_RA": [
+      309.031,
+      0.0,
+      0.0
+    ],
+    "OBJECT_2000004_FRAME": "VESTA_FIXED",
+    "FRAME_2000004_CLASS": 2.0,
+    "FRAME_2000004_NAME": "VESTA_FIXED"
+  },
+  "detector_sample_summing": 1,
+  "detector_line_summing": 1,
+  "focal_length_model": {
+    "focal_length": 150.07
+  },
+  "detector_center": {
+    "line": 512.0,
+    "sample": 512.0
+  },
+  "starting_detector_line": 0,
+  "starting_detector_sample": 0,
+  "focal2pixel_lines": [
+    0.0,
+    0.0,
+    71.40816909454442
+  ],
+  "focal2pixel_samples": [
+    0.0,
+    71.40816909454442,
+    0.0
+  ],
+  "optical_distortion": {
+    "radtan": {
+      "coefficients": [
+        8.4e-06, 0, 0, 0, 0
+      ]
+    }
+  },
+  "instrument_position": {
+    "spk_table_start_time": 366389046.66804266,
+    "spk_table_end_time": 366389046.66804266,
+    "spk_table_original_size": 1,
+    "ephemeris_times": [
+      366389046.66804266
+    ],
+    "positions": [
+      [
+        -980.0261618498736,
+        1388.7080325894044,
+        2466.5530852201077
+      ]
+    ],
+    "velocities": [
+      [
+        -0.038273210022520744,
+        0.04959477604204062,
+        -0.04302704368708845
+      ]
+    ],
+    "reference_frame": 1
+  },
+  "sun_position": {
+    "spk_table_start_time": 366389046.66804266,
+    "spk_table_end_time": 366389046.66804266,
+    "spk_table_original_size": 1,
+    "ephemeris_times": [
+      366389046.66804266
+    ],
+    "positions": [
+      [
+        -235084739.21033305,
+        210948757.04546872,
+        114748421.64433399
+      ]
+    ],
+    "velocities": [
+      [
+        -15.345047951161861,
+        -12.985834298998117,
+        -3.1660155049823224
+      ]
+    ],
+    "reference_frame": 1
+  }
+}