diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e5226c71a72c614d729657a814b7e2a279486bc..afea28afb603659980b2aceca63295cb0469b0d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,8 @@ add_library(usgscsm SHARED
             src/UsgsAstroPlugin.cpp
             src/UsgsAstroFrameSensorModel.cpp
             src/UsgsAstroLsSensorModel.cpp
-            src/Distortion.cpp)
+            src/Distortion.cpp
+	    src/Utilities.cpp)
 
 set_target_properties(usgscsm PROPERTIES
     VERSION ${PROJECT_VERSION}
diff --git a/include/usgscsm/UsgsAstroLsSensorModel.h b/include/usgscsm/UsgsAstroLsSensorModel.h
index 3cd5f317dc330509f0b405e92bb4b4a37f71ddd1..eb8bf85dc0caaaefba054c37409b8fdd815a09da 100644
--- a/include/usgscsm/UsgsAstroLsSensorModel.h
+++ b/include/usgscsm/UsgsAstroLsSensorModel.h
@@ -31,7 +31,6 @@
 #include <SettableEllipsoid.h>
 #include <CorrelationModel.h>
 
-
 class UsgsAstroLsSensorModel : public csm::RasterGM, virtual public csm::SettableEllipsoid
 {
 public:
@@ -916,27 +915,13 @@ private:
       double* achievedPrecision = NULL,
       csm::WarningList* warnings = NULL) const;
 
-   // methods pulled out of los2ecf and computeViewingPixel
-
-   void computeDistortedFocalPlaneCoordinates(
-       const double& line,
-       const double& sample,
-       double& distortedLine,
-       double& distortedSample) const;
-
-   void calculateRotationMatrixFromQuaternions(
-       const double& time,
-       double cameraToBody[9]) const;
-
-   void calculateRotationMatrixFromEuler(
-       double euler[],
-       double rotationMatrix[]) const;
+   void reconstructSensorDistortion(
+     double& focalX,
+     double& focalY,
+     const double& desiredPrecision) const;
 
-   void createCameraLookVector(
-       const double& undistortedFocalPlaneX,
-       const double& undistortedFocalPlaneY,
-       const std::vector<double>& adj,
-       double cameraLook[]) const;
+   void getQuaternions(const double& time,
+                       double quaternion[4]) const;
 
    void calculateAttitudeCorrection(
        const double& time,
diff --git a/include/usgscsm/Utilities.h b/include/usgscsm/Utilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..a7b1b7606506fec497df472358e9705ee187b6e8
--- /dev/null
+++ b/include/usgscsm/Utilities.h
@@ -0,0 +1,48 @@
+#ifndef Utilities_h
+#define Utilities_h
+
+#include <vector>
+#include <math.h>
+#include <tuple>
+
+// methods pulled out of los2ecf and computeViewingPixel
+
+// for now, put everything in here. 
+// TODO: later, consider if it makes sense to pull sample/line offsets out
+// Compute distorted focalPlane coordinates in mm
+std::tuple<double, double> computeDistortedFocalPlaneCoordinates(
+  const double& line,
+  const double& sample,
+  const double& sampleOrigin,
+  const double& lineOrigin, 
+  const double& sampleSumming,
+  const double& startingSample,
+  const double& lineOffset,
+  const double iTransS[],
+  const double iTransL[]);
+    
+void calculateRotationMatrixFromQuaternions(
+  double quaternions[4],
+  double cameraToBody[9]);
+
+void calculateRotationMatrixFromEuler(
+  double euler[],
+  double rotationMatrix[]);
+
+void createCameraLookVector(
+  const double& undistortedFocalPlaneX,
+  const double& undistortedFocalPlaneY,
+  const double& zDirection,
+  const double& focalLength,
+  const double& focalLengthBias,
+  const double& halfSwath,
+  double cameraLook[]);
+
+//void calculateAttitudeCorrection(
+//  const double& time,
+//  
+//  double attCorr[9]);
+//
+
+#endif
+
diff --git a/src/UsgsAstroFrameSensorModel.cpp b/src/UsgsAstroFrameSensorModel.cpp
index 03f45a7357a996ad636e0006290026a881579f04..ca233c8be1d386da66118c5ae98fcf00ce25f248 100644
--- a/src/UsgsAstroFrameSensorModel.cpp
+++ b/src/UsgsAstroFrameSensorModel.cpp
@@ -126,7 +126,7 @@ csm::ImageCoord UsgsAstroFrameSensorModel::groundToImage(
 
   // Camera rotation matrix
   double m[3][3];
-  calcRotationMatrix(m,adjustments);
+  calcRotationMatrix(m, adjustments);
 
   // Sensor position
   double undistortedx, undistortedy, denom;
diff --git a/src/UsgsAstroLsSensorModel.cpp b/src/UsgsAstroLsSensorModel.cpp
index ad040c96fc7b32dc7efe4b07b58e96d48a0ef534..616069537749fadca3a09fe877ba4b0048536a70 100644
--- a/src/UsgsAstroLsSensorModel.cpp
+++ b/src/UsgsAstroLsSensorModel.cpp
@@ -19,6 +19,7 @@
 #define USGS_SENSOR_LIBRARY
 
 #include "UsgsAstroLsSensorModel.h"
+#include "Utilities.h"
 #include "Distortion.h"
 
 #include <algorithm>
@@ -1658,92 +1659,18 @@ double UsgsAstroLsSensorModel::getValue(
 // Functions pulled out of losToEcf and computeViewingPixel
 // **************************************************************************
 
-// Compute distorted focalPlane coordinates in mm
-void UsgsAstroLsSensorModel::computeDistortedFocalPlaneCoordinates(const double& line, const double& sample, double& distortedLine, double& distortedSample) const{
-  double detSample = (sample - 1.0)
-      * m_detectorSampleSumming + m_startingSample;
-  double m11 = m_iTransL[1];
-  double m12 = m_iTransL[2];
-  double m21 = m_iTransS[1];
-  double m22 = m_iTransS[2];
-  double t1 = line + m_detectorLineOffset
-               - m_detectorLineOrigin - m_iTransL[0];
-  double t2 = detSample - m_detectorSampleOrigin - m_iTransS[0];
-  double determinant = m11 * m22 - m12 * m21;
-  double p11 = m11 / determinant;
-  double p12 = -m12 / determinant;
-  double p21 = -m21 / determinant;
-  double p22 = m22 / determinant;
-  distortedLine = p11 * t1 + p12 * t2;
-  distortedSample = p21 * t1 + p22 * t2;
-}
-
-
-// Define imaging ray in image space (In other words, create a look vector in camera space)
-void UsgsAstroLsSensorModel::createCameraLookVector(const double& undistortedFocalPlaneX, const double& undistortedFocalPlaneY, const std::vector<double>& adj, double cameraLook[]) const{
-   cameraLook[0] = -undistortedFocalPlaneX * m_zDirection;
-   cameraLook[1] = -undistortedFocalPlaneY * m_zDirection;
-   cameraLook[2] = -m_focal * (1.0 - getValue(15, adj) / m_halfSwath);
-   double magnitude = sqrt(cameraLook[0] * cameraLook[0]
-                  + cameraLook[1] * cameraLook[1]
-                  + cameraLook[2] * cameraLook[2]);
-   cameraLook[0] /= magnitude;
-   cameraLook[1] /= magnitude;
-   cameraLook[2] /= magnitude;
-};
-
-
-// Given a time and a flag to indicate whether the a->b or b->a rotation should be calculated
-// uses the quaternions in the m_quaternions member to calclate a rotation matrix.
-void UsgsAstroLsSensorModel::calculateRotationMatrixFromQuaternions(const double& time, double rotationMatrix[9]) const {
+void UsgsAstroLsSensorModel::getQuaternions(const double& time, double q[4]) const{
   int nOrder = 8;
   if (m_platformFlag == 0)
      nOrder = 4;
   int nOrderQuat = nOrder;
   if (m_numQuaternions < 6 && nOrder == 8)
      nOrderQuat = 4;
-  double q[4];
   lagrangeInterp(
-     m_numQuaternions, &m_quaternions[0], m_t0Quat, m_dtQuat,
-     time, 4, nOrderQuat, q);
-  double norm = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
-  q[0] /= norm;
-  q[1] /= norm;
-  q[2] /= norm;
-  q[3] /= norm;
-
-  rotationMatrix[0] = q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
-  rotationMatrix[1] = 2 * (q[0] * q[1] - q[2] * q[3]);
-  rotationMatrix[2] = 2 * (q[0] * q[2] + q[1] * q[3]);
-  rotationMatrix[3] = 2 * (q[0] * q[1] + q[2] * q[3]);
-  rotationMatrix[4] = -q[0] * q[0] + q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
-  rotationMatrix[5] = 2 * (q[1] * q[2] - q[0] * q[3]);
-  rotationMatrix[6] = 2 * (q[0] * q[2] - q[1] * q[3]);
-  rotationMatrix[7] = 2 * (q[1] * q[2] + q[0] * q[3]);
-  rotationMatrix[8] = -q[0] * q[0] - q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
-};
-
-// Calculates a rotation matrix from Euler angles
-void UsgsAstroLsSensorModel::calculateRotationMatrixFromEuler(double euler[],
-                                                              double rotationMatrix[]) const {
-  double cos_a = cos(euler[0]);
-  double sin_a = sin(euler[0]);
-  double cos_b = cos(euler[1]);
-  double sin_b = sin(euler[1]);
-  double cos_c = cos(euler[2]);
-  double sin_c = sin(euler[2]);
-
-  rotationMatrix[0] = cos_b * cos_c;
-  rotationMatrix[1] = -cos_a * sin_c + sin_a * sin_b * cos_c;
-  rotationMatrix[2] = sin_a * sin_c + cos_a * sin_b * cos_c;
-  rotationMatrix[3] = cos_b * sin_c;
-  rotationMatrix[4] = cos_a * cos_c + sin_a * sin_b * sin_c;
-  rotationMatrix[5] = -sin_a * cos_c + cos_a * sin_b * sin_c;
-  rotationMatrix[6] = -sin_b;
-  rotationMatrix[7] = sin_a * cos_b;
-  rotationMatrix[8] = cos_a * cos_b;
+     m_numQuaternions, &m_quaternions[0], m_t0Quat, m_dtQuat, time, 4, nOrderQuat, q);
 }
 
+
 void UsgsAstroLsSensorModel::calculateAttitudeCorrection(const double& time, const std::vector<double>& adj, double attCorr[9]) const {
   double aTime = time - m_t0Quat;
   double euler[3];
@@ -1790,16 +1717,16 @@ void UsgsAstroLsSensorModel::losToEcf(
    double fractionalLine = line - floor(line);
 
    // Compute distorted image coordinates in mm (sample, line on image (pixels) -> focal plane
-   double natFocalPlaneX, natFocalPlaneY;
-   computeDistortedFocalPlaneCoordinates(fractionalLine, sampleUSGSFull, natFocalPlaneX, natFocalPlaneY);
+   std::tuple<double, double> natFocalPlane;
+   natFocalPlane = computeDistortedFocalPlaneCoordinates(fractionalLine, sampleUSGSFull, m_detectorSampleOrigin, m_detectorLineOrigin, m_detectorSampleSumming, m_startingSample, m_detectorLineOffset, m_iTransS, m_iTransL);
 
    // Remove lens distortion
    std::tuple<double, double> undistortedPoint;
-   undistortedPoint = removeDistortion(natFocalPlaneX, natFocalPlaneY, m_opticalDistCoef);
+   undistortedPoint = removeDistortion(std::get<0>(natFocalPlane), std::get<1>(natFocalPlane), m_opticalDistCoef);
 
   // Define imaging ray (look vector) in camera space
    double cameraLook[3];
-   createCameraLookVector(std::get<0>(undistortedPoint), std::get<1>(undistortedPoint), adj, cameraLook);
+   createCameraLookVector(std::get<0>(undistortedPoint), std::get<1>(undistortedPoint), m_zDirection, m_focal, getValue(15, adj), m_halfSwath, cameraLook); 
 
    // Apply attitude correction
    double attCorr[9];
@@ -1817,8 +1744,10 @@ void UsgsAstroLsSensorModel::losToEcf(
                           + attCorr[8] * cameraLook[2];
 
 // Rotate the look vector into the body fixed frame from the camera reference frame by applying the rotation matrix from the sensor quaternions
+   double quaternions[4];
+   getQuaternions(time, quaternions); 
    double cameraToBody[9];
-   calculateRotationMatrixFromQuaternions(time, cameraToBody);
+   calculateRotationMatrixFromQuaternions(quaternions, cameraToBody);
 
    bodyLookX = cameraToBody[0] * correctedCameraLook[0]
              + cameraToBody[1] * correctedCameraLook[1]
@@ -2354,8 +2283,10 @@ csm::ImageCoord UsgsAstroLsSensorModel::computeViewingPixel(
    double bodyLookZ = groundPoint.z - zc;
 
    // Rotate the look vector into the camera reference frame
+   double quaternions[4];
+   getQuaternions(time, quaternions); 
    double bodyToCamera[9];
-   calculateRotationMatrixFromQuaternions(time, bodyToCamera);
+   calculateRotationMatrixFromQuaternions(quaternions, bodyToCamera);
 
    // Apply transpose of matrix to rotate body->camera
    double cameraLookX = bodyToCamera[0] * bodyLookX
diff --git a/src/Utilities.cpp b/src/Utilities.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9c82f6cdf766fc760136fea19f3ed9474fa342a
--- /dev/null
+++ b/src/Utilities.cpp
@@ -0,0 +1,90 @@
+#include "Utilities.h"
+
+// Calculates a rotation matrix from Euler angles
+void calculateRotationMatrixFromEuler(double euler[],
+                                      double rotationMatrix[]) {
+  double cos_a = cos(euler[0]);
+  double sin_a = sin(euler[0]);
+  double cos_b = cos(euler[1]);
+  double sin_b = sin(euler[1]);
+  double cos_c = cos(euler[2]);
+  double sin_c = sin(euler[2]);
+
+  rotationMatrix[0] = cos_b * cos_c;
+  rotationMatrix[1] = -cos_a * sin_c + sin_a * sin_b * cos_c;
+  rotationMatrix[2] = sin_a * sin_c + cos_a * sin_b * cos_c;
+  rotationMatrix[3] = cos_b * sin_c;
+  rotationMatrix[4] = cos_a * cos_c + sin_a * sin_b * sin_c;
+  rotationMatrix[5] = -sin_a * cos_c + cos_a * sin_b * sin_c;
+  rotationMatrix[6] = -sin_b;
+  rotationMatrix[7] = sin_a * cos_b;
+  rotationMatrix[8] = cos_a * cos_b;
+}
+
+
+// uses a quaternion to calclate a rotation matrix.
+void calculateRotationMatrixFromQuaternions(double q[4], double rotationMatrix[9]) {
+  double norm = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
+  q[0] /= norm;
+  q[1] /= norm;
+  q[2] /= norm;
+  q[3] /= norm;
+
+  rotationMatrix[0] = q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
+  rotationMatrix[1] = 2 * (q[0] * q[1] - q[2] * q[3]);
+  rotationMatrix[2] = 2 * (q[0] * q[2] + q[1] * q[3]);
+  rotationMatrix[3] = 2 * (q[0] * q[1] + q[2] * q[3]);
+  rotationMatrix[4] = -q[0] * q[0] + q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
+  rotationMatrix[5] = 2 * (q[1] * q[2] - q[0] * q[3]);
+  rotationMatrix[6] = 2 * (q[0] * q[2] - q[1] * q[3]);
+  rotationMatrix[7] = 2 * (q[1] * q[2] + q[0] * q[3]);
+  rotationMatrix[8] = -q[0] * q[0] - q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
+}
+
+std::tuple<double, double> computeDistortedFocalPlaneCoordinates(
+  const double& line,
+  const double& sample,
+  const double& sampleOrigin,
+  const double& lineOrigin, 
+  const double& sampleSumming,
+  const double& startingSample,
+  const double& lineOffset,
+  const double iTransS[],
+  const double iTransL[]) {
+  double detSample = (sample - 1.0) * sampleSumming + startingSample;
+  double m11 = iTransL[1];
+  double m12 = iTransL[2];
+  double m21 = iTransS[1];
+  double m22 = iTransS[2];
+  double t1 = line + lineOffset - lineOrigin - iTransL[0];
+  double t2 = detSample - sampleOrigin - iTransS[0];
+  double determinant = m11 * m22 - m12 * m21;
+  double p11 = m11 / determinant;
+  double p12 = -m12 / determinant;
+  double p21 = -m21 / determinant;
+  double p22 = m22 / determinant;
+
+  double distortedLine = p11 * t1 + p12 * t2;
+  double distortedSample = p21 * t1 + p22 * t2;
+  return std::make_tuple(distortedLine, distortedSample);  
+};
+
+// Define imaging ray in image space (In other words, create a look vector in camera space)
+void createCameraLookVector(
+  const double& undistortedFocalPlaneX,
+  const double& undistortedFocalPlaneY,
+  const double& zDirection,
+  const double& focalLength,
+  const double& focalLengthBias,
+  const double& halfSwath,
+  double cameraLook[]) {
+   cameraLook[0] = -undistortedFocalPlaneX * zDirection;
+   cameraLook[1] = -undistortedFocalPlaneY * zDirection;
+   cameraLook[2] = -focalLength * (1.0 - focalLengthBias / halfSwath);
+   double magnitude = sqrt(cameraLook[0] * cameraLook[0]
+                  + cameraLook[1] * cameraLook[1]
+                  + cameraLook[2] * cameraLook[2]);
+   cameraLook[0] /= magnitude;
+   cameraLook[1] /= magnitude;
+   cameraLook[2] /= magnitude;
+}